Standardizing bridges themselves and the end-to-end bridging process is a difficult and ambitious project. A prior proposal with this goal was not able to gain momentum.
The current proposal focuses more narrowly on standardizing the interface that a token has to implement in order to be used in a bridge system, which among other things requires the token to be mintable by the bridge.
This is not yet an ERC. I’m looking to get input from the relevant parties and confirm willingness to implement this standard. There are several discussion points listed below.
Abstract
A standard interface for a bridge to interact with a destination ERC20 token. The scenario covered is that of a bridge where deposits on a source chain trigger minting on a destination chain.
Motivation
Although bridges tend to have the ability to deploy an off-the-shelf ERC20 contract as the bridged counterpart of a particular token, a protocol may want its canonical bridged token to be a custom implementation or have a different set of features on top of the standard ones. In that case, if the protocol wants to make this canonical token available on multiple chains it will currently need to deploy a different version of the code to each chain, as bridges expect different interfaces of the token.
The goal of this proposal is to enable code portability for bridged ERC20 tokens, so that the same code can be deployed to different networks with zero changes.
Specification
As a strawman proposal, this is the interface currently used by Arbitrum.
interface ERC20Bridged is ERC20 {
function l1Address() external view returns (address);
function bridgeMint(address account, uint256 amount) external;
function bridgeBurn(address account, uint256 amount) external;
}
l1Address
Returns the address of the L1 token that this one is a bridged version of.
This getter allows the bridge to verify that it is correct to mint the token for a deposit of a particular L1 token. It is needed because the address of the L2 token may be an input to the deposit operation, and not inferred from a one-to-one mapping.
bridgeMint
Mints amount
of the token and credits it to account
.
bridgeBurn
Burns amount
of the token, deducted from the balance of account
.
Discussion
Naming
l1Address
Optimism uses l1Token
. The choice between “address” and “token” is minor, but I believe this standard should apply more broadly to protocols and bridges that are not strictly Layer 2s, so a different name would be more appropriate.
Additionally, even for a Layer 2 protocol, the name l1Address
assumes assets are bridged from L1 to L2, and a standard interface should not assume this is the only possible bridging direction.
Some alternatives: sourceToken
, originToken
.
bridgeMint, bridgeBurn
Optimism uses mint
and burn
. What are the reasons each project went with their naming?
Polygon PoS Portal uses deposit
and withdraw
, which is different as it is meant to be called by the token holder themselves: function withdraw(uint amount)
.
Events
Arbitrum bridged tokens emit the standard ERC20 Transfer
event. Optimism’s emit events Mint
and Burn
on top of Transfer
. None of these events appear to be used as part of the bridge’s on-chain operation, though they may be used for off-chain monitoring.
Polygon’s PoS Portal uses standard Transfer
events, and in fact relies on burn events to finalize withdrawals in Ethereum. This may be problematic as tokens could be burnable for reasons unrelated to withdrawals, so it may be advisable to instead rely on a special-purpose event.
An event for minting may also be useful for some bridge designs, so we might add two events:
event BridgeMinted(address indexed account, uint amount);
event BridgeBurned(address indexed account, uint amount);
Generality
Multi-chain bridges
Could a bridge process deposits from multiple chains? If so, a bridged token may need to complement the address of the source token with the ID of the source chain.
function sourceToken() view returns (address token, uint chainId)
Multi-bridge tokens
It’s not possible to force a token to be exclusively tied to a single bridge. Does this break any assumptions? Should a standard have an opinion about it?
Bridges that rely on burn events to prove withdrawals should consider this possibility. A burn should be somehow tied to a single bridge
Multi-source tokens
Could a token have multiple source tokens, possibly from multiple source chains? To support this scenario, instead of reporting a supported address as with l1Address
the bridged token could offer a function to query whether a particular address is supported.
function sourceToken(address token) view returns (bool);
function sourceToken(address token, uint chainId) view returns (bool);
Mintable tokens
Is it ok if a bridged token is also mintable (on the destination chain) through other means?
Backwards Compatibility
If we move forward with this proposal as an ERC, the resulting interface will likely be different from that implemented by bridges today. However, it seems all bridges are currently upgradeable, so there should be a backwards compatible upgrade path that bridge operators can agree to implement.
This appears simple enough by using ERC165 interfaces. Before executing a mint operation, the bridge can check using ERC165 if the standard interface is supported. If it is not supported, it can fall back to its legacy interface.
Similarly for withdrawals the bridge can support both interfaces.
If the withdrawal relies on the proof of an event, both the previous event as well as the standardized event could be supported. However, if the previously used event was a standard ERC20 Transfer
event, both may be emitted at the same time and the bridge should make sure it only processes a withdrawal once.
References
- Optimism L2StandardBridge
- Arbitrum L2ArbitrumGateway
- Polygon ChildChainManager