From 8fe722003f05993aa819b0dd272a03e19c014266 Mon Sep 17 00:00:00 2001 From: arjunbhuptani Date: Wed, 5 Jul 2023 17:59:13 +0100 Subject: [PATCH 01/16] Add draft EIP --- ERCS/eip-draft_bridged_tokens.md | 366 +++++++++++++++++++++++++++++++ 1 file changed, 366 insertions(+) create mode 100644 ERCS/eip-draft_bridged_tokens.md diff --git a/ERCS/eip-draft_bridged_tokens.md b/ERCS/eip-draft_bridged_tokens.md new file mode 100644 index 0000000000..164e796703 --- /dev/null +++ b/ERCS/eip-draft_bridged_tokens.md @@ -0,0 +1,366 @@ +--- +title: Bridged Token Standard (xERC20) +description: An interface for creating fungible representations of tokens bridged across domains. +author: Shaito (@0xShaito), Excalibor (@excaliborr), Arjun Bhuptani (@arjunbhuptani) +discussions-to: +status: Draft +type: Standards Track +category: ERC +created: 2023-06-27 +requires: 20 +--- + +## Abstract + +This proposal (affectionately called xERC20) defines a minimal extension to ERC-20 that enables bridging tokens across domains without creating multiple infungible representations of the same underlying asset. Token issuers can define which bridges are able to mint or burn the xERC20 on a given domain and configure rate limits for each allowed bridge. + +## Motivation + +With the rapid proliferation of L2 domains, fungible token liquidity has become increasingly fragmented across domains. This, coupled with the need for projects to transfer tokens between chains faster than rollup exit windows, has meant that token issuers must choose from one of two options to bridge their tokens: + +1. Bridge tokens through the “canonical” rollup bridge and work with atomic swap or fast-liquidity providers for L2→L1 or L2→L2 interactions. While this is the safer option, it necessitates significant requirements for issuers to incentivize or bootstrap liquidity on every supported chain, limiting support to only the most liquid of assets. Liquidity-based bridging additionally introduces slippage or other unpredictable pricing for users, hindering composability across domains. +2. Work with a 3rd party bridge. This option removes liquidity and pricing concerns making it more favorable for longer-tail issuers, but locks a given minted representation of a bridged token to only its associated bridge. This creates a tradeoff for issuers between security/sovereignty and user experience: If the token is bridged through only a single provider, the token supply and implementation is now fully and in perpetuity controlled by the bridge. If the token is bridged through multiple options (including "canonical" rollup bridges), multiple infungible (“wrapped”) representations of the same underlying asset are created on L2. + +In the ideal case, token issuers want the following properties for bridged representations of their tokens: + +- Sovereignty. Issuers want to be the logical owners of the canonical representation of their token on L2 and not be locked into any single specific option forever. +- Fungibility. Token issuers want a single “canonical” representation of their token on each L2, regardless of which bridges (canonical or otherwise) are supported by the issuer. +- Security. Issuers want to opt into novel secure bridging approaches as they are developed and have granular control over their risk tolerance for any given option. +- Minimal Liquidity. Issuers want to minimize the costs and complexity of acquiring liquidity for their token on each supported bridge and chain. This property becomes increasingly important as the space eventually expands to 100s or 1000s of connected domains. + +There has been some previous work to solve this problem. However, solutions have historically either failed to satisfy all of the above desirable properties or have been custom-built for only a single token ecosystem. + +- Celer’s Open Canonical Token Standard proposed a lock-in free standard for bridging tokens to new domains. However, it largely targeted alternative L1s (that don’t already have a canonical bridge) and did not fully solve the fungibility problem. Regardless, Celer’s approach inspired some of the key thinking behind this standard. +- Maker’s Teleport facility allows for minting and burning canonical DAI between domains. While the approach solves for the desirable properties above, it is highly custom to Maker’s architecture and relies on Maker’s own economic security to function. Circle CCTP similarly solves this problem, but using a mechanism that only centralized token issuers can implement. +- Token issuer multi-bridge implementations, e.g. Angle protocol and Threshold Network’s tBTC. These examples solve for some or all of the above desiderata and can be applied more broadly to all tokens if coupled with minor additions for compatibility with existing deployed tokens. + +## Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. + +### Overview + +The system proposed below has two main components: + +- A standard interface for bridged tokens +- A wrapper (aka “Lockbox”) that allows existing tokens to adopt the above interface + +### Token Interface + +All xERC20 tokens MUST implement the standard ERC20 interface. Note that while many of the below functions are inspired by ERC777, implementers are NOT REQUIRED to adhere to the full ERC777 specification. + +All EIP-XX tokens MUST implement the following interface. + +```ts +interface IXERC20 { + /** + * @notice Emits when a lockbox is set + * + * @param _lockbox The address of the lockbox + */ + + event LockboxSet(address _lockbox); + + /** + * @notice Emits when a limit is set + * + * @param _newLimit The updated limit we are setting to the bridge + * @param _bridge The address of the bridge we are setting the limit too + */ + + event BridgeLimitsSet(uint256 _newLimit, address indexed _bridge); + + /** + * @notice Emits when a limit is set + * + * @param _newLimit The updated limit we are setting to the bridge + * @param _burner The address of the bridge we are setting the limit too + */ + + event BurnerLimitsSet(uint256 _newLimit, address indexed _burner); + + /** + * @notice Reverts when a user with too low of a limit tries to call mint/burn + */ + + error IXERC20_NotHighEnoughLimits(); + + /** + * @notice Reverts when caller is not the factory + */ + + error IXERC20_NotFactory(); + + struct Bridge { + BridgeParameters minterParams; + BridgeParameters burnerParams; + } + + struct BridgeParameters { + uint256 timestamp; + uint256 ratePerSecond; + uint256 maxLimit; + uint256 currentLimit; + } + + /** + * @notice Sets the lockbox address + * + * @param _lockbox The address of the lockbox (0x0 if no lockbox) + */ + + function setLockbox(address _lockbox) external; + + /** + * @notice Updates the limits of any bridge + * @dev Can only be called by the owner + * @param _mintingLimit The updated minting limit we are setting to the bridge + * @param _burningLimit The updated burning limit we are setting to the bridge + * @param _bridge The address of the bridge we are setting the limits too + */ + function setLimits(address _bridge, uint256 _mintingLimit, uint256 _burningLimit) external; + + /** + * @notice Returns the max limit of a bridge + * + * @param _bridge The bridge we are viewing the limits of + * @return _limit The limit the bridge has + */ + function mintingMaxLimitOf(address _bridge) external view returns (uint256 _limit); + + /** + * @notice Returns the max limit of a bridge + * + * @param _bridge the bridge we are viewing the limits of + * @return _limit The limit the bridge has + */ + + function burningMaxLimitOf(address _bridge) external view returns (uint256 _limit); + + /** + * @notice Returns the current limit of a bridge + * + * @param _bridge The bridge we are viewing the limits of + * @return _limit The limit the bridge has + */ + + function mintingCurrentLimitOf(address _bridge) external view returns (uint256 _limit); + + /** + * @notice Returns the current limit of a bridge + * + * @param _bridge the bridge we are viewing the limits of + * @return _limit The limit the bridge has + */ + + function burningCurrentLimitOf(address _bridge) external view returns (uint256 _limit); + + /** + * @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; +} +``` + +Implementations MUST additionally satisfy the following requirements: +- `mint` MUST check that the caller's current available `limit` is greater than or equal to `_amount` +- `mint` MUST increase the supply of the underlying ERC-20 by `_amount` and reduce the current available `limit` +- `burn` MUST check that the caller's current available `limit` is greater than or equal to `_amount` +- `burn` MUST decrease the supply of the underlying ERC-20 by `_amount` and reduce the current available `limit` + +## Lockbox + +The lockbox tries to emulate the WETH contract interface as much as possible. Lockboxes MUST implement the following interface: + +```ts +interface IXERC20Lockbox { + /** + * @notice Emitted when tokens are deposited into the lockbox + */ + + event Deposit(address _sender, uint256 _amount); + + /** + * @notice Emitted when tokens are withdrawn from the lockbox + */ + + event Withdraw(address _sender, uint256 _amount); + + /** + * @notice Reverts when a user tries to deposit native tokens on a non-native lockbox + */ + + error IXERC20Lockbox_NotNative(); + + /** + * @notice Reverts when a user tries to deposit non-native tokens on a native lockbox + */ + + error IXERC20Lockbox_Native(); + + /** + * @notice Reverts when a user tries to withdraw and the call fails + */ + + error IXERC20Lockbox_WithdrawFailed(); + + /** + * @notice Deposit ERC20 tokens into the lockbox + * + * @param _amount The amount of tokens to deposit + */ + + function deposit(uint256 _amount) external; + + /** + * @notice Withdraw ERC20 tokens from the lockbox + * + * @param _amount The amount of tokens to withdraw + */ + + function withdraw(uint256 _amount) external; +} +``` + +Lockboxes SHOULD additionally implement the following alternative `deposit` function for native (non-ERC20) assets. +```ts +/** + * @notice Deposit native assets (e.g. ETH) into the lockbox + */ + + function deposit() external payable; +``` + + +## Rationale + + + +The proposed standard attempts to satisfy the following conditions for bridged tokens regardless of where and how they are bridged: + +1. Tokens received at the destination should be the canonical tokens. +2. Bridges should not need to bootstrap liquidity for each new chain and asset. +3. Cross-domain interactions involving tokens should be slippage-free, simplifying composability. +4. Token issuers should own decision-making around which bridges to support and be able to parametrize risk for each. They should not be locked into only supporting a single bridge. + +### Fungibility + +The core problem that this standard tackles is the **********************fungibility********************** of tokens bridged across domains against the “canonical” token on that domain. (Note: which token is “canonical” is dictated by the token issuer and is sometimes, but not always, the token minted by a given domain’s enshrined bridge - e.g. a rollup bridge). + +!https://s3-us-west-2.amazonaws.com/secure.notion-static.com/524e6503-835b-4833-82f4-9640806ec438/fragmentation.png + +It is not enough to simply allow multiple bridges to mint the same representation on a remote domain if liquidity is locked into bridges on the home domain. To illustrate this, consider an example where two bridges control minting rights of canonical USDT on an L2: + +- Alice bridges 100 USDT from L1→L2 through bridge 1. The underlying L1 USDT tokens is locked in bridge 1 and 100 USDT is minted on L2. +- Bob bridges 100 USDT from L1→L2 through bridge 2. Similar to the above case, the underlying L1 USDT tokens are locked in bridge 2 and 100 USDT is minted on L2. +- Suppose Alice pays Bob her 100 USDT. Bob now has 200 USDT. +- Bob attempts to bridge the 200 USDT from L2→L1 through bridge 2. This transaction fails, because bridge 2 only has 100 USDT custodied that it can give to Bob. + +The core property that this example illustrates is that locking tokens across multiple bridges on the token’s “home” domain makes it impossible to have fungibility without impeding user experience on remote domains. Minting or burning the token can solve this problem, but not all ERC20 tokens implement a configurable mint/burn interface. + +### Lockbox + +This proposal specifically solves for the above problem in cases where tokens do not already have a mint/burn interface. Tokens on the source chain are locked into a Lockbox, which mints corresponding xERC20-compatible tokens that can be sent to bridges. + +!https://s3-us-west-2.amazonaws.com/secure.notion-static.com/1b11d689-a130-443a-8458-2db7da03198e/xERC20.png + +1. A given ERC20 is wrapped into its xERC20 representation. +2. The xERC20 can then be transferred to any approved bridge. The bridge should check rate limits for the token and then `burn` the token. +3. On the target domain, the bridge then similarly `mint`s the token. +4. When transferring back to the home chain, the xERC20 can be unwrapped back into the original ERC20 token. + +Using this mechanism, the underlying ERC20 token is consolidated to the Lockbox contract, and shared across all supported bridges. + +### Rate Limits + +A key consideration for consolidating home chain liquidity (and, by extension, allowing multiple bridges to mint the same representation) is the risk introduced due to the failure of any single bridge. In other words, there is a tradeoff space between fungibility (i.e. user experience) and security. + +The current best practice for limiting this risk is for issuers to enshrine a single bridge that mints the canonical representation on a given domain (this is often the rollup bridge, but we are increasingly seeing projects moving to proprietary/3rd party bridges citing liquidity and UX concerns). In this case, the token issuer fully trusts the enshrined bridge. Alternative bridges that want to support the token then must build liquidity for the token, where the risk to the token issuer of a given bridge’s failure is capped to the total liquidity locked in the bridge. + +The xERC20 proposal attempts to mimic and improve upon this risk topology without the need for external liquidity. Instead of risk being capped by the locked tokens in a given (non-enshrined) bridge, risk is now capped by rate limits that are configurable on a per-bridge basis. This gives issuers granular control over their risk appetite as issuers can experiment with different bridges and adjust their confidence over time. Perhaps most importantly: this approach also encourages more open competition around security, as issuers no longer have to default to using only the most liquid or well-funded options. + +### Edge Case Considerations for Limits + +Minting and burning limits introduce failure modes that can impede UX. This is a necessary part of ensuring that bridge risk is compartmentalized and this standard assumes that implementers can work towards raising or altogether removing limits for bridges as they build confidence in them over time. + +Regardless of the above, the failure modes associated with rate limits generally map directly to **existing** failure modes around insufficient liquidity on bridges, and in many cases improve upon them. The two cases to consider here are: + +1. Hitting burn limits on the source chain. This case is hit when a given bridge has capped its limit on burning tokens, causing a revert of the transaction that included a call to the bridge. + 1. In the current liquidity-bridging model, bridges will typically have no way to know upfront if they have sufficient liquidity on the target chain for a given transaction. This means that a limit-based approach (where the transaction **fails fast**) is a significant improvement to UX. +2. Hitting minting limits on the destination chain. This case can be hit *after* tokens are burned on the source chain in cases where many different minting transactions are simultaneously triggered on a given destination domain and bridge combination, leading to the bridge’s limit being saturated. + 1. This problem exists in the current model if there is insufficient liquidity on the destination for a given bridge to complete a transaction within some defined slippage constraints. This case is not well-handled by bridges at the moment. Bridges are forced to either output some wrapped representation, or force users to wait until there is more liquidity. + 2. In the limit-based approach, the bridge will similarly not be able to complete the transaction on the destination domain until it has more capacity available. However, a limit approach provides some more reasonable guarantees to the user: (1) user have a much higher degree of predictability around time and pricing of the outputted transaction, (2) users would not receive some wrapped representation, and (3) bridges would have a simpler pathway for users to send the tokens back to the source domain or any other destination. + +## Backwards Compatibility + +This proposal is fully backwards compatible with ERC-20. + +Aside from the above, the following compatibility vectors were considered when designing this proposal: + +- Compatibility with existing/deployed tokens +- Compatibility with canonical & 3rd party bridges + +### Compatibility with Deployed Tokens + +There are three states that token issuers begin with when migrating to xERC20s: + +1. The token does not exist yet OR is upgradeable/controlled by the issuer on each supported domain. +2. The token is deployed to a single home domain but not others yet. +3. The token is deployed and/or bridged to multiple domains + +The proposed xERC20 standard solves for (1) out of the box - token issuers should simply deploy xERC20 interface-compatible tokens on all domains they wish to support with no lockbox needed. + +Case (2) is straightforward to solve with xERC20s as well. Token issuers should deploy a lockbox on their home chain, and then wrap their ERC20s into xERC20s prior to bridging them. This wrapping step may add some friction depending on the bridge - this is discussed further in the Compatibility with Bridges section. + +Case (3) is the most challenging to solve for as issuers may not have sovereign control over the “canonical” representation of the token on any remote domain and this necessitates a token migration of some form at least. As an example, tokens bridged using the default Arbitrum rollup bridge would be fully controlled by the rollup bridge. For these cases, we recommend the following migration path for issuers: + +1. Deploy a lockbox on the remote domain which locks the canonical-bridge-minted token and mints a new xERC20. +2. Establish the new xERC20 token as the canonical asset for the domain - this is largely a social consensus activity driven by DAO agreement and project communications. +3. Deploy a lockbox on the home domain which locks the home canonical token and mints a new xERC20. +4. Allowlist all desired bridges *including* the canonical bridge that owns the legacy implementation, mapping the xERC20 representation on the home domain to the xERC20 representation on the remote. +5. At this point, it is fully possible for users to begin transferring the token across all bridges as would be expected from the xERC20 standard. However, note that the canonical bridge connecting home to remote will now have two bridge paths: (a) ERC20→ERC20 (locking the ERC20 at home), and (b) xERC20→xERC20. Now, the issuer can begin the process of sunsetting the legacy canonical ERC20 on the remote domain. +6. The issuer should at this point disallow minting *new* legacy canonical ERC20s on the remote domain and only allow users to bridge ERC20s *back* to the home domain (by unwrapping xERC20 on the remote). This would organically & gradually lead to the ERC20 on the home chain becoming unlocked from the home<>remote canonical bridge, but token issuers can also incentivize this behavior if there is a desire for it to occur more quickly. + +### Compatibility with Bridges + +One key benefit to the xERC20 model is that the simple requirement of a burn & mint interface makes this proposal compatible with most bridges either out of the box or through a predefined custom token mapping process. The following bridges & domains were considered in the creation of this proposal: + +- **3rd party bridges:** every 3rd party bridge that relies on messaging infrastructure already supports a mint and burn interface and has a pathway to map custom minted tokens. +- **Arbitrum rollup bridge:** Arbitrum allows token issuers to [write a custom gateway](https://developer.arbitrum.io/asset-bridging#other-flavors-of-gateways). +- **OP Stack bridge:** Optimism supports [adding a custom bridge](https://community.optimism.io/docs/guides/bridge-dev/#building-a-custom-bridge). +- **Polygon PoS bridge:** Polygon supports custom tokens [through their fx portal](https://wiki.polygon.technology/docs/develop/l1-l2-communication/fx-portal). +- **ZkSync bridge**: Zksync supports [custom bridges of any kind](https://era.zksync.io/docs/reference/concepts/bridging/bridging-asset.html#custom-bridges-on-l1-and-l2). +- **GnosisChain Omnibridge:** GnosisChain does not currently support custom tokens, but is in the process of redesigning their omnibridge and plans to allow this functionality. + +Note: In most of the above cases, a custom bridge integration also means integration into canonical bridge UIs, ensuring that users have a consistent experience throughout the process. Additionally, a single xERC20 custom bridge implementation could be built for each ecosystem and serve any number of token issuers. + +## Reference Implementation + +You can find a reference implementation and associated test cases [here](https://github.com/defi-wonderland/xTokens/blob/dev/solidity/contracts/XERC20.sol). + +## Security Considerations + +Please see the associated discussion in the **Rationale** section. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From f828f37050b0401e83dc30c5e079524dc8c8ade2 Mon Sep 17 00:00:00 2001 From: arjunbhuptani Date: Wed, 5 Jul 2023 18:03:49 +0100 Subject: [PATCH 02/16] Add image assets --- ERCS/eip-draft_bridged_tokens.md | 4 ++-- .../eip-draft_bridged_tokens/fragmentation.png | Bin 0 -> 23658 bytes assets/eip-draft_bridged_tokens/xERC20.png | Bin 0 -> 32009 bytes 3 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 assets/eip-draft_bridged_tokens/fragmentation.png create mode 100644 assets/eip-draft_bridged_tokens/xERC20.png diff --git a/ERCS/eip-draft_bridged_tokens.md b/ERCS/eip-draft_bridged_tokens.md index 164e796703..feb76307c0 100644 --- a/ERCS/eip-draft_bridged_tokens.md +++ b/ERCS/eip-draft_bridged_tokens.md @@ -266,7 +266,7 @@ The proposed standard attempts to satisfy the following conditions for bridged t The core problem that this standard tackles is the **********************fungibility********************** of tokens bridged across domains against the “canonical” token on that domain. (Note: which token is “canonical” is dictated by the token issuer and is sometimes, but not always, the token minted by a given domain’s enshrined bridge - e.g. a rollup bridge). -!https://s3-us-west-2.amazonaws.com/secure.notion-static.com/524e6503-835b-4833-82f4-9640806ec438/fragmentation.png +![](../assets/eip-draft_bridged_tokens/fragmentation.png) It is not enough to simply allow multiple bridges to mint the same representation on a remote domain if liquidity is locked into bridges on the home domain. To illustrate this, consider an example where two bridges control minting rights of canonical USDT on an L2: @@ -281,7 +281,7 @@ The core property that this example illustrates is that locking tokens across mu This proposal specifically solves for the above problem in cases where tokens do not already have a mint/burn interface. Tokens on the source chain are locked into a Lockbox, which mints corresponding xERC20-compatible tokens that can be sent to bridges. -!https://s3-us-west-2.amazonaws.com/secure.notion-static.com/1b11d689-a130-443a-8458-2db7da03198e/xERC20.png +![](../assets/eip-draft_bridged_tokens/xERC20.png) 1. A given ERC20 is wrapped into its xERC20 representation. 2. The xERC20 can then be transferred to any approved bridge. The bridge should check rate limits for the token and then `burn` the token. diff --git a/assets/eip-draft_bridged_tokens/fragmentation.png b/assets/eip-draft_bridged_tokens/fragmentation.png new file mode 100644 index 0000000000000000000000000000000000000000..955f389f4da1e96debbb6639d5d2635708fe011b GIT binary patch literal 23658 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

