TIP-3

This document is better viewed at https://docs.broxus.com/tip3

The TIP-3 token standard is a distributed token standard designed specifically for TVM-like networks. It was developed as part of the work of the Everscale blockchain. It offers a number of advantages over traditional token standards, such as ERC-20, including a more efficient storage and management of token balances and the ability to avoid the high maintenance costs associated with sharding the registry.

The TIP-3 standard is made up of a set of interfaces, contracts, and utilities that work together to facilitate the creation and management of tokens. The core contracts that implement the behavior specified in the standard are:

For an overview of TIP-3 tokens and a walk through on how to create a token contract read our TIP-3 guide.

Core

TIP3TokenRoot: is an interface that defines the minimal required functionality for a TIP-3 compliant token root contract. It includes functions for querying the name, symbol, number of decimals, total supply, and wallet code of the token. These functions are used for display purposes and do not affect the contract’s arithmetic.

ITokenRoot: the interface for the token root contract that stores general information about the token, such as the name, symbol, `decimals, and totalSupply.

TokenRootBase: is an implementation of the TIP-3 token standard. It provides the minimal required functionality for a token root contract, including storing general information about the token such as name, symbol, decimals, and total supply. This contract serves as the foundation for other contracts that build upon it, such as the:

which add additional functionality to the basic token root contract.

TIP3TokenWallet: is an interface that defines the minimal functionality required for a TIP-3 token wallet contract.

ITokenWallet: the interface for the token wallet contract that represents each token holder’s balance, and functions for transferring tokens, accepting transfers and mints from root contract, and querying owner and wallet information. It also includes the SID interface for interface detection.

TokenWalletBase: is an implementation of the TIP-3 token standard. It provides the minimal required functionality for a token wallet contract, including storing information about the balance of the tokens. This contract serves as the foundation for other contracts that build upon it, such as the:

which add additional functionality to the basic token wallet contract.

Full Implementation of TIP-3

TokenRoot: This contract stores general information about the token, such as name, symbol, decimals, walletCode_. It also includes functionality for transferring ownership of the token root contract and the ability to burn and pause token burning.

TokenRootUpgradeable: an implementation of the ITokenRootUpgradeable interface, which allows for the upgrading of the token root contract.

TokenWallet: Each token holder has their own instance of this contract, which stores information about the balance of the tokens. Token transfers happen in a decentralized fashion between the wallets of the sender and the recipient.

TokenWalletUpgradeable: Similar to TokenWallet, but with the added ability to upgrade the contract.

Abstract Contracts

In addition to these core contracts, there are also several abstract contracts that provide additional functionality. These include:

TokenRootBurnableByRootBase: This contract extends the functionality of TokenRoot and allows for burning tokens of any wallet, disabling the ability to burn tokens through the TokenRoot, and a view method that returns the state of 'burnByRootDisabled_'.

TokenRootBurnPausableBase: This contract extends the functionality of TokenRoot and allows for starting and stopping burning tokens, and a view method that returns the state of burnPaused_.

TokenRootDisableableMintBase: This contract extends the functionality of TokenRoot and allows for permanently disabling token minting, and a view method that returns the state of mintDisabled_.

TokenRootTransferableOwnershipBase: This contract extends the functionality of TokenRoot and adding a 1-step ownership transfer mechanism.

TokenWalletBurnableBase: This contract extends the functionality of TokenWallet and allows for burning self-tokens.

TokenWalletBurnableByRootBase: This contract extends the functionality of TokenWallet and allows for burning tokens by TokenRoot.

TokenWalletDestroyableBase: This contract extends the functionality of TokenWallet and allows for destroying the wallet.

Additional contracts

SID: The contract in TIP-6.1 standard defines a method for determining the interfaces implemented by a smart contract on the TVM-liked networks. It uses the XOR of all function selectors in the interface as the identifier for the interface. This allows for querying if a contract supports a specific interface and adapting the way it is interacted with.

TokenFactory: the contract that is used to create new token roots.

TokenRoot

This document is better viewed at https://docs.tip3.com/token-root

The TokenRoot contract is an implementation of the all required and optional functionality TIP-3 Token Standard.

Each token holder has its own instance of the TokenWallet contract, which stores information about the balance of the tokens. Token transfers happen in a peer-to-peer fashion, between the sender’s and recipient’s token wallets.

Including storing general information about the token such as name, `symbol, decimals, and totalSupply. It also includes functionality for transferring ownership of the token root contract and for burning and pausing token burning, minting.

TokenRoot is based on abstractions such as:

that add additional functionality to the basic token root contract. These contracts are designed to extend the functionality of TokenRoot contract and allows for burning tokens of any wallet, disabling the ability to burn tokens through the TokenRoot, starting and stopping burning tokens, permanently disabling token minting, transferring ownership of the token root contract and so on.

Core

TIP3TokenRoot

import "@broxus-ton-tokens-contracts/contracts/interfaces/TIP3TokenRoot.sol";

