Each message will contain a nonce, however messages can be delivered in any order
BridgeHub->Ethereum
Step 1: User initiates bridging action in offchain UX app
From the perspective of the UX layer, the main difference is that it will need to estimate the necessary bridging fees offchain, and then ensure that the user can provide those fees in the final transaction.
# Transfer Assets originating from AH
XCM.execute({
Withdraw DOT from users account
Buy Execution & Transport fees with users assets on AH
Burn/Lock Assets (ENA or PNA)
??? Burn Fees needed on BH (Teleport Initiated) ???
Send XCM to BH {
ReceiveTeleportedAssets(DOT)
Export command to Gateway (ExportMessage) {
Fee Assets teleported from AH (Teleport Completed)
ClearOrigin,
BuyExecution,
DepositAsset {
assets: filter,
beneficiary: AccountKey20,
},
}
}
})
# Transfer ENA originating from Hydra
XCM.execute({
Fee assets provided from from Hydra (ReserveAssetDeposited)
Buy Execution & Transport fees with users assets
Burn/Lock Assets (ENA or PNA)
Send XCM to BH {
Origin IS /AssetHub
DescendOrigin /AssetHub/Alice
Buy Execution/Transport fees
Export command to Gateway
}
})
Teleport DOT to users account on BH
Export an inner message to Ethereum.
The inner message should contain instructions that tell BH to take fees from users account on BH.
Transact bridge
Since non-system parachains cannot effectively transfer DOT to BH without going through AH or the relay chain, users on those parachains will need to pre-fund fees in their accounts on BH.
For the entrypoint, users will need to execute the following on BH:
The EthereumTransactor.transact extrinsic will:
Withdraw the reward from the origin location's SA
Commit the transact and the delivery reward
Step 2: Accepting a message and committing it for a delivery
A global nonce will be incremented and inserted into the message payload,
Message payloads will be stored in an MMR, with each nonce corresponding to an MMR leaf index. The leaf format will be Ethereum abi-encoded for easy processing on the Ethereum side
To incentivize message delivery and alert relayer about new pending messages, additional data will be inserted into the PendingMessagesstorage map.
The fees provided with the message will be locked in the origin's sovereign account on BH.
Step 3: Ensuring delivery by adding fees
Hopefully a relayer will decide to relay the message across the bridge, after determining that the job is profitable.
If no relayer picks up the job, the user can add additional fees to make the job more attractive.
This extrinsic will update the Reward in the PendingMessages storage map.
Step 4: The message is delivered to the Gateway contract
The relayer calls Gateway.submitV2(message, proof, rewardAddress)
The rewardAddress is an address on AssetHub where the relayer will be rewarded.
In order to prevent replay of messages delivered to the Gateway, we need to mark message nonces as delivered using a growable bitmap
The Gateway emits an event InboundMessageDispatched(nonce, rewardAddress, messageId)
Other Changes
On-chain gas usage estimation is obsolete and will be removed
The relayer pays for all execution. Even for transact.
Step 5: The relayer submits proof-of-delivery back to BH
The relayer relays proof back to BH that the Gateway emitted The Gateway emitted InboundMessageDispatched(nonce, rewardAddress, messageId).
The delivery will marked by removing the message from PendingMessages
Step 6: The relayer is rewarded on AssetHub
An XCM is sent to AssetHub that teleports DOT into the account specified by InboundMessageDispatched.rewardAddress.
Ethereum->BridgeHub
Unordered messages
As with the other direction, messages can be delivered in any order. Bitmaps will be used to store delivery status and prevent replay.
Fees
Relayers will now be able to claim their rewards on AssetHub. This solves the existing problem where fees are just collected on the Ethereum side and can only be transferred to an EOA wallet using a privileged governance call.
The user will pay an ETH fee upfront. This will be exchanged for WDOT behind the scenes
The WDOT fee amount will be included in the message
When the message is delivered to BridgeHub, an additional XCM will be sent to AssetHub to mint DOT into the relayers account
Fees will be estimated off-chain, and users can supply any fee. This obviously will result in trapped assets on AssetHub if the fees are not high enough. We will therefore need to depend on XCMv5 which has better support for trapping and claiming assets.
Scenario: Gateway->Polkadot token transfers
For both ENA and PNA assets.
User API:
User must provide Ether to the transaction. the quoteSendTokenFee API will calculate the minimum that ether must be provided by examining destinationFeeToken, destinationFee and relayerReward
User calls gateway to initiate a bridging action, with these inputs
token, amount, dest para, dest account, dest fee
The fee token on the final destination. Can be either WETH, or a PNA supported by the final dest
Ether for the relayer reward
Relayer delivers message to BH and provides funds for subsequent processing
Pays DOT for execution on BH
Pays DOT for local XCM transport fees to AH
Pays DOT for remote execution on AH, and delivery fee to final para
XCM is sent to AH
AH executes XCM. DOT is transferred from SA of Gateway to relayer and optionally used for fees on final destination.
XCM is sent to final destination
Since relayers must front DOT from their account on BH, they will need to perform an off-chain check to see whether the provided Ether is valuable enough to offset their cost on BH.
Scenario: Transact
User must provide Ether to the transaction for relayer reward
User includes WETH in message. Other inputs:
Destination, Call bytes
Location of fee token on dest, and fee amount
Maximum weight that the call can consume on the dest
Relayer pays normal transaction fee on BH
Relayer is rewarded WETH on AH
Final execution on dest para paid for from pre-funded sovereign account of msg.sender Specifically: LocationToAccountId(/Ethereum/AddressKey20(msg.sender))
Off-chain fee estimation
Hydra->AH->BH->Gateway
Fees need to be estimated on all four consensus systems:
Source Fees (XCM)
XCM transport & execution costs on Hydra, AH, BH. Estimation can be done using the new XCM DryRun runtime APIs.
Flow:
Dry run XCM on Hydra, output fees and XCM that is sent to AH
Dry run XCM on AH, output fees and XCM that is sent to BH
Dry run XCM on BH, output fees
Destination Fees (Ethereum)
We will implement a helper library that takes as inputs the following and produces an estimated fee in DOT:
Ethereum gas price
ETH/DOT exchange rate
A static table of worst-case gas usage for each bridge command
For Transact an additional user-specified parameter can state the worst case gas usage for the inner nested call
Mitigating volatility
Even with the accuracy of off-chain estimation, there could be volatility with the ETH/DOT rate and gas price. A 20% buffer should be added to cover these.
Gateway->BH->AH->Hydra
The entry point for fee estimation will be BH. We will need to add a custom runtime API to BH that:
function sendToken(
// Address of ENA or PNA token
address token,
// Amount to send
uint128 amount,
// Destination para (multi-hop)
ParaID destination,
// Destination account
bytes32 destinationAccount,
// Wrapped ERC20 token used to pay for fees on final destination
// Either WETH, or a PNA. User must own token
address destinationFeeToken,
// XCM transport and execution fee on the destination parachain
uint128 destinationFee,
// XCM execution fee and delivery fee to destination parachain (DOT)
uint128 assetHubFee
// relayer reward deposited on AH
uint128 relayerReward,
)