oG8%gTa_u+L_zl+>^~xQ!R8EIhB>B+pKZoTyXd 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%0D_s4|- z1ssh0xB5+^VpPl#!?+N{sH} zc(h1zzID}l7#-0grbgG!8emkh+NltW?;Ta$^oPxCY@vdEQW-MZg&RI4pW&)Lyrl-J z`^zjw$YcfEae46>?NfaBw)%~e*(+IreW%5FJdK_quTfIZz5}BZDZ?P%=LZP;dB!H| z`A6MxzE9kj8$~1&4Wt1--;W(Q0E$Vj|00Pk-oFF5S69JwM6^Usr@nmA2 zXP~o$C<8-@YO^GmwAQa(`UXTd7)aBjB2t_=PaP0#Cz|8)*o=b6>tgBAy9BE9US=_` z2_+6Pt9p=}XL}G6AJX-`l@H$0@_fZOvx_1|7PflRlg~~ZN%pWyDjXNixy5)9B&F@b z(4;xmRQXA>lZxuJ$31mn9Ma~Rr5eN;H9#JHf4?o95BlmvsO5qOP08m;3$XtSP(1tO z;_sj$g3yM#=p9%e3X%cE%RUsujlsPj4J$6pe7iAV*YESkY6oc_)YYj@c_UCN`Sw$8 zD1K9@IR>FwALAS+Wl{D!Om@!y3apPi&>Z&EU|+#&0pV@ zA+Kl=9tT@CW!f)3;X`e%clgHH{J&56)SNo}C;KJrUD)=QwbDePAaZey`TAYncLMfq z%=^nXa%j)Qt10A|G>!`I5Ms{i+p~j+6QtvlT$)DXIAn*=4P&x|1h~NReJXV~%DEiV z8v$7ws+{=7`D}zwo$^L`Y6x$I(#~kG!Mf9<1qU#(qm4oA#^ZG8&^6|DqzCvDwfwbv z8e`cXH@QOMZ_WL z$61t*$ftm$o9o3Se4Ur!F1g_npHG9F?TQN5Uy4F-QK|l4N4Wy3LBizO>xx_v%Xf`TnW*tE&lpf;PN2^n);0ORSXGaXe1&Bxo#z6c znZi`}S4>%(b@~GSLDuDvm`@>ntRpn!xuq<)7GAgi##DVWuW~LI?8n~t?TN2c3X5SY zT~|10+?+QkJl<2=NIAj|0EOkJNJ{BGsEly>7pf}t$}QOm(bF%L^L4X$Ii!NZ!Oa2d z_{9f9UK8OiRU~jCBsYB2mONNp!*1j|=v}osS_#j)Hxy1088UE421{9#=fXn#4d!m1 zE2V>|`Liz$1_lF5*vx&UaHom!Fx#_b9R8t%R&IsbP;xUGM0B@0#Y+K-87(%-4DhNS zk0BP&?{USWMwFLlIYaiGgf9ezG=jU{v@LJEWgHxF`E@&mL}X0EQM^mRX7n8&o%zmh z!&_=~rzfu$r|ULQ{ANJF$^AoDdaDbkh6Z~CPm;CtVMBP{TmgLGEkNNLn8Dg z_z)To^)N literal 0 HcmV?d00001 From da8e88eae6f0233378c956b5258cb19e5400467b Mon Sep 17 00:00:00 2001 From: arjunbhuptani Date: Wed, 5 Jul 2023 18:51:25 +0100 Subject: [PATCH 03/16] Minor spec fixes --- ERCS/eip-draft_bridged_tokens.md | 30 ++++-------------------------- 1 file changed, 4 insertions(+), 26 deletions(-) diff --git a/ERCS/eip-draft_bridged_tokens.md b/ERCS/eip-draft_bridged_tokens.md index feb76307c0..23ea974c39 100644 --- a/ERCS/eip-draft_bridged_tokens.md +++ b/ERCS/eip-draft_bridged_tokens.md @@ -2,7 +2,7 @@ title: Bridged Token Standard (xERC20) description: An interface for creating fungible representations of tokens bridged across domains. author: Shaito (@0xShaito), Excalibor (@excaliborr), Arjun Bhuptani (@arjunbhuptani) -discussions-to: +discussions-to: (TODO) status: Draft type: Standards Track category: ERC @@ -64,20 +64,12 @@ interface IXERC20 { /** * @notice Emits when a limit is set * - * @param _newLimit The updated limit we are setting to the bridge + * @param _mintingLimit The updated minting limit we are setting to the bridge + * @param _burningLimit The updated burning limit we are setting to the bridge * @param _bridge The address of the bridge we are setting the limit too */ - event BridgeLimitsSet(uint256 _newLimit, address indexed _bridge); - - /** - * @notice Emits when a limit is set - * - * @param _newLimit The updated limit we are setting to the bridge - * @param _burner The address of the bridge we are setting the limit too - */ - - event BurnerLimitsSet(uint256 _newLimit, address indexed _burner); + event BridgeLimitsSet(uint256 _mintingLimit, uint256 _burningLimit, address indexed _bridge); /** * @notice Reverts when a user with too low of a limit tries to call mint/burn @@ -85,12 +77,6 @@ interface IXERC20 { error IXERC20_NotHighEnoughLimits(); - /** - * @notice Reverts when caller is not the factory - */ - - error IXERC20_NotFactory(); - struct Bridge { BridgeParameters minterParams; BridgeParameters burnerParams; @@ -247,14 +233,6 @@ Lockboxes SHOULD additionally implement the following alternative `deposit` func ## Rationale - - The proposed standard attempts to satisfy the following conditions for bridged tokens regardless of where and how they are bridged: 1. Tokens received at the destination should be the canonical tokens. From 1e1b20fc6383217af12d2402b002926034bb5b6d Mon Sep 17 00:00:00 2001 From: arjunbhuptani Date: Wed, 5 Jul 2023 18:57:16 +0100 Subject: [PATCH 04/16] Fix title --- ERCS/eip-draft_bridged_tokens.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/eip-draft_bridged_tokens.md b/ERCS/eip-draft_bridged_tokens.md index 23ea974c39..832f45498e 100644 --- a/ERCS/eip-draft_bridged_tokens.md +++ b/ERCS/eip-draft_bridged_tokens.md @@ -1,5 +1,5 @@ --- -title: Bridged Token Standard (xERC20) +title: Bridged Token Standard description: An interface for creating fungible representations of tokens bridged across domains. author: Shaito (@0xShaito), Excalibor (@excaliborr), Arjun Bhuptani (@arjunbhuptani) discussions-to: (TODO) From ff07bbbb4ae5c1ab9b4b9593fdd6ef69b758579b Mon Sep 17 00:00:00 2001 From: arjunbhuptani Date: Fri, 7 Jul 2023 13:22:00 +0100 Subject: [PATCH 05/16] Fix build + add aggregator section --- ERCS/eip-7281.md | 357 +++++++++++++++++++++++++++++++ ERCS/eip-draft_bridged_tokens.md | 85 ++++---- 2 files changed, 406 insertions(+), 36 deletions(-) create mode 100644 ERCS/eip-7281.md diff --git a/ERCS/eip-7281.md b/ERCS/eip-7281.md new file mode 100644 index 0000000000..ce4dd57c44 --- /dev/null +++ b/ERCS/eip-7281.md @@ -0,0 +1,357 @@ +--- +eip: 7281 +title: Sovereign Bridged Token +description: An interface for creating fungible representations of tokens bridged across domains. +author: Shaito (@0xShaito), Excalibor (@excaliborr), Arjun Bhuptani (@arjunbhuptani) +discussions-to: (TODO) +status: Draft +type: Standards Track +category: ERC +created: 2023-06-27 +requires: 20 +--- + +## Abstract + +This proposal defines a minimal extension to [ERC-20](../EIPS/eip-20.md) (affectionately called xERC-20) that enables bridging tokens across domains without creating multiple infungible representations of the same underlying asset. Token issuers can define which bridges are able to mint or burn the xERC-20 on a given domain and configure rate limits for each allowed bridge. + +## Motivation + +With the rapid proliferation of L2s, fungible token liquidity has become increasingly fragmented across domains. This, coupled with the need for projects to transfer tokens between chains faster than rollup exit windows, has meant that token issuers must choose from one of two options to bridge their tokens: + +1. Bridge tokens through the “canonical” rollup bridge and work with atomic swap or fast-liquidity providers for L2→L1 or L2→L2 interactions. While this is the safer option, it necessitates significant requirements for issuers to incentivize or bootstrap liquidity on every supported chain, limiting support to only the most liquid of assets. Liquidity-based bridging additionally introduces slippage or other unpredictable pricing for users, hindering composability across domains. +2. Work with a 3rd party bridge. This option removes liquidity and pricing concerns making it more favorable for longer-tail issuers, but locks a given minted representation of a bridged token to only its associated bridge. This creates a tradeoff for issuers between security/sovereignty and user experience: If the token is bridged through only a single provider, the token supply and implementation is now fully and in perpetuity controlled by the bridge. If the token is bridged through multiple options (including "canonical" rollup bridges), multiple infungible (“wrapped”) representations of the same underlying asset are created on L2. + +In the ideal case, token issuers want the following properties for bridged representations of their tokens: + +- Sovereignty. Issuers want to be the logical owners of the canonical representation of their token on L2 and not be locked into any single specific option forever. +- Fungibility. Token issuers want a single “canonical” representation of their token on each L2, regardless of which bridges (canonical or otherwise) are supported by the issuer. +- Security. Issuers want to opt into novel secure bridging approaches as they are developed and have granular control over their risk tolerance for any given option. +- Minimal Liquidity. Issuers want to minimize the costs and complexity of acquiring liquidity for their token on each supported bridge and chain. This property becomes increasingly important as the space eventually expands to 100s or 1000s of connected domains. + +There has been some previous work to solve this problem. However, solutions have historically either failed to satisfy all of the above desirable properties or have been custom-built for only a single token ecosystem. + +- Celer’s Open Canonical Token Standard proposed a lock-in free standard for bridging tokens to new domains. However, it largely targeted alternative L1s (that don’t already have a canonical bridge) and did not fully solve the fungibility problem. Regardless, Celer’s approach inspired some of the key thinking behind this standard. +- Maker’s Teleport facility allows for minting and burning canonical DAI between domains. While the approach solves for the desirable properties above, it is highly custom to Maker’s architecture and relies on Maker’s own economic security to function. Circle CCTP similarly solves this problem, but using a mechanism that only centralized token issuers can implement. +- Token issuer multi-bridge implementations, e.g. Angle protocol, Frax Ferry, and Threshold Network’s tBTC. These examples solve for some or all of the above desiderata and can be applied more broadly to all tokens if coupled with minor additions for compatibility with existing deployed tokens. + +## Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. + +### Overview + +The system proposed below has two main components: + +- A standard interface for bridged tokens +- A wrapper (aka “Lockbox”) that allows existing tokens to adopt the above interface + +### Token Interface + +All xERC-20 tokens MUST implement the standard ERC-20 interface. Note that while many of the below functions are inspired by ERC777, implementers are NOT REQUIRED to adhere to the full ERC777 specification. + +All EIP-XX tokens MUST implement the following interface. + +```ts +interface IXERC-20 { + /** + * @notice Emits when a lockbox is set + * + * @param _lockbox The address of the lockbox + */ + + event LockboxSet(address _lockbox); + + /** + * @notice Emits when a limit is set + * + * @param _mintingLimit The updated minting limit we are setting to the bridge + * @param _burningLimit The updated burning limit we are setting to the bridge + * @param _bridge The address of the bridge we are setting the limit too + */ + + event BridgeLimitsSet(uint256 _mintingLimit, uint256 _burningLimit, address indexed _bridge); + + /** + * @notice Reverts when a user with too low of a limit tries to call mint/burn + */ + + error IXERC-20_NotHighEnoughLimits(); + + struct Bridge { + BridgeParameters minterParams; + BridgeParameters burnerParams; + } + + struct BridgeParameters { + uint256 timestamp; + uint256 ratePerSecond; + uint256 maxLimit; + uint256 currentLimit; + } + + /** + * @notice Sets the lockbox address + * + * @param _lockbox The address of the lockbox (0x0 if no lockbox) + */ + + function setLockbox(address _lockbox) external; + + /** + * @notice Updates the limits of any bridge + * @dev Can only be called by the owner + * @param _mintingLimit The updated minting limit we are setting to the bridge + * @param _burningLimit The updated burning limit we are setting to the bridge + * @param _bridge The address of the bridge we are setting the limits too + */ + function setLimits(address _bridge, uint256 _mintingLimit, uint256 _burningLimit) external; + + /** + * @notice Returns the max limit of a bridge + * + * @param _bridge The bridge we are viewing the limits of + * @return _limit The limit the bridge has + */ + function mintingMaxLimitOf(address _bridge) external view returns (uint256 _limit); + + /** + * @notice Returns the max limit of a bridge + * + * @param _bridge the bridge we are viewing the limits of + * @return _limit The limit the bridge has + */ + + function burningMaxLimitOf(address _bridge) external view returns (uint256 _limit); + + /** + * @notice Returns the current limit of a bridge + * + * @param _bridge The bridge we are viewing the limits of + * @return _limit The limit the bridge has + */ + + function mintingCurrentLimitOf(address _bridge) external view returns (uint256 _limit); + + /** + * @notice Returns the current limit of a bridge + * + * @param _bridge the bridge we are viewing the limits of + * @return _limit The limit the bridge has + */ + + function burningCurrentLimitOf(address _bridge) external view returns (uint256 _limit); + + /** + * @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; +} +``` + +Implementations MUST additionally satisfy the following requirements: +- `mint` MUST check that the caller's current available `limit` is greater than or equal to `_amount` +- `mint` MUST increase the supply of the underlying ERC-20 by `_amount` and reduce the current available `limit` +- `burn` MUST check that the caller's current available `limit` is greater than or equal to `_amount` +- `burn` MUST decrease the supply of the underlying ERC-20 by `_amount` and reduce the current available `limit` + +### Lockbox + +The lockbox tries to emulate the WETH contract interface as much as possible. Lockboxes MUST implement the following interface: + +```ts +interface IXERC-20Lockbox { + /** + * @notice Emitted when tokens are deposited into the lockbox + */ + + event Deposit(address _sender, uint256 _amount); + + /** + * @notice Emitted when tokens are withdrawn from the lockbox + */ + + event Withdraw(address _sender, uint256 _amount); + + /** + * @notice Reverts when a user tries to deposit native tokens on a non-native lockbox + */ + + error IXERC-20Lockbox_NotNative(); + + /** + * @notice Reverts when a user tries to deposit non-native tokens on a native lockbox + */ + + error IXERC-20Lockbox_Native(); + + /** + * @notice Reverts when a user tries to withdraw and the call fails + */ + + error IXERC-20Lockbox_WithdrawFailed(); + + /** + * @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; +} +``` + +Lockboxes SHOULD additionally implement the following alternative `deposit` function for native (non-ERC-20) assets. +```ts +/** + * @notice Deposit native assets (e.g. ETH) into the lockbox + */ + + function deposit() external payable; +``` + + +## Rationale + +The proposed standard attempts to satisfy the following conditions for bridged tokens regardless of where and how they are bridged: + +1. Tokens received at the destination should be the canonical tokens. +2. Bridges should not need to bootstrap liquidity for each new chain and asset. +3. Cross-domain interactions involving tokens should be slippage-free, simplifying composability. +4. Token issuers should own decision-making around which bridges to support and be able to parametrize risk for each. They should not be locked into only supporting a single bridge. + +### Fungibility + +The core problem that this standard tackles is the **fungibility** of tokens bridged across domains against the “canonical” token on that domain. (Note: which token is “canonical” is dictated by the token issuer and is sometimes, but not always, the token minted by a given domain’s enshrined bridge - e.g. a rollup bridge). + +![](../assets/eip-draft_bridged_tokens/fragmentation.png) + +It is not enough to simply allow multiple bridges to mint the same representation on a remote domain if liquidity is locked into bridges on the home domain. To illustrate this, consider an example where two bridges control minting rights of canonical USDT on an L2: + +- Alice bridges 100 USDT from L1→L2 through bridge 1. The underlying L1 USDT tokens is locked in bridge 1 and 100 USDT is minted on L2. +- Bob bridges 100 USDT from L1→L2 through bridge 2. Similar to the above case, the underlying L1 USDT tokens are locked in bridge 2 and 100 USDT is minted on L2. +- Suppose Alice pays Bob her 100 USDT. Bob now has 200 USDT. +- Bob attempts to bridge the 200 USDT from L2→L1 through bridge 2. This transaction fails, because bridge 2 only has 100 USDT custodied that it can give to Bob. + +The core property that this example illustrates is that locking tokens across multiple bridges on the token’s “home” domain makes it impossible to have fungibility without impeding user experience on remote domains. Minting or burning the token can solve this problem, but not all ERC-20 tokens implement a configurable mint/burn interface. + +### Lockbox + +This proposal specifically solves for the above problem in cases where tokens do not already have a mint/burn interface. Tokens on the source chain are locked into a Lockbox, which mints corresponding xERC-20-compatible tokens that can be sent to bridges. + +![](../assets/eip-draft_bridged_tokens/xERC-20.png) + +1. A given ERC-20 is wrapped into its xERC-20 representation. +2. The xERC-20 can then be transferred to any approved bridge. The bridge should check rate limits for the token and then `burn` the token. +3. On the target domain, the bridge then similarly `mint`s the token. +4. When transferring back to the home chain, the xERC-20 can be unwrapped back into the original ERC-20 token. + +Using this mechanism, the underlying ERC-20 token is consolidated to the Lockbox contract, and shared across all supported bridges. + +### Rate Limits + +A key consideration for consolidating home chain liquidity (and, by extension, allowing multiple bridges to mint the same representation) is the risk introduced due to the failure of any single bridge. In other words, there is a tradeoff space between fungibility (i.e. user experience) and security. + +The current best practice for limiting this risk is for issuers to enshrine a single bridge that mints the canonical representation on a given domain (this is often the rollup bridge, but we are increasingly seeing projects moving to proprietary/3rd party bridges citing liquidity and UX concerns). In this case, the token issuer fully trusts the enshrined bridge. Alternative bridges that want to support the token then must build liquidity for the token, where the risk to the token issuer of a given bridge’s failure is capped to the total liquidity locked in the bridge. + +The xERC-20 proposal attempts to mimic and improve upon this risk topology without the need for external liquidity. Instead of risk being capped by the locked tokens in a given (non-enshrined) bridge, risk is now capped by rate limits that are configurable on a per-bridge basis. This gives issuers granular control over their risk appetite as issuers can experiment with different bridges and adjust their confidence over time. Perhaps most importantly: this approach also encourages more open competition around security, as issuers no longer have to default to using only the most liquid or well-funded options. + +### Edge Case Considerations for Limits + +Minting and burning limits introduce failure modes that can impede UX. This is a necessary part of ensuring that bridge risk is compartmentalized and this standard assumes that implementers can work towards raising or altogether removing limits for bridges as they build confidence in them over time. + +Regardless of the above, the failure modes associated with rate limits generally map directly to **existing** failure modes around insufficient liquidity on bridges, and in many cases improve upon them. The two cases to consider here are: + +1. Hitting burn limits on the source chain. This case is hit when a given bridge has capped its limit on burning tokens, causing a revert of the transaction that included a call to the bridge. + 1. In the current liquidity-bridging model, bridges will typically have no way to know upfront if they have sufficient liquidity on the target chain for a given transaction. This means that a limit-based approach (where the transaction **fails fast**) is a significant improvement to UX. +2. Hitting minting limits on the destination chain. This case can be hit *after* tokens are burned on the source chain in cases where many different minting transactions are simultaneously triggered on a given destination domain and bridge combination, leading to the bridge’s limit being saturated. + 1. This problem exists in the current model if there is insufficient liquidity on the destination for a given bridge to complete a transaction within some defined slippage constraints. This case is not well-handled by bridges at the moment. Bridges are forced to either output some wrapped representation, or force users to wait until there is more liquidity. + 2. In the limit-based approach, the bridge will similarly not be able to complete the transaction on the destination domain until it has more capacity available. However, a limit approach provides some more reasonable guarantees to the user: (1) user have a much higher degree of predictability around time and pricing of the outputted transaction, (2) users would not receive some wrapped representation, and (3) bridges would have a simpler pathway for users to send the tokens back to the source domain or any other destination. + +### Aggregation +EIP-7281 introduces new dynamics for aggregators that massively improve user safety and experience across chains. + +There are two unsolved mechanism design problems that currently exist around bridge aggregation: +1. Bridge aggregators primarily compare bridges based on price, which itself is a function of the gas costs needed to use a given bridge and the slippage due to liquidity on that bridge. Competing solely on price heavily favors (a) bridges that take a more custodial/centralized approach to cut costs, and (b) bridges that are willing and able to spend lots of capital on liquidity incentives. This creates a system of incentives that penalizes security-minded approaches & open competition. +2. Bridge aggregators tap into liquidity from DEX aggregators at the source and destination chains. To do this effectively, they need to query DEX aggregators to get a quote for a destination chain swap, *before they initiate the transaction on the source chain*. However, because liquidity-based bridges introduce slippage on crosschain transfers, there is no way for bridge aggregators to know *up front* how many tokens would be received on the destination. Aggregators currently get around this problem by defaulting to some maximum slippage (or minimum amount received) passed into the underlying bridge protocol - this means that users *always* lose 1%-3% of their value when bridging regardless of how much liquidity is available on a bridge. + +With EIP-7281, the above problems are solved elegantly: +1. Because xERC-20s are able to be transferred 1:1 across chains (i.e. they have uniform pricing), aggregators are largely incentivized to route xERC-20 transfers based on *available limits* for a given asset (as transferring over a bridge with insufficient limits would result in a negative experience for their users). In other words, aggregators now route based on a **token-issuer-defined** metric of the perceived security of a given bridge. This radically improves the incentives around secure bridge development, pushing bridges to optimize for security in order to receive the highest possible rate limits for a given token. Perhaps most importantly, this definition of security is sovereign to the token issuer, eliminating the need for aggregators, chains, or other ecosystem actors be "central planners" on determining a given bridge's security model. +2. With slippage-free xERC-20 transfers, aggregators can know precisely how many tokens will get bridged across chains, eliminating headaches and custom code around sourcing destination-chain liquidity from DEXes. This massively improves pricing for users and composability for developers who want to build across chains. + + +## Backwards Compatibility + +This proposal is fully backwards compatible with ERC-20. + +Aside from the above, the following compatibility vectors were considered when designing this proposal: + +- Compatibility with existing/deployed tokens +- Compatibility with canonical & 3rd party bridges + +### Compatibility with Deployed Tokens + +There are three states that token issuers begin with when migrating to xERC-20s: + +1. The token does not exist yet OR is upgradeable/controlled by the issuer on each supported domain. +2. The token is deployed to a single home domain but not others yet. +3. The token is deployed and/or bridged to multiple domains + +The proposed xERC-20 standard solves for (1) out of the box - token issuers should simply deploy xERC-20 interface-compatible tokens on all domains they wish to support with no lockbox needed. + +Case (2) is straightforward to solve with xERC-20s as well. Token issuers should deploy a lockbox on their home chain, and then wrap their ERC-20s into xERC-20s prior to bridging them. This wrapping step may add some friction depending on the bridge - this is discussed further in the Compatibility with Bridges section. + +Case (3) is the most challenging to solve for as issuers may not have sovereign control over the “canonical” representation of the token on any remote domain and this necessitates a token migration of some form at least. As an example, tokens bridged using the default Arbitrum rollup bridge would be fully controlled by the rollup bridge. For these cases, we recommend the following migration path for issuers: + +1. Deploy a lockbox on the remote domain which locks the canonical-bridge-minted token and mints a new xERC-20. +2. Establish the new xERC-20 token as the canonical asset for the domain - this is largely a social consensus activity driven by DAO agreement and project communications. +3. Deploy a lockbox on the home domain which locks the home canonical token and mints a new xERC-20. +4. Allowlist all desired bridges *including* the canonical bridge that owns the legacy implementation, mapping the xERC-20 representation on the home domain to the xERC-20 representation on the remote. +5. At this point, it is fully possible for users to begin transferring the token across all bridges as would be expected from the xERC-20 standard. However, note that the canonical bridge connecting home to remote will now have two bridge paths: (a) ERC-20→ERC-20 (locking the ERC-20 at home), and (b) xERC-20→xERC-20. Now, the issuer can begin the process of sunsetting the legacy canonical ERC-20 on the remote domain. +6. The issuer should at this point disallow minting *new* legacy canonical ERC-20s on the remote domain and only allow users to bridge ERC-20s *back* to the home domain (by unwrapping xERC-20 on the remote). This would organically & gradually lead to the ERC-20 on the home chain becoming unlocked from the home<>remote canonical bridge, but token issuers can also incentivize this behavior if there is a desire for it to occur more quickly. + +### Compatibility with Bridges + +One key benefit to the xERC-20 model is that the simple requirement of a burn & mint interface makes this proposal compatible with most bridges either out of the box or through a predefined custom token mapping process. The following bridges & domains were considered in the creation of this proposal: + +- **3rd party bridges:** every 3rd party bridge that relies on messaging infrastructure already supports a mint and burn interface and has a pathway to map custom minted tokens. +- **Arbitrum rollup bridge:** Arbitrum allows token issuers to [write a custom gateway](https://developer.arbitrum.io/asset-bridging#other-flavors-of-gateways). +- **OP Stack bridge:** Optimism supports [adding a custom bridge](https://community.optimism.io/docs/guides/bridge-dev/#building-a-custom-bridge). +- **Polygon PoS bridge:** Polygon supports custom tokens [through their fx portal](https://wiki.polygon.technology/docs/develop/l1-l2-communication/fx-portal). +- **ZkSync bridge**: Zksync supports [custom bridges of any kind](https://era.zksync.io/docs/reference/concepts/bridging/bridging-asset.html#custom-bridges-on-l1-and-l2). +- **GnosisChain Omnibridge:** GnosisChain does not currently support custom tokens, but is in the process of redesigning their omnibridge and plans to allow this functionality. + +Note: In most of the above cases, a custom bridge integration also means integration into canonical bridge UIs, ensuring that users have a consistent experience throughout the process. Additionally, a single xERC-20 custom bridge implementation could be built for each ecosystem and serve any number of token issuers. + +## Reference Implementation + +You can find a reference implementation and associated test cases [here](https://github.com/defi-wonderland/xTokens/blob/dev/solidity/contracts/XERC-20.sol). + +## Security Considerations + +Please see the associated discussion in the **Rationale** section. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). diff --git a/ERCS/eip-draft_bridged_tokens.md b/ERCS/eip-draft_bridged_tokens.md index 832f45498e..ce4dd57c44 100644 --- a/ERCS/eip-draft_bridged_tokens.md +++ b/ERCS/eip-draft_bridged_tokens.md @@ -1,5 +1,6 @@ --- -title: Bridged Token Standard +eip: 7281 +title: Sovereign Bridged Token description: An interface for creating fungible representations of tokens bridged across domains. author: Shaito (@0xShaito), Excalibor (@excaliborr), Arjun Bhuptani (@arjunbhuptani) discussions-to: (TODO) @@ -12,11 +13,11 @@ requires: 20 ## Abstract -This proposal (affectionately called xERC20) defines a minimal extension to ERC-20 that enables bridging tokens across domains without creating multiple infungible representations of the same underlying asset. Token issuers can define which bridges are able to mint or burn the xERC20 on a given domain and configure rate limits for each allowed bridge. +This proposal defines a minimal extension to [ERC-20](../EIPS/eip-20.md) (affectionately called xERC-20) that enables bridging tokens across domains without creating multiple infungible representations of the same underlying asset. Token issuers can define which bridges are able to mint or burn the xERC-20 on a given domain and configure rate limits for each allowed bridge. ## Motivation -With the rapid proliferation of L2 domains, fungible token liquidity has become increasingly fragmented across domains. This, coupled with the need for projects to transfer tokens between chains faster than rollup exit windows, has meant that token issuers must choose from one of two options to bridge their tokens: +With the rapid proliferation of L2s, fungible token liquidity has become increasingly fragmented across domains. This, coupled with the need for projects to transfer tokens between chains faster than rollup exit windows, has meant that token issuers must choose from one of two options to bridge their tokens: 1. Bridge tokens through the “canonical” rollup bridge and work with atomic swap or fast-liquidity providers for L2→L1 or L2→L2 interactions. While this is the safer option, it necessitates significant requirements for issuers to incentivize or bootstrap liquidity on every supported chain, limiting support to only the most liquid of assets. Liquidity-based bridging additionally introduces slippage or other unpredictable pricing for users, hindering composability across domains. 2. Work with a 3rd party bridge. This option removes liquidity and pricing concerns making it more favorable for longer-tail issuers, but locks a given minted representation of a bridged token to only its associated bridge. This creates a tradeoff for issuers between security/sovereignty and user experience: If the token is bridged through only a single provider, the token supply and implementation is now fully and in perpetuity controlled by the bridge. If the token is bridged through multiple options (including "canonical" rollup bridges), multiple infungible (“wrapped”) representations of the same underlying asset are created on L2. @@ -32,7 +33,7 @@ There has been some previous work to solve this problem. However, solutions have - Celer’s Open Canonical Token Standard proposed a lock-in free standard for bridging tokens to new domains. However, it largely targeted alternative L1s (that don’t already have a canonical bridge) and did not fully solve the fungibility problem. Regardless, Celer’s approach inspired some of the key thinking behind this standard. - Maker’s Teleport facility allows for minting and burning canonical DAI between domains. While the approach solves for the desirable properties above, it is highly custom to Maker’s architecture and relies on Maker’s own economic security to function. Circle CCTP similarly solves this problem, but using a mechanism that only centralized token issuers can implement. -- Token issuer multi-bridge implementations, e.g. Angle protocol and Threshold Network’s tBTC. These examples solve for some or all of the above desiderata and can be applied more broadly to all tokens if coupled with minor additions for compatibility with existing deployed tokens. +- Token issuer multi-bridge implementations, e.g. Angle protocol, Frax Ferry, and Threshold Network’s tBTC. These examples solve for some or all of the above desiderata and can be applied more broadly to all tokens if coupled with minor additions for compatibility with existing deployed tokens. ## Specification @@ -47,12 +48,12 @@ The system proposed below has two main components: ### Token Interface -All xERC20 tokens MUST implement the standard ERC20 interface. Note that while many of the below functions are inspired by ERC777, implementers are NOT REQUIRED to adhere to the full ERC777 specification. +All xERC-20 tokens MUST implement the standard ERC-20 interface. Note that while many of the below functions are inspired by ERC777, implementers are NOT REQUIRED to adhere to the full ERC777 specification. All EIP-XX tokens MUST implement the following interface. ```ts -interface IXERC20 { +interface IXERC-20 { /** * @notice Emits when a lockbox is set * @@ -75,7 +76,7 @@ interface IXERC20 { * @notice Reverts when a user with too low of a limit tries to call mint/burn */ - error IXERC20_NotHighEnoughLimits(); + error IXERC-20_NotHighEnoughLimits(); struct Bridge { BridgeParameters minterParams; @@ -167,12 +168,12 @@ Implementations MUST additionally satisfy the following requirements: - `burn` MUST check that the caller's current available `limit` is greater than or equal to `_amount` - `burn` MUST decrease the supply of the underlying ERC-20 by `_amount` and reduce the current available `limit` -## Lockbox +### Lockbox The lockbox tries to emulate the WETH contract interface as much as possible. Lockboxes MUST implement the following interface: ```ts -interface IXERC20Lockbox { +interface IXERC-20Lockbox { /** * @notice Emitted when tokens are deposited into the lockbox */ @@ -189,22 +190,22 @@ interface IXERC20Lockbox { * @notice Reverts when a user tries to deposit native tokens on a non-native lockbox */ - error IXERC20Lockbox_NotNative(); + error IXERC-20Lockbox_NotNative(); /** * @notice Reverts when a user tries to deposit non-native tokens on a native lockbox */ - error IXERC20Lockbox_Native(); + error IXERC-20Lockbox_Native(); /** * @notice Reverts when a user tries to withdraw and the call fails */ - error IXERC20Lockbox_WithdrawFailed(); + error IXERC-20Lockbox_WithdrawFailed(); /** - * @notice Deposit ERC20 tokens into the lockbox + * @notice Deposit ERC-20 tokens into the lockbox * * @param _amount The amount of tokens to deposit */ @@ -212,7 +213,7 @@ interface IXERC20Lockbox { function deposit(uint256 _amount) external; /** - * @notice Withdraw ERC20 tokens from the lockbox + * @notice Withdraw ERC-20 tokens from the lockbox * * @param _amount The amount of tokens to withdraw */ @@ -221,7 +222,7 @@ interface IXERC20Lockbox { } ``` -Lockboxes SHOULD additionally implement the following alternative `deposit` function for native (non-ERC20) assets. +Lockboxes SHOULD additionally implement the following alternative `deposit` function for native (non-ERC-20) assets. ```ts /** * @notice Deposit native assets (e.g. ETH) into the lockbox @@ -242,7 +243,7 @@ The proposed standard attempts to satisfy the following conditions for bridged t ### Fungibility -The core problem that this standard tackles is the **********************fungibility********************** of tokens bridged across domains against the “canonical” token on that domain. (Note: which token is “canonical” is dictated by the token issuer and is sometimes, but not always, the token minted by a given domain’s enshrined bridge - e.g. a rollup bridge). +The core problem that this standard tackles is the **fungibility** of tokens bridged across domains against the “canonical” token on that domain. (Note: which token is “canonical” is dictated by the token issuer and is sometimes, but not always, the token minted by a given domain’s enshrined bridge - e.g. a rollup bridge). ![](../assets/eip-draft_bridged_tokens/fragmentation.png) @@ -253,20 +254,20 @@ It is not enough to simply allow multiple bridges to mint the same representatio - Suppose Alice pays Bob her 100 USDT. Bob now has 200 USDT. - Bob attempts to bridge the 200 USDT from L2→L1 through bridge 2. This transaction fails, because bridge 2 only has 100 USDT custodied that it can give to Bob. -The core property that this example illustrates is that locking tokens across multiple bridges on the token’s “home” domain makes it impossible to have fungibility without impeding user experience on remote domains. Minting or burning the token can solve this problem, but not all ERC20 tokens implement a configurable mint/burn interface. +The core property that this example illustrates is that locking tokens across multiple bridges on the token’s “home” domain makes it impossible to have fungibility without impeding user experience on remote domains. Minting or burning the token can solve this problem, but not all ERC-20 tokens implement a configurable mint/burn interface. ### Lockbox -This proposal specifically solves for the above problem in cases where tokens do not already have a mint/burn interface. Tokens on the source chain are locked into a Lockbox, which mints corresponding xERC20-compatible tokens that can be sent to bridges. +This proposal specifically solves for the above problem in cases where tokens do not already have a mint/burn interface. Tokens on the source chain are locked into a Lockbox, which mints corresponding xERC-20-compatible tokens that can be sent to bridges. -![](../assets/eip-draft_bridged_tokens/xERC20.png) +![](../assets/eip-draft_bridged_tokens/xERC-20.png) -1. A given ERC20 is wrapped into its xERC20 representation. -2. The xERC20 can then be transferred to any approved bridge. The bridge should check rate limits for the token and then `burn` the token. +1. A given ERC-20 is wrapped into its xERC-20 representation. +2. The xERC-20 can then be transferred to any approved bridge. The bridge should check rate limits for the token and then `burn` the token. 3. On the target domain, the bridge then similarly `mint`s the token. -4. When transferring back to the home chain, the xERC20 can be unwrapped back into the original ERC20 token. +4. When transferring back to the home chain, the xERC-20 can be unwrapped back into the original ERC-20 token. -Using this mechanism, the underlying ERC20 token is consolidated to the Lockbox contract, and shared across all supported bridges. +Using this mechanism, the underlying ERC-20 token is consolidated to the Lockbox contract, and shared across all supported bridges. ### Rate Limits @@ -274,7 +275,7 @@ A key consideration for consolidating home chain liquidity (and, by extension, a The current best practice for limiting this risk is for issuers to enshrine a single bridge that mints the canonical representation on a given domain (this is often the rollup bridge, but we are increasingly seeing projects moving to proprietary/3rd party bridges citing liquidity and UX concerns). In this case, the token issuer fully trusts the enshrined bridge. Alternative bridges that want to support the token then must build liquidity for the token, where the risk to the token issuer of a given bridge’s failure is capped to the total liquidity locked in the bridge. -The xERC20 proposal attempts to mimic and improve upon this risk topology without the need for external liquidity. Instead of risk being capped by the locked tokens in a given (non-enshrined) bridge, risk is now capped by rate limits that are configurable on a per-bridge basis. This gives issuers granular control over their risk appetite as issuers can experiment with different bridges and adjust their confidence over time. Perhaps most importantly: this approach also encourages more open competition around security, as issuers no longer have to default to using only the most liquid or well-funded options. +The xERC-20 proposal attempts to mimic and improve upon this risk topology without the need for external liquidity. Instead of risk being capped by the locked tokens in a given (non-enshrined) bridge, risk is now capped by rate limits that are configurable on a per-bridge basis. This gives issuers granular control over their risk appetite as issuers can experiment with different bridges and adjust their confidence over time. Perhaps most importantly: this approach also encourages more open competition around security, as issuers no longer have to default to using only the most liquid or well-funded options. ### Edge Case Considerations for Limits @@ -288,6 +289,18 @@ Regardless of the above, the failure modes associated with rate limits generally 1. This problem exists in the current model if there is insufficient liquidity on the destination for a given bridge to complete a transaction within some defined slippage constraints. This case is not well-handled by bridges at the moment. Bridges are forced to either output some wrapped representation, or force users to wait until there is more liquidity. 2. In the limit-based approach, the bridge will similarly not be able to complete the transaction on the destination domain until it has more capacity available. However, a limit approach provides some more reasonable guarantees to the user: (1) user have a much higher degree of predictability around time and pricing of the outputted transaction, (2) users would not receive some wrapped representation, and (3) bridges would have a simpler pathway for users to send the tokens back to the source domain or any other destination. +### Aggregation +EIP-7281 introduces new dynamics for aggregators that massively improve user safety and experience across chains. + +There are two unsolved mechanism design problems that currently exist around bridge aggregation: +1. Bridge aggregators primarily compare bridges based on price, which itself is a function of the gas costs needed to use a given bridge and the slippage due to liquidity on that bridge. Competing solely on price heavily favors (a) bridges that take a more custodial/centralized approach to cut costs, and (b) bridges that are willing and able to spend lots of capital on liquidity incentives. This creates a system of incentives that penalizes security-minded approaches & open competition. +2. Bridge aggregators tap into liquidity from DEX aggregators at the source and destination chains. To do this effectively, they need to query DEX aggregators to get a quote for a destination chain swap, *before they initiate the transaction on the source chain*. However, because liquidity-based bridges introduce slippage on crosschain transfers, there is no way for bridge aggregators to know *up front* how many tokens would be received on the destination. Aggregators currently get around this problem by defaulting to some maximum slippage (or minimum amount received) passed into the underlying bridge protocol - this means that users *always* lose 1%-3% of their value when bridging regardless of how much liquidity is available on a bridge. + +With EIP-7281, the above problems are solved elegantly: +1. Because xERC-20s are able to be transferred 1:1 across chains (i.e. they have uniform pricing), aggregators are largely incentivized to route xERC-20 transfers based on *available limits* for a given asset (as transferring over a bridge with insufficient limits would result in a negative experience for their users). In other words, aggregators now route based on a **token-issuer-defined** metric of the perceived security of a given bridge. This radically improves the incentives around secure bridge development, pushing bridges to optimize for security in order to receive the highest possible rate limits for a given token. Perhaps most importantly, this definition of security is sovereign to the token issuer, eliminating the need for aggregators, chains, or other ecosystem actors be "central planners" on determining a given bridge's security model. +2. With slippage-free xERC-20 transfers, aggregators can know precisely how many tokens will get bridged across chains, eliminating headaches and custom code around sourcing destination-chain liquidity from DEXes. This massively improves pricing for users and composability for developers who want to build across chains. + + ## Backwards Compatibility This proposal is fully backwards compatible with ERC-20. @@ -299,28 +312,28 @@ Aside from the above, the following compatibility vectors were considered when d ### Compatibility with Deployed Tokens -There are three states that token issuers begin with when migrating to xERC20s: +There are three states that token issuers begin with when migrating to xERC-20s: 1. The token does not exist yet OR is upgradeable/controlled by the issuer on each supported domain. 2. The token is deployed to a single home domain but not others yet. 3. The token is deployed and/or bridged to multiple domains -The proposed xERC20 standard solves for (1) out of the box - token issuers should simply deploy xERC20 interface-compatible tokens on all domains they wish to support with no lockbox needed. +The proposed xERC-20 standard solves for (1) out of the box - token issuers should simply deploy xERC-20 interface-compatible tokens on all domains they wish to support with no lockbox needed. -Case (2) is straightforward to solve with xERC20s as well. Token issuers should deploy a lockbox on their home chain, and then wrap their ERC20s into xERC20s prior to bridging them. This wrapping step may add some friction depending on the bridge - this is discussed further in the Compatibility with Bridges section. +Case (2) is straightforward to solve with xERC-20s as well. Token issuers should deploy a lockbox on their home chain, and then wrap their ERC-20s into xERC-20s prior to bridging them. This wrapping step may add some friction depending on the bridge - this is discussed further in the Compatibility with Bridges section. Case (3) is the most challenging to solve for as issuers may not have sovereign control over the “canonical” representation of the token on any remote domain and this necessitates a token migration of some form at least. As an example, tokens bridged using the default Arbitrum rollup bridge would be fully controlled by the rollup bridge. For these cases, we recommend the following migration path for issuers: -1. Deploy a lockbox on the remote domain which locks the canonical-bridge-minted token and mints a new xERC20. -2. Establish the new xERC20 token as the canonical asset for the domain - this is largely a social consensus activity driven by DAO agreement and project communications. -3. Deploy a lockbox on the home domain which locks the home canonical token and mints a new xERC20. -4. Allowlist all desired bridges *including* the canonical bridge that owns the legacy implementation, mapping the xERC20 representation on the home domain to the xERC20 representation on the remote. -5. At this point, it is fully possible for users to begin transferring the token across all bridges as would be expected from the xERC20 standard. However, note that the canonical bridge connecting home to remote will now have two bridge paths: (a) ERC20→ERC20 (locking the ERC20 at home), and (b) xERC20→xERC20. Now, the issuer can begin the process of sunsetting the legacy canonical ERC20 on the remote domain. -6. The issuer should at this point disallow minting *new* legacy canonical ERC20s on the remote domain and only allow users to bridge ERC20s *back* to the home domain (by unwrapping xERC20 on the remote). This would organically & gradually lead to the ERC20 on the home chain becoming unlocked from the home<>remote canonical bridge, but token issuers can also incentivize this behavior if there is a desire for it to occur more quickly. +1. Deploy a lockbox on the remote domain which locks the canonical-bridge-minted token and mints a new xERC-20. +2. Establish the new xERC-20 token as the canonical asset for the domain - this is largely a social consensus activity driven by DAO agreement and project communications. +3. Deploy a lockbox on the home domain which locks the home canonical token and mints a new xERC-20. +4. Allowlist all desired bridges *including* the canonical bridge that owns the legacy implementation, mapping the xERC-20 representation on the home domain to the xERC-20 representation on the remote. +5. At this point, it is fully possible for users to begin transferring the token across all bridges as would be expected from the xERC-20 standard. However, note that the canonical bridge connecting home to remote will now have two bridge paths: (a) ERC-20→ERC-20 (locking the ERC-20 at home), and (b) xERC-20→xERC-20. Now, the issuer can begin the process of sunsetting the legacy canonical ERC-20 on the remote domain. +6. The issuer should at this point disallow minting *new* legacy canonical ERC-20s on the remote domain and only allow users to bridge ERC-20s *back* to the home domain (by unwrapping xERC-20 on the remote). This would organically & gradually lead to the ERC-20 on the home chain becoming unlocked from the home<>remote canonical bridge, but token issuers can also incentivize this behavior if there is a desire for it to occur more quickly. ### Compatibility with Bridges -One key benefit to the xERC20 model is that the simple requirement of a burn & mint interface makes this proposal compatible with most bridges either out of the box or through a predefined custom token mapping process. The following bridges & domains were considered in the creation of this proposal: +One key benefit to the xERC-20 model is that the simple requirement of a burn & mint interface makes this proposal compatible with most bridges either out of the box or through a predefined custom token mapping process. The following bridges & domains were considered in the creation of this proposal: - **3rd party bridges:** every 3rd party bridge that relies on messaging infrastructure already supports a mint and burn interface and has a pathway to map custom minted tokens. - **Arbitrum rollup bridge:** Arbitrum allows token issuers to [write a custom gateway](https://developer.arbitrum.io/asset-bridging#other-flavors-of-gateways). @@ -329,11 +342,11 @@ One key benefit to the xERC20 model is that the simple requirement of a burn & m - **ZkSync bridge**: Zksync supports [custom bridges of any kind](https://era.zksync.io/docs/reference/concepts/bridging/bridging-asset.html#custom-bridges-on-l1-and-l2). - **GnosisChain Omnibridge:** GnosisChain does not currently support custom tokens, but is in the process of redesigning their omnibridge and plans to allow this functionality. -Note: In most of the above cases, a custom bridge integration also means integration into canonical bridge UIs, ensuring that users have a consistent experience throughout the process. Additionally, a single xERC20 custom bridge implementation could be built for each ecosystem and serve any number of token issuers. +Note: In most of the above cases, a custom bridge integration also means integration into canonical bridge UIs, ensuring that users have a consistent experience throughout the process. Additionally, a single xERC-20 custom bridge implementation could be built for each ecosystem and serve any number of token issuers. ## Reference Implementation -You can find a reference implementation and associated test cases [here](https://github.com/defi-wonderland/xTokens/blob/dev/solidity/contracts/XERC20.sol). +You can find a reference implementation and associated test cases [here](https://github.com/defi-wonderland/xTokens/blob/dev/solidity/contracts/XERC-20.sol). ## Security Considerations From 0f9cca8703085e5e10cf03e648d6e33aea546ffe Mon Sep 17 00:00:00 2001 From: Arjun Bhuptani Date: Tue, 18 Jul 2023 17:23:56 +0100 Subject: [PATCH 06/16] improve migration path spec --- ERCS/eip-7281.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ERCS/eip-7281.md b/ERCS/eip-7281.md index ce4dd57c44..f1d0bbbcfb 100644 --- a/ERCS/eip-7281.md +++ b/ERCS/eip-7281.md @@ -329,7 +329,8 @@ Case (3) is the most challenging to solve for as issuers may not have sovereign 3. Deploy a lockbox on the home domain which locks the home canonical token and mints a new xERC-20. 4. Allowlist all desired bridges *including* the canonical bridge that owns the legacy implementation, mapping the xERC-20 representation on the home domain to the xERC-20 representation on the remote. 5. At this point, it is fully possible for users to begin transferring the token across all bridges as would be expected from the xERC-20 standard. However, note that the canonical bridge connecting home to remote will now have two bridge paths: (a) ERC-20→ERC-20 (locking the ERC-20 at home), and (b) xERC-20→xERC-20. Now, the issuer can begin the process of sunsetting the legacy canonical ERC-20 on the remote domain. -6. The issuer should at this point disallow minting *new* legacy canonical ERC-20s on the remote domain and only allow users to bridge ERC-20s *back* to the home domain (by unwrapping xERC-20 on the remote). This would organically & gradually lead to the ERC-20 on the home chain becoming unlocked from the home<>remote canonical bridge, but token issuers can also incentivize this behavior if there is a desire for it to occur more quickly. +6. The issuer should at this point disallow minting *new* legacy canonical ERC-20s on the remote domain. This would organically & gradually lead to the legacy ERC-20s on the remote chain to become locked into the lockbox. +7. At any point in the future, the token issuer can then use their own treasury to unwrap xERC-20s on the remote domain into legacy ERC-20s and send them back to the home chain, incurring the latency of this on behalf of users. ### Compatibility with Bridges From d1d8945b4b4ebb5e87f50b9c7cce270320c94e56 Mon Sep 17 00:00:00 2001 From: just-a-node Date: Fri, 3 Nov 2023 11:50:37 -0600 Subject: [PATCH 07/16] Remove draft --- ERCS/eip-draft_bridged_tokens.md | 357 ------------------------------- 1 file changed, 357 deletions(-) delete mode 100644 ERCS/eip-draft_bridged_tokens.md diff --git a/ERCS/eip-draft_bridged_tokens.md b/ERCS/eip-draft_bridged_tokens.md deleted file mode 100644 index ce4dd57c44..0000000000 --- a/ERCS/eip-draft_bridged_tokens.md +++ /dev/null @@ -1,357 +0,0 @@ ---- -eip: 7281 -title: Sovereign Bridged Token -description: An interface for creating fungible representations of tokens bridged across domains. -author: Shaito (@0xShaito), Excalibor (@excaliborr), Arjun Bhuptani (@arjunbhuptani) -discussions-to: (TODO) -status: Draft -type: Standards Track -category: ERC -created: 2023-06-27 -requires: 20 ---- - -## Abstract - -This proposal defines a minimal extension to [ERC-20](../EIPS/eip-20.md) (affectionately called xERC-20) that enables bridging tokens across domains without creating multiple infungible representations of the same underlying asset. Token issuers can define which bridges are able to mint or burn the xERC-20 on a given domain and configure rate limits for each allowed bridge. - -## Motivation - -With the rapid proliferation of L2s, fungible token liquidity has become increasingly fragmented across domains. This, coupled with the need for projects to transfer tokens between chains faster than rollup exit windows, has meant that token issuers must choose from one of two options to bridge their tokens: - -1. Bridge tokens through the “canonical” rollup bridge and work with atomic swap or fast-liquidity providers for L2→L1 or L2→L2 interactions. While this is the safer option, it necessitates significant requirements for issuers to incentivize or bootstrap liquidity on every supported chain, limiting support to only the most liquid of assets. Liquidity-based bridging additionally introduces slippage or other unpredictable pricing for users, hindering composability across domains. -2. Work with a 3rd party bridge. This option removes liquidity and pricing concerns making it more favorable for longer-tail issuers, but locks a given minted representation of a bridged token to only its associated bridge. This creates a tradeoff for issuers between security/sovereignty and user experience: If the token is bridged through only a single provider, the token supply and implementation is now fully and in perpetuity controlled by the bridge. If the token is bridged through multiple options (including "canonical" rollup bridges), multiple infungible (“wrapped”) representations of the same underlying asset are created on L2. - -In the ideal case, token issuers want the following properties for bridged representations of their tokens: - -- Sovereignty. Issuers want to be the logical owners of the canonical representation of their token on L2 and not be locked into any single specific option forever. -- Fungibility. Token issuers want a single “canonical” representation of their token on each L2, regardless of which bridges (canonical or otherwise) are supported by the issuer. -- Security. Issuers want to opt into novel secure bridging approaches as they are developed and have granular control over their risk tolerance for any given option. -- Minimal Liquidity. Issuers want to minimize the costs and complexity of acquiring liquidity for their token on each supported bridge and chain. This property becomes increasingly important as the space eventually expands to 100s or 1000s of connected domains. - -There has been some previous work to solve this problem. However, solutions have historically either failed to satisfy all of the above desirable properties or have been custom-built for only a single token ecosystem. - -- Celer’s Open Canonical Token Standard proposed a lock-in free standard for bridging tokens to new domains. However, it largely targeted alternative L1s (that don’t already have a canonical bridge) and did not fully solve the fungibility problem. Regardless, Celer’s approach inspired some of the key thinking behind this standard. -- Maker’s Teleport facility allows for minting and burning canonical DAI between domains. While the approach solves for the desirable properties above, it is highly custom to Maker’s architecture and relies on Maker’s own economic security to function. Circle CCTP similarly solves this problem, but using a mechanism that only centralized token issuers can implement. -- Token issuer multi-bridge implementations, e.g. Angle protocol, Frax Ferry, and Threshold Network’s tBTC. These examples solve for some or all of the above desiderata and can be applied more broadly to all tokens if coupled with minor additions for compatibility with existing deployed tokens. - -## Specification - -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. - -### Overview - -The system proposed below has two main components: - -- A standard interface for bridged tokens -- A wrapper (aka “Lockbox”) that allows existing tokens to adopt the above interface - -### Token Interface - -All xERC-20 tokens MUST implement the standard ERC-20 interface. Note that while many of the below functions are inspired by ERC777, implementers are NOT REQUIRED to adhere to the full ERC777 specification. - -All EIP-XX tokens MUST implement the following interface. - -```ts -interface IXERC-20 { - /** - * @notice Emits when a lockbox is set - * - * @param _lockbox The address of the lockbox - */ - - event LockboxSet(address _lockbox); - - /** - * @notice Emits when a limit is set - * - * @param _mintingLimit The updated minting limit we are setting to the bridge - * @param _burningLimit The updated burning limit we are setting to the bridge - * @param _bridge The address of the bridge we are setting the limit too - */ - - event BridgeLimitsSet(uint256 _mintingLimit, uint256 _burningLimit, address indexed _bridge); - - /** - * @notice Reverts when a user with too low of a limit tries to call mint/burn - */ - - error IXERC-20_NotHighEnoughLimits(); - - struct Bridge { - BridgeParameters minterParams; - BridgeParameters burnerParams; - } - - struct BridgeParameters { - uint256 timestamp; - uint256 ratePerSecond; - uint256 maxLimit; - uint256 currentLimit; - } - - /** - * @notice Sets the lockbox address - * - * @param _lockbox The address of the lockbox (0x0 if no lockbox) - */ - - function setLockbox(address _lockbox) external; - - /** - * @notice Updates the limits of any bridge - * @dev Can only be called by the owner - * @param _mintingLimit The updated minting limit we are setting to the bridge - * @param _burningLimit The updated burning limit we are setting to the bridge - * @param _bridge The address of the bridge we are setting the limits too - */ - function setLimits(address _bridge, uint256 _mintingLimit, uint256 _burningLimit) external; - - /** - * @notice Returns the max limit of a bridge - * - * @param _bridge The bridge we are viewing the limits of - * @return _limit The limit the bridge has - */ - function mintingMaxLimitOf(address _bridge) external view returns (uint256 _limit); - - /** - * @notice Returns the max limit of a bridge - * - * @param _bridge the bridge we are viewing the limits of - * @return _limit The limit the bridge has - */ - - function burningMaxLimitOf(address _bridge) external view returns (uint256 _limit); - - /** - * @notice Returns the current limit of a bridge - * - * @param _bridge The bridge we are viewing the limits of - * @return _limit The limit the bridge has - */ - - function mintingCurrentLimitOf(address _bridge) external view returns (uint256 _limit); - - /** - * @notice Returns the current limit of a bridge - * - * @param _bridge the bridge we are viewing the limits of - * @return _limit The limit the bridge has - */ - - function burningCurrentLimitOf(address _bridge) external view returns (uint256 _limit); - - /** - * @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; -} -``` - -Implementations MUST additionally satisfy the following requirements: -- `mint` MUST check that the caller's current available `limit` is greater than or equal to `_amount` -- `mint` MUST increase the supply of the underlying ERC-20 by `_amount` and reduce the current available `limit` -- `burn` MUST check that the caller's current available `limit` is greater than or equal to `_amount` -- `burn` MUST decrease the supply of the underlying ERC-20 by `_amount` and reduce the current available `limit` - -### Lockbox - -The lockbox tries to emulate the WETH contract interface as much as possible. Lockboxes MUST implement the following interface: - -```ts -interface IXERC-20Lockbox { - /** - * @notice Emitted when tokens are deposited into the lockbox - */ - - event Deposit(address _sender, uint256 _amount); - - /** - * @notice Emitted when tokens are withdrawn from the lockbox - */ - - event Withdraw(address _sender, uint256 _amount); - - /** - * @notice Reverts when a user tries to deposit native tokens on a non-native lockbox - */ - - error IXERC-20Lockbox_NotNative(); - - /** - * @notice Reverts when a user tries to deposit non-native tokens on a native lockbox - */ - - error IXERC-20Lockbox_Native(); - - /** - * @notice Reverts when a user tries to withdraw and the call fails - */ - - error IXERC-20Lockbox_WithdrawFailed(); - - /** - * @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; -} -``` - -Lockboxes SHOULD additionally implement the following alternative `deposit` function for native (non-ERC-20) assets. -```ts -/** - * @notice Deposit native assets (e.g. ETH) into the lockbox - */ - - function deposit() external payable; -``` - - -## Rationale - -The proposed standard attempts to satisfy the following conditions for bridged tokens regardless of where and how they are bridged: - -1. Tokens received at the destination should be the canonical tokens. -2. Bridges should not need to bootstrap liquidity for each new chain and asset. -3. Cross-domain interactions involving tokens should be slippage-free, simplifying composability. -4. Token issuers should own decision-making around which bridges to support and be able to parametrize risk for each. They should not be locked into only supporting a single bridge. - -### Fungibility - -The core problem that this standard tackles is the **fungibility** of tokens bridged across domains against the “canonical” token on that domain. (Note: which token is “canonical” is dictated by the token issuer and is sometimes, but not always, the token minted by a given domain’s enshrined bridge - e.g. a rollup bridge). - -![](../assets/eip-draft_bridged_tokens/fragmentation.png) - -It is not enough to simply allow multiple bridges to mint the same representation on a remote domain if liquidity is locked into bridges on the home domain. To illustrate this, consider an example where two bridges control minting rights of canonical USDT on an L2: - -- Alice bridges 100 USDT from L1→L2 through bridge 1. The underlying L1 USDT tokens is locked in bridge 1 and 100 USDT is minted on L2. -- Bob bridges 100 USDT from L1→L2 through bridge 2. Similar to the above case, the underlying L1 USDT tokens are locked in bridge 2 and 100 USDT is minted on L2. -- Suppose Alice pays Bob her 100 USDT. Bob now has 200 USDT. -- Bob attempts to bridge the 200 USDT from L2→L1 through bridge 2. This transaction fails, because bridge 2 only has 100 USDT custodied that it can give to Bob. - -The core property that this example illustrates is that locking tokens across multiple bridges on the token’s “home” domain makes it impossible to have fungibility without impeding user experience on remote domains. Minting or burning the token can solve this problem, but not all ERC-20 tokens implement a configurable mint/burn interface. - -### Lockbox - -This proposal specifically solves for the above problem in cases where tokens do not already have a mint/burn interface. Tokens on the source chain are locked into a Lockbox, which mints corresponding xERC-20-compatible tokens that can be sent to bridges. - -![](../assets/eip-draft_bridged_tokens/xERC-20.png) - -1. A given ERC-20 is wrapped into its xERC-20 representation. -2. The xERC-20 can then be transferred to any approved bridge. The bridge should check rate limits for the token and then `burn` the token. -3. On the target domain, the bridge then similarly `mint`s the token. -4. When transferring back to the home chain, the xERC-20 can be unwrapped back into the original ERC-20 token. - -Using this mechanism, the underlying ERC-20 token is consolidated to the Lockbox contract, and shared across all supported bridges. - -### Rate Limits - -A key consideration for consolidating home chain liquidity (and, by extension, allowing multiple bridges to mint the same representation) is the risk introduced due to the failure of any single bridge. In other words, there is a tradeoff space between fungibility (i.e. user experience) and security. - -The current best practice for limiting this risk is for issuers to enshrine a single bridge that mints the canonical representation on a given domain (this is often the rollup bridge, but we are increasingly seeing projects moving to proprietary/3rd party bridges citing liquidity and UX concerns). In this case, the token issuer fully trusts the enshrined bridge. Alternative bridges that want to support the token then must build liquidity for the token, where the risk to the token issuer of a given bridge’s failure is capped to the total liquidity locked in the bridge. - -The xERC-20 proposal attempts to mimic and improve upon this risk topology without the need for external liquidity. Instead of risk being capped by the locked tokens in a given (non-enshrined) bridge, risk is now capped by rate limits that are configurable on a per-bridge basis. This gives issuers granular control over their risk appetite as issuers can experiment with different bridges and adjust their confidence over time. Perhaps most importantly: this approach also encourages more open competition around security, as issuers no longer have to default to using only the most liquid or well-funded options. - -### Edge Case Considerations for Limits - -Minting and burning limits introduce failure modes that can impede UX. This is a necessary part of ensuring that bridge risk is compartmentalized and this standard assumes that implementers can work towards raising or altogether removing limits for bridges as they build confidence in them over time. - -Regardless of the above, the failure modes associated with rate limits generally map directly to **existing** failure modes around insufficient liquidity on bridges, and in many cases improve upon them. The two cases to consider here are: - -1. Hitting burn limits on the source chain. This case is hit when a given bridge has capped its limit on burning tokens, causing a revert of the transaction that included a call to the bridge. - 1. In the current liquidity-bridging model, bridges will typically have no way to know upfront if they have sufficient liquidity on the target chain for a given transaction. This means that a limit-based approach (where the transaction **fails fast**) is a significant improvement to UX. -2. Hitting minting limits on the destination chain. This case can be hit *after* tokens are burned on the source chain in cases where many different minting transactions are simultaneously triggered on a given destination domain and bridge combination, leading to the bridge’s limit being saturated. - 1. This problem exists in the current model if there is insufficient liquidity on the destination for a given bridge to complete a transaction within some defined slippage constraints. This case is not well-handled by bridges at the moment. Bridges are forced to either output some wrapped representation, or force users to wait until there is more liquidity. - 2. In the limit-based approach, the bridge will similarly not be able to complete the transaction on the destination domain until it has more capacity available. However, a limit approach provides some more reasonable guarantees to the user: (1) user have a much higher degree of predictability around time and pricing of the outputted transaction, (2) users would not receive some wrapped representation, and (3) bridges would have a simpler pathway for users to send the tokens back to the source domain or any other destination. - -### Aggregation -EIP-7281 introduces new dynamics for aggregators that massively improve user safety and experience across chains. - -There are two unsolved mechanism design problems that currently exist around bridge aggregation: -1. Bridge aggregators primarily compare bridges based on price, which itself is a function of the gas costs needed to use a given bridge and the slippage due to liquidity on that bridge. Competing solely on price heavily favors (a) bridges that take a more custodial/centralized approach to cut costs, and (b) bridges that are willing and able to spend lots of capital on liquidity incentives. This creates a system of incentives that penalizes security-minded approaches & open competition. -2. Bridge aggregators tap into liquidity from DEX aggregators at the source and destination chains. To do this effectively, they need to query DEX aggregators to get a quote for a destination chain swap, *before they initiate the transaction on the source chain*. However, because liquidity-based bridges introduce slippage on crosschain transfers, there is no way for bridge aggregators to know *up front* how many tokens would be received on the destination. Aggregators currently get around this problem by defaulting to some maximum slippage (or minimum amount received) passed into the underlying bridge protocol - this means that users *always* lose 1%-3% of their value when bridging regardless of how much liquidity is available on a bridge. - -With EIP-7281, the above problems are solved elegantly: -1. Because xERC-20s are able to be transferred 1:1 across chains (i.e. they have uniform pricing), aggregators are largely incentivized to route xERC-20 transfers based on *available limits* for a given asset (as transferring over a bridge with insufficient limits would result in a negative experience for their users). In other words, aggregators now route based on a **token-issuer-defined** metric of the perceived security of a given bridge. This radically improves the incentives around secure bridge development, pushing bridges to optimize for security in order to receive the highest possible rate limits for a given token. Perhaps most importantly, this definition of security is sovereign to the token issuer, eliminating the need for aggregators, chains, or other ecosystem actors be "central planners" on determining a given bridge's security model. -2. With slippage-free xERC-20 transfers, aggregators can know precisely how many tokens will get bridged across chains, eliminating headaches and custom code around sourcing destination-chain liquidity from DEXes. This massively improves pricing for users and composability for developers who want to build across chains. - - -## Backwards Compatibility - -This proposal is fully backwards compatible with ERC-20. - -Aside from the above, the following compatibility vectors were considered when designing this proposal: - -- Compatibility with existing/deployed tokens -- Compatibility with canonical & 3rd party bridges - -### Compatibility with Deployed Tokens - -There are three states that token issuers begin with when migrating to xERC-20s: - -1. The token does not exist yet OR is upgradeable/controlled by the issuer on each supported domain. -2. The token is deployed to a single home domain but not others yet. -3. The token is deployed and/or bridged to multiple domains - -The proposed xERC-20 standard solves for (1) out of the box - token issuers should simply deploy xERC-20 interface-compatible tokens on all domains they wish to support with no lockbox needed. - -Case (2) is straightforward to solve with xERC-20s as well. Token issuers should deploy a lockbox on their home chain, and then wrap their ERC-20s into xERC-20s prior to bridging them. This wrapping step may add some friction depending on the bridge - this is discussed further in the Compatibility with Bridges section. - -Case (3) is the most challenging to solve for as issuers may not have sovereign control over the “canonical” representation of the token on any remote domain and this necessitates a token migration of some form at least. As an example, tokens bridged using the default Arbitrum rollup bridge would be fully controlled by the rollup bridge. For these cases, we recommend the following migration path for issuers: - -1. Deploy a lockbox on the remote domain which locks the canonical-bridge-minted token and mints a new xERC-20. -2. Establish the new xERC-20 token as the canonical asset for the domain - this is largely a social consensus activity driven by DAO agreement and project communications. -3. Deploy a lockbox on the home domain which locks the home canonical token and mints a new xERC-20. -4. Allowlist all desired bridges *including* the canonical bridge that owns the legacy implementation, mapping the xERC-20 representation on the home domain to the xERC-20 representation on the remote. -5. At this point, it is fully possible for users to begin transferring the token across all bridges as would be expected from the xERC-20 standard. However, note that the canonical bridge connecting home to remote will now have two bridge paths: (a) ERC-20→ERC-20 (locking the ERC-20 at home), and (b) xERC-20→xERC-20. Now, the issuer can begin the process of sunsetting the legacy canonical ERC-20 on the remote domain. -6. The issuer should at this point disallow minting *new* legacy canonical ERC-20s on the remote domain and only allow users to bridge ERC-20s *back* to the home domain (by unwrapping xERC-20 on the remote). This would organically & gradually lead to the ERC-20 on the home chain becoming unlocked from the home<>remote canonical bridge, but token issuers can also incentivize this behavior if there is a desire for it to occur more quickly. - -### Compatibility with Bridges - -One key benefit to the xERC-20 model is that the simple requirement of a burn & mint interface makes this proposal compatible with most bridges either out of the box or through a predefined custom token mapping process. The following bridges & domains were considered in the creation of this proposal: - -- **3rd party bridges:** every 3rd party bridge that relies on messaging infrastructure already supports a mint and burn interface and has a pathway to map custom minted tokens. -- **Arbitrum rollup bridge:** Arbitrum allows token issuers to [write a custom gateway](https://developer.arbitrum.io/asset-bridging#other-flavors-of-gateways). -- **OP Stack bridge:** Optimism supports [adding a custom bridge](https://community.optimism.io/docs/guides/bridge-dev/#building-a-custom-bridge). -- **Polygon PoS bridge:** Polygon supports custom tokens [through their fx portal](https://wiki.polygon.technology/docs/develop/l1-l2-communication/fx-portal). -- **ZkSync bridge**: Zksync supports [custom bridges of any kind](https://era.zksync.io/docs/reference/concepts/bridging/bridging-asset.html#custom-bridges-on-l1-and-l2). -- **GnosisChain Omnibridge:** GnosisChain does not currently support custom tokens, but is in the process of redesigning their omnibridge and plans to allow this functionality. - -Note: In most of the above cases, a custom bridge integration also means integration into canonical bridge UIs, ensuring that users have a consistent experience throughout the process. Additionally, a single xERC-20 custom bridge implementation could be built for each ecosystem and serve any number of token issuers. - -## Reference Implementation - -You can find a reference implementation and associated test cases [here](https://github.com/defi-wonderland/xTokens/blob/dev/solidity/contracts/XERC-20.sol). - -## Security Considerations - -Please see the associated discussion in the **Rationale** section. - -## Copyright - -Copyright and related rights waived via [CC0](../LICENSE.md). From a9b1ece5f3da68a893c0ecec303f67123bc4ebee Mon Sep 17 00:00:00 2001 From: just-a-node Date: Fri, 3 Nov 2023 11:55:58 -0600 Subject: [PATCH 08/16] Fix syntax errors for formatter --- ERCS/eip-7281.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/ERCS/eip-7281.md b/ERCS/eip-7281.md index f1d0bbbcfb..0c639db801 100644 --- a/ERCS/eip-7281.md +++ b/ERCS/eip-7281.md @@ -3,7 +3,7 @@ eip: 7281 title: Sovereign Bridged Token description: An interface for creating fungible representations of tokens bridged across domains. author: Shaito (@0xShaito), Excalibor (@excaliborr), Arjun Bhuptani (@arjunbhuptani) -discussions-to: (TODO) +discussions-to: https://ethereum-magicians.org/t/erc-7281-sovereign-bridged-tokens/14979 status: Draft type: Standards Track category: ERC @@ -48,7 +48,7 @@ The system proposed below has two main components: ### Token Interface -All xERC-20 tokens MUST implement the standard ERC-20 interface. Note that while many of the below functions are inspired by ERC777, implementers are NOT REQUIRED to adhere to the full ERC777 specification. +All xERC-20 tokens MUST implement the standard ERC-20 interface. Note that while many of the below functions are inspired by ERC-777, implementers are NOT REQUIRED to adhere to the full ERC-777 specification. All EIP-XX tokens MUST implement the following interface. @@ -76,7 +76,7 @@ interface IXERC-20 { * @notice Reverts when a user with too low of a limit tries to call mint/burn */ - error IXERC-20_NotHighEnoughLimits(); + error IXERC20_NotHighEnoughLimits(); struct Bridge { BridgeParameters minterParams; @@ -163,6 +163,7 @@ interface IXERC-20 { ``` Implementations MUST additionally satisfy the following requirements: + - `mint` MUST check that the caller's current available `limit` is greater than or equal to `_amount` - `mint` MUST increase the supply of the underlying ERC-20 by `_amount` and reduce the current available `limit` - `burn` MUST check that the caller's current available `limit` is greater than or equal to `_amount` @@ -173,7 +174,7 @@ Implementations MUST additionally satisfy the following requirements: The lockbox tries to emulate the WETH contract interface as much as possible. Lockboxes MUST implement the following interface: ```ts -interface IXERC-20Lockbox { +interface IXERC20Lockbox { /** * @notice Emitted when tokens are deposited into the lockbox */ @@ -190,13 +191,13 @@ interface IXERC-20Lockbox { * @notice Reverts when a user tries to deposit native tokens on a non-native lockbox */ - error IXERC-20Lockbox_NotNative(); + error IXERC20Lockbox_NotNative(); /** * @notice Reverts when a user tries to deposit non-native tokens on a native lockbox */ - error IXERC-20Lockbox_Native(); + error IXERC20Lockbox_Native(); /** * @notice Reverts when a user tries to withdraw and the call fails @@ -223,6 +224,7 @@ interface IXERC-20Lockbox { ``` Lockboxes SHOULD additionally implement the following alternative `deposit` function for native (non-ERC-20) assets. + ```ts /** * @notice Deposit native assets (e.g. ETH) into the lockbox @@ -293,10 +295,12 @@ Regardless of the above, the failure modes associated with rate limits generally EIP-7281 introduces new dynamics for aggregators that massively improve user safety and experience across chains. There are two unsolved mechanism design problems that currently exist around bridge aggregation: + 1. Bridge aggregators primarily compare bridges based on price, which itself is a function of the gas costs needed to use a given bridge and the slippage due to liquidity on that bridge. Competing solely on price heavily favors (a) bridges that take a more custodial/centralized approach to cut costs, and (b) bridges that are willing and able to spend lots of capital on liquidity incentives. This creates a system of incentives that penalizes security-minded approaches & open competition. 2. Bridge aggregators tap into liquidity from DEX aggregators at the source and destination chains. To do this effectively, they need to query DEX aggregators to get a quote for a destination chain swap, *before they initiate the transaction on the source chain*. However, because liquidity-based bridges introduce slippage on crosschain transfers, there is no way for bridge aggregators to know *up front* how many tokens would be received on the destination. Aggregators currently get around this problem by defaulting to some maximum slippage (or minimum amount received) passed into the underlying bridge protocol - this means that users *always* lose 1%-3% of their value when bridging regardless of how much liquidity is available on a bridge. With EIP-7281, the above problems are solved elegantly: + 1. Because xERC-20s are able to be transferred 1:1 across chains (i.e. they have uniform pricing), aggregators are largely incentivized to route xERC-20 transfers based on *available limits* for a given asset (as transferring over a bridge with insufficient limits would result in a negative experience for their users). In other words, aggregators now route based on a **token-issuer-defined** metric of the perceived security of a given bridge. This radically improves the incentives around secure bridge development, pushing bridges to optimize for security in order to receive the highest possible rate limits for a given token. Perhaps most importantly, this definition of security is sovereign to the token issuer, eliminating the need for aggregators, chains, or other ecosystem actors be "central planners" on determining a given bridge's security model. 2. With slippage-free xERC-20 transfers, aggregators can know precisely how many tokens will get bridged across chains, eliminating headaches and custom code around sourcing destination-chain liquidity from DEXes. This massively improves pricing for users and composability for developers who want to build across chains. From 386de6ea676dab4c56185c86d8004b07249745e3 Mon Sep 17 00:00:00 2001 From: just-a-node Date: Sat, 17 Feb 2024 16:22:34 -0700 Subject: [PATCH 09/16] Address comments requiring non-material changes --- ERCS/eip-7281.md | 62 ++++++++---------- .../xERC20.png => eip-7281/XERC20.png} | Bin .../fragmentation.png | Bin 3 files changed, 29 insertions(+), 33 deletions(-) rename assets/{eip-draft_bridged_tokens/xERC20.png => eip-7281/XERC20.png} (100%) rename assets/{eip-draft_bridged_tokens => eip-7281}/fragmentation.png (100%) diff --git a/ERCS/eip-7281.md b/ERCS/eip-7281.md index 0c639db801..81f467469d 100644 --- a/ERCS/eip-7281.md +++ b/ERCS/eip-7281.md @@ -13,7 +13,7 @@ requires: 20 ## Abstract -This proposal defines a minimal extension to [ERC-20](../EIPS/eip-20.md) (affectionately called xERC-20) that enables bridging tokens across domains without creating multiple infungible representations of the same underlying asset. Token issuers can define which bridges are able to mint or burn the xERC-20 on a given domain and configure rate limits for each allowed bridge. +This proposal defines a minimal extension to [ERC-20](../EIPS/eip-20.md) (affectionately called XERC20) that enables bridging tokens across domains without creating multiple infungible representations of the same underlying asset. Token issuers can define which bridges are able to mint or burn the XERC20 on a given domain and configure rate limits for each allowed bridge. ## Motivation @@ -48,12 +48,12 @@ The system proposed below has two main components: ### Token Interface -All xERC-20 tokens MUST implement the standard ERC-20 interface. Note that while many of the below functions are inspired by ERC-777, implementers are NOT REQUIRED to adhere to the full ERC-777 specification. +All `XERC20` tokens MUST implement the standard ERC-20 interface. Note that while many of the below functions are inspired by ERC-777, implementers are NOT REQUIRED to adhere to the full ERC-777 specification. -All EIP-XX tokens MUST implement the following interface. +All `XERC20` tokens MUST implement the following interface. ```ts -interface IXERC-20 { +interface IXERC20 { /** * @notice Emits when a lockbox is set * @@ -203,7 +203,7 @@ interface IXERC20Lockbox { * @notice Reverts when a user tries to withdraw and the call fails */ - error IXERC-20Lockbox_WithdrawFailed(); + error IXERC20Lockbox_WithdrawFailed(); /** * @notice Deposit ERC-20 tokens into the lockbox @@ -260,14 +260,14 @@ The core property that this example illustrates is that locking tokens across mu ### Lockbox -This proposal specifically solves for the above problem in cases where tokens do not already have a mint/burn interface. Tokens on the source chain are locked into a Lockbox, which mints corresponding xERC-20-compatible tokens that can be sent to bridges. +This proposal specifically solves for the above problem in cases where tokens do not already have a mint/burn interface. Tokens on the source chain are locked into a Lockbox, which mints corresponding `XERC20`-compatible tokens that can be sent to bridges. -![](../assets/eip-draft_bridged_tokens/xERC-20.png) +![](../assets/eip-7291/XERC20.png) -1. A given ERC-20 is wrapped into its xERC-20 representation. -2. The xERC-20 can then be transferred to any approved bridge. The bridge should check rate limits for the token and then `burn` the token. +1. A given ERC-20 is wrapped into its `XERC20` representation. +2. The `XERC20` can then be transferred to any approved bridge. The bridge should check rate limits for the token and then `burn` the token. 3. On the target domain, the bridge then similarly `mint`s the token. -4. When transferring back to the home chain, the xERC-20 can be unwrapped back into the original ERC-20 token. +4. When transferring back to the home chain, the `XERC20` can be unwrapped back into the original ERC-20 token. Using this mechanism, the underlying ERC-20 token is consolidated to the Lockbox contract, and shared across all supported bridges. @@ -277,7 +277,7 @@ A key consideration for consolidating home chain liquidity (and, by extension, a The current best practice for limiting this risk is for issuers to enshrine a single bridge that mints the canonical representation on a given domain (this is often the rollup bridge, but we are increasingly seeing projects moving to proprietary/3rd party bridges citing liquidity and UX concerns). In this case, the token issuer fully trusts the enshrined bridge. Alternative bridges that want to support the token then must build liquidity for the token, where the risk to the token issuer of a given bridge’s failure is capped to the total liquidity locked in the bridge. -The xERC-20 proposal attempts to mimic and improve upon this risk topology without the need for external liquidity. Instead of risk being capped by the locked tokens in a given (non-enshrined) bridge, risk is now capped by rate limits that are configurable on a per-bridge basis. This gives issuers granular control over their risk appetite as issuers can experiment with different bridges and adjust their confidence over time. Perhaps most importantly: this approach also encourages more open competition around security, as issuers no longer have to default to using only the most liquid or well-funded options. +The `XERC20` proposal attempts to mimic and improve upon this risk topology without the need for external liquidity. Instead of risk being capped by the locked tokens in a given (non-enshrined) bridge, risk is now capped by rate limits that are configurable on a per-bridge basis. This gives issuers granular control over their risk appetite as issuers can experiment with different bridges and adjust their confidence over time. Perhaps most importantly: this approach also encourages more open competition around security, as issuers no longer have to default to using only the most liquid or well-funded options. ### Edge Case Considerations for Limits @@ -292,7 +292,7 @@ Regardless of the above, the failure modes associated with rate limits generally 2. In the limit-based approach, the bridge will similarly not be able to complete the transaction on the destination domain until it has more capacity available. However, a limit approach provides some more reasonable guarantees to the user: (1) user have a much higher degree of predictability around time and pricing of the outputted transaction, (2) users would not receive some wrapped representation, and (3) bridges would have a simpler pathway for users to send the tokens back to the source domain or any other destination. ### Aggregation -EIP-7281 introduces new dynamics for aggregators that massively improve user safety and experience across chains. +This proposal introduces new dynamics for aggregators that massively improve user safety and experience across chains. There are two unsolved mechanism design problems that currently exist around bridge aggregation: @@ -301,8 +301,8 @@ There are two unsolved mechanism design problems that currently exist around bri With EIP-7281, the above problems are solved elegantly: -1. Because xERC-20s are able to be transferred 1:1 across chains (i.e. they have uniform pricing), aggregators are largely incentivized to route xERC-20 transfers based on *available limits* for a given asset (as transferring over a bridge with insufficient limits would result in a negative experience for their users). In other words, aggregators now route based on a **token-issuer-defined** metric of the perceived security of a given bridge. This radically improves the incentives around secure bridge development, pushing bridges to optimize for security in order to receive the highest possible rate limits for a given token. Perhaps most importantly, this definition of security is sovereign to the token issuer, eliminating the need for aggregators, chains, or other ecosystem actors be "central planners" on determining a given bridge's security model. -2. With slippage-free xERC-20 transfers, aggregators can know precisely how many tokens will get bridged across chains, eliminating headaches and custom code around sourcing destination-chain liquidity from DEXes. This massively improves pricing for users and composability for developers who want to build across chains. +1. Because `XERC20`s are able to be transferred 1:1 across chains (i.e. they have uniform pricing), aggregators are largely incentivized to route `XERC20` transfers based on *available limits* for a given asset (as transferring over a bridge with insufficient limits would result in a negative experience for their users). In other words, aggregators now route based on a **token-issuer-defined** metric of the perceived security of a given bridge. This radically improves the incentives around secure bridge development, pushing bridges to optimize for security in order to receive the highest possible rate limits for a given token. Perhaps most importantly, this definition of security is sovereign to the token issuer, eliminating the need for aggregators, chains, or other ecosystem actors be "central planners" on determining a given bridge's security model. +2. With slippage-free `XERC20` transfers, aggregators can know precisely how many tokens will get bridged across chains, eliminating headaches and custom code around sourcing destination-chain liquidity from DEXes. This massively improves pricing for users and composability for developers who want to build across chains. ## Backwards Compatibility @@ -316,42 +316,38 @@ Aside from the above, the following compatibility vectors were considered when d ### Compatibility with Deployed Tokens -There are three states that token issuers begin with when migrating to xERC-20s: +There are three states that token issuers begin with when migrating to `XERC20`s: 1. The token does not exist yet OR is upgradeable/controlled by the issuer on each supported domain. 2. The token is deployed to a single home domain but not others yet. 3. The token is deployed and/or bridged to multiple domains -The proposed xERC-20 standard solves for (1) out of the box - token issuers should simply deploy xERC-20 interface-compatible tokens on all domains they wish to support with no lockbox needed. +The proposed `XERC20` standard solves for (1) out of the box - token issuers should simply deploy `XERC20` interface-compatible tokens on all domains they wish to support with no lockbox needed. -Case (2) is straightforward to solve with xERC-20s as well. Token issuers should deploy a lockbox on their home chain, and then wrap their ERC-20s into xERC-20s prior to bridging them. This wrapping step may add some friction depending on the bridge - this is discussed further in the Compatibility with Bridges section. +Case (2) is straightforward to solve with `XERC20`s as well. Token issuers should deploy a lockbox on their home chain, and then wrap their ERC-20s into `XERC20`s prior to bridging them. This wrapping step may add some friction depending on the bridge - this is discussed further in the Compatibility with Bridges section. Case (3) is the most challenging to solve for as issuers may not have sovereign control over the “canonical” representation of the token on any remote domain and this necessitates a token migration of some form at least. As an example, tokens bridged using the default Arbitrum rollup bridge would be fully controlled by the rollup bridge. For these cases, we recommend the following migration path for issuers: -1. Deploy a lockbox on the remote domain which locks the canonical-bridge-minted token and mints a new xERC-20. -2. Establish the new xERC-20 token as the canonical asset for the domain - this is largely a social consensus activity driven by DAO agreement and project communications. -3. Deploy a lockbox on the home domain which locks the home canonical token and mints a new xERC-20. -4. Allowlist all desired bridges *including* the canonical bridge that owns the legacy implementation, mapping the xERC-20 representation on the home domain to the xERC-20 representation on the remote. -5. At this point, it is fully possible for users to begin transferring the token across all bridges as would be expected from the xERC-20 standard. However, note that the canonical bridge connecting home to remote will now have two bridge paths: (a) ERC-20→ERC-20 (locking the ERC-20 at home), and (b) xERC-20→xERC-20. Now, the issuer can begin the process of sunsetting the legacy canonical ERC-20 on the remote domain. +1. Deploy a lockbox on the remote domain which locks the canonical-bridge-minted token and mints a new `XERC20`. +2. Establish the new `XERC20` token as the canonical asset for the domain - this is largely a social consensus activity driven by DAO agreement and project communications. +3. Deploy a lockbox on the home domain which locks the home canonical token and mints a new `XERC20`. +4. Allowlist all desired bridges *including* the canonical bridge that owns the legacy implementation, mapping the `XERC20` representation on the home domain to the `XERC20` representation on the remote. +5. At this point, it is fully possible for users to begin transferring the token across all bridges as would be expected from the `XERC20` standard. However, note that the canonical bridge connecting home to remote will now have two bridge paths: (a) ERC-20→ERC-20 (locking the ERC-20 at home), and (b) `XERC20`→`XERC20`. Now, the issuer can begin the process of sunsetting the legacy canonical ERC-20 on the remote domain. 6. The issuer should at this point disallow minting *new* legacy canonical ERC-20s on the remote domain. This would organically & gradually lead to the legacy ERC-20s on the remote chain to become locked into the lockbox. -7. At any point in the future, the token issuer can then use their own treasury to unwrap xERC-20s on the remote domain into legacy ERC-20s and send them back to the home chain, incurring the latency of this on behalf of users. +7. At any point in the future, the token issuer can then use their own treasury to unwrap `XERC20`s on the remote domain into legacy ERC-20s and send them back to the home chain, incurring the latency of this on behalf of users. ### Compatibility with Bridges -One key benefit to the xERC-20 model is that the simple requirement of a burn & mint interface makes this proposal compatible with most bridges either out of the box or through a predefined custom token mapping process. The following bridges & domains were considered in the creation of this proposal: +One key benefit to the `XERC20` model is that the simple requirement of a burn & mint interface makes this proposal compatible with most bridges either out of the box or through a predefined custom token mapping process. The following bridges & domains were considered in the creation of this proposal: - **3rd party bridges:** every 3rd party bridge that relies on messaging infrastructure already supports a mint and burn interface and has a pathway to map custom minted tokens. -- **Arbitrum rollup bridge:** Arbitrum allows token issuers to [write a custom gateway](https://developer.arbitrum.io/asset-bridging#other-flavors-of-gateways). -- **OP Stack bridge:** Optimism supports [adding a custom bridge](https://community.optimism.io/docs/guides/bridge-dev/#building-a-custom-bridge). -- **Polygon PoS bridge:** Polygon supports custom tokens [through their fx portal](https://wiki.polygon.technology/docs/develop/l1-l2-communication/fx-portal). -- **ZkSync bridge**: Zksync supports [custom bridges of any kind](https://era.zksync.io/docs/reference/concepts/bridging/bridging-asset.html#custom-bridges-on-l1-and-l2). +- **Arbitrum rollup bridge:** Arbitrum allows token issuers to write a custom gateway +- **OP Stack bridge:** Optimism supports adding a custom bridge +- **Polygon PoS bridge:** Polygon supports custom tokens through their fx portal +- **ZkSync bridge**: Zksync supports custom bridges of any kind - **GnosisChain Omnibridge:** GnosisChain does not currently support custom tokens, but is in the process of redesigning their omnibridge and plans to allow this functionality. -Note: In most of the above cases, a custom bridge integration also means integration into canonical bridge UIs, ensuring that users have a consistent experience throughout the process. Additionally, a single xERC-20 custom bridge implementation could be built for each ecosystem and serve any number of token issuers. - -## Reference Implementation - -You can find a reference implementation and associated test cases [here](https://github.com/defi-wonderland/xTokens/blob/dev/solidity/contracts/XERC-20.sol). +Note: In most of the above cases, a custom bridge integration also means integration into canonical bridge UIs, ensuring that users have a consistent experience throughout the process. Additionally, a single `XERC20` custom bridge implementation could be built for each ecosystem and serve any number of token issuers. ## Security Considerations diff --git a/assets/eip-draft_bridged_tokens/xERC20.png b/assets/eip-7281/XERC20.png similarity index 100% rename from assets/eip-draft_bridged_tokens/xERC20.png rename to assets/eip-7281/XERC20.png diff --git a/assets/eip-draft_bridged_tokens/fragmentation.png b/assets/eip-7281/fragmentation.png similarity index 100% rename from assets/eip-draft_bridged_tokens/fragmentation.png rename to assets/eip-7281/fragmentation.png From 85ffda3b89211afc6dc1b136f005e3e09aab547a Mon Sep 17 00:00:00 2001 From: just-a-node Date: Sat, 17 Feb 2024 16:34:44 -0700 Subject: [PATCH 10/16] Fix link to diagram --- ERCS/eip-7281.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/eip-7281.md b/ERCS/eip-7281.md index 81f467469d..dc962148c8 100644 --- a/ERCS/eip-7281.md +++ b/ERCS/eip-7281.md @@ -247,7 +247,7 @@ The proposed standard attempts to satisfy the following conditions for bridged t The core problem that this standard tackles is the **fungibility** of tokens bridged across domains against the “canonical” token on that domain. (Note: which token is “canonical” is dictated by the token issuer and is sometimes, but not always, the token minted by a given domain’s enshrined bridge - e.g. a rollup bridge). -![](../assets/eip-draft_bridged_tokens/fragmentation.png) +![](../assets/eip-7281/fragmentation.png) It is not enough to simply allow multiple bridges to mint the same representation on a remote domain if liquidity is locked into bridges on the home domain. To illustrate this, consider an example where two bridges control minting rights of canonical USDT on an L2: From b5f14cc2ba6b4520aabbb6e0b261f7fcedc8c671 Mon Sep 17 00:00:00 2001 From: just-a-node Date: Sat, 17 Feb 2024 16:45:15 -0700 Subject: [PATCH 11/16] Fix eipw validation check --- ERCS/eip-7281.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/ERCS/eip-7281.md b/ERCS/eip-7281.md index dc962148c8..7da68d2dfe 100644 --- a/ERCS/eip-7281.md +++ b/ERCS/eip-7281.md @@ -48,7 +48,7 @@ The system proposed below has two main components: ### Token Interface -All `XERC20` tokens MUST implement the standard ERC-20 interface. Note that while many of the below functions are inspired by ERC-777, implementers are NOT REQUIRED to adhere to the full ERC-777 specification. +All `XERC20` tokens MUST implement the standard `ERC20` interface. Note that while many of the below functions are inspired by ERC-777, implementers are NOT REQUIRED to adhere to the full ERC-777 specification. All `XERC20` tokens MUST implement the following interface. @@ -165,9 +165,9 @@ interface IXERC20 { Implementations MUST additionally satisfy the following requirements: - `mint` MUST check that the caller's current available `limit` is greater than or equal to `_amount` -- `mint` MUST increase the supply of the underlying ERC-20 by `_amount` and reduce the current available `limit` +- `mint` MUST increase the supply of the underlying `ERC20` by `_amount` and reduce the current available `limit` - `burn` MUST check that the caller's current available `limit` is greater than or equal to `_amount` -- `burn` MUST decrease the supply of the underlying ERC-20 by `_amount` and reduce the current available `limit` +- `burn` MUST decrease the supply of the underlying `ERC20` by `_amount` and reduce the current available `limit` ### Lockbox @@ -206,7 +206,7 @@ interface IXERC20Lockbox { error IXERC20Lockbox_WithdrawFailed(); /** - * @notice Deposit ERC-20 tokens into the lockbox + * @notice Deposit `ERC20` tokens into the lockbox * * @param _amount The amount of tokens to deposit */ @@ -214,7 +214,7 @@ interface IXERC20Lockbox { function deposit(uint256 _amount) external; /** - * @notice Withdraw ERC-20 tokens from the lockbox + * @notice Withdraw `ERC20` tokens from the lockbox * * @param _amount The amount of tokens to withdraw */ @@ -223,7 +223,7 @@ interface IXERC20Lockbox { } ``` -Lockboxes SHOULD additionally implement the following alternative `deposit` function for native (non-ERC-20) assets. +Lockboxes SHOULD additionally implement the following alternative `deposit` function for native (non-`ERC20`) assets. ```ts /** @@ -256,7 +256,7 @@ It is not enough to simply allow multiple bridges to mint the same representatio - Suppose Alice pays Bob her 100 USDT. Bob now has 200 USDT. - Bob attempts to bridge the 200 USDT from L2→L1 through bridge 2. This transaction fails, because bridge 2 only has 100 USDT custodied that it can give to Bob. -The core property that this example illustrates is that locking tokens across multiple bridges on the token’s “home” domain makes it impossible to have fungibility without impeding user experience on remote domains. Minting or burning the token can solve this problem, but not all ERC-20 tokens implement a configurable mint/burn interface. +The core property that this example illustrates is that locking tokens across multiple bridges on the token’s “home” domain makes it impossible to have fungibility without impeding user experience on remote domains. Minting or burning the token can solve this problem, but not all `ERC20` tokens implement a configurable mint/burn interface. ### Lockbox @@ -264,12 +264,12 @@ This proposal specifically solves for the above problem in cases where tokens do ![](../assets/eip-7291/XERC20.png) -1. A given ERC-20 is wrapped into its `XERC20` representation. +1. A given `ERC20` is wrapped into its `XERC20` representation. 2. The `XERC20` can then be transferred to any approved bridge. The bridge should check rate limits for the token and then `burn` the token. 3. On the target domain, the bridge then similarly `mint`s the token. -4. When transferring back to the home chain, the `XERC20` can be unwrapped back into the original ERC-20 token. +4. When transferring back to the home chain, the `XERC20` can be unwrapped back into the original `ERC20` token. -Using this mechanism, the underlying ERC-20 token is consolidated to the Lockbox contract, and shared across all supported bridges. +Using this mechanism, the underlying `ERC20` token is consolidated to the Lockbox contract, and shared across all supported bridges. ### Rate Limits @@ -307,7 +307,7 @@ With EIP-7281, the above problems are solved elegantly: ## Backwards Compatibility -This proposal is fully backwards compatible with ERC-20. +This proposal is fully backwards compatible with `ERC20`. Aside from the above, the following compatibility vectors were considered when designing this proposal: @@ -324,7 +324,7 @@ There are three states that token issuers begin with when migrating to `XERC20`s The proposed `XERC20` standard solves for (1) out of the box - token issuers should simply deploy `XERC20` interface-compatible tokens on all domains they wish to support with no lockbox needed. -Case (2) is straightforward to solve with `XERC20`s as well. Token issuers should deploy a lockbox on their home chain, and then wrap their ERC-20s into `XERC20`s prior to bridging them. This wrapping step may add some friction depending on the bridge - this is discussed further in the Compatibility with Bridges section. +Case (2) is straightforward to solve with `XERC20`s as well. Token issuers should deploy a lockbox on their home chain, and then wrap their `ERC20`s into `XERC20`s prior to bridging them. This wrapping step may add some friction depending on the bridge - this is discussed further in the Compatibility with Bridges section. Case (3) is the most challenging to solve for as issuers may not have sovereign control over the “canonical” representation of the token on any remote domain and this necessitates a token migration of some form at least. As an example, tokens bridged using the default Arbitrum rollup bridge would be fully controlled by the rollup bridge. For these cases, we recommend the following migration path for issuers: @@ -332,9 +332,9 @@ Case (3) is the most challenging to solve for as issuers may not have sovereign 2. Establish the new `XERC20` token as the canonical asset for the domain - this is largely a social consensus activity driven by DAO agreement and project communications. 3. Deploy a lockbox on the home domain which locks the home canonical token and mints a new `XERC20`. 4. Allowlist all desired bridges *including* the canonical bridge that owns the legacy implementation, mapping the `XERC20` representation on the home domain to the `XERC20` representation on the remote. -5. At this point, it is fully possible for users to begin transferring the token across all bridges as would be expected from the `XERC20` standard. However, note that the canonical bridge connecting home to remote will now have two bridge paths: (a) ERC-20→ERC-20 (locking the ERC-20 at home), and (b) `XERC20`→`XERC20`. Now, the issuer can begin the process of sunsetting the legacy canonical ERC-20 on the remote domain. -6. The issuer should at this point disallow minting *new* legacy canonical ERC-20s on the remote domain. This would organically & gradually lead to the legacy ERC-20s on the remote chain to become locked into the lockbox. -7. At any point in the future, the token issuer can then use their own treasury to unwrap `XERC20`s on the remote domain into legacy ERC-20s and send them back to the home chain, incurring the latency of this on behalf of users. +5. At this point, it is fully possible for users to begin transferring the token across all bridges as would be expected from the `XERC20` standard. However, note that the canonical bridge connecting home to remote will now have two bridge paths: (a) `ERC20`→`ERC20` (locking the `ERC20` at home), and (b) `XERC20`→`XERC20`. Now, the issuer can begin the process of sunsetting the legacy canonical `ERC20` on the remote domain. +6. The issuer should at this point disallow minting *new* legacy canonical `ERC20`s on the remote domain. This would organically & gradually lead to the legacy `ERC20`s on the remote chain to become locked into the lockbox. +7. At any point in the future, the token issuer can then use their own treasury to unwrap `XERC20`s on the remote domain into legacy `ERC20`s and send them back to the home chain, incurring the latency of this on behalf of users. ### Compatibility with Bridges From 4fc6882afee6272a0f31383394215d2141f1d019 Mon Sep 17 00:00:00 2001 From: just-a-node Date: Sat, 17 Feb 2024 17:43:03 -0700 Subject: [PATCH 12/16] More lint fixes --- ERCS/{eip-7281.md => erc-7281.md} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename ERCS/{eip-7281.md => erc-7281.md} (99%) diff --git a/ERCS/eip-7281.md b/ERCS/erc-7281.md similarity index 99% rename from ERCS/eip-7281.md rename to ERCS/erc-7281.md index 7da68d2dfe..318a20537a 100644 --- a/ERCS/eip-7281.md +++ b/ERCS/erc-7281.md @@ -48,7 +48,7 @@ The system proposed below has two main components: ### Token Interface -All `XERC20` tokens MUST implement the standard `ERC20` interface. Note that while many of the below functions are inspired by ERC-777, implementers are NOT REQUIRED to adhere to the full ERC-777 specification. +All `XERC20` tokens MUST implement the standard `ERC20` interface. Note that while many of the below functions are inspired by [ERC-777](./erc-777.md), implementers are NOT REQUIRED to adhere to the full [ERC-777](./erc-777.md) specification. All `XERC20` tokens MUST implement the following interface. @@ -299,7 +299,7 @@ There are two unsolved mechanism design problems that currently exist around bri 1. Bridge aggregators primarily compare bridges based on price, which itself is a function of the gas costs needed to use a given bridge and the slippage due to liquidity on that bridge. Competing solely on price heavily favors (a) bridges that take a more custodial/centralized approach to cut costs, and (b) bridges that are willing and able to spend lots of capital on liquidity incentives. This creates a system of incentives that penalizes security-minded approaches & open competition. 2. Bridge aggregators tap into liquidity from DEX aggregators at the source and destination chains. To do this effectively, they need to query DEX aggregators to get a quote for a destination chain swap, *before they initiate the transaction on the source chain*. However, because liquidity-based bridges introduce slippage on crosschain transfers, there is no way for bridge aggregators to know *up front* how many tokens would be received on the destination. Aggregators currently get around this problem by defaulting to some maximum slippage (or minimum amount received) passed into the underlying bridge protocol - this means that users *always* lose 1%-3% of their value when bridging regardless of how much liquidity is available on a bridge. -With EIP-7281, the above problems are solved elegantly: +With `XERC20`, the above problems are solved elegantly: 1. Because `XERC20`s are able to be transferred 1:1 across chains (i.e. they have uniform pricing), aggregators are largely incentivized to route `XERC20` transfers based on *available limits* for a given asset (as transferring over a bridge with insufficient limits would result in a negative experience for their users). In other words, aggregators now route based on a **token-issuer-defined** metric of the perceived security of a given bridge. This radically improves the incentives around secure bridge development, pushing bridges to optimize for security in order to receive the highest possible rate limits for a given token. Perhaps most importantly, this definition of security is sovereign to the token issuer, eliminating the need for aggregators, chains, or other ecosystem actors be "central planners" on determining a given bridge's security model. 2. With slippage-free `XERC20` transfers, aggregators can know precisely how many tokens will get bridged across chains, eliminating headaches and custom code around sourcing destination-chain liquidity from DEXes. This massively improves pricing for users and composability for developers who want to build across chains. From 0134fe7a9863162ae4cd3804c4aba838d7b69444 Mon Sep 17 00:00:00 2001 From: just-a-node Date: Sat, 17 Feb 2024 17:48:55 -0700 Subject: [PATCH 13/16] Fix one more eipw validation check --- ERCS/erc-7281.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7281.md b/ERCS/erc-7281.md index 318a20537a..4c988c9d79 100644 --- a/ERCS/erc-7281.md +++ b/ERCS/erc-7281.md @@ -13,7 +13,7 @@ requires: 20 ## Abstract -This proposal defines a minimal extension to [ERC-20](../EIPS/eip-20.md) (affectionately called XERC20) that enables bridging tokens across domains without creating multiple infungible representations of the same underlying asset. Token issuers can define which bridges are able to mint or burn the XERC20 on a given domain and configure rate limits for each allowed bridge. +This proposal defines a minimal extension to [ERC-20](../EIPS/eip-20.md) (affectionately called `XERC20`) that enables bridging tokens across domains without creating multiple infungible representations of the same underlying asset. Token issuers can define which bridges are able to mint or burn the `XERC20` on a given domain and configure rate limits for each allowed bridge. ## Motivation From ed435a39c89631c7dddf0efee76a0786261baaee Mon Sep 17 00:00:00 2001 From: just-a-node Date: Sat, 17 Feb 2024 18:15:02 -0700 Subject: [PATCH 14/16] Linked asset typo --- ERCS/erc-7281.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7281.md b/ERCS/erc-7281.md index 4c988c9d79..cad117c67d 100644 --- a/ERCS/erc-7281.md +++ b/ERCS/erc-7281.md @@ -262,7 +262,7 @@ The core property that this example illustrates is that locking tokens across mu This proposal specifically solves for the above problem in cases where tokens do not already have a mint/burn interface. Tokens on the source chain are locked into a Lockbox, which mints corresponding `XERC20`-compatible tokens that can be sent to bridges. -![](../assets/eip-7291/XERC20.png) +![](../assets/eip-7281/XERC20.png) 1. A given `ERC20` is wrapped into its `XERC20` representation. 2. The `XERC20` can then be transferred to any approved bridge. The bridge should check rate limits for the token and then `burn` the token. From 6cf3fbc8e928ac5de4c2bd7217a8094ded8771fd Mon Sep 17 00:00:00 2001 From: just-a-node Date: Fri, 23 Feb 2024 19:11:17 -0700 Subject: [PATCH 15/16] Move fungibility section and expand on abstract --- ERCS/erc-7281.md | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/ERCS/erc-7281.md b/ERCS/erc-7281.md index cad117c67d..32857d4b8d 100644 --- a/ERCS/erc-7281.md +++ b/ERCS/erc-7281.md @@ -13,23 +13,36 @@ requires: 20 ## Abstract -This proposal defines a minimal extension to [ERC-20](../EIPS/eip-20.md) (affectionately called `XERC20`) that enables bridging tokens across domains without creating multiple infungible representations of the same underlying asset. Token issuers can define which bridges are able to mint or burn the `XERC20` on a given domain and configure rate limits for each allowed bridge. +This proposal defines a minimal extension to [ERC-20](../EIPS/eip-20.md) (affectionately called `XERC20`) that enables bridging tokens across domains without creating multiple infungible representations of the same underlying asset. It introduces the concept of a Lockbox to allow existing tokens to comply with the specification through a familiar wrapping mechanism and exposes new interfaces that allow token issuers to apply custom risk profiles at a per bridge per domain granularity. ## Motivation -With the rapid proliferation of L2s, fungible token liquidity has become increasingly fragmented across domains. This, coupled with the need for projects to transfer tokens between chains faster than rollup exit windows, has meant that token issuers must choose from one of two options to bridge their tokens: +With the rapid proliferation of L2s, fungible token liquidity has become increasingly fragmented across domains. What issuers really need is for a single "canonical" representation of their token to exist on each L2, regardless of which bridges are supported by the issuer. Currently, the "canonical" token of an L2 is dictated by the token issuer and is sometimes, but not always, the token minted by a given domain’s enshrined bridge - e.g. a rollup bridge. Other representations of that token can exist on the same L2 because other bridges will deploy their own flavor of the token that they can then mint/burn. In this paradigm, multiple bridges lock token liquidity on L1 (or the home domain) and mint different representations of the token on L2 (or the remote domain). This ultimately causes slippage in cross-chain token transfers because users realistically only want to use the "canonical" version. + +However, even if bridges were all allowed to mint the same representation tokens on a remote domain, there is still an issue. On the home domain, token liquidity is locked and custodied across multiple bridges. To illustrate this problem, consider an example where two bridges control minting rights of canonical USDT on an L2: + +![](../assets/eip-7281/fragmentation.png) + +- Alice bridges 100 USDT from L1→L2 through Bridge 1. The underlying L1 USDT tokens is locked in Bridge 1 and 100 USDT is minted on L2. +- Bob bridges 100 USDT from L1→L2 through Bridge 2. Similarly, the underlying L1 USDT tokens are locked in Bridge 2 and 100 USDT is minted on L2. +- Suppose Alice pays Bob her 100 USDT on L2. Bob now has 200 USDT. +- Bob attempts to bridge the 200 USDT from L2→L1 through Bridge 2. This transaction fails because Bridge 2 only has 100 USDT custodied that it can give to Bob. + +The core property that this example illustrates is that locking tokens across multiple bridges on the token’s home domain makes it impossible to have fungibility without impeding user experience on remote domains. Minting or burning the token can solve this problem, but not all `ERC20` tokens implement a configurable mint/burn interface. + +This, coupled with the need for projects to transfer tokens between chains faster than rollup exit windows, means that token issuers must choose from one of two options to bridge their tokens: 1. Bridge tokens through the “canonical” rollup bridge and work with atomic swap or fast-liquidity providers for L2→L1 or L2→L2 interactions. While this is the safer option, it necessitates significant requirements for issuers to incentivize or bootstrap liquidity on every supported chain, limiting support to only the most liquid of assets. Liquidity-based bridging additionally introduces slippage or other unpredictable pricing for users, hindering composability across domains. 2. Work with a 3rd party bridge. This option removes liquidity and pricing concerns making it more favorable for longer-tail issuers, but locks a given minted representation of a bridged token to only its associated bridge. This creates a tradeoff for issuers between security/sovereignty and user experience: If the token is bridged through only a single provider, the token supply and implementation is now fully and in perpetuity controlled by the bridge. If the token is bridged through multiple options (including "canonical" rollup bridges), multiple infungible (“wrapped”) representations of the same underlying asset are created on L2. -In the ideal case, token issuers want the following properties for bridged representations of their tokens: +In the ideal case, token issuers want the following properties for their bridged tokens: +- Fungibility, as highlighted above. - Sovereignty. Issuers want to be the logical owners of the canonical representation of their token on L2 and not be locked into any single specific option forever. -- Fungibility. Token issuers want a single “canonical” representation of their token on each L2, regardless of which bridges (canonical or otherwise) are supported by the issuer. - Security. Issuers want to opt into novel secure bridging approaches as they are developed and have granular control over their risk tolerance for any given option. - Minimal Liquidity. Issuers want to minimize the costs and complexity of acquiring liquidity for their token on each supported bridge and chain. This property becomes increasingly important as the space eventually expands to 100s or 1000s of connected domains. -There has been some previous work to solve this problem. However, solutions have historically either failed to satisfy all of the above desirable properties or have been custom-built for only a single token ecosystem. +There has been some previous work to solve these problems. However, solutions have historically either failed to satisfy all of the above desirable properties or have been custom-built for only a single token ecosystem. - Celer’s Open Canonical Token Standard proposed a lock-in free standard for bridging tokens to new domains. However, it largely targeted alternative L1s (that don’t already have a canonical bridge) and did not fully solve the fungibility problem. Regardless, Celer’s approach inspired some of the key thinking behind this standard. - Maker’s Teleport facility allows for minting and burning canonical DAI between domains. While the approach solves for the desirable properties above, it is highly custom to Maker’s architecture and relies on Maker’s own economic security to function. Circle CCTP similarly solves this problem, but using a mechanism that only centralized token issuers can implement. @@ -243,21 +256,6 @@ The proposed standard attempts to satisfy the following conditions for bridged t 3. Cross-domain interactions involving tokens should be slippage-free, simplifying composability. 4. Token issuers should own decision-making around which bridges to support and be able to parametrize risk for each. They should not be locked into only supporting a single bridge. -### Fungibility - -The core problem that this standard tackles is the **fungibility** of tokens bridged across domains against the “canonical” token on that domain. (Note: which token is “canonical” is dictated by the token issuer and is sometimes, but not always, the token minted by a given domain’s enshrined bridge - e.g. a rollup bridge). - -![](../assets/eip-7281/fragmentation.png) - -It is not enough to simply allow multiple bridges to mint the same representation on a remote domain if liquidity is locked into bridges on the home domain. To illustrate this, consider an example where two bridges control minting rights of canonical USDT on an L2: - -- Alice bridges 100 USDT from L1→L2 through bridge 1. The underlying L1 USDT tokens is locked in bridge 1 and 100 USDT is minted on L2. -- Bob bridges 100 USDT from L1→L2 through bridge 2. Similar to the above case, the underlying L1 USDT tokens are locked in bridge 2 and 100 USDT is minted on L2. -- Suppose Alice pays Bob her 100 USDT. Bob now has 200 USDT. -- Bob attempts to bridge the 200 USDT from L2→L1 through bridge 2. This transaction fails, because bridge 2 only has 100 USDT custodied that it can give to Bob. - -The core property that this example illustrates is that locking tokens across multiple bridges on the token’s “home” domain makes it impossible to have fungibility without impeding user experience on remote domains. Minting or burning the token can solve this problem, but not all `ERC20` tokens implement a configurable mint/burn interface. - ### Lockbox This proposal specifically solves for the above problem in cases where tokens do not already have a mint/burn interface. Tokens on the source chain are locked into a Lockbox, which mints corresponding `XERC20`-compatible tokens that can be sent to bridges. From 052a0c89d98d6042617874caef323f415327f1ee Mon Sep 17 00:00:00 2001 From: just-a-node Date: Sat, 9 Nov 2024 01:08:01 -0700 Subject: [PATCH 16/16] Add co-author Co-authored-by: pedrouid --- ERCS/erc-7281.md | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/ERCS/erc-7281.md b/ERCS/erc-7281.md index 32857d4b8d..87b74b7670 100644 --- a/ERCS/erc-7281.md +++ b/ERCS/erc-7281.md @@ -28,7 +28,7 @@ However, even if bridges were all allowed to mint the same representation tokens - Suppose Alice pays Bob her 100 USDT on L2. Bob now has 200 USDT. - Bob attempts to bridge the 200 USDT from L2→L1 through Bridge 2. This transaction fails because Bridge 2 only has 100 USDT custodied that it can give to Bob. -The core property that this example illustrates is that locking tokens across multiple bridges on the token’s home domain makes it impossible to have fungibility without impeding user experience on remote domains. Minting or burning the token can solve this problem, but not all `ERC20` tokens implement a configurable mint/burn interface. +The core property that this example illustrates is that locking tokens across multiple bridges on the token’s home domain makes it impossible to have fungibility without impeding user experience on remote domains. Minting or burning the token can solve this problem, but not all [ERC-20](./eip-20.md) tokens implement a configurable mint/burn interface. This, coupled with the need for projects to transfer tokens between chains faster than rollup exit windows, means that token issuers must choose from one of two options to bridge their tokens: @@ -65,7 +65,7 @@ All `XERC20` tokens MUST implement the standard `ERC20` interface. Note that whi All `XERC20` tokens MUST implement the following interface. -```ts +```solidity interface IXERC20 { /** * @notice Emits when a lockbox is set @@ -178,15 +178,15 @@ interface IXERC20 { Implementations MUST additionally satisfy the following requirements: - `mint` MUST check that the caller's current available `limit` is greater than or equal to `_amount` -- `mint` MUST increase the supply of the underlying `ERC20` by `_amount` and reduce the current available `limit` +- `mint` MUST increase the supply of the underlying ERC-20 token by `_amount` and reduce the current available `limit` - `burn` MUST check that the caller's current available `limit` is greater than or equal to `_amount` -- `burn` MUST decrease the supply of the underlying `ERC20` by `_amount` and reduce the current available `limit` +- `burn` MUST decrease the supply of the underlying ERC-20 token by `_amount` and reduce the current available `limit` ### Lockbox The lockbox tries to emulate the WETH contract interface as much as possible. Lockboxes MUST implement the following interface: -```ts +```solidity interface IXERC20Lockbox { /** * @notice Emitted when tokens are deposited into the lockbox @@ -236,9 +236,9 @@ interface IXERC20Lockbox { } ``` -Lockboxes SHOULD additionally implement the following alternative `deposit` function for native (non-`ERC20`) assets. +Lockboxes SHOULD additionally implement the following alternative `deposit` function for native (non-ERC-20 token) assets. -```ts +```solidity /** * @notice Deposit native assets (e.g. ETH) into the lockbox */ @@ -267,7 +267,7 @@ This proposal specifically solves for the above problem in cases where tokens do 3. On the target domain, the bridge then similarly `mint`s the token. 4. When transferring back to the home chain, the `XERC20` can be unwrapped back into the original `ERC20` token. -Using this mechanism, the underlying `ERC20` token is consolidated to the Lockbox contract, and shared across all supported bridges. +Using this mechanism, the underlying ERC-20 token is consolidated to the Lockbox contract, and shared across all supported bridges. ### Rate Limits @@ -305,7 +305,7 @@ With `XERC20`, the above problems are solved elegantly: ## Backwards Compatibility -This proposal is fully backwards compatible with `ERC20`. +This proposal is fully backwards compatible with ERC-20. Aside from the above, the following compatibility vectors were considered when designing this proposal: @@ -349,7 +349,27 @@ Note: In most of the above cases, a custom bridge integration also means integra ## Security Considerations -Please see the associated discussion in the **Rationale** section. +In addition to the granular risk controls outlined in the [Rate Limits](#rate-limits) section, token issuers should be aware of the following security considerations. + +### Access Control + +Implementations should clearly define roles that manage critical functions such as setting the Lockbox and updating rate limits. Role-based access control (RBAC) can be implemented using battle-tested libraries like OpenZeppelin's AccessControl. For token projects managed by DAOs, it is imperative that ownership and parameter-adjusting functions are guarded in accordance with rules set by the DAO. + +### Upgradeability + +If the issuer decides to deploy upgradeable contracts, they must consider security measures to ensure upgrades can only be performed by authorized roles. The upgrade process should be transparent and auditable. Similarly to implementing RBAC, upgradeability can be included via battle-tested libraries. + +### Lockbox Asset Custody + +The Lockbox essentially emulates the behavior of Wrapped Ether (WETH) and vanilla implementations should not need to be owned nor upgradeable. However, if a token issuer requires some custom functionality on the Lockbox then they must ensure that the Lockbox securely custodies the original ERC-20 tokens. + +### Mint/Burn Checks + +To reiterate security points from the [Token Interface](#token-interface) section: +- `mint` MUST check that the caller's current available `limit` is greater than or equal to `_amount` +- `mint` MUST increase the supply of the underlying ERC-20 token by `_amount` and reduce the current available `limit` +- `burn` MUST check that the caller's current available `limit` is greater than or equal to `_amount` +- `burn` MUST decrease the supply of the underlying ERC-20 token by `_amount` and reduce the current available `limit` ## Copyright