Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update for multitoken #39

Merged
merged 5 commits into from
Jul 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading