More token standards for the God of Token Standards!
There are almost no projects built on the blockchain that can be developed without tokens integration. They are essential entities in the crypto world. Different chains create their own token standards that match their peculiarities the best. The token standard design impacts how quickly the system can grow and how quickly other protocols can be implemented.
This article describes two Tezos token standards, their strengths and weaknesses, and how their limitations can be addressed.
FA1.2
FA1.2 is the oldest token standard that was developed at the dawn of the Tezos ecosystem and proposed in the TZIP-7. It was designed as the closest analog of ERC20, with the smallest adoption to the platform reality.
The standard defines the rules for smart contracts that represent the ledger for single assets and the entrypoints to interact with them.
There are 2 regular methods and 3 view methods mentioned in the TZIP:
(address :spender, nat :value) %approve
(address :from, (address :to, nat :value)) %transfer
(view (address :owner, address :spender) nat) %getAllowance
(view (address :owner) nat) %getBalance
(view unit nat) %getTotalSupply
approve
allows the spender to spend value tokens. Only the owner can allow someone to spend their tokens, which may not fit in with someone’s business logic.
transfer
allows the transfer of assets from one account to another; however, only one transfer can be made per call, which makes multi-transfers expensive.
The view functions are simple methods that, instead of updating something in the contract, create the operation that sends the response to another contract. Only the total supply and the user’s balance and allowance can be requested in the standard way.
So, the standard has many disadvantages:
- Only single assets are supported;
- There is no way to implement custom logic for the approval (e.g. when it can only be done by the contract admin);
- There is no storage specification;
- View methods are just the methods that return operations (fake views);
- Batch transfers aren’t supported;
- here is a lack of infinite approvals;
- Metadata isn’t specified in the standard.
FA2
FA2, introduced in TZIP-12, was designed to mitigate some of the above issues. The standard is very adaptable and allows the creation of single and multi-assets, and fungible, non-fungible, collectible, or hybrid tokens.
There are 2 regular methods and 1 view method specified in the TZIP:
(list %transfer
(pair
(address %from_)
(list %txs
(pair
(address %to_)
(pair
(nat %token_id)
(nat %amount)
)
)
)
)
)
(list %update_operators
(or
(pair %add_operator
(address %owner)
(pair
(address %operator)
(nat %token_id)
)
)
(pair %remove_operator
(address %owner)
(pair
(address %operator)
(nat %token_id)
)
)
)
)
(pair %balance_of
(list %requests
(pair
(address %owner)
(nat %token_id)
)
)
(contract %callback
(list
(pair
(pair %request
(address %owner)
(nat %token_id)
)
(nat %balance)
)
)
)
)
transfer
allows the transfer of assets from one account to another. Batch transfers are supported: a few assets can be transferred from a few senders to many receivers.
update_operators
allows the spender to spend any amount of the tokens of some user. Many approvals can be done per transaction.
balance_of
is a callback view to receive the balances of some users. The operation can return the balances of many tokens and users.
The standard also describes the token metadata format. The balance update rules are also mentioned but are not obligatory.
Although the standard is more complete than FA1.2, there are still some disadvantages:
- Only infinite approval is supported;
- There is no storage specification;
- View methods are just the methods that return operations (fake views);
- There are no views for supply metrics.
Protocol Changes
There were a few cool perks introduced in Hangzhou.
Timelock allows the user to send a transaction whose content won’t be seen for some time. Michelson on-chain views makes view-only interactions between contracts easier. The global constants table allows some Micheline expressions to be stored globally and then be found by the hash and used by any contract.
So, it would be nice to reflect these changes in the token standard.
Discussion
As the key solution to approach the protocol changes and dev experience improves, the new token standard can be considered. The main discussion around it takes place on Agora. However, it is not very active.
Long story short, it has been proposed that the standard should have the following features:
- Supports transfer_and_call mechanics;
- Supports views;
- Has the global table of constants;
- Specifies and has views for supply metrics;
- Supports finite allowances;
- Supports tokens with expiries;
- Supports non-transferable token functionality;
- Integrates tickets;
- Implements privacy features;
- Supports upgradeability mechanics;
- Supports allowance for flash-loans and subscription models;
- Is compatible with state-channels, ZK-rollups, and optimistic Rollups;
- Has optional royalties support;
- Integrates TZIP-17.
Essentially, an all-in-one token.
I also tried conducting a survey on the dev slack channel and only got 5 eye reactions (👀) and no responses (what engagement, lol). So, I ended up discussing it with the MadFish team.
The main goal was to ascertain whether there are any issues relating to token standards that make development painful and hence, whether there is a need to create a new standard. Finally, we agreed that the main problem is the views that aren’t really views but rather methods with callbacks. We deserve true views integration but developing a new token standard and integrating it into the existing infrastructure seems to be too tricky.
Suggestions
In my opinion, the standard should be as simple as possible and shouldn’t cover everything in the world. It should only specify the payment and assets management logic and be easily extendable by other standards. So, the specification for flash-loans, privacy, tickets, obligatory TZIP-17 integration, royalties support, etc., seems to be redundant in the token standard and should be proposed in separate TZIPs.
I like the idea of creating a new perfect token standard, which would basically be an improved FA2 token with true views and some obligatory cool perks, but I consider this to be unrealistic.
What seems to be realistic is a standard that extends the FA2. This means that new TZIPs can be proposed that can be followed in future FA2 tokens. The tokens that will be implemented according to it will be still compatible with all protocols that support FA2. Let’s look at the additional features.
Compatible with FA2
All the requirements for the FA2 standard must be implemented.
Extended with obligatory views
💡 The views are referring to the views introduced in Hangzhou
The token that supports the new standard must implement the balance_of
view with the same signature as the method balance_of
. get_total_supply
returns the number of tokens currently in circulation. get_max_supply
returns Some(max_supply)
if the token supply is capped and None
otherwise. get_supported_standards
returns all the supported standards; it can be used to ensure that the token supports tickets, permits, or the flash loan standard.
Enable transfer and call functionality
Support is the method that allows a user to transfer tokens and then “notify” another contract. The method “implementation” resembles %transfer
with the only difference being an extra parameter %callback
– the entry point of another contract that will be called.
(pair %transfer_and_call (contract %callback unit)
(list %transfers
(pair (address %from_)
(list %txs (pair (address %to_) (pair (nat %token_id) (nat %amount)))))))
Support finite allowance
The token must implement the %approve
method that allows it to give the approval to spend a fixed amount of tokens. The method works for all types of tokens (fungible, NFT, collectibles). The method must not fail if the approved amount is higher than 1 in the case of NFTs.
(list %approve (or (pair %add_operator
(address %owner)
(pair (address %operator) (pair (nat %token_id) (nat %amount))))
(pair %remove_operator
(address %owner)
(pair (address %operator) (pair (nat %token_id) (nat %amount))))))
Summary
In summary, I believe that we need a new standard that would extend the TZIP-12 and make it more dev-friendly.
The main features that should be introduced are:
- Support of views:
- balance of the user
- user operators
- total supply
- max supply
- supported standards
- Support of transfer_and_call mechanics
- Support of finite allowance.
Actually, as far as the standard goes, it is pretty simple. Someone can create a tool that wraps the existing FA2 tokens into the FA2 that implements the new standard. So, the new protocols will only need to work with the newest tokens.
If you’re interested in this topic, please share your opinion on the Agora or Slack threads.
1 comment
Make the all in one standard with all the features.
Be the best.
That’s what Tezos deserves.