Bridge

Davos Bridge offers a cross-chain protocol to unify liquidity across blockchains. The protocol is a permissionless on-chain utility that can burn DUSD on a source chain and mint DUSD in same amount on a destination chain.

Why Did We Decide to Make Davos Bridge?

First, Davos Bridge eliminates the need to use conventional "lock-and-mint" bridge, which locks DUSD on the source chain (potential security problem) and mints a synthetic bridged version on the destination chain (liquidity fragmentation and poor UX).

Besides this, there are more important reasons to the "why":

  1. Burning/Minting is better for an omnichain fungible token like DUSD.

  2. We fully control the cost (zero cost).

  3. We don't rely on third-party protocols to enable DUSD on other chains, meaning no additional counter-party risk.

  4. The bridge is able to support any future chain.

  5. The bridge makes cross-chain transfers of DUSD as frictionless as possible.

  6. DUSD becomes a routing asset for stablecoin cross-chain transfers by onboarding Davos Bridge in Bridge aggregators, which create more trading volume for DUSD stable LPs.

How Does It Work?

  1. The user approves access to DUSD for Davos Bridge on the source chain.

  2. The user deposits DUSD on the source chain, and Davos Bridge burns it.

  3. A special external entity reacts to the burn event, and the user obtains from it the proof data needed when claiming at Step 4.

  4. The users claims DUSD on the destination chain, and Davos Bridge mints it for the user.

Supported Chains

  • Arbitrum

  • BNB Smart Chain

  • Ethereum

  • Optimism

  • Polygon

  • Polygon zkEVM

Contracts

  • DavosBridge β€” external cross-chain bridge that is deployed on the corresponding chains and linked together.

  • DUSD β€” stablecoin DUSD users can borrow from Davos.

Mainnet Addresses

DavosBridge

  • Arbitrum (0xC734528d0525923F29979393f3988168ad26d402)

  • BNB Smart Chain (0xDB34888e13FF86dE87469Ac6d4FfC8A5b293B79D)

  • Ethereum (0x6DeF4570251E1f435E121b3Ee47174496D851C99)

  • Optimism (0xDB34888e13FF86dE87469Ac6d4FfC8A5b293B79D)

  • Polygon (0x78BE0423567A85Ba677d3AA5b73b45970E52256b)

  • Polygon zkEVM (0x2304CE6B42D505141A286B7382d4D515950b1890)

DUSD

  • Arbitrum (0x8EC1877698ACF262Fe8Ad8a295ad94D6ea258988)

  • BNB Smart Chain (0x8EC1877698ACF262Fe8Ad8a295ad94D6ea258988)

  • Ethereum (0xa48F322F8b3edff967629Af79E027628b9Dd1298)

  • Optimism (0xed72aC9BA68caE26D7889d3b954cC7DcA31117Ca)

  • Polygon (0xEC38621e72D86775a89C7422746de1f52bbA5320)

  • Polygon zkEVM (0x819d1Daa794c1c46B841981b61cC978d95A17b8e)

Quickstart: Bridge DUSD

1. Approve Bridge to Access DUSD

approve() β€” approves access for Davos Bridge to user's DUSD on the source chain.

Parameters

  • usd (address) β€” address of Davos Bridge to approve access to user's DUSD for.

  • wad (uint256) β€” amount of DUSD to approve access to.

Smart Contracts

Examples

Ethereum Mainnet transaction

2. Deposit DUSD on the Source Chain

depositToken() β€” deposits DUSD on the source chain (subsequently causes the bridge to burn this DUSD).

Parameters

  • fromToken (address) β€” address of the DUSD contract on the source chain.

  • toChain (uint256) β€” ID of the destination chain.

  • toAddress (address) β€” address to mint tokens in the destination network.

  • amount (uint256) β€” amount of DUSD to bridge.

Smart Contracts

Examples

Ethereum Mainnet transaction

3. Get Proof Data

Host

https://mainnet.protocol.ankr.com

Endpoint

POST /v1alpha/notarize_transaction

Request

curl --request POST \
     --url 'https://mainnet.protocol.ankr.com/v1alpha/notarize_transaction' \
     --header 'accept: application/json, text/plain, */*' \
     --header 'content-type: application/json' \
     --data-raw '{"transaction_hash":"ABba0mFzexwfoErXtulg0nYRC9cViC49udkvUDZ9/6lF","chainId":"1","threshold_key":"6f6b2799-a37a-4b14-8efb-f36b446269b2"}' \
     --compressed

