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 or CosmWasm’s CW-20.
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
fn name() -> u64
Returns the total supply of tokens that have been minted.
decimals
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
fn name() -> String
Returns the symbol of the token, such as “ETH”.
symbol
Note: Requires dynamic-length strings, which are not yet implemented
fn symbol() -> String
Returns the name of the token, such as “Ether”.
mint
(optional)
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)
fn burn()
Burns all tokens sent to the contract in this function invocation.
Emits a Burn
event.
Events
Mint
struct Mint {
recipient: b256,
amount: u64,
}
Burn
struct Burn {
sender: b256,
amount: u64,
}
Reference Implementation
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.