axelar-cgp-sui

Module 0xa5::coin_management

use 0x1::option;
use 0x2::balance;
use 0x2::clock;
use 0x2::coin;
use 0x2::tx_context;
use 0xa1::channel;
use 0xa5::flow_limit;

Struct CoinManagement

Struct that stores information about the ITS Coin.

struct CoinManagement<T> has store
Fields
treasury_cap: option::Option<coin::TreasuryCap<T>>
balance: option::Option<balance::Balance<T>>
distributor: option::Option<address>
operator: option::Option<address>
flow_limit: flow_limit::FlowLimit
scaling: u256
dust: u256

Constants

const EDistributorNeedsTreasuryCap: vector<u8> = [116, 114, 121, 105, 110, 103, 32, 116, 111, 32, 97, 100, 100, 32, 97, 32, 100, 105, 115, 116, 114, 105, 98, 117, 116, 111, 114, 32, 116, 111, 32, 97, 32, 96, 67, 111, 105, 110, 77, 97, 110, 97, 103, 101, 109, 101, 110, 116, 96, 32, 116, 104, 97, 116, 32, 100, 111, 101, 115, 32, 110, 111, 116, 32, 104, 97, 118, 101, 32, 97, 32, 96, 84, 114, 101, 97, 115, 117, 114, 121, 67, 97, 112, 96];

const ENotOperator: vector<u8> = [99, 104, 97, 110, 110, 101, 108, 32, 112, 114, 111, 118, 105, 100, 101, 100, 32, 105, 115, 32, 110, 111, 116, 32, 116, 104, 101, 32, 111, 112, 101, 114, 97, 116, 111, 114];

Function new_with_cap

Create a new CoinManagement with a TreasuryCap. This type of CoinManagement allows minting and burning of coins.

public fun new_with_cap<T>(treasury_cap: coin::TreasuryCap<T>): coin_management::CoinManagement<T>
Implementation
public fun new_with_cap<T>(treasury_cap: TreasuryCap<T>): CoinManagement<T> {
    CoinManagement<T> {
        treasury_cap: option::some(treasury_cap),
        balance: option::none(),
        distributor: option::none(),
        operator: option::none(),
        flow_limit: flow_limit::new(),
        scaling: 0, // placeholder, this gets edited when a coin is registered.
        dust: 0,
    }
}

Function new_locked

Create a new CoinManagement with a Balance. The stored Balance can be used to take and put coins.

public fun new_locked<T>(): coin_management::CoinManagement<T>
Implementation
public fun new_locked<T>(): CoinManagement<T> {
    CoinManagement<T> {
        treasury_cap: option::none(),
        balance: option::some(balance::zero()),
        distributor: option::none(),
        operator: option::none(),
        flow_limit: flow_limit::new(),
        scaling: 0, // placeholder, this gets edited when a coin is registered.
        dust: 0,
    }
}

Function add_distributor

Adds the distributor address to the CoinManagement. Only works for a CoinManagement with a TreasuryCap.

public fun add_distributor<T>(self: &mut coin_management::CoinManagement<T>, distributor: address)
Implementation
public fun add_distributor<T>(
    self: &mut CoinManagement<T>,
    distributor: address,
) {
    assert!(has_capability(self), EDistributorNeedsTreasuryCap);
    self.distributor.fill(distributor);
}

Function add_operator

Adds the distributor address to the CoinManagement. Only works for a CoinManagement with a TreasuryCap.

public fun add_operator<T>(self: &mut coin_management::CoinManagement<T>, operator: address)
Implementation
public fun add_operator<T>(self: &mut CoinManagement<T>, operator: address) {
    self.operator.fill(operator);
}

Function set_flow_limit

Adds a rate limit to the CoinManagement. Note that this rate limit will be calculated for the remote decimals of the token, not for the native decimals. To be used by the designated operator of the contract.

public fun set_flow_limit<T>(self: &mut coin_management::CoinManagement<T>, channel: &channel::Channel, flow_limit: u64)
Implementation
public fun set_flow_limit<T>(
    self: &mut CoinManagement<T>,
    channel: &Channel,
    flow_limit: u64,
) {
    assert!(self.operator.contains(&channel.to_address()), ENotOperator);
    self.flow_limit.set_flow_limit(flow_limit);
}

Function take_balance

Takes the given amount of Coins from user. Returns the amount that the ITS is supposed to give on other chains.

public(friend) fun take_balance<T>(self: &mut coin_management::CoinManagement<T>, to_take: balance::Balance<T>, clock: &clock::Clock): u256
Implementation
public(package) fun take_balance<T>(
    self: &mut CoinManagement<T>,
    to_take: Balance<T>,
    clock: &Clock,
): u256 {
    self.flow_limit.add_flow_out(to_take.value(), clock);
    let amount = (to_take.value() as u256) * self.scaling;
    if (has_capability(self)) {
        self.burn(to_take);
    } else {
        self.balance.borrow_mut().join(to_take);
    };
    amount
}

Function give_coin

Withdraws or mints the given amount of coins. Any leftover amount from previous transfers is added to the coin here.

public(friend) fun give_coin<T>(self: &mut coin_management::CoinManagement<T>, amount: u256, clock: &clock::Clock, ctx: &mut tx_context::TxContext): coin::Coin<T>
Implementation
public(package) fun give_coin<T>(
    self: &mut CoinManagement<T>,
    mut amount: u256,
    clock: &Clock,
    ctx: &mut TxContext,
): Coin<T> {
    amount = amount + self.dust;
    self.dust = amount % self.scaling;
    let sui_amount = (amount / self.scaling as u64);
    self.flow_limit.add_flow_out(sui_amount, clock);
    if (has_capability(self)) {
        self.mint(sui_amount, ctx)
    } else {
        coin::take(self.balance.borrow_mut(), sui_amount, ctx)
    }
}

Function set_scaling

public(friend) fun set_scaling<T>(self: &mut coin_management::CoinManagement<T>, scaling: u256)
Implementation
public(package) fun set_scaling<T>(
    self: &mut CoinManagement<T>,
    scaling: u256,
) {
    self.scaling = scaling;
}

Function mint

public(friend) fun mint<T>(self: &mut coin_management::CoinManagement<T>, amount: u64, ctx: &mut tx_context::TxContext): coin::Coin<T>
Implementation
public(package) fun mint<T>(
    self: &mut CoinManagement<T>,
    amount: u64,
    ctx: &mut TxContext,
): Coin<T> {
    self.treasury_cap.borrow_mut().mint(amount, ctx)
}

Function burn

public(friend) fun burn<T>(self: &mut coin_management::CoinManagement<T>, balance: balance::Balance<T>)
Implementation
public(package) fun burn<T>(self: &mut CoinManagement<T>, balance: Balance<T>) {
    self.treasury_cap.borrow_mut().supply_mut().decrease_supply(balance);
}

Function is_distributor

Checks if the given address is a distributor.

public fun is_distributor<T>(self: &coin_management::CoinManagement<T>, distributor: address): bool
Implementation
public fun is_distributor<T>(
    self: &CoinManagement<T>,
    distributor: address,
): bool {
    &distributor == self.distributor.borrow()
}

Function has_capability

Returns true if the coin management has a TreasuryCap.

public fun has_capability<T>(self: &coin_management::CoinManagement<T>): bool
Implementation
public fun has_capability<T>(self: &CoinManagement<T>): bool {
    self.treasury_cap.is_some()
}