Parameters

  • transaction_hash (string) β€” hash of the depositToken transaction in the Base64 format. To generate, use the TXID of the depositToken transaction from Step 2 and refer to this code snippet:

    function hexToBase64(hexstring) {
    return btoa(
    hexstring
    .match(/\w{2}/g)
    ?.map(a => {
    return String.fromCharCode(parseInt(a, 16));
    })
    .join('') ?? '',
      );
    }
  • chain_id (uint256) β€” ID of the source chain.

  • threshold_key (string) β€” public key of the authorizing address. Constant value is 6f6b2799-a37a-4b14-8efb-f36b446269b2.

Response

200

{
  "notarized_transaction":
    {
      "id":"85c92a46-acf6-443f-be82-cfbad2fbee5c",
      "status":"NOTARIZED_TRANSACTION_STATUS_CONFIRMED",
      "blockchain":"BLOCKCHAIN_WEB3",
      "transaction_hash":"ABba0mFzexwfoErXtulg0nYRC9cViC49udkvUDZ9/6lF",
      "block_number":"17636646",
      "block_hash":"EFIdWvMPmRcs82Imo2MGYBCV4vxXIIkj9+GSDmPxvkc=",
      "transaction_index":"209",
      "receipt_hash":"dqWBZMoxb8aNPOWsYf28Om05vAzMbGGJGSsvIoGK8S8=",
      "transferred_amount":"0",
      "chain_id":"1",
      "threshold_key":"6f6b2799-a37a-4b14-8efb-f36b446269b2",
      "proposal":"1dc87c89-b6ac-4d61-bbc2-91acfe982ada",
      "payload":"bxR1MZlIpt0FAQvb501dma9CK/PvaGdhebdWP6rcZTo=",
      "signature":"TWyol5kmDm6reCUIKoqVymSMqR2O/PQ2USbqZI0vFT4xJZ5XS5zDyePw4ZSWZ8XSP0e/+HBWVvXNMg+0L+AtSQE=",
      "raw_payload":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARba0mFzexwfoErXtulg0nYRC9cViC49udkvUDZ9/6lFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAENHSYQUh1a8w+ZFyzzYiajYwZgEJXi/FcgiSP34ZIOY/G+RwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADRdqWBZMoxb8aNPOWsYf28Om05vAzMbGGJGSsvIoGK8S8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="
    }
} 

4. Claim DUSD on the Destination Chain

withdraw() β€” mints DUSD for the user on the destination chain.

Parameters

  • bytes (bytes) β€” encoded proof. To generate, use the raw_payload from the response at Step 3, bring it to the Base64 format, then bring the result to the hex format, and add 0x at the beginning. Refer to this code snippet as an example:

    bytes: `0x${Buffer.from(data.raw_payload, 'base64').toString('hex')}

    To learn about Buffer, read Buffer in Node.js.

  • rawReceipt (bytes) β€” transaction receipt of the depositToken transaction. To generate, use the TXID of the depositToken transaction from Step 2 and refer to this code snippet as an example:

    const receipt = await web3.eth.getTransactionReceipt(txHash);
    const rawReceipt = encodeTransactionReceipt(receipt);
    import { rlp } from 'ethereumjs-util';
    import Web3 from 'web3';
    import { TransactionReceipt } from 'web3-core';
     
    function encodeTransactionReceipt(txReceipt: TransactionReceipt): string {
    const rlpLogs = txReceipt.logs.map(log => {
    return [
    log.address,
    log.topics,
    // eslint-disable-next-line no-buffer-constructor
    new Buffer(log.data.substring(2), 'hex'),
    ];
    });
    const rlpReceipt = [
    Web3.utils.numberToHex(Number(txReceipt.status)),
    Web3.utils.numberToHex(txReceipt.cumulativeGasUsed),
    rlpLogs,
    ];
    const encodedReceipt: Buffer = rlp.encode(rlpReceipt);
    return `0x${encodedReceipt.toString('hex')}`;
    }
  • proofSignature (bytes) β€” proof of the valid signature. To generate, use signature from Step 3 and refer to this code snippet as an example:

    const myBuffer = Buffer.from(data.signature, 'base64');
    myBuffer[myBuffer.length - 1] += 27;
    let newSignature = '0x';
    myBuffer.forEach(byte => {
    // eslint-disable-next-line no-bitwise
    newSignature += `0${(byte & 0xff).toString(16)}`.slice(-2);
    });

    To learn about Buffer, read Buffer in Node.js.

Smart Contracts

Examples

Ethereum Mainnet transaction

Last updated