From 8259c1838dd7728992fd3f83833d6488a399466a Mon Sep 17 00:00:00 2001 From: Ricardo Guilherme Schmidt <3esmit@gmail.com> Date: Fri, 10 Apr 2026 15:43:13 -0300 Subject: [PATCH] refactor(amm)!: derive pool active state from LP supply instead of explicit flag Remove the `active: bool` field from `PoolDefinition` and replace it with an implicit invariant: a pool is considered active when `liquidity_pool_supply >= MINIMUM_LIQUIDITY`. BREAKING CHANGE: `PoolDefinition` Borsh serialization format has changed. Existing on-chain pool accounts encoded with the `active` field are incompatible with this version. Closes #25 --- amm/core/src/lib.rs | 14 ++-- amm/methods/guest/src/bin/amm.rs | 2 +- amm/src/new_definition.rs | 17 ++--- amm/src/remove.rs | 6 +- amm/src/swap.rs | 9 ++- amm/src/sync.rs | 7 +- amm/src/tests.rs | 110 ++++++++++--------------------- integration_tests/tests/amm.rs | 68 +++++++++---------- 8 files changed, 96 insertions(+), 137 deletions(-) diff --git a/amm/core/src/lib.rs b/amm/core/src/lib.rs index 67783de..eab2db0 100644 --- a/amm/core/src/lib.rs +++ b/amm/core/src/lib.rs @@ -15,7 +15,7 @@ const LP_LOCK_HOLDING_PDA_SEED: [u8; 32] = [1; 32]; /// AMM Program Instruction. #[derive(Serialize, Deserialize)] pub enum Instruction { - /// Initializes a new Pool (or re-initializes an inactive Pool). + /// Initializes a new Pool (or re-initializes an existing zero-supply Pool). /// /// On initialization, `MINIMUM_LIQUIDITY` LP tokens are permanently locked /// in the LP-lock holding PDA; the caller receives `initial_lp - MINIMUM_LIQUIDITY`. @@ -104,7 +104,7 @@ pub enum Instruction { /// Sync pool reserves with current vault balances. /// /// Required accounts: - /// - AMM Pool (initialized, active) + /// - AMM Pool (initialized, with LP supply at or above minimum liquidity) /// - Vault Holding Account for Token A (initialized) /// - Vault Holding Account for Token B (initialized) SyncReserves, @@ -119,19 +119,13 @@ pub struct PoolDefinition { pub vault_a_id: AccountId, pub vault_b_id: AccountId, pub liquidity_pool_id: AccountId, + /// Total LP supply tracked by the pool. After initialization it includes the permanently + /// locked `MINIMUM_LIQUIDITY`; a zero supply means the pool is uninitialized pub liquidity_pool_supply: u128, pub reserve_a: u128, pub reserve_b: u128, /// Fee tier in basis points. pub fees: u128, - /// Indicates whether the pool is initialized for use. - /// `MINIMUM_LIQUIDITY` LP tokens are permanently locked at initialization - /// and cannot be removed, so `liquidity_pool_supply` will never drop below - /// `MINIMUM_LIQUIDITY` for pools created after the minimum-liquidity lock - /// was introduced. Reaching that floor does not by itself imply - /// `active = false`; pools may remain active with only the permanently - /// locked minimum liquidity remaining. - pub active: bool, } pub const FEE_BPS_DENOMINATOR: u128 = 10_000; diff --git a/amm/methods/guest/src/bin/amm.rs b/amm/methods/guest/src/bin/amm.rs index f761a68..5d7d618 100644 --- a/amm/methods/guest/src/bin/amm.rs +++ b/amm/methods/guest/src/bin/amm.rs @@ -15,7 +15,7 @@ mod amm { #[allow(unused_imports)] use super::*; - /// Initializes a new Pool (or re-initializes an inactive Pool). + /// Initializes a new Pool (or re-initializes an existing zero-supply Pool). #[instruction] pub fn new_definition( pool: AccountWithMetadata, diff --git a/amm/src/new_definition.rs b/amm/src/new_definition.rs index b2c27ec..b357dc1 100644 --- a/amm/src/new_definition.rs +++ b/amm/src/new_definition.rs @@ -73,7 +73,7 @@ pub fn new_definition( assert_supported_fee_tier(fees); // TODO: return here - // Verify that Pool Account is not active + // A pool can only be initialized from a fresh account state. let is_new_pool = pool.account == Account::default(); let pool_account_data = if is_new_pool { PoolDefinition::default() @@ -82,16 +82,10 @@ pub fn new_definition( .expect("AMM program expects a valid Pool account") }; - assert!( - !pool_account_data.active, - "Cannot initialize an active Pool Definition" + assert_eq!( + pool_account_data.liquidity_pool_supply, 0, + "Cannot initialize a Pool Definition with nonzero LP supply" ); - if !is_new_pool { - assert_eq!( - pool_account_data.liquidity_pool_supply, 0, - "New definition: inactive Pool Definition must have zero LP supply before reinitialization" - ); - } // LP Token minting calculation let initial_lp = token_a_amount @@ -117,11 +111,10 @@ pub fn new_definition( reserve_a: token_a_amount.into(), reserve_b: token_b_amount.into(), fees, - active: true, }; pool_post.data = Data::from(&pool_post_definition); - let pool_post: AccountPostState = if pool.account == Account::default() { + let pool_post: AccountPostState = if is_new_pool { AccountPostState::new_claimed(pool_post.clone()) } else { AccountPostState::new(pool_post.clone()) diff --git a/amm/src/remove.rs b/amm/src/remove.rs index ab1f7d8..951c639 100644 --- a/amm/src/remove.rs +++ b/amm/src/remove.rs @@ -29,7 +29,10 @@ pub fn remove_liquidity( .expect("Remove liquidity: AMM Program expects a valid Pool Definition Account"); assert_supported_fee_tier(pool_def_data.fees); - assert!(pool_def_data.active, "Pool is inactive"); + assert!( + pool_def_data.liquidity_pool_supply >= MINIMUM_LIQUIDITY, + "Pool liquidity supply is below minimum liquidity" + ); assert_eq!( pool_def_data.liquidity_pool_id, pool_definition_lp.account_id, "LP definition mismatch" @@ -135,7 +138,6 @@ pub fn remove_liquidity( .reserve_b .checked_sub(withdraw_amount_b) .expect("reserve_b - withdraw_amount_b underflows"), - active: true, ..pool_def_data.clone() }; diff --git a/amm/src/swap.rs b/amm/src/swap.rs index fe5c544..fefcd2c 100644 --- a/amm/src/swap.rs +++ b/amm/src/swap.rs @@ -1,11 +1,11 @@ -use amm_core::assert_supported_fee_tier; +use amm_core::{assert_supported_fee_tier, MINIMUM_LIQUIDITY}; pub use amm_core::{compute_liquidity_token_pda_seed, compute_vault_pda_seed, PoolDefinition}; use nssa_core::{ account::{AccountId, AccountWithMetadata, Data}, program::{AccountPostState, ChainedCall}, }; -/// Validates swap setup: checks pool is active, vaults match, and reserves are sufficient. +/// Validates swap setup: checks pool liquidity is ready, vaults match, and reserves are sufficient. fn validate_swap_setup( pool: &AccountWithMetadata, vault_a: &AccountWithMetadata, @@ -15,7 +15,10 @@ fn validate_swap_setup( .expect("AMM Program expects a valid Pool Definition Account"); assert_supported_fee_tier(pool_def_data.fees); - assert!(pool_def_data.active, "Pool is inactive"); + assert!( + pool_def_data.liquidity_pool_supply >= MINIMUM_LIQUIDITY, + "Pool liquidity supply is below minimum liquidity" + ); assert_eq!( vault_a.account_id, pool_def_data.vault_a_id, "Vault A was not provided" diff --git a/amm/src/sync.rs b/amm/src/sync.rs index 1a6e00a..957457e 100644 --- a/amm/src/sync.rs +++ b/amm/src/sync.rs @@ -1,4 +1,4 @@ -use amm_core::{read_vault_fungible_balances, PoolDefinition}; +use amm_core::{read_vault_fungible_balances, PoolDefinition, MINIMUM_LIQUIDITY}; use nssa_core::{ account::{AccountWithMetadata, Data}, program::{AccountPostState, ChainedCall}, @@ -12,7 +12,10 @@ pub fn sync_reserves( let pool_def_data = PoolDefinition::try_from(&pool.account.data) .expect("Sync reserves: AMM Program expects a valid Pool Definition Account"); - assert!(pool_def_data.active, "Pool is inactive"); + assert!( + pool_def_data.liquidity_pool_supply >= MINIMUM_LIQUIDITY, + "Pool liquidity supply is below minimum liquidity" + ); assert_eq!( vault_a.account_id, pool_def_data.vault_a_id, "Vault A was not provided" diff --git a/amm/src/tests.rs b/amm/src/tests.rs index 70b8434..dd9c3f9 100644 --- a/amm/src/tests.rs +++ b/amm/src/tests.rs @@ -875,7 +875,6 @@ impl AccountWithMetadataForTests { reserve_a: BalanceForTests::vault_a_reserve_init(), reserve_b: BalanceForTests::vault_b_reserve_init(), fees: BalanceForTests::fee_tier(), - active: true, }), nonce: Nonce(0), }, @@ -903,7 +902,6 @@ impl AccountWithMetadataForTests { reserve_a: 1_000, reserve_b: 500, fees: BalanceForTests::fee_tier(), - active: true, }), nonce: Nonce(0), }, @@ -927,7 +925,6 @@ impl AccountWithMetadataForTests { reserve_a: 0, reserve_b: BalanceForTests::vault_b_reserve_init(), fees: BalanceForTests::fee_tier(), - active: true, }), nonce: Nonce(0), }, @@ -951,7 +948,6 @@ impl AccountWithMetadataForTests { reserve_a: BalanceForTests::vault_a_reserve_init(), reserve_b: 0, fees: BalanceForTests::fee_tier(), - active: true, }), nonce: Nonce(0), }, @@ -975,7 +971,6 @@ impl AccountWithMetadataForTests { reserve_a: BalanceForTests::vault_a_reserve_low(), reserve_b: BalanceForTests::vault_b_reserve_high(), fees: BalanceForTests::fee_tier(), - active: true, }), nonce: Nonce(0), }, @@ -999,7 +994,6 @@ impl AccountWithMetadataForTests { reserve_a: BalanceForTests::vault_a_reserve_high(), reserve_b: BalanceForTests::vault_b_reserve_low(), fees: BalanceForTests::fee_tier(), - active: true, }), nonce: Nonce(0), }, @@ -1023,7 +1017,6 @@ impl AccountWithMetadataForTests { reserve_a: BalanceForTests::vault_a_swap_test_1(), reserve_b: BalanceForTests::vault_b_swap_test_1(), fees: BalanceForTests::fee_tier(), - active: true, }), nonce: Nonce(0), }, @@ -1047,7 +1040,6 @@ impl AccountWithMetadataForTests { reserve_a: BalanceForTests::vault_a_swap_test_2(), reserve_b: BalanceForTests::vault_b_swap_test_2(), fees: BalanceForTests::fee_tier(), - active: true, }), nonce: Nonce(0), }, @@ -1071,7 +1063,6 @@ impl AccountWithMetadataForTests { reserve_a: 1498_u128, reserve_b: 334_u128, fees: BalanceForTests::fee_tier(), - active: true, }), nonce: Nonce(0), }, @@ -1095,7 +1086,6 @@ impl AccountWithMetadataForTests { reserve_a: 715_u128, reserve_b: 700_u128, fees: BalanceForTests::fee_tier(), - active: true, }), nonce: Nonce(0), }, @@ -1119,7 +1109,6 @@ impl AccountWithMetadataForTests { reserve_a: BalanceForTests::vault_a_reserve_init(), reserve_b: BalanceForTests::vault_b_reserve_init(), fees: BalanceForTests::fee_tier(), - active: true, }), nonce: Nonce(0), }, @@ -1143,7 +1132,6 @@ impl AccountWithMetadataForTests { reserve_a: BalanceForTests::vault_a_add_successful(), reserve_b: BalanceForTests::vault_b_add_successful(), fees: BalanceForTests::fee_tier(), - active: true, }), nonce: Nonce(0), }, @@ -1167,7 +1155,6 @@ impl AccountWithMetadataForTests { reserve_a: BalanceForTests::vault_a_remove_successful(), reserve_b: BalanceForTests::vault_b_remove_successful(), fees: BalanceForTests::fee_tier(), - active: true, }), nonce: Nonce(0), }, @@ -1176,7 +1163,7 @@ impl AccountWithMetadataForTests { } } - fn pool_definition_inactive() -> AccountWithMetadata { + fn pool_definition_below_minimum_liquidity() -> AccountWithMetadata { AccountWithMetadata { account: Account { program_owner: ProgramId::default(), @@ -1187,11 +1174,10 @@ impl AccountWithMetadataForTests { vault_a_id: IdForTests::vault_a_id(), vault_b_id: IdForTests::vault_b_id(), liquidity_pool_id: IdForTests::token_lp_definition_id(), - liquidity_pool_supply: BalanceForTests::lp_supply_init(), + liquidity_pool_supply: MINIMUM_LIQUIDITY - 1, reserve_a: BalanceForTests::vault_a_reserve_init(), reserve_b: BalanceForTests::vault_b_reserve_init(), fees: BalanceForTests::fee_tier(), - active: false, }), nonce: Nonce(0), }, @@ -1200,7 +1186,7 @@ impl AccountWithMetadataForTests { } } - fn pool_definition_reinitializable() -> AccountWithMetadata { + fn pool_definition_zero_supply_reinitializable() -> AccountWithMetadata { AccountWithMetadata { account: Account { program_owner: ProgramId::default(), @@ -1215,7 +1201,6 @@ impl AccountWithMetadataForTests { reserve_a: 0, reserve_b: 0, fees: 0u128, - active: false, }), nonce: Nonce(0), }, @@ -1239,7 +1224,6 @@ impl AccountWithMetadataForTests { reserve_a: BalanceForTests::vault_a_reserve_init(), reserve_b: BalanceForTests::vault_b_reserve_init(), fees: BalanceForTests::fee_tier(), - active: false, }), nonce: Nonce(0), }, @@ -1280,30 +1264,6 @@ impl AccountWithMetadataForTests { } } - fn pool_definition_active() -> AccountWithMetadata { - AccountWithMetadata { - account: Account { - program_owner: ProgramId::default(), - balance: 0u128, - data: Data::from(&PoolDefinition { - definition_token_a_id: IdForTests::token_a_definition_id(), - definition_token_b_id: IdForTests::token_b_definition_id(), - vault_a_id: IdForTests::vault_a_id(), - vault_b_id: IdForTests::vault_b_id(), - liquidity_pool_id: IdForTests::token_lp_definition_id(), - liquidity_pool_supply: BalanceForTests::lp_supply_init(), - reserve_a: BalanceForTests::vault_a_reserve_init(), - reserve_b: BalanceForTests::vault_b_reserve_init(), - fees: BalanceForTests::fee_tier(), - active: true, - }), - nonce: Nonce(0), - }, - is_authorized: true, - account_id: IdForTests::pool_definition_id(), - } - } - /// Legacy/corrupted pool state whose reported supply has already been drained down to the /// permanent lock (liquidity_pool_supply == MINIMUM_LIQUIDITY). fn pool_definition_at_minimum_liquidity() -> AccountWithMetadata { @@ -1321,7 +1281,6 @@ impl AccountWithMetadataForTests { reserve_a: BalanceForTests::vault_a_reserve_init(), reserve_b: BalanceForTests::vault_b_reserve_init(), fees: BalanceForTests::fee_tier(), - active: true, }), nonce: Nonce(0), }, @@ -1944,11 +1903,11 @@ fn test_call_new_definition_wrong_vault_id_2() { ); } -#[should_panic(expected = "Cannot initialize an active Pool Definition")] +#[should_panic(expected = "Cannot initialize a Pool Definition with nonzero LP supply")] #[test] -fn test_call_new_definition_cannot_initialize_active_pool() { +fn test_call_new_definition_cannot_initialize_nonzero_supply_pool() { let _post_states = new_definition( - AccountWithMetadataForTests::pool_definition_active(), + AccountWithMetadataForTests::pool_definition_init(), AccountWithMetadataForTests::vault_a_init(), AccountWithMetadataForTests::vault_b_init(), AccountWithMetadataForTests::pool_lp_init(), @@ -1968,7 +1927,7 @@ fn test_call_new_definition_cannot_initialize_active_pool() { fn test_call_new_definition_initial_lp_too_small() { // isqrt(1000 * 1000) = 1000 == MINIMUM_LIQUIDITY, so the assertion fires. let _post_states = new_definition( - AccountWithMetadataForTests::pool_definition_reinitializable(), + AccountWithMetadataForTests::pool_definition_zero_supply_reinitializable(), AccountWithMetadataForTests::vault_a_init(), AccountWithMetadataForTests::vault_b_init(), AccountWithMetadataForTests::pool_lp_reinitializable(), @@ -1986,7 +1945,7 @@ fn test_call_new_definition_initial_lp_too_small() { #[test] fn test_call_new_definition_chained_call_successful() { let (post_states, chained_calls) = new_definition( - AccountWithMetadataForTests::pool_definition_reinitializable(), + AccountWithMetadataForTests::pool_definition_zero_supply_reinitializable(), AccountWithMetadataForTests::vault_a_init(), AccountWithMetadataForTests::vault_b_init(), AccountWithMetadataForTests::pool_lp_reinitializable(), @@ -2090,11 +2049,11 @@ fn test_call_swap_reserves_vault_mismatch_2() { ); } -#[should_panic(expected = "Pool is inactive")] +#[should_panic(expected = "Pool liquidity supply is below minimum liquidity")] #[test] -fn test_call_swap_ianctive() { +fn test_call_swap_below_minimum_liquidity() { let _post_states = swap_exact_input( - AccountWithMetadataForTests::pool_definition_inactive(), + AccountWithMetadataForTests::pool_definition_below_minimum_liquidity(), AccountWithMetadataForTests::vault_a_init(), AccountWithMetadataForTests::vault_b_init(), AccountWithMetadataForTests::user_holding_a(), @@ -2279,11 +2238,11 @@ fn call_swap_exact_output_reserves_vault_mismatch_2() { ); } -#[should_panic(expected = "Pool is inactive")] +#[should_panic(expected = "Pool liquidity supply is below minimum liquidity")] #[test] -fn call_swap_exact_output_inactive() { +fn call_swap_exact_output_below_minimum_liquidity() { let _post_states = swap_exact_output( - AccountWithMetadataForTests::pool_definition_inactive(), + AccountWithMetadataForTests::pool_definition_below_minimum_liquidity(), AccountWithMetadataForTests::vault_a_init(), AccountWithMetadataForTests::vault_b_init(), AccountWithMetadataForTests::user_holding_a(), @@ -2426,11 +2385,10 @@ fn swap_exact_output_overflow_protection() { vault_a_id: IdForTests::vault_a_id(), vault_b_id: IdForTests::vault_b_id(), liquidity_pool_id: IdForTests::token_lp_definition_id(), - liquidity_pool_supply: 1, + liquidity_pool_supply: MINIMUM_LIQUIDITY, reserve_a: large_reserve, reserve_b, fees: BalanceForTests::fee_tier(), - active: true, }), nonce: Nonce(0), }, @@ -2482,7 +2440,7 @@ fn swap_exact_output_overflow_protection() { #[test] fn test_new_definition_lp_asymmetric_amounts() { let (post_states, chained_calls) = new_definition( - AccountWithMetadataForTests::pool_definition_reinitializable(), + AccountWithMetadataForTests::pool_definition_zero_supply_reinitializable(), AccountWithMetadataForTests::vault_a_init(), AccountWithMetadataForTests::vault_b_init(), AccountWithMetadataForTests::pool_lp_reinitializable(), @@ -2519,7 +2477,7 @@ fn test_new_definition_lp_symmetric_amounts() { assert_eq!(expected_lp, 2_000); let (post_states, chained_calls) = new_definition( - AccountWithMetadataForTests::pool_definition_reinitializable(), + AccountWithMetadataForTests::pool_definition_zero_supply_reinitializable(), AccountWithMetadataForTests::vault_a_init(), AccountWithMetadataForTests::vault_b_init(), AccountWithMetadataForTests::pool_lp_reinitializable(), @@ -2574,13 +2532,11 @@ fn test_new_definition_lp_symmetric_amounts() { assert_eq!(chained_call_lp_user, expected_lp_user_call); } -#[should_panic( - expected = "New definition: inactive Pool Definition must have zero LP supply before reinitialization" -)] +#[should_panic(expected = "Cannot initialize a Pool Definition with nonzero LP supply")] #[test] fn test_call_new_definition_reinitialization_requires_zero_pool_supply() { let _post_states = new_definition( - AccountWithMetadataForTests::pool_definition_inactive(), + AccountWithMetadataForTests::pool_definition_init(), AccountWithMetadataForTests::vault_a_init(), AccountWithMetadataForTests::vault_b_init(), AccountWithMetadataForTests::pool_lp_reinitializable(), @@ -2601,7 +2557,7 @@ fn test_call_new_definition_reinitialization_requires_zero_pool_supply() { #[test] fn test_call_new_definition_reinitialization_requires_zero_lp_definition_supply() { let _post_states = new_definition( - AccountWithMetadataForTests::pool_definition_reinitializable(), + AccountWithMetadataForTests::pool_definition_zero_supply_reinitializable(), AccountWithMetadataForTests::vault_a_init(), AccountWithMetadataForTests::vault_b_init(), AccountWithMetadataForTests::pool_lp_init(), @@ -2702,7 +2658,6 @@ fn test_minimum_liquidity_lock_and_remove_all_user_lp() { assert_eq!(pool_after_remove.liquidity_pool_supply, MINIMUM_LIQUIDITY); assert!(pool_after_remove.reserve_a > 0); assert!(pool_after_remove.reserve_b > 0); - assert!(pool_after_remove.active); } #[test] @@ -2754,6 +2709,16 @@ fn test_sync_reserves_panics_when_vault_b_under_collateralized() { ); } +#[should_panic(expected = "Pool liquidity supply is below minimum liquidity")] +#[test] +fn test_sync_reserves_rejects_pool_below_minimum_liquidity() { + let _ = sync_reserves( + AccountWithMetadataForTests::pool_definition_below_minimum_liquidity(), + AccountWithMetadataForTests::vault_a_init(), + AccountWithMetadataForTests::vault_b_init(), + ); +} + #[test] fn test_donation_then_add_liquidity_sync_mitigates_mispricing() { let donation_a = 100u128; @@ -2822,7 +2787,7 @@ fn new_definition_overflow_protection() { let large_amount = u128::MAX / 2 + 1; let _result = new_definition( - AccountWithMetadataForTests::pool_definition_reinitializable(), + AccountWithMetadataForTests::pool_definition_zero_supply_reinitializable(), AccountWithMetadataForTests::vault_a_init(), AccountWithMetadataForTests::vault_b_init(), AccountWithMetadataForTests::pool_lp_reinitializable(), @@ -2853,11 +2818,10 @@ fn add_liquidity_overflow_protection() { vault_a_id: IdForTests::vault_a_id(), vault_b_id: IdForTests::vault_b_id(), liquidity_pool_id: IdForTests::token_lp_definition_id(), - liquidity_pool_supply: 1_000, + liquidity_pool_supply: MINIMUM_LIQUIDITY, reserve_a: large_reserve, reserve_b, fees: BalanceForTests::fee_tier(), - active: true, }), nonce: Nonce(0), }, @@ -2928,7 +2892,6 @@ fn remove_liquidity_overflow_protection() { reserve_a: large_reserve, reserve_b, fees: BalanceForTests::fee_tier(), - active: true, }), nonce: Nonce(0), }, @@ -3008,11 +2971,10 @@ fn swap_exact_input_overflow_protection() { vault_a_id: IdForTests::vault_a_id(), vault_b_id: IdForTests::vault_b_id(), liquidity_pool_id: IdForTests::token_lp_definition_id(), - liquidity_pool_supply: 1, + liquidity_pool_supply: MINIMUM_LIQUIDITY, reserve_a: 1_000, reserve_b: large_reserve, fees: BalanceForTests::fee_tier(), - active: true, }), nonce: Nonce(0), }, @@ -3071,7 +3033,7 @@ fn test_new_definition_supports_all_fee_tiers() { FEE_TIER_BPS_100, ] { let (post_states, _) = new_definition( - AccountWithMetadataForTests::pool_definition_reinitializable(), + AccountWithMetadataForTests::pool_definition_zero_supply_reinitializable(), AccountWithMetadataForTests::vault_a_init(), AccountWithMetadataForTests::vault_b_init(), AccountWithMetadataForTests::pool_lp_reinitializable(), @@ -3095,10 +3057,10 @@ fn test_new_definition_supports_all_fee_tiers() { #[test] fn test_new_definition_rejects_unsupported_fee_tier() { let _ = new_definition( - AccountWithMetadataForTests::pool_definition_inactive(), + AccountWithMetadataForTests::pool_definition_zero_supply_reinitializable(), AccountWithMetadataForTests::vault_a_init(), AccountWithMetadataForTests::vault_b_init(), - AccountWithMetadataForTests::pool_lp_init(), + AccountWithMetadataForTests::pool_lp_reinitializable(), AccountWithMetadataForTests::lp_lock_holding_uninit(), AccountWithMetadataForTests::user_holding_a(), AccountWithMetadataForTests::user_holding_b(), diff --git a/integration_tests/tests/amm.rs b/integration_tests/tests/amm.rs index b36da68..00d4128 100644 --- a/integration_tests/tests/amm.rs +++ b/integration_tests/tests/amm.rs @@ -300,7 +300,6 @@ impl Accounts { reserve_a: Balances::vault_a_init(), reserve_b: Balances::vault_b_init(), fees: Balances::fee_tier(), - active: true, }), nonce: Nonce(0), } @@ -409,7 +408,6 @@ impl Accounts { reserve_a: Balances::vault_a_swap_1(), reserve_b: Balances::vault_b_swap_1(), fees: Balances::fee_tier(), - active: true, }), nonce: Nonce(0), } @@ -477,7 +475,6 @@ impl Accounts { reserve_a: Balances::vault_a_swap_2(), reserve_b: Balances::vault_b_swap_2(), fees: Balances::fee_tier(), - active: true, }), nonce: Nonce(0), } @@ -545,7 +542,6 @@ impl Accounts { reserve_a: Balances::vault_a_add(), reserve_b: Balances::vault_b_add(), fees: Balances::fee_tier(), - active: true, }), nonce: Nonce(0), } @@ -638,7 +634,6 @@ impl Accounts { reserve_a: Balances::vault_a_remove(), reserve_b: Balances::vault_b_remove(), fees: Balances::fee_tier(), - active: true, }), nonce: Nonce(0), } @@ -717,7 +712,7 @@ impl Accounts { } } - fn token_lp_definition_init_inactive() -> Account { + fn token_lp_definition_reinitializable() -> Account { Account { program_owner: Ids::token_program(), balance: 0_u128, @@ -730,7 +725,7 @@ impl Accounts { } } - fn vault_a_init_inactive() -> Account { + fn vault_a_reinitializable() -> Account { Account { program_owner: Ids::token_program(), balance: 0_u128, @@ -742,7 +737,7 @@ impl Accounts { } } - fn vault_b_init_inactive() -> Account { + fn vault_b_reinitializable() -> Account { Account { program_owner: Ids::token_program(), balance: 0_u128, @@ -754,7 +749,7 @@ impl Accounts { } } - fn pool_definition_inactive() -> Account { + fn pool_definition_zero_supply_reinitializable() -> Account { Account { program_owner: Ids::amm_program(), balance: 0_u128, @@ -768,7 +763,6 @@ impl Accounts { reserve_a: 0, reserve_b: 0, fees: Balances::fee_tier(), - active: false, }), nonce: Nonce(0), } @@ -849,7 +843,6 @@ impl Accounts { reserve_a: Balances::vault_a_init(), reserve_b: Balances::vault_b_init(), fees: Balances::fee_tier(), - active: true, }), nonce: Nonce(0), } @@ -1056,14 +1049,17 @@ fn amm_remove_liquidity_insufficient_user_lp_fails() { } #[test] -fn amm_new_definition_inactive_initialized_pool_and_uninit_user_lp() { +fn amm_new_definition_zero_supply_initialized_pool_and_uninit_user_lp() { let mut state = state_for_amm_tests_with_new_def(); - state.force_insert_account(Ids::vault_a(), Accounts::vault_a_init_inactive()); - state.force_insert_account(Ids::vault_b(), Accounts::vault_b_init_inactive()); - state.force_insert_account(Ids::pool_definition(), Accounts::pool_definition_inactive()); + state.force_insert_account(Ids::vault_a(), Accounts::vault_a_reinitializable()); + state.force_insert_account(Ids::vault_b(), Accounts::vault_b_reinitializable()); + state.force_insert_account( + Ids::pool_definition(), + Accounts::pool_definition_zero_supply_reinitializable(), + ); state.force_insert_account( Ids::token_lp_definition(), - Accounts::token_lp_definition_init_inactive(), + Accounts::token_lp_definition_reinitializable(), ); execute_new_definition(&mut state, Balances::fee_tier()); @@ -1103,14 +1099,17 @@ fn amm_new_definition_inactive_initialized_pool_and_uninit_user_lp() { } #[test] -fn amm_new_definition_inactive_initialized_pool_init_user_lp() { +fn amm_new_definition_zero_supply_initialized_pool_init_user_lp() { let mut state = state_for_amm_tests_with_new_def(); - state.force_insert_account(Ids::vault_a(), Accounts::vault_a_init_inactive()); - state.force_insert_account(Ids::vault_b(), Accounts::vault_b_init_inactive()); - state.force_insert_account(Ids::pool_definition(), Accounts::pool_definition_inactive()); + state.force_insert_account(Ids::vault_a(), Accounts::vault_a_reinitializable()); + state.force_insert_account(Ids::vault_b(), Accounts::vault_b_reinitializable()); + state.force_insert_account( + Ids::pool_definition(), + Accounts::pool_definition_zero_supply_reinitializable(), + ); state.force_insert_account( Ids::token_lp_definition(), - Accounts::token_lp_definition_init_inactive(), + Accounts::token_lp_definition_reinitializable(), ); state.force_insert_account(Ids::user_lp(), Accounts::user_lp_holding_init_zero()); @@ -1153,8 +1152,8 @@ fn amm_new_definition_inactive_initialized_pool_init_user_lp() { #[test] fn amm_new_definition_uninitialized_pool() { let mut state = state_for_amm_tests_with_new_def(); - state.force_insert_account(Ids::vault_a(), Accounts::vault_a_init_inactive()); - state.force_insert_account(Ids::vault_b(), Accounts::vault_b_init_inactive()); + state.force_insert_account(Ids::vault_a(), Accounts::vault_a_reinitializable()); + state.force_insert_account(Ids::vault_b(), Accounts::vault_b_reinitializable()); execute_new_definition(&mut state, Balances::fee_tier()); @@ -1201,8 +1200,8 @@ fn amm_new_definition_supports_all_fee_tiers() { FEE_TIER_BPS_100, ] { let mut state = state_for_amm_tests_with_new_def(); - state.force_insert_account(Ids::vault_a(), Accounts::vault_a_init_inactive()); - state.force_insert_account(Ids::vault_b(), Accounts::vault_b_init_inactive()); + state.force_insert_account(Ids::vault_a(), Accounts::vault_a_reinitializable()); + state.force_insert_account(Ids::vault_b(), Accounts::vault_b_reinitializable()); execute_new_definition(&mut state, fees); @@ -1216,12 +1215,15 @@ fn amm_new_definition_supports_all_fee_tiers() { #[test] fn amm_new_definition_rejects_unsupported_fee_tier_transaction() { let mut state = state_for_amm_tests_with_new_def(); - state.force_insert_account(Ids::vault_a(), Accounts::vault_a_init_inactive()); - state.force_insert_account(Ids::vault_b(), Accounts::vault_b_init_inactive()); - state.force_insert_account(Ids::pool_definition(), Accounts::pool_definition_inactive()); + state.force_insert_account(Ids::vault_a(), Accounts::vault_a_reinitializable()); + state.force_insert_account(Ids::vault_b(), Accounts::vault_b_reinitializable()); + state.force_insert_account( + Ids::pool_definition(), + Accounts::pool_definition_zero_supply_reinitializable(), + ); state.force_insert_account( Ids::token_lp_definition(), - Accounts::token_lp_definition_init_inactive(), + Accounts::token_lp_definition_reinitializable(), ); state.force_insert_account(Ids::user_lp(), Accounts::user_lp_holding_init_zero()); @@ -1230,19 +1232,19 @@ fn amm_new_definition_rejects_unsupported_fee_tier_transaction() { assert!(matches!(result, Err(NssaError::ProgramExecutionFailed(_)))); assert_eq!( state.get_account_by_id(Ids::pool_definition()), - Accounts::pool_definition_inactive() + Accounts::pool_definition_zero_supply_reinitializable() ); assert_eq!( state.get_account_by_id(Ids::vault_a()), - Accounts::vault_a_init_inactive() + Accounts::vault_a_reinitializable() ); assert_eq!( state.get_account_by_id(Ids::vault_b()), - Accounts::vault_b_init_inactive() + Accounts::vault_b_reinitializable() ); assert_eq!( state.get_account_by_id(Ids::token_lp_definition()), - Accounts::token_lp_definition_init_inactive() + Accounts::token_lp_definition_reinitializable() ); assert_eq!( state.get_account_by_id(Ids::user_a()),