Fungible Token Interface (TIP-3.1)
Requires: TIP-6.1
Abstract
The following standard allows for the implementation of a standard API for tokens within smart contracts. General information about token is stored in the token root contract. Each token holder has its own instance of token wallet contract. Token transfers SHOULD be implemented in P2P fashion, between sender and receiver token wallets.
Motivation
A standard interface allows any tokens on Venom to be re-used by other applications: from wallets to decentralized exchanges.
Specification
The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.
Notes
- We choose Standard Interface Detection to expose the interfaces that a TIP3 smart contract supports.
- This standard does not define the external methods to initiate transfer, mint or burn tokens. Though it defines the methods, which MUST be called on a recipient token wallet or token root during these operations.
- The rules for a token wallet ownership MUST be defined in a child standards.
- A
-1
offset is added to some function IDs derivations, so the preimage of the hash cannot be known, further reducing the chances of a possible collisions.
Token root
Name
Returns the name of the token - e.g. "MyToken".
function name() public view responsible returns (string);
Symbol
Returns the symbol of the token. E.g. “HIX”.
function symbol() public view responsible returns (string);
Decimals
Returns the number of decimals the token uses - e.g. 8, means to divide the token amount by 100000000 to get its user representation.
function decimals() public view responsible returns (uint8);
Total supply
Returns the total token supply.
function totalSupply() public view responsible returns (uint128);
Token wallet code
Returns the token wallet code.
function walletCode() public view responsible returns (TvmCell);
Accept tokens burn
Does not have a standard signature, but has a standard function ID 0x192B51B1
obtained as tvm.functionId('acceptBurn(uint128)') - 1
. The uint128 _value
parameter MUST be first. The function name and the rest of the parameters are not fixed by this standard and can be reinvented for each substandard.
Decreases token total supply by _value
. The contract MUST check that the sender is a correct token wallet. Before sending this message, caller token wallet MUST decrease its own balance by _value
. If the mint can't be accepted (e.g. invalid sender), this message MUST be bounced.
Any function from the following snippet is a valid example:
interface TIP3AcceptBurn {
function acceptBurn(uint128 _value) functionID(0x192B51B1) public;
function acceptBurn2(uint128 _value, uint256 _publicKey, address _owner) functionID(0x192B51B1) public;
function acceptBurn3(uint128 _value, TvmCell _meta) functionID(0x192B51B1) public;
}
Standard interface detection
interface TIP3TokenRoot {
function acceptBurn(uint128 _value) functionID(0x192B51B1) public view responsible;
function name() public view responsible returns (string);
function symbol() public view responsible returns (string);
function decimals() public view responsible returns (uint8);
function totalSupply() public view responsible returns (uint128);
function walletCode() public view responsible returns (TvmCell);
}
The token root interface ID is 0x4371D8ED
.
Token wallet
Root
Returns the token root address.
function root() public view responsible returns (address);
Balance
Returns the token wallet balance.
function balance() public view responsible returns (uint128);
Wallet code
Returns the token wallet code.
function walletCode() public view responsible returns (TvmCell);
Accept tokens transfer
Does not have a standard signature, but has a standard function ID 0x67A0B95F
obtained as tvm.functionId('acceptTransfer(uint128)') - 1
. The uint128 _value
parameter MUST be first. The function name and the rest of the parameters are not fixed by this standard and can be reinvented for each substandard.
Increases token wallet balance by _value
. The contract MUST check that the sender is a correct token wallet. Before sending this message, caller token wallet MUST decrease its own balance by _value
. If the transfer can't be accepted (e.g. invalid sender), this message MUST be bounced.
Any function from the following snippet is a valid example:
interface TIP3AcceptTransfer {
function acceptTransfer(uint128 _value) functionID(0x67A0B95F) external;
function acceptTransfer2(uint128 _value, uint256 _publicKey, address _owner) functionID(0x67A0B95F) external;
function acceptTransfer3(uint128 _value, TvmCell _meta) functionID(0x67A0B95F) external;
}
Accept tokens mint
Does not have a standard signature, but has a standard function ID 0x4384F298
obtained as tvm.functionId('acceptMint(uint128)') - 1
. The uint128 _value
parameter MUST be first. The function name and the rest of the parameters are not fixed by this standard and can be reinvented for each substandard.
Increases token wallet balance by _value
. The contract MUST check that the sender is a correct token root. Before sending this message, token root MUST increase the total supply by _value
. If the mint can't be accepted (e.g. invalid sender), this message MUST be bounced.
Any function from the following snippet is a valid example:
interface TIP3AcceptMint {
function acceptMint(uint128 _value) functionID(0x4384F298) external;
function acceptMint2(uint128 _value, uint256 _publicKey, address _owner) functionID(0x4384F298) external;
function acceptMint3(uint128 _value, TvmCell _meta) functionID(0x4384F298) external;
}
On-bounce behaviour
The acceptTransfer
or acceptBurn
methods can be bounced, e.g. receiver token wallet has a different code or burning disabled. The token wallet behaviour in these cases should be implemented according to the following rules.
Handle acceptTransfer
bounce
Increases token wallet balance according to the value, specified in the bounce body.
Handle acceptBurn
bounce
Increases token wallet balance according to the value, specified in the bounce body.
Standard interface detection
interface TIP3TokenWallet {
function acceptTransfer(uint128 _value) functionID(0x67A0B95F) external;
function acceptMint(uint128 _value) functionID(0x4384F298) external;
function root() public view responsible returns (address);
function balance() public view responsible returns (uint128);
function walletCode() public view responsible returns (TvmCell);
}
The token wallet interface ID is 0x4F479FA3
.
References
The original TIP-3.1 standard was developed and maintained by the Everscale network community.