From cd8b0918c1bc2ab56285af45bf02f0fa69e6f5d4 Mon Sep 17 00:00:00 2001 From: runtianz Date: Wed, 9 Apr 2025 10:03:36 -0700 Subject: [PATCH] Removing checks for DFA --- .../doc/dispatchable_fungible_asset.md | 3 - .../sources/dispatchable_fungible_asset.move | 3 - .../aptos-framework/tests/clamped_token.move | 92 +++++++++++++++++++ .../tests/clamped_token_tests.move | 55 +++++++++++ .../tests/nil_op_token_tests.move | 2 - .../aptos-framework/tests/ten_x_token.move | 35 ++++++- 6 files changed, 179 insertions(+), 11 deletions(-) create mode 100644 aptos-move/framework/aptos-framework/tests/clamped_token.move create mode 100644 aptos-move/framework/aptos-framework/tests/clamped_token_tests.move diff --git a/aptos-move/framework/aptos-framework/doc/dispatchable_fungible_asset.md b/aptos-move/framework/aptos-framework/doc/dispatchable_fungible_asset.md index bfe682fe63ce4..7dc2ce54d7ac3 100644 --- a/aptos-move/framework/aptos-framework/doc/dispatchable_fungible_asset.md +++ b/aptos-move/framework/aptos-framework/doc/dispatchable_fungible_asset.md @@ -228,7 +228,6 @@ The semantics of deposit will be governed by the function specified in DispatchF features::dispatchable_fungible_asset_enabled(), error::aborted(ENOT_ACTIVATED) ); - let start_balance = fungible_asset::balance(store); let func = option::borrow(&func_opt); function_info::load_module_from_function(func); let fa = dispatchable_withdraw( @@ -237,8 +236,6 @@ The semantics of deposit will be governed by the function specified in DispatchF borrow_transfer_ref(store), func, ); - let end_balance = fungible_asset::balance(store); - assert!(amount <= start_balance - end_balance, error::aborted(EAMOUNT_MISMATCH)); fa } else { fungible_asset::unchecked_withdraw(object::object_address(&store), amount) diff --git a/aptos-move/framework/aptos-framework/sources/dispatchable_fungible_asset.move b/aptos-move/framework/aptos-framework/sources/dispatchable_fungible_asset.move index 40087d979bf76..293b4e069efb5 100644 --- a/aptos-move/framework/aptos-framework/sources/dispatchable_fungible_asset.move +++ b/aptos-move/framework/aptos-framework/sources/dispatchable_fungible_asset.move @@ -84,7 +84,6 @@ module aptos_framework::dispatchable_fungible_asset { features::dispatchable_fungible_asset_enabled(), error::aborted(ENOT_ACTIVATED) ); - let start_balance = fungible_asset::balance(store); let func = option::borrow(&func_opt); function_info::load_module_from_function(func); let fa = dispatchable_withdraw( @@ -93,8 +92,6 @@ module aptos_framework::dispatchable_fungible_asset { borrow_transfer_ref(store), func, ); - let end_balance = fungible_asset::balance(store); - assert!(amount <= start_balance - end_balance, error::aborted(EAMOUNT_MISMATCH)); fa } else { fungible_asset::unchecked_withdraw(object::object_address(&store), amount) diff --git a/aptos-move/framework/aptos-framework/tests/clamped_token.move b/aptos-move/framework/aptos-framework/tests/clamped_token.move new file mode 100644 index 0000000000000..d5994bb298c07 --- /dev/null +++ b/aptos-move/framework/aptos-framework/tests/clamped_token.move @@ -0,0 +1,92 @@ +#[test_only] +module 0xcafe::clamped_token { + // Create a token with max amount one can withdraw on each withdraw call. + + use aptos_framework::fungible_asset::{Self, FungibleAsset, RawBalanceRef, RawSupplyRef, TransferRef}; + use aptos_framework::dispatchable_fungible_asset; + use aptos_framework::object::{ConstructorRef, Object}; + use aptos_framework::function_info; + + use std::option; + use std::option::Option; + use std::signer; + use std::string; + + struct BalanceStore has key { + balance_ref: RawBalanceRef, + supply_ref: RawSupplyRef, + } + + public fun initialize(account: &signer, constructor_ref: &ConstructorRef) { + assert!(signer::address_of(account) == @0xcafe, 1); + let balance_ref = fungible_asset::generate_raw_balance_ref(constructor_ref); + let supply_ref = fungible_asset::generate_raw_supply_ref(constructor_ref); + move_to(account, BalanceStore { balance_ref, supply_ref }); + + let balance_value = function_info::new_function_info( + account, + string::utf8(b"clamped_token"), + string::utf8(b"derived_balance"), + ); + let supply_value = function_info::new_function_info( + account, + string::utf8(b"clamped_token"), + string::utf8(b"derived_supply"), + ); + + let withdraw = function_info::new_function_info( + account, + string::utf8(b"clamped_token"), + string::utf8(b"withdraw"), + ); + + let deposit = function_info::new_function_info( + account, + string::utf8(b"clamped_token"), + string::utf8(b"deposit"), + ); + + dispatchable_fungible_asset::register_dispatch_functions( + constructor_ref, + option::some(withdraw), + option::some(deposit), + option::some(balance_value) + ); + dispatchable_fungible_asset::register_derive_supply_dispatch_function( + constructor_ref, + option::some(supply_value) + ); + } + + public fun derived_balance(store: Object): u64 acquires BalanceStore { + fungible_asset::balance_with_ref( + &borrow_global(@0xcafe).balance_ref, + store + ) + } + + public fun derived_supply(metadata: Object): Option acquires BalanceStore { + option::some(option::extract(&mut fungible_asset::supply_with_ref( + &borrow_global(@0xcafe).supply_ref, + metadata + ))) + } + + public fun withdraw( + store: Object, + amount: u64, + transfer_ref: &TransferRef, + ): FungibleAsset { + // Clamp the max amount of asset to withdraw: at most 10 can be withdrawn each call. + assert!(amount <= 10, 0); + fungible_asset::withdraw_with_ref(transfer_ref, store, amount) + } + + public fun deposit( + store: Object, + fa: FungibleAsset, + transfer_ref: &TransferRef, + ) { + fungible_asset::deposit_with_ref(transfer_ref, store, fa) + } +} diff --git a/aptos-move/framework/aptos-framework/tests/clamped_token_tests.move b/aptos-move/framework/aptos-framework/tests/clamped_token_tests.move new file mode 100644 index 0000000000000..ae6daee527137 --- /dev/null +++ b/aptos-move/framework/aptos-framework/tests/clamped_token_tests.move @@ -0,0 +1,55 @@ +#[test_only] +module aptos_framework::clamped_token_tests { + use aptos_framework::fungible_asset::{Self, Metadata, TestToken}; + use aptos_framework::dispatchable_fungible_asset; + use aptos_framework::object; + use 0xcafe::clamped_token; + use std::option; + + #[test(creator = @0xcafe)] + fun test_clamped( + creator: &signer, + ) { + let (creator_ref, token_object) = fungible_asset::create_test_token(creator); + let (mint, _, _, _) = fungible_asset::init_test_metadata(&creator_ref); + let metadata = object::convert(token_object); + + let creator_store = fungible_asset::create_test_store(creator, metadata); + + clamped_token::initialize(creator, &creator_ref); + + assert!(dispatchable_fungible_asset::derived_supply(metadata) == option::some(0), 2); + // Mint + let fa = fungible_asset::mint(&mint, 100); + dispatchable_fungible_asset::deposit(creator_store, fa); + + assert!(dispatchable_fungible_asset::derived_balance(creator_store) == 100, 4); + assert!(dispatchable_fungible_asset::derived_supply(metadata) == option::some(100), 5); + + let fa = dispatchable_fungible_asset::withdraw(creator, creator_store, 5); + dispatchable_fungible_asset::deposit(creator_store, fa); + } + + #[test(creator = @0xcafe)] + #[expected_failure(abort_code = 0, location = 0xcafe::clamped_token)] + fun test_clamped_aborted( + creator: &signer, + ) { + let (creator_ref, token_object) = fungible_asset::create_test_token(creator); + let (mint, _, _, _) = fungible_asset::init_test_metadata(&creator_ref); + let metadata = object::convert(token_object); + + let creator_store = fungible_asset::create_test_store(creator, metadata); + + clamped_token::initialize(creator, &creator_ref); + + assert!(dispatchable_fungible_asset::derived_supply(metadata) == option::some(0), 2); + // Mint + let fa = fungible_asset::mint(&mint, 100); + dispatchable_fungible_asset::deposit(creator_store, fa); + + // Failed to withdraw as it exceeds the withdraw limit. + let fa = dispatchable_fungible_asset::withdraw(creator, creator_store, 20); + dispatchable_fungible_asset::deposit(creator_store, fa); + } +} diff --git a/aptos-move/framework/aptos-framework/tests/nil_op_token_tests.move b/aptos-move/framework/aptos-framework/tests/nil_op_token_tests.move index d4bf6abbdba52..985fab258bc71 100644 --- a/aptos-move/framework/aptos-framework/tests/nil_op_token_tests.move +++ b/aptos-move/framework/aptos-framework/tests/nil_op_token_tests.move @@ -7,7 +7,6 @@ module aptos_framework::nil_op_token_tests { use std::option; #[test(creator = @0xcafe)] - #[expected_failure(abort_code=0x70002, location=aptos_framework::dispatchable_fungible_asset)] fun test_nil_op_token( creator: &signer, ) { @@ -26,7 +25,6 @@ module aptos_framework::nil_op_token_tests { // Deposit will cause an re-entrant call into dispatchable_fungible_asset dispatchable_fungible_asset::deposit(creator_store, fa); - // Withdraw will fail because it's not drawing the basic amount. let fa = dispatchable_fungible_asset::withdraw(creator, creator_store, 10); dispatchable_fungible_asset::deposit(creator_store, fa); } diff --git a/aptos-move/framework/aptos-framework/tests/ten_x_token.move b/aptos-move/framework/aptos-framework/tests/ten_x_token.move index a1ac6406265d7..42799fdfa3efb 100644 --- a/aptos-move/framework/aptos-framework/tests/ten_x_token.move +++ b/aptos-move/framework/aptos-framework/tests/ten_x_token.move @@ -1,6 +1,6 @@ #[test_only] module 0xcafe::ten_x_token { - use aptos_framework::fungible_asset::{Self, RawBalanceRef, RawSupplyRef}; + use aptos_framework::fungible_asset::{Self, FungibleAsset, RawBalanceRef, RawSupplyRef, TransferRef}; use aptos_framework::dispatchable_fungible_asset; use aptos_framework::object::{ConstructorRef, Object}; use aptos_framework::function_info; @@ -31,10 +31,23 @@ module 0xcafe::ten_x_token { string::utf8(b"ten_x_token"), string::utf8(b"derived_supply"), ); + + let withdraw = function_info::new_function_info( + account, + string::utf8(b"ten_x_token"), + string::utf8(b"withdraw"), + ); + + let deposit = function_info::new_function_info( + account, + string::utf8(b"ten_x_token"), + string::utf8(b"deposit"), + ); + dispatchable_fungible_asset::register_dispatch_functions( constructor_ref, - option::none(), - option::none(), + option::some(withdraw), + option::some(deposit), option::some(balance_value) ); dispatchable_fungible_asset::register_derive_supply_dispatch_function( @@ -58,4 +71,20 @@ module 0xcafe::ten_x_token { metadata )) * 10) } + + public fun withdraw( + store: Object, + amount: u64, + transfer_ref: &TransferRef, + ): FungibleAsset { + fungible_asset::withdraw_with_ref(transfer_ref, store, amount) + } + + public fun deposit( + store: Object, + fa: FungibleAsset, + transfer_ref: &TransferRef, + ) { + fungible_asset::deposit_with_ref(transfer_ref, store, fa) + } }