From b53e82b731e011dcb710c59ba5e54e7177716253 Mon Sep 17 00:00:00 2001 From: alnoki <43892045+alnoki@users.noreply.github.com> Date: Mon, 11 Mar 2024 15:13:56 -0700 Subject: [PATCH 01/17] Update fee rate to hundredths of basis point --- src/move/econia/sources/core.move | 40 +++++++++++++++---------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/move/econia/sources/core.move b/src/move/econia/sources/core.move index e722e2f..7a0de94 100644 --- a/src/move/econia/sources/core.move +++ b/src/move/econia/sources/core.move @@ -22,8 +22,8 @@ module econia::core { const GENESIS_ORACLE_FEE: u64 = 0; const GENESIS_INTEGRATOR_WITHDRAWAL_FEE: u64 = 0; - const GENESIS_DEFAULT_POOL_FEE_RATE_BPS: u8 = 30; - const GENESIS_DEFAULT_TAKER_FEE_RATE_BPS: u8 = 0; + const GENESIS_DEFAULT_POOL_FEE_RATE: u16 = 3_000; + const GENESIS_DEFAULT_TAKER_FEE_RATE: u16 = 0; const GENESIS_DEFAULT_MAX_PRICE_SIG_FIGS: u8 = 4; const GENESIS_DEFAULT_EVICTION_TREE_HEIGHT: u8 = 5; const GENESIS_DEFAULT_EVICTION_PRICE_DIVISOR_ASK: u128 = 100_000_000_000_000_000_000; @@ -77,8 +77,8 @@ module econia::core { } struct MarketParameters has copy, drop, store { - pool_fee_rate_bps: u8, - taker_fee_rate_bps: u8, + pool_fee_rate: u16, + taker_fee_rate: u16, max_price_sig_figs: u8, eviction_tree_height: u8, eviction_price_divisor_ask: u128, @@ -307,8 +307,8 @@ module econia::core { public entry fun update_market_parameters( econia: &signer, market_id_option: vector, - pool_fee_rate_bps_option: vector, - taker_fee_rate_bps_option: vector, + pool_fee_rate_option: vector, + taker_fee_rate_option: vector, max_price_sig_figs_option: vector, eviction_tree_height_option: vector, eviction_price_divisor_ask_option: vector, @@ -335,12 +335,12 @@ module econia::core { ) }; set_value_via_option_vector( - &mut market_parameters_ref_mut.pool_fee_rate_bps, - &pool_fee_rate_bps_option, + &mut market_parameters_ref_mut.pool_fee_rate, + &pool_fee_rate_option, ); set_value_via_option_vector( - &mut market_parameters_ref_mut.taker_fee_rate_bps, - &taker_fee_rate_bps_option, + &mut market_parameters_ref_mut.taker_fee_rate, + &taker_fee_rate_option, ); set_value_via_option_vector( &mut market_parameters_ref_mut.max_price_sig_figs, @@ -599,8 +599,8 @@ module econia::core { integrator_withdrawal_fee: GENESIS_INTEGRATOR_WITHDRAWAL_FEE, }, default_market_parameters: MarketParameters { - pool_fee_rate_bps: GENESIS_DEFAULT_POOL_FEE_RATE_BPS, - taker_fee_rate_bps: GENESIS_DEFAULT_TAKER_FEE_RATE_BPS, + pool_fee_rate: GENESIS_DEFAULT_POOL_FEE_RATE, + taker_fee_rate: GENESIS_DEFAULT_TAKER_FEE_RATE, max_price_sig_figs: GENESIS_DEFAULT_MAX_PRICE_SIG_FIGS, eviction_tree_height: GENESIS_DEFAULT_EVICTION_TREE_HEIGHT, eviction_price_divisor_ask: GENESIS_DEFAULT_EVICTION_PRICE_DIVISOR_ASK, @@ -698,8 +698,8 @@ module econia::core { #[test_only] public fun assert_market_parameters( market_parameters: MarketParameters, - pool_fee_rate_bps: u8, - taker_fee_rate_bps: u8, + pool_fee_rate: u16, + taker_fee_rate: u16, max_price_sig_figs: u8, eviction_tree_height: u8, eviction_price_divisor_ask: u128, @@ -708,8 +708,8 @@ module econia::core { inner_node_order: u8, leaf_node_order: u8, ) { - assert!(market_parameters.pool_fee_rate_bps == pool_fee_rate_bps, 0); - assert!(market_parameters.taker_fee_rate_bps == taker_fee_rate_bps, 0); + assert!(market_parameters.pool_fee_rate == pool_fee_rate, 0); + assert!(market_parameters.taker_fee_rate == taker_fee_rate, 0); assert!(market_parameters.max_price_sig_figs == max_price_sig_figs, 0); assert!(market_parameters.eviction_tree_height == eviction_tree_height, 0); assert!(market_parameters.eviction_price_divisor_ask == eviction_price_divisor_ask, 0); @@ -1135,8 +1135,8 @@ module econia::core { ); assert_market_parameters( registry_ref.default_market_parameters, - GENESIS_DEFAULT_POOL_FEE_RATE_BPS, - GENESIS_DEFAULT_TAKER_FEE_RATE_BPS, + GENESIS_DEFAULT_POOL_FEE_RATE, + GENESIS_DEFAULT_TAKER_FEE_RATE, GENESIS_DEFAULT_MAX_PRICE_SIG_FIGS, GENESIS_DEFAULT_EVICTION_TREE_HEIGHT, GENESIS_DEFAULT_EVICTION_PRICE_DIVISOR_ASK, @@ -1379,8 +1379,8 @@ module econia::core { ); assert_market_parameters( borrow_registry().default_market_parameters, - GENESIS_DEFAULT_POOL_FEE_RATE_BPS, - GENESIS_DEFAULT_TAKER_FEE_RATE_BPS, + GENESIS_DEFAULT_POOL_FEE_RATE, + GENESIS_DEFAULT_TAKER_FEE_RATE, GENESIS_DEFAULT_MAX_PRICE_SIG_FIGS, 5, 6, From c67d80d23bb2c6b9b277ba85dea480cbfda40cc4 Mon Sep 17 00:00:00 2001 From: alnoki <43892045+alnoki@users.noreply.github.com> Date: Mon, 11 Mar 2024 15:27:56 -0700 Subject: [PATCH 02/17] Fix tests broken by FA migration PR https://github.com/aptos-labs/aptos-core/pull/11224 --- src/move/econia/sources/core.move | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/move/econia/sources/core.move b/src/move/econia/sources/core.move index 7a0de94..62b3749 100644 --- a/src/move/econia/sources/core.move +++ b/src/move/econia/sources/core.move @@ -16,8 +16,10 @@ module econia::core { use aptos_framework::aptos_coin; #[test_only] use econia::test_assets; + #[test_only] + use std::features; - const GENESIS_UTILITY_ASSET_METADATA_ADDRESS: address = @aptos_framework; + const GENESIS_UTILITY_ASSET_METADATA_ADDRESS: address = @aptos_fungible_asset; const GENESIS_MARKET_REGISTRATION_FEE: u64 = 100_000_000; const GENESIS_ORACLE_FEE: u64 = 0; const GENESIS_INTEGRATOR_WITHDRAWAL_FEE: u64 = 0; @@ -852,6 +854,8 @@ module econia::core { #[test_only] public fun ensure_module_initialized_for_test() { + let feature = features::get_coin_to_fungible_asset_migration_feature(); + features::change_feature_flags(&get_signer(@std), vector[feature], vector[]); aptos_coin::ensure_initialized_with_fa_metadata_for_test(); if (!exists(@econia)) init_module(&get_signer(@econia)); } From afb112144b5fc4aa7c59fe81d1bfc259e1ddf335 Mon Sep 17 00:00:00 2001 From: alnoki <43892045+alnoki@users.noreply.github.com> Date: Mon, 11 Mar 2024 15:29:42 -0700 Subject: [PATCH 03/17] Rename taker fee to protocol fee --- src/move/econia/sources/core.move | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/move/econia/sources/core.move b/src/move/econia/sources/core.move index 62b3749..457eae0 100644 --- a/src/move/econia/sources/core.move +++ b/src/move/econia/sources/core.move @@ -25,7 +25,7 @@ module econia::core { const GENESIS_INTEGRATOR_WITHDRAWAL_FEE: u64 = 0; const GENESIS_DEFAULT_POOL_FEE_RATE: u16 = 3_000; - const GENESIS_DEFAULT_TAKER_FEE_RATE: u16 = 0; + const GENESIS_DEFAULT_PROTOCOL_FEE_RATE: u16 = 0; const GENESIS_DEFAULT_MAX_PRICE_SIG_FIGS: u8 = 4; const GENESIS_DEFAULT_EVICTION_TREE_HEIGHT: u8 = 5; const GENESIS_DEFAULT_EVICTION_PRICE_DIVISOR_ASK: u128 = 100_000_000_000_000_000_000; @@ -80,7 +80,7 @@ module econia::core { struct MarketParameters has copy, drop, store { pool_fee_rate: u16, - taker_fee_rate: u16, + protocol_fee_rate: u16, max_price_sig_figs: u8, eviction_tree_height: u8, eviction_price_divisor_ask: u128, @@ -310,7 +310,7 @@ module econia::core { econia: &signer, market_id_option: vector, pool_fee_rate_option: vector, - taker_fee_rate_option: vector, + protocol_fee_rate_option: vector, max_price_sig_figs_option: vector, eviction_tree_height_option: vector, eviction_price_divisor_ask_option: vector, @@ -341,8 +341,8 @@ module econia::core { &pool_fee_rate_option, ); set_value_via_option_vector( - &mut market_parameters_ref_mut.taker_fee_rate, - &taker_fee_rate_option, + &mut market_parameters_ref_mut.protocol_fee_rate, + &protocol_fee_rate_option, ); set_value_via_option_vector( &mut market_parameters_ref_mut.max_price_sig_figs, @@ -602,7 +602,7 @@ module econia::core { }, default_market_parameters: MarketParameters { pool_fee_rate: GENESIS_DEFAULT_POOL_FEE_RATE, - taker_fee_rate: GENESIS_DEFAULT_TAKER_FEE_RATE, + protocol_fee_rate: GENESIS_DEFAULT_PROTOCOL_FEE_RATE, max_price_sig_figs: GENESIS_DEFAULT_MAX_PRICE_SIG_FIGS, eviction_tree_height: GENESIS_DEFAULT_EVICTION_TREE_HEIGHT, eviction_price_divisor_ask: GENESIS_DEFAULT_EVICTION_PRICE_DIVISOR_ASK, @@ -701,7 +701,7 @@ module econia::core { public fun assert_market_parameters( market_parameters: MarketParameters, pool_fee_rate: u16, - taker_fee_rate: u16, + protocol_fee_rate: u16, max_price_sig_figs: u8, eviction_tree_height: u8, eviction_price_divisor_ask: u128, @@ -711,7 +711,7 @@ module econia::core { leaf_node_order: u8, ) { assert!(market_parameters.pool_fee_rate == pool_fee_rate, 0); - assert!(market_parameters.taker_fee_rate == taker_fee_rate, 0); + assert!(market_parameters.protocol_fee_rate == protocol_fee_rate, 0); assert!(market_parameters.max_price_sig_figs == max_price_sig_figs, 0); assert!(market_parameters.eviction_tree_height == eviction_tree_height, 0); assert!(market_parameters.eviction_price_divisor_ask == eviction_price_divisor_ask, 0); @@ -1140,7 +1140,7 @@ module econia::core { assert_market_parameters( registry_ref.default_market_parameters, GENESIS_DEFAULT_POOL_FEE_RATE, - GENESIS_DEFAULT_TAKER_FEE_RATE, + GENESIS_DEFAULT_PROTOCOL_FEE_RATE, GENESIS_DEFAULT_MAX_PRICE_SIG_FIGS, GENESIS_DEFAULT_EVICTION_TREE_HEIGHT, GENESIS_DEFAULT_EVICTION_PRICE_DIVISOR_ASK, @@ -1384,7 +1384,7 @@ module econia::core { assert_market_parameters( borrow_registry().default_market_parameters, GENESIS_DEFAULT_POOL_FEE_RATE, - GENESIS_DEFAULT_TAKER_FEE_RATE, + GENESIS_DEFAULT_PROTOCOL_FEE_RATE, GENESIS_DEFAULT_MAX_PRICE_SIG_FIGS, 5, 6, From 90d7667ff57aed7c4f3d5a8c684a5fe251e044f5 Mon Sep 17 00:00:00 2001 From: alnoki <43892045+alnoki@users.noreply.github.com> Date: Mon, 11 Mar 2024 16:41:24 -0700 Subject: [PATCH 04/17] Update resources for concurrent FA transfers --- src/move/econia/sources/core.move | 653 +++++------------------------- 1 file changed, 103 insertions(+), 550 deletions(-) diff --git a/src/move/econia/sources/core.move b/src/move/econia/sources/core.move index 457eae0..023486e 100644 --- a/src/move/econia/sources/core.move +++ b/src/move/econia/sources/core.move @@ -48,10 +48,10 @@ module econia::core { const E_MARKET_NOT_COLLATERALIZED_BASE: u64 = 5; /// Market is not fully collateralized with quote asset. const E_MARKET_NOT_COLLATERALIZED_QUOTE: u64 = 6; - /// Specified user does not own the given market account. - const E_DOES_NOT_OWN_MARKET_ACCOUNT: u64 = 7; - /// Market account does not exist at given address. - const E_NO_MARKET_ACCOUNT: u64 = 8; + /// Specified user does not own the given open orders resource. + const E_DOES_NOT_OWN_OPEN_ORDERS: u64 = 7; + /// Open orders resource does not exist at given address. + const E_NO_OPEN_ORDERS: u64 = 8; #[resource_group_member(group = ObjectGroup)] struct Market has key { @@ -60,15 +60,15 @@ module econia::core { trading_pair: TradingPair, market_parameters: MarketParameters, extend_ref: ExtendRef, - base_balances: MarketBalances, - quote_balances: MarketBalances, + base_balances: AssetBalances, + quote_balances: AssetBalances, } - struct MarketBalances has copy, drop, store { - market_account_deposits: u64, + struct AssetBalances has copy, drop, store { book_liquidity: u64, pool_liquidity: u64, - unclaimed_integrator_fees: u64, + unclaimed_pool_fees: u64, + unclaimed_protocol_fees: u64, } struct MarketMetadata has copy, drop, store { @@ -91,59 +91,24 @@ module econia::core { } #[resource_group_member(group = ObjectGroup)] - struct MarketAccount has key { + struct OpenOrders has key { market_id: u64, trading_pair: TradingPair, market_address: address, user: address, - market_account_address: address, - extend_ref: ExtendRef, - base_balances: MarketAccountBalances, - quote_balances: MarketAccountBalances, - } - - struct MarketAccountBalances has copy, drop, store { - available: u64, - total: u64, - } - - struct MarketAccountBalancesView has copy, drop, store { - base_balances: MarketAccountBalances, - quote_balances: MarketAccountBalances, + open_orders_address: address, } - struct MarketAccountMetadata has copy, drop, store { + struct OpenOrdersMetadata has copy, drop, store { market_id: u64, trading_pair: TradingPair, market_address: address, user: address, - market_account_address: address, - } - - struct MarketAccounts has key { - map: SmartTable, - } - - #[resource_group_member(group = ObjectGroup)] - struct IntegratorFeeStore has key { - market_id: u64, - trading_pair: TradingPair, - market_address: address, - integrator: address, - extend_ref: ExtendRef, - quote_available: u64, - } - - struct IntegratorFeeStoreMetadata has copy, drop, store { - market_id: u64, - trading_pair: TradingPair, - market_address: address, - integrator: address, - integrator_fee_store_address: address, + open_orders_address: address, } - struct IntegratorFeeStores has key { - map: SmartTable, + struct OpenOrdersByMarket has key { + map: SmartTable, } struct Null has drop, key, store {} @@ -200,11 +165,11 @@ module econia::core { let market_parameters = registry_ref_mut.default_market_parameters; let market_signer = object::generate_signer(&constructor_ref); let market_address = object::address_from_constructor_ref(&constructor_ref); - let no_balances = MarketBalances { - market_account_deposits: 0, + let no_balances = AssetBalances { book_liquidity: 0, pool_liquidity: 0, - unclaimed_integrator_fees: 0, + unclaimed_pool_fees: 0, + unclaimed_protocol_fees: 0, }; move_to(&market_signer, Market { market_id, @@ -225,83 +190,39 @@ module econia::core { table::add(trading_pair_market_ids_ref_mut, trading_pair, market_id); } - public entry fun ensure_market_account_registered( + public entry fun ensure_open_orders_registered( user: &signer, base_metadata: Object, quote_metadata: Object, - ) acquires MarketAccounts, Registry { + ) acquires OpenOrdersByMarket, Registry { let user_address = signer::address_of(user); - if (!exists(user_address)) { - move_to(user, MarketAccounts { map: smart_table::new() }); + if (!exists(user_address)) { + move_to(user, OpenOrdersByMarket { map: smart_table::new() }); }; - let market_accounts_map_ref_mut = &mut borrow_global_mut(user_address).map; + let open_orders_map_ref_mut = &mut borrow_global_mut(user_address).map; let trading_pair = TradingPair { base_metadata, quote_metadata }; - if (smart_table::contains(market_accounts_map_ref_mut, trading_pair)) return; + if (smart_table::contains(open_orders_map_ref_mut, trading_pair)) return; ensure_market_registered(user, base_metadata, quote_metadata); let (market_id, market_address) = get_market_id_and_address_for_registered_pair(trading_pair); - let (constructor_ref, extend_ref) = create_nontransferable_sticky_object(user_address); - let no_balances = MarketAccountBalances { available: 0, total: 0 }; - let market_account_address = object::address_from_constructor_ref(&constructor_ref); - move_to(&object::generate_signer(&constructor_ref), MarketAccount { + let (constructor_ref, _) = create_nontransferable_sticky_object(user_address); + let open_orders_address = object::address_from_constructor_ref(&constructor_ref); + move_to(&object::generate_signer(&constructor_ref), OpenOrders { market_id, trading_pair, market_address, user: user_address, - market_account_address, - extend_ref, - base_balances: no_balances, - quote_balances: no_balances, + open_orders_address, }); smart_table::add( - market_accounts_map_ref_mut, + open_orders_map_ref_mut, trading_pair, - MarketAccountMetadata { + OpenOrdersMetadata { market_id, trading_pair, market_address, user: user_address, - market_account_address, - } - ); - } - - public entry fun ensure_integrator_fee_store_registered( - integrator: &signer, - base_metadata: Object, - quote_metadata: Object, - ) acquires IntegratorFeeStores, Registry { - let integrator_address = signer::address_of(integrator); - if (!exists(integrator_address)) { - move_to(integrator, IntegratorFeeStores { map: smart_table::new() }); - }; - let integrator_fee_stores_map_ref_mut = - &mut borrow_global_mut(integrator_address).map; - let trading_pair = TradingPair { base_metadata, quote_metadata }; - if (smart_table::contains(integrator_fee_stores_map_ref_mut, trading_pair)) return; - ensure_market_registered(integrator, base_metadata, quote_metadata); - let (market_id, market_address) = - get_market_id_and_address_for_registered_pair(trading_pair); - let (constructor_ref, extend_ref) = - create_nontransferable_sticky_object(integrator_address); - move_to(&object::generate_signer(&constructor_ref), IntegratorFeeStore { - market_id, - trading_pair, - market_address, - integrator: integrator_address, - extend_ref, - quote_available: 0, - }); - smart_table::add( - integrator_fee_stores_map_ref_mut, - trading_pair, - IntegratorFeeStoreMetadata { - market_id, - trading_pair, - market_address, - integrator: integrator_address, - integrator_fee_store_address: - object::address_from_constructor_ref(&constructor_ref), + open_orders_address, } ); } @@ -427,125 +348,14 @@ module econia::core { ); } - public entry fun deposit( - user: &signer, - market_account_address: address, - base_amount: u64, - quote_amount: u64, - ) acquires Market, MarketAccount { - let (market_ref_mut, market_account_ref_mut) = borrow_market_and_market_account_mut( - user, - market_account_address, - ); - assert_market_fully_collateralized(market_ref_mut); - market_account_transfer( - user, - market_account_ref_mut, - market_ref_mut, - base_amount, - true, - true, - ); - market_account_transfer( - user, - market_account_ref_mut, - market_ref_mut, - quote_amount, - false, - true, - ); - } - - public entry fun withdraw( - user: &signer, - market_account_address: address, - base_amount: u64, - quote_amount: u64, - ) acquires Market, MarketAccount { - let (market_ref_mut, market_account_ref_mut) = borrow_market_and_market_account_mut( - user, - market_account_address, - ); - market_account_transfer( - user, - market_account_ref_mut, - market_ref_mut, - base_amount, - true, - false, - ); - market_account_transfer( - user, - market_account_ref_mut, - market_ref_mut, - quote_amount, - false, - false, - ); - } - - fun market_account_transfer( - user: &signer, - market_account_ref_mut: &mut MarketAccount, - market_ref_mut: &mut Market, - amount: u64, - transfer_base: bool, - deposit: bool, - ) { - let actual_transfer_amount = if (deposit) amount else - socialize_withdrawal_amount(market_ref_mut, amount, transfer_base); - let (metadata, user_balances_ref_mut, market_balances_ref_mut) = if (transfer_base) ( - market_account_ref_mut.trading_pair.base_metadata, - &mut market_account_ref_mut.base_balances, - &mut market_ref_mut.base_balances, - ) else ( - market_account_ref_mut.trading_pair.quote_metadata, - &mut market_account_ref_mut.quote_balances, - &mut market_ref_mut.quote_balances, - ); - let (sender, recipient, user_total, user_available, market_balance) = if (deposit) { - ( - user, - market_account_ref_mut.market_address, - user_balances_ref_mut.total + amount, - user_balances_ref_mut.available + amount, - market_balances_ref_mut.market_account_deposits + amount, - ) - } else { - ( - &object::generate_signer_for_extending(&market_ref_mut.extend_ref), - signer::address_of(user), - user_balances_ref_mut.total - amount, - user_balances_ref_mut.available - amount, - market_balances_ref_mut.market_account_deposits - amount, - ) - }; - user_balances_ref_mut.total = user_total; - user_balances_ref_mut.available = user_available; - market_balances_ref_mut.market_account_deposits = market_balance; - primary_fungible_store::transfer(sender, metadata, recipient, actual_transfer_amount); - } - - #[view] - public fun market_account_balances( - market_account_address: address - ): MarketAccountBalancesView - acquires MarketAccount { - assert_market_account_exists(market_account_address); - let market_account_ref = borrow_global(market_account_address); - let base_balances = market_account_ref.base_balances; - let quote_balances = market_account_ref.quote_balances; - MarketAccountBalancesView { base_balances, quote_balances } - } - - fun assert_market_account_exists( - market_account_address: address, + fun assert_open_orders_exists( + open_orders_address: address, ) { - assert!(exists(market_account_address), E_NO_MARKET_ACCOUNT); + assert!(exists(open_orders_address), E_NO_OPEN_ORDERS); } - fun assert_market_account_owner(market_account_ref: &MarketAccount, user: address) { - assert!(market_account_ref.user == user, E_DOES_NOT_OWN_MARKET_ACCOUNT); + fun assert_open_orders_owner(open_orders_ref: &OpenOrders, user: address) { + assert!(open_orders_ref.user == user, E_DOES_NOT_OWN_OPEN_ORDERS); } fun assert_market_fully_collateralized(market_ref: &Market) { @@ -564,10 +374,17 @@ module econia::core { E_MARKET_NOT_COLLATERALIZED_QUOTE, ); let balance = primary_fungible_store::balance(market_ref.market_address, asset_metadata); - let minimum_balance = asset_amounts.market_account_deposits + asset_amounts.pool_liquidity; + let minimum_balance = expected_vault_balance(&asset_amounts); assert!(balance >= minimum_balance, error_code); } + fun expected_vault_balance(asset_amounts_ref: &AssetBalances): u64 { + asset_amounts_ref.book_liquidity + + asset_amounts_ref.pool_liquidity + + asset_amounts_ref.unclaimed_pool_fees + + asset_amounts_ref.unclaimed_protocol_fees + } + fun create_nontransferable_sticky_object(owner: address): (ConstructorRef, ExtendRef) { let constructor_ref = object::create_sticky_object(owner); let transfer_ref = object::generate_transfer_ref(&constructor_ref); @@ -650,20 +467,15 @@ module econia::core { withdraw_base: bool, ): u64 { let (balances_ref, asset_metadata) = if (withdraw_base) ( - market_ref.base_balances, + &market_ref.base_balances, market_ref.trading_pair.base_metadata, ) else ( - market_ref.quote_balances, + &market_ref.quote_balances, market_ref.trading_pair.quote_metadata, ); - let expected_vault_balance = - balances_ref.market_account_deposits + - balances_ref.pool_liquidity + - balances_ref.unclaimed_integrator_fees; - let actual_vault_balance = primary_fungible_store::balance( - market_ref.market_address, - asset_metadata, - ); + let expected_vault_balance = expected_vault_balance(balances_ref); + let actual_vault_balance = + primary_fungible_store::balance(market_ref.market_address, asset_metadata); if (actual_vault_balance >= expected_vault_balance) return amount; let numerator = (amount as u128) * (actual_vault_balance as u128); let denominator = (expected_vault_balance as u128); @@ -674,20 +486,6 @@ module econia::core { inline fun borrow_registry_mut(): &mut Registry { borrow_global_mut(@econia) } - inline fun borrow_market_and_market_account_mut( - user: &signer, - market_account_address: address, - ): ( - &mut Market, - &mut MarketAccount, - ) { - assert_market_account_exists(market_account_address); - let market_account_ref_mut = borrow_global_mut(market_account_address); - assert_market_account_owner(market_account_ref_mut, signer::address_of(user)); - let market_ref_mut = borrow_global_mut(market_account_ref_mut.market_address); - (market_ref_mut, market_account_ref_mut) - } - #[test_only] const MARKET_REGISTRANT_FOR_TEST: address = @0xace; #[test_only] @@ -724,26 +522,26 @@ module econia::core { #[test_only] public fun assert_market_balances( market_address: address, - base_market_account_deposits: u64, base_book_liquidity: u64, base_pool_liquidity: u64, - base_unclaimed_integrator_fees: u64, - quote_market_account_deposits: u64, + base_unclaimed_pool_fees: u64, + base_unclaimed_protocol_fees: u64, quote_book_liquidity: u64, quote_pool_liquidity: u64, - quote_unclaimed_integrator_fees: u64, + quote_unclaimed_pool_fees: u64, + quote_unclaimed_protocol_fees: u64, ) acquires Market { let market_ref = borrow_global(market_address); let base_balances = market_ref.base_balances; - assert!(base_balances.market_account_deposits == base_market_account_deposits, 0); assert!(base_balances.book_liquidity == base_book_liquidity, 0); assert!(base_balances.pool_liquidity == base_pool_liquidity, 0); - assert!(base_balances.unclaimed_integrator_fees == base_unclaimed_integrator_fees, 0); + assert!(base_balances.unclaimed_pool_fees == base_unclaimed_pool_fees, 0); + assert!(base_balances.unclaimed_protocol_fees == base_unclaimed_protocol_fees, 0); let quote_balances = market_ref.quote_balances; - assert!(quote_balances.market_account_deposits == quote_market_account_deposits, 0); assert!(quote_balances.book_liquidity == quote_book_liquidity, 0); assert!(quote_balances.pool_liquidity == quote_pool_liquidity, 0); - assert!(quote_balances.unclaimed_integrator_fees == quote_unclaimed_integrator_fees, 0); + assert!(quote_balances.unclaimed_pool_fees == quote_unclaimed_pool_fees, 0); + assert!(quote_balances.unclaimed_protocol_fees == quote_unclaimed_protocol_fees, 0); } #[test_only] @@ -759,20 +557,6 @@ module econia::core { assert!(primary_fungible_store::balance(market_address, metadata) == quote_expected, 0); } - #[test_only] - public fun assert_wallet_balances( - market_account_address: address, - base_expected: u64, - quote_expected: u64, - ) acquires MarketAccount { - let market_account_ref = borrow_global(market_account_address); - let user = market_account_ref.user; - let base_metadata = market_account_ref.trading_pair.base_metadata; - let quote_metadata = market_account_ref.trading_pair.quote_metadata; - assert!(primary_fungible_store::balance(user, base_metadata) == base_expected, 0); - assert!(primary_fungible_store::balance(user, quote_metadata) == quote_expected, 0); - } - #[test_only] public fun assert_registry_parameters( registry_parameters: RegistryParameters, @@ -790,68 +574,21 @@ module econia::core { } #[test_only] - public fun assert_market_account_balances( - market_account_address: address, - base_available: u64, - base_total: u64, - quote_available: u64, - quote_total: u64, - ) acquires MarketAccount { - let balances_view = market_account_balances(market_account_address); - assert!(balances_view.base_balances.available == base_available, 0); - assert!(balances_view.base_balances.total == base_total, 0); - assert!(balances_view.quote_balances.available == quote_available, 0); - assert!(balances_view.quote_balances.total == quote_total, 0); - } - - #[test_only] - public fun assert_market_account_fields( - market_account_address: address, + public fun assert_open_orders_fields( + open_orders_address: address, market_id: u64, trading_pair: TradingPair, market_address: address, user: address, - base_available: u64, - base_total: u64, - quote_available: u64, - quote_total: u64, - ) acquires MarketAccount { - let market_account_ref = borrow_global(market_account_address); - assert!(market_account_ref.market_id == market_id, 0); - assert!(market_account_ref.trading_pair == trading_pair, 0); - assert!(market_account_ref.market_address == market_address, 0); - assert!(market_account_ref.user == user, 0); - assert!(market_account_ref.market_account_address == market_account_address, 0); - let extend_ref_address = object::address_from_extend_ref(&market_account_ref.extend_ref); - assert!(extend_ref_address == market_account_address, 0); - assert!(market_account_ref.base_balances.available == base_available, 0); - assert!(market_account_ref.base_balances.total == base_total, 0); - assert!(market_account_ref.quote_balances.available == quote_available, 0); - assert!(market_account_ref.quote_balances.total == quote_total, 0); - } - - #[test_only] - public fun assert_integrator_fee_store_fields( - integrator_fee_store_address: address, - market_id: u64, - trading_pair: TradingPair, - market_address: address, - integrator: address, - quote_available: u64, - ) acquires IntegratorFeeStore { - let integrator_fee_store_ref = - borrow_global(integrator_fee_store_address); - assert!(integrator_fee_store_ref.market_id == market_id, 0); - assert!(integrator_fee_store_ref.trading_pair == trading_pair, 0); - assert!(integrator_fee_store_ref.market_address == market_address, 0); - assert!(integrator_fee_store_ref.integrator == integrator, 0); - let extend_ref_address = - object::address_from_extend_ref(&integrator_fee_store_ref.extend_ref); - assert!(extend_ref_address == integrator_fee_store_address, 0); - assert!(integrator_fee_store_ref.quote_available == quote_available, 0); + ) acquires OpenOrders { + let open_orders_ref = borrow_global(open_orders_address); + assert!(open_orders_ref.market_id == market_id, 0); + assert!(open_orders_ref.trading_pair == trading_pair, 0); + assert!(open_orders_ref.market_address == market_address, 0); + assert!(open_orders_ref.user == user, 0); + assert!(open_orders_ref.open_orders_address == open_orders_address, 0); } - #[test_only] public fun ensure_module_initialized_for_test() { let feature = features::get_coin_to_fungible_asset_migration_feature(); @@ -917,19 +654,22 @@ module econia::core { } #[test_only] - public fun ensure_market_account_registered_for_test(): ( + public fun ensure_open_orders_registered_for_test(): ( address, - address, - ) acquires MarketAccounts, Registry { + address + ) acquires + OpenOrdersByMarket, + Registry + { ensure_market_registered_for_test(); let (base_metadata, quote_metadata) = test_assets::get_metadata(); - ensure_market_account_registered(&get_signer(USER_FOR_TEST), base_metadata, quote_metadata); + ensure_open_orders_registered(&get_signer(USER_FOR_TEST), base_metadata, quote_metadata); let market_address = get_test_market_address(); - let market_accounts_map_ref_mut = &mut borrow_global_mut(USER_FOR_TEST).map; - let market_account_metadata_ref = - smart_table::borrow(market_accounts_map_ref_mut, get_test_trading_pair()); - let market_account_address = market_account_metadata_ref.market_account_address; - (market_address, market_account_address) + let open_orders_by_market_map_ref = &borrow_global(USER_FOR_TEST).map; + let open_orders_metadata_ref = + smart_table::borrow(open_orders_by_market_map_ref, get_test_trading_pair()); + let open_orders_address = open_orders_metadata_ref.open_orders_address; + (market_address, open_orders_address) } #[test_only] @@ -945,52 +685,32 @@ module econia::core { assert_option_vector_is_valid_length(&vector[0, 0]); } - #[test, expected_failure(abort_code = E_NO_MARKET_ACCOUNT)] - fun test_assert_market_account_exists_no_market_account() { - assert_market_account_exists(@0x0); + #[test, expected_failure(abort_code = E_NO_OPEN_ORDERS)] + fun test_open_orders_exists_no_open_orders() { + assert_open_orders_exists(@0x0); } - #[test, expected_failure(abort_code = E_DOES_NOT_OWN_MARKET_ACCOUNT)] - fun test_assert_market_account_ownership_does_not_own_market_account() + #[test, expected_failure(abort_code = E_DOES_NOT_OWN_OPEN_ORDERS)] + fun test_assert_open_orders_owner_does_not_own_open_orders() acquires - MarketAccount, - MarketAccounts, + OpenOrders, + OpenOrdersByMarket, Registry, { - let (_, market_account_address) = ensure_market_account_registered_for_test(); - assert_market_account_owner(borrow_global(market_account_address), @0x0); + let (_, open_orders_address) = ensure_open_orders_registered_for_test(); + assert_open_orders_owner(borrow_global(open_orders_address), @0x0); } #[test, expected_failure(abort_code = E_MARKET_NOT_COLLATERALIZED_BASE)] fun test_assert_market_fully_collateralized_market_not_collateralized_base() - acquires - MarketAccount, - MarketAccounts, - Market, - Registry, - { - let (_, market_account_address) = ensure_market_account_registered_for_test(); - test_assets::mint(USER_FOR_TEST, 100, 200); - deposit(&get_signer(USER_FOR_TEST), market_account_address, 100, 200); - let market_address = get_test_market_address(); - test_assets::burn(market_address, 1, 0); - assert_market_fully_collateralized(borrow_global(market_address)); + acquires Market { + assert_market_fully_collateralized(borrow_global(@0x0)); } #[test, expected_failure(abort_code = E_MARKET_NOT_COLLATERALIZED_QUOTE)] fun test_assert_market_fully_collateralized_market_not_collateralized_quote() - acquires - MarketAccount, - MarketAccounts, - Market, - Registry, - { - let (_, market_account_address) = ensure_market_account_registered_for_test(); - test_assets::mint(USER_FOR_TEST, 100, 200); - deposit(&get_signer(USER_FOR_TEST), market_account_address, 100, 200); - let market_address = get_test_market_address(); - test_assets::burn(market_address, 0, 1); - assert_market_fully_collateralized(borrow_global(market_address)); + acquires Market { + assert_market_fully_collateralized(borrow_global(@0x0)); } #[test] @@ -1002,130 +722,6 @@ module econia::core { assert!(object::owner(object) == @econia, 0); } - #[test] - fun test_deposit_withdraw() acquires Market, MarketAccount, MarketAccounts, Registry { - let (market_address, market_account_address) = ensure_market_account_registered_for_test(); - let start_base = 123; - let start_quote = 456; - let deposit_base = 100; - let deposit_quote = 200; - let normal_withdraw_base = 50; - let normal_withdraw_quote = 75; - let wallet_after_deposit_base = start_base - deposit_base; - let wallet_after_deposit_quote = start_quote - deposit_quote; - let wallet_after_withdrawal_1_base = wallet_after_deposit_base + normal_withdraw_base; - let wallet_after_withdrawal_1_quote = wallet_after_deposit_quote + normal_withdraw_quote; - let burn_base = 25; - let burn_quote = 50; - let socialized_withdraw_base = 20; - let socialized_withdraw_quote = 70; - let balance_after_withdraw_1_base = deposit_base - normal_withdraw_base; - let balance_after_withdraw_1_quote = deposit_quote - normal_withdraw_quote; - let balance_after_withdraw_2_base = - balance_after_withdraw_1_base - socialized_withdraw_base; - let balance_after_withdraw_2_quote = - balance_after_withdraw_1_quote - socialized_withdraw_quote; - let vault_after_burn_base = balance_after_withdraw_1_base - burn_base; - let vault_after_burn_quote = balance_after_withdraw_1_quote - burn_quote; - let socialized_transfer_amount_base = - socialized_withdraw_base * vault_after_burn_base / balance_after_withdraw_1_base; - let socialized_transfer_amount_quote = - socialized_withdraw_quote * vault_after_burn_quote / balance_after_withdraw_1_quote; - let vault_final_base = vault_after_burn_base - socialized_transfer_amount_base; - let vault_final_quote = vault_after_burn_quote - socialized_transfer_amount_quote; - let wallet_final_base = wallet_after_withdrawal_1_base + socialized_transfer_amount_base; - let wallet_final_quote = wallet_after_withdrawal_1_quote + socialized_transfer_amount_quote; - test_assets::mint(USER_FOR_TEST, start_base, start_quote); - assert_wallet_balances(market_account_address, start_base, start_quote); - let user = get_signer(USER_FOR_TEST); - deposit(&user, market_account_address, deposit_base, deposit_quote); - assert_market_account_balances( - market_account_address, - deposit_base, - deposit_base, - deposit_quote, - deposit_quote, - ); - assert_market_balances( - market_address, - deposit_base, - 0, - 0, - 0, - deposit_quote, - 0, - 0, - 0, - ); - assert_wallet_balances( - market_account_address, - wallet_after_deposit_base, - wallet_after_deposit_quote, - ); - assert_vault_values(market_address, deposit_base, deposit_quote); - withdraw(&user, market_account_address, normal_withdraw_base, normal_withdraw_quote); - assert_market_account_balances( - market_account_address, - balance_after_withdraw_1_base, - balance_after_withdraw_1_base, - balance_after_withdraw_1_quote, - balance_after_withdraw_1_quote, - ); - assert_market_balances( - market_address, - balance_after_withdraw_1_base, - 0, - 0, - 0, - balance_after_withdraw_1_quote, - 0, - 0, - 0, - ); - assert_wallet_balances( - market_account_address, - wallet_after_withdrawal_1_base, - wallet_after_withdrawal_1_quote, - ); - assert_vault_values( - market_address, - balance_after_withdraw_1_base, - balance_after_withdraw_1_quote, - ); - test_assets::burn(market_address, burn_base, burn_quote); - assert_vault_values(market_address, vault_after_burn_base, vault_after_burn_quote); - withdraw( - &user, - market_account_address, - socialized_withdraw_base, - socialized_withdraw_quote, - ); - assert_market_account_balances( - market_account_address, - balance_after_withdraw_2_base, - balance_after_withdraw_2_base, - balance_after_withdraw_2_quote, - balance_after_withdraw_2_quote, - ); - assert_market_balances( - market_address, - balance_after_withdraw_2_base, - 0, - 0, - 0, - balance_after_withdraw_2_quote, - 0, - 0, - 0, - ); - assert_wallet_balances( - market_account_address, - wallet_final_base, - wallet_final_quote, - ); - assert_vault_values(market_address, vault_final_base, vault_final_quote); - } - #[test] fun test_genesis_values() acquires Registry { ensure_module_initialized_for_test(); @@ -1202,10 +798,10 @@ module econia::core { } #[test] - fun test_ensure_market_account_registered() acquires MarketAccount, MarketAccounts, Registry { + fun test_ensure_open_orders_registered() acquires OpenOrders, OpenOrdersByMarket, Registry { ensure_market_registered_for_test(); let (base_metadata, quote_metadata) = test_assets::get_metadata(); - ensure_market_account_registered( + ensure_open_orders_registered( &get_signer(USER_FOR_TEST), base_metadata, quote_metadata @@ -1214,70 +810,27 @@ module econia::core { let market_metadata = *table_with_length::borrow(®istry.markets, MARKET_ID_FOR_TEST); let trading_pair = market_metadata.trading_pair; let market_address = market_metadata.market_address; - let market_accounts_map_ref = &borrow_global(USER_FOR_TEST).map; - let market_account_metadata = *smart_table::borrow(market_accounts_map_ref, trading_pair); - assert!(market_account_metadata.market_id == MARKET_ID_FOR_TEST, 0); - assert!(market_account_metadata.trading_pair == trading_pair, 0); - assert!(market_account_metadata.market_address == market_address, 0); - assert!(market_account_metadata.user == USER_FOR_TEST, 0); - assert_market_account_fields( - market_account_metadata.market_account_address, + let open_orders_by_market_map_ref = &borrow_global(USER_FOR_TEST).map; + let open_orders_metadata = + *smart_table::borrow(open_orders_by_market_map_ref, trading_pair); + assert!(open_orders_metadata.market_id == MARKET_ID_FOR_TEST, 0); + assert!(open_orders_metadata.trading_pair == trading_pair, 0); + assert!(open_orders_metadata.market_address == market_address, 0); + assert!(open_orders_metadata.user == USER_FOR_TEST, 0); + assert_open_orders_fields( + open_orders_metadata.open_orders_address, MARKET_ID_FOR_TEST, trading_pair, market_address, USER_FOR_TEST, - 0, - 0, - 0, - 0, ); - ensure_market_account_registered( + ensure_open_orders_registered( &get_signer(USER_FOR_TEST), base_metadata, quote_metadata ); } - #[test] - fun test_ensure_integrator_fee_store_registered() acquires - IntegratorFeeStore, - IntegratorFeeStores, - Registry - { - ensure_market_registered_for_test(); - let (base_metadata, quote_metadata) = test_assets::get_metadata(); - ensure_integrator_fee_store_registered( - &get_signer(INTEGRATOR_FOR_TEST), - base_metadata, - quote_metadata - ); - let registry = borrow_registry(); - let market_metadata = *table_with_length::borrow(®istry.markets, MARKET_ID_FOR_TEST); - let trading_pair = market_metadata.trading_pair; - let market_address = market_metadata.market_address; - let integrator_fee_stores_map_ref = - &borrow_global(INTEGRATOR_FOR_TEST).map; - let integrator_fee_store_metadata = - *smart_table::borrow(integrator_fee_stores_map_ref, trading_pair); - assert!(integrator_fee_store_metadata.market_id == MARKET_ID_FOR_TEST, 0); - assert!(integrator_fee_store_metadata.trading_pair == trading_pair, 0); - assert!(integrator_fee_store_metadata.market_address == market_address, 0); - assert!(integrator_fee_store_metadata.integrator == INTEGRATOR_FOR_TEST, 0); - assert_integrator_fee_store_fields( - integrator_fee_store_metadata.integrator_fee_store_address, - MARKET_ID_FOR_TEST, - trading_pair, - market_address, - INTEGRATOR_FOR_TEST, - 0, - ); - ensure_integrator_fee_store_registered( - &get_signer(INTEGRATOR_FOR_TEST), - base_metadata, - quote_metadata - ); - } - #[test] fun test_update_recognized_markets() acquires Registry { ensure_markets_registered_for_test(); From cd2f4fb66c14a041d7c9513b6b67df3e35200966 Mon Sep 17 00:00:00 2001 From: alnoki <43892045+alnoki@users.noreply.github.com> Date: Mon, 11 Mar 2024 16:44:19 -0700 Subject: [PATCH 05/17] Fix broken collateralization test --- src/move/econia/sources/core.move | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/move/econia/sources/core.move b/src/move/econia/sources/core.move index 023486e..2838f69 100644 --- a/src/move/econia/sources/core.move +++ b/src/move/econia/sources/core.move @@ -703,14 +703,22 @@ module econia::core { #[test, expected_failure(abort_code = E_MARKET_NOT_COLLATERALIZED_BASE)] fun test_assert_market_fully_collateralized_market_not_collateralized_base() - acquires Market { - assert_market_fully_collateralized(borrow_global(@0x0)); + acquires Market, Registry { + ensure_market_registered_for_test(); + let market_address = get_test_market_address(); + let market_ref_mut = borrow_global_mut(market_address); + market_ref_mut.base_balances.pool_liquidity = 1; + assert_market_fully_collateralized(borrow_global(market_address)); } #[test, expected_failure(abort_code = E_MARKET_NOT_COLLATERALIZED_QUOTE)] fun test_assert_market_fully_collateralized_market_not_collateralized_quote() - acquires Market { - assert_market_fully_collateralized(borrow_global(@0x0)); + acquires Market, Registry { + ensure_market_registered_for_test(); + let market_address = get_test_market_address(); + let market_ref_mut = borrow_global_mut(market_address); + market_ref_mut.quote_balances.pool_liquidity = 1; + assert_market_fully_collateralized(borrow_global(market_address)); } #[test] From 9d347f29735176250b21eb17ccd8231393884083 Mon Sep 17 00:00:00 2001 From: alnoki <43892045+alnoki@users.noreply.github.com> Date: Mon, 11 Mar 2024 16:49:08 -0700 Subject: [PATCH 06/17] Add coverage testing for open orders existence --- src/move/econia/sources/core.move | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/move/econia/sources/core.move b/src/move/econia/sources/core.move index 2838f69..e490c00 100644 --- a/src/move/econia/sources/core.move +++ b/src/move/econia/sources/core.move @@ -701,6 +701,17 @@ module econia::core { assert_open_orders_owner(borrow_global(open_orders_address), @0x0); } + #[test] + fun test_open_orders_exists_and_correct_owner() + acquires + OpenOrders, + OpenOrdersByMarket, + Registry, + { + let (_, open_orders_address) = ensure_open_orders_registered_for_test(); + assert_open_orders_owner(borrow_global(open_orders_address), USER_FOR_TEST); + } + #[test, expected_failure(abort_code = E_MARKET_NOT_COLLATERALIZED_BASE)] fun test_assert_market_fully_collateralized_market_not_collateralized_base() acquires Market, Registry { From 322832c9ecb19349b216a5147fa88ddad5e4f60b Mon Sep 17 00:00:00 2001 From: alnoki <43892045+alnoki@users.noreply.github.com> Date: Mon, 11 Mar 2024 17:10:03 -0700 Subject: [PATCH 07/17] Return test market address in registration helper --- src/move/econia/sources/core.move | 39 ++++++++++++++----------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/src/move/econia/sources/core.move b/src/move/econia/sources/core.move index e490c00..5754ce1 100644 --- a/src/move/econia/sources/core.move +++ b/src/move/econia/sources/core.move @@ -597,13 +597,6 @@ module econia::core { if (!exists(@econia)) init_module(&get_signer(@econia)); } - #[test_only] - public fun get_test_market_address(): address acquires Registry { - ensure_market_registered_for_test(); - let registry_ref = borrow_global(@econia); - table_with_length::borrow(®istry_ref.markets, MARKET_ID_FOR_TEST).market_address - } - #[test_only] public fun get_test_trading_pair(): TradingPair { let (base_metadata, quote_metadata) = test_assets::get_metadata(); @@ -625,18 +618,23 @@ module econia::core { } #[test_only] - public fun ensure_market_registered_for_test() acquires Registry { + public fun ensure_market_registered_for_test(): address acquires Registry { ensure_module_initialized_for_test(); let trading_pair = get_test_trading_pair(); let registry_ref = borrow_global(@econia); - if (table::contains(®istry_ref.trading_pair_market_ids, trading_pair)) return; - mint_fa_apt_to_market_registrant(); - let registrant = get_signer(MARKET_REGISTRANT_FOR_TEST); - ensure_market_registered( - ®istrant, - trading_pair.base_metadata, - trading_pair.quote_metadata - ); + if (!table::contains(®istry_ref.trading_pair_market_ids, trading_pair)) { + mint_fa_apt_to_market_registrant(); + let registrant = get_signer(MARKET_REGISTRANT_FOR_TEST); + ensure_market_registered( + ®istrant, + trading_pair.base_metadata, + trading_pair.quote_metadata + ); + }; + let registry_ref = borrow_global(@econia); + let market_address = + table_with_length::borrow(®istry_ref.markets, MARKET_ID_FOR_TEST).market_address; + market_address } #[test_only] @@ -661,10 +659,9 @@ module econia::core { OpenOrdersByMarket, Registry { - ensure_market_registered_for_test(); + let market_address = ensure_market_registered_for_test(); let (base_metadata, quote_metadata) = test_assets::get_metadata(); ensure_open_orders_registered(&get_signer(USER_FOR_TEST), base_metadata, quote_metadata); - let market_address = get_test_market_address(); let open_orders_by_market_map_ref = &borrow_global(USER_FOR_TEST).map; let open_orders_metadata_ref = smart_table::borrow(open_orders_by_market_map_ref, get_test_trading_pair()); @@ -715,8 +712,7 @@ module econia::core { #[test, expected_failure(abort_code = E_MARKET_NOT_COLLATERALIZED_BASE)] fun test_assert_market_fully_collateralized_market_not_collateralized_base() acquires Market, Registry { - ensure_market_registered_for_test(); - let market_address = get_test_market_address(); + let market_address = ensure_market_registered_for_test(); let market_ref_mut = borrow_global_mut(market_address); market_ref_mut.base_balances.pool_liquidity = 1; assert_market_fully_collateralized(borrow_global(market_address)); @@ -725,8 +721,7 @@ module econia::core { #[test, expected_failure(abort_code = E_MARKET_NOT_COLLATERALIZED_QUOTE)] fun test_assert_market_fully_collateralized_market_not_collateralized_quote() acquires Market, Registry { - ensure_market_registered_for_test(); - let market_address = get_test_market_address(); + let market_address = ensure_market_registered_for_test(); let market_ref_mut = borrow_global_mut(market_address); market_ref_mut.quote_balances.pool_liquidity = 1; assert_market_fully_collateralized(borrow_global(market_address)); From 7d83649cae805bcd9a2a32f46368eb43523aab6f Mon Sep 17 00:00:00 2001 From: alnoki <43892045+alnoki@users.noreply.github.com> Date: Mon, 11 Mar 2024 17:27:13 -0700 Subject: [PATCH 08/17] Add socialized withdrawal function tests --- src/move/econia/sources/core.move | 46 ++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/src/move/econia/sources/core.move b/src/move/econia/sources/core.move index 5754ce1..d44aee6 100644 --- a/src/move/econia/sources/core.move +++ b/src/move/econia/sources/core.move @@ -52,6 +52,10 @@ module econia::core { const E_DOES_NOT_OWN_OPEN_ORDERS: u64 = 7; /// Open orders resource does not exist at given address. const E_NO_OPEN_ORDERS: u64 = 8; + /// Requested withdrawal amount exceeds expected vault balance for base. + const E_WITHDRAWAL_EXCEEDS_EXPECTED_VAULT_BALANCE_BASE: u64 = 9; + /// Requested withdrawal amount exceeds expected vault balance for quote. + const E_WITHDRAWAL_EXCEEDS_EXPECTED_VAULT_BALANCE_QUOTE: u64 = 9; #[resource_group_member(group = ObjectGroup)] struct Market has key { @@ -466,16 +470,19 @@ module econia::core { amount: u64, withdraw_base: bool, ): u64 { - let (balances_ref, asset_metadata) = if (withdraw_base) ( + let (balances_ref, asset_metadata, error_code) = if (withdraw_base) ( &market_ref.base_balances, market_ref.trading_pair.base_metadata, + E_WITHDRAWAL_EXCEEDS_EXPECTED_VAULT_BALANCE_BASE, ) else ( &market_ref.quote_balances, market_ref.trading_pair.quote_metadata, + E_WITHDRAWAL_EXCEEDS_EXPECTED_VAULT_BALANCE_QUOTE, ); let expected_vault_balance = expected_vault_balance(balances_ref); let actual_vault_balance = primary_fungible_store::balance(market_ref.market_address, asset_metadata); + assert!(amount <= expected_vault_balance, error_code); if (actual_vault_balance >= expected_vault_balance) return amount; let numerator = (amount as u128) * (actual_vault_balance as u128); let denominator = (expected_vault_balance as u128); @@ -727,6 +734,43 @@ module econia::core { assert_market_fully_collateralized(borrow_global(market_address)); } + #[test] + fun test_socialize_withdrawal_amount() acquires Market, Registry { + let market_address = ensure_market_registered_for_test(); + let market_ref_mut = borrow_global_mut(market_address); + assert!(socialize_withdrawal_amount(market_ref_mut, 0, true) == 0, 0); + assert!(socialize_withdrawal_amount(market_ref_mut, 0, false) == 0, 0); + market_ref_mut = borrow_global_mut(market_address); + let balances_ref_mut = &mut market_ref_mut.base_balances; + balances_ref_mut.book_liquidity = 10; + balances_ref_mut.pool_liquidity = 20; + balances_ref_mut = &mut market_ref_mut.quote_balances; + balances_ref_mut.unclaimed_pool_fees = 12; + balances_ref_mut.unclaimed_protocol_fees = 24; + test_assets::mint(market_address, 30, 36); + assert!(socialize_withdrawal_amount(market_ref_mut, 5, true) == 5, 0); + assert!(socialize_withdrawal_amount(market_ref_mut, 8, false) == 8, 0); + test_assets::burn(market_address, 15, 12); + assert!(socialize_withdrawal_amount(market_ref_mut, 10, true) == 5, 0); + assert!(socialize_withdrawal_amount(market_ref_mut, 18, false) == 12, 0); + } + + #[test, expected_failure(abort_code = E_WITHDRAWAL_EXCEEDS_EXPECTED_VAULT_BALANCE_BASE)] + fun test_socialize_withdrawal_amount_withdrawal_exceeds_expected_vault_balance_base() + acquires Market, Registry { + let market_address = ensure_market_registered_for_test(); + let market_ref = borrow_global(market_address); + socialize_withdrawal_amount(market_ref, 10, true); + } + + #[test, expected_failure(abort_code = E_WITHDRAWAL_EXCEEDS_EXPECTED_VAULT_BALANCE_QUOTE)] + fun test_socialize_withdrawal_amount_withdrawal_exceeds_expected_vault_balance_quote() + acquires Market, Registry { + let market_address = ensure_market_registered_for_test(); + let market_ref = borrow_global(market_address); + socialize_withdrawal_amount(market_ref, 10, false); + } + #[test] fun test_create_nontransferable_sticky_object() { let (constructor_ref, _) = create_nontransferable_sticky_object(@econia); From bcbcae81c8adf982a8e9ec7cf072d2075dff9743 Mon Sep 17 00:00:00 2001 From: alnoki <43892045+alnoki@users.noreply.github.com> Date: Mon, 11 Mar 2024 17:30:04 -0700 Subject: [PATCH 09/17] Ensure 100% coverage --- src/move/econia/sources/core.move | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/move/econia/sources/core.move b/src/move/econia/sources/core.move index d44aee6..b216968 100644 --- a/src/move/econia/sources/core.move +++ b/src/move/econia/sources/core.move @@ -713,6 +713,7 @@ module econia::core { Registry, { let (_, open_orders_address) = ensure_open_orders_registered_for_test(); + assert_open_orders_exists(open_orders_address); assert_open_orders_owner(borrow_global(open_orders_address), USER_FOR_TEST); } @@ -748,6 +749,7 @@ module econia::core { balances_ref_mut.unclaimed_pool_fees = 12; balances_ref_mut.unclaimed_protocol_fees = 24; test_assets::mint(market_address, 30, 36); + assert_market_fully_collateralized(market_ref_mut); assert!(socialize_withdrawal_amount(market_ref_mut, 5, true) == 5, 0); assert!(socialize_withdrawal_amount(market_ref_mut, 8, false) == 8, 0); test_assets::burn(market_address, 15, 12); From b89813a0904822ab2a990520e0cf84c2ea74c5d8 Mon Sep 17 00:00:00 2001 From: alnoki <43892045+alnoki@users.noreply.github.com> Date: Mon, 11 Mar 2024 17:49:27 -0700 Subject: [PATCH 10/17] Add active status check --- src/move/econia/sources/core.move | 79 ++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 18 deletions(-) diff --git a/src/move/econia/sources/core.move b/src/move/econia/sources/core.move index b216968..fcdd486 100644 --- a/src/move/econia/sources/core.move +++ b/src/move/econia/sources/core.move @@ -55,7 +55,9 @@ module econia::core { /// Requested withdrawal amount exceeds expected vault balance for base. const E_WITHDRAWAL_EXCEEDS_EXPECTED_VAULT_BALANCE_BASE: u64 = 9; /// Requested withdrawal amount exceeds expected vault balance for quote. - const E_WITHDRAWAL_EXCEEDS_EXPECTED_VAULT_BALANCE_QUOTE: u64 = 9; + const E_WITHDRAWAL_EXCEEDS_EXPECTED_VAULT_BALANCE_QUOTE: u64 = 10; + /// The protocol is inactive. + const E_INACTIVE: u64 = 11; #[resource_group_member(group = ObjectGroup)] struct Market has key { @@ -132,6 +134,10 @@ module econia::core { default_market_parameters: MarketParameters, } + struct Status has key { + active: bool, + } + struct TradingPair has copy, drop, store { base_metadata: Object, quote_metadata: Object, @@ -141,11 +147,15 @@ module econia::core { registrant: &signer, base_metadata: Object, quote_metadata: Object, - ) acquires Registry { + ) acquires + Registry, + Status + { let registry_ref_mut = borrow_registry_mut(); let trading_pair = TradingPair { base_metadata, quote_metadata }; let trading_pair_market_ids_ref_mut = &mut registry_ref_mut.trading_pair_market_ids; if (table::contains(trading_pair_market_ids_ref_mut, trading_pair)) return; + assert_active_status(); assert!(base_metadata != quote_metadata, E_BASE_QUOTE_METADATA_SAME); let utility_asset_metadata = registry_ref_mut.registry_parameters.utility_asset_metadata; let market_registration_fee = registry_ref_mut.registry_parameters.market_registration_fee; @@ -198,7 +208,12 @@ module econia::core { user: &signer, base_metadata: Object, quote_metadata: Object, - ) acquires OpenOrdersByMarket, Registry { + ) acquires + OpenOrdersByMarket, + Registry, + Status, + { + assert_active_status(); let user_address = signer::address_of(user); if (!exists(user_address)) { move_to(user, OpenOrdersByMarket { map: smart_table::new() }); @@ -352,6 +367,15 @@ module econia::core { ); } + public entry fun set_status(econia: &signer, active: bool) acquires Status { + assert_signer_is_econia(econia); + borrow_global_mut(@econia).active = active + } + + fun assert_active_status() acquires Status { + assert!(borrow_global(@econia).active, E_INACTIVE); + } + fun assert_open_orders_exists( open_orders_address: address, ) { @@ -433,6 +457,7 @@ module econia::core { leaf_node_order: GENESIS_DEFAULT_LEAF_NODE_ORDER, }, }); + move_to(econia, Status { active: true }); } fun assert_signer_is_econia(account: &signer) { @@ -625,7 +650,7 @@ module econia::core { } #[test_only] - public fun ensure_market_registered_for_test(): address acquires Registry { + public fun ensure_market_registered_for_test(): address acquires Registry, Status { ensure_module_initialized_for_test(); let trading_pair = get_test_trading_pair(); let registry_ref = borrow_global(@econia); @@ -645,7 +670,7 @@ module econia::core { } #[test_only] - public fun ensure_markets_registered_for_test() acquires Registry { + public fun ensure_markets_registered_for_test() acquires Registry, Status { ensure_market_registered_for_test(); let trading_pair_flipped = get_test_trading_pair_flipped(); let registry_ref = borrow_global(@econia); @@ -664,7 +689,8 @@ module econia::core { address ) acquires OpenOrdersByMarket, - Registry + Registry, + Status { let market_address = ensure_market_registered_for_test(); let (base_metadata, quote_metadata) = test_assets::get_metadata(); @@ -679,6 +705,16 @@ module econia::core { #[test_only] public fun get_signer(addr: address): signer { account::create_signer_for_test(addr) } + #[test, expected_failure(abort_code = E_INACTIVE)] + fun test_assert_active_status_inactive() acquires Status { + ensure_module_initialized_for_test(); + set_status(&get_signer(@econia), false); + assert_active_status(); + } + + #[test, expected_failure(abort_code = E_NOT_ECONIA)] + fun test_set_status_not_econia() acquires Status { set_status(&get_signer(@0x0), false); } + #[test, expected_failure(abort_code = E_NOT_ECONIA)] fun test_assert_signer_is_econia_not_econia() { assert_signer_is_econia(&get_signer(@0x0)); @@ -700,6 +736,7 @@ module econia::core { OpenOrders, OpenOrdersByMarket, Registry, + Status, { let (_, open_orders_address) = ensure_open_orders_registered_for_test(); assert_open_orders_owner(borrow_global(open_orders_address), @0x0); @@ -711,6 +748,7 @@ module econia::core { OpenOrders, OpenOrdersByMarket, Registry, + Status, { let (_, open_orders_address) = ensure_open_orders_registered_for_test(); assert_open_orders_exists(open_orders_address); @@ -719,7 +757,7 @@ module econia::core { #[test, expected_failure(abort_code = E_MARKET_NOT_COLLATERALIZED_BASE)] fun test_assert_market_fully_collateralized_market_not_collateralized_base() - acquires Market, Registry { + acquires Market, Registry, Status { let market_address = ensure_market_registered_for_test(); let market_ref_mut = borrow_global_mut(market_address); market_ref_mut.base_balances.pool_liquidity = 1; @@ -728,7 +766,7 @@ module econia::core { #[test, expected_failure(abort_code = E_MARKET_NOT_COLLATERALIZED_QUOTE)] fun test_assert_market_fully_collateralized_market_not_collateralized_quote() - acquires Market, Registry { + acquires Market, Registry, Status { let market_address = ensure_market_registered_for_test(); let market_ref_mut = borrow_global_mut(market_address); market_ref_mut.quote_balances.pool_liquidity = 1; @@ -736,7 +774,7 @@ module econia::core { } #[test] - fun test_socialize_withdrawal_amount() acquires Market, Registry { + fun test_socialize_withdrawal_amount() acquires Market, Registry, Status{ let market_address = ensure_market_registered_for_test(); let market_ref_mut = borrow_global_mut(market_address); assert!(socialize_withdrawal_amount(market_ref_mut, 0, true) == 0, 0); @@ -759,7 +797,7 @@ module econia::core { #[test, expected_failure(abort_code = E_WITHDRAWAL_EXCEEDS_EXPECTED_VAULT_BALANCE_BASE)] fun test_socialize_withdrawal_amount_withdrawal_exceeds_expected_vault_balance_base() - acquires Market, Registry { + acquires Market, Registry, Status { let market_address = ensure_market_registered_for_test(); let market_ref = borrow_global(market_address); socialize_withdrawal_amount(market_ref, 10, true); @@ -767,7 +805,7 @@ module econia::core { #[test, expected_failure(abort_code = E_WITHDRAWAL_EXCEEDS_EXPECTED_VAULT_BALANCE_QUOTE)] fun test_socialize_withdrawal_amount_withdrawal_exceeds_expected_vault_balance_quote() - acquires Market, Registry { + acquires Market, Registry, Status { let market_address = ensure_market_registered_for_test(); let market_ref = borrow_global(market_address); socialize_withdrawal_amount(market_ref, 10, false); @@ -808,7 +846,7 @@ module econia::core { } #[test] - fun test_ensure_market_registered() acquires Market, Registry { + fun test_ensure_market_registered() acquires Market, Registry, Status { ensure_markets_registered_for_test(); let registry_ref = borrow_registry(); let trading_pair_market_ids_ref = ®istry_ref.trading_pair_market_ids; @@ -840,7 +878,7 @@ module econia::core { } #[test, expected_failure(abort_code = E_NOT_ENOUGH_UTILITY_ASSET_TO_REGISTER_MARKET)] - fun test_ensure_market_registered_not_enough_utility_asset() acquires Registry { + fun test_ensure_market_registered_not_enough_utility_asset() acquires Registry, Status { ensure_market_registered_for_test(); let (base_metadata, quote_metadata) = test_assets::get_metadata(); ensure_market_registered( @@ -851,14 +889,19 @@ module econia::core { } #[test, expected_failure(abort_code = E_BASE_QUOTE_METADATA_SAME)] - fun test_ensure_market_registered_base_quote_metadata_same() acquires Registry { + fun test_ensure_market_registered_base_quote_metadata_same() acquires Registry, Status { ensure_module_initialized_for_test(); let (metadata, _) = test_assets::get_metadata(); ensure_market_registered(&get_signer(MARKET_REGISTRANT_FOR_TEST), metadata, metadata); } #[test] - fun test_ensure_open_orders_registered() acquires OpenOrders, OpenOrdersByMarket, Registry { + fun test_ensure_open_orders_registered() acquires + OpenOrders, + OpenOrdersByMarket, + Registry, + Status + { ensure_market_registered_for_test(); let (base_metadata, quote_metadata) = test_assets::get_metadata(); ensure_open_orders_registered( @@ -892,7 +935,7 @@ module econia::core { } #[test] - fun test_update_recognized_markets() acquires Registry { + fun test_update_recognized_markets() acquires Registry, Status { ensure_markets_registered_for_test(); let registry_ref = borrow_registry(); assert!(!smart_table::contains(®istry_ref.recognized_market_ids, 1), 0); @@ -947,7 +990,7 @@ module econia::core { } #[test] - fun test_update_market_parameters() acquires Market, Registry { + fun test_update_market_parameters() acquires Market, Registry, Status { ensure_market_registered_for_test(); let econia = get_signer(@econia); update_market_parameters( @@ -1009,7 +1052,7 @@ module econia::core { } #[test, expected_failure(abort_code = E_INVALID_MARKET_ID)] - fun test_update_market_parameters_invalid_market_id() acquires Market, Registry { + fun test_update_market_parameters_invalid_market_id() acquires Market, Registry, Status { ensure_market_registered_for_test(); update_market_parameters( &get_signer(@econia), From 9cb87f0589225c1fd3a486dcc9a357dda304508c Mon Sep 17 00:00:00 2001 From: alnoki <43892045+alnoki@users.noreply.github.com> Date: Mon, 11 Mar 2024 18:17:15 -0700 Subject: [PATCH 11/17] Add inner/leaf node B+ map registry params --- src/move/econia/sources/core.move | 79 ++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 2 deletions(-) diff --git a/src/move/econia/sources/core.move b/src/move/econia/sources/core.move index fcdd486..7ccee3d 100644 --- a/src/move/econia/sources/core.move +++ b/src/move/econia/sources/core.move @@ -23,6 +23,10 @@ module econia::core { const GENESIS_MARKET_REGISTRATION_FEE: u64 = 100_000_000; const GENESIS_ORACLE_FEE: u64 = 0; const GENESIS_INTEGRATOR_WITHDRAWAL_FEE: u64 = 0; + const GENESIS_BOOK_MAP_INNER_NODE_ORDER: u16 = 7; + const GENESIS_BOOK_MAP_LEAF_NODE_ORDER: u16 = 10; + const GENESIS_TICK_MAP_INNER_NODE_ORDER: u16 = 20; + const GENESIS_TICK_MAP_LEAF_NODE_ORDER: u16 = 12; const GENESIS_DEFAULT_POOL_FEE_RATE: u16 = 3_000; const GENESIS_DEFAULT_PROTOCOL_FEE_RATE: u16 = 0; @@ -124,6 +128,13 @@ module econia::core { market_registration_fee: u64, oracle_fee: u64, integrator_withdrawal_fee: u64, + book_map_node_orders: NewMarketNodeOrders, + tick_map_node_orders: NewMarketNodeOrders, + } + + struct NewMarketNodeOrders has copy, drop, store { + inner_node_order: u16, + leaf_node_order: u16, } struct Registry has key { @@ -346,6 +357,10 @@ module econia::core { market_registration_fee_option: vector, oracle_fee_option: vector, integrator_withdrawal_fee_option: vector, + book_map_inner_node_order_option: vector, + book_map_leaf_node_order_option: vector, + tick_map_inner_node_order_option: vector, + tick_map_leaf_node_order_option: vector, ) acquires Registry { assert_signer_is_econia(econia); let registry_parameters_ref_mut = &mut borrow_registry_mut().registry_parameters; @@ -365,6 +380,22 @@ module econia::core { &mut registry_parameters_ref_mut.integrator_withdrawal_fee, &integrator_withdrawal_fee_option, ); + set_value_via_option_vector( + &mut registry_parameters_ref_mut.book_map_node_orders.inner_node_order, + &book_map_inner_node_order_option, + ); + set_value_via_option_vector( + &mut registry_parameters_ref_mut.book_map_node_orders.leaf_node_order, + &book_map_leaf_node_order_option, + ); + set_value_via_option_vector( + &mut registry_parameters_ref_mut.tick_map_node_orders.inner_node_order, + &tick_map_inner_node_order_option, + ); + set_value_via_option_vector( + &mut registry_parameters_ref_mut.tick_map_node_orders.leaf_node_order, + &tick_map_leaf_node_order_option, + ); } public entry fun set_status(econia: &signer, active: bool) acquires Status { @@ -444,6 +475,14 @@ module econia::core { market_registration_fee: GENESIS_MARKET_REGISTRATION_FEE, oracle_fee: GENESIS_ORACLE_FEE, integrator_withdrawal_fee: GENESIS_INTEGRATOR_WITHDRAWAL_FEE, + book_map_node_orders: NewMarketNodeOrders { + inner_node_order: GENESIS_BOOK_MAP_INNER_NODE_ORDER, + leaf_node_order: GENESIS_BOOK_MAP_LEAF_NODE_ORDER, + }, + tick_map_node_orders: NewMarketNodeOrders { + inner_node_order: GENESIS_TICK_MAP_INNER_NODE_ORDER, + leaf_node_order: GENESIS_TICK_MAP_LEAF_NODE_ORDER, + }, }, default_market_parameters: MarketParameters { pool_fee_rate: GENESIS_DEFAULT_POOL_FEE_RATE, @@ -596,6 +635,10 @@ module econia::core { market_registration_fee: u64, oracle_fee: u64, integrator_withdrawal_fee: u64, + book_map_inner_node_order: u16, + book_map_leaf_node_order: u16, + tick_map_inner_node_order: u16, + tick_map_leaf_node_order: u16, ) { let utility_asset_metadata_address_to_check = object::object_address(®istry_parameters.utility_asset_metadata); @@ -603,6 +646,12 @@ module econia::core { assert!(registry_parameters.market_registration_fee == market_registration_fee, 0); assert!(registry_parameters.oracle_fee == oracle_fee, 0); assert!(registry_parameters.integrator_withdrawal_fee == integrator_withdrawal_fee, 0); + let node_orders = registry_parameters.book_map_node_orders; + assert!(node_orders.inner_node_order == book_map_inner_node_order, 0); + assert!(node_orders.leaf_node_order == book_map_leaf_node_order, 0); + node_orders = registry_parameters.tick_map_node_orders; + assert!(node_orders.inner_node_order == tick_map_inner_node_order, 0); + assert!(node_orders.leaf_node_order == tick_map_leaf_node_order, 0); } #[test_only] @@ -830,6 +879,10 @@ module econia::core { GENESIS_MARKET_REGISTRATION_FEE, GENESIS_ORACLE_FEE, GENESIS_INTEGRATOR_WITHDRAWAL_FEE, + GENESIS_BOOK_MAP_INNER_NODE_ORDER, + GENESIS_BOOK_MAP_LEAF_NODE_ORDER, + GENESIS_TICK_MAP_INNER_NODE_ORDER, + GENESIS_TICK_MAP_LEAF_NODE_ORDER, ); assert_market_parameters( registry_ref.default_market_parameters, @@ -962,13 +1015,27 @@ module econia::core { fun test_update_registry_parameters() acquires Registry { ensure_module_initialized_for_test(); let econia = get_signer(@econia); - update_registry_parameters(&econia, vector[], vector[], vector[], vector[]); + update_registry_parameters( + &econia, + vector[], + vector[], + vector[], + vector[], + vector[], + vector[], + vector[], + vector[], + ); assert_registry_parameters( borrow_registry().registry_parameters, GENESIS_UTILITY_ASSET_METADATA_ADDRESS, GENESIS_MARKET_REGISTRATION_FEE, GENESIS_ORACLE_FEE, GENESIS_INTEGRATOR_WITHDRAWAL_FEE, + GENESIS_BOOK_MAP_INNER_NODE_ORDER, + GENESIS_BOOK_MAP_LEAF_NODE_ORDER, + GENESIS_TICK_MAP_INNER_NODE_ORDER, + GENESIS_TICK_MAP_LEAF_NODE_ORDER, ); test_assets::ensure_assets_initialized(); let (new_metadata, _) = test_assets::get_metadata(); @@ -978,7 +1045,11 @@ module econia::core { vector[new_metadata_address], vector[1], vector[2], - vector[3] + vector[3], + vector[4], + vector[5], + vector[6], + vector[7], ); assert_registry_parameters( borrow_registry().registry_parameters, @@ -986,6 +1057,10 @@ module econia::core { 1, 2, 3, + 4, + 5, + 6, + 7 ); } From bce6631c7e24e247969454ee404fa3acefe4b1b4 Mon Sep 17 00:00:00 2001 From: alnoki <43892045+alnoki@users.noreply.github.com> Date: Mon, 11 Mar 2024 19:44:16 -0700 Subject: [PATCH 12/17] Index open orders by market ID, not trading pair --- src/move/econia/sources/core.move | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/move/econia/sources/core.move b/src/move/econia/sources/core.move index 7ccee3d..b08ac47 100644 --- a/src/move/econia/sources/core.move +++ b/src/move/econia/sources/core.move @@ -118,7 +118,7 @@ module econia::core { } struct OpenOrdersByMarket has key { - map: SmartTable, + map: SmartTable, } struct Null has drop, key, store {} @@ -229,12 +229,12 @@ module econia::core { if (!exists(user_address)) { move_to(user, OpenOrdersByMarket { map: smart_table::new() }); }; - let open_orders_map_ref_mut = &mut borrow_global_mut(user_address).map; - let trading_pair = TradingPair { base_metadata, quote_metadata }; - if (smart_table::contains(open_orders_map_ref_mut, trading_pair)) return; ensure_market_registered(user, base_metadata, quote_metadata); + let trading_pair = TradingPair { base_metadata, quote_metadata }; let (market_id, market_address) = get_market_id_and_address_for_registered_pair(trading_pair); + let open_orders_map_ref_mut = &mut borrow_global_mut(user_address).map; + if (smart_table::contains(open_orders_map_ref_mut, market_id)) return; let (constructor_ref, _) = create_nontransferable_sticky_object(user_address); let open_orders_address = object::address_from_constructor_ref(&constructor_ref); move_to(&object::generate_signer(&constructor_ref), OpenOrders { @@ -246,7 +246,7 @@ module econia::core { }); smart_table::add( open_orders_map_ref_mut, - trading_pair, + market_id, OpenOrdersMetadata { market_id, trading_pair, @@ -746,7 +746,7 @@ module econia::core { ensure_open_orders_registered(&get_signer(USER_FOR_TEST), base_metadata, quote_metadata); let open_orders_by_market_map_ref = &borrow_global(USER_FOR_TEST).map; let open_orders_metadata_ref = - smart_table::borrow(open_orders_by_market_map_ref, get_test_trading_pair()); + smart_table::borrow(open_orders_by_market_map_ref, MARKET_ID_FOR_TEST); let open_orders_address = open_orders_metadata_ref.open_orders_address; (market_address, open_orders_address) } @@ -968,7 +968,7 @@ module econia::core { let market_address = market_metadata.market_address; let open_orders_by_market_map_ref = &borrow_global(USER_FOR_TEST).map; let open_orders_metadata = - *smart_table::borrow(open_orders_by_market_map_ref, trading_pair); + *smart_table::borrow(open_orders_by_market_map_ref, MARKET_ID_FOR_TEST); assert!(open_orders_metadata.market_id == MARKET_ID_FOR_TEST, 0); assert!(open_orders_metadata.trading_pair == trading_pair, 0); assert!(open_orders_metadata.market_address == market_address, 0); From d8cfdbb97a96288a9b2e469387f26e95e52763d2 Mon Sep 17 00:00:00 2001 From: alnoki <43892045+alnoki@users.noreply.github.com> Date: Mon, 11 Mar 2024 20:13:21 -0700 Subject: [PATCH 13/17] Use rational number eviction parameters --- src/move/econia/sources/core.move | 129 ++++++++++++++++++++++-------- 1 file changed, 94 insertions(+), 35 deletions(-) diff --git a/src/move/econia/sources/core.move b/src/move/econia/sources/core.move index b08ac47..7901f30 100644 --- a/src/move/econia/sources/core.move +++ b/src/move/econia/sources/core.move @@ -32,9 +32,12 @@ module econia::core { const GENESIS_DEFAULT_PROTOCOL_FEE_RATE: u16 = 0; const GENESIS_DEFAULT_MAX_PRICE_SIG_FIGS: u8 = 4; const GENESIS_DEFAULT_EVICTION_TREE_HEIGHT: u8 = 5; - const GENESIS_DEFAULT_EVICTION_PRICE_DIVISOR_ASK: u128 = 100_000_000_000_000_000_000; - const GENESIS_DEFAULT_EVICTION_PRICE_DIVISOR_BID: u128 = 100_000_000_000_000_000_000; - const GENESIS_DEFAULT_EVICTION_LIQUIDITY_DIVISOR: u128 = 1_000_000_000_000_000_000_000_000; + const GENESIS_DEFAULT_EVICTION_PRICE_RATIO_ASK_NUMERATOR: u64 = 1; + const GENESIS_DEFAULT_EVICTION_PRICE_RATIO_ASK_DENOMINATOR: u64 = 3; + const GENESIS_DEFAULT_EVICTION_PRICE_RATIO_BID_NUMERATOR: u64 = 1; + const GENESIS_DEFAULT_EVICTION_PRICE_RATIO_BID_DENOMINATOR: u64 = 5; + const GENESIS_DEFAULT_EVICTION_LIQUIDITY_RATIO_NUMERATOR: u64 = 1; + const GENESIS_DEFAULT_EVICTION_LIQUIDITY_RATIO_DENOMINATOR: u64 = 100_000; const GENESIS_DEFAULT_INNER_NODE_ORDER: u8 = 10; const GENESIS_DEFAULT_LEAF_NODE_ORDER: u8 = 5; @@ -93,13 +96,18 @@ module econia::core { protocol_fee_rate: u16, max_price_sig_figs: u8, eviction_tree_height: u8, - eviction_price_divisor_ask: u128, - eviction_price_divisor_bid: u128, - eviction_liquidity_divisor: u128, + eviction_price_ratio_ask: Rational, + eviction_price_ratio_bid: Rational, + eviction_liquidity_ratio: Rational, inner_node_order: u8, leaf_node_order: u8, } + struct Rational has copy, drop, store { + numerator: u64, + denominator: u64, + } + #[resource_group_member(group = ObjectGroup)] struct OpenOrders has key { market_id: u64, @@ -264,9 +272,12 @@ module econia::core { protocol_fee_rate_option: vector, max_price_sig_figs_option: vector, eviction_tree_height_option: vector, - eviction_price_divisor_ask_option: vector, - eviction_price_divisor_bid_option: vector, - eviction_liquidity_divisor_option: vector, + eviction_price_ratio_ask_numerator_option: vector, + eviction_price_ratio_ask_denominator_option: vector, + eviction_price_ratio_bid_numerator_option: vector, + eviction_price_ratio_bid_denominator_option: vector, + eviction_liquidity_ratio_numerator_option: vector, + eviction_liquidity_ratio_denominator_option: vector, inner_node_order_option: vector, leaf_node_order_option: vector, ) acquires Market, Registry { @@ -304,16 +315,28 @@ module econia::core { &eviction_tree_height_option, ); set_value_via_option_vector( - &mut market_parameters_ref_mut.eviction_price_divisor_ask, - &eviction_price_divisor_ask_option, + &mut market_parameters_ref_mut.eviction_price_ratio_ask.numerator, + &eviction_price_ratio_ask_numerator_option, + ); + set_value_via_option_vector( + &mut market_parameters_ref_mut.eviction_price_ratio_ask.denominator, + &eviction_price_ratio_ask_denominator_option, + ); + set_value_via_option_vector( + &mut market_parameters_ref_mut.eviction_price_ratio_bid.numerator, + &eviction_price_ratio_bid_numerator_option, + ); + set_value_via_option_vector( + &mut market_parameters_ref_mut.eviction_price_ratio_bid.denominator, + &eviction_price_ratio_bid_denominator_option, ); set_value_via_option_vector( - &mut market_parameters_ref_mut.eviction_price_divisor_bid, - &eviction_price_divisor_bid_option, + &mut market_parameters_ref_mut.eviction_liquidity_ratio.numerator, + &eviction_liquidity_ratio_numerator_option, ); set_value_via_option_vector( - &mut market_parameters_ref_mut.eviction_liquidity_divisor, - &eviction_liquidity_divisor_option, + &mut market_parameters_ref_mut.eviction_liquidity_ratio.denominator, + &eviction_liquidity_ratio_denominator_option, ); set_value_via_option_vector( &mut market_parameters_ref_mut.inner_node_order, @@ -489,9 +512,18 @@ module econia::core { protocol_fee_rate: GENESIS_DEFAULT_PROTOCOL_FEE_RATE, max_price_sig_figs: GENESIS_DEFAULT_MAX_PRICE_SIG_FIGS, eviction_tree_height: GENESIS_DEFAULT_EVICTION_TREE_HEIGHT, - eviction_price_divisor_ask: GENESIS_DEFAULT_EVICTION_PRICE_DIVISOR_ASK, - eviction_price_divisor_bid: GENESIS_DEFAULT_EVICTION_PRICE_DIVISOR_BID, - eviction_liquidity_divisor: GENESIS_DEFAULT_EVICTION_LIQUIDITY_DIVISOR, + eviction_price_ratio_ask: Rational { + numerator: GENESIS_DEFAULT_EVICTION_PRICE_RATIO_ASK_NUMERATOR, + denominator: GENESIS_DEFAULT_EVICTION_PRICE_RATIO_ASK_DENOMINATOR, + }, + eviction_price_ratio_bid: Rational { + numerator: GENESIS_DEFAULT_EVICTION_PRICE_RATIO_BID_NUMERATOR, + denominator: GENESIS_DEFAULT_EVICTION_PRICE_RATIO_BID_DENOMINATOR, + }, + eviction_liquidity_ratio: Rational { + numerator: GENESIS_DEFAULT_EVICTION_LIQUIDITY_RATIO_NUMERATOR, + denominator: GENESIS_DEFAULT_EVICTION_LIQUIDITY_RATIO_DENOMINATOR, + }, inner_node_order: GENESIS_DEFAULT_INNER_NODE_ORDER, leaf_node_order: GENESIS_DEFAULT_LEAF_NODE_ORDER, }, @@ -573,9 +605,12 @@ module econia::core { protocol_fee_rate: u16, max_price_sig_figs: u8, eviction_tree_height: u8, - eviction_price_divisor_ask: u128, - eviction_price_divisor_bid: u128, - eviction_liquidity_divisor: u128, + eviction_price_ratio_ask_numerator: u64, + eviction_price_ratio_ask_denominator: u64, + eviction_price_ratio_bid_numerator: u64, + eviction_price_ratio_bid_denominator: u64, + eviction_liquidity_ratio_numerator: u64, + eviction_liquidity_ratio_denominator: u64, inner_node_order: u8, leaf_node_order: u8, ) { @@ -583,9 +618,15 @@ module econia::core { assert!(market_parameters.protocol_fee_rate == protocol_fee_rate, 0); assert!(market_parameters.max_price_sig_figs == max_price_sig_figs, 0); assert!(market_parameters.eviction_tree_height == eviction_tree_height, 0); - assert!(market_parameters.eviction_price_divisor_ask == eviction_price_divisor_ask, 0); - assert!(market_parameters.eviction_price_divisor_bid == eviction_price_divisor_bid, 0); - assert!(market_parameters.eviction_liquidity_divisor == eviction_liquidity_divisor, 0); + let ratio = market_parameters.eviction_price_ratio_ask; + assert!(ratio.numerator == eviction_price_ratio_ask_numerator, 0); + assert!(ratio.denominator == eviction_price_ratio_ask_denominator, 0); + ratio = market_parameters.eviction_price_ratio_bid; + assert!(ratio.numerator == eviction_price_ratio_bid_numerator, 0); + assert!(ratio.denominator == eviction_price_ratio_bid_denominator, 0); + ratio = market_parameters.eviction_liquidity_ratio; + assert!(ratio.numerator == eviction_liquidity_ratio_numerator, 0); + assert!(ratio.denominator == eviction_liquidity_ratio_denominator, 0); assert!(market_parameters.inner_node_order == inner_node_order, 0); assert!(market_parameters.leaf_node_order == leaf_node_order, 0); } @@ -890,9 +931,12 @@ module econia::core { GENESIS_DEFAULT_PROTOCOL_FEE_RATE, GENESIS_DEFAULT_MAX_PRICE_SIG_FIGS, GENESIS_DEFAULT_EVICTION_TREE_HEIGHT, - GENESIS_DEFAULT_EVICTION_PRICE_DIVISOR_ASK, - GENESIS_DEFAULT_EVICTION_PRICE_DIVISOR_BID, - GENESIS_DEFAULT_EVICTION_LIQUIDITY_DIVISOR, + GENESIS_DEFAULT_EVICTION_PRICE_RATIO_ASK_NUMERATOR, + GENESIS_DEFAULT_EVICTION_PRICE_RATIO_ASK_DENOMINATOR, + GENESIS_DEFAULT_EVICTION_PRICE_RATIO_BID_NUMERATOR, + GENESIS_DEFAULT_EVICTION_PRICE_RATIO_BID_DENOMINATOR, + GENESIS_DEFAULT_EVICTION_LIQUIDITY_RATIO_NUMERATOR, + GENESIS_DEFAULT_EVICTION_LIQUIDITY_RATIO_DENOMINATOR, GENESIS_DEFAULT_INNER_NODE_ORDER, GENESIS_DEFAULT_LEAF_NODE_ORDER, ); @@ -1074,6 +1118,9 @@ module econia::core { vector[2], vector[3], vector[4], + vector[5], + vector[6], + vector[], vector[], vector[], vector[], @@ -1092,10 +1139,13 @@ module econia::core { 2, 3, 4, - GENESIS_DEFAULT_EVICTION_TREE_HEIGHT, - GENESIS_DEFAULT_EVICTION_PRICE_DIVISOR_ASK, - GENESIS_DEFAULT_EVICTION_PRICE_DIVISOR_BID, - GENESIS_DEFAULT_EVICTION_LIQUIDITY_DIVISOR, + 5, + 6, + GENESIS_DEFAULT_EVICTION_PRICE_RATIO_ASK_DENOMINATOR, + GENESIS_DEFAULT_EVICTION_PRICE_RATIO_BID_NUMERATOR, + GENESIS_DEFAULT_EVICTION_PRICE_RATIO_BID_DENOMINATOR, + GENESIS_DEFAULT_EVICTION_LIQUIDITY_RATIO_NUMERATOR, + GENESIS_DEFAULT_EVICTION_LIQUIDITY_RATIO_DENOMINATOR, GENESIS_DEFAULT_INNER_NODE_ORDER, GENESIS_DEFAULT_LEAF_NODE_ORDER, ); @@ -1105,24 +1155,30 @@ module econia::core { vector[], vector[], vector[], - vector[5], - vector[6], + vector[], + vector[], vector[7], vector[8], vector[9], vector[10], + vector[11], + vector[12], + vector[13], ); assert_market_parameters( borrow_registry().default_market_parameters, GENESIS_DEFAULT_POOL_FEE_RATE, GENESIS_DEFAULT_PROTOCOL_FEE_RATE, GENESIS_DEFAULT_MAX_PRICE_SIG_FIGS, - 5, - 6, + GENESIS_DEFAULT_EVICTION_TREE_HEIGHT, + GENESIS_DEFAULT_EVICTION_PRICE_RATIO_ASK_NUMERATOR, 7, 8, 9, 10, + 11, + 12, + 13, ) } @@ -1141,6 +1197,9 @@ module econia::core { vector[], vector[], vector[], + vector[], + vector[], + vector[], ); } From 146ab078cc983c2d758e553b5cc282590fd7e95a Mon Sep 17 00:00:00 2001 From: alnoki <43892045+alnoki@users.noreply.github.com> Date: Mon, 11 Mar 2024 20:15:43 -0700 Subject: [PATCH 14/17] Remove inner node/leaf node order market params --- src/move/econia/sources/core.move | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/src/move/econia/sources/core.move b/src/move/econia/sources/core.move index 7901f30..c5c88a8 100644 --- a/src/move/econia/sources/core.move +++ b/src/move/econia/sources/core.move @@ -99,8 +99,6 @@ module econia::core { eviction_price_ratio_ask: Rational, eviction_price_ratio_bid: Rational, eviction_liquidity_ratio: Rational, - inner_node_order: u8, - leaf_node_order: u8, } struct Rational has copy, drop, store { @@ -278,8 +276,6 @@ module econia::core { eviction_price_ratio_bid_denominator_option: vector, eviction_liquidity_ratio_numerator_option: vector, eviction_liquidity_ratio_denominator_option: vector, - inner_node_order_option: vector, - leaf_node_order_option: vector, ) acquires Market, Registry { assert_signer_is_econia(econia); assert_option_vector_is_valid_length(&market_id_option); @@ -338,14 +334,6 @@ module econia::core { &mut market_parameters_ref_mut.eviction_liquidity_ratio.denominator, &eviction_liquidity_ratio_denominator_option, ); - set_value_via_option_vector( - &mut market_parameters_ref_mut.inner_node_order, - &inner_node_order_option, - ); - set_value_via_option_vector( - &mut market_parameters_ref_mut.leaf_node_order, - &leaf_node_order_option, - ); if (!updating_default_parameters) { borrow_global_mut(market_address).market_parameters = *market_parameters_ref_mut; @@ -524,8 +512,6 @@ module econia::core { numerator: GENESIS_DEFAULT_EVICTION_LIQUIDITY_RATIO_NUMERATOR, denominator: GENESIS_DEFAULT_EVICTION_LIQUIDITY_RATIO_DENOMINATOR, }, - inner_node_order: GENESIS_DEFAULT_INNER_NODE_ORDER, - leaf_node_order: GENESIS_DEFAULT_LEAF_NODE_ORDER, }, }); move_to(econia, Status { active: true }); @@ -611,8 +597,6 @@ module econia::core { eviction_price_ratio_bid_denominator: u64, eviction_liquidity_ratio_numerator: u64, eviction_liquidity_ratio_denominator: u64, - inner_node_order: u8, - leaf_node_order: u8, ) { assert!(market_parameters.pool_fee_rate == pool_fee_rate, 0); assert!(market_parameters.protocol_fee_rate == protocol_fee_rate, 0); @@ -627,8 +611,6 @@ module econia::core { ratio = market_parameters.eviction_liquidity_ratio; assert!(ratio.numerator == eviction_liquidity_ratio_numerator, 0); assert!(ratio.denominator == eviction_liquidity_ratio_denominator, 0); - assert!(market_parameters.inner_node_order == inner_node_order, 0); - assert!(market_parameters.leaf_node_order == leaf_node_order, 0); } #[test_only] @@ -937,8 +919,6 @@ module econia::core { GENESIS_DEFAULT_EVICTION_PRICE_RATIO_BID_DENOMINATOR, GENESIS_DEFAULT_EVICTION_LIQUIDITY_RATIO_NUMERATOR, GENESIS_DEFAULT_EVICTION_LIQUIDITY_RATIO_DENOMINATOR, - GENESIS_DEFAULT_INNER_NODE_ORDER, - GENESIS_DEFAULT_LEAF_NODE_ORDER, ); } @@ -1125,8 +1105,6 @@ module econia::core { vector[], vector[], vector[], - vector[], - vector[], ); let registry = borrow_registry(); let markets_ref = ®istry.markets; @@ -1146,8 +1124,6 @@ module econia::core { GENESIS_DEFAULT_EVICTION_PRICE_RATIO_BID_DENOMINATOR, GENESIS_DEFAULT_EVICTION_LIQUIDITY_RATIO_NUMERATOR, GENESIS_DEFAULT_EVICTION_LIQUIDITY_RATIO_DENOMINATOR, - GENESIS_DEFAULT_INNER_NODE_ORDER, - GENESIS_DEFAULT_LEAF_NODE_ORDER, ); update_market_parameters( &econia, @@ -1162,8 +1138,6 @@ module econia::core { vector[9], vector[10], vector[11], - vector[12], - vector[13], ); assert_market_parameters( borrow_registry().default_market_parameters, @@ -1177,8 +1151,6 @@ module econia::core { 9, 10, 11, - 12, - 13, ) } @@ -1198,8 +1170,6 @@ module econia::core { vector[], vector[], vector[], - vector[], - vector[], ); } From 3e2d6a524e57524999e5e25f13d9154305c5d3ca Mon Sep 17 00:00:00 2001 From: alnoki <43892045+alnoki@users.noreply.github.com> Date: Mon, 11 Mar 2024 20:38:46 -0700 Subject: [PATCH 15/17] Add rational helper funcs with constant linking --- src/move/econia/sources/core.move | 13 ++++++ src/move/econia/sources/rational.move | 58 +++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 src/move/econia/sources/rational.move diff --git a/src/move/econia/sources/core.move b/src/move/econia/sources/core.move index c5c88a8..3b60e32 100644 --- a/src/move/econia/sources/core.move +++ b/src/move/econia/sources/core.move @@ -18,6 +18,8 @@ module econia::core { use econia::test_assets; #[test_only] use std::features; + #[test_only] + use econia::rational; const GENESIS_UTILITY_ASSET_METADATA_ADDRESS: address = @aptos_fungible_asset; const GENESIS_MARKET_REGISTRATION_FEE: u64 = 100_000_000; @@ -41,6 +43,10 @@ module econia::core { const GENESIS_DEFAULT_INNER_NODE_ORDER: u8 = 10; const GENESIS_DEFAULT_LEAF_NODE_ORDER: u8 = 5; + const COMPARE_LEFT_GREATER: u8 = 0; + const COMPARE_RIGHT_GREATER: u8 = 1; + const COMPARE_EQUAL: u8 = 2; + /// Registrant's utility asset primary fungible store balance is below market registration fee. const E_NOT_ENOUGH_UTILITY_ASSET_TO_REGISTER_MARKET: u64 = 0; /// Signer is not Econia. @@ -814,6 +820,13 @@ module econia::core { assert_open_orders_owner(borrow_global(open_orders_address), @0x0); } + #[test] + fun test_common_constants_rational() { + assert!(COMPARE_EQUAL == rational::get_COMPARE_EQUAL(), 0); + assert!(COMPARE_LEFT_GREATER == rational::get_COMPARE_LEFT_GREATER(), 0); + assert!(COMPARE_RIGHT_GREATER == rational::get_COMPARE_RIGHT_GREATER(), 0); + } + #[test] fun test_open_orders_exists_and_correct_owner() acquires diff --git a/src/move/econia/sources/rational.move b/src/move/econia/sources/rational.move new file mode 100644 index 0000000..214c2f6 --- /dev/null +++ b/src/move/econia/sources/rational.move @@ -0,0 +1,58 @@ +module econia::rational { + + friend econia::core; + + const SHIFT_NUMERATOR: u8 = 64; + const HI_64_u128: u128 = 0xffffffffffffffff; + + const COMPARE_LEFT_GREATER: u8 = 0; + const COMPARE_RIGHT_GREATER: u8 = 1; + const COMPARE_EQUAL: u8 = 2; + + public(friend) inline fun encode(numerator: u64, denominator: u64): u128 { + (numerator as u128) << SHIFT_NUMERATOR | (denominator as u128) + } + + public(friend) inline fun decode(encoded: u128): (u64, u64) { + ((encoded >> SHIFT_NUMERATOR as u64), (encoded & HI_64_u128 as u64)) + } + + public(friend) inline fun compare_unchecked( + left_numerator: u64, + left_denominator: u64, + right_numerator: u64, + right_denominator: u64 + ): u8 { + let (a, b) = ( + (left_numerator as u128) * (right_denominator as u128), + (right_numerator as u128) * (left_denominator as u128), + ); + if (a > b) COMPARE_LEFT_GREATER else if (a < b) COMPARE_RIGHT_GREATER else COMPARE_EQUAL + } + + #[test_only] + public(friend) fun get_COMPARE_LEFT_GREATER(): u8 { COMPARE_LEFT_GREATER } + + #[test_only] + public(friend) fun get_COMPARE_RIGHT_GREATER(): u8 { COMPARE_RIGHT_GREATER } + + #[test_only] + public(friend) fun get_COMPARE_EQUAL(): u8 { COMPARE_EQUAL } + + #[test] + fun test_encode_decode() { + let numerator = 5; + let denominator = 64; + let encoded = encode(numerator, denominator); + let (numerator_decoded, denominator_decoded) = decode(encoded); + assert!(numerator == numerator_decoded, 0); + assert!(denominator == denominator_decoded, 0); + } + + #[test] + fun test_compare_unchecked() { + assert!(compare_unchecked(1, 5, 2, 10) == COMPARE_EQUAL, 0); + assert!(compare_unchecked(1, 4, 1, 5) == COMPARE_LEFT_GREATER, 0); + assert!(compare_unchecked(1, 5, 1, 4) == COMPARE_RIGHT_GREATER, 0); + } +} \ No newline at end of file From 875a555bbe829ffcac78dca268a96928f4838573 Mon Sep 17 00:00:00 2001 From: alnoki <43892045+alnoki@users.noreply.github.com> Date: Mon, 11 Mar 2024 20:40:57 -0700 Subject: [PATCH 16/17] Run pre-commit, fixing end-of-file newline --- src/move/econia/sources/rational.move | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/move/econia/sources/rational.move b/src/move/econia/sources/rational.move index 214c2f6..4a97d85 100644 --- a/src/move/econia/sources/rational.move +++ b/src/move/econia/sources/rational.move @@ -55,4 +55,4 @@ module econia::rational { assert!(compare_unchecked(1, 4, 1, 5) == COMPARE_LEFT_GREATER, 0); assert!(compare_unchecked(1, 5, 1, 4) == COMPARE_RIGHT_GREATER, 0); } -} \ No newline at end of file +} From 38f4d3ed9883d0f408e64915dcd4047356f36ed0 Mon Sep 17 00:00:00 2001 From: alnoki <43892045+alnoki@users.noreply.github.com> Date: Mon, 18 Mar 2024 16:40:05 -0700 Subject: [PATCH 17/17] Simplify public entry option args --- src/move/econia/sources/core.move | 249 ++++++++++++++---------------- 1 file changed, 117 insertions(+), 132 deletions(-) diff --git a/src/move/econia/sources/core.move b/src/move/econia/sources/core.move index 3b60e32..b029a4c 100644 --- a/src/move/econia/sources/core.move +++ b/src/move/econia/sources/core.move @@ -7,6 +7,7 @@ module econia::core { use aptos_framework::table_with_length::{Self, TableWithLength}; use aptos_framework::primary_fungible_store; use aptos_framework::smart_table::{Self, SmartTable}; + use std::option::{Self, Option}; use std::signer; use std::vector; @@ -53,8 +54,8 @@ module econia::core { const E_NOT_ECONIA: u64 = 1; /// Market ID is not valid. const E_INVALID_MARKET_ID: u64 = 2; - /// An option represented as a vector has more than 1 element. - const E_OPTION_VECTOR_TOO_LONG: u64 = 3; + /// The protocol is inactive. + const E_INACTIVE: u64 = 3; /// Base and quote metadata are identical. const E_BASE_QUOTE_METADATA_SAME: u64 = 4; /// Market is not fully collateralized with base asset. @@ -69,8 +70,6 @@ module econia::core { const E_WITHDRAWAL_EXCEEDS_EXPECTED_VAULT_BALANCE_BASE: u64 = 9; /// Requested withdrawal amount exceeds expected vault balance for quote. const E_WITHDRAWAL_EXCEEDS_EXPECTED_VAULT_BALANCE_QUOTE: u64 = 10; - /// The protocol is inactive. - const E_INACTIVE: u64 = 11; #[resource_group_member(group = ObjectGroup)] struct Market has key { @@ -271,26 +270,25 @@ module econia::core { public entry fun update_market_parameters( econia: &signer, - market_id_option: vector, - pool_fee_rate_option: vector, - protocol_fee_rate_option: vector, - max_price_sig_figs_option: vector, - eviction_tree_height_option: vector, - eviction_price_ratio_ask_numerator_option: vector, - eviction_price_ratio_ask_denominator_option: vector, - eviction_price_ratio_bid_numerator_option: vector, - eviction_price_ratio_bid_denominator_option: vector, - eviction_liquidity_ratio_numerator_option: vector, - eviction_liquidity_ratio_denominator_option: vector, + market_id_option: Option, + pool_fee_rate_option: Option, + protocol_fee_rate_option: Option, + max_price_sig_figs_option: Option, + eviction_tree_height_option: Option, + eviction_price_ratio_ask_numerator_option: Option, + eviction_price_ratio_ask_denominator_option: Option, + eviction_price_ratio_bid_numerator_option: Option, + eviction_price_ratio_bid_denominator_option: Option, + eviction_liquidity_ratio_numerator_option: Option, + eviction_liquidity_ratio_denominator_option: Option, ) acquires Market, Registry { assert_signer_is_econia(econia); - assert_option_vector_is_valid_length(&market_id_option); - let updating_default_parameters = vector::is_empty(&market_id_option); + let updating_default_parameters = option::is_none(&market_id_option); let registry_ref_mut = borrow_registry_mut(); let (market_parameters_ref_mut, market_address) = if (updating_default_parameters) { (&mut registry_ref_mut.default_market_parameters, @0x0) } else { - let market_id = *vector::borrow(&market_id_option, 0); + let market_id = option::destroy_some(market_id_option); let markets_ref_mut = &mut registry_ref_mut.markets; let market_exists = table_with_length::contains(markets_ref_mut, market_id); assert!(market_exists, E_INVALID_MARKET_ID); @@ -300,45 +298,45 @@ module econia::core { market_metadata_ref_mut.market_address, ) }; - set_value_via_option_vector( + set_value_via_option( &mut market_parameters_ref_mut.pool_fee_rate, - &pool_fee_rate_option, + pool_fee_rate_option, ); - set_value_via_option_vector( + set_value_via_option( &mut market_parameters_ref_mut.protocol_fee_rate, - &protocol_fee_rate_option, + protocol_fee_rate_option, ); - set_value_via_option_vector( + set_value_via_option( &mut market_parameters_ref_mut.max_price_sig_figs, - &max_price_sig_figs_option, + max_price_sig_figs_option, ); - set_value_via_option_vector( + set_value_via_option( &mut market_parameters_ref_mut.eviction_tree_height, - &eviction_tree_height_option, + eviction_tree_height_option, ); - set_value_via_option_vector( + set_value_via_option( &mut market_parameters_ref_mut.eviction_price_ratio_ask.numerator, - &eviction_price_ratio_ask_numerator_option, + eviction_price_ratio_ask_numerator_option, ); - set_value_via_option_vector( + set_value_via_option( &mut market_parameters_ref_mut.eviction_price_ratio_ask.denominator, - &eviction_price_ratio_ask_denominator_option, + eviction_price_ratio_ask_denominator_option, ); - set_value_via_option_vector( + set_value_via_option( &mut market_parameters_ref_mut.eviction_price_ratio_bid.numerator, - &eviction_price_ratio_bid_numerator_option, + eviction_price_ratio_bid_numerator_option, ); - set_value_via_option_vector( + set_value_via_option( &mut market_parameters_ref_mut.eviction_price_ratio_bid.denominator, - &eviction_price_ratio_bid_denominator_option, + eviction_price_ratio_bid_denominator_option, ); - set_value_via_option_vector( + set_value_via_option( &mut market_parameters_ref_mut.eviction_liquidity_ratio.numerator, - &eviction_liquidity_ratio_numerator_option, + eviction_liquidity_ratio_numerator_option, ); - set_value_via_option_vector( + set_value_via_option( &mut market_parameters_ref_mut.eviction_liquidity_ratio.denominator, - &eviction_liquidity_ratio_denominator_option, + eviction_liquidity_ratio_denominator_option, ); if (!updating_default_parameters) { borrow_global_mut(market_address).market_parameters = @@ -370,48 +368,48 @@ module econia::core { public entry fun update_registry_parameters( econia: &signer, - utility_asset_metadata_address_option: vector
, - market_registration_fee_option: vector, - oracle_fee_option: vector, - integrator_withdrawal_fee_option: vector, - book_map_inner_node_order_option: vector, - book_map_leaf_node_order_option: vector, - tick_map_inner_node_order_option: vector, - tick_map_leaf_node_order_option: vector, + utility_asset_metadata_address_option: Option
, + market_registration_fee_option: Option, + oracle_fee_option: Option, + integrator_withdrawal_fee_option: Option, + book_map_inner_node_order_option: Option, + book_map_leaf_node_order_option: Option, + tick_map_inner_node_order_option: Option, + tick_map_leaf_node_order_option: Option, ) acquires Registry { assert_signer_is_econia(econia); let registry_parameters_ref_mut = &mut borrow_registry_mut().registry_parameters; - set_object_via_address_option_vector( + set_object_via_address_option( &mut registry_parameters_ref_mut.utility_asset_metadata, - &utility_asset_metadata_address_option, + utility_asset_metadata_address_option, ); - set_value_via_option_vector( + set_value_via_option( &mut registry_parameters_ref_mut.market_registration_fee, - &market_registration_fee_option, + market_registration_fee_option, ); - set_value_via_option_vector( + set_value_via_option( &mut registry_parameters_ref_mut.oracle_fee, - &oracle_fee_option, + oracle_fee_option, ); - set_value_via_option_vector( + set_value_via_option( &mut registry_parameters_ref_mut.integrator_withdrawal_fee, - &integrator_withdrawal_fee_option, + integrator_withdrawal_fee_option, ); - set_value_via_option_vector( + set_value_via_option( &mut registry_parameters_ref_mut.book_map_node_orders.inner_node_order, - &book_map_inner_node_order_option, + book_map_inner_node_order_option, ); - set_value_via_option_vector( + set_value_via_option( &mut registry_parameters_ref_mut.book_map_node_orders.leaf_node_order, - &book_map_leaf_node_order_option, + book_map_leaf_node_order_option, ); - set_value_via_option_vector( + set_value_via_option( &mut registry_parameters_ref_mut.tick_map_node_orders.inner_node_order, - &tick_map_inner_node_order_option, + tick_map_inner_node_order_option, ); - set_value_via_option_vector( + set_value_via_option( &mut registry_parameters_ref_mut.tick_map_node_orders.leaf_node_order, - &tick_map_leaf_node_order_option, + tick_map_leaf_node_order_option, ); } @@ -527,29 +525,21 @@ module econia::core { assert!(signer::address_of(account) == @econia, E_NOT_ECONIA); } - fun assert_option_vector_is_valid_length(option_vector_ref: &vector) { - assert!(vector::length(option_vector_ref) <= 1, E_OPTION_VECTOR_TOO_LONG); - } - - fun set_value_via_option_vector( + fun set_value_via_option( value_ref_mut: &mut T, - option_vector_ref: &vector + option: Option ) { - assert_option_vector_is_valid_length(option_vector_ref); - if (!vector::is_empty(option_vector_ref)) { - *value_ref_mut = *vector::borrow(option_vector_ref, 0); + if (option::is_some(&option)) { + *value_ref_mut = option::destroy_some(option); } } - fun set_object_via_address_option_vector( + fun set_object_via_address_option( object_ref_mut: &mut Object, - address_option_vector_ref: &vector
+ address_option: Option
) { - assert_option_vector_is_valid_length(address_option_vector_ref); - if (!vector::is_empty(address_option_vector_ref)) { - *object_ref_mut = object::address_to_object( - *vector::borrow(address_option_vector_ref, 0) - ); + if (option::is_some(&address_option)) { + *object_ref_mut = object::address_to_object(option::destroy_some(address_option)); } } @@ -798,11 +788,6 @@ module econia::core { assert_signer_is_econia(&get_signer(@0x0)); } - #[test, expected_failure(abort_code = E_OPTION_VECTOR_TOO_LONG)] - fun test_assert_option_vector_is_valid_length_option_vector_too_long() { - assert_option_vector_is_valid_length(&vector[0, 0]); - } - #[test, expected_failure(abort_code = E_NO_OPEN_ORDERS)] fun test_open_orders_exists_no_open_orders() { assert_open_orders_exists(@0x0); @@ -1054,14 +1039,14 @@ module econia::core { let econia = get_signer(@econia); update_registry_parameters( &econia, - vector[], - vector[], - vector[], - vector[], - vector[], - vector[], - vector[], - vector[], + option::none(), + option::none(), + option::none(), + option::none(), + option::none(), + option::none(), + option::none(), + option::none(), ); assert_registry_parameters( borrow_registry().registry_parameters, @@ -1079,14 +1064,14 @@ module econia::core { let new_metadata_address = object::object_address(&new_metadata); update_registry_parameters( &econia, - vector[new_metadata_address], - vector[1], - vector[2], - vector[3], - vector[4], - vector[5], - vector[6], - vector[7], + option::some(new_metadata_address), + option::some(1), + option::some(2), + option::some(3), + option::some(4), + option::some(5), + option::some(6), + option::some(7), ); assert_registry_parameters( borrow_registry().registry_parameters, @@ -1107,17 +1092,17 @@ module econia::core { let econia = get_signer(@econia); update_market_parameters( &econia, - vector[1], - vector[2], - vector[3], - vector[4], - vector[5], - vector[6], - vector[], - vector[], - vector[], - vector[], - vector[], + option::some(1), + option::some(2), + option::some(3), + option::some(4), + option::some(5), + option::some(6), + option::none(), + option::none(), + option::none(), + option::none(), + option::none(), ); let registry = borrow_registry(); let markets_ref = ®istry.markets; @@ -1140,17 +1125,17 @@ module econia::core { ); update_market_parameters( &econia, - vector[], - vector[], - vector[], - vector[], - vector[], - vector[], - vector[7], - vector[8], - vector[9], - vector[10], - vector[11], + option::none(), + option::none(), + option::none(), + option::none(), + option::none(), + option::none(), + option::some(7), + option::some(8), + option::some(9), + option::some(10), + option::some(11), ); assert_market_parameters( borrow_registry().default_market_parameters, @@ -1172,17 +1157,17 @@ module econia::core { ensure_market_registered_for_test(); update_market_parameters( &get_signer(@econia), - vector[2], - vector[], - vector[], - vector[], - vector[], - vector[], - vector[], - vector[], - vector[], - vector[], - vector[], + option::some(2), + option::none(), + option::none(), + option::none(), + option::none(), + option::none(), + option::none(), + option::none(), + option::none(), + option::none(), + option::none(), ); }