The goal of this document is to specify minimum interface requirements for cross-domain bridges (both 3rd party and canonical) to support ERC-7281. ### Table of Contents - [Background](#Background) - [Specification](#Specification) - [Recommendations for Canonical Bridges](#Recommendations-for-Canonical-Bridges) - [Recommendations for Bridge Aggregators](#Recommendations-for-Bridge-Aggregators) ## Background xERC20 is an open proposed standard for Sovereign Bridged Tokens. The approach allows tokens to be minted and burned across chains by multiple bridges (canonical or 3rd-party), while giving token issuers the ability to granularly control their security preferences for each bridge using rate limits. ![](https://hackmd.io/_uploads/SkKdPhCFh.png) xERC20 has two components which must be supported by bridges: - The xERC20 token implementation - The xERC20 lockbox #### Resources: - [ERC-7281 specification.](https://github.com/connext/EIPs/blob/master/EIPS/eip-7281.md) - [ERC-7281 discussion post.](https://ethereum-magicians.org/t/erc-7281-sovereign-bridged-tokens/14979) - [Reference xERC20.sol implementation.](https://github.com/defi-wonderland/xERC20/blob/dev/solidity/contracts/XERC20.sol) - [Reference xERC20Lockbox.sol implementation.](https://github.com/defi-wonderland/xERC20/blob/dev/solidity/contracts/XERC20Lockbox.sol) ## Specification Bridges that want to support xERC20 MUST, at minimum, support the following mint/burn interface onchain: ```solidity /** * @notice Mints tokens for a user * @dev Can only be called by a bridge * @param _user The address of the user who needs tokens minted * @param _amount The amount of tokens being minted */ function mint(address _user, uint256 _amount) external; /** * @notice Burns tokens for a user * @dev Can only be called by a bridge * @param _user The address of the user who needs tokens burned * @param _amount The amount of tokens being burned */ function burn(address _user, uint256 _amount) external;``` ``` Bridges MUST additionally handle the error case where rate limits are saturated. This can happen in one of two ways: 1. The burn limit for a given bridge is hit on the source chain. In this case, the transaction should simply revert and return funds to the user. 2. The mint limit for a given bridge is hit on the destination chain. In this case, the transaction should be held and retried later. Bridges SHOULD wrap normal ERC20 tokens into xERC20s as part of their onchain contracts if one is deployed on a given chain: ```solidity /** * @notice Deposit ERC-20 tokens into the lockbox * * @param _amount The amount of tokens to deposit */ function deposit(uint256 _amount) external; /** * @notice Withdraw ERC-20 tokens from the lockbox * * @param _amount The amount of tokens to withdraw */ function withdraw(uint256 _amount) external; ``` Bridges can optionally wrap tokens into xERC20s using a UI-level flow, multicall or similar pattern typically used for wrapping ETH into WETH. ### Token Mappings In order to successfully wrap and burn/mint xERC20 tokens, bridges must first know *which* tokens need to be wrapped. In the ideal case, there is a public registry of all tokens that support the xERC20 standard that bridges can read from on all chains. We have found through preliminary research, however, that this is an extremely challenging problem to solve in a way that is both crediby neutral and remains resilient to attack vectors involving incorrect token mappings. For the time being, bridges MUST maintain their own mapping of tokens across chains. Specifically for xERC20, they MUST also maintain a mapping of a given ERC20 to its associated `xERC20Lockbox` contract. ## Recommendations for Canonical Bridges > Note: We define **Canonical Bridges** as bridges that are enshrined into a given domain - e.g. Hashi for Gnosis, or the rollup bridges for rollups. Canonical bridges typically implement two components: 1. An underlying messaging system between domains 2. An application built on top of the above that acts as the canonical token bridge. Typically, this application custodies tokens on L1, and then mints a representation of that token on L2. In some cases, domain operators support permissionlessly building additional custom token bridges on top of their messaging systems. Some examples: - Arbitrum supports mapping [a custom gateway](https://developer.arbitrum.io/asset-bridging#other-flavors-of-gateways) for token bridging. - Optimism supports [building a custom token bridge](https://community.optimism.io/docs/guides/bridge-dev/#building-a-custom-bridge). - Polygon supports custom crosschain logic [through their fx-portal](https://wiki.polygon.technology/docs/category/fxportal). We expect that canonical bridge implementers can and should build the xERC20 token bridge on top of existing base messaging functionality, at the same level as the canonical token bridge, to avoid edge cases around token minting/locking. In addition to this, canonical bridges SHOULD appropriately route ERC20 tokens that have existing mapped xERC20 representations to their lockbox and then bridge them via the xERC20 bridge. This helps to avoid the following cases: 1. An xERC20's underlying ERC20 token is locked-and-minted across chains leading to a new bridged-ERC20 representation created on the domain that is infungible with the token-issuer-defined canonical token. 2. An xERC20 is incorrectly routed to the canonical lock-and-mint bridge instead of the xERC20 bridge contracts on the home domain, which once again creates an incorrect and infungible representation on the remote domain. ## Recommendations for Bridge Aggregators Bridge aggregators do not have to do an onchain integration to support xERC20s as they function just like regular ERC20s. However, they will need some offchain functionality to support xERC20s: 1. Aggregators MUST identify tokens that have xERC20 representations and wrap/unwrap the tokens if needed via its lockbox. 2. Aggregators SHOULD query the xERC20 contracts for source and target domains to determine which bridges have the highest available `current limit` for minting or burning a token and route transfers based on this limit. For point (2): Aggregators will typically route token bridging activities based on pricing and available liquidity for each bridge. In the xERC20 model, this is no longer as relevant. Instead, aggregators should now be prioritizing routing based on *availability* to ensure that a transaction does not hit a bridge's limit while in-flight.