dispatchable_fungible_asset - [testnet]
Esta página aún no está disponible en tu idioma.
This defines the fungible asset module that can issue fungible asset of any Metadata
object. The
metadata object can be any object that equipped with Metadata
resource.
The dispatchable_fungible_asset wraps the existing fungible_asset module and adds the ability for token issuer to customize the logic for withdraw and deposit operations. For example:
- Deflation token: a fixed percentage of token will be destructed upon transfer.
- Transfer allowlist: token can only be transfered to addresses in the allow list.
- Predicated transfer: transfer can only happen when some certain predicate has been met.
- Loyalty token: a fixed loyalty will be paid to a designated address when a fungible asset transfer happens
The api listed here intended to be an in-place replacement for defi applications that uses fungible_asset api directly and is safe for non-dispatchable (aka vanilla) fungible assets as well.
See AIP-73 for further discussion
use 0x1::error;use 0x1::features;use 0x1::function_info;use 0x1::fungible_asset;use 0x1::object;use 0x1::option;
Constants
Feature is not activated yet on the network.
const ENOT_ACTIVATED: u64 = 3;
Recipient is not getting the guaranteed value;
const EAMOUNT_MISMATCH: u64 = 2;
Dispatch target is not loaded.
const ENOT_LOADED: u64 = 4;
TransferRefStore doesn’t exist on the fungible asset type.
const ESTORE_NOT_FOUND: u64 = 1;
Resources
TransferRefStore
#[resource_group_member(#[group = 0x1::object::ObjectGroup])]struct TransferRefStore has key
Fields
-
transfer_ref: fungible_asset::TransferRef
Functions
register_dispatch_functions
public fun register_dispatch_functions(constructor_ref: &object::ConstructorRef, withdraw_function: option::Option<function_info::FunctionInfo>, deposit_function: option::Option<function_info::FunctionInfo>, derived_balance_function: option::Option<function_info::FunctionInfo>)
Implementation
public fun register_dispatch_functions( constructor_ref: &ConstructorRef, withdraw_function: Option<FunctionInfo>, deposit_function: Option<FunctionInfo>, derived_balance_function: Option<FunctionInfo>,) { fungible_asset::register_dispatch_functions( constructor_ref, withdraw_function, deposit_function, derived_balance_function, ); let store_obj = &object::generate_signer(constructor_ref); move_to<TransferRefStore>( store_obj, TransferRefStore { transfer_ref: fungible_asset::generate_transfer_ref(constructor_ref), } );}
register_derive_supply_dispatch_function
public fun register_derive_supply_dispatch_function(constructor_ref: &object::ConstructorRef, dispatch_function: option::Option<function_info::FunctionInfo>)
Implementation
public fun register_derive_supply_dispatch_function( constructor_ref: &ConstructorRef, dispatch_function: Option<FunctionInfo>) { fungible_asset::register_derive_supply_dispatch_function( constructor_ref, dispatch_function );}
withdraw
Withdraw amount
of the fungible asset from store
by the owner.
The semantics of deposit will be governed by the function specified in DispatchFunctionStore.
public fun withdraw<T: key>(owner: &signer, store: object::Object<T>, amount: u64): fungible_asset::FungibleAsset
Implementation
public fun withdraw<T: key>( owner: &signer, store: Object<T>, amount: u64,): FungibleAsset acquires TransferRefStore { fungible_asset::withdraw_sanity_check(owner, store, false); fungible_asset::withdraw_permission_check(owner, store, amount); let func_opt = fungible_asset::withdraw_dispatch_function(store); if (option::is_some(&func_opt)) { assert!( features::dispatchable_fungible_asset_enabled(), error::aborted(ENOT_ACTIVATED) ); let func = option::borrow(&func_opt); function_info::load_module_from_function(func); let fa = dispatchable_withdraw( store, amount, borrow_transfer_ref(store), func, ); fa } else { fungible_asset::unchecked_withdraw(object::object_address(&store), amount) }}
deposit
Deposit amount
of the fungible asset to store
.
The semantics of deposit will be governed by the function specified in DispatchFunctionStore.
public fun deposit<T: key>(store: object::Object<T>, fa: fungible_asset::FungibleAsset)
Implementation
public fun deposit<T: key>(store: Object<T>, fa: FungibleAsset) acquires TransferRefStore { fungible_asset::deposit_sanity_check(store, false); let func_opt = fungible_asset::deposit_dispatch_function(store); if (option::is_some(&func_opt)) { assert!( features::dispatchable_fungible_asset_enabled(), error::aborted(ENOT_ACTIVATED) ); let func = option::borrow(&func_opt); function_info::load_module_from_function(func); dispatchable_deposit( store, fa, borrow_transfer_ref(store), func ) } else { fungible_asset::unchecked_deposit(object::object_address(&store), fa) }}
transfer
Transfer an amount
of fungible asset from from_store
, which should be owned by sender
, to receiver
.
Note: it does not move the underlying object.
public entry fun transfer<T: key>(sender: &signer, from: object::Object<T>, to: object::Object<T>, amount: u64)
Implementation
public entry fun transfer<T: key>( sender: &signer, from: Object<T>, to: Object<T>, amount: u64,) acquires TransferRefStore { let fa = withdraw(sender, from, amount); deposit(to, fa);}
transfer_assert_minimum_deposit
Transfer an amount
of fungible asset from from_store
, which should be owned by sender
, to receiver
.
The recipient is guranteed to receive asset greater than the expected amount.
Note: it does not move the underlying object.
public entry fun transfer_assert_minimum_deposit<T: key>(sender: &signer, from: object::Object<T>, to: object::Object<T>, amount: u64, expected: u64)
Implementation
public entry fun transfer_assert_minimum_deposit<T: key>( sender: &signer, from: Object<T>, to: Object<T>, amount: u64, expected: u64) acquires TransferRefStore { let start = fungible_asset::balance(to); let fa = withdraw(sender, from, amount); deposit(to, fa); let end = fungible_asset::balance(to); assert!(end - start >= expected, error::aborted(EAMOUNT_MISMATCH));}
derived_balance
Get the derived value of store using the overloaded hook.
The semantics of value will be governed by the function specified in DispatchFunctionStore.
#[view]public fun derived_balance<T: key>(store: object::Object<T>): u64
Implementation
public fun derived_balance<T: key>(store: Object<T>): u64 { let func_opt = fungible_asset::derived_balance_dispatch_function(store); if (option::is_some(&func_opt)) { assert!( features::dispatchable_fungible_asset_enabled(), error::aborted(ENOT_ACTIVATED) ); let func = option::borrow(&func_opt); function_info::load_module_from_function(func); dispatchable_derived_balance(store, func) } else { fungible_asset::balance(store) }}
is_derived_balance_at_least
Whether the derived value of store using the overloaded hook is at least amount
The semantics of value will be governed by the function specified in DispatchFunctionStore.
#[view]public fun is_derived_balance_at_least<T: key>(store: object::Object<T>, amount: u64): bool
Implementation
public fun is_derived_balance_at_least<T: key>(store: Object<T>, amount: u64): bool { let func_opt = fungible_asset::derived_balance_dispatch_function(store); if (option::is_some(&func_opt)) { assert!( features::dispatchable_fungible_asset_enabled(), error::aborted(ENOT_ACTIVATED) ); let func = option::borrow(&func_opt); function_info::load_module_from_function(func); dispatchable_derived_balance(store, func) >= amount } else { fungible_asset::is_balance_at_least(store, amount) }}
derived_supply
Get the derived supply of the fungible asset using the overloaded hook.
The semantics of supply will be governed by the function specified in DeriveSupplyDispatch.
#[view]public fun derived_supply<T: key>(metadata: object::Object<T>): option::Option<u128>
Implementation
public fun derived_supply<T: key>(metadata: Object<T>): Option<u128> { let func_opt = fungible_asset::derived_supply_dispatch_function(metadata); if (option::is_some(&func_opt)) { assert!( features::dispatchable_fungible_asset_enabled(), error::aborted(ENOT_ACTIVATED) ); let func = option::borrow(&func_opt); function_info::load_module_from_function(func); dispatchable_derived_supply(metadata, func) } else { fungible_asset::supply(metadata) }}
borrow_transfer_ref
fun borrow_transfer_ref<T: key>(metadata: object::Object<T>): &fungible_asset::TransferRef
Implementation
inline fun borrow_transfer_ref<T: key>(metadata: Object<T>): &TransferRef acquires TransferRefStore { let metadata_addr = object::object_address( &fungible_asset::store_metadata(metadata) ); assert!( exists<TransferRefStore>(metadata_addr), error::not_found(ESTORE_NOT_FOUND) ); &borrow_global<TransferRefStore>(metadata_addr).transfer_ref}
dispatchable_withdraw
fun dispatchable_withdraw<T: key>(store: object::Object<T>, amount: u64, transfer_ref: &fungible_asset::TransferRef, function: &function_info::FunctionInfo): fungible_asset::FungibleAsset
Implementation
native fun dispatchable_withdraw<T: key>( store: Object<T>, amount: u64, transfer_ref: &TransferRef, function: &FunctionInfo,): FungibleAsset;
dispatchable_deposit
fun dispatchable_deposit<T: key>(store: object::Object<T>, fa: fungible_asset::FungibleAsset, transfer_ref: &fungible_asset::TransferRef, function: &function_info::FunctionInfo)
Implementation
native fun dispatchable_deposit<T: key>( store: Object<T>, fa: FungibleAsset, transfer_ref: &TransferRef, function: &FunctionInfo,);
dispatchable_derived_balance
fun dispatchable_derived_balance<T: key>(store: object::Object<T>, function: &function_info::FunctionInfo): u64
Implementation
native fun dispatchable_derived_balance<T: key>( store: Object<T>, function: &FunctionInfo,): u64;
dispatchable_derived_supply
fun dispatchable_derived_supply<T: key>(metadata: object::Object<T>, function: &function_info::FunctionInfo): option::Option<u128>
Implementation
native fun dispatchable_derived_supply<T: key>( metadata: Object<T>, function: &FunctionInfo,): Option<u128>;
Specification
pragma verify = false;
dispatchable_withdraw
fun dispatchable_withdraw<T: key>(store: object::Object<T>, amount: u64, transfer_ref: &fungible_asset::TransferRef, function: &function_info::FunctionInfo): fungible_asset::FungibleAsset
pragma opaque;
dispatchable_deposit
fun dispatchable_deposit<T: key>(store: object::Object<T>, fa: fungible_asset::FungibleAsset, transfer_ref: &fungible_asset::TransferRef, function: &function_info::FunctionInfo)
pragma opaque;
dispatchable_derived_balance
fun dispatchable_derived_balance<T: key>(store: object::Object<T>, function: &function_info::FunctionInfo): u64
pragma opaque;
dispatchable_derived_supply
fun dispatchable_derived_supply<T: key>(metadata: object::Object<T>, function: &function_info::FunctionInfo): option::Option<u128>
pragma opaque;