Interface of the TIP-3.1 TokenRoot contract.

name() → string external

Returns the name of the token.

symbol() → string external

Returns the symbol of the token, usually a shorter version of the name.

decimals() → uint8 external

Returns the number of decimals used to get its user representation. For example, if decimals equals 6, a balance of 42_500_000 tokens should be displayed to a user as 42.5 (42_500_000 / 10 ** 6).

This information is only used for display purposes: it in no way affects any of the arithmetic of the contract.

totalSupply() → uint128 external

Returns the amount of tokens in existence.

walletCode() → TvmCell external

Returns the walletCode of the TokenWallet contract.

TokenRootDisableableMintBase

import "@broxus-ton-tokens-contracts/contracts/abstract/TokenRootDisableableMintBase.sol";

Implementation of the IBurnPausableTokenRoot interface.

This abstraction extends the functionality of TokenRootBase and increases the capabilities of TokenRoot, adding the ability to permanently disable token minting. And a view method that returns the state of mintDisabled_.

disableMint() → bool external

Post condition:

  • mintDisabled_ is set to true.

mintDisabled() → bool external

_mintEnabled() → bool internal

ITokenRoot

import "@broxus-ton-tokens-contracts/contracts/interfaces/ITokenRoot.sol";

Interface of the minimal required functionality of TIP-3 standard. The interface also inherits the supportInterface interface, which is used to identify whether the contract supports the interface. This is described in the TIP-6.1 standard. (see https://docs.everscale.network/standard/TIP-6.1)

rootOwner() → address external

Returns current owner address of TokenRoot.

walletOf(address owner) → address external

Derive TokenWallet address from owner address.

acceptBurn(uint128 amount, address walletOwner, address remainingGasTo, address callbackTo, TvmCell payload) external

Accepts burning amount of tokens from the TokenWallet, owned by walletOwner. Called by TokenWallet, when it receives burn request from the owner.

mint(uint128 amount, address recipient, uint128 deployWalletValue, address remainingGasTo, bool notify, TvmCell payload) external

Mint tokens to a specified recipient, optionally deploying a new token wallet for the recipient if necessary.

If deployWalletValue is greater than 0, token root MUST deploy token wallet for recipient. Otherwise, it mints tokens without deploying token wallet, which may lead to failed minting.

deployWallet(address owner, uint128 deployWalletValue) → address external

Deploy a new TokenWallet with initial balance.

TokenRootBase

import "@broxus-ton-tokens-contracts/contracts/abstract/TokenRootBase.sol";

Implementation of the ITokenRoot interface.

This abstraction describes the minimal required functionality of Token Root contract according to the TIP-3 standard.

Also used as a base class for implementing abstractions such as:

Modifiers

onlyRootOwner() modifier

Modifier than throws if called by any account other than the rootOwner_.

fallback() external

Default entrypoint if no other entry point fits.

name() → string external

symbol() → string external

decimals() → uint8 external

totalSupply() → uint128 external

walletCode() → TvmCell external

rootOwner() → address external

walletOf(address walletOwner) → address public

Precondition:

  • walletOwner cannot be the zero address.

deployWallet(address walletOwner, uint128 deployWalletValue) → address tokenWallet public

Precondtion:

  • walletOwner cannot be the zero address.

  • deployWalletValue must be enough to deploy a new wallet.

Postcondition:

  • Returns the address of the deployed wallet.

mint(uint128 amount, address recipient, uint128 deployWalletValue, address remainingGasTo, bool notify, TvmCell payload) external

Preconditions:

  • sender MUST be rootOwner.

  • Minting should be allowed on the TokenRoot contract.

  • Either recipients TokenWallet it must already be deployed, or there must be enough deployWalletValue available to deploy a new wallet.

  • amount cannot be zero.

  • recipient cannot be the zero address.

Postconditions:

  • The totalSupply_ must increase by the amount that is minted.

  • If deployWalletValue is greater than 0, then a new TokenWallet MUST be deployed.

acceptBurn(uint128 amount, address walletOwner, address remainingGasTo, address callbackTo, TvmCell payload) external

Preconditions:

  • Burning should be allowed on the TokenRoot contract.

  • Sender should be a valid token wallet deployed by this contract.

Postconditions:

  • The totalSupply_ must decrease by the amount that is burned.

  • If callbackTo is not set, remainingGasTo will receive the remaining gas, otherwise IAcceptTokensBurnCallback.onAcceptTokensBurn will be called on the callbackTo contract.

_mint(uint128 amount, address recipient, uint128 deployWalletValue, address remainingGasTo, bool notify, TvmCell payload) internal

Realization of TokenRootBase.mint function.

Postcondition:

  • totalSupply_ is increased by amount.

  • If deployWalletValue is zero then balance of recipient is increased by amount.

  • Else, new TokenWallet is deployed with initial balance equal to deployWalletValue.

  • ITokenWallet.acceptMint is called on the deployed wallet.

We pass bounce flag true in acceptMint, so that in the TokenWallet cannot accept the mint, then TokenWallet will bounce to the current onBounce, and the totalSupply will be decreased by amount.

_getExpectedWalletAddress(address walletOwner) → address internal

Derive wallet address from owner.

The function uses the tvm.hash, that computes the representation hash of of the wallet StateInit data and returns it as a 256-bit unsigned integer, then converted to an address.

For string and bytes it computes hash of the tree of cells that contains data but not data itself.

This allows the contract to determine the expected address of a wallet based on its owner’s address. See sha256 to count hash of data.

onBounce(TvmSlice slice) external

On-bounce handler.

Used in case ITokenWallet.acceptMint fails so the totalSupply_ can be decreased back.

sendSurplusGas(address to) external

Withdraw all surplus balance in EVERs. Can by called only by owner address.

_reserve() → uint128 internal

Calculates reserve EVERs for the remainder of the contract that subsequent output actions cannot spend more money than the remainder.

_targetBalance() → uint128 internal

Returns the target balance of the contract.

Target balance is used for tvm.rawReserve, which creates an output action that reserves EVER. It is roughly equivalent to creating an outgoing message that carries reserve nanoevers to itself, so that subsequent spend actions cannot spend more money than the reserve.

_mintEnabled() → bool internal

Checks if minting is enabled.

_burnEnabled() → bool internal

Checks if burning is enabled.

_buildWalletInitData(address walletOwner) → TvmCell internal

Builds the wallet StateInit data.

_deployWallet(TvmCell initData, uint128 deployWalletValue, address remainingGasTo) → address internal

Deploys new token wallet.

TokenRoot

import "@broxus-ton-tokens-contracts/contracts/TokenRoot.sol";

This is an implementation of TokenRoot that implements all the required methods of the TIP-3 standard.

You can read more about the standard TIP-3 in the documentation: https://docs.everscale.network/standard/TIP-3/

The token root contract stores general information about the token, such as name, symbol, decimals, walletCode_, see ITokenRoot.

Each token holder has its own instance of the token wallet contract, which stores information about the balance of the tokens, see ITokenWallet. The transfer of tokens is carried out in P2P mode between the wallets of the sender’s and recipient’s tokens.

constructor(address initialSupplyTo, uint128 initialSupply, uint128 deployWalletValue, bool mintDisabled, bool burnByRootDisabled, bool burnPaused, address remainingGasTo) public

Sets the values for mintDisabled_, burnByRootDisabled_, burnPaused_, and increases the totalSupply_ if initialSupply is not zero.

Parameters such as symbol, decimals, name, rootOwner_, randomNonce_ and walletCode_ are set during contract deployment, and passed as StateInit params`.

Also, the listed parameters, with the exception of totalSupply_ and burnPaused_, are immutable: they can only be set once during construction.

supportsInterface(bytes4 interfaceID) → bool external

Implementation of the SID interface.

_targetBalance() → uint128 internal

Implementation of the TokenRootBase._targetBalance virtual function.

_buildWalletInitData(address walletOwner) → TvmCell internal

The InitData consists of:

  • contr (contract) - defines the contract whose StateInit will be created. Mandatory to be set if the varInit option is specified.

  • varInit (initialization list) - used to set static variables of the contract, see TokenWalletBase. Conflicts with data and must be set contr.

    `root_` - the address of the TokenRoot contract.
    `owner_` - the address of the owner of the wallet.
  • pubkey` - the public key of the contract. The value 0 means that the wallet can be owned only by another contract. contract, the most common example is Account.

  • code - the code of the TokenWallet.

_deployWallet(TvmCell initData, uint128 deployWalletValue, address) → address internal

Implementation of the virtual function TokenRootBase._deployWallet.

Deploys a new TokenWallet contract according to the TIP-3 standard.

Abstractions

TokenRootBurnableByRootBase

import "@broxus-ton-tokens-contracts/contracts/abstract/TokenRootBurnableByRootBase.sol";

Implementation of the IBurnableByRootTokenRoot interface.

This abstraction extends the functionality of TokenRootBase and increases the capabilities of TokenRoot, namely burning tokens of any wallet, disabling the ability to burn tokens through the TokenRoot. And a view method that returns the state of 'burnByRootDisabled_'.

burnTokens(uint128 amount, address walletOwner, address remainingGasTo, address callbackTo, TvmCell payload) external

Preconditions:

  • burnByRootDisabled_ must be false.

  • amount must be greater than zero.

  • walletOwner must be a non-zero address.

For burning calls the IBurnableByRootTokenWallet.burnByRoot method of the wallet, so the TokenWallet must implement this method.

We pass the bounce true flag to the wallet, but this Bounce is not covered by the TokenRoot.

disableBurnByRoot() → bool external

burnByRootDisabled() → bool external

TokenRootBurnPausableBase

import "@broxus-ton-tokens-contracts/contracts/abstract/TokenRootBurnPausableBase.sol";

Implementation of the IBurnPausableTokenRoot interface.

This abstraction extends the functionality of TokenRootBase and increases the capabilities of TokenRoot, the ability to start and stop burning tokens. And a view method that returns the state of burnPaused_.

burnPaused() → bool external

Returns the current state of the ability to burn tokens.

setBurnPaused(bool paused) → bool external

Post condition:

  • burnPaused_ is set to the value of the paused parameter.

_burnEnabled() → bool internal

TokenRootDisableableMintBase

import "@broxus-ton-tokens-contracts/contracts/abstract/TokenRootDisableableMintBase.sol";

Implementation of the IBurnPausableTokenRoot interface.

This abstraction extends the functionality of TokenRootBase and increases the capabilities of TokenRoot, adding the ability to permanently disable token minting. And a view method that returns the state of mintDisabled_.

disableMint() → bool external

Post condition:

  • mintDisabled_ is set to true.

mintDisabled() → bool external

_mintEnabled() → bool internal

TokenRootTransferableOwnershipBase

import "@broxus-ton-tokens-contracts/contracts/abstract/TokenRootTransferableOwnershipBase.sol";

Implementation of the ITransferableOwnership interface.

This abstraction extends the functionality of TokenRootBase, adding a 1-step ownership transfer mechanism.

transferOwnership(address newOwner, address remainingGasTo, mapping(address => struct ICallbackParamsStructure.CallbackParams) callbacks) external

Precondition:

  • Caller must be owner.

Postconditions:

  • Ownership is transferred to new owner.

Interfaces

IAcceptTokensBurnCallback

import "@broxus-ton-tokens-contracts/contracts/interfaces/IAcceptTokensBurnCallback.sol";

Interface defines a callback function that can be used by a TokenRoot to notify the owner of a TokenWallet when their tokens have been burned.

Chain of calls: 1) walletOwner → IBurnableTokenWallet(wallet).burn(…​) → IBurnPausableTokenRoot(root).tokensBurned(…​) → IAcceptTokensBurnCallback(callbackTo).onAcceptTokensBurn(…​) → …​ 2) rootOwner → IBurnableByRootTokenRoot(root).burnTokens(…​) → IBurnableByRootTokenWallet(wallet).burnByRoot(…​) → IBurnPausableTokenRoot(root).tokensBurned(…​) → IAcceptTokensBurnCallback(callbackTo).onAcceptTokensBurn(…​) → …​

