overloadable_fungible_asset - [devnet]
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 overloadable_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
See AIP-73 for further discussion
use 0x1::error;use 0x1::function_info;use 0x1::fungible_asset;use 0x1::object;use 0x1::signer;use 0x1::string;
Constants
Trying to register overload functions to fungible asset that has already been initialized with custom transfer function.
const EALREADY_REGISTERED: u64 = 5;
Fungibility is only available for non-deletable objects.
const EOBJECT_IS_DELETABLE: u64 = 18;
Recipient is not getting the guaranteed value;
const EAMOUNT_MISMATCH: u64 = 4;
Provided deposit function type doesn’t meet the signature requirement.
const EDEPOSIT_FUNCTION_SIGNATURE_MISMATCH: u64 = 2;
Calling overloadable api on non-overloadable fungible asset store.
const EFUNCTION_STORE_NOT_FOUND: u64 = 3;
Provided withdraw function type doesn’t meet the signature requirement.
const EWITHDRAW_FUNCTION_SIGNATURE_MISMATCH: u64 = 1;
Resources
OverloadFunctionStore
#[resource_group_member(#[group = 0x1::object::ObjectGroup])]struct OverloadFunctionStore has key
Fields
-
withdraw_function: function_info::FunctionInfo
-
deposit_function: function_info::FunctionInfo
-
transfer_ref: fungible_asset::TransferRef
Functions
register_overload_functions
Create a fungible asset store whose transfer rule would be overloaded by the provided function.
public fun register_overload_functions(constructor_ref: &object::ConstructorRef, withdraw_function: function_info::FunctionInfo, deposit_function: function_info::FunctionInfo)
Implementation
public fun register_overload_functions( constructor_ref: &ConstructorRef, withdraw_function: FunctionInfo, deposit_function: FunctionInfo,) { let dispatcher_withdraw_function_info = function_info::new_function_info( @aptos_framework, string::utf8(b"overloadable_fungible_asset"), string::utf8(b"dispatchable_withdraw"), ); // Verify that caller type matches callee type so wrongly typed function cannot be registered. assert!(function_info::check_dispatch_type_compatibility( &dispatcher_withdraw_function_info, &withdraw_function ), error::invalid_argument(EWITHDRAW_FUNCTION_SIGNATURE_MISMATCH));
let dispatcher_deposit_function_info = function_info::new_function_info( @aptos_framework, string::utf8(b"overloadable_fungible_asset"), string::utf8(b"dispatchable_deposit"), ); // Verify that caller type matches callee type so wrongly typed function cannot be registered. assert!(function_info::check_dispatch_type_compatibility( &dispatcher_deposit_function_info, &deposit_function ), error::invalid_argument(EDEPOSIT_FUNCTION_SIGNATURE_MISMATCH));
assert!(!object::can_generate_delete_ref(constructor_ref), error::invalid_argument(EOBJECT_IS_DELETABLE)); assert!(!exists<OverloadFunctionStore>(object::address_from_constructor_ref(constructor_ref)), error::already_exists(EALREADY_REGISTERED));
// Freeze the FungibleStore to force usign the new overloaded api. let extend_ref = object::generate_extend_ref(constructor_ref); fungible_asset::set_global_frozen_flag(&extend_ref, true);
let store_obj = &object::generate_signer(constructor_ref);
// Store the overload function hook. move_to<OverloadFunctionStore>(store_obj, OverloadFunctionStore { withdraw_function, deposit_function, transfer_ref: fungible_asset::generate_transfer_ref(constructor_ref), });}
withdraw
Withdraw amount
of the fungible asset from store
by the owner.
The semantics of deposit will be governed by the function specified in OverloadFunctionStore.
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 OverloadFunctionStore { let metadata_addr = object::object_address(&fungible_asset::store_metadata(store)); let owner_address = signer::address_of(owner); assert!(exists<OverloadFunctionStore>(metadata_addr), error::not_found(EFUNCTION_STORE_NOT_FOUND)); let overloadable_store = borrow_global<OverloadFunctionStore>(metadata_addr); dispatchable_withdraw( owner_address, store, amount, &overloadable_store.transfer_ref, &overloadable_store.withdraw_function, )}
deposit
Deposit amount
of the fungible asset to store
.
The semantics of deposit will be governed by the function specified in OverloadFunctionStore.
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 OverloadFunctionStore { let metadata_addr = object::object_address(&fungible_asset::store_metadata(store)); assert!(exists<OverloadFunctionStore>(metadata_addr), error::not_found(EFUNCTION_STORE_NOT_FOUND)); let overloadable_store = borrow_global<OverloadFunctionStore>(metadata_addr); dispatchable_deposit( store, fa, &overloadable_store.transfer_ref, &overloadable_store.deposit_function, );}
transfer_fixed_send
A transfer with a fixed amount debited from the sender
public fun transfer_fixed_send<T: key>(_sender: &signer, from: object::Object<T>, to: object::Object<T>, send_amount: u64)
Implementation
public fun transfer_fixed_send<T: key>( _sender: &signer, from: Object<T>, to: Object<T>, send_amount: u64,) acquires OverloadFunctionStore { let metadata_addr = object::object_address(&fungible_asset::store_metadata(from)); assert!(exists<OverloadFunctionStore>(metadata_addr), error::not_found(EFUNCTION_STORE_NOT_FOUND)); let overloadable_store = borrow_global<OverloadFunctionStore>(metadata_addr); let fa = fungible_asset::withdraw_with_ref(&overloadable_store.transfer_ref, from, send_amount); deposit(to, fa);}
transfer_fixed_receive
A transfer with a fixed amount credited to the recipient
public fun transfer_fixed_receive<T: key>(sender: &signer, from: object::Object<T>, to: object::Object<T>, receive_amount: u64)
Implementation
public fun transfer_fixed_receive<T: key>( sender: &signer, from: Object<T>, to: Object<T>, receive_amount: u64,) acquires OverloadFunctionStore { let fa = withdraw(sender, from, receive_amount); let metadata_addr = object::object_address(&fungible_asset::store_metadata(from)); let overloadable_store = borrow_global<OverloadFunctionStore>(metadata_addr); assert!(fungible_asset::amount(&fa) == receive_amount, error::aborted(EAMOUNT_MISMATCH)); fungible_asset::deposit_with_ref(&overloadable_store.transfer_ref, to, fa);}
dispatchable_withdraw
fun dispatchable_withdraw<T: key>(owner: address, 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>( owner: address, 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,);