Skip to main content
Version: 1.0

Fungible Tokens in Cadence 1.0

On September 4th, 2024 the Flow Mainnet upgraded to Cadence 1.0. In addition to many changes to the Cadence programming language, the Cadence token standards also got streamlined and improved. All applications need to migrate their existing Cadence scripts and transactions for the update. If you do not update your code, your application will not function.

This document describes the changes to the Cadence Fungible Token (FT) standard. We'll be using the ExampleToken contract as an example. Many projects have used ExampleToken as a starting point for their projects, so it is widely applicable to most NFT developers on Flow. The upgrades required for ExampleToken will cover 90%+ of what you'll need to do to update your contract. Each project most likely has additional logic or features that aren't included in ExampleToken, but hopefully after reading this guide, you'll understand Cadence 1.0 well enough that you can easily make any other changes that are necessary.

As always, there are plenty of people on the Flow team and in the community who are happy to help answer any questions you may have, so please reach out in Discord if you need any help.

Important Info

Please read the FLIP that describes the changes to the FungibleToken standard first.

The updated code for the V2 Fungible Token standard is located in the master branch of the flow-ft repo. Please look at the PR that made the changes to understand how the standard and examples have changed. Note the changes to the FungibleTokenMetadataViews, Burner, FungibleTokenSwitchboard, and TokenForwarding contracts.

Additionally, here are the import addresses for all of the important contracts related to fungible tokens. The second column is the import address if you are testing with a basic version of the emulator. The third column contains the import addresses if you are using the Cadence testing framework.

ContractEmulator Import AddressTesting Framework
FungibleToken0xee82856bf20e2aa60x0000000000000002
ViewResolver0xf8d6e0586b0a20c70x0000000000000001
Burner0xf8d6e0586b0a20c70x0000000000000001
MetadataViews0xf8d6e0586b0a20c70x0000000000000001
FungibleTokenMetadataViews0xee82856bf20e2aa60x0000000000000002
FungibleTokenSwitchboard0xee82856bf20e2aa60x0000000000000002

See the other guides in this section of the docs for the import addresses of other important contracts in the emulator.

As for contracts that are important for NFT developers but aren't "core contracts", here is information about where to find the Cadence 1.0 versions of each:

USDC: USDC was migrated to standard bridged USDC on Flow. See the repo for the latest version of the USDC contract.

Account Linking and Hybrid Custody: See this PR in the hybrid custody repo for updated hybrid custody contracts.

This Discord announcement also contains versions of a lot of important contracts.

Use the Flow Contract Browser to find the 1.0 code of other contracts.

Migration Guide

Please see the NFT Cadence 1.0 migration guide. While the contracts aren't exactly the same, they share a huge amount of functionality, and the changes described in that guide will cover 90% of the changes that are needed for fungible tokens, so if you just follow those instructions for your fungible token contract, you'll be most of the way there.

Here, we will only describe the changes that are specific to the fungible token standard.

Vault implements FungibleToken.Vault

FungibleToken.Vault is no longer a resource type specification. It is now an interface that inherits from Provider, Receiver, Balance, ViewResolver.Resolver, and Burner.Burnable.

Since Vault is an interface, you will need to update every instance in your code that refers to @FungibleToken.Vault or &FungibleToken.Vault to @{FungibleToken.Vault} or &{FungibleToken.Vault} respectively to show that it is now an interface specification instead of a concrete type specification. Example in deposit():


_10
/// deposit now accepts a resource that implements the `FungibleToken.Vault` interface type
_10
access(all) fun deposit(from: @{FungibleToken.Vault})

If you have any more questions, please ask in discord and the Flow team will be happy to assist!