onAcceptTokensBurn(uint128 amount, address walletOwner, address wallet, address remainingGasTo, TvmCell payload) external

Callback used by the Token Root contract when it receives a request to burn tokens on ITokenRoot.acceptBurn from a token wallet and successfully completes the burning process. This allows the wallet owner to take appropriate action, such as triggering a business logic.

IBurnableByRootTokenRoot

import "@broxus-ton-tokens-contracts/contracts/interfaces/IBurnableByRootTokenRoot.sol";

Interface for disabling the ability of the TokenRoot contract to burn tokens on behalf of any TokenWallet contract.

Chain of calls:

rootOwner → IBurnableByRootTokenRoot(root).burnTokens(…​) → IBurnableByRootTokenWallet(wallet).burnByRoot(…​) → ITokenRoot(root).acceptBurn(…​) → IAcceptTokensBurnCallback(callbackTo).onAcceptTokensBurn(…​) → …​

burnTokens(uint128 amount, address walletOwner, address remainingGasTo, address callbackTo, TvmCell payload) external

Allows for rootOwner burn tokens from any TokenWallet. This method can be disabled using disableBurnByRoot()

disableBurnByRoot() → bool external

Allows to disable burnTokens method forever

Precondition:

  • sender must be rootOwner.

Postcondition:

  • burn by TokenRoot must be disabled forever.

