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.
TIP3TokenRoot
import "@broxus-ton-tokens-contracts/contracts/interfaces/TIP3TokenRoot.sol";
Interface of the TIP-3.1 TokenRoot contract.
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. |
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_
.
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:
name() → string
external
See TIP3TokenRoot.name
.
symbol() → string
external
See TIP3TokenRoot.symbol
.
rootOwner() → address
external
See ITokenRoot.rootOwner
.
walletOf(address walletOwner) → address
public
See ITokenRoot.walletOf
.
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
See ITokenRoot.mint
.
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 theamount
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 theamount
that is burned. -
If
callbackTo
is not set,remainingGasTo
will receive the remaining gas, otherwiseIAcceptTokensBurnCallback.onAcceptTokensBurn
will be called on thecallbackTo
contract.
_mint(uint128 amount, address recipient, uint128 deployWalletValue, address remainingGasTo, bool notify, TvmCell payload)
internal
Realization of TokenRootBase.mint
function.
Postcondition:
-
totalSupply_
is increased byamount
. -
If
deployWalletValue
is zero thenbalance
ofrecipient
is increased byamount
. -
Else, new
TokenWallet
is deployed with initial balance equal todeployWalletValue
. -
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.
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 whoseStateInit
will be created. Mandatory to be set if thevarInit
option is specified. -
varInit
(initialization list) - used to set static variables of the contract, seeTokenWalletBase
. 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 theTokenWallet
.
_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.
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 befalse
. -
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.
|
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_
.
setBurnPaused(bool paused) → bool
external
Post condition:
-
burnPaused_
is set to the value of thepaused
parameter.
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_
.
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.
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()
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
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
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.
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.
platformCode() → TvmCell
external
Returns the TokenWalletPlatform
code cell.
requestUpgradeWallet(uint32 currentVersion, address walletOwner, address remainingGasTo)
external
Upgrades the wallet code on request TokenWallet
.
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.
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.
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:
TIP3TokenWallet
import "@broxus-ton-tokens-contracts/contracts/interfaces/TIP3TokenWallet.sol";
Interface of the TIP-3.1 TokenWallet contract.
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.
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
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:
owner() → address
external
See ITokenWallet.owner
.
root() → address
external
See TIP3TokenWallet.root
.
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 tobalance_
. -
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 byamount
.
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 tobalance_
. -
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 byamount
.
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 byamount
.
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 byamount
.
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 tobalance_
.
Postcondition:
-
balance_
will be decreased byamount
. IfITokenRoot.acceptBurn
fails - message will be bounced toonBounce
, andbalance_
will be increased back.
_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.
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
See IDestroyable.destroy
.
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.
_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, seeTokenWalletBase
. 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, seeTokenRootBase
.
_deployWallet(TvmCell initData, uint128 deployWalletValue, address) → address
internal
Implementation of the virtual function TokenWalletBase._deployWallet
.
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 theamount
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
See IDestroyable.destroy
.
Precondition:
-
The wallet balance must be empty.
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.
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(…) →
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(…) → …
IDestroyable
import "@broxus-ton-tokens-contracts/contracts/interfaces/IDestroyable.sol";
Interface extends contract interface adding destroy function.
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.
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.
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
.
upgrade(address remainingGasTo)
external
Sends a request to the TokenRootUpgradeable
to upgrade the Wallet code to
the latest version.
_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.