Wrapped asset bridge allows bridging ERC20 tokens and native gas tokens (e.g. ETH) from existing EVM chains (e.g. Ethereum, Avalanche, BSC, etc.) to subnets or brand new EVM chains where those assets do not exist natively. It supports mapping the same wrapped token to multiple tokens on other chains. E.g. moving native USDC from Ethereum or Avalanche to NewChainX will result in the same wrapped asset on NewChainX.
The bridge is not intended for bridging between existing L1 EVM chains (e.g. between Ethereum and Avalanche)
- Clone the repository
- run
yarn
yarn test
Run the full suite of unit tests.
yarn coverage
Get the coverage report.
- Deploy
OriginalTokenBridge.solon existing EVM chains. - Deploy
WrappedTokenBridge.solon the new EVM chain. - Call
setTrustedRemoteAddressinWrappedTokenBridgecontract and in eachOriginalTokenBridgecontract. - For each token you want to bridge (e.g.,
USDC,WETH, etc), deployWrappedERC20contract on the new EVM chain. Make sure to setdecimalsin theWrappedERC20to the number of decimals used in the original token you want to bridge (e.g.,6decimals forUSDC,18decimals forWETH). If you want to add an additional functionality to the wrapped token, inherit it fromWrappedERC20and add a custom logic to the derived contract. - For each token you want to bridge, call
registerToken(address token, uint8 sharedDecimals)function inOriginalTokenBridgeandregisterToken(address localToken, uint16 remoteChainId, address remoteToken)function inWrappedTokenBridge. Each wrapped token can be mapped to multiple original tokens on different chains (e.g.USDCon the new chain is mapped toUSDCon Ethereum andUSDCon Avalanche).
- Call
estimateBridgeFee(bool useZro, bytes calldata adapterParams)inOriginalTokenBridgecontract. - Call
bridge(address token, uint amountLD, address to, LzLib.CallParams calldata callParams, bytes memory adapterParams)inOriginalTokenBridgecontract to bridgeERC20tokens passingnativeFeeobtained earlier as a value. This will lockERC20tokens inOriginalTokenBridgecontract and send a LayerZero message to theWrappedTokenBridgeon another chain to mint wrapped tokens. To bridgeETHusebridgeNative(uint amountLD, address to, LzLib.CallParams calldata callParams, bytes memory adapterParams)function and pass a sum ofnativeFeeand amount as a value.
- Call
estimateBridgeFee(uint16 remoteChainId, bool useZro, bytes calldata adapterParams)inWrappedTokenBridge. - Call
bridge(address localToken, uint16 remoteChainId, uint amount, address to, bool unwrapWeth, LzLib.CallParams calldata callParams, bytes memory adapterParams)supplyingnativeFeeobtained earlier as a value. This will burn wrapped tokens and send a LayerZero message toOriginalTokenBridgecontract on another chain to unlock original tokens.