burnByRootDisabled() → bool external

Returns true if burnTokens method is disabled.

IBurnPausableTokenRoot

import "@broxus-ton-tokens-contracts/contracts/interfaces/IBurnPausableTokenRoot.sol";

The interface that defines additional functionality enabling and disabling the mechanism for burning tokens on a contract

setBurnPaused(bool paused) → bool external

Pause/Unpause token burns.

if paused, then all burned tokens will be bounced to TokenWallet.

burnPaused() → bool external

Returns true if token burns are paused, and false otherwise.

IDisableableMintTokenRoot

import "@broxus-ton-tokens-contracts/contracts/interfaces/IDisableableMintTokenRoot.sol";

Interface defines a contract that has functions to permanently disable the minting of new tokens and check the status of the ability to mint new tokens.

disableMint() → bool external

Disable mint forever This is an irreversible action

mintDisabled() → bool external

Сheck if the minting of new tokens has already been disabled

ITransferTokenRootOwnershipCallback

import "@broxus-ton-tokens-contracts/contracts/interfaces/ITransferTokenRootOwnershipCallback.sol";

Interface describing the callback function that is called by the token root contract after the ownership transfer.

onTransferTokenRootOwnership(address oldOwner, address newOwner, address remainingGasTo, TvmCell payload) external

