Skip to content

Commit

Permalink
Merge pull request #39 from anoma/yuji/ibc-multitoken
Browse files Browse the repository at this point in the history
update for multitoken
  • Loading branch information
cwgoes authored Jul 2, 2023
2 parents 72c0bd4 + bdf636b commit 4eefb04
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 79 deletions.
26 changes: 4 additions & 22 deletions packages/specs/pages/base-ledger/fungible-token.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,10 @@

The fungible token validity predicate authorises token balance changes on the basis of conservation-of-supply and approval-by-sender. Namada implements a "multitoken" validity predicate, in that all tokens have the same logic and can share one VP (with appropriate storage distinctions).

A token balance is stored with a storage key. The token balance key should be `{token_addr}/balance/{owner_addr}` or `{token_addr}/{sub_prefix}/balance/{owner_addr}`. `{sub_prefix}` can have multiple key segments. These keys can be made with [token functions](https://github.com/anoma/namada/blob/5da82f093f10c0381865accba99f60c557360c51/core/src/types/token.rs).
A token balance is stored with a storage key. The token balance key should be `#Multitoken/{token_addr}/balance/{owner_addr}`. These keys can be made with [token functions](https://github.com/anoma/namada/blob/5da82f093f10c0381865accba99f60c557360c51/core/src/types/token.rs).

We can have multitoken balances with the same token and the same owner by `{sub_prefix}`, e.g. a token balance received over IBC is managed in `{token_addr}/ibc/{ibc_token_hash}/balance/{receiver_addr}`. It is distinguished from the receiver's original balance in `{token_addr}/balance/{receiver_addr}` to know which chain the token was transferred from.
We can have multitoken balances for the same owner by `{token_addr}`, e.g. a token received over IBC is managed in `#Multitoken/{ibc_token}/balance/{receiver_addr}`. It is distinguished from the receiver's original balance in `#Multitoken/{token_addr}/balance/{receiver_addr}` to know which chain the token was transferred from. The `{ibc_token}` is explained in [IBC](../interoperability/ibc.md).

The transfers between the following keys are allowed:
Transfers between the balances with the same `{token_addr}` are allowed. Specifically, we can transfer a token from `#Multitoken/{token_addr}/balance/{sender_addr}` to `#Multitoken/{token_addr}/balance/{receiver_addr}`.

| Source | Target |
|----|----|
| `{token_addr}/balance/{sender_addr}` | `{token_addr}/balance/{receiver_addr}` |
| `{token_addr}/{sub_prefix}/balance/{sender_addr}` | `{token_addr}/{sub_prefix}/balance/{receiver_addr}` |

A transfer can be allowed from a balance without `{sub_prefix}` to another one without `{sub_prefix}` and between balances with the same `{sub_prefix}`. The `{sub_prefix}` can be given with `--sub-prefix` argument when Namada CLI `namadac transfer`.

Some special transactions can transfer to another balance with the different `{sub_prefix}`. IBC transaction transfers from a balance with `{sub_prefix}` to another balance with a different `{sub_prefix}`. IBC transfers handle the sub prefix `ibc/{port_id}/{channel_id}` for the IBC escrow, mint, and burn accounts and the sub prefix `ibc/{ibc_token_hash}` for receiving a token. IBC transaction transfers a token between the following keys:

| IBC operation | Source | Target |
|----|----|----|
| Send (as the source) | `{token_addr}/balance/{sender_addr}` | `{token_addr}/ibc/{port_id}/{channel_id}/balance/IBC_ESCROW` |
| Send (to the source) | `{token_addr}/balance/{sender_addr}` | `{token_addr}/ibc/{port_id}/{channel_id}/balance/IBC_BURN` |
| Refund (when sending as the source) | `{token_addr}/ibc/{port_id}/{channel_id}/balance/IBC_ESCROW` | `{token_addr}/balance/{sender_addr}` |
| Refund (when sending to the source) | `{token_addr}/ibc/{port_id}/{channel_id}/balance/IBC_BURN` | `{token_addr}/balance/{sender_addr}` |
| Receive (as the source) | `{token_addr}/ibc/{port_id}/{channel_id}/balance/IBC_ESCROW` | `{token_addr}/balance/{receiver_addr}` |
| Receive (from the source) | `{token_addr}/ibc/{port_id}/{channel_id}/balance/IBC_MINT` | `{token_addr}/ibc/{ibc_token_hash}/balance/{receiver_addr}` |

[IBC token validity predicate](https://github.com/anoma/namada/blob/5da82f093f10c0381865accba99f60c557360c51/shared/src/ledger/ibc/vp/token.rs) should validate these transfers. These special transfers like IBC should be validated by not only the fungible token validity predicate but also other validity predicates.
These balance changes are validated by the multitoken validity predicate. It also checks the minted or burned token. If a token is minted or burned, i.e. when `#Multitoken/{token_addr}/balance/minted` is updated in the transaction, not only the total minted balance is checked but also calling the minter's validity predicate is checked. The minter should be set in a transaction minting the token. For example, when a token is received over IBC, the received token will be minted for the receiver's balance `#Multitoken/{ibc_token}/balance/{receiver_addr}`. The minted balance `#Multitoken/{ibc_token/balance/minted` is also increased by the amount of the received token. The minted amount should be checked by the multitoken validity predicate. And, the multitoken validity predicate checks if the minter's validity predicate, the IBC validity predicate in this case, will be called (IBC validity predicate checks the minted amount is correct for the corresponding IBC operation).
Loading

0 comments on commit 4eefb04

Please sign in to comment.