Skip to main content

Token standards

Intermediate
Concept

Overview

Tokens deployed on ICP must adhere to a standard. The network's native token, ICP, adheres to its own standard as it is unique on the network in the sense that it is used for network utility and governance. Tokens created for other purposes on the network typically adhere to one of the ICRC standards.

ICRC stands for `Internet Computer Request for Comments'. ICRC standards are proposed by the community working group and are not specific to tokens; they can be created for anything on ICP, such as services, canister calls, or authentication methods. However, this documentation will detail the ICRC standards that are specific to tokens.

In the past, the DIP-721 standard was promoted and used by projects on the network for deploying non-fungible tokens. The ICRC-7 standard has since been developed as a newer alternative to the DIP-721 standard.

How standards are created

  • The ICRC working group creates an initial proposal for an ICRC standard.

  • The proposal is agreed upon through a rough consensus of the working group as a starting point for the standard.

  • The proposal is refined through improvement iterations by the working group.

  • Once the proposal is deemed ready for implementation by the working group, it is proposed to the NNS through an NNS proposal.

  • The ICRC standard is either adopted or rejected by the NNS.

ICP tokens

The ICP token is the network's native token used for various utility and governance functions, such as:

  • Paying for a canister's resources by being converted into cycles.

  • Rewarding node providers for contributing resources to the network.

  • Rewarding neurons for staking ICP into the neuron and voting on governance proposals.

View an example dapp for ICP transfers.

ICRC-1

The ICRC-1 standard is for fungible tokens on ICP. It uses an Account value that corresponds to the pair (principal, subaccount), where a principal can have multiple accounts, and each subaccount of a principal is identified by a 32-byte string.

The ICRC-1 standard is considered the 'base' standard and intentionally excludes certain features and functions, such as:

  • Reliable transaction notifications for smart contracts.

  • A block structure and the interface for fetching blocks.

  • Pre-signed transactions.

ICRC-1 supports extensions of this standard to implement these missing functions, and the icrc1_supported_standards endpoint can be queried to return the name of all supported extensions.

Token metadata

Token metadata is used to provide information about the token, such as the name, symbol, or fee. Available metadata entries for ICRC-1 tokens include:

  • icrc1:symbol: The token's currency code, such as variant { Text = "XTKN" }.

  • icrc1:name: The token's name, such as variant { Text = "Test Token" }.

  • icrc1:decimals: The number of decimals used by the token, such as variant { Nat = 8 }.

  • icrc1:fee: The token's default transfer fee, such as variant { Nat = 10_000 }.

Example ICRC-1 tokens on ICP include:

View an example dapp for ICRC-1 transfers.

Read the full ICRC-1 standard.

ICRC-2

The ICRC-2 standard is an extension of the ICRC-1 standard that enables additional functionality for icrc2_approve and icrc2_transfer_from transactions. Since it is an extension of ICRC-1, it supports the entire ICRC-1 standard's methods and metadata. The approve functionality allows an account owner to delegate token transfers to a third party on the owner's behalf, while the transfer from method enables approved token transactions to be initiated. This approval functionality is common in the Ethereum ecosystem through the ERC-20 token standard.

The approve and transfer from workflow uses two steps:

  1. First, the account owner allows another user to transfer up to X tokens from their account (A) by calling the ledger's icrc2_approve method.

  2. The user transfers up to X tokens from account A to any account through the icrc2_transfer_from method. The number of transfers is not limited as long as the total amount spent is below X.

Example ICRC-2 tokens on ICP include:

View an example of dapp for an ICRC-2 token swap.

View an example of a dapp that enables the transfer_from workflow.

Read the full ICRC-2 standard.

ICRC-7

ICRC-7 defines a standard for non-fungible tokens (NFTs) on ICP and can be used to create a set of NFTs, also referred to as an NFT collection. It is a minimal standard and can be thought of as the equivalent of the ICRC-1 standard, but for non-fungible tokens instead of fungible tokens. This base standard intentionally excludes some functions, such as:

  • Reliable transaction notifications for smart contracts.

  • A block structure and the interface for fetching blocks.

  • Pre-signed transactions.

ICRC-7 accounts have the same structure and follow the same overall principles as ICRC-1 accounts. ICRC-7 views the ICRC-1 Account as a primary concept, meaning that operations like transfers always refer to the full account and not only the principal portion. Some methods include an extra optional from_subaccount or spender_subaccount parameter that, together with the caller, forms an account to perform the respective operation on. Leaving such subaccount parameter null is executed the same as referring to the default subaccount comprised of all zeroes.

An extension of ICRC-7, ICRC-37, extends the standard in the same manner that ICRC-2 extends ICRC-1 as it enables spender approval functionality.

Token metadata

Available metadata entries for ICRC-7 tokens include:

  • icrc7:symbol: Type Text that defines the token's symbol, similar to a token's currency code.

  • icrc7:name: Type Text that defines the name of the token.

  • icrc7:description: Type Text that provides a description of the token.

  • icrc7:logo: Type Text, an optional URL of the token's logo image.

  • icrc7:total_supply: Type Nat: The current total number of tokens in existence.

  • icrc7:supply_cap: Type Nat, an optional maximum supply of tokens, after which minting new tokens is not possible.

Additional technical metadata elements can be found in the ICRC-7 specification.

Read the full ICRC-7 standard.

ICRC-37

The ICRC-37 standard is an extension of ICRC-7 that provides additional functionality for an approval workflow. This standard adds support for creating approvals, revoking approvals, querying approval information, and making transfers based on approvals. Token ledgers that implement ICRC-37 must implement all of the functions within ICRC-7, but ledgers that support ICRC-7 may choose whether or not to implement ICRC-37 if they intend to offer approve and transfer functionalities. The scope of ICRC-37 was originally part of ICRC-7 but was split into a separate standard for the following reasons:

  • ICRC-7 and ICRC-37 are much shorter and, hence, easier to navigate on their own.

  • Ledgers that do not want to implement approval and transfer from semantics do not need to provide dummy implementations of the corresponding methods that fail by default.

Token metadata

ICRC-37 supports all metadata entries in ICRC-7 but also includes the following:

  • icrc37:max_approvals_per_token_or_collection: Type Nat, used to define the maximum number of active approvals the ledger implementation allows per principal or per token.

  • icrc37:max_revoke_approvals: Type Nat, an optional number of approvals that may be revoked.

Read the full ICRC-37 standard.

DIP-20

The DIP-20 standard is a fungible token standard for ICP designed to replicate the Ethereum standard ERC-20. DIP-20 is a community-contributed standard that has since been replaced by the ICRC-2 standard.

View the full DIP-20 specification.

DIP-721

The DIP-721 standard is a non-fungible token standard for ICP designed to replicate the Ethereum standard ERC-721. DIP-721 is a community-contributed standard that has since been replaced by the proposed ICRC-7 standard.

View the full DIP-721 specification.

Resources