sui::balance
A storable handler for Balances in general. Is used in the Coin
module to allow balance operations and can be used to implement
custom coins with Supply
and Balance
s.
Supply
Balance
value
supply_value
create_supply
increase_supply
decrease_supply
zero
join
split
withdraw_all
destroy_zero
create_staking_rewards
destroy_storage_rebates
destroy_supply
send_to_account
withdraw_from_account
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::address;
use sui::dynamic_field;
use sui::hex;
use sui::object;
use sui::party;
use sui::transfer;
use sui::tx_context;
use sui::vec_map;
Supply
A Supply of T. Used for minting and burning.
Wrapped into a TreasuryCap
in the Coin
module.
public struct Supply<phantom T> has store
value: u64
Balance
Storable balance - an inner struct of a Coin type. Can be used to store coins which don’t need the key ability.
public struct Balance<phantom T> has store
value: u64
For when trying to destroy a non-zero balance.
const ENonZero: u64 = 0;
For when an overflow is happening on Supply operations.
const EOverflow: u64 = 1;
For when trying to withdraw more than there is.
const ENotEnough: u64 = 2;
Sender is not @0x0 the system address.
const ENotSystemAddress: u64 = 3;
System operation performed for a coin other than SUI
const ENotSUI: u64 = 4;
const SUI_TYPE_NAME: vector<u8> = vector[48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 50, 58, 58, 115, 117, 105, 58, 58, 83, 85, 73];
value
Get the amount stored in a Balance
.
public fun value<T>(self: &sui::balance::Balance<T>): u64
supply_value
Get the Supply
value.
public fun supply_value<T>(supply: &sui::balance::Supply<T>): u64
public fun supply_value<T>(supply: &Supply<T>): u64 {
supply.value
}
create_supply
Create a new supply for type T.
public fun create_supply<T: drop>(_: T): sui::balance::Supply<T>
public fun create_supply<T: drop>(_: T): Supply<T> {
Supply { value: 0 }
}
increase_supply
Increase supply by value
and create a new Balance<T>
with this value.
public fun increase_supply<T>(self: &mut sui::balance::Supply<T>, value: u64): sui::balance::Balance<T>
public fun increase_supply<T>(self: &mut Supply<T>, value: u64): Balance<T> {
assert!(value < (18446744073709551615u64 - self.value), EOverflow);
self.value = self.value + value;
Balance { value }
}
decrease_supply
Burn a Balance
public fun decrease_supply<T>(self: &mut sui::balance::Supply<T>, balance: sui::balance::Balance<T>): u64
public fun decrease_supply<T>(self: &mut Supply<T>, balance: Balance<T>): u64 {
let Balance { value } = balance;
assert!(self.value >= value, EOverflow);
self.value = self.value - value;
value
}
zero
Create a zero Balance
for type T
.
public fun zero<T>(): sui::balance::Balance<T>
join
Join two balances together.
public fun join<T>(self: &mut sui::balance::Balance<T>, balance: sui::balance::Balance<T>): u64
public fun join<T>(self: &mut Balance<T>, balance: Balance<T>): u64 {
let Balance { value } = balance;
self.value = self.value + value;
self.value
}
split
Split a Balance
and take a sub balance from it.
public fun split<T>(self: &mut sui::balance::Balance<T>, value: u64): sui::balance::Balance<T>
public fun split<T>(self: &mut Balance<T>, value: u64): Balance<T> {
assert!(self.value >= value, ENotEnough);
self.value = self.value - value;
Balance { value }
}
withdraw_all
Withdraw all balance. After this the remaining balance must be 0.
public fun withdraw_all<T>(self: &mut sui::balance::Balance<T>): sui::balance::Balance<T>
public fun withdraw_all<T>(self: &mut Balance<T>): Balance<T> {
let value = self.value;
split(self, value)
}
destroy_zero
Destroy a zero Balance
.
public fun destroy_zero<T>(balance: sui::balance::Balance<T>)
public fun destroy_zero<T>(balance: Balance<T>) {
assert!(balance.value == 0, ENonZero);
let Balance { value: _ } = balance;
}
create_staking_rewards
CAUTION: this function creates a Balance
without increasing the supply.
It should only be called by the epoch change system txn to create staking rewards,
and nowhere else.
fun create_staking_rewards<T>(value: u64, ctx: &sui::tx_context::TxContext): sui::balance::Balance<T>
fun create_staking_rewards<T>(value: u64, ctx: &TxContext): Balance<T> {
assert!(ctx.sender() == @0x0, ENotSystemAddress);
assert!(
std::type_name::with_defining_ids<T>().into_string().into_bytes() == SUI_TYPE_NAME,
ENotSUI,
);
Balance { value }
}
destroy_storage_rebates
CAUTION: this function destroys a Balance
without decreasing the supply.
It should only be called by the epoch change system txn to destroy storage rebates,
and nowhere else.
fun destroy_storage_rebates<T>(self: sui::balance::Balance<T>, ctx: &sui::tx_context::TxContext)
fun destroy_storage_rebates<T>(self: Balance<T>, ctx: &TxContext) {
assert!(ctx.sender() == @0x0, ENotSystemAddress);
assert!(
std::type_name::with_defining_ids<T>().into_string().into_bytes() == SUI_TYPE_NAME,
ENotSUI,
);
let Balance { value: _ } = self;
}
destroy_supply
Destroy a Supply
preventing any further minting and burning.
public(package) fun destroy_supply<T>(self: sui::balance::Supply<T>): u64
public(package) fun destroy_supply<T>(self: Supply<T>): u64 {
let Supply { value } = self;
value
}
send_to_account
fun send_to_account<T>(balance: sui::balance::Balance<T>, recipient: address)
fun send_to_account<T>(balance: Balance<T>, recipient: address) {
let Balance { value } = balance;
let accumulator = sui::accumulator::accumulator_address<Balance<T>>(recipient);
sui::accumulator::emit_deposit_event<Balance<T>>(accumulator, recipient, value);
}
withdraw_from_account
fun withdraw_from_account<T>(amount: u64, ctx: &sui::tx_context::TxContext): sui::balance::Balance<T>
fun withdraw_from_account<T>(amount: u64, ctx: &TxContext): Balance<T> {
let owner = ctx.sender();
let accumulator = sui::accumulator::accumulator_address<Balance<T>>(owner);
let credit = Balance { value: amount };
sui::accumulator::emit_withdraw_event<Balance<T>>(accumulator, owner, amount);
credit
}