Regulated Coin
Sui provides a way to create a Coin with a global Denylist. This is useful for creating a regulated coin, where the issuer can restrict certain accounts from holding the coin. The denylist functionality is native to the network and maintains the fast path.
module examples::reg_coin {
use sui::coin;
/// The type identifier of coin. The coin will have a type
/// tag of kind: `Coin<package_object::reg_coin::REG_COIN>`
/// Make sure that the name of the type matches the module's name.
public struct REG_COIN has drop {}
/// Module initializer is called once on module publish. A treasury
/// cap is sent to the publisher, who then controls minting and burning
fun init(witness: REG_COIN, ctx: &mut TxContext) {
// Unlike regular currency, regulated currency uses a different method.
let (treasury, denycap, metadata) = coin::create_regulated_currency(
witness,
6, // decimals
b"REG", // symbol
b"My Coin", // name
b"Do good, and you're good", // description
option::none(), // icon url
ctx
);
// transfer the `TreasuryCap` to the sender, so they can mint and burn
transfer::public_transfer(treasury, ctx.sender());
// transfer the `DenyCap` to the sender, so they can freeze and
// unfreeze accounts from using the currency
transfer::public_transfer(denycap, ctx.sender());
// metadata is typically frozen after creation
transfer::public_freeze_object(metadata);
}
// === Entry Functions (can be replaced by direct calls in PTBs) ===
use sui::deny_list::DenyList;
use sui::coin::DenyCap;
/// Add an account to denylist preventing them from using the currency.
/// DenyList is a special shared object with reserved address `0x403`.
entry fun block_account(
deny_list: &mut DenyList,
deny_cap: &mut DenyCap<REG_COIN>,
account: address,
ctx: &mut TxContext
) {
coin::deny_list_add(deny_list, deny_cap, account, ctx);
}
/// Remove an account from denylist allowing them to use the currency.
/// DenyList is a special shared object with reserved address `0x403`.
entry fun unblock_account(
deny_list: &mut DenyList,
deny_cap: &mut DenyCap<REG_COIN>,
account: address,
ctx: &mut TxContext
) {
coin::deny_list_remove(deny_list, deny_cap, account, ctx);
}
}
Currently, the Denylist is only supported for the Coin type. In the future, it may be extended to some other system types.