Skip to main content

Changelog

  • 24-05-2023: Initial draft

Status

Accepted and applied in v7.1 of ibc-go

Context

Every ICS-20 transfer channel has its own escrow bank account. This account is used to lock tokens that are transferred out of a chain that acts as the source of the tokens (i.e. when the tokens being transferred have not returned to the originating chain). This design makes it easy to query the balance of the escrow accounts and find out the total amount of tokens in escrow in a particular channel. However, there are use cases where it would be useful to determine the total escrowed amount of a given denomination across all channels where those tokens have been transferred out. For example: assuming that there are three channels between Cosmos Hub to Osmosis and 10 ATOM have been transferred from the Cosmos Hub to Osmosis on each of those channels, then we would like to know that 30 ATOM have been transferred (i.e. are locked in the escrow accounts of each channel) without needing to iterate over each escrow account to add up the balances of each. For a sample use case where this feature would be useful, please refer to Osmosis’ rate limiting use case described in #2664.

Decision

State entry denom -> amount

The total amount of tokens in escrow (across all transfer channels) for a given denomination is stored in state in an entry keyed by the denomination: totalEscrowForDenom/{denom}.

Panic if amount is negative

If a negative amount is ever attempted to be stored, then the keeper function will panic:

Delete state entry if amount is zero

When setting the amount for a particular denomination, the value might be zero if all tokens that were transferred out of the chain have been transferred back. If this happens, then the state entry for this particular denomination will be deleted, since Cosmos SDK’s x/bank module prunes any non-zero balances:

Bundle escrow/unescrow with setting state entry

Two new functions are implemented that bundle together the operations of escrowing/unescrowing and setting the total escrow amount in state, since these operations need to be executed together. For escrowing tokens:
For unescrowing tokens:
When tokens need to be escrowed in sendTransfer, then escrowToken is called; when tokens need to be unescrowed on execution of the OnRecvPacket, OnAcknowledgementPacket or OnTimeoutPacket callbacks, then unescrowToken is called.

gRPC query endpoint and CLI to retrieve amount

A gRPC query endpoint is added so that it is possible to retrieve the total amount for a given denomination:
And a CLI query is also available to retrieve the total amount via the command line:

Consequences

Positive

  • Possibility to retrieve the total amount of a particular denomination in escrow across all transfer channels without iteration.

Negative

No notable consequences

Neutral

  • A new entry is added to state for every denomination that is transferred out of the chain.

References

Issues: PRs: