IBC Token Transfer Basics
IBC token transfers function through a packet-relay mechanism between chains:Core Transfer Mechanism
- Token Escrow/Burn: When a token is sent from its source chain, it is escrowed (for native tokens) or burned (for non-native tokens) on the sending chain.
- Packet Relay: An IBC packet containing transfer details is sent to the destination chain.
-
Token Release/Mint: On the destination chain, the token is either:
- Released from escrow (if the destination is the original source of the token)
- Minted as an IBC voucher token (if the token is not native to the destination)
- Acknowledgement: The destination chain sends back an acknowledgement to confirm receipt of the packet.
Denomination Trace
To track the origin of tokens as they move between chains, IBC uses denomination traces:- Native Tokens: When sent to another chain, native tokens (e.g.,
untrn
) become prefixed with path information:{destPort}/{destChannel}/{denom}
- IBC Tokens: When received from another chain, tokens carry their full path history
untrn
on Neutron is sent to Cosmos Hub via channel-1- On Cosmos Hub, it appears as
transfer/channel-X/untrn
- If sent back to Neutron, it reverts to its original form:
untrn
Neutron’s Enhanced Transfer Module
Neutron extends the standard IBC transfer module with contract-focused features:Contract Detection and Handling
The Transfer module automatically detects contract senders and applies specific handling:-
Contract Detection: The module uses
HasContractInfo(ctx, senderAddress)
to determine if the sender is a smart contract. -
Contract-Specific Validation: For contract senders, the module validates fees using
msg.Fee.Validate()
. -
Fee Locking: For contracts, fees are automatically locked using
FeeKeeper.LockFees()
before sending the packet.
Enhanced Response Objects
Standard IBC transfers return minimal information. Neutron enhances this:-
Extended Response: The
MsgTransferResponse
includes:sequence_id
: The IBC packet sequence numberchannel
: The source channel ID
- Traceability: These fields enable correlation between transfer requests and their outcomes.
Callback System
The Transfer module implements a callback system for contract senders:- Callback Trigger: When acknowledgements or timeouts are received, the module checks if the original sender was a contract.
-
Message Preparation: The module calls
keeper.PrepareSudoCallbackMessage()
to create the callback message. -
Sudo Call: The module executes
sudoKeeper.Sudo(ctx, senderAddress, msg)
to deliver the callback. -
Error Handling: Failed Sudo calls are logged but do not block IBC processing:
"HandleAcknowledgement: failed to Sudo contract on packet acknowledgement"
Fee Management
The Transfer module coordinates with the Fee Refunder module for packet fees:-
Fee Validation: Only contracts must provide valid fees (
Validate(isContract bool)
method). -
Fee Locking: Before packet transmission, contracts’ fees are locked via
FeeKeeper.LockFees()
. -
Fee Distribution: The module distributes fees to relayers:
DistributeAcknowledgementFee()
for successful packetsDistributeTimeoutFee()
for timed-out packets
Module Architecture
The Transfer module is implemented as a wrapper around the standard IBC Transfer module:Wrapper Pattern
Method Overrides
The module overrides key IBC handlers:OnAcknowledgementPacket()
: Adds callback processing after standard handlingOnTimeoutPacket()
: Adds callback processing after standard handlingTransfer()
: Adds contract detection, fee locking, and enhanced response
Standard IBC Delegation
For all other functionality (queries, denomination traces, parameters), the module delegates to the underlying standard IBC Transfer implementation.Error Handling and Processing
The Transfer module implements robust error handling:- Sudo Call Failures: Logged as debug messages but processing continues
- Fee Processing: Happens regardless of callback success/failure
- IBC Processing: Not blocked by contract callback failures
Contract Callback Behavior: The specific format and content of callback messages depend on the Contract Manager module’s
PrepareSudoCallbackMessage()
implementation. Contracts should refer to the Contract Manager module documentation for callback message specifications.