This function is called by the token root contract after the ownership transfer. @param oldOwner The address of the old owner. @param newOwner The address of the new owner. @param remainingGasTo The address of the contract that will receive the remaining gas. @param payload Payload data.

@dev not having this function in the interface will cause the compiler to generate a default implementation of this function.

Upgradeability

ITokenRootUpgradeable

import "@broxus-ton-tokens-contracts/contracts/interfaces/ITokenRootUpgradeable.sol";

Interface extends the ITokenRoot interface and defines functionality for upgradable token wallets. The interface includes functions for interacting with upgradable token wallets, such as requesting upgrades, changing the wallet code, and upgrading the TokenRoot contract.

walletVersion() → uint32 external

Get the current version of the wallet code.

platformCode() → TvmCell external

Returns the TokenWalletPlatform code cell.

requestUpgradeWallet(uint32 currentVersion, address walletOwner, address remainingGasTo) external

Upgrades the wallet code on request TokenWallet.

setWalletCode(TvmCell code) external

Changes the wallet code for future deploy new wallets.

upgrade(TvmCell code) external

Upgrades the TokenRoot code.

TokenRootUpgradeable

import "@broxus-ton-tokens-contracts/contracts/TokenRootUpgradeable.sol";

This is an implementation of upgradable token root that implements all the required methods of the TIP-3 standard.

constructor(address initialSupplyTo, uint128 initialSupply, uint128 deployWalletValue, bool mintDisabled, bool burnByRootDisabled, bool burnPaused, address remainingGasTo) public

Sets the values for mintDisabled_, burnByRootDisabled_,burnPaused_, and increases the totalSupply_ if initialSupply is not zero.

Parameters such as symbol, decimals, name, rootOwner_ randomNonce_ deployer_, and platformCode_ are set during contract deployment, and passed as StateInit params.

Also, the listed parameters, with the exception of totalSupply_ and burnPaused_, are immutable: they can only be set once during construction.

supportsInterface(bytes4 interfaceID) → bool external

Implementation of the SID interface.

walletVersion() → uint32 external

platformCode() → TvmCell external

requestUpgradeWallet(uint32 currentVersion, address walletOwner, address remainingGasTo) external

Preconditions: - Sender is a valid wallet. - currentVersion must be not equal to walletVersion_.

Postcondition: - If currentVersion is not equal to walletVersion_, then the wallet will be upgraded to the new version. Otherwise, the remaining gas will be transferred to remainingGasTo.

setWalletCode(TvmCell code) external

Preconditions: - Sender must be the owner of the TokenRoot.

Postcondition: - walletCode_ is set to code. - walletVersion_ is incremented.

upgrade(TvmCell code) external

Precondition: - Sender must be the owner of the TokenRoot.

_targetBalance() → uint128 internal

Returns the target balance.

_buildWalletInitData(address walletOwner) → TvmCell internal

Returns the wallet init data for deploy new wallet.

_deployWallet(TvmCell initData, uint128 deployWalletValue, address remainingGasTo) → address internal

implemetation logic deployWallet function.

TokenWallet

This document is better viewed at https://docs.broxus.com/tip3

The Token Wallet contract, is an implementation of the TIP-3 Token Standard. It provides all the required methods specified in the standard, as well as additional optional functionality such as the ability to minting, burning/burning by TokenRoot tokens, and destroying the wallet.

Each token holder has their own instance of the token wallet contract, and transfers occur in a decentralized fashion. The sender’s token wallet must send a specific message to the receiver’s token wallet, and since all token wallets have the same code, it is easy for the receiver’s token wallet to check the correctness of the sender’s token wallet.

The TokenWallet is based on abstractions such as:

Core

TIP3TokenWallet

import "@broxus-ton-tokens-contracts/contracts/interfaces/TIP3TokenWallet.sol";

Interface of the TIP-3.1 TokenWallet contract.

root() → address external

Returns the current root contract of the wallet.

balance() → uint128 external

Returns the current balance of the wallet.

walletCode() → TvmCell external

Returns the wallet code.

ITokenWallet

import "@broxus-ton-tokens-contracts/contracts/interfaces/ITokenWallet.sol";

The ITokenWallet interface defines the minimal required functionality for a TIP-3 compliant token wallet contract. It inherits the TIP3TokenWallet interface, which provides basic information about the token wallet such as its root contract and current balance. Additionally, the ITokenWallet interface also includes the SID interface, which allows other contracts to query if a contract implements a specific interface.

owner() → address external

Returns the current owner of the wallet.

transfer(uint128 amount, address recipient, uint128 deployWalletValue, address remainingGasTo, bool notify, TvmCell payload) external

Transfer tokens and optionally deploy TokenWallet for recipient.

If deployWalletValue !=0 deploy token wallet for recipient using that gas value

transferToWallet(uint128 amount, address recipientTokenWallet, address remainingGasTo, bool notify, TvmCell payload) external

