Bridging Lucid Assets
Introduction
To bridge tokens from Chain A to Chain B, an Asset Controller contract must be deployed on both chains.
To successfully bridge tokens from a controller on a source chain, ensure that:
The selected bridge adapter is whitelisted by an admin.
The adapter has sufficient mint/burn limits (unless bridging without limits).
The following sections describe how to manually bridge tokens by interacting directly with the smart contracts. This is intended for advanced users. It is recommended to use the Lucid App to bridge tokens or to construct/export transactions for execution via Safe, Snapshot’s oSnap module, or a Governor proposal.
Bridging Tokens
To bridge Lucid assets, you interact directly with the Lucid Wrapper contract (address and deployed chains can be viewed here), which serves as the entry point to bridge Lucid assets across any chain. It also supports EIP-2612 (aka ERC20Permit) for compatible assets, so the erc20 approve transaction can be skipped. The following functions are available on the Lucid Wrapper contract:
Single Bridge
Using a single bridge is the default way to bridge tokens. You can initiate a transfer by calling transferTo on the Wrapper contract on the source chain:
transferTo
Burns or locks tokens (depending on the configuration) on the source chain
Sends a mint message to the destination chain via the selected bridge adapter
msg.valuemust contain the bridge adapter feeThe token allowance must be approved prior to calling this function
adapter
address
The address of the bridge adapter to use
bridgeOptions
bytes
Additional params to be used by the adapter. Refer to the documentation of the specific adapter you are using
If the selected bridge adapter is not whitelisted, or if it does not have sufficient burn limits, the transaction will revert. Any account holding the token managed by the Asset Controller can initiate a transfer.
Events emitted
The following events are emitted after a transfer has been sent:
From the Lucid Wrapper contract:
The data bytes array is emitted unchanged from the input parameters.
From the Asset Controller contract:
The transferId can be used to:
Resend the transfer using another adapter
Track delivery status on the destination chain or the Lucid App
transferToWPermit
This function works similar to transferTo() as outlined above, but it accepts an EIP-2612 signature to register the user's ERC20 approval, eliminating the need for a prior approve() transaction. If the signature is invalid, the transaction will revert.
Can only be used with tokens that implement EIP-2612. Check if the token you are bridging supports this functionality.
bridgeAdapter
address
The address of the bridge adapter to use
bridgeOptions
bytes
Additional params to be used by the adapter. Refer to the documentation of the specific adapter you are using
resendTransfer
If a bridge fails to deliver a transfer to the destination chain, anyone can call resendTransfer, specifying the transferId and a different whitelisted adapter.
No new tokens will be burned
The original bridge message is resent using the new adapter
The burn amount is deducted from the new adapter’s burn limit
The function is payable, and
msg.valuemust contain the new adapter’s fee
transferId
bytes32
The unique identifier of the message.
adapter
address
The address of the bridge adapter.
bridgeOptions
bytes
Additional abi-encoded options that are passed to the bridge adapter, specific for the bridge adapter.
Events emitted
The following events are emitted after a transfer has been sent:
From the Lucid Wrapper contract:
From the Asset Controller contract:
Multiple Bridges (higher limits)
For transfers that exceed a single adapter’s limit, you can use multiple bridge adapters by calling the overloaded transferTo() function. This function:
Burns tokens on the source chain
Sends the mint message through multiple whitelisted adapters
Requires the addresses of adapters that have been pre-approved for with higher limits
msg.valuemust include any multi-bridge feesThe token allowance must be set before calling this function.
To determine:
The minimum number of adapters required for minting (if 0 is returned, then multiple bridges support is disabled):
To determine whether a specific adapter is approved for bridging with higher limits:
To get the current multi-bridge limits, call bridges(0x0).
transferTo (multiple bridges)
To send a transfer, call the following function:
adapters
address[]
The addresses of the bridge adapter to use.
fees
uint256[]
The fees to be paid to the bridge adapters (in the same order as adapters).
bridgeOptions
bytes[]
Additional params to be used by each adapter. Refer to the documentation of the specific adapter you are using
A token allowance must be given before calling this function, which should include the multi-bridge fee, if any.
If the bridgeAdapter that was selected is not whitelisted, or the burn limits are not enough, then the transaction will revert.
Events emitted
The following events are emitted after a transfer has been sent:
From the Lucid Wrapper contract:
The data bytes array is emitted unchanged from the input parameters.
From the Asset Controller contract:
The transferId can be used to:
Resend the transfer using another adapter
Track delivery status on the destination chain or the Lucid App
transferToWPermit (multiple bridges)
This function works similar to transferTo() as outlined above, but it accepts an EIP-2612 signature to register the user's ERC20 approval, eliminating the need for a prior approve() transaction. If the signature is invalid, the transaction will revert.
Can only be used with tokens that implement EIP-2612. Check if the token you are bridging supports this functionality.
adapters
address[]
The addresses of the bridge adapter to use.
fees
uint256[]
The fees to be paid to the bridge adapters (in the same order as adapters).
bridgeOptions
bytes[]
Additional params to be used by each adapter. Refer to the documentation of the specific adapter you are using
Events emitted
The following events are emitted after a transfer has been sent:
From the Lucid Wrapper contract:
The data bytes array is emitted unchanged from the input parameters.
From the Asset Controller contract:
The transferId can be used to:
Resend the transfer using another adapter
Track delivery status on the destination chain or the Lucid App
resendTransfer (multiple bridges)
If delivery fails in a multi-bridge setup, the transfer can be resent using another whitelisted adapter by calling resendTransfer().
Works similarly to the single-bridge
resendTransfertransferNo additional tokens are burned
The message is simply resent using the new adapter
transferId
bytes32
The unique identifier of the message.
adapters
address[]
The addresses of the bridge adapters.
fees
uint256[]
The fees to be paid to the bridge adapters (in the same order as adapters).
bridgeOptions
bytes[]
Additional params to be used by each adapter. Refer to the documentation of the specific adapter you are using
Events emitted
The following events are emitted after a transfer has been sent:
From the Lucid Wrapper contract:
From the Asset Controller contract:
Structs
DepositInput
PermitData
Fees
Before bridging assets, you should first estimate the fees. To do this, call the corresponding function on the Lucid Wrapper contract on the source chain, providing the controller address, the destination chain ID, and the amount to be bridged. The function will return both the estimated fee and the net amount you will receive on the destination chain.
Note that some transfers do not incur a fee, in which case you will receive the full amount.
Multi-hop transfer
To create a multi-hop transfer, you construct and pass the multi-hop configuration in the data parameter of transferTo or transferToWPermit functions. If a transfer is not multi-hop, then the data parameter is an empty bytes array.
In multi-hop transfers, the recipient of the tokens in the mid-point chain is the 2-of-3 Safe multisig. The address of the multisig should be passed as the recipient in the DepositInput struct. As a result, the destChainId in the same struct is the chain id of the midpoint chain. For the addresses/chain ids, refer to this page.
Read more about how to construct the data parameter in this page.
Token Minting
Once the message is delivered to the destination Asset Controller by the bridge adapters, the transfer must be executed.
Lucid will automatically execute the transfer once it becomes eligible. However, anyone can manually execute it by calling the following function on the asset controller on the destination chain, passing the transfer ID:
This function can be called by any account.
Last updated