Explanation
This document explains the principles, architecture, and internal mechanisms of the Fee Refunder module.
Core Concepts
The IBC Relayer Challenge
IBC relayers perform the critical task of facilitating communication between blockchains. They:
- Monitor packets on the source chain
- Submit proofs of these packets to the destination chain
- Return acknowledgements or timeouts back to the source chain
However, this work incurs costs in gas fees, creating an economic challenge: How do we ensure relayers are properly compensated for their services?
The Spam Attack Problem
Without an appropriate fee mechanism, the IBC infrastructure is vulnerable to abuse:
- Malicious actors could send numerous IBC packets without paying for the relaying costs
- Smart contracts could deliberately create infinite loops of IBC messages (send → acknowledge → send new message → acknowledge → etc.)
- Relayers would quickly stop serving chains where they consistently lose money
The Solution
The Fee Refunder module provides a solution inspired by, but not fully implementing, the ICS-29 specification:
- Fee Pre-payment: Smart contracts must pre-pay fees for acknowledgement and timeout handling
- Fee Escrow: Fees are locked in the module until the packet is resolved
- Conditional Refunds: Depending on the packet outcome (ack or timeout), the appropriate fee is distributed
This creates a sustainable economic model for both the chain and its relayers.
Architecture
graph TD
A[Smart Contract] -->|Send IBC transaction with Fees| B[Fee Refunder Module]
B -->|Lock Fees| C[Escrow Account]
D[IBC Relayer] -->|Deliver Ack| E[IBC Module]
F[IBC Relayer] -->|Deliver Timeout| E
E -->|Process Ack| G[Fee Refunder: Distribute Ack Fee]
E -->|Process Timeout| H[Fee Refunder: Distribute Timeout Fee]
G -->|Pay Ack Fee| D
G -->|Refund Timeout Fee| A
H -->|Pay Timeout Fee| F
H -->|Refund Ack Fee| A
Implementation Details
Fee Structure
The Fee structure includes:
message Fee {
repeated cosmos.base.v1beta1.Coin recv_fee = 1;
repeated cosmos.base.v1beta1.Coin ack_fee = 2;
repeated cosmos.base.v1beta1.Coin timeout_fee = 3;
}
ack_fee: Coins paid to the relayer who delivers the acknowledgementtimeout_fee: Coins paid to the relayer who delivers the timeoutrecv_fee: Currently must be zero (used for ICS-29 compatibility)
Fee Locking
When a smart contract sends an IBC packet (via MsgTransfer or MsgSubmitTx), the module:
- Validates that the provided fees meet the minimum requirements
- Locks the total fee amount (ack_fee + timeout_fee) in the module's account
- Stores the fee information associated with the packet ID
Core Logic (simplified):
- Validate the channel exists
- Check fees meet minimum requirements
- Store fee information with packet ID
- Transfer total fees to module account
- Emit lock_fees event
Fee Distribution for Acknowledgements
When an IBC acknowledgement is received, the module:
- Retrieves the stored fee information for the packet
- Sends the acknowledgement fee to the relayer who delivered the ack
- Returns the timeout fee to the original payer (smart contract)
- Removes the fee information from storage
Core Logic:
- Retrieve stored fee information for the packet
- Send acknowledgement fee to the relayer
- Return unused timeout fee to original payer
- Emit distribute_ack_fee event
- Remove fee information from storage
Fee Distribution for Timeouts
When an IBC timeout is received, the module:
- Retrieves the stored fee information for the packet
- Sends the timeout fee to the relayer who delivered the timeout
- Returns the acknowledgement fee to the original payer (smart contract)
- Removes the fee information from storage
Core Logic:
- Retrieve stored fee information for the packet
- Send timeout fee to the relayer
- Return unused acknowledgement fee to original payer
- Emit distribute_timeout_fee event
- Remove fee information from storage
Minimum Fee Enforcement
To prevent spam and ensure relayers are properly compensated, the module enforces minimum fees:
- Governance sets minimum required fees via the
min_feeparameter - The
checkFeesfunction validates that provided fees meet or exceed these minimums - Transactions with insufficient fees are rejected
Fee Validation:
- Timeout fee must meet or exceed minimum governance-set timeout fee
- Acknowledgement fee must meet or exceed minimum governance-set ack fee
- Fee denominations must be allowed (present in minimum fee parameters)
- Receive fee must be zero (not supported)
Compatibility with ICS-29
While inspired by ICS-29, the Fee Refunder module operates independently for several reasons:
- Compatibility: It allows Neutron to connect with chains that don't support ICS-29
- Interface Consistency: It maintains the same API interface as ICS-29 for developer ease
- Future Upgrade Path: When Neutron eventually supports native ICS-29, contracts won't need changes
The key difference is that the Fee Refunder only handles acknowledgements and timeouts, not receive packets, as those would require support from counterparty chains.
Security Considerations
The module includes several security measures:
- Atomic Operations: Fee locking and distribution use atomic operations to prevent partial state changes
- Escrow Model: Fees are locked until packet resolution, ensuring relayers can trust they'll be paid
- Fee Validation: Only allowed denominations with sufficient amounts can be used as fees
- Receive Fee Prevention: Receive fees are prohibited to prevent compatibility issues with other chains