Interchain Gas Payment
To deliver a message, a transaction must be included on the destination chain that calls the Mailbox process
function with the encoded message and ISM metadata.
For convenience, relayers watch for dispatched messages and will submit process transactions on behalf of the message sender if they receive sufficient payment on the origin chain. We refer to this as interchain gas payment.
Because messages can trigger arbitrary code execution, the relayer must meter the handle
call with a gasLimit
to charge appropriately at message dispatch time.
Post Dispatch
During the post-dispatch hook, the InterchainGasPaymaster
contract will revert if payment is insufficient to cover the relayer's anticipated costs. The relayer will honor quotes from dispatch
time.
Gas Limit
When none is specified, the gasLimit
for metering the handle
call uses a static default of 50_000
.
We recommend developers benchmark their handle
implementations in unit tests to determine a reasonable gasLimit
to use.
If you expect the handle
function to consume more than this default, you should override the default gasLimit
in metadata.
Refunds
If the message sender pays more than the hook quotes, the contract will refund the difference. If none is specified, the refund address will default to the message sender. This allows senders to skip explicit quoteDispatch
calls.
Refunds can present a risk of reentrancy. Special care should be taken to ensure safety against reentrancy exploits.
Refunds are only made if payment is greater than the quote. Refunds are not made if delivery requires less gas than what was paid. If a refund is unsuccessful, the payForGas
call will revert. To specify a different refund address, override the default refundAddress
in metadata.
Metadata
This hook expects metadata in a packed encoding of StandardHookMetadata
. See the Mailbox dispatch overloads for how to pass metadata overrides.
- Solidity
struct StandardHookMetadata {
uint16 variant;
uint256 msgValue;
uint256 gasLimit;
address refundAddress;
}
Examples
bytes memory metadata = abi.encodePacked(
StandardHookMetadata({
variant: 1, // only variant supported by this hook
msgValue: 0, // unused by this hook
gasLimit: 100000, // override default gas limit
refundAddress: msg.sender // override default refund address
})
);
Gas Oracles
The interchain gas payment requirement is calculated using oraclized gas price and exchange rates between supported origin and destination chains.
Exchange rates and gas prices are up to the relayer to decide. A spread may be charged to account for drift and operating costs.
- Solidity
view
override
returns (uint128 tokenExchangeRate, uint128 gasPrice)
{
IGasOracle _gasOracle = destinationGasConfigs[_destinationDomain]
Parameters
destinationDomain
: The message's destination domain
Returns
tokenExchangeRate
: The exchange rate between the origin and destination chain's gas tokensgasPrice
: The gas price for the destination chain
The quoteGasPayment
function calculates fees for the relayer's anticipated costs.
- Solidity
uint32 _destinationDomain,
uint256 _gasLimit
) public view virtual override returns (uint256) {
// Get the gas data for the destination domain.
(
uint128 _tokenExchangeRate,
Parameters
destinationDomain
: The message's destination domaingasLimit
: The gas limit to meter thehandle
call with
Returns
fee
: The payment required for thepostDispatch
to succeed
Retrying
If the handle
call consumes more gas than quoted, the relayer will not submit a process transaction. In this case, additional gas can be paid for with the payForGas
function.
- Solidity
function payForGas(
bytes32 _messageId,
uint32 _destinationDomain,
uint256 _gasAmount,
address _refundAddress
) external payable;
Parameters
messageId
: The message identifier returned fromdispatch
calldestinationDomain
: The message's destination domaingasAmount
: The additional gas amount to pay forrefundAddress
: The address to refund excess payment to