Overview of FA2
This post introduces FA2 (TZIP-12), a proposal for a unified token contract interface, supporting both a wide range of token types (e.g. fungible, non-fungible, non-transferrable, etc.) as well as multi-asset contracts (a la ERC-1155). FA2 aspires to offer wide expressivity to create novel implementations and even invent token types while maintaining a common interface standard for wallet integrators and external developers.
In initiating a request for comment, we hope to identify opportunities to refine the interface through feedback and early use. And please reach out if interested in collaborating!
This post introduces FA2 and its motivations at a high level. We recommend reading the TZIP-12 proposal and trying it yourself using Stove Labs’ tutorial.
As noted in “Next Steps”, we will soon provide reference implementations for single- and multi- asset versions of FA2 alongside a blog post about implementation patterns.
- TZIP-12 Proposal (FA2: Multi-Asset Interface)
- TZIP-12 resources and permissioning examples
- Stove Labs’ FA2 prototype walk-through tutorial using Truffle and Flextesa
Over the past several years, Ethereum’s ERC-20 (fungible tokens) and ERC-721 (non-fungible tokens) have become synonymous with blockchain-based assets. In response to growing demand for an ERC-20 equivalent interface standard on Tezos, last year we released FA1.2 (TZIP-7) based on work with Serokell and Nomadic Labs. FA1.2 implementations have emerged in SmartPy, LIGO, Lorentz, and others.
As noted last year, we’ve aimed to follow up FA1.2 with a new token standard proposal, beginning with prototypes inspired by ERC-1155. This eventually led us to FA2, a new token standard proposal we are introducing today for public comment on Tezos Agora.
While FA1.2 has seen robust demand for financial use cases needing a single fungible token contract, FA2 is agnostic to token type and allows both single- and multi-token contracts via one standard API. All entry points in FA2 are batch operations, allowing multiple transfers of different tokens and/or token types to be executed in one atomic transaction.
FA2 enables all of the familiar functionality of FA1.2 but also broadens the potential for tokenization on Tezos significantly.
FA2 provides developers a wide latitude to define and invent token types and complex token interactions while maintaining a standard API for wallets and external applications. Such examples include NFTs for collectible assets, non-transferrable badges to incentivize behaviors, and multi-asset contracts containing thousands of different gaming items with interactive, transmutable behaviors.
FA2 Design Considerations
The FA2 proposal is also inspired by direct experience implementing tokens (e.g. FA1.2) on Tezos and by feedback on early FA2 prototypes from nearly two dozen external individuals and teams. Included in this group were EIP standards proposers, tokenization platforms, custodians, and institutional users, as well as gaming, exchange, and marketplace builders. We’ve also gathered input from indexer developers, language creators, prominent security auditors, and Tezos core developers. Additionally, we’ve worked directly with early implementers and potential integrators of FA2, incorporating their feedback while iterating on the specification.
Two common themes emerged from our experience with FA1.2 and broader research into how users and developers actually use tokens on Ethereum:
1. Standards fragmentation by token type in Ethereum has been driven by adoption, rather than intent
- Ethereum’s major token standards have emerged based on popular token types (ERC-20 for fungible tokens, ERC-721 for non-fungible)
- Although FA1.2 has seen early momentum, Tezos is nascent enough not to have strong path dependence towards standards specific to token types
- In the long-run, a token standard which is agnostic to token type may produce stronger network effects and less friction as wallets and external applications need to support just one core transport API across multiple token types
2. Permissions standardization must balance flexibility for customization (e.g. whitelisting) with a need to avoid fragmentation (e.g. by compatibility with popular contracts)
- Over-specification of permissioning restricts developers’ expressivity to create novel implementations and creates integration friction for wallets, constraining network effects from both sides
- Under-specification leads to fragmentation and capture by popular implementations or use cases (e.g. exchanges)
FA2 also led us to reflect more broadly on how standard proposals interplay with Tezos as a self-amending protocol which can add new functionality over time. For these purposes, we have been especially interested in potential core features discussed on Agora such as contract signatures (“stamps”), event logging, and read-only calls, all of which might improve usability and could be useful for a future updated version of the standard.
To facilitate rapid iteration and external feedback, we’ve chosen CameLIGO for the initial interface specification and reference implementation, using the opportunity to provide significant feedback to the LIGO language team (in the form of dozens of Gitlab issues). We will also soon publish both a Michelson interface and SmartPy implementation for FA2 incorporating any changes to the spec based on community feedback.
Standard vs. Implementation
What should be the scope of an interface standard and what should be left up to implementers?
Standardization aims to solve collective action problems, situations in which users would all benefit by cooperating but find it too costly to do so alone. In the case of a token, the API standard has already been chosen at the time of contract development, i.e. before the user accesses it, making standardization necessary. An API standard instead is used to ensure interoperability with related applications and wallets which want to support tokens but do not want to have to support many different APIs.
However, a standard is enforced on all implementers, so being too feature-rich or over-specified risks taxing all users, not just contract deployers. By contrast, under-specified standards risk fragmentation, creating walled gardens in which different incompatible standards or implementations become stuck.
In the context of tokens, such concerns are particularly salient to permissioning, defined here as rules governing who can send, receive, and/or administer tokens on another user’s behalf and how. Standard permissioning is especially necessary for both trust-minimized interactions with external contracts (e.g. an auction or a DAO) as well as for centrally-administered tokens like digital securities.
Early designs of FA2 considered splitting this permissioning entirely from the core transfer semantic, aiming to completely modularize the standard. But as described in Practical Use below, some amount of minimal permissioning standardization may be needed to ensure ease of adoption for wallets and other end-users and avoid fragmentation.
As a result, FA2’s interface specification proposes to standardize transfer semantics (supporting both single and multi-token transfers), accessing balances and total supply, metadata, and some basic operator permissioning. It also proposes an entrypoint called permissions_descriptor allowing external contracts or clients to discover an FA2 contract’s permissioning schema and configure it.
Conversely, FA2 proposes to leave it to implementers to handle common considerations such as defining the contract’s token type(s) (e.g. non-fungible vs. fungible vs. semi-fungible), administration and whitelisting, contract upgradability, and supply operations (e.g. mint/burn).
As visualized in the diagram below, FA2 also leaves to implementers to decide on their preferred permissioning architecture: namely, whether they would prefer to implement permissioning via the same contract (i.e. a “monolith”), a transfer hook to another contract, or a separate wrapper contract. For more detailed explanation of permissioning or “permissions policies”, please see FA2 Permissions Policies and Configuration in the TZIP-12 proposal.
FA2 Implementation Patterns
An upcoming blog post called “Implementing FA2” will cover implementation examples in greater depth and the pros and cons of difference architectures.
Practical Use (i.e. learning from Ethereum)
How do developers and users actually use and interact with token contracts?
Standards are ratified by use rather than by white papers, proposals, or working groups. In practice, standards gain network effects with real use as tooling is built to quickly integrate them into exchanges, wallets, and marketplaces.
Experience with ERC-20, ERC-721, and ERC-1155 provide some of the strongest insight into how token contracts are actually used.
For example, ERC-20 has permissioning so narrowly scoped ( allowance ) that it is commonly ignored by users who set a very high value out of convenience. On the other hand, ERC-1155 has a very broad notion of permission, allowing operators (an external contract that can be provided transfer permissions) unlimited ability to transfer all tokens within a contract while also requiring a token receiver interface to receive tokens. The latter was found to add significant friction during prototyping, a point validated by discussions with major institutional custodians and wallet developers who would have to interact with it.
FA2 aims to provide a usable permission policy at the right level of granularity. In the case of multi-asset contracts, we’ve proposed to introduce operators by token type (set as all token types for single-asset contracts). Given ERC-20 users’ tendency to opt-out of allowances de facto when approving transfers by external contracts, we’ve also considered operator expiration and a notion of default expiry (e.g. n blocks or n transactions) for operators.
Overall, many of these considerations reflect a broader question of where in the stack (e.g. in token standards vs. a dedicated wallet permissions standard) different permissioning schemas should be standardized and at what level of granularity. In the case of spending limits (a la allowances) or operator expiry, real-world behavior with ERC-20 suggests that smart contract wallets (a la Argent) or even the protocol itself may be better places to configure such granular permissioning than within a token standard.
Similarly, during our design process we identified features which are very well-suited for specific applications (e.g. pre-authorization for certain exchanges) or tooling (e.g. storage standardization for indexers). Yet in many cases these were likely not universal enough or may introduce other kinds of subtle path dependence for future standardization efforts or core development.
However, pursuing a highly generalized standard attempts to please all users at the risk of pleasing none at all. In designing FA2, we also placed priority on ensuring support for high-volume use cases that comprise the lion’s share of blockchain-based asset activity today: namely, how such designs would affect swaps and NFT-based use cases.
How can we ensure that standards evolve as Tezos itself evolves?
Tezos’ nascency as a platform and self-amending nature pose unique challenges for proposing an interface standard. Additionally, multiple reviewers suggested avoiding optimizing too heavily on gas costs at the expense of a high quality design given Tezos’ ability to improve via the amendment process.
Features under discussion, such as event logging, contract signatures, and read-only calls may improve usability and reduce friction and we hope to extend or upgrade FA2 if such features are approved by the Tezos community. Below we speculate on how such prospective features would affect FA2 and what a transition would look like for implementers.
|Proposed Features*||Proposed Benefit||Potential Impact on FA2||Transition Phase|
|Event Logging||Off-chain querying; deferred cross-contract interactions||Information-only and/or user-provided hooks/callbacks||New contracts may implement FA2 extension supporting on-chain events|
|Contract signatures (“stamps”)||Using FA2 tokens with an external contract is as easy as with Tez||Consider removing Operator entry points||If they are added after or at the same time as events, they could be provided in event data. If they’re added before, users will need a way to access them, e.g. with callbacks|
|Views (read-only calls)||Cross-contract composability and ease of accessing token data||Extend standard with view entrypoint||New contracts may implement both callback entry points and views|
*subject to amendment process
Further Directions and Request for Comment
Below are some questions we’ve provided as part of our FA2 request-for-comment and which inform ongoing efforts to improve the proposal.
- Are operators the best available approach to permissioning transfers by external contracts?
- Should operators have specified allowances (i.e. number of tokens allowed to transfer) or expiration (e.g. n blocks or n transactions after approving an operator)?
- If operators do have expiration, should they have a default expiration? Note: Timestamps or LEVEL, a proposed Michelson instruction, may ease implementation of operator expiry based on number of blocks
- Should transfer hooks be a core component of FA2 or instead be included in a separate standard which developers compose with FA2?
- What types of permissioning should be defined in token standards vs. smart contract wallets (a la Argent or Gnosis Safe) and/or dedicated permissions standards?
- Is there a permissions schema that is widely used in practice and requires a standard API, but is not covered by FA2 as presented in TZIP-12?
- Should (or to what extent should) contract metadata be an independent standard / protocol feature or should it be specific to a token standard a la ERC-20?
- Should there be a standard mechanism for attaching metadata externally (e.g. in a separate contract registry or off-chain)?
- Should versioning be stored in contract metadata?
- What should be included in contract versioning?
- Should Total Supply be part of token metadata rather than a separate entrypoint?
- How should decimals and granularity be handled to avoid fragmentation while also easing wallet integration?
- Should any parts of contract storage be standardized (e.g. to assist indexers)?
Future Proofing (see section above)
- How might FA2 be affected by future amendments?
- What best practices and/or tooling should be developed such that smart contract standards can prepare for future protocol amendments?
- Agora/Blog Post: Implementing FA2
- FA2 Michelson interface
Reference Implementations in development or planned:
- SmartPy implementations (single- and multi-asset versions)
- Single Asset Fungible
- Single Asset NFT
- Single Asset Non-Transferrable
- Multi-asset Contract
We also hope to schedule a regular technical call to discuss future directions for FA2 and take public comments. Stay tuned!
We are deeply grateful for all who have provided early feedback on FA2. We plan to provide a public acknowledgements list in our upcoming post, Implementing FA2 .