# SRC-20: Fungible token standard

**URL:** <https://forum.fuel.network/t/src-20-fungible-token-standard/186>\
**Category:** Sway RFCs\
**Created:** [December 12, 2022, 10:46pm UTC](https://forum.fuel.network/t/src-20-fungible-token-standard/186 "2022-12-12T22:46:07Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![david](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/david/32/32_2.png) [@david](https://forum.fuel.network/u/david)\
**Post date:** [December 12, 2022, 10:46pm UTC](https://forum.fuel.network/t/src-20-fungible-token-standard/186/1 "2022-12-12T22:46:07Z")

</div>

# Summary

SRC-20 is a standard for fungible tokens built in Sway.

# Abstract

SRC-20 defines a common interface for Sway smart contracts that issue fungible tokens. Given that the Fuel VM supports native assets, this standard will be primarily concerned with asset metadata (name, symbol, supply, decimals), as well as other optional functions (mint, burn).

_Note: while most SRCs will be numbered sequentially, the number SRC-20 was chosen to align with the EVM’s famous “ERC-20 standard”, as well other similar standards like BSC’s [BEP-20](https://github.com/bnb-chain/BEPs/blob/master/BEP20.md) or CosmWasm’s [CW-20](https://docs.cosmwasm.com/cw-plus/0.9.0/cw20/spec/)._

# Motivation

A standardized token format will allow for smart contracts to interact with any arbitrary fungible token. This SRC provides all the standard features that developers have learned to expect from the ERC-20 standard.

# Specification

## Methods

### `total_supply`

```rust
fn name() -> u64

```

Returns the total supply of tokens that have been minted.

### `decimals`

```rust
fn decimals() -> u8

```

Returns the number of decimals the token uses - e.g. `8`, means to divide the token amount by `100000000` to get its user representation.

_Note: is it worth considering ERC777’s `granularity`, which is more powerful?_

### `name`

**Note: Requires dynamic-length strings, which are not yet implemented**

```rust
fn name() -> String

```

Returns the symbol of the token, such as “ETH”.

### `symbol`

**Note: Requires dynamic-length strings, which are not yet implemented**

```rust
fn symbol() -> String

```

Returns the name of the token, such as “Ether”.

### `mint` (optional)

```rust
fn mint(recipient: Identity, amount: u64)

```

Mints `amount` tokens and transfers them to the `recipient` address. This function may contain arbitrary conditions for minting, and revert if those conditions are not met.

Emits a `Mint` event.

### `burn` (optional)

```rust
fn burn()

```

Burns all tokens sent to the contract in this function invocation.

Emits a `Burn` event.

## Events

### Mint

```rust
struct Mint {
    recipient: b256,
    amount: u64,
}

```

### Burn

```rust
struct Burn {
    sender: b256,
    amount: u64,
}

```

# Reference Implementation

```rust
contract;

abi Token {
    #[storage(read)]
    fn total_supply() -> u64;
    fn decimals() -> u8;
    fn name() -> String;
    fn symbol() -> String;
    fn mint(recipient: Identity, amount: u64);
    fn burn();
}

struct Mint {
    recipient: b256,
    amount: u64,
}

struct Burn {
    sender: b256,
    amount: u64,
}

storage {
    total_supply: u64 = 0,
}

impl Token for Contract {
    #[storage(read)]
    fn total_supply() -> u64 {
        storage.total_supply
    }

    fn decimals() -> u8 {
        9
    }

    fn name() -> String {
        // TODO
    }

    fn symbol() -> String {
        // TODO
    }

    fn mint(recipient: Identity, amount: u64) {
        storage.total_supply += amount;
        mint_to_address(storage.mint_amount, recipient);
        log(Mint);
    }

    fn burn() {
        burn(msg_amount());
        log(Burn);
    }
}

```

# Security Considerations

This standard does not introduce any security concerns, as it does not call external contracts, nor does it define any mutations of the contract state.

---

<div class="post-metadata">

**Author:** ![furnic](https://avatars.discourse-cdn.com/v4/letter/f/97f17d/32.png) [@furnic](https://forum.fuel.network/u/furnic)\
**Post date:** [December 14, 2022, 1:42pm UTC](https://forum.fuel.network/t/src-20-fungible-token-standard/186/2 "2022-12-14T13:42:32Z")

</div>

First of all, it’s great to see some effort toward creating standards by the community!

I will look over this more closely, but one thing that jumped out at me was that `fn mint` takes an `Identity` type for the `recipient` param (as it should), so it should therefore use `std::token::mint_to` which also takes an `Identity`.

Also, we do have a public repo set up for just this type of thing here:

> **[GitHub - FuelLabs/sway-rfcs: RFCs for changes to Sway](https://github.com/FuelLabs/sway-rfcs)**
>
> RFCs for changes to Sway. Contribute to FuelLabs/sway-rfcs development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![david](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/david/32/32_2.png) [@david](https://forum.fuel.network/u/david)\
**Post date:** [December 22, 2022, 8:48pm UTC](https://forum.fuel.network/t/src-20-fungible-token-standard/186/3 "2022-12-22T20:48:15Z")

</div>

Some quick updates:

Thanks @furnic for the tip regarding `mint_to`. I’ll update the post to include that once it’s possible to edit posts ([[Meta] Ability to edit posts](https://forum.fuel.network/t/meta-ability-to-edit-posts/1134)).

Also, @fuel had a good post about the ability to store strings in Sway:

> [@How to save strings in the storage of dapp?](https://forum.fuel.network/t/how-to-save-strings-in-the-storage-of-dapp/735):
>
> Hello everyone! In an attempt to implement a token contract on fuel I forked swayswap’s token contract and noticed that swayswap’s token doesn’t support the same fields like name, symbol, and decimals. Then in [one of my previous topics](https://forum.fuel.network/t/which-token-contract-i-should-to-use/373) @david sent me a topic with [src-20 fungible token standard](https://forum.fuel.network/t/src-20-fungible-token-standard/186), but there is no name, symbol implementation too… And today I decided to figure out how I can store strings in the storage. In the progress of my research I found some solutions, let’s take a closer l…

@fuel’s current token implementation ([https://github.com/sway-gang/fuel-token-standard/blob/master/src/main.sw](https://github.com/sway-gang/fuel-token-standard/blob/master/src/main.sw)) currently uses fixed-length character arrays for the name & symbol elements. This is probably the best way to implement these strings today, however I believe the final token standard should use dynamic-length strings (which aren’t available yet).

---

<div class="post-metadata">

**Author:** ![zzzzt](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/zzzzt/32/724_2.png) [@zzzzt](https://forum.fuel.network/u/zzzzt)\
**Post date:** [January 16, 2023, 6:46pm UTC](https://forum.fuel.network/t/src-20-fungible-token-standard/186/4 "2023-01-16T18:46:52Z")

</div>

> [@furnic](#):
>
> [GitHub - FuelLabs/sway-rfcs: RFCs for changes to Sway](https://github.com/FuelLabs/sway-rfcs)

i think this should be `fn totoal_supply() -> u64?`

 ![image](https://us1.discourse-cdn.com/flex022/uploads/fuel/original/1X/39114b9c100d5ff2475f56cfb4cc318ff7f53f1e.png)

---

<div class="post-metadata">

**Author:** ![irka\_ukrainka](https://avatars.discourse-cdn.com/v4/letter/i/f17d59/32.png) [@irka\_ukrainka](https://forum.fuel.network/u/irka_ukrainka)\
**Post date:** [January 18, 2023, 10:44am UTC](https://forum.fuel.network/t/src-20-fungible-token-standard/186/5 "2023-01-18T10:44:38Z")

</div>

so difficult information

---

<div class="post-metadata">

**Author:** ![Daniel-Verilog](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/daniel-verilog/32/705_2.png) [@Daniel-Verilog](https://forum.fuel.network/u/Daniel-Verilog)\
**Post date:** [February 9, 2023, 12:07am UTC](https://forum.fuel.network/t/src-20-fungible-token-standard/186/6 "2023-02-09T00:07:49Z")

</div>

the `mint` function has to be a permissioned function, please consider adding `onlyOwner` or `onlyDAO` similar logic into the consideration.

Besides, I feel the modern day token contracts all have hardcoded inflation, such as Uniswap governance, where project team are only allow less than 2% of the token inflation.

---

<div class="post-metadata">

**Author:** ![furnic](https://avatars.discourse-cdn.com/v4/letter/f/97f17d/32.png) [@furnic](https://forum.fuel.network/u/furnic)\
**Post date:** [February 14, 2023, 7:13pm UTC](https://forum.fuel.network/t/src-20-fungible-token-standard/186/7 "2023-02-14T19:13:20Z")

</div>

@david Sorry for the delay on this, but it looks like letting users edit posts is NOT on the agenda atm. So, I suggest posting an updated abi based on feedback and we can continue to discuss from there 🙂

---

<div class="post-metadata">

**Author:** ![fuel](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/fuel/32/1677_2.png) [@fuel](https://forum.fuel.network/u/fuel)\
**Post date:** [February 15, 2023, 12:42pm UTC](https://forum.fuel.network/t/src-20-fungible-token-standard/186/8 "2023-02-15T12:42:18Z")

</div>

I’m Alex from SWAY GANG , we’re building [swaylend.com](http://swaylend.com) (Compound rewritten into Sway)

I would like to discuss a fungible token standard on fuel.

Teams building defi projects on Fuel use their own temporary token standards.

Let’s join forces and build a universal and efficient token standard.

As I see it, we now have two options:

1. Rewrite the ERC-20-like fuel standard

2. Implement a token standard based on the native token

We have already implemented option 2 in [swaylend.com](http://swaylend.com)

It has methods for getting decimals, name, symbol etc

> **[GitHub - sway-gang/fuel-token-standard: Fuel network Fungible token standard](https://github.com/sway-gang/fuel-token-standard)**
>
> Fuel network Fungible token standard. Contribute to sway-gang/fuel-token-standard development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![furnic](https://avatars.discourse-cdn.com/v4/letter/f/97f17d/32.png) [@furnic](https://forum.fuel.network/u/furnic)\
**Post date:** [February 15, 2023, 9:14pm UTC](https://forum.fuel.network/t/src-20-fungible-token-standard/186/9 "2023-02-15T21:14:28Z")

</div>

Thanks for sharing the “Fuel Token Standard”, I just had a quick look over it now.  
What is the purpose of `set_mint_amount` ? It was not clear to me what it does without docs.  
I think in general, a token standard should be as minimal as practical. So any admin functions for example could be part of a separate `TokenAdmin` abi . A fungible token contract would implement the basic `Token` abi, and could optionally implement the `TokenAdmin` abi if that functionality is needed, without forcing all users of the standard to implement unneeded functions. So we can compose functionality by combining the set of `abi`s we need for a given use case.  
Exposing a transfer function in the abi is key, so nice to see your `transfer_coins` function. It should probably take an `Identity` instead of an `Address` if you want to be able to transfer to contracts as well.  
Just a few of my own thought based on an initial readthrough, but nice work!

---

<div class="post-metadata">

**Author:** ![fuel](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/fuel/32/1677_2.png) [@fuel](https://forum.fuel.network/u/fuel)\
**Post date:** [February 16, 2023, 10:17am UTC](https://forum.fuel.network/t/src-20-fungible-token-standard/186/10 "2023-02-16T10:17:58Z")

</div>

Most of the methods associated with administering tokens are only needed for the testnet period. As soon as the testnet comes, they are all gone. Also I brought up this topic to agree on a standard with all of you, so please let’s first decide which approach we will choose and then develop a standard. I am so far ready to participate 100%.

---

<div class="post-metadata">

**Author:** ![furnic](https://avatars.discourse-cdn.com/v4/letter/f/97f17d/32.png) [@furnic](https://forum.fuel.network/u/furnic)\
**Post date:** [March 6, 2023, 11:30pm UTC](https://forum.fuel.network/t/src-20-fungible-token-standard/186/11 "2023-03-06T23:30:20Z")

</div>

So after some discussion last week about this with some fuel contributors, we were leaning towards something like the following as far as the abi goes, which is pretty much what @david originally proposed:

```auto
abi Token {
    #[storage(read)]
    fn total_supply() -> U256;
    fn decimals() -> u8;
    fn name() -> str[64];
    fn symbol() -> str[32];
}

```

Any other functions would be part of some optional add-on abis, i.e: `mint`, `burn`, etc… and these would also need to be specified in a standard way.

A return type of `U256` for `total_supply` would support tokens with either very large supplies or high precision needs(18 decimals for example), but most tokens could probably be fine 9 decimals precision and storing the total supply as a `u64` (and just casting to a `U256` when returning).

`name` and `symbol` are tricky as the support for dynamic strings in Sway is not implemented yet. I think using static sized strings for these and just padding the strings with spaces to the required size is fine, for example: `const SYMBOL: str[32] = "MYTKN ";`.  
It’s a little hacky but gets the job done for now and the frontend can easily trim the whitespace.

 ![image](https://us1.discourse-cdn.com/flex022/uploads/fuel/original/2X/1/1e8431ff9aa96f78f5cb0206c5c228cc8076e05a.png)

Speak up if you have any thoughts, questions or concerns with this approach, as nothing is written in stone yet 🙂

Also, as much as the dev in me appreciates the `SRC` prefix, I wonder if we should consider using `FRC` for Fuel, as there will likely be other languages targeting the Fuel VM meaning the standard should to be higher level than just Sway. 🤔

cc @david @fuel

---

<div class="post-metadata">

**Author:** ![fuel](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/fuel/32/1677_2.png) [@fuel](https://forum.fuel.network/u/fuel)\
**Post date:** [March 9, 2023, 12:21am UTC](https://forum.fuel.network/t/src-20-fungible-token-standard/186/12 "2023-03-09T00:21:51Z")

</div>

@furnic @david  
Let’s have a call and discuss this,  
Also, I want to suggest setup a telegram/discord chat about token standard because its too big response time here

---

<div class="post-metadata">

**Author:** ![furnic](https://avatars.discourse-cdn.com/v4/letter/f/97f17d/32.png) [@furnic](https://forum.fuel.network/u/furnic)\
**Post date:** [March 10, 2023, 6:38pm UTC](https://forum.fuel.network/t/src-20-fungible-token-standard/186/13 "2023-03-10T18:38:52Z")

</div>

For everyone interested, I’ve copied the main points over from this topic to a github issue in the Fuel labs RFCs repo to try to finalize a standard: [Create a standard abi for fungible tokens. · Issue #13 · FuelLabs/rfcs · GitHub](https://github.com/FuelLabs/rfcs/issues/13)  
I feel like we’re close, but need a bit more discussion of fine details.

cc @fuel @david

---

<div class="post-metadata">

**Author:** ![furnic](https://avatars.discourse-cdn.com/v4/letter/f/97f17d/32.png) [@furnic](https://forum.fuel.network/u/furnic)\
**Post date:** [March 14, 2023, 3:13pm UTC](https://forum.fuel.network/t/src-20-fungible-token-standard/186/14 "2023-03-14T15:13:09Z")

</div>

Just a reminder: please comment [here](https://github.com/FuelLabs/rfcs/issues/13) if you want to have more input on a fungible token standard!

cc @david @fuel

---

<div class="post-metadata">

**Author:** ![fuel](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/fuel/32/1677_2.png) [@fuel](https://forum.fuel.network/u/fuel)\
**Post date:** [May 18, 2023, 11:13pm UTC](https://forum.fuel.network/t/src-20-fungible-token-standard/186/15 "2023-05-18T23:13:38Z")

</div>

sorry ser, missed this message  
Will do right now 🫡

---

<div class="post-metadata">

**Author:** ![david](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/david/32/32_2.png) [@david](https://forum.fuel.network/u/david)\
**Post date:** [May 19, 2023, 1:31am UTC](https://forum.fuel.network/t/src-20-fungible-token-standard/186/16 "2023-05-19T01:31:28Z")

</div>

Hey @fuel, we’ve moved standards to the sway-standards repo.

The new place for SRC-20 discussions is here:

> <https://github.com/FuelLabs/sway-standards/issues/1>
>
> \# Abstract
> 
> The following standard allows for the implementation of a standard… API for \[Native Assets\](https://fuellabs.github.io/sway/v0.38.0/book/blockchain-development/native\_assets.html) using the Sway Language. This standard provides basic functionality as well as on-chain metadata for other applications to use.
> 
> \# Motivation
> 
> A standard interface for \[Native Assets\](https://fuellabs.github.io/sway/v0.38.0/book/blockchain-development/native\_assets.html) on Fuel allows external applications to interact with the token, whether that be decentralized exchanges, wallets, or Fuel's \[Scripts\](https://fuellabs.github.io/sway/v0.38.0/book/sway-program-types/scripts.html) and \[Predicates\](https://fuellabs.github.io/sway/v0.38.0/book/sway-program-types/predicates.html). 
> 
> \# Prior Art
> 
> The SRC-20 Fungible Token Standard naming pays homage to the \[ERC-20 Token Standard\](https://eips.ethereum.org/EIPS/eip-20) seen on Ethereum. While there is functionality we may use as reference, it is noted that Fuel's \[Native Assets\](https://fuellabs.github.io/sway/v0.38.0/book/blockchain-development/native\_assets.html) are fundamentally different than Ethereum's tokens.
> 
> There has been a discussion of the Fungile Token Standard on the \[Fuel Forum\](https://forum.fuel.network/). This discussion can be found \[here\](https://forum.fuel.network/t/src-20-fungible-token-standard/186). 
> 
> There has also been a Fungile Token Standard implementation added to the \[Sway-Libs\](https://github.com/FuelLabs/sway-libs) repository before the creation of the \[Sway-Standards\](https://github.com/FuelLabs/sway-standards) repository. The introduction of this standard in the \[Sway-Standards\](https://github.com/FuelLabs/sway-standards) repository will deprecate the Sway-Libs Fungible Token Standard.
> 
> \# Specification
> 
> \## Required Public Functions
> 
> The following functions MUST be implemented to follow the SRC-20 standard:
> 
> \### \`fn name() -\> String\` 
> Returns the name of the token, such as “Ether”.
> 
> \### \`fn total\_supply() -\> u64\`
> Returns the total supply of tokens that have been minted.
> 
> \### \`fn decimals() -\> u8\`
> Returns the number of decimals the token uses - e.g. 8, means to divide the token amount by 100000000 to get its user representation.
> 
> \### \`fn symbol() -\> String\`
> Returns the symbol of the token, such as “ETH”.
> 
> \### Rationale
> 
> As the SRC-20 Fungible Token Standard leverages Native Assets on Fuel, we do not require the implementation of certain functions such as transfer. This is done directly within the FuelVM and there is no smart contract that requires updating of balances. As Fuel is UTXO based, any transfer events may be indexed on transaction receipts. 
> 
> Following this, we have omitted the inclusion of any transfer functions or events. The provided specification outlines only the required functions and events to implement fully functional tokens on the Fuel Network. Additional functionality and properties may be added as needed.
> 
> \### Backwards Compatibility
> 
> This standard is compatible with Fuel's \[Native Assets\](https://fuellabs.github.io/sway/v0.38.0/book/blockchain-development/native\_assets.html). There are no other standards that require compatibility.
> 
> \### Security Considerations
> 
> This standard does not introduce any security concerns, as it does not call external contracts, nor does it define any mutations of the contract state.
> 
> \### Example ABI
> 
> \`\`\`rust 
> abi MyToken {
> #\[storage(read)\]
> fn total\_supply() -\> u64;
> #\[storage(read)\]
> fn decimals() -\> u8;
> #\[storage(read)\]
> fn name() -\> String;
> #\[storage(read)\]
> fn symbol() -\> String;
> }
> \`\`\`
> 
> This draft standard is to be released as \`v0.1\`.
