Request for Comment on TZIP-12 (FA2): A Multi-Asset Interface for Tezos

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!

Key Resources:

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.

Introduction

Background

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.

Future-proofing

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.

Permissions

  • 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?

Metadata

  • 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?

Storage

  • 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?

Next Steps

  • 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!

Acknowledgements

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 .

13 Likes

:clap: Great progress. Finding the sweet spot between over/under specification around Permissions is important to the usability of the spec.

A big applause to the team behind this work and the great writeup. I am definitely looking forward to the next one - Implementing FA2.

Here are some thoughts:

Permissions:

As a user, I would prefer doing “damage control” by specifying allowances (approving number of tokens allowed to transfer).
The expiration approach provides a nice convenience, but I believe damage control is more important.

Number of blocks, LEVEL

I would opt for a separate standard that developers compose with FA2.

I think this is best discussed in the online meeting. There are use-cases where dedicated permissions standards will be needed. However, a multi-sig smart contract wallet will be definitely needed as template for developers.

Metadata

A good item to be discussed in the meeting.

Yes! It is an important building block to enable metadata stored in decentralised storage systems.

→ online meeting. I think a discussion is needed to understand the intention.

I do not have a strong opinion on this, but it might be better to store supply as metadata. Next to this, there could be the decimals entry in the metadata. Everything at one place.

Storage

Yes! I think this is required, because as I understand the ERC-1155 approach, indexing a central element and let’s eliminate some parts that could go wrong.

As mentioned above, the multi-sig will be one of the first features required imo.

We at Stove Labs are still forming our opinion on the questions raised by you and are also thinking about new bullet points. We are looking forward to discuss them in detail in an online meeting!

1 Like

FA2 Answer

Permissions

Are operators the best available approach to permissioning transfers by external contracts?

I believe they are not, for multiple reasons:

  • They are a topic complex enough to deserve its own separate treatment
  • They make the standard heavier than needed, and can easily be factored out of it
  • Their current version is both too complex (most contracts not needing them) and too simple, as evidenced by the next points
  • 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
    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?

Only having operator/owner, specified allowances and expiration still leave out important use–cases:

  • Multisig
  • Daily spending limit
  • Votes
  • Generic blackbox permission

Adding all of these features would make the standard (and contract size) blow up.

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?

I believe permission matters be all moved to a dedicated permission standard, that the token standard should refer to that permission standard, and that wallets should support it.


Metadata

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)?

Yes. I discuss it more extensively in this thread.

Should Total Supply be part of token metadata rather than a separate entrypoint?

It of course should. However, we do not really have support for metadata right now. So I suggest adding it in the standard (as other kind of metadata), and removing it later once we stop needing it, as we should.

How should decimals and granularity be handled to avoid fragmentation while also easing wallet integration?

In metadata too. However, I believe it is best to leave it dealt informally instead of adding it in the contract until we have metadata.


Version

Should versioning be stored in contract metadata?
What should be included in contract versioning?

All talks of smart-contract “versioning” have been confusing me, and I believe they will until I see a clear description or concrete proposition.


External Views

Should any parts of contract storage be standardized (e.g. to assist indexers)?

Yes. I discuss it more extensively in this thread.


Future Proofing

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?

I believe not much can be done on that front so far. I found the discussion of potential future amendments and their implications good enough for now.

4 Likes

#LittleFix The link src should be replaced by LEVEL instruction (!71) · Merge requests · Metastate / tezos · GitLab