Module sui::coin
Defines the
Coin type - platform wide representation of fungible
tokens and coins. Coin can be described as a secure wrapper around
Balance type.
- Struct Coin
- Struct CoinMetadata
- Struct RegulatedCoinMetadata
- Struct TreasuryCap
- Struct DenyCapV2
- Struct CurrencyCreated
- Struct DenyCap
- Constants
- Function total_supply
- Function treasury_into_supply
- Function supply_immut
- Function supply_mut
- Function value
- Function balance
- Function balance_mut
- Function from_balance
- Function into_balance
- Function take
- Function put
- Function join
- Function split
- Function divide_into_n
- Function zero
- Function destroy_zero
- Function create_currency
- Function create_regulated_currency_v2
- Function migrate_regulated_currency_to_v2
- Function mint
- Function mint_balance
- Function burn
- Function deny_list_v2_add
- Function deny_list_v2_remove
- Function deny_list_v2_contains_current_epoch
- Function deny_list_v2_contains_next_epoch
- Function deny_list_v2_enable_global_pause
- Function deny_list_v2_disable_global_pause
- Function deny_list_v2_is_global_pause_enabled_current_epoch
- Function deny_list_v2_is_global_pause_enabled_next_epoch
- Function mint_and_transfer
- Function update_name
- Function update_symbol
- Function update_description
- Function update_icon_url
- Function get_decimals
- Function get_name
- Function get_symbol
- Function get_description
- Function get_icon_url
- Function destroy_metadata
- Function deny_cap_id
- Function new_deny_cap_v2
- Function new_treasury_cap
- Function allow_global_pause
- Function supply
- Function create_regulated_currency
- Function deny_list_add
- Function deny_list_remove
- Function deny_list_contains
use std::address;
use std::ascii;
use std::bcs;
use std::option;
use std::string;
use std::type_name;
use std::vector;
use sui::accumulator;
use sui::accumulator_metadata;
use sui::accumulator_settlement;
use sui::address;
use sui::bag;
use sui::balance;
use sui::bcs;
use sui::config;
use sui::deny_list;
use sui::dynamic_field;
use sui::dynamic_object_field;
use sui::event;
use sui::funds_accumulator;
use sui::hash;
use sui::hex;
use sui::object;
use sui::party;
use sui::table;
use sui::transfer;
use sui::tx_context;
use sui::types;
use sui::url;
use sui::vec_map;
use sui::vec_set;
Struct Coin
A coin of type T worth
value. Transferable and storable
public struct Coin<phantom T> has key, store
Fields
Struct CoinMetadata
Each Coin type T created through
create_currency function will have a
unique instance of CoinMetadatapublic struct CoinMetadata<phantom T> has key, store
Fields
-
id: sui::object::UID -
decimals: u8 -
Number of decimal places the coin uses.
A coin with
N andvaluedecimalsD should be shown as N / 10^D E.g., a coin with
7002 and decimals 3 should be displayed as 7.002 This is metadata for display usage only.value -
name: std::string::String - Name for the token
-
symbol: std::ascii::String - Symbol for the token
-
description: std::string::String - Description of the token
-
icon_url: std::option::Option<sui::url::Url> - URL for the token logo
Struct RegulatedCoinMetadata
Similar to CoinMetadata, but created only for regulated coins that use the DenyList. This object is always immutable.
public struct RegulatedCoinMetadata<phantom T> has key
Fields
-
id: sui::object::UID -
coin_metadata_object: sui::object::ID - The ID of the coin's CoinMetadata object.
-
deny_cap_object: sui::object::ID - The ID of the coin's DenyCap object.
Struct TreasuryCap
Capability allowing the bearer to mint and burn
coins of type T. Transferable
public struct TreasuryCap<phantom T> has key, store
Fields
Struct DenyCapV2
Capability allowing the bearer to deny addresses from using the currency's coins-- immediately preventing those addresses from interacting with the coin as an input to a transaction and at the start of the next preventing them from receiving the coin. If
allow_global_pause is true, the bearer can enable a global pause that behaves as if
all addresses were added to the deny list.
public struct DenyCapV2<phantom T> has key, store
Fields
-
id: sui::object::UID -
allow_global_pause: bool
Struct CurrencyCreated
public struct CurrencyCreated<phantom T> has copy, drop
Fields
-
decimals: u8
Struct DenyCap
Capability allowing the bearer to freeze addresses, preventing those addresses from interacting with the coin as an input to a transaction.
public struct DenyCap<phantom T> has key, store
Fields
-
id: sui::object::UID
Constants
A type passed to create_supply is not a one-time witness.
const EBadWitness: u64 = 0;
Invalid arguments are passed to a function.
const EInvalidArg: u64 = 1;
Trying to split a coin more times than its balance allows.
const ENotEnough: u64 = 2;
const EGlobalPauseNotAllowed: u64 = 3;
The index into the deny list vector for the
sui::coin::Coin type.
const DENY_LIST_COIN_INDEX: u64 = 0;
Function total_supply
Return the total number of T's in circulation.
public fun total_supply<T>(cap: &sui::coin::TreasuryCap<T>): u64
Implementation
public fun total_supply<T>(cap: &TreasuryCap<T>): u64 {
balance::supply_value(&cap.total_supply)
}
Function treasury_into_supply
Unwrap
TreasuryCap getting the Supply.
Operation is irreversible. Supply cannot be converted into a
TreasuryCap due
to different security guarantees (TreasuryCap can be created only once for a type)
public fun treasury_into_supply<T>(treasury: sui::coin::TreasuryCap<T>): sui::balance::Supply<T>
Implementation
public fun treasury_into_supply<T>(treasury: TreasuryCap<T>): Supply<T> {
let TreasuryCap { id, total_supply } = treasury;
id.delete();
total_supply
}
Function supply_immut
Get immutable reference to the treasury's Supply.
public fun supply_immut<T>(treasury: &sui::coin::TreasuryCap<T>): &sui::balance::Supply<T>
Implementation
public fun supply_immut<T>(treasury: &TreasuryCap<T>): &Supply<T> {
&treasury.total_supply
}
Function supply_mut
Get mutable reference to the treasury's Supply.
public fun supply_mut<T>(treasury: &mut sui::coin::TreasuryCap<T>): &mut sui::balance::Supply<T>
Implementation
public fun supply_mut<T>(treasury: &mut TreasuryCap<T>): &mut Supply<T> {
&mut treasury.total_supply
}
Function value
Public getter for the coin's value
public fun value<T>(self: &sui::coin::Coin<T>): u64
Function balance
Get immutable reference to the balance of a coin.
public fun balance<T>(coin: &sui::coin::Coin<T>): &sui::balance::Balance<T>
Function balance_mut
Get a mutable reference to the balance of a coin.
public fun balance_mut<T>(coin: &mut sui::coin::Coin<T>): &mut sui::balance::Balance<T>
Implementation
public fun balance_mut<T>(coin: &mut Coin<T>): &mut Balance<T> {
&mut coin.balance
}
Function from_balance
Wrap a balance into a Coin to make it transferable.
public fun from_balance<T>(balance: sui::balance::Balance<T>, ctx: &mut sui::tx_context::TxContext): sui::coin::Coin<T>
Implementation
public fun from_balance<T>(balance: Balance<T>, ctx: &mut TxContext): Coin<T> {
Coin { id: object::new(ctx), balance }
}
Function into_balance
Destruct a Coin wrapper and keep the balance.
public fun into_balance<T>(coin: sui::coin::Coin<T>): sui::balance::Balance<T>
Function take
Take a
Coin worth of value from Balance.
Aborts if value > balance.value
public fun take<T>(balance: &mut sui::balance::Balance<T>, value: u64, ctx: &mut sui::tx_context::TxContext): sui::coin::Coin<T>
Function put
Put a
Coin<T> to the Balance<T>.
public fun put<T>(balance: &mut sui::balance::Balance<T>, coin: sui::coin::Coin<T>)
Function join
Consume the coin c and add its value to self.
Aborts if
c.value + self.value > U64_MAX
public entry fun join<T>(self: &mut sui::coin::Coin<T>, c: sui::coin::Coin<T>)
Function split
Split coin self to two coins, one with balance split_amount,
and the remaining balance is left is self.
public fun split<T>(self: &mut sui::coin::Coin<T>, split_amount: u64, ctx: &mut sui::tx_context::TxContext): sui::coin::Coin<T>
Function divide_into_n
Split coin self into n - 1 coins with equal balances. The remainder is left in
self. Return newly created coins.
public fun divide_into_n<T>(self: &mut sui::coin::Coin<T>, n: u64, ctx: &mut sui::tx_context::TxContext): vector<sui::coin::Coin<T>>
Implementation
public fun divide_into_n<T>(self: &mut Coin<T>, n: u64, ctx: &mut TxContext): vector<Coin<T>> {
assert!(n > 0, EInvalidArg);
assert!(n <= self.value(), ENotEnough);
let split_amount = self.value() / n;
vector::tabulate!(n - 1, |_| self.split(split_amount, ctx))
}
Function zero
Make any Coin with a zero value. Useful for placeholding bids/payments or preemptively making empty balances.
public fun zero<T>(ctx: &mut sui::tx_context::TxContext): sui::coin::Coin<T>
Implementation
public fun zero<T>(ctx: &mut TxContext): Coin<T> {
Coin { id: object::new(ctx), balance: balance::zero() }
}
Function destroy_zero
Destroy a coin with value zero
public fun destroy_zero<T>(c: sui::coin::Coin<T>)
Implementation
public fun destroy_zero<T>(c: Coin<T>) {
let Coin { id, balance } = c;
id.delete();
balance.destroy_zero()
}
Function create_currency
Create a new currency type T as and return the
TreasuryCap for
T to the caller. Can only be called with a one-time-witness
type, ensuring that there's only one TreasuryCap per T.
public fun create_currency<T: drop>(witness: T, decimals: u8, symbol: vector<u8>, name: vector<u8>, description: vector<u8>, icon_url: std::option::Option<sui::url::Url>, ctx: &mut sui::tx_context::TxContext): (sui::coin::TreasuryCap<T>, sui::coin::CoinMetadata<T>)
Implementation
public fun create_currency<T: drop>(
witness: T,
decimals: u8,
symbol: vector<u8>,
name: vector<u8>,
description: vector<u8>,
icon_url: Option<Url>,
ctx: &mut TxContext,
): (TreasuryCap<T>, CoinMetadata<T>) {
// Make sure there's only one instance of the type T
assert!(sui::types::is_one_time_witness(&witness), EBadWitness);
(
TreasuryCap {
id: object::new(ctx),
total_supply: balance::create_supply(witness),
},
CoinMetadata {
id: object::new(ctx),
decimals,
name: name.to_string(),
symbol: symbol.to_ascii_string(),
description: description.to_string(),
icon_url,
},
)
}
Function create_regulated_currency_v2
This creates a new currency, via
create_currency, but with an extra capability that
allows for specific addresses to have their coins frozen. When an address is added to the
deny list, it is immediately unable to interact with the currency's coin as input objects.
Additionally at the start of the next epoch, they will be unable to receive the currency's
coin.
The allow_global_pause flag enables an additional API that will cause all addresses to
be denied. Note however, that this doesn't affect per-address entries of the deny list and
will not change the result of the "contains" APIs.
public fun create_regulated_currency_v2<T: drop>(witness: T, decimals: u8, symbol: vector<u8>, name: vector<u8>, description: vector<u8>, icon_url: std::option::Option<sui::url::Url>, allow_global_pause: bool, ctx: &mut sui::tx_context::TxContext): (sui::coin::TreasuryCap<T>, sui::coin::DenyCapV2<T>, sui::coin::CoinMetadata<T>)
Implementation
public fun create_regulated_currency_v2<T: drop>(
witness: T,
decimals: u8,
symbol: vector<u8>,
name: vector<u8>,
description: vector<u8>,
icon_url: Option<Url>,
allow_global_pause: bool,
ctx: &mut TxContext,
): (TreasuryCap<T>, DenyCapV2<T>, CoinMetadata<T>) {
let (treasury_cap, metadata) = create_currency(
witness,
decimals,
symbol,
name,
description,
icon_url,
ctx,
);
let deny_cap = DenyCapV2 {
id: object::new(ctx),
allow_global_pause,
};
transfer::freeze_object(RegulatedCoinMetadata<T> {
id: object::new(ctx),
coin_metadata_object: object::id(&metadata),
deny_cap_object: object::id(&deny_cap),
});
(treasury_cap, deny_cap, metadata)
}
Function migrate_regulated_currency_to_v2
Given the
DenyCap for a regulated currency, migrate it to the new DenyCapV2 type.
All entries in the deny list will be migrated to the new format.
See create_regulated_currency_v2 for details on the new v2 of the deny list.
public fun migrate_regulated_currency_to_v2<T>(deny_list: &mut sui::deny_list::DenyList, cap: sui::coin::DenyCap<T>, allow_global_pause: bool, ctx: &mut sui::tx_context::TxContext): sui::coin::DenyCapV2<T>
Implementation
public fun migrate_regulated_currency_to_v2<T>(
deny_list: &mut DenyList,
cap: DenyCap<T>,
allow_global_pause: bool,
ctx: &mut TxContext,
): DenyCapV2<T> {
let DenyCap { id } = cap;
id.delete();
let ty = type_name::with_original_ids<T>().into_string().into_bytes();
deny_list.migrate_v1_to_v2(DENY_LIST_COIN_INDEX, ty, ctx);
DenyCapV2 {
id: object::new(ctx),
allow_global_pause,
}
}
Function mint
Create a coin worth
value and increase the total supply
in cap accordingly.
public fun mint<T>(cap: &mut sui::coin::TreasuryCap<T>, value: u64, ctx: &mut sui::tx_context::TxContext): sui::coin::Coin<T>
Implementation
public fun mint<T>(cap: &mut TreasuryCap<T>, value: u64, ctx: &mut TxContext): Coin<T> {
Coin {
id: object::new(ctx),
balance: cap.total_supply.increase_supply(value),
}
}
Function mint_balance
Mint some amount of T as a Balance and increase the total
supply in cap accordingly.
Aborts if
value + cap.total_supply >= U64_MAX
public fun mint_balance<T>(cap: &mut sui::coin::TreasuryCap<T>, value: u64): sui::balance::Balance<T>
Implementation
public fun mint_balance<T>(cap: &mut TreasuryCap<T>, value: u64): Balance<T> {
cap.total_supply.increase_supply(value)
}
Function burn
Destroy the coin c and decrease the total supply in cap
accordingly.
public entry fun burn<T>(cap: &mut sui::coin::TreasuryCap<T>, c: sui::coin::Coin<T>): u64
Implementation
public entry fun burn<T>(cap: &mut TreasuryCap<T>, c: Coin<T>): u64 {
let Coin { id, balance } = c;
id.delete();
cap.total_supply.decrease_supply(balance)
}