Transfer tokens using another TokenWallet address, that wallet must be deployed previously

acceptTransfer(uint128 amount, address sender, address remainingGasTo, bool notify, TvmCell payload) external

Callback for transfer operation

acceptMint(uint128 amount, address remainingGasTo, bool notify, TvmCell payload) external

Accept minted tokens from root

TokenWalletBase

import "@broxus-ton-tokens-contracts/contracts/abstract/TokenWalletBase.sol";

Implementation of the ITokenWallet interface.

This abstraction describes the minimal required functionality of TokenWaellet contract according to the TIP-3 standard.

Also used as a base class for implementing abstractions such as:

onlyRoot() modifier

Modifier than throws if called by any account other than the TokenRoot.

onlyOwner() modifier

Modifier than throws if called by any account other than the owner_.

balance() → uint128 external

owner() → address external

root() → address external

walletCode() → TvmCell external

transfer(uint128 amount, address recipient, uint128 deployWalletValue, address remainingGasTo, bool notify, TvmCell payload) external

The function then uses the address of the recipient and StateInit (derived using a function called _buildWalletInitData)

to determine the address of the recipient’s token wallet. The sender’s wallet then decreases its balance_ by the amount and calls the ITokenWallet.acceptTransfer on the recipient’s token wallet.

If the recipient’s wallet is unable to accept the transfer, the sender’s wallet will return an error message and increase its balance_ by the amount.

Note that the recipient may not have a token wallet yet. In this case, if a sufficient amount of deployWalletValue is passed to the function, a token wallet will be deployed for the recipient. If a transfer is attempted to a non-existent token wallet and the required value is not provided, the transaction will fail with an error.

Preconditions:

  • amount must be greater than zero.

  • amount must be less than or equal to balance_.

  • recipient must be a non-zero address and should not be equal to the address of the owner of the sender’s wallet.

Postcondition:

  • balance_ will be decreased by amount.

transferToWallet(uint128 amount, address recipientTokenWallet, address remainingGasTo, bool notify, TvmCell payload) external

Almost the same as the TokenWalletBase.transfer, only it takes the address of the deployed TokenWallet. If the recipientTokenWallet is not deployed, the transaction will fail.

Preconditions:

  • amount must be greater than zero.

  • amount must be less than or equal to balance_.

  • recipientTokenWallet must be a non-zero address and should not be equal to the address of the sender’s TokenWallet.

Postcondition:

  • balance_ will be decreased by amount.

acceptTransfer(uint128 amount, address sender, address remainingGasTo, bool notify, TvmCell payload) external

Accepts incoming transfer for amount amount of tokens from TokenWallet, owned sender.

If notify is false, than the remaining gas MUST be sent to the remainingGasTo. Otherwise, the IAcceptTokensTransferCallback.onAcceptTokensTransfer sends to the TokenWallet owner with the same remainingGasTo and payload.

Preconditions:

  • The transfer must come from the same wallet.

Postcondition:

  • balance_ will be increased by amount.

acceptMint(uint128 amount, address remainingGasTo, bool notify, TvmCell payload) external

Accepts incoming mint foramount of tokens from TokenRoot. If notify is false, than the remaining gas MUST be sent to the remainingGasTo. Otherwise, the IAcceptTokensMintCallback.onAcceptTokensMint sends to the TokenWallet owner with the same remainingGasTo and payload.

Preconditions:

  • The mint must come from the TokenRoot.

Postcondition:

  • balance_ will be increased by amount.

onBounce(TvmSlice body) external

Catch bounce if acceptTransfer or acceptBurn fails

_burn(uint128 amount, address remainingGasTo, address callbackTo, TvmCell payload) internal

Burns amount tokens from TokenWallet, decreasing the balance_.

Preconditions:

  • amount must be greater than 0.

  • amount must be less than or equal to balance_.

Postcondition:

  • balance_ will be decreased by amount. If ITokenRoot.acceptBurn fails - message will be bounced to onBounce, and balance_ will be increased back.

sendSurplusGas(address to) external

Withdraw all surplus balance in EVERs.

_reserve() → uint128 internal

Calculates the reserve by taking the maximum of the contract’s current balance minus the value of the message (i.e. the amount of EVERs spent on the current transaction) and the target balance of the contract (as determined by the _targetBalance function). This ensures that the reserve is set to the lower of the contract’s current balance or its target balance, ensuring that the contract does not spend more EVERs than it has available.

_targetBalance() → uint128 internal

Returns the target balance of the contract.

Target balance is used for tvm.rawReserve, which creates an output action that reserves EVER. It is roughly equivalent to creating an outgoing message that carries reserve nanoevers to itself, so that subsequent spend actions cannot spend more money than the reserve.

_buildWalletInitData(address walletOwner) → TvmCell internal

Builds the wallet StateInit data.

_deployWallet(TvmCell initData, uint128 deployWalletValue, address remainingGasTo) → address internal

Deploys new token wallet.

TokenWalletDestroyableBase

import "@broxus-ton-tokens-contracts/contracts/abstract/TokenWalletDestroyableBase.sol";

Implementation of the IDestroyable interface.

This abstraction extends the functionality of TokenWalletBase and adding the ability to destroy the wallet.

destroy(address remainingGasTo) external

Precondition:

  • The wallet balance must be empty.

TokenWallet

import "@broxus-ton-tokens-contracts/contracts/TokenWallet.sol";

This is an implementation of TokenWallet that implements all the required methods of the TIP-3 standard. As well as optional ones: burn and collections.

Each token holder has its own instance of token wallet contract. Transfer happens in a decentralized fashion - sender token wallet SHOULD send the specific message to the receiver token wallet. Since token wallets have the same code, it’s easy for receiver token wallet to check the correctness of sender token wallet.

constructor() public

Creates new token wallet

Nothing is passed to the constructor, but during the deployment of the contract, the following parameters are passed to StateInit:

`root_` - address of the root token contract
`owner_` - address of the owner of the wallet

Preconditions:

  • msg.pubkey() MUST be equal to zero. This means that the owner of the TokenWallet can only smart contract.

  • owner_ MUST be a non-zero address.

supportsInterface(bytes4 interfaceID) → bool external

Implemetation of SID interface.

_targetBalance() → uint128 internal

_buildWalletInitData(address walletOwner) → TvmCell internal

We need this to deploy new wallets, as well as to check incoming messages from other wallets.

The InitData consists of: - contr (contract) - defines the contract whose StateInit will be created. Mandatory to be set if the varInit option is specified.

  • varInit (initialization list) - used to set static variables of the contract, see TokenWalletBase. Conflicts with data and must be set contr.

    `root_` - the address of the TokenRoot contract.
    `owner_` - the address of the owner of the wallet.
  • pubkey` - the public key of the contract. The value 0 means that the wallet can be owned only by another contract. contract, the most common example is Wallet.

  • code - the code of the TokenWallet, see TokenRootBase.

_deployWallet(TvmCell initData, uint128 deployWalletValue, address) → address internal

Implementation of the virtual function TokenWalletBase._deployWallet.

Abstractions

TokenWalletBurnableBase

import "@broxus-ton-tokens-contracts/contracts/abstract/TokenWalletBurnableBase.sol";

Implementation of the IBurnableTokenWallet interface.

This abstraction extends the functionality of TokenWalletBase and adding burning self-tokens functional.

burn(uint128 amount, address remainingGasTo, address callbackTo, TvmCell payload) external

Burn tokens from the wallet.

Precondition:

  • sender must be the wallet owner.

For implementation details, see TokenWalletBase._burn.

TokenWalletBurnableByRootBase

import "@broxus-ton-tokens-contracts/contracts/abstract/TokenWalletBurnableByRootBase.sol";

Implementation of the IBurnableByRootTokenWallet interface.

This abstraction extends the functionality of TokenWalletBase and adding burning tokens by TokenRoot.

burnByRoot(uint128 amount, address remainingGasTo, address callbackTo, TvmCell payload) external

Precondition:

  • the caller must be TokenRoot.

Postcondition:

  • The balance_ of wallet must decrease by the amount that is burned.

For implementation details, see TokenWalletBase._burn.

TokenWalletDestroyableBase

import "@broxus-ton-tokens-contracts/contracts/abstract/TokenWalletDestroyableBase.sol";

Implementation of the IDestroyable interface.

This abstraction extends the functionality of TokenWalletBase and adding the ability to destroy the wallet.

destroy(address remainingGasTo) external

Precondition:

  • The wallet balance must be empty.

Interfaces

IAcceptTokensMintCallback

import "@broxus-ton-tokens-contracts/contracts/interfaces/IAcceptTokensMintCallback.sol";

Interface defines a callback function that can be used by a token wallet contract to notify the owner of the wallet when new tokens are minted on their wallet.

onAcceptTokensMint(address tokenRoot, uint128 amount, address remainingGasTo, TvmCell payload) external

Callback used by the wallet contract when it receives a mint of tokens. This allows the owner of the wallet to take appropriate action, triggering a business logic.

IAcceptTokensTransferCallback

import "@broxus-ton-tokens-contracts/contracts/interfaces/IAcceptTokensTransferCallback.sol";

Interface defines a callback function that can be used by a Token Wallet contract to notify the owner of the wallet when their wallet receives a transfer of tokens.

Chain of calls:

senderWallet -> ITokenWallet(sender).transfer(...) ->
                ITokenWallet(receiver).acceptTransfer(...) ->
                IAcceptTokensTransferCallback(callbackTo).onAcceptTokensTransfer(...) -> ...

onAcceptTokensTransfer(address tokenRoot, uint128 amount, address sender, address senderWallet, address remainingGasTo, TvmCell payload) external

Callback by the wallet contract when it receives a transfer of tokens. This allows the wallet owner to take appropriate action, such as triggering a business logic.

IBounceTokensBurnCallback

import "@broxus-ton-tokens-contracts/contracts/interfaces/IBounceTokensBurnCallback.sol";

Interface defines a callback function that can be used by a token wallet contract to notify its owner when a burn operation is reverted.

Chain of calls:

walletOwner → IBurnableTokenWallet(walletOwner).burn(…​) → ITokenRoot(root).acceptBurn(…​) → TokenWalletBase.onBounce(…​) → IBounceTokensBurnCallback(callbackTo).onBounceTokensBurn(…​) →

onBounceTokensBurn(address tokenRoot, uint128 amount) external

Invoked by the token wallet when a burn operation is reverted.

IBurnableTokenWallet

import "@broxus-ton-tokens-contracts/contracts/interfaces/IBurnableTokenWallet.sol";

An interface that defines additional functionality for burning tokens owned by the TokenWallet, according to the TIP-3.2 standard.

Сhain of calls:

walletOwner → IBurnableTokenWallet(wallet).burn(…​) → ITokenRoot(root).acceptBurn(…​) → IAcceptTokensBurnCallback(callbackTo).onAcceptTokensBurn(…​) → …​

burn(uint128 amount, address remainingGasTo, address callbackTo, TvmCell payload) external

Allows for walletOwner burn tokens.

IDestroyable

import "@broxus-ton-tokens-contracts/contracts/interfaces/IDestroyable.sol";

Interface extends contract interface adding destroy function.

destroy(address remainingGasTo) external

Destroys the contract.

Upgradeability

ITokenWalletUpgradeable

import "@broxus-ton-tokens-contracts/contracts/interfaces/ITokenWalletUpgradeable.sol";

The interface extends the ITokenWallet defines a set of functions for upgradable token wallets.

platformCode() → TvmCell external

Returns the code of functions implemented in TokenWalletPlatform.

upgrade(address remainingGasTo) external

Sends a request to the TokenRoot to upgrade the Wallet code to the latest version.

The wallet calls a method ITokenRootUpgradeable.requestUpgradeWallet and then the TokenRoot calls acceptUpgrade of Token Wallet passing in the new wallet code.

acceptUpgrade(TvmCell code, uint32 newVersion, address remainingGasTo) external

The function is a callback that can be called by the TokenRootUpgradeable contract to upgrade the code of an TokenWalletUpgradeable to the latest version.

Callback upgrades Wallet code to the latest version of the walletCode_. Only TokenRoot can call this method.

TokenWalletPlatform

import "@broxus-ton-tokens-contracts/contracts/TokenWalletPlatform.sol";

Theis contract provides an immutable foundation for a wallet token contract that can be updated. It ensures that all wallet addresses are considered to be derived from the same code, regardless of the version of the wallet.

We uses the tvm.buildStateInit function to create a StateInit data cell containing the TokenWalletPlatform code and static data. Then use the tvm.hash function to compute the hash of the StateInit data and convert it to an address.

constructor(TvmCell walletCode, uint32 walletVersion, address sender, address remainingGasTo) public

Contstructor for TokenWalletPlatform.

TokenWalletUpgradeable

import "@broxus-ton-tokens-contracts/contracts/TokenWalletUpgradeable.sol";

This is an implementation of TokenWallet upgradeable that implements all the required methods of the TIP-3 standard. As well as optional ones: burn and collections.

Each token holder has its own instance of token wallet contract. Transfer happens in a decentralized fashion - sender token wallet SHOULD send the specific message to the receiver token wallet. Since token wallets have the same code, it’s easy for receiver token wallet to check the correctness of sender token wallet.

constructor() public

The constructor has been reverted because it was called in the TokenWalletPlatform. The revert() function is used to prevent the contract from executing any further.

supportsInterface(bytes4 interfaceID) → bool external

platformCode() → TvmCell external

onDeployRetry(TvmCell, uint32, address sender, address remainingGasTo) external

This function is used if the deployment transaction fails, then the unused Evers will be returned to the remainingGasTo.

version() → uint32 external

Returns the version of the Wallet.

upgrade(address remainingGasTo) external

Sends a request to the TokenRootUpgradeable to upgrade the Wallet code to the latest version.

acceptUpgrade(TvmCell newCode, uint32 newVersion, address remainingGasTo) external

_targetBalance() → uint128 internal

Returns the TokenGas.TARGET_WALLET_BALANCE EVER of gas reserved for the current operation.

_buildWalletInitData(address walletOwner) → TvmCell internal

Implementation of the TokenRootBase._buildWalletInitData.

This function builds the init data for the upgradeable wallet. Used in transfer and mint function, for deploy new wallet, when the recipient is not a deployed wallet. It is also used in AcceptTransfer to ensure that the transfer is from a valid wallet.

_deployWallet(TvmCell initData, uint128 deployWalletValue, address remainingGasTo) → address internal

Deploy new upgradeable TokenWallet.