From ea27eeb9299a2e98f2709a9c3d2b753b389b3032 Mon Sep 17 00:00:00 2001 From: jonesmarvin8 <83104039+jonesmarvin8@users.noreply.github.com> Date: Sat, 6 Dec 2025 14:52:18 -0500 Subject: [PATCH] fixed add and remove logic, and tests --- nssa/program_methods/guest/Cargo.toml | 3 +- nssa/program_methods/guest/src/bin/amm.rs | 3431 ++++++++------------- nssa/src/state.rs | 1861 +++++------ 3 files changed, 2106 insertions(+), 3189 deletions(-) diff --git a/nssa/program_methods/guest/Cargo.toml b/nssa/program_methods/guest/Cargo.toml index 64f74b8..0861989 100644 --- a/nssa/program_methods/guest/Cargo.toml +++ b/nssa/program_methods/guest/Cargo.toml @@ -8,5 +8,4 @@ edition = "2024" [dependencies] risc0-zkvm = { version = "3.0.3", features = ['std'] } nssa-core = { path = "../../core" } -serde = { version = "1.0.219", default-features = false } -bytemuck = "1.24.0" \ No newline at end of file +serde = { version = "1.0.219", default-features = false } \ No newline at end of file diff --git a/nssa/program_methods/guest/src/bin/amm.rs b/nssa/program_methods/guest/src/bin/amm.rs index ec56670..f37623d 100644 --- a/nssa/program_methods/guest/src/bin/amm.rs +++ b/nssa/program_methods/guest/src/bin/amm.rs @@ -3,8 +3,7 @@ use nssa_core::{ program::{ProgramId, ProgramInput, ChainedCall, read_nssa_inputs, write_nssa_outputs_with_chained_call}, }; -use bytemuck; - +//TODO update comments // The AMM program has five functions (four directly accessible via instructions): // 1. New AMM definition. // Arguments to this function are: @@ -41,15 +40,23 @@ use bytemuck; // * reserve_amounts is the pool's reserves; used to compute the withdraw amount. // * Outputs the token transfers as a Vec and the withdraw amount. -const POOL_DEFINITION_DATA_SIZE: usize = 209; -const MAX_NUMBER_POOLS: usize = 32; +const POOL_DEFINITION_DATA_SIZE: usize = 225; +const MAX_NUMBER_POOLS: usize = 31; const AMM_DEFINITION_DATA_SIZE: usize = 1024; struct AMMDefinition { + name: [u8;32], pool_ids: Vec, } impl AMMDefinition { + fn new(name: &[u8;32]) -> Vec { + + let mut bytes = [0; AMM_DEFINITION_DATA_SIZE]; + bytes[0..32].copy_from_slice(name); + bytes.into() + } + fn into_data(self) -> Vec { let size_of_pool: usize = self.pool_ids.len(); @@ -72,9 +79,12 @@ impl AMMDefinition { let size_of_pool = data.len()/32; + let mut name: [u8;32] = [0;32]; + name.copy_from_slice(&data[0..32]); + let mut pool_ids = Vec::::new(); - for i in 0..size_of_pool { + for i in 1..size_of_pool+1 { pool_ids.push( AccountId::new(data[i*32..(i+1)*32].try_into().expect("Parse data: The AMM program must be provided a valid AccountIds")) ); @@ -85,6 +95,7 @@ impl AMMDefinition { } Some( Self{ + name, pool_ids }) } @@ -99,6 +110,7 @@ struct PoolDefinition{ liquidity_pool_supply: u128, reserve_a: u128, reserve_b: u128, + fees: u128, active: bool } @@ -113,7 +125,8 @@ impl PoolDefinition { bytes[160..176].copy_from_slice(&self.liquidity_pool_supply.to_le_bytes()); bytes[176..192].copy_from_slice(&self.reserve_a.to_le_bytes()); bytes[192..208].copy_from_slice(&self.reserve_b.to_le_bytes()); - bytes[208] = self.active as u8; + bytes[208..224].copy_from_slice(&self.fees.to_le_bytes()); + bytes[224] = self.active as u8; bytes.into() } @@ -129,8 +142,9 @@ impl PoolDefinition { let liquidity_pool_supply = u128::from_le_bytes(data[160..176].try_into().expect("Parse data: The AMM program must be provided a valid u128 for liquidity cap")); let reserve_a = u128::from_le_bytes(data[176..192].try_into().expect("Parse data: The AMM program must be provided a valid u128 for reserve A balance")); let reserve_b = u128::from_le_bytes(data[192..208].try_into().expect("Parse data: The AMM program must be provided a valid u128 for reserve B balance")); - - let active = match data[208] { + let fees = u128::from_le_bytes(data[208..224].try_into().expect("Parse data: The AMM program must be provided a valid u128 for fees")); + + let active = match data[224] { 0 => false, 1 => true, _ => panic!("Parse data: The AMM program must be provided a valid bool for active"), @@ -145,6 +159,7 @@ impl PoolDefinition { liquidity_pool_supply, reserve_a, reserve_b, + fees, active, }) } @@ -264,7 +279,7 @@ fn main() { token_program_id[6] = u32::from_le_bytes(instruction[57..61].try_into().expect("New definition: AMM Program expects valid u32")); token_program_id[7] = u32::from_le_bytes(instruction[61..65].try_into().expect("New definition: AMM Program expects valid u32")); - let (post_states, chained_call) = new_definition(&pre_states, + let (post_states, chained_call) = new_pool(&pre_states, &[balance_a, balance_b], token_program_id ); @@ -273,27 +288,24 @@ fn main() { } 1 => { let mut token_addr: [u8;32] = [0;32]; - token_addr[0..].copy_from_slice(&instruction[17..49]); + token_addr[0..].copy_from_slice(&instruction[33..65]); let token_addr = AccountId::new(token_addr); - let amount = u128::from_le_bytes(instruction[1..17].try_into().expect("Swap: AMM Program expects valid u128 for balance to move")); + let amount_in = u128::from_le_bytes(instruction[1..17].try_into().expect("Swap: AMM Program expects valid u128 for balance to move")); + let min_amount_out = u128::from_le_bytes(instruction[17..33].try_into().expect("Swap: AMM Program expects valid u128 for balance to move")); - let (post_states, chained_call) = swap(&pre_states, amount, token_addr); + let (post_states, chained_call) = swap(&pre_states, &[amount_in, min_amount_out], token_addr); write_nssa_outputs_with_chained_call(pre_states, post_states, chained_call); } 2 => { - - let balance_a = u128::from_le_bytes(instruction[1..17].try_into().expect("Add liquidity: AMM Program expects valid u128 for balance a")); - let balance_b = u128::from_le_bytes(instruction[17..33].try_into().expect("Add liquidity: AMM Program expects valid u128 for balance b")); - - let mut token_addr: [u8;32] = [0;32]; - token_addr[0..].copy_from_slice(&instruction[33..65]); - let token_addr = AccountId::new(token_addr); - + let min_amount_lp = u128::from_le_bytes(instruction[1..17].try_into().expect("Add liquidity: AMM Program expects valid u128 for min amount lp")); + let max_amount_a = u128::from_le_bytes(instruction[17..33].try_into().expect("Add liquidity: AMM Program expects valid u128 for max amount a")); + let max_amount_b = u128::from_le_bytes(instruction[33..49].try_into().expect("Add liquidity: AMM Program expects valid u128 for max amount b")); + let (post_states, chained_call) = add_liquidity(&pre_states, - &[balance_a, balance_b], token_addr.clone()); + &[min_amount_lp, max_amount_a, max_amount_b]); write_nssa_outputs_with_chained_call(pre_states, post_states, chained_call); } 3 => { @@ -310,16 +322,38 @@ fn main() { }; } -fn new_definition( +//TODO: test +//add access to +fn new_definition ( + pre_states: &[AccountWithMetadata], + name: &[u8;32], + ) -> Vec { + + if pre_states.len() != 1 { + panic!("Invalid number of input accounts"); + } + + let mut new_amm_post = pre_states[0].account.clone(); + + new_amm_post.data = AMMDefinition::new(name); + + vec![new_amm_post] +} + +//TODO: fix this +fn new_pool ( pre_states: &[AccountWithMetadata], balance_in: &[u128], token_program: ProgramId, ) -> (Vec, Vec) { + + //Pool accounts: pool itself, and its 2 vaults and LP token //2 accounts for funding tokens //initial funder's LP account - if pre_states.len() != 7 { + //TODO: update this test + if pre_states.len() != 8 { panic!("Invalid number of input accounts") } @@ -327,16 +361,22 @@ fn new_definition( panic!("Invalid number of balance") } - let pool = &pre_states[0]; - let vault_a = &pre_states[1]; - let vault_b = &pre_states[2]; - let pool_lp = &pre_states[3]; - let user_holding_a = &pre_states[4]; - let user_holding_b = &pre_states[5]; - let user_holding_lp = &pre_states[6]; + let amm = &pre_states[0]; + let pool = &pre_states[1]; + let vault_a = &pre_states[2]; + let vault_b = &pre_states[3]; + let pool_lp = &pre_states[4]; + let user_holding_a = &pre_states[5]; + let user_holding_b = &pre_states[6]; + let user_holding_lp = &pre_states[7]; - if pool.account != Account::default() || !pool.is_authorized { - panic!("Pool account is initiated or not authorized"); + if amm.account == Account::default() { + panic!("AMM is not initialized"); + } + + //TODO: ignore inactive for now. + if !pool.is_authorized { + panic!("Pool account is not authorized"); } // TODO: temporary band-aid to prevent vault's from being @@ -353,6 +393,7 @@ fn new_definition( panic!("Balances must be nonzero") } + // Verify token_a and token_b are different let definition_token_a_id = TokenHolding::parse(&user_holding_a.account.data).expect("New definition: AMM Program expects valid Token Holding account for Token A").definition_id; let definition_token_b_id = TokenHolding::parse(&user_holding_b.account.data).expect("New definition: AMM Program expects valid Token Holding account for Token B").definition_id; @@ -361,6 +402,17 @@ fn new_definition( panic!("Cannot set up a swap for a token with itself.") } + let amm_data = AMMDefinition::parse(&amm.account.data).expect("AMM program expects a valid AMM account definition"); +/* + for i in 0..MAX_NUMBER_POOLS { + if( + amm_d + ) + } +*/ +//pool data + + // 5. Update pool account let mut pool_post = Account::default(); let pool_post_definition = PoolDefinition { @@ -372,6 +424,7 @@ fn new_definition( liquidity_pool_supply: amount_a, reserve_a: amount_a, reserve_b: amount_b, + fees: 0u128, //TODO: we assume all fees are 0 for now. active: true, }; @@ -380,7 +433,7 @@ fn new_definition( let mut chained_call = Vec::new(); //Chain call for Token A (user_holding_a -> Vault_A) - let mut instruction: [u8;32] = [0; 32]; + let mut instruction: [u8;23] = [0; 23]; instruction[0] = 1; instruction[1..17].copy_from_slice(&amount_a.to_le_bytes()); let instruction_data = risc0_zkvm::serde::to_vec(&instruction).expect("New definition: AMM Program expects valid instruction_data"); @@ -429,7 +482,7 @@ fn new_definition( fn swap( pre_states: &[AccountWithMetadata], - amount: u128, + amounts: &[u128], token_id: AccountId, ) -> (Vec, Vec) { @@ -437,6 +490,13 @@ fn swap( panic!("Invalid number of input accounts"); } + if amounts.len() != 2 { + panic!("Invalid number of amounts provided"); + } + + let amount_in = amounts[0]; + let min_amount_out = amounts[1]; + let pool = &pre_states[0]; let vault_a = &pre_states[1]; let vault_b = &pre_states[2]; @@ -459,26 +519,29 @@ fn swap( } // fetch pool reserves - //validates reserves is at least the vaults' balances - assert!(TokenHolding::parse(&vault_a.account.data).expect("Swap: AMM Program expects a valid Token Holding Account for Vault A").balance >= pool_def_data.reserve_a); - assert!(TokenHolding::parse(&vault_b.account.data).expect("Swap: AMM Program expects a valid Token Holding Account for Vault B").balance >= pool_def_data.reserve_b); - //Cannot swap if a reserve is 0 - assert!(pool_def_data.reserve_a > 0); - assert!(pool_def_data.reserve_b > 0); + // validates reserves is at least the vaults' balances + if TokenHolding::parse(&vault_a.account.data).expect("Swap: AMM Program expects a valid Token Holding Account for Vault A").balance < pool_def_data.reserve_a { + panic!("Reserve for Token A exceeds vault balance"); + } + if TokenHolding::parse(&vault_b.account.data).expect("Swap: AMM Program expects a valid Token Holding Account for Vault B").balance < pool_def_data.reserve_b { + panic!("Reserve for Token B exceeds vault balance"); + } let (chained_call, [deposit_a, withdraw_a], [deposit_b, withdraw_b]) = if token_id == pool_def_data.definition_token_a_id { let (chained_call, withdraw_b) = swap_logic(&[user_holding_a.clone(), vault_a.clone(), vault_b.clone(), user_holding_b.clone()], - amount, - &[pool_def_data.reserve_a, pool_def_data.reserve_b]); + amount_in, + &[pool_def_data.reserve_a, pool_def_data.reserve_b], + min_amount_out); - (chained_call, [amount, 0], [0, withdraw_b]) + (chained_call, [amount_in, 0], [0, withdraw_b]) } else if token_id == pool_def_data.definition_token_b_id { let (chained_call, withdraw_a) = swap_logic(&[user_holding_b.clone(), vault_b.clone(), vault_a.clone(), user_holding_a.clone()], - amount, - &[pool_def_data.reserve_b, pool_def_data.reserve_a]); + amount_in, + &[pool_def_data.reserve_b, pool_def_data.reserve_a], + min_amount_out); - (chained_call, [0, withdraw_a], [amount, 0]) + (chained_call, [0, withdraw_a], [amount_in, 0]) } else { panic!("AccountId is not a token type for the pool"); }; @@ -494,6 +557,7 @@ fn swap( liquidity_pool_supply: pool_def_data.liquidity_pool_supply.clone(), reserve_a: pool_def_data.reserve_a + deposit_a - withdraw_a, reserve_b: pool_def_data.reserve_b + deposit_b - withdraw_b, + fees: 0u128, active: true, }; @@ -513,6 +577,7 @@ fn swap_logic( pre_states: &[AccountWithMetadata], deposit_amount: u128, reserve_amounts: &[u128], + min_amount_out: u128, ) -> (Vec, u128) { @@ -530,10 +595,15 @@ fn swap_logic( let withdraw_amount = (reserve_withdraw_vault_amount * deposit_amount)/(reserve_deposit_vault_amount + deposit_amount); //Slippage check - assert!(withdraw_amount != 0); + if min_amount_out > withdraw_amount { + panic!("Withdraw amount is less than minimal amount out"); + } + + if withdraw_amount == 0 { + panic!("Withdraw amount should be nonzero"); + } let mut chained_call = Vec::new(); - let mut instruction_data = [0;23]; instruction_data[0] = 1; instruction_data[1..17].copy_from_slice(&deposit_amount.to_le_bytes()); @@ -562,19 +632,16 @@ fn swap_logic( } fn add_liquidity(pre_states: &[AccountWithMetadata], - max_balance_in: &[u128], - main_token: AccountId) -> (Vec, Vec) { + balances: &[u128]) -> (Vec, Vec) { if pre_states.len() != 7 { panic!("Invalid number of input accounts"); } - //TODO: add logic for re-initialized - let pool = &pre_states[0]; let vault_a = &pre_states[1]; let vault_b = &pre_states[2]; - let pool_lp = &pre_states[3]; + let pool_definition_lp = &pre_states[3]; let user_holding_a = &pre_states[4]; let user_holding_b = &pre_states[5]; let user_holding_lp = &pre_states[6]; @@ -585,57 +652,52 @@ fn add_liquidity(pre_states: &[AccountWithMetadata], panic!("Vault A was not provided"); } + // TODO: need to check this one + if pool_def_data.liquidity_pool_id != pool_definition_lp.account_id { + panic!("LP definition mismatch"); + } + if vault_b.account_id != pool_def_data.vault_b_addr { panic!("Vault B was not provided"); } - if max_balance_in.len() != 2 { + if balances.len() != 3 { panic!("Invalid number of input balances"); } - let max_amount_a = max_balance_in[0]; - let max_amount_b = max_balance_in[1]; + + let min_amount_lp = balances[0]; + let max_amount_a = balances[1]; + let max_amount_b = balances[2]; if max_amount_a == 0 || max_amount_b == 0 { panic!("Both max-balances must be nonzero"); } + + if min_amount_lp == 0 { + panic!("Min-lp must be nonzero"); + } // 2. Determine deposit amount let vault_b_balance = TokenHolding::parse(&vault_b.account.data).expect("Add liquidity: AMM Program expects valid Token Holding Account for Vault B").balance; let vault_a_balance = TokenHolding::parse(&vault_a.account.data).expect("Add liquidity: AMM Program expects valid Token Holding Account for Vault A").balance; - if vault_a_balance == 0 || vault_b_balance == 0 { - panic!("Vaults must have nonzero balances"); - } - + if pool_def_data.reserve_a == 0 || pool_def_data.reserve_b == 0 { panic!("Reserves must be nonzero"); } - //Calculate actual_amounts - let actual_amount_a = if main_token == pool_def_data.definition_token_a_id { - max_amount_a - } else if main_token == pool_def_data.definition_token_b_id { - (pool_def_data.reserve_a*max_amount_b)/pool_def_data.reserve_b - } else { - panic!("Mismatch of token types"); //main token does not match with vaults. - }; - - let actual_amount_b = if main_token == pool_def_data.definition_token_a_id { - (pool_def_data.reserve_b*max_amount_a)/pool_def_data.reserve_a - } else if main_token == pool_def_data.definition_token_b_id { - max_amount_b - } else { - panic!("Mismatch of token types"); //main token does not match with vaults. - }; - - // 3. Validate amounts - let user_holding_a_balance = TokenHolding::parse(&user_holding_a.account.data).expect("Add liquidity: AMM Program expects a valid Token Holding Account for User A").balance; - let user_holding_b_balance = TokenHolding::parse(&user_holding_b.account.data).expect("Add liquidity: AMM Program expects a valid Token Holding Account for User B").balance; - assert!(max_amount_a >= actual_amount_a && max_amount_b >= actual_amount_b); - if user_holding_a_balance < actual_amount_a { - panic!("Insufficient balance"); + if vault_a_balance < pool_def_data.reserve_a || vault_b_balance < pool_def_data.reserve_b { + panic!("Vaults' balances must be at least the reserve amounts"); } - if user_holding_b_balance < actual_amount_b { - panic!("Insufficient balance"); + // Calculate actual_amounts + let ideal_a: u128 = (pool_def_data.reserve_a*max_amount_b)/pool_def_data.reserve_b; + let ideal_b: u128 = (pool_def_data.reserve_b*max_amount_a)/pool_def_data.reserve_a; + + let actual_amount_a = if ideal_a > max_amount_a { max_amount_a } else { ideal_a }; + let actual_amount_b = if ideal_b > max_amount_b { max_amount_b } else { ideal_b }; + + // 3. Validate amounts + if max_amount_a < actual_amount_a || max_amount_b < actual_amount_b { + panic!("Actual trade amounts cannot exceed max_amounts"); } if actual_amount_a == 0 || actual_amount_b == 0 { @@ -643,8 +705,17 @@ fn add_liquidity(pre_states: &[AccountWithMetadata], } // 4. Calculate LP to mint - let delta_lp = (pool_def_data.liquidity_pool_supply * actual_amount_b)/pool_def_data.reserve_b; + let delta_lp = std::cmp::min(pool_def_data.liquidity_pool_supply * actual_amount_a/pool_def_data.reserve_a, + pool_def_data.liquidity_pool_supply * actual_amount_b/pool_def_data.reserve_b); + if delta_lp == 0 { + panic!("Payable LP must be nonzero"); + } + + if delta_lp < min_amount_lp { + panic!("Payable LP is less than provided minimum LP amount"); + } + // 5. Update pool account let mut pool_post = pool.account.clone(); let pool_post_definition = PoolDefinition { @@ -656,6 +727,7 @@ fn add_liquidity(pre_states: &[AccountWithMetadata], liquidity_pool_supply: pool_def_data.liquidity_pool_supply + delta_lp, reserve_a: pool_def_data.reserve_a + actual_amount_a, reserve_b: pool_def_data.reserve_b + actual_amount_b, + fees: 0u128, active: true, }; @@ -684,15 +756,15 @@ fn add_liquidity(pre_states: &[AccountWithMetadata], pre_states: vec![user_holding_b.clone(), vault_b.clone()] }; - // Chain call for LP (user_holding_lp -> Pool_LP) + // Chain call for LP (mint new tokens for user_holding_lp) let mut instruction_data = [0; 23]; - instruction_data[0] = 1; + instruction_data[0] = 4; instruction_data[1..17].copy_from_slice(&delta_lp.to_le_bytes()); let instruction_data = risc0_zkvm::serde::to_vec(&instruction_data).expect("Add liquidity: AMM Program expects valid token transfer instruction data"); let call_token_lp = ChainedCall{ - program_id: pool_lp.account.program_owner, + program_id: pool_definition_lp.account.program_owner, instruction_data: instruction_data, - pre_states: vec![pool_lp.clone(), user_holding_lp.clone()] + pre_states: vec![pool_definition_lp.clone(), user_holding_lp.clone()] }; @@ -724,7 +796,7 @@ fn remove_liquidity(pre_states: &[AccountWithMetadata], let pool = &pre_states[0]; let vault_a = &pre_states[1]; let vault_b = &pre_states[2]; - let pool_lp = &pre_states[3]; + let pool_definition_lp = &pre_states[3]; let user_holding_a = &pre_states[4]; let user_holding_b = &pre_states[5]; let user_holding_lp = &pre_states[6]; @@ -744,6 +816,12 @@ fn remove_liquidity(pre_states: &[AccountWithMetadata], panic!("Pool is inactive"); } + // TODO: need to check this one + if pool_def_data.liquidity_pool_id != pool_definition_lp.account_id { + panic!("LP definition mismatch"); + } + + if vault_a.account_id != pool_def_data.vault_a_addr { panic!("Vault A was not provided"); } @@ -752,6 +830,14 @@ fn remove_liquidity(pre_states: &[AccountWithMetadata], panic!("Vault B was not provided"); } + if amount_min_a == 0 || amount_min_b == 0 { + panic!("Minimum withdraw amount must be nonzero"); + } + + if amount_lp == 0 { + panic!("Liquidity amount must be nonzero"); + } + // 2. Compute withdrawal amounts let user_holding_lp_data = TokenHolding::parse(&user_holding_lp.account.data).expect("Remove liquidity: AMM Program expects a valid Token Account for liquidity token"); @@ -759,12 +845,8 @@ fn remove_liquidity(pre_states: &[AccountWithMetadata], panic!("Invalid liquidity account provided"); } - if user_holding_lp_data.balance < amount_lp { - panic!("Invalid liquidity amount provided"); - } - - let withdraw_amount_a = pool_def_data.reserve_a * (amount_lp/pool_def_data.liquidity_pool_supply); - let withdraw_amount_b = pool_def_data.reserve_b * (amount_lp/pool_def_data.liquidity_pool_supply); + let withdraw_amount_a = (pool_def_data.reserve_a * amount_lp)/pool_def_data.liquidity_pool_supply; + let withdraw_amount_b = (pool_def_data.reserve_b * amount_lp)/pool_def_data.liquidity_pool_supply; // 3. Validate and slippage check if withdraw_amount_a < amount_min_a { @@ -777,6 +859,8 @@ fn remove_liquidity(pre_states: &[AccountWithMetadata], // 4. Calculate LP to reduce cap by let delta_lp : u128 = (pool_def_data.liquidity_pool_supply*amount_lp)/pool_def_data.liquidity_pool_supply; + let active: bool = if pool_def_data.liquidity_pool_supply - delta_lp == 0 { false } else { true }; + // 5. Update pool account let mut pool_post = pool.account.clone(); let pool_post_definition = PoolDefinition { @@ -788,18 +872,16 @@ fn remove_liquidity(pre_states: &[AccountWithMetadata], liquidity_pool_supply: pool_def_data.liquidity_pool_supply - delta_lp, reserve_a: pool_def_data.reserve_a - withdraw_amount_a, reserve_b: pool_def_data.reserve_b - withdraw_amount_b, - active: true, + fees: 0u128, + active, }; pool_post.data = pool_post_definition.into_data(); let mut chained_call = Vec::new(); - let mut instruction_data = [0; 23]; - instruction_data[0] = 1; - //Chaincall for Token A withdraw - let mut instruction: [u8;32] = [0; 32]; + let mut instruction: [u8;23] = [0; 23]; instruction[0] = 1; instruction[1..17].copy_from_slice(&withdraw_amount_a.to_le_bytes()); let instruction_data = risc0_zkvm::serde::to_vec(&instruction).expect("Remove liquidity: AMM Program expects valid token transfer instruction data"); @@ -810,7 +892,7 @@ fn remove_liquidity(pre_states: &[AccountWithMetadata], }; //Chaincall for Token B withdraw - let mut instruction: [u8;32] = [0; 32]; + let mut instruction: [u8;23] = [0; 23]; instruction[0] = 1; instruction[1..17].copy_from_slice(&withdraw_amount_b.to_le_bytes()); let instruction_data = risc0_zkvm::serde::to_vec(&instruction).expect("Remove liquidity: AMM Program expects valid token transfer instruction data"); @@ -820,25 +902,24 @@ fn remove_liquidity(pre_states: &[AccountWithMetadata], pre_states: vec![vault_b.clone(), user_holding_b.clone()] }; - //TODO: make this a call for burn once implemented in - // Token Program //Chaincall for LP adjustment - let mut instruction: [u8;32] = [0; 32]; - instruction[0] = 1; + let mut instruction: [u8;23] = [0; 23]; + instruction[0] = 3; instruction[1..17].copy_from_slice(&delta_lp.to_le_bytes()); let instruction_data = risc0_zkvm::serde::to_vec(&instruction).expect("Remove liquidity: AMM Program expects valid token transfer instruction data"); let call_token_lp = ChainedCall{ - program_id: pool_lp.account.program_owner, + program_id: pool_definition_lp.account.program_owner, instruction_data: instruction_data, - pre_states: vec![user_holding_lp.clone(), pool_lp.clone()] + pre_states: vec![pool_definition_lp.clone(), user_holding_lp.clone()] }; chained_call.push(call_token_lp); chained_call.push(call_token_b); chained_call.push(call_token_a); - + let post_states = vec! - [pool_post.clone(), + [ + pool_post.clone(), pre_states[1].account.clone(), pre_states[2].account.clone(), pre_states[3].account.clone(), @@ -851,10 +932,9 @@ fn remove_liquidity(pre_states: &[AccountWithMetadata], #[cfg(test)] mod tests { - use nssa_core::{{account::{Account, AccountId, AccountWithMetadata, Data}, program::ChainedCall}, program::ProgramId}; - - use crate::{PoolDefinition, TOKEN_HOLDING_TYPE, TokenHolding, add_liquidity, new_definition, remove_liquidity, swap}; + use nssa_core::{{account::{Account, AccountId, AccountWithMetadata}, program::ChainedCall}, program::ProgramId}; + use crate::{PoolDefinition, TokenDefinition, TokenHolding, add_liquidity, new_pool, remove_liquidity, swap}; const TOKEN_PROGRAM_ID: ProgramId = [15;8]; @@ -865,45 +945,104 @@ mod tests { vault_b_uninit, vault_a_init, vault_b_init, + vault_a_init_high, + vault_b_init_high, + vault_a_init_low, + vault_b_init_low, + vault_a_init_zero, + vault_b_init_zero, vault_a_wrong_acc_id, vault_b_wrong_acc_id, pool_lp_uninit, pool_lp_init, - pool_lp_wrong_acc_id, + pool_lp_wrong_acc_id, //TODO use? user_holding_lp_uninit, user_holding_lp_init, pool_definition_uninit, pool_definition_init, + pool_definition_init_reserve_a_zero, + pool_definition_init_reserve_b_zero, + pool_definition_init_reserve_a_low, + pool_definition_init_reserve_b_low, pool_definition_unauth, + pool_definition_swap_test_1, + pool_definition_swap_test_2, + pool_definition_add_zero_lp, + pool_definition_add_successful, + pool_definition_remove_successful, } enum BalanceEnum { vault_a_reserve_init, vault_b_reserve_init, + vault_a_reserve_low, + vault_b_reserve_low, + vault_a_reserve_high, + vault_b_reserve_high, user_token_a_bal, user_token_b_bal, user_token_lp_bal, remove_min_amount_a, remove_min_amount_b, + remove_actual_a_successful, + remove_min_amount_b_low, + remove_min_amount_a_low, //TODO use? remove_amount_lp, - remove_amount_lp_too_large, - add_amount_a, - add_amount_b, + remove_amount_lp_1, + add_max_amount_a_low, + add_max_amount_b_low, + add_max_amount_b_high, //TODO use? + add_max_amount_a, + add_max_amount_b, + add_min_amount_lp, + vault_a_swap_test_1, + vault_a_swap_test_2, + vault_b_swap_test_1, + vault_b_swap_test_2, + min_amount_out, + vault_a_add_successful, + vault_b_add_successful, + add_successful_amount_a_lp, + add_successful_amount_b, + vault_a_remove_successful, + vault_b_remove_successful, } fn helper_balance_constructor(selection: BalanceEnum) -> u128 { match selection { - BalanceEnum::vault_a_reserve_init => 1000, - BalanceEnum::vault_b_reserve_init => 250, - BalanceEnum::user_token_a_bal => 1000, + BalanceEnum::vault_a_reserve_init => 1_000, + BalanceEnum::vault_b_reserve_init => 500, + BalanceEnum::vault_a_reserve_low => 10, + BalanceEnum::vault_b_reserve_low => 10, + BalanceEnum::vault_a_reserve_high => 500_000, + BalanceEnum::vault_b_reserve_high => 500_000, + BalanceEnum::user_token_a_bal => 1_000, BalanceEnum::user_token_b_bal => 500, BalanceEnum::user_token_lp_bal => 100, BalanceEnum::remove_min_amount_a => 50, - BalanceEnum::remove_min_amount_b => 50, - BalanceEnum::remove_amount_lp => 50, - BalanceEnum::remove_amount_lp_too_large => 150, - BalanceEnum::add_amount_a => 500, - BalanceEnum::add_amount_b => 200, + BalanceEnum::remove_min_amount_b => 100, + BalanceEnum::remove_actual_a_successful => 100, + BalanceEnum::remove_min_amount_b_low => 50, + BalanceEnum::remove_min_amount_a_low => 10, + BalanceEnum::remove_amount_lp => 100, + BalanceEnum::remove_amount_lp_1 => 30, + BalanceEnum::add_max_amount_a => 500, + BalanceEnum::add_max_amount_b => 200, + BalanceEnum::add_max_amount_b_high => 20_000, + BalanceEnum::add_max_amount_a_low => 10, + BalanceEnum::add_max_amount_b_low => 10, + BalanceEnum::add_min_amount_lp => 20, + BalanceEnum::vault_a_swap_test_1 => 1_500, + BalanceEnum::vault_a_swap_test_2 => 715, + BalanceEnum::vault_b_swap_test_1 => 334, + BalanceEnum::vault_b_swap_test_2 => 700, + BalanceEnum::min_amount_out => 200, + BalanceEnum::vault_a_add_successful => 1_400, + BalanceEnum::vault_b_add_successful => 700, + BalanceEnum::add_successful_amount_a_lp => 400, + BalanceEnum::add_successful_amount_b => 200, + BalanceEnum::vault_a_remove_successful => 900, + BalanceEnum::vault_b_remove_successful => 450, _ => panic!("Invalid selection") } } @@ -921,6 +1060,226 @@ mod tests { pool_lp_id, } + enum ChainedCallsEnum { + cc_token_a_initialization, + cc_token_b_initialization, + cc_pool_lp_initialization, + cc_swap_token_a_test_1, + cc_swap_token_b_test_1, + cc_swap_token_a_test_2, + cc_swap_token_b_test_2, + cc_add_token_a, + cc_add_token_b, + cc_add_pool_lp, + cc_remove_token_a, + cc_remove_token_b, + cc_remove_pool_lp, + } + + fn helper_chained_call_constructor(selection: ChainedCallsEnum) -> ChainedCall { + match selection { + ChainedCallsEnum::cc_token_a_initialization => { + let mut instruction: [u8;23] = [0; 23]; + instruction[0] = 1; + instruction[1..17].copy_from_slice( + &helper_balance_constructor(BalanceEnum::user_token_a_bal) + .to_le_bytes()); + let instruction_data = risc0_zkvm::serde::to_vec(&instruction).expect("AMM Program expects valid transaction instruction data"); + ChainedCall{ + program_id: TOKEN_PROGRAM_ID, + instruction_data, + pre_states: vec![ + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::vault_a_uninit)], + } + } + ChainedCallsEnum::cc_token_b_initialization => { + let mut instruction: [u8;23] = [0; 23]; + instruction[0] = 1; + instruction[1..17].copy_from_slice( + &helper_balance_constructor(BalanceEnum::user_token_b_bal) + .to_le_bytes()); + let instruction_data = risc0_zkvm::serde::to_vec(&instruction).expect("AMM Program expects valid transaction instruction data"); + ChainedCall{ + program_id: TOKEN_PROGRAM_ID, + instruction_data, + pre_states: vec![ + helper_account_constructor(AccountEnum::user_holding_b), + helper_account_constructor(AccountEnum::vault_b_uninit)], + } + } + ChainedCallsEnum::cc_pool_lp_initialization => { + let mut instruction: [u8;23] = [0; 23]; + instruction[0] = 1; + instruction[1..17].copy_from_slice( + &helper_balance_constructor(BalanceEnum::user_token_a_bal) + .to_le_bytes()); + let instruction_data = risc0_zkvm::serde::to_vec(&instruction).expect("AMM Program expects valid transaction instruction data"); + ChainedCall{ + program_id: TOKEN_PROGRAM_ID, + instruction_data, + pre_states: vec![ + helper_account_constructor(AccountEnum::pool_lp_uninit), + helper_account_constructor(AccountEnum::user_holding_lp_uninit)], + } + } + ChainedCallsEnum::cc_swap_token_a_test_1 => { + let mut instruction_data: [u8;23] = [0; 23]; + instruction_data[0] = 1; + instruction_data[1..17].copy_from_slice( + &helper_balance_constructor(BalanceEnum::add_max_amount_a) + .to_le_bytes()); + let instruction_data = risc0_zkvm::serde::to_vec(&instruction_data).expect("AMM Program expects valid transaction instruction data"); + ChainedCall{ + program_id: TOKEN_PROGRAM_ID, + instruction_data, + pre_states: vec![ + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::vault_a_init)], + } + } + ChainedCallsEnum::cc_swap_token_b_test_1 => { + let swap_amount: u128 = 166; + let mut instruction: [u8;23] = [0; 23]; + instruction[0] = 1; + instruction[1..17].copy_from_slice( + &swap_amount + .to_le_bytes()); + let instruction_data = risc0_zkvm::serde::to_vec(&instruction).expect("AMM Program expects valid transaction instruction data"); + ChainedCall{ + program_id: TOKEN_PROGRAM_ID, + instruction_data, + pre_states: vec![ + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::user_holding_b)], + } + } + ChainedCallsEnum::cc_swap_token_a_test_2 => { + let swap_amount: u128 = 285; + let mut instruction_data: [u8;23] = [0; 23]; + instruction_data[0] = 1; + instruction_data[1..17].copy_from_slice( + &swap_amount + .to_le_bytes()); + let instruction_data = risc0_zkvm::serde::to_vec(&instruction_data).expect("AMM Program expects valid transaction instruction data"); + ChainedCall{ + program_id: TOKEN_PROGRAM_ID, + instruction_data, + pre_states: vec![ + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::user_holding_a)], + } + } + ChainedCallsEnum::cc_swap_token_b_test_2 => { + let mut instruction: [u8;23] = [0; 23]; + instruction[0] = 1; + instruction[1..17].copy_from_slice( + &helper_balance_constructor(BalanceEnum::add_max_amount_b) + .to_le_bytes()); + let instruction_data = risc0_zkvm::serde::to_vec(&instruction).expect("AMM Program expects valid transaction instruction data"); + ChainedCall{ + program_id: TOKEN_PROGRAM_ID, + instruction_data, + pre_states: vec![ + helper_account_constructor(AccountEnum::user_holding_b), + helper_account_constructor(AccountEnum::vault_b_init)], + } + } + ChainedCallsEnum::cc_add_token_a => { + let mut instruction: [u8;23] = [0; 23]; + instruction[0] = 1; + instruction[1..17].copy_from_slice( + &helper_balance_constructor(BalanceEnum::add_successful_amount_a_lp) + .to_le_bytes()); + let instruction_data = risc0_zkvm::serde::to_vec(&instruction).expect("AMM Program expects valid transaction instruction data"); + ChainedCall{ + program_id: TOKEN_PROGRAM_ID, + instruction_data, + pre_states: vec![ + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::vault_a_init)], + } + } + ChainedCallsEnum::cc_add_token_b => { + let mut instruction: [u8;23] = [0; 23]; + instruction[0] = 1; + instruction[1..17].copy_from_slice( + &helper_balance_constructor(BalanceEnum::add_successful_amount_b) + .to_le_bytes()); + let instruction_data = risc0_zkvm::serde::to_vec(&instruction).expect("Swap Logic: AMM Program expects valid transaction instruction data"); + ChainedCall{ + program_id: TOKEN_PROGRAM_ID, + instruction_data, + pre_states: vec![ + helper_account_constructor(AccountEnum::user_holding_b), + helper_account_constructor(AccountEnum::vault_b_init)], + } + } + ChainedCallsEnum::cc_add_pool_lp => { + let mut instruction: [u8;23] = [0; 23]; + instruction[0] = 4; + instruction[1..17].copy_from_slice( + &helper_balance_constructor(BalanceEnum::add_successful_amount_a_lp) + .to_le_bytes()); + let instruction_data = risc0_zkvm::serde::to_vec(&instruction).expect("Swap Logic: AMM Program expects valid transaction instruction data"); + ChainedCall{ + program_id: TOKEN_PROGRAM_ID, + instruction_data, + pre_states: vec![ + helper_account_constructor(AccountEnum::pool_lp_init), + helper_account_constructor(AccountEnum::user_holding_lp_init)], + } + } + ChainedCallsEnum::cc_remove_token_a => { + let mut instruction: [u8;23] = [0; 23]; + instruction[0] = 1; + instruction[1..17].copy_from_slice( + &helper_balance_constructor(BalanceEnum::remove_actual_a_successful) + .to_le_bytes()); + let instruction_data = risc0_zkvm::serde::to_vec(&instruction).expect("AMM Program expects valid transaction instruction data"); + ChainedCall{ + program_id: TOKEN_PROGRAM_ID, + instruction_data, + pre_states: vec![ + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::user_holding_a),], + } + } + ChainedCallsEnum::cc_remove_token_b => { + let mut instruction: [u8;23] = [0; 23]; + instruction[0] = 1; + instruction[1..17].copy_from_slice( + &helper_balance_constructor(BalanceEnum::remove_min_amount_b_low) + .to_le_bytes()); + let instruction_data = risc0_zkvm::serde::to_vec(&instruction).expect("AMM Program expects valid transaction instruction data"); + ChainedCall{ + program_id: TOKEN_PROGRAM_ID, + instruction_data, + pre_states: vec![ + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::user_holding_b),], + } + } + ChainedCallsEnum::cc_remove_pool_lp => { + let mut instruction: [u8;23] = [0; 23]; + instruction[0] = 3; + instruction[1..17].copy_from_slice( + &helper_balance_constructor(BalanceEnum::remove_actual_a_successful) + .to_le_bytes()); + let instruction_data = risc0_zkvm::serde::to_vec(&instruction).expect("AMM Program expects valid transaction instruction data"); + ChainedCall{ + program_id: TOKEN_PROGRAM_ID, + instruction_data, + pre_states: vec![ + helper_account_constructor(AccountEnum::user_holding_lp_init), + helper_account_constructor(AccountEnum::pool_lp_init),], + } + } + + _ => panic!("Invalid selection") + } + } + fn helper_id_constructor(selection: IdEnum) -> AccountId { match selection { @@ -939,7 +1298,6 @@ mod tests { } fn helper_account_constructor(selection: AccountEnum) -> AccountWithMetadata { - let amm_program_id: ProgramId = [16;8]; match selection { AccountEnum::user_holding_a => AccountWithMetadata { @@ -1032,6 +1390,96 @@ mod tests { is_authorized: true, account_id: helper_id_constructor(IdEnum::vault_b_id), }, + AccountEnum::vault_a_init_high => AccountWithMetadata { + account: Account { + program_owner: TOKEN_PROGRAM_ID, + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_a_definition_id), + balance: helper_balance_constructor(BalanceEnum::vault_a_reserve_high), + }), + nonce: 0, + }, + is_authorized: true, + account_id: helper_id_constructor(IdEnum::vault_a_id), + }, + AccountEnum::vault_b_init_high => AccountWithMetadata { + account: Account { + program_owner: TOKEN_PROGRAM_ID, + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_b_definition_id), + balance: helper_balance_constructor(BalanceEnum::vault_b_reserve_high), + }), + nonce: 0, + }, + is_authorized: true, + account_id: helper_id_constructor(IdEnum::vault_b_id), + }, + AccountEnum::vault_a_init_low => AccountWithMetadata { + account: Account { + program_owner: TOKEN_PROGRAM_ID, + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_a_definition_id), + balance: helper_balance_constructor(BalanceEnum::vault_a_reserve_low), + }), + nonce: 0, + }, + is_authorized: true, + account_id: helper_id_constructor(IdEnum::vault_a_id), + }, + AccountEnum::vault_b_init_low => AccountWithMetadata { + account: Account { + program_owner: TOKEN_PROGRAM_ID, + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_b_definition_id), + balance: helper_balance_constructor(BalanceEnum::vault_b_reserve_low), + }), + nonce: 0, + }, + is_authorized: true, + account_id: helper_id_constructor(IdEnum::vault_b_id), + }, + AccountEnum::vault_a_init_zero => AccountWithMetadata { + account: Account { + program_owner: TOKEN_PROGRAM_ID, + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_a_definition_id), + balance: 0, + }), + nonce: 0, + }, + is_authorized: true, + account_id: helper_id_constructor(IdEnum::vault_a_id), + }, + AccountEnum::vault_b_init_zero => AccountWithMetadata { + account: Account { + program_owner: TOKEN_PROGRAM_ID, + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_b_definition_id), + balance: 0, + }), + nonce: 0, + }, + is_authorized: true, + account_id: helper_id_constructor(IdEnum::vault_b_id), + }, AccountEnum::vault_a_wrong_acc_id => AccountWithMetadata { account: Account { program_owner: TOKEN_PROGRAM_ID, @@ -1066,41 +1514,41 @@ mod tests { account: Account { program_owner: TOKEN_PROGRAM_ID, balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: 1u8, - definition_id: helper_id_constructor(IdEnum::token_lp_definition_id), - balance: 0, + data: TokenDefinition::into_data( + TokenDefinition{ + account_type: 0u8, + name: [1;6], + total_supply: 0u128, }), nonce: 0, }, is_authorized: true, - account_id: helper_id_constructor(IdEnum::pool_lp_id), + account_id: helper_id_constructor(IdEnum::token_lp_definition_id), }, AccountEnum::pool_lp_init => AccountWithMetadata { account: Account { program_owner: TOKEN_PROGRAM_ID, balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: 1u8, - definition_id: helper_id_constructor(IdEnum::token_lp_definition_id), - balance: helper_balance_constructor(BalanceEnum::vault_a_reserve_init), + data: TokenDefinition::into_data( + TokenDefinition{ + account_type: 0u8, + name: [1;6], + total_supply: helper_balance_constructor(BalanceEnum::vault_a_reserve_init), }), nonce: 0, }, is_authorized: true, - account_id: helper_id_constructor(IdEnum::pool_lp_id), + account_id: helper_id_constructor(IdEnum::token_lp_definition_id), }, AccountEnum::pool_lp_wrong_acc_id => AccountWithMetadata { - account: Account { + account: Account { program_owner: TOKEN_PROGRAM_ID, balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: 1u8, - definition_id: helper_id_constructor(IdEnum::token_lp_definition_id), - balance: helper_balance_constructor(BalanceEnum::vault_a_reserve_init), + data: TokenDefinition::into_data( + TokenDefinition{ + account_type: 0u8, + name: [1;6], + total_supply: helper_balance_constructor(BalanceEnum::vault_a_reserve_init), }), nonce: 0, }, @@ -1144,7 +1592,7 @@ mod tests { }, AccountEnum::pool_definition_init => AccountWithMetadata { account: Account { - program_owner: amm_program_id, + program_owner: ProgramId::default(), balance: 0u128, data: PoolDefinition::into_data( PoolDefinition { @@ -1156,6 +1604,95 @@ mod tests { liquidity_pool_supply: helper_balance_constructor(BalanceEnum::vault_a_reserve_init), reserve_a: helper_balance_constructor(BalanceEnum::vault_a_reserve_init), reserve_b: helper_balance_constructor(BalanceEnum::vault_b_reserve_init), + fees: 0u128, + active: true, + }), + nonce: 0, + }, + is_authorized: true, + account_id: helper_id_constructor(IdEnum::pool_definition_id), + }, + AccountEnum::pool_definition_init_reserve_a_zero => AccountWithMetadata { + account: Account { + program_owner: ProgramId::default(), + balance: 0u128, + data: PoolDefinition::into_data( + PoolDefinition { + definition_token_a_id: helper_id_constructor(IdEnum::token_a_definition_id), + definition_token_b_id: helper_id_constructor(IdEnum::token_b_definition_id), + vault_a_addr: helper_id_constructor(IdEnum::vault_a_id), + vault_b_addr: helper_id_constructor(IdEnum::vault_b_id), + liquidity_pool_id: helper_id_constructor(IdEnum::token_lp_definition_id), + liquidity_pool_supply: helper_balance_constructor(BalanceEnum::vault_a_reserve_init), + reserve_a: 0, + reserve_b: helper_balance_constructor(BalanceEnum::vault_b_reserve_init), + fees: 0u128, + active: true, + }), + nonce: 0, + }, + is_authorized: true, + account_id: helper_id_constructor(IdEnum::pool_definition_id), + }, + AccountEnum::pool_definition_init_reserve_b_zero => AccountWithMetadata { + account: Account { + program_owner: ProgramId::default(), + balance: 0u128, + data: PoolDefinition::into_data( + PoolDefinition { + definition_token_a_id: helper_id_constructor(IdEnum::token_a_definition_id), + definition_token_b_id: helper_id_constructor(IdEnum::token_b_definition_id), + vault_a_addr: helper_id_constructor(IdEnum::vault_a_id), + vault_b_addr: helper_id_constructor(IdEnum::vault_b_id), + liquidity_pool_id: helper_id_constructor(IdEnum::token_lp_definition_id), + liquidity_pool_supply: helper_balance_constructor(BalanceEnum::vault_a_reserve_init), + reserve_a: helper_balance_constructor(BalanceEnum::vault_a_reserve_init), + reserve_b: 0, + fees: 0u128, + active: true, + }), + nonce: 0, + }, + is_authorized: true, + account_id: helper_id_constructor(IdEnum::pool_definition_id), + }, + AccountEnum::pool_definition_init_reserve_a_low => AccountWithMetadata { + account: Account { + program_owner: ProgramId::default(), + balance: 0u128, + data: PoolDefinition::into_data( + PoolDefinition { + definition_token_a_id: helper_id_constructor(IdEnum::token_a_definition_id), + definition_token_b_id: helper_id_constructor(IdEnum::token_b_definition_id), + vault_a_addr: helper_id_constructor(IdEnum::vault_a_id), + vault_b_addr: helper_id_constructor(IdEnum::vault_b_id), + liquidity_pool_id: helper_id_constructor(IdEnum::token_lp_definition_id), + liquidity_pool_supply: helper_balance_constructor(BalanceEnum::vault_a_reserve_low), + reserve_a: helper_balance_constructor(BalanceEnum::vault_a_reserve_low), + reserve_b: helper_balance_constructor(BalanceEnum::vault_b_reserve_high), + fees: 0u128, + active: true, + }), + nonce: 0, + }, + is_authorized: true, + account_id: helper_id_constructor(IdEnum::pool_definition_id), + }, + AccountEnum::pool_definition_init_reserve_b_low => AccountWithMetadata { + account: Account { + program_owner: ProgramId::default(), + balance: 0u128, + data: PoolDefinition::into_data( + PoolDefinition { + definition_token_a_id: helper_id_constructor(IdEnum::token_a_definition_id), + definition_token_b_id: helper_id_constructor(IdEnum::token_b_definition_id), + vault_a_addr: helper_id_constructor(IdEnum::vault_a_id), + vault_b_addr: helper_id_constructor(IdEnum::vault_b_id), + liquidity_pool_id: helper_id_constructor(IdEnum::token_lp_definition_id), + liquidity_pool_supply: helper_balance_constructor(BalanceEnum::vault_a_reserve_high), + reserve_a: helper_balance_constructor(BalanceEnum::vault_a_reserve_high), + reserve_b: helper_balance_constructor(BalanceEnum::vault_b_reserve_low), + fees: 0u128, active: true, }), nonce: 0, @@ -1165,7 +1702,7 @@ mod tests { }, AccountEnum::pool_definition_unauth => AccountWithMetadata { account: Account { - program_owner: amm_program_id, + program_owner: ProgramId::default(), balance: 0u128, data: PoolDefinition::into_data( PoolDefinition { @@ -1177,6 +1714,7 @@ mod tests { liquidity_pool_supply: helper_balance_constructor(BalanceEnum::vault_a_reserve_init), reserve_a: helper_balance_constructor(BalanceEnum::vault_a_reserve_init), reserve_b: helper_balance_constructor(BalanceEnum::vault_b_reserve_init), + fees: 0u128, active: true, }), nonce: 0, @@ -1184,78 +1722,126 @@ mod tests { is_authorized: false, account_id: helper_id_constructor(IdEnum::pool_definition_id), }, + AccountEnum::pool_definition_swap_test_1 => AccountWithMetadata { + account: Account { + program_owner: ProgramId::default(), + balance: 0u128, + data: PoolDefinition::into_data( + PoolDefinition { + definition_token_a_id: helper_id_constructor(IdEnum::token_a_definition_id), + definition_token_b_id: helper_id_constructor(IdEnum::token_b_definition_id), + vault_a_addr: helper_id_constructor(IdEnum::vault_a_id), + vault_b_addr: helper_id_constructor(IdEnum::vault_b_id), + liquidity_pool_id: helper_id_constructor(IdEnum::token_lp_definition_id), + liquidity_pool_supply: helper_balance_constructor(BalanceEnum::vault_a_reserve_init), + reserve_a: helper_balance_constructor(BalanceEnum::vault_a_swap_test_1), + reserve_b: helper_balance_constructor(BalanceEnum::vault_b_swap_test_1), + fees: 0u128, + active: true, + }), + nonce: 0, + }, + is_authorized: true, + account_id: helper_id_constructor(IdEnum::pool_definition_id), + }, + AccountEnum::pool_definition_swap_test_2 => AccountWithMetadata { + account: Account { + program_owner: ProgramId::default(), + balance: 0u128, + data: PoolDefinition::into_data( + PoolDefinition { + definition_token_a_id: helper_id_constructor(IdEnum::token_a_definition_id), + definition_token_b_id: helper_id_constructor(IdEnum::token_b_definition_id), + vault_a_addr: helper_id_constructor(IdEnum::vault_a_id), + vault_b_addr: helper_id_constructor(IdEnum::vault_b_id), + liquidity_pool_id: helper_id_constructor(IdEnum::token_lp_definition_id), + liquidity_pool_supply: helper_balance_constructor(BalanceEnum::vault_a_reserve_init), + reserve_a: helper_balance_constructor(BalanceEnum::vault_a_swap_test_2), + reserve_b: helper_balance_constructor(BalanceEnum::vault_b_swap_test_2), + fees: 0u128, + active: true, + }), + nonce: 0, + }, + is_authorized: true, + account_id: helper_id_constructor(IdEnum::pool_definition_id), + }, + AccountEnum::pool_definition_add_zero_lp => AccountWithMetadata { + account: Account { + program_owner: ProgramId::default(), + balance: 0u128, + data: PoolDefinition::into_data( + PoolDefinition { + definition_token_a_id: helper_id_constructor(IdEnum::token_a_definition_id), + definition_token_b_id: helper_id_constructor(IdEnum::token_b_definition_id), + vault_a_addr: helper_id_constructor(IdEnum::vault_a_id), + vault_b_addr: helper_id_constructor(IdEnum::vault_b_id), + liquidity_pool_id: helper_id_constructor(IdEnum::token_lp_definition_id), + liquidity_pool_supply: helper_balance_constructor(BalanceEnum::vault_a_reserve_low), + reserve_a: helper_balance_constructor(BalanceEnum::vault_a_reserve_init), + reserve_b: helper_balance_constructor(BalanceEnum::vault_b_reserve_init), + fees: 0u128, + active: true, + }), + nonce: 0, + }, + is_authorized: true, + account_id: helper_id_constructor(IdEnum::pool_definition_id), + }, + AccountEnum::pool_definition_add_successful => AccountWithMetadata { + account: Account { + program_owner: ProgramId::default(), + balance: 0u128, + data: PoolDefinition::into_data( + PoolDefinition { + definition_token_a_id: helper_id_constructor(IdEnum::token_a_definition_id), + definition_token_b_id: helper_id_constructor(IdEnum::token_b_definition_id), + vault_a_addr: helper_id_constructor(IdEnum::vault_a_id), + vault_b_addr: helper_id_constructor(IdEnum::vault_b_id), + liquidity_pool_id: helper_id_constructor(IdEnum::token_lp_definition_id), + liquidity_pool_supply: helper_balance_constructor(BalanceEnum::vault_a_add_successful), + reserve_a: helper_balance_constructor(BalanceEnum::vault_a_add_successful), + reserve_b: helper_balance_constructor(BalanceEnum::vault_b_add_successful), + fees: 0u128, + active: true, + }), + nonce: 0, + }, + is_authorized: true, + account_id: helper_id_constructor(IdEnum::pool_definition_id), + }, + AccountEnum::pool_definition_remove_successful => AccountWithMetadata { + account: Account { + program_owner: ProgramId::default(), + balance: 0u128, + data: PoolDefinition::into_data( + PoolDefinition { + definition_token_a_id: helper_id_constructor(IdEnum::token_a_definition_id), + definition_token_b_id: helper_id_constructor(IdEnum::token_b_definition_id), + vault_a_addr: helper_id_constructor(IdEnum::vault_a_id), + vault_b_addr: helper_id_constructor(IdEnum::vault_b_id), + liquidity_pool_id: helper_id_constructor(IdEnum::token_lp_definition_id), + liquidity_pool_supply: helper_balance_constructor(BalanceEnum::vault_a_remove_successful), + reserve_a: helper_balance_constructor(BalanceEnum::vault_a_remove_successful), + reserve_b: helper_balance_constructor(BalanceEnum::vault_b_remove_successful), + fees: 0u128, + active: true, + }), + nonce: 0, + }, + is_authorized: true, + account_id: helper_id_constructor(IdEnum::pool_definition_id), + }, _ => panic!("Invalid selection"), } } - -/* -TODO: delete - fn helper_account_constructor(selection: AccountEnum) -> AccountWithMetadata { - let amm_program_id: ProgramId = [15;8]; - let token_program_id: ProgramId = [16;8]; - let helper_id_constructor(IdEnum::token_a_definition_id) = AccountId::new([42;32]); - let helper_id_constructor(IdEnum::token_b_definition_id) = AccountId::new([43;32]); - let helper_id_constructor(IdEnum::token_lp_definition_id) = AccountId::new([44;32]); - let user_token_a_id = AccountId::new([45;32]); - let user_token_b_id = AccountId::new([46;32]); - let user_token_lp_id = AccountId::new([47;32]); - let pool_definition_id = AccountId::new([48;32]); - let vault_a_id = AccountId::new([45;32]); - let vault_b_id = AccountId::new([46;32]); - let pool_lp_id = AccountId::new([47;32]); - - let helper_balance_constructor(BalanceEnum::vault_a_reserve_init): u128 = 1000; - let helper_balance_constructor(BalanceEnum::vault_b_reserve_init): u128 = 250; - let user_token_a_bal: u128 = 500; - let helper_balance_constructor(BalanceEnum::user_token_b_bal): u128 = 250; - let helper_balance_constructor(BalanceEnum::user_token_lp_bal): u128 = 100; - - enum AccountEnum { - account_a_holding, - account_b_holding, - vault_a_uninit, - vault_b_uninit, - vault_a_init, - vault_b_init, - vault_a_wrong_acc_id, - vault_b_wrong_acc_id, - pool_lp_uninit, - pool_lp_init, - pool_lp_wrong_acc_id, - account_lp_holding_uninit, - account_lp_holding_init, - pool_definition_uninit, - pool_definition_init, - - enum BalanceEnum { - uninit_balance, - vault_a_reserve_init, - vault_b_reserve_init, - user_token_a_bal, - user_token_b_bal, - user_token_lp_bal - } - - } - - // amm_pool is a default account that will initiate the amm definition account values -// vault_holding_a is a token holding account for token a -// vault_holding_b is a token holding account for token b -// pool_lp is a token holding account for the pool's lp token -// user_holding_a is a token holding account for token a -// user_holding_b is a token holding account for token b -// user_holding_lp is a token holding account for lp token - -*/ - - #[should_panic(expected = "Invalid number of input accounts")] #[test] - fn test_call_new_definition_with_invalid_number_of_accounts_1() { + fn test_call_new_pool_with_invalid_number_of_accounts_1() { let pre_states = vec![ helper_account_constructor(AccountEnum::pool_definition_uninit),] ; - let _post_states = new_definition(&pre_states, + let _post_states = new_pool(&pre_states, &[helper_balance_constructor(BalanceEnum::user_token_a_bal), helper_balance_constructor(BalanceEnum::user_token_b_bal)], TOKEN_PROGRAM_ID); @@ -1263,12 +1849,12 @@ TODO: delete #[should_panic(expected = "Invalid number of input accounts")] #[test] - fn test_call_new_definition_with_invalid_number_of_accounts_2() { + fn test_call_new_pool_with_invalid_number_of_accounts_2() { let pre_states = vec![ helper_account_constructor(AccountEnum::pool_definition_uninit), helper_account_constructor(AccountEnum::vault_a_uninit), ]; - let _post_states = new_definition(&pre_states, + let _post_states = new_pool(&pre_states, &[helper_balance_constructor(BalanceEnum::user_token_a_bal), helper_balance_constructor(BalanceEnum::user_token_b_bal)], TOKEN_PROGRAM_ID); @@ -1276,13 +1862,13 @@ TODO: delete #[should_panic(expected = "Invalid number of input accounts")] #[test] - fn test_call_new_definition_with_invalid_number_of_accounts_3() { + fn test_call_new_pool_with_invalid_number_of_accounts_3() { let pre_states = vec![ helper_account_constructor(AccountEnum::pool_definition_uninit), helper_account_constructor(AccountEnum::vault_a_uninit), helper_account_constructor(AccountEnum::vault_b_uninit), ]; - let _post_states = new_definition(&pre_states, + let _post_states = new_pool(&pre_states, &[helper_balance_constructor(BalanceEnum::user_token_a_bal), helper_balance_constructor(BalanceEnum::user_token_b_bal)], TOKEN_PROGRAM_ID); @@ -1290,14 +1876,14 @@ TODO: delete #[should_panic(expected = "Invalid number of input accounts")] #[test] - fn test_call_new_definition_with_invalid_number_of_accounts_4() { + fn test_call_new_pool_with_invalid_number_of_accounts_4() { let pre_states = vec![ helper_account_constructor(AccountEnum::pool_definition_uninit), helper_account_constructor(AccountEnum::vault_a_uninit), helper_account_constructor(AccountEnum::vault_b_uninit), helper_account_constructor(AccountEnum::pool_lp_uninit), ]; - let _post_states = new_definition(&pre_states, + let _post_states = new_pool(&pre_states, &[helper_balance_constructor(BalanceEnum::user_token_a_bal), helper_balance_constructor(BalanceEnum::user_token_b_bal)], TOKEN_PROGRAM_ID); @@ -1305,7 +1891,7 @@ TODO: delete #[should_panic(expected = "Invalid number of input accounts")] #[test] - fn test_call_new_definition_with_invalid_number_of_accounts_5() { + fn test_call_new_pool_with_invalid_number_of_accounts_5() { let pre_states = vec![ helper_account_constructor(AccountEnum::pool_definition_uninit), helper_account_constructor(AccountEnum::vault_a_uninit), @@ -1313,7 +1899,7 @@ TODO: delete helper_account_constructor(AccountEnum::pool_lp_uninit), helper_account_constructor(AccountEnum::user_holding_a), ]; - let _post_states = new_definition(&pre_states, + let _post_states = new_pool(&pre_states, &[helper_balance_constructor(BalanceEnum::user_token_a_bal), helper_balance_constructor(BalanceEnum::user_token_b_bal)], TOKEN_PROGRAM_ID); @@ -1321,7 +1907,7 @@ TODO: delete #[should_panic(expected = "Invalid number of input accounts")] #[test] - fn test_call_new_definition_with_invalid_number_of_accounts_6() { + fn test_call_new_pool_with_invalid_number_of_accounts_6() { let pre_states = vec![ helper_account_constructor(AccountEnum::pool_definition_uninit), helper_account_constructor(AccountEnum::vault_a_uninit), @@ -1330,7 +1916,7 @@ TODO: delete helper_account_constructor(AccountEnum::user_holding_a), helper_account_constructor(AccountEnum::user_holding_b), ]; - let _post_states = new_definition(&pre_states, + let _post_states = new_pool(&pre_states, &[helper_balance_constructor(BalanceEnum::user_token_a_bal), helper_balance_constructor(BalanceEnum::user_token_b_bal)], TOKEN_PROGRAM_ID); @@ -1338,7 +1924,7 @@ TODO: delete #[should_panic(expected = "Invalid number of balance")] #[test] - fn test_call_new_definition_with_invalid_number_of_balances_1() { + fn test_call_new_pool_with_invalid_number_of_balances_1() { let pre_states = vec![ helper_account_constructor(AccountEnum::pool_definition_uninit), helper_account_constructor(AccountEnum::vault_a_uninit), @@ -1348,14 +1934,14 @@ TODO: delete helper_account_constructor(AccountEnum::user_holding_b), helper_account_constructor(AccountEnum::user_holding_lp_uninit), ]; - let _post_states = new_definition(&pre_states, + let _post_states = new_pool(&pre_states, &[helper_balance_constructor(BalanceEnum::user_token_a_bal)], TOKEN_PROGRAM_ID); } #[should_panic(expected = "Pool account is initiated or not authorized")] #[test] - fn test_call_new_definition_with_initiated_pool() { + fn test_call_new_pool_with_initiated_pool() { let pre_states = vec![ helper_account_constructor(AccountEnum::pool_definition_init), helper_account_constructor(AccountEnum::vault_a_uninit), @@ -1365,7 +1951,7 @@ TODO: delete helper_account_constructor(AccountEnum::user_holding_b), helper_account_constructor(AccountEnum::user_holding_lp_uninit), ]; - let _post_states = new_definition(&pre_states, + let _post_states = new_pool(&pre_states, &[helper_balance_constructor(BalanceEnum::user_token_a_bal), helper_balance_constructor(BalanceEnum::user_token_b_bal)], TOKEN_PROGRAM_ID); @@ -1373,7 +1959,7 @@ TODO: delete #[should_panic(expected = "Pool account is initiated or not authorized")] #[test] - fn test_call_new_definition_with_unauthorized_pool() { + fn test_call_new_pool_with_unauthorized_pool() { let pre_states = vec![ helper_account_constructor(AccountEnum::pool_definition_unauth), helper_account_constructor(AccountEnum::vault_a_uninit), @@ -1383,7 +1969,7 @@ TODO: delete helper_account_constructor(AccountEnum::user_holding_b), helper_account_constructor(AccountEnum::user_holding_lp_uninit), ]; - let _post_states = new_definition(&pre_states, + let _post_states = new_pool(&pre_states, &[helper_balance_constructor(BalanceEnum::user_token_a_bal), helper_balance_constructor(BalanceEnum::user_token_b_bal)], TOKEN_PROGRAM_ID); @@ -1391,7 +1977,7 @@ TODO: delete #[should_panic(expected = "Balances must be nonzero")] #[test] - fn test_call_new_definition_with_balance_zero_1() { + fn test_call_new_pool_with_balance_zero_1() { let pre_states = vec![ helper_account_constructor(AccountEnum::pool_definition_uninit), helper_account_constructor(AccountEnum::vault_a_uninit), @@ -1401,7 +1987,7 @@ TODO: delete helper_account_constructor(AccountEnum::user_holding_b), helper_account_constructor(AccountEnum::user_holding_lp_uninit), ]; - let _post_states = new_definition(&pre_states, + let _post_states = new_pool(&pre_states, &[0, helper_balance_constructor(BalanceEnum::user_token_b_bal)], TOKEN_PROGRAM_ID); @@ -1409,7 +1995,7 @@ TODO: delete #[should_panic(expected = "Balances must be nonzero")] #[test] - fn test_call_new_definition_with_balance_zero_2() { + fn test_call_new_pool_with_balance_zero_2() { let pre_states = vec![ helper_account_constructor(AccountEnum::pool_definition_uninit), helper_account_constructor(AccountEnum::vault_a_uninit), @@ -1419,7 +2005,7 @@ TODO: delete helper_account_constructor(AccountEnum::user_holding_b), helper_account_constructor(AccountEnum::user_holding_lp_uninit), ]; - let _post_states = new_definition(&pre_states, + let _post_states = new_pool(&pre_states, &[helper_balance_constructor(BalanceEnum::user_token_a_bal), 0], TOKEN_PROGRAM_ID); @@ -1427,7 +2013,7 @@ TODO: delete #[should_panic(expected = "Cannot set up a swap for a token with itself.")] #[test] - fn test_call_new_definition_same_token() { + fn test_call_new_pool_same_token() { let pre_states = vec![ helper_account_constructor(AccountEnum::pool_definition_uninit), helper_account_constructor(AccountEnum::vault_a_uninit), @@ -1437,15 +2023,14 @@ TODO: delete helper_account_constructor(AccountEnum::user_holding_a), helper_account_constructor(AccountEnum::user_holding_lp_uninit), ]; - let _post_states = new_definition(&pre_states, + let _post_states = new_pool(&pre_states, &[helper_balance_constructor(BalanceEnum::user_token_a_bal), helper_balance_constructor(BalanceEnum::user_token_b_bal)], TOKEN_PROGRAM_ID); } - //TODO: fix this #[test] - fn test_call_new_definition_chain_call_success() { + fn test_call_new_pool_chain_call_success() { let pre_states = vec![ helper_account_constructor(AccountEnum::pool_definition_uninit), helper_account_constructor(AccountEnum::vault_a_uninit), @@ -1455,112 +2040,25 @@ TODO: delete helper_account_constructor(AccountEnum::user_holding_b), helper_account_constructor(AccountEnum::user_holding_lp_uninit), ]; - let post_states = new_definition(&pre_states, + let (post_states, chained_calls) = new_pool(&pre_states, &[helper_balance_constructor(BalanceEnum::user_token_a_bal), helper_balance_constructor(BalanceEnum::user_token_b_bal)], TOKEN_PROGRAM_ID); - } + let pool_post = post_states[0].clone(); - - /*TODO: ^^^ need to chain call checks - let user_holding_a = AccountWithMetadata { - account: user_holding_a.clone(), - is_authorized: true, - account_id: AccountId::new([5; 32])}; - - let user_holding_b = AccountWithMetadata { - account: user_holding_b.clone(), - is_authorized: true, - account_id: AccountId::new([6; 32])}; - - let user_holding_lp = AccountWithMetadata { - account: user_holding_lp.clone(), - is_authorized: true, - account_id: AccountId::new([7; 32]) - }; - - let vault_a = AccountWithMetadata { - account: vault_a.clone(), - is_authorized: true, - account_id: AccountId::new([2; 32])}; - - let vault_b = AccountWithMetadata { - account: vault_b.clone(), - is_authorized: true, - account_id: AccountId::new([3; 32])}; - - let pool_lp = AccountWithMetadata { - account: pool_lp.clone(), - is_authorized: true, - account_id: AccountId::new([4; 32])}; - - let pre_states = vec![AccountWithMetadata { - account: pool.clone(), - is_authorized: true, - account_id: AccountId::new([0; 32])}, - vault_a.clone(), - vault_b.clone(), - pool_lp.clone(), - user_holding_a.clone(), - user_holding_b.clone(), - user_holding_lp.clone(), - ]; - let balance_a = 15u128; - let balance_b = 15u128; - let token_program_id: [u32;8] = [0; 8]; - let (post_states, chained_calls) = new_definition(&pre_states, &[balance_a, balance_b], token_program_id); + let pool_data = PoolDefinition::parse(&pool_post.data).unwrap(); + assert!(helper_account_constructor(AccountEnum::pool_definition_init).account == + pool_post); let chained_call_lp = chained_calls[0].clone(); let chained_call_b = chained_calls[1].clone(); let chained_call_a = chained_calls[2].clone(); - - //Expected chain_call for Token A - let mut instruction: [u8;32] = [0; 32]; - instruction[0] = 1; - instruction[1..17].copy_from_slice(&balance_a.to_le_bytes()); - let instruction_data = risc0_zkvm::serde::to_vec(&instruction).unwrap(); - let expected_chained_call_a = ChainedCall{ - program_id: token_program_id, - instruction_data, - pre_states: vec![user_holding_a.clone(), vault_a.clone()], - }; - //Expected chain call for Token B - let mut instruction: [u8;32] = [0; 32]; - instruction[0] = 1; - instruction[1..17].copy_from_slice(&balance_b.to_le_bytes()); - let instruction_data = risc0_zkvm::serde::to_vec(&instruction).unwrap(); - let expected_chained_call_b = ChainedCall{ - program_id: token_program_id, - instruction_data, - pre_states: vec![user_holding_b.clone(), vault_b.clone()], - }; - - //Expected chain call for LP - let mut instruction: [u8;32] = [0; 32]; - instruction[0] = 1; - instruction[1..17].copy_from_slice(&balance_a.to_le_bytes()); - let instruction_data = risc0_zkvm::serde::to_vec(&instruction).unwrap(); - let expected_chained_call_lp = ChainedCall{ - program_id: token_program_id, - instruction_data, - pre_states: vec![pool_lp.clone(), user_holding_lp.clone()], - }; - - assert!(chained_call_a.program_id == expected_chained_call_a.program_id); - assert!(chained_call_a.instruction_data == expected_chained_call_a.instruction_data); - assert!(chained_call_a.pre_states[0].account == expected_chained_call_a.pre_states[0].account); - assert!(chained_call_a.pre_states[1].account == expected_chained_call_a.pre_states[1].account); - assert!(chained_call_b.program_id == expected_chained_call_b.program_id); - assert!(chained_call_b.instruction_data == expected_chained_call_b.instruction_data); - assert!(chained_call_b.pre_states[0].account == expected_chained_call_b.pre_states[0].account); - assert!(chained_call_b.pre_states[1].account == expected_chained_call_b.pre_states[1].account); - assert!(chained_call_lp.program_id == expected_chained_call_lp.program_id); - assert!(chained_call_lp.instruction_data == expected_chained_call_lp.instruction_data); - assert!(chained_call_lp.pre_states[0].account == expected_chained_call_lp.pre_states[0].account); - assert!(chained_call_lp.pre_states[1].account == expected_chained_call_lp.pre_states[1].account); - }*/ + assert!(chained_call_lp == helper_chained_call_constructor(ChainedCallsEnum::cc_pool_lp_initialization)); + assert!(chained_call_a == helper_chained_call_constructor(ChainedCallsEnum::cc_token_a_initialization)); + assert!(chained_call_b == helper_chained_call_constructor(ChainedCallsEnum::cc_token_b_initialization)); + } #[should_panic(expected = "Invalid number of input accounts")] #[test] @@ -1693,178 +2191,150 @@ TODO: delete ); } + #[should_panic(expected = "Invalid liquidity account provided")] #[test] - //TODO: need to fix this test - fn test_call_remove_liquidity_chain_call_success() { - let mut pool = Account::default(); - let mut vault_a = Account::default(); - let mut vault_b = Account::default(); - let mut user_holding_a = Account::default(); - let mut user_holding_b = Account::default(); - let mut pool_lp = Account::default(); - let mut user_holding_lp = Account::default(); + fn test_call_remove_liquidity_insufficient_liquidity_amount() { + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::pool_lp_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + helper_account_constructor(AccountEnum::user_holding_a), //different token account than lp to create desired error + ]; + let _post_states = remove_liquidity(&pre_states, + &[helper_balance_constructor(BalanceEnum::remove_amount_lp), + helper_balance_constructor(BalanceEnum::remove_min_amount_a), + helper_balance_constructor(BalanceEnum::remove_min_amount_b)], + ); + } - let definition_token_a_id = AccountId::new([1;32]); - let definition_token_b_id = AccountId::new([2;32]); - - vault_a.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 15u128 } - ); + #[should_panic(expected = "Insufficient minimal withdraw amount (Token A) provided for liquidity amount")] + #[test] + fn test_call_remove_liquidity_insufficient_balance_1() { + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::pool_lp_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + helper_account_constructor(AccountEnum::user_holding_lp_init), + ]; + let _post_states = remove_liquidity(&pre_states, + &[helper_balance_constructor(BalanceEnum::remove_amount_lp_1), + helper_balance_constructor(BalanceEnum::remove_min_amount_a), + helper_balance_constructor(BalanceEnum::remove_min_amount_b)], + ); + } - vault_b.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_b_id.clone(), - balance: 15u128 } - ); + #[should_panic(expected = "Insufficient minimal withdraw amount (Token B) provided for liquidity amount")] + #[test] + fn test_call_remove_liquidity_insufficient_balance_2() { + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::pool_lp_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + helper_account_constructor(AccountEnum::user_holding_lp_init), + ]; + let _post_states = remove_liquidity(&pre_states, + &[helper_balance_constructor(BalanceEnum::remove_amount_lp), + helper_balance_constructor(BalanceEnum::remove_min_amount_a), + helper_balance_constructor(BalanceEnum::remove_min_amount_b)], + ); + } - pool_lp.data = vec![ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; + #[should_panic(expected = "Minimum withdraw amount must be nonzero")] + #[test] + fn test_call_remove_liquidity_min_bal_zero_1() { + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::pool_lp_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + helper_account_constructor(AccountEnum::user_holding_lp_init), + ]; + let _post_states = remove_liquidity(&pre_states, + &[helper_balance_constructor(BalanceEnum::remove_amount_lp), + 0, + helper_balance_constructor(BalanceEnum::remove_min_amount_b)], + ); + } - let vault_a_addr = AccountId::new([5;32]); - let vault_b_addr = AccountId::new([6;32]); - let liquidity_pool_id = AccountId::new([7;32]); - let liquidity_pool_supply: u128 = 30u128; - let reserve_a: u128 = 30; - let reserve_b: u128 = 20; - let user_holding_lp_amt: u128 = 10; - let token_program_id: [u32;8] = [0; 8]; + #[should_panic(expected = "Minimum withdraw amount must be nonzero")] + #[test] + fn test_call_remove_liquidity_min_bal_zero_2() { + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::pool_lp_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + helper_account_constructor(AccountEnum::user_holding_lp_init), + ]; + let _post_states = remove_liquidity(&pre_states, + &[helper_balance_constructor(BalanceEnum::remove_amount_lp), + helper_balance_constructor(BalanceEnum::remove_min_amount_a), + 0], + ); + } - pool.data = PoolDefinition::into_data( PoolDefinition { - definition_token_a_id: definition_token_a_id.clone(), - definition_token_b_id: definition_token_b_id.clone(), - vault_a_addr: vault_a_addr.clone(), - vault_b_addr: vault_b_addr.clone(), - liquidity_pool_id, - liquidity_pool_supply: reserve_a, - reserve_a, - reserve_b, - active: true, - }); - - user_holding_a.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 5u128 } - ); + #[should_panic(expected = "Liquidity amount must be nonzero")] + #[test] + fn test_call_remove_liquidity_lp_bal_zero() { + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::pool_lp_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + helper_account_constructor(AccountEnum::user_holding_lp_init), + ]; + let _post_states = remove_liquidity(&pre_states, + &[0, + helper_balance_constructor(BalanceEnum::remove_min_amount_a), + helper_balance_constructor(BalanceEnum::remove_min_amount_b),], + ); + } - user_holding_b.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_b_id.clone(), - balance: 5u128 } - ); + #[test] + fn test_call_remove_liquidity_chained_call_successful() { + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::pool_lp_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + helper_account_constructor(AccountEnum::user_holding_lp_init), + ]; + let (post_states, chained_calls) = remove_liquidity(&pre_states, + &[helper_balance_constructor(BalanceEnum::remove_amount_lp), + helper_balance_constructor(BalanceEnum::remove_min_amount_a), + helper_balance_constructor(BalanceEnum::remove_min_amount_b_low),], + ); - user_holding_lp.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id: AccountId::new([3;32]), - balance: user_holding_lp_amt } - ); + let pool_post = post_states[0].clone(); - let user_holding_a = AccountWithMetadata { - account: user_holding_a.clone(), - is_authorized: true, - account_id: AccountId::new([5; 32])}; - - let user_holding_b = AccountWithMetadata { - account: user_holding_b.clone(), - is_authorized: true, - account_id: AccountId::new([6; 32])}; - - let user_holding_lp = AccountWithMetadata { - account: user_holding_lp.clone(), - is_authorized: true, - account_id: AccountId::new([7; 32]) - }; - - let vault_a = AccountWithMetadata { - account: vault_a.clone(), - is_authorized: true, - account_id: vault_a_addr.clone(),}; - - let vault_b = AccountWithMetadata { - account: vault_b.clone(), - is_authorized: true, - account_id: vault_b_addr.clone()}; - - let pool_lp = AccountWithMetadata { - account: pool_lp.clone(), - is_authorized: true, - account_id: AccountId::new([4; 32])}; - - let pre_states = vec![AccountWithMetadata { - account: pool.clone(), - is_authorized: true, - account_id: AccountId::new([0; 32])}, - vault_a.clone(), - vault_b.clone(), - pool_lp.clone(), - user_holding_a.clone(), - user_holding_b.clone(), - user_holding_lp.clone(), - ]; - - let amount_lp = 5; - let amount_min_a = 2; - let amount_min_b = 2; - let (post_states, chained_calls) = remove_liquidity(&pre_states, &[amount_lp, amount_min_a, amount_min_b]); + assert!(helper_account_constructor(AccountEnum::pool_definition_remove_successful).account == + pool_post); let chained_call_lp = chained_calls[0].clone(); - let chained_call_b = chained_calls[1].clone(); - let chained_call_a = chained_calls[2].clone(); - - //Expected withdraw - let withdraw_amount_a = reserve_a * (amount_lp/reserve_a); - let withdraw_amount_b = reserve_b * (amount_lp/reserve_a); + let chained_call_b = chained_calls[1].clone(); + let chained_call_a = chained_calls[2].clone(); - //Expected chain_call for Token A - let mut instruction: [u8;32] = [0; 32]; - instruction[0] = 1; - instruction[1..17].copy_from_slice(&withdraw_amount_a.to_le_bytes()); - let instruction_data = risc0_zkvm::serde::to_vec(&instruction).unwrap(); - let expected_chained_call_a = ChainedCall{ - program_id: token_program_id, - instruction_data, - pre_states: vec![vault_a.clone(), user_holding_a.clone()], - }; - - //Expected chain call for Token B - let mut instruction: [u8;32] = [0; 32]; - instruction[0] = 1; - instruction[1..17].copy_from_slice(&withdraw_amount_b.to_le_bytes()); - let instruction_data = risc0_zkvm::serde::to_vec(&instruction).unwrap(); - let expected_chained_call_b = ChainedCall{ - program_id: token_program_id, - instruction_data, - pre_states: vec![vault_b.clone(), user_holding_b.clone()], - }; - - //Expected chain call for LP - let mut instruction: [u8;32] = [0; 32]; - instruction[0] = 1; - instruction[1..17].copy_from_slice(&user_holding_lp_amt.to_le_bytes()); - let instruction_data = risc0_zkvm::serde::to_vec(&instruction).unwrap(); - let expected_chained_call_lp = ChainedCall{ - program_id: token_program_id, - instruction_data, - pre_states: vec![user_holding_lp.clone(), pool_lp.clone()], - }; - - assert!(chained_call_a.program_id == expected_chained_call_a.program_id); - assert!(chained_call_a.instruction_data == expected_chained_call_a.instruction_data); - assert!(chained_call_a.pre_states[0].account == expected_chained_call_a.pre_states[0].account); - assert!(chained_call_a.pre_states[1].account == expected_chained_call_a.pre_states[1].account); - assert!(chained_call_b.program_id == expected_chained_call_b.program_id); - assert!(chained_call_b.instruction_data == expected_chained_call_b.instruction_data); - assert!(chained_call_b.pre_states[0].account == expected_chained_call_b.pre_states[0].account); - assert!(chained_call_b.pre_states[1].account == expected_chained_call_b.pre_states[1].account); - assert!(chained_call_lp.program_id == expected_chained_call_lp.program_id); - assert!(chained_call_lp.instruction_data == expected_chained_call_lp.instruction_data); - assert!(chained_call_lp.pre_states[0].account == expected_chained_call_lp.pre_states[0].account); - assert!(chained_call_lp.pre_states[1].account == expected_chained_call_lp.pre_states[1].account); - } + assert!(chained_call_a == helper_chained_call_constructor(ChainedCallsEnum::cc_remove_token_a)); + assert!(chained_call_b == helper_chained_call_constructor(ChainedCallsEnum::cc_remove_token_b)); + assert!(chained_call_lp.instruction_data == helper_chained_call_constructor(ChainedCallsEnum::cc_remove_pool_lp).instruction_data); + } #[should_panic(expected = "Invalid number of input accounts")] #[test] @@ -1873,10 +2343,9 @@ TODO: delete helper_account_constructor(AccountEnum::pool_definition_init), ]; let _post_states = add_liquidity(&pre_states, - &[helper_balance_constructor(BalanceEnum::remove_amount_lp), - helper_balance_constructor(BalanceEnum::add_amount_a), - helper_balance_constructor(BalanceEnum::add_amount_b)], - helper_id_constructor(IdEnum::vault_a_id), + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::add_max_amount_b), + helper_balance_constructor(BalanceEnum::add_min_amount_lp),], ); } @@ -1888,10 +2357,9 @@ TODO: delete helper_account_constructor(AccountEnum::vault_a_init), ]; let _post_states = add_liquidity(&pre_states, - &[helper_balance_constructor(BalanceEnum::remove_amount_lp), - helper_balance_constructor(BalanceEnum::add_amount_a), - helper_balance_constructor(BalanceEnum::add_amount_b)], - helper_id_constructor(IdEnum::vault_a_id), + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::add_max_amount_b), + helper_balance_constructor(BalanceEnum::add_min_amount_lp),], ); } @@ -1904,10 +2372,9 @@ TODO: delete helper_account_constructor(AccountEnum::vault_b_init), ]; let _post_states = add_liquidity(&pre_states, - &[helper_balance_constructor(BalanceEnum::remove_amount_lp), - helper_balance_constructor(BalanceEnum::add_amount_a), - helper_balance_constructor(BalanceEnum::add_amount_b)], - helper_id_constructor(IdEnum::vault_a_id), + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::add_max_amount_b), + helper_balance_constructor(BalanceEnum::add_min_amount_lp),], ); } @@ -1921,10 +2388,9 @@ TODO: delete helper_account_constructor(AccountEnum::pool_lp_init), ]; let _post_states = add_liquidity(&pre_states, - &[helper_balance_constructor(BalanceEnum::remove_amount_lp), - helper_balance_constructor(BalanceEnum::add_amount_a), - helper_balance_constructor(BalanceEnum::add_amount_b)], - helper_id_constructor(IdEnum::vault_a_id), + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::add_max_amount_b), + helper_balance_constructor(BalanceEnum::add_min_amount_lp),], ); } @@ -1939,10 +2405,9 @@ TODO: delete helper_account_constructor(AccountEnum::user_holding_a), ]; let _post_states = add_liquidity(&pre_states, - &[helper_balance_constructor(BalanceEnum::remove_amount_lp), - helper_balance_constructor(BalanceEnum::add_amount_a), - helper_balance_constructor(BalanceEnum::add_amount_b)], - helper_id_constructor(IdEnum::vault_a_id), + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::add_max_amount_b), + helper_balance_constructor(BalanceEnum::add_min_amount_lp),], ); } @@ -1958,22 +2423,12 @@ TODO: delete helper_account_constructor(AccountEnum::user_holding_b), ]; let _post_states = add_liquidity(&pre_states, - &[helper_balance_constructor(BalanceEnum::remove_amount_lp), - helper_balance_constructor(BalanceEnum::add_amount_a), - helper_balance_constructor(BalanceEnum::add_amount_b)], - helper_id_constructor(IdEnum::vault_a_id), + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::add_max_amount_b), + helper_balance_constructor(BalanceEnum::add_min_amount_lp),], ); } - - /* - - helper_account_constructor(AccountEnum::vault_b_init), - helper_account_constructor(AccountEnum::pool_lp_init), - helper_account_constructor(AccountEnum::user_holding_a), - helper_account_constructor(AccountEnum::user_holding_b), - helper_account_constructor(AccountEnum::user_holding_lp_init), */ - - + #[should_panic(expected = "Invalid number of input balances")] #[test] fn test_call_add_liquidity_invalid_number_of_balances_1() { @@ -1987,8 +2442,7 @@ TODO: delete helper_account_constructor(AccountEnum::user_holding_lp_init), ]; let _post_states = add_liquidity(&pre_states, - &[helper_balance_constructor(BalanceEnum::add_amount_a),], - helper_id_constructor(IdEnum::vault_a_id), + &[helper_balance_constructor(BalanceEnum::add_max_amount_a),], ); } @@ -2005,9 +2459,9 @@ TODO: delete helper_account_constructor(AccountEnum::user_holding_lp_init), ]; let _post_states = add_liquidity(&pre_states, - &[helper_balance_constructor(BalanceEnum::add_amount_a), - helper_balance_constructor(BalanceEnum::add_amount_b),], - helper_id_constructor(IdEnum::vault_a_id), + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::add_max_amount_b), + helper_balance_constructor(BalanceEnum::add_min_amount_lp),], ); } @@ -2024,9 +2478,9 @@ TODO: delete helper_account_constructor(AccountEnum::user_holding_lp_init), ]; let _post_states = add_liquidity(&pre_states, - &[helper_balance_constructor(BalanceEnum::add_amount_a), - helper_balance_constructor(BalanceEnum::add_amount_b),], - helper_id_constructor(IdEnum::vault_a_id), + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::add_max_amount_b), + helper_balance_constructor(BalanceEnum::add_min_amount_lp),], ); } @@ -2043,9 +2497,9 @@ TODO: delete helper_account_constructor(AccountEnum::user_holding_lp_init), ]; let _post_states = add_liquidity(&pre_states, - &[0, - helper_balance_constructor(BalanceEnum::add_amount_b),], - helper_id_constructor(IdEnum::vault_a_id), + &[0, + helper_balance_constructor(BalanceEnum::add_max_amount_b), + helper_balance_constructor(BalanceEnum::add_min_amount_lp),], ); } @@ -2062,1670 +2516,423 @@ TODO: delete helper_account_constructor(AccountEnum::user_holding_lp_init), ]; let _post_states = add_liquidity(&pre_states, - &[helper_balance_constructor(BalanceEnum::add_amount_a), - 0,], - helper_id_constructor(IdEnum::vault_a_id), + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + 0, + helper_balance_constructor(BalanceEnum::add_min_amount_lp),], ); } - /* - #[should_panic(expected = "Mismatch of token types")] + #[should_panic(expected = "Min-lp must be nonzero")] #[test] - fn test_call_add_liquidity_incorrect_token_type() { - let mut pool = Account::default(); - let mut vault1 = Account::default(); - let mut vault2 = Account::default(); - let mut pool_lp = Account::default(); - - - let definition_token_a_id = AccountId::new([1;32]); - let definition_token_b_id = AccountId::new([2;32]); - - - vault1.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 15u128 } - ); - - vault2.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_b_id.clone(), - balance: 15u128 } - ); - - pool_lp.data = vec![ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; - - let vault_a_addr = AccountId::new([5;32]); - let vault_b_addr = AccountId::new([6;32]); - let liquidity_pool_id = AccountId::new([7;32]); - let liquidity_pool_supply: u128 = 30u128; - let reserve_a: u128 = 10; - let reserve_b: u128 = 20; - let token_program_id: [u32;8] = [0; 8]; - - pool.data = PoolDefinition::into_data( PoolDefinition { - definition_token_a_id, - definition_token_b_id, - vault_a_addr: vault_a_addr.clone(), - vault_b_addr: vault_b_addr.clone(), - liquidity_pool_id, - liquidity_pool_supply, - reserve_a, - reserve_b, - token_program_id, - }); - - let pre_states = vec![AccountWithMetadata { - account: pool, - is_authorized: true, - account_id: AccountId::new([0; 32])}, - AccountWithMetadata { - account: vault1, - is_authorized: true, - account_id: vault_a_addr.clone()}, - AccountWithMetadata { - account: vault2, - is_authorized: true, - account_id: vault_b_addr.clone()}, - AccountWithMetadata { - account: pool_lp, - is_authorized: true, - account_id: AccountId::new([4; 32])}, - AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([5; 32])}, - AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([6; 32])}, - AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([7; 32])}, - ]; - let balance_a = 15u128; - let balance_b = 15u128; - let main_token = AccountId::new([9;32]); - let _post_states = add_liquidity(&pre_states, &[balance_a,balance_b], main_token); + fn test_call_add_liquidity_zero_min_lp() { + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::pool_lp_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + helper_account_constructor(AccountEnum::user_holding_lp_init), + ]; + let _post_states = add_liquidity(&pre_states, + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::add_max_amount_b), + 0],); } - #[should_panic(expected = "Vaults must have nonzero balances")] + #[should_panic(expected = "Vaults' balances must be at least the reserve amounts")] #[test] - fn test_call_add_liquidity_zero_vault_balance_1() { - let mut pool = Account::default(); - let mut vault1 = Account::default(); - let mut vault2 = Account::default(); - let mut pool_lp = Account::default(); - - - let definition_token_a_id = AccountId::new([1;32]); - let definition_token_b_id = AccountId::new([2;32]); - - vault1.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 0u128 } - ); - - vault2.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_b_id.clone(), - balance: 15u128 } - ); - - pool_lp.data = vec![ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; - - let vault_a_addr = AccountId::new([5;32]); - let vault_b_addr = AccountId::new([6;32]); - let liquidity_pool_id = AccountId::new([7;32]); - let liquidity_pool_supply: u128 = 30u128; - let reserve_a: u128 = 10; - let reserve_b: u128 = 20; - let token_program_id: [u32;8] = [0; 8]; - - pool.data = PoolDefinition::into_data( PoolDefinition { - definition_token_a_id: definition_token_a_id.clone(), - definition_token_b_id: definition_token_b_id.clone(), - vault_a_addr: vault_a_addr.clone(), - vault_b_addr: vault_b_addr.clone(), - liquidity_pool_id, - liquidity_pool_supply, - reserve_a, - reserve_b, - token_program_id, - }); - - let pre_states = vec![AccountWithMetadata { - account: pool, - is_authorized: true, - account_id: AccountId::new([0; 32])}, - AccountWithMetadata { - account: vault1, - is_authorized: true, - account_id: vault_a_addr.clone()}, - AccountWithMetadata { - account: vault2, - is_authorized: true, - account_id: vault_b_addr.clone()}, - AccountWithMetadata { - account: pool_lp, - is_authorized: true, - account_id: AccountId::new([4; 32])}, - AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([5; 32])}, - AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([6; 32])}, - AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([7; 32])}, - ]; - let balance_a = 15u128; - let balance_b = 15u128; - let main_token = definition_token_a_id.clone(); - let _post_states = add_liquidity(&pre_states, &[balance_a,balance_b], main_token); + fn test_call_add_liquidity_vault_insufficient_balance_1() { + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_init_zero), + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::pool_lp_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + helper_account_constructor(AccountEnum::user_holding_lp_init), + ]; + let _post_states = add_liquidity(&pre_states, + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::add_max_amount_b), + helper_balance_constructor(BalanceEnum::add_min_amount_lp),], + ); } - #[should_panic(expected = "Vaults must have nonzero balances")] + #[should_panic(expected = "Vaults' balances must be at least the reserve amounts")] #[test] - fn test_call_add_liquidity_zero_vault_balance_2() { - let mut pool = Account::default(); - let mut vault1 = Account::default(); - let mut vault2 = Account::default(); - let mut pool_lp = Account::default(); - - - let definition_token_a_id = AccountId::new([1;32]); - let definition_token_b_id = AccountId::new([2;32]); - - vault1.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 15u128 } - ); - - vault2.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_b_id.clone(), - balance: 0u128 } - ); - - pool_lp.data = vec![ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; - - let vault_a_addr = AccountId::new([5;32]); - let vault_b_addr = AccountId::new([6;32]); - let liquidity_pool_id = AccountId::new([7;32]); - let liquidity_pool_supply: u128 = 30u128; - let reserve_a: u128 = 10; - let reserve_b: u128 = 20; - let token_program_id: [u32;8] = [0; 8]; - - pool.data = PoolDefinition::into_data( PoolDefinition { - definition_token_a_id: definition_token_a_id.clone(), - definition_token_b_id: definition_token_b_id.clone(), - vault_a_addr: vault_a_addr.clone(), - vault_b_addr: vault_b_addr.clone(), - liquidity_pool_id, - liquidity_pool_supply, - reserve_a, - reserve_b, - token_program_id, - }); - - let pre_states = vec![AccountWithMetadata { - account: pool, - is_authorized: true, - account_id: AccountId::new([0; 32])}, - AccountWithMetadata { - account: vault1, - is_authorized: true, - account_id: vault_a_addr.clone()}, - AccountWithMetadata { - account: vault2, - is_authorized: true, - account_id: vault_b_addr.clone()}, - AccountWithMetadata { - account: pool_lp, - is_authorized: true, - account_id: AccountId::new([4; 32])}, - AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([5; 32])}, - AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([6; 32])}, - AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([7; 32])}, - ]; - let balance_a = 15u128; - let balance_b = 15u128; - let main_token = definition_token_a_id.clone(); - let _post_states = add_liquidity(&pre_states, &[balance_a,balance_b], main_token); + fn test_call_add_liquidity_vault_insufficient_balance_2() { + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::vault_b_init_zero), + helper_account_constructor(AccountEnum::pool_lp_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + helper_account_constructor(AccountEnum::user_holding_lp_init), + ]; + let _post_states = add_liquidity(&pre_states, + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::add_max_amount_b), + helper_balance_constructor(BalanceEnum::add_min_amount_lp),], + ); } - #[should_panic(expected = "Insufficient balance")] + #[should_panic(expected = "A trade amount is 0")] #[test] - fn test_call_add_liquidity_insufficient_balance_1() { - let mut pool = Account::default(); - let mut vault1 = Account::default(); - let mut vault2 = Account::default(); - let mut pool_lp = Account::default(); - let mut user_holding_a = Account::default(); - let mut user_holding_b = Account::default(); - - - let definition_token_a_id = AccountId::new([1;32]); - let definition_token_b_id = AccountId::new([2;32]); - - vault1.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 15u128 } - ); - - user_holding_a.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 10u128 } - ); - - vault1.balance = 15u128; - vault2.balance = 15u128; - - vault2.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_b_id.clone(), - balance: 15u128 } - ); - - user_holding_b.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_b_id.clone(), - balance: 40u128 } - ); - - pool_lp.data = vec![ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; - - let vault_a_addr = AccountId::new([5;32]); - let vault_b_addr = AccountId::new([6;32]); - let liquidity_pool_id = AccountId::new([7;32]); - let liquidity_pool_supply: u128 = 30u128; - let reserve_a: u128 = 15; - let reserve_b: u128 = 15; - let token_program_id: [u32;8] = [0; 8]; - - pool.data = PoolDefinition::into_data( PoolDefinition { - definition_token_a_id: definition_token_a_id.clone(), - definition_token_b_id: definition_token_b_id.clone(), - vault_a_addr: vault_a_addr.clone(), - vault_b_addr: vault_b_addr.clone(), - liquidity_pool_id, - liquidity_pool_supply, - reserve_a, - reserve_b, - token_program_id, - }); - - let pre_states = vec![AccountWithMetadata { - account: pool, - is_authorized: true, - account_id: AccountId::new([0; 32])}, - AccountWithMetadata { - account: vault1, - is_authorized: true, - account_id: vault_a_addr.clone()}, - AccountWithMetadata { - account: vault2, - is_authorized: true, - account_id: vault_b_addr.clone()}, - AccountWithMetadata { - account: pool_lp, - is_authorized: true, - account_id: AccountId::new([4; 32])}, - AccountWithMetadata { - account: user_holding_a, - is_authorized: true, - account_id: AccountId::new([5; 32])}, - AccountWithMetadata { - account: user_holding_b, - is_authorized: true, - account_id: AccountId::new([6; 32])}, - AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([7; 32])}, - ]; - let balance_a = 15u128; - let balance_b = 15u128; - let main_token = definition_token_a_id.clone(); - let _post_states = add_liquidity(&pre_states, &[balance_a,balance_b], main_token); + fn test_call_add_liquidity_actual_amount_zero_1() { + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init_reserve_a_low), + helper_account_constructor(AccountEnum::vault_a_init_low), + helper_account_constructor(AccountEnum::vault_b_init_high), + helper_account_constructor(AccountEnum::pool_lp_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + helper_account_constructor(AccountEnum::user_holding_lp_init), + ]; + let _post_states = add_liquidity(&pre_states, + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::add_max_amount_b), + helper_balance_constructor(BalanceEnum::add_min_amount_lp),], + ); } - #[should_panic(expected = "Insufficient balance")] + #[should_panic(expected = "A trade amount is 0")] #[test] - fn test_call_add_liquidity_insufficient_balance_2() { - let mut pool = Account::default(); - let mut vault1 = Account::default(); - let mut vault2 = Account::default(); - let mut pool_lp = Account::default(); - let mut user_holding_a = Account::default(); - let mut user_holding_b = Account::default(); - - - let definition_token_a_id = AccountId::new([1;32]); - let definition_token_b_id = AccountId::new([2;32]); - - vault1.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 15u128 } - ); - - user_holding_a.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 40u128 } - ); - - vault1.balance = 15u128; - vault2.balance = 15u128; - - vault2.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_b_id.clone(), - balance: 15u128 } - ); - - user_holding_b.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_b_id.clone(), - balance: 10u128 } - ); - - pool_lp.data = vec![ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; - - let vault_a_addr = AccountId::new([5;32]); - let vault_b_addr = AccountId::new([6;32]); - let liquidity_pool_id = AccountId::new([7;32]); - let liquidity_pool_supply: u128 = 30u128; - let reserve_a: u128 = 15; - let reserve_b: u128 = 15; - let token_program_id: [u32;8] = [0; 8]; - - pool.data = PoolDefinition::into_data( PoolDefinition { - definition_token_a_id: definition_token_a_id.clone(), - definition_token_b_id: definition_token_b_id.clone(), - vault_a_addr: vault_a_addr.clone(), - vault_b_addr: vault_b_addr.clone(), - liquidity_pool_id, - liquidity_pool_supply, - reserve_a, - reserve_b, - token_program_id, - }); - - let pre_states = vec![AccountWithMetadata { - account: pool, - is_authorized: true, - account_id: AccountId::new([0; 32])}, - AccountWithMetadata { - account: vault1, - is_authorized: true, - account_id: vault_a_addr.clone()}, - AccountWithMetadata { - account: vault2, - is_authorized: true, - account_id: vault_b_addr.clone()}, - AccountWithMetadata { - account: pool_lp, - is_authorized: true, - account_id: AccountId::new([4; 32])}, - AccountWithMetadata { - account: user_holding_a, - is_authorized: true, - account_id: AccountId::new([5; 32])}, - AccountWithMetadata { - account: user_holding_b, - is_authorized: true, - account_id: AccountId::new([6; 32])}, - AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([7; 32])}, - ]; - let balance_a = 15u128; - let balance_b = 15u128; - let main_token = definition_token_a_id.clone(); - let _post_states = add_liquidity(&pre_states, &[balance_a,balance_b], main_token); - } - - #[should_panic(expected = "A trade amount is 0")] - #[test] - fn test_call_add_liquidity_actual_trade_insufficient() { - let mut pool = Account::default(); - let mut vault1 = Account::default(); - let mut vault2 = Account::default(); - let mut pool_lp = Account::default(); - let mut user_holding_a = Account::default(); - let mut user_holding_b = Account::default(); - let definition_token_a_id = AccountId::new([1;32]); - let definition_token_b_id = AccountId::new([2;32]); - - vault1.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 1500u128 } - ); - - user_holding_a.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 40u128 } - ); - - vault1.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 1500u128 } - ); - - vault2.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_b_id.clone(), - balance: 2000u128 } - ); - - - - user_holding_b.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 40u128 } - ); - - pool_lp.data = vec![ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; - - let vault_a_addr = AccountId::new([5;32]); - let vault_b_addr = AccountId::new([6;32]); - let liquidity_pool_id = AccountId::new([7;32]); - let liquidity_pool_supply: u128 = 30u128; - let reserve_a: u128 = 1500u128; - let reserve_b: u128 = 2000u128; - let token_program_id: [u32;8] = [0; 8]; - - pool.data = PoolDefinition::into_data( PoolDefinition { - definition_token_a_id: definition_token_a_id.clone(), - definition_token_b_id: definition_token_b_id.clone(), - vault_a_addr: vault_a_addr.clone(), - vault_b_addr: vault_b_addr.clone(), - liquidity_pool_id, - liquidity_pool_supply, - reserve_a, - reserve_b, - token_program_id, - }); - - let pre_states = vec![AccountWithMetadata { - account: pool, - is_authorized: true, - account_id: AccountId::new([0; 32])}, - AccountWithMetadata { - account: vault1, - is_authorized: true, - account_id: vault_a_addr.clone()}, - AccountWithMetadata { - account: vault2, - is_authorized: true, - account_id: vault_b_addr.clone()}, - AccountWithMetadata { - account: pool_lp, - is_authorized: true, - account_id: AccountId::new([4; 32])}, - AccountWithMetadata { - account: user_holding_a, - is_authorized: true, - account_id: AccountId::new([5; 32])}, - AccountWithMetadata { - account: user_holding_b, - is_authorized: true, - account_id: AccountId::new([6; 32])}, - AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([7; 32])}, - ]; - let balance_a = 1u128; - let balance_b = 1u128; - let main_token = definition_token_b_id.clone(); - let _post_states = add_liquidity(&pre_states, &[balance_a,balance_b], main_token); + fn test_call_add_liquidity_actual_amount_zero_2() { + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init_reserve_b_low), + helper_account_constructor(AccountEnum::vault_a_init_high), + helper_account_constructor(AccountEnum::vault_b_init_low), + helper_account_constructor(AccountEnum::pool_lp_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + helper_account_constructor(AccountEnum::user_holding_lp_init), + ]; + let _post_states = add_liquidity(&pre_states, + &[helper_balance_constructor(BalanceEnum::add_max_amount_a_low), + helper_balance_constructor(BalanceEnum::add_max_amount_b_low), + helper_balance_constructor(BalanceEnum::add_min_amount_lp),], + ); } #[should_panic(expected = "Reserves must be nonzero")] #[test] fn test_call_add_liquidity_reserves_zero_1() { - let mut pool = Account::default(); - let mut vault1 = Account::default(); - let mut vault2 = Account::default(); - let mut pool_lp = Account::default(); - - - let definition_token_a_id = AccountId::new([1;32]); - let definition_token_b_id = AccountId::new([2;32]); - - vault1.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 15u128 } - ); - - vault2.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_b_id.clone(), - balance: 15u128 } - ); - - pool_lp.data = vec![ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; - - let vault_a_addr = AccountId::new([5;32]); - let vault_b_addr = AccountId::new([6;32]); - let liquidity_pool_id = AccountId::new([7;32]); - let liquidity_pool_supply: u128 = 30u128; - let reserve_a: u128 = 15; - let reserve_b: u128 = 0; - let token_program_id: [u32;8] = [0; 8]; - - pool.data = PoolDefinition::into_data( PoolDefinition { - definition_token_a_id: definition_token_a_id.clone(), - definition_token_b_id: definition_token_b_id.clone(), - vault_a_addr: vault_a_addr.clone(), - vault_b_addr: vault_b_addr.clone(), - liquidity_pool_id, - liquidity_pool_supply, - reserve_a, - reserve_b, - token_program_id, - }); - - let mut user_holding_a = Account::default(); - let mut user_holding_b = Account::default(); - - let pre_states = vec![AccountWithMetadata { - account: pool, - is_authorized: true, - account_id: AccountId::new([0; 32])}, - AccountWithMetadata { - account: vault1, - is_authorized: true, - account_id: vault_a_addr.clone()}, - AccountWithMetadata { - account: vault2, - is_authorized: true, - account_id: vault_b_addr.clone()}, - AccountWithMetadata { - account: pool_lp, - is_authorized: true, - account_id: AccountId::new([4; 32])}, - AccountWithMetadata { - account: user_holding_a, - is_authorized: true, - account_id: AccountId::new([5; 32])}, - AccountWithMetadata { - account: user_holding_b, - is_authorized: true, - account_id: AccountId::new([6; 32])}, - AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([7; 32])}, - ]; - let balance_a = 15u128; - let balance_b = 15u128; - let main_token = definition_token_b_id.clone(); - let _post_states = add_liquidity(&pre_states, &[balance_a,balance_b], main_token); + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init_reserve_a_zero), + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::pool_lp_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + helper_account_constructor(AccountEnum::user_holding_lp_init), + ]; + let _post_states = add_liquidity(&pre_states, + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::add_max_amount_b), + helper_balance_constructor(BalanceEnum::add_min_amount_lp),], + ); } #[should_panic(expected = "Reserves must be nonzero")] #[test] - fn test_call_add_liquidity_reserves_zero() { - let mut pool = Account::default(); - let mut vault1 = Account::default(); - let mut vault2 = Account::default(); - let mut pool_lp = Account::default(); + fn test_call_add_liquidity_reserves_zero_2() { + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init_reserve_b_zero), + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::pool_lp_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + helper_account_constructor(AccountEnum::user_holding_lp_init), + ]; + let _post_states = add_liquidity(&pre_states, + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::add_max_amount_b), + helper_balance_constructor(BalanceEnum::add_min_amount_lp),], + ); + } - let definition_token_a_id = AccountId::new([1;32]); - let definition_token_b_id = AccountId::new([2;32]); - - vault1.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 15u128 } - ); - - vault2.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_b_id.clone(), - balance: 15u128 } - ); - - pool_lp.data = vec![ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; - - let vault_a_addr = AccountId::new([5;32]); - let vault_b_addr = AccountId::new([6;32]); - let liquidity_pool_id = AccountId::new([7;32]); - let liquidity_pool_supply: u128 = 30u128; - let reserve_a: u128 = 0; - let reserve_b: u128 = 15; - let token_program_id: [u32;8] = [0; 8]; - - pool.data = PoolDefinition::into_data( PoolDefinition { - definition_token_a_id: definition_token_a_id.clone(), - definition_token_b_id: definition_token_b_id.clone(), - vault_a_addr: vault_a_addr.clone(), - vault_b_addr: vault_b_addr.clone(), - liquidity_pool_id, - liquidity_pool_supply, - reserve_a, - reserve_b, - token_program_id, - }); - - let mut user_holding_a = Account::default(); - let mut user_holding_b = Account::default(); - - let pre_states = vec![AccountWithMetadata { - account: pool, - is_authorized: true, - account_id: AccountId::new([0; 32])}, - AccountWithMetadata { - account: vault1, - is_authorized: true, - account_id: vault_a_addr.clone()}, - AccountWithMetadata { - account: vault2, - is_authorized: true, - account_id: vault_b_addr.clone()}, - AccountWithMetadata { - account: pool_lp, - is_authorized: true, - account_id: AccountId::new([4; 32])}, - AccountWithMetadata { - account: user_holding_a, - is_authorized: true, - account_id: AccountId::new([5; 32])}, - AccountWithMetadata { - account: user_holding_b, - is_authorized: true, - account_id: AccountId::new([6; 32])}, - AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([7; 32])}, - ]; - let balance_a = 15u128; - let balance_b = 15u128; - let main_token = definition_token_b_id.clone(); - let _post_states = add_liquidity(&pre_states, &[balance_a,balance_b], main_token); + #[should_panic(expected = "Payable LP must be nonzero")] + #[test] + fn test_call_add_liquidity_payable_lp_zero() { + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_add_zero_lp), + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::pool_lp_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + helper_account_constructor(AccountEnum::user_holding_lp_init), + ]; + let _post_states = add_liquidity(&pre_states, + &[helper_balance_constructor(BalanceEnum::add_max_amount_a_low), + helper_balance_constructor(BalanceEnum::add_max_amount_b_low), + helper_balance_constructor(BalanceEnum::add_min_amount_lp),], + ); } #[test] - fn test_call_add_liquidity_chain_call_success_1() { - let mut pool = Account::default(); - let mut vault_a = Account::default(); - let mut vault_b = Account::default(); - let mut user_holding_a = Account::default(); - let mut user_holding_b = Account::default(); - let mut pool_lp = Account::default(); - let mut user_holding_lp = Account::default(); - - let definition_token_a_id = AccountId::new([1;32]); - let definition_token_b_id = AccountId::new([2;32]); - - vault_a.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 15u128 } - ); - - vault_b.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_b_id.clone(), - balance: 15u128 } - ); - - pool_lp.data = vec![ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; - - let liquidity_pool_id = AccountId::new([7;32]); - let liquidity_pool_supply: u128 = 30u128; - let reserve_a: u128 = 30; - let reserve_b: u128 = 20; - let user_holding_lp_amt: u128 = 10; - let token_program_id: [u32;8] = [0; 8]; - let vault_a_addr = AccountId::new([7;32]); - let vault_b_addr = AccountId::new([9;32]); - - pool.data = PoolDefinition::into_data( PoolDefinition { - definition_token_a_id: definition_token_a_id.clone(), - definition_token_b_id: definition_token_b_id.clone(), - vault_a_addr: vault_a_addr.clone(), - vault_b_addr: vault_b_addr.clone(), - liquidity_pool_id, - liquidity_pool_supply: reserve_a, - reserve_a, - reserve_b, - token_program_id, - }); - - user_holding_a.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 50u128 } - ); - - user_holding_b.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_b_id.clone(), - balance: 50u128 } - ); - - user_holding_lp.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id: AccountId::new([3;32]), - balance: user_holding_lp_amt } - ); - - let user_holding_a = AccountWithMetadata { - account: user_holding_a.clone(), - is_authorized: true, - account_id: AccountId::new([5; 32])}; + fn test_call_add_liquidity_successful_chain_call() { + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::pool_lp_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + helper_account_constructor(AccountEnum::user_holding_lp_init), + ]; + let (post_states, chained_calls) = add_liquidity(&pre_states, + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::add_max_amount_b), + helper_balance_constructor(BalanceEnum::add_min_amount_lp),], + ); - let user_holding_b = AccountWithMetadata { - account: user_holding_b.clone(), - is_authorized: true, - account_id: AccountId::new([6; 32])}; + let pool_post = post_states[0].clone(); - let user_holding_lp = AccountWithMetadata { - account: user_holding_lp.clone(), - is_authorized: true, - account_id: AccountId::new([7; 32]) - }; - - let vault_a = AccountWithMetadata { - account: vault_a.clone(), - is_authorized: true, - account_id: vault_a_addr.clone()}; - - let vault_b = AccountWithMetadata { - account: vault_b.clone(), - is_authorized: true, - account_id: vault_b_addr.clone()}; - - let pool_lp = AccountWithMetadata { - account: pool_lp.clone(), - is_authorized: true, - account_id: AccountId::new([4; 32])}; - - let pre_states = vec![AccountWithMetadata { - account: pool.clone(), - is_authorized: true, - account_id: AccountId::new([0; 32])}, - vault_a.clone(), - vault_b.clone(), - pool_lp.clone(), - user_holding_a.clone(), - user_holding_b.clone(), - user_holding_lp.clone(), - ]; - - let balance_a = 10u128; - let balance_b = 30u128; - let main_token = definition_token_a_id.clone(); - let (post_states, chained_calls) = add_liquidity(&pre_states, &[balance_a,balance_b], main_token); + assert!(helper_account_constructor(AccountEnum::pool_definition_add_successful).account == + pool_post); let chained_call_lp = chained_calls[0].clone(); let chained_call_b = chained_calls[1].clone(); let chained_call_a = chained_calls[2].clone(); - - //Expected amounts - let expected_actual_amount_a = balance_a; - //Uses: (pool_def_data.reserve_b*actual_amount_a)/pool_def_data.reserve_a - let expected_actual_amount_b = (reserve_b*expected_actual_amount_a)/reserve_a; - let expected_delta_lp = (reserve_a * expected_actual_amount_b)/reserve_b; - //Expected chain_call for Token A - let mut instruction: [u8;23] = [0; 23]; - instruction[0] = 1; - instruction[1..17].copy_from_slice(&expected_actual_amount_a.to_le_bytes()); - let instruction_data = risc0_zkvm::serde::to_vec(&instruction).unwrap(); - let expected_chained_call_a = ChainedCall{ - program_id: token_program_id, - instruction_data, - pre_states: vec![user_holding_a.clone(), vault_a.clone()], - }; - //Expected chain call for Token B - let mut instruction: [u8;23] = [0; 23]; - instruction[0] = 1; - instruction[1..17].copy_from_slice(&expected_actual_amount_b.to_le_bytes()); - let instruction_data = risc0_zkvm::serde::to_vec(&instruction).unwrap(); - let expected_chained_call_b = ChainedCall{ - program_id: token_program_id, - instruction_data, - pre_states: vec![user_holding_b.clone(), vault_b.clone()], - }; - - //Expected chain call for LP - let mut instruction: [u8;23] = [0; 23]; - instruction[0] = 1; - instruction[1..17].copy_from_slice(&expected_delta_lp.to_le_bytes()); - let instruction_data = risc0_zkvm::serde::to_vec(&instruction).unwrap(); - let expected_chained_call_lp = ChainedCall{ - program_id: token_program_id, - instruction_data, - pre_states: vec![pool_lp.clone(), user_holding_lp.clone()], - }; - - assert!(chained_call_a.program_id == expected_chained_call_a.program_id); - assert!(chained_call_a.instruction_data == expected_chained_call_a.instruction_data); - assert!(chained_call_a.pre_states[0].account == expected_chained_call_a.pre_states[0].account); - assert!(chained_call_a.pre_states[1].account == expected_chained_call_a.pre_states[1].account); - assert!(chained_call_b.program_id == expected_chained_call_b.program_id); - assert!(chained_call_b.instruction_data == expected_chained_call_b.instruction_data); - assert!(chained_call_b.pre_states[0].account == expected_chained_call_b.pre_states[0].account); - assert!(chained_call_b.pre_states[1].account == expected_chained_call_b.pre_states[1].account); - assert!(chained_call_lp.program_id == expected_chained_call_lp.program_id); - assert!(chained_call_lp.instruction_data == expected_chained_call_lp.instruction_data); - assert!(chained_call_lp.pre_states[0].account == expected_chained_call_lp.pre_states[0].account); - assert!(chained_call_lp.pre_states[1].account == expected_chained_call_lp.pre_states[1].account); - } - - #[test] - fn test_call_add_liquidity_chain_call_success_2() { - let mut pool = Account::default(); - let mut vault_a = Account::default(); - let mut vault_b = Account::default(); - let mut user_holding_a = Account::default(); - let mut user_holding_b = Account::default(); - let mut pool_lp = Account::default(); - let mut user_holding_lp = Account::default(); - - let definition_token_a_id = AccountId::new([1;32]); - let definition_token_b_id = AccountId::new([2;32]); - - vault_a.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 15u128 } - ); - - vault_b.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_b_id.clone(), - balance: 15u128 } - ); - - pool_lp.data = vec![ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; - - let vault_a_addr = AccountId::new([5;32]); - let vault_b_addr = AccountId::new([6;32]); - let liquidity_pool_id = AccountId::new([7;32]); - let liquidity_pool_supply: u128 = 30u128; - let reserve_a: u128 = 30; - let reserve_b: u128 = 20; - let user_holding_lp_amt: u128 = 10; - let token_program_id: [u32;8] = [0; 8]; - let vault_a_addr = AccountId::new([2;32]); - let vault_b_addr = AccountId::new([3;32]); - - pool.data = PoolDefinition::into_data( PoolDefinition { - definition_token_a_id: definition_token_a_id.clone(), - definition_token_b_id: definition_token_b_id.clone(), - vault_a_addr: vault_a_addr.clone(), - vault_b_addr: vault_b_addr.clone(), - liquidity_pool_id, - liquidity_pool_supply: reserve_a, - reserve_a, - reserve_b, - token_program_id, - }); - - user_holding_a.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 50u128 } - ); - - user_holding_b.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_b_id.clone(), - balance: 50u128 } - ); - - user_holding_lp.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id: AccountId::new([3;32]), - balance: user_holding_lp_amt } - ); - - let user_holding_a = AccountWithMetadata { - account: user_holding_a.clone(), - is_authorized: true, - account_id: AccountId::new([5; 32])}; - - let user_holding_b = AccountWithMetadata { - account: user_holding_b.clone(), - is_authorized: true, - account_id: AccountId::new([6; 32])}; - - let user_holding_lp = AccountWithMetadata { - account: user_holding_lp.clone(), - is_authorized: true, - account_id: AccountId::new([7; 32]) - }; - - let vault_a = AccountWithMetadata { - account: vault_a.clone(), - is_authorized: true, - account_id: vault_a_addr.clone()}; - - let vault_b = AccountWithMetadata { - account: vault_b.clone(), - is_authorized: true, - account_id: vault_b_addr.clone()}; - - let pool_lp = AccountWithMetadata { - account: pool_lp.clone(), - is_authorized: true, - account_id: AccountId::new([4; 32])}; - - let pre_states = vec![AccountWithMetadata { - account: pool.clone(), - is_authorized: true, - account_id: AccountId::new([0; 32])}, - vault_a.clone(), - vault_b.clone(), - pool_lp.clone(), - user_holding_a.clone(), - user_holding_b.clone(), - user_holding_lp.clone(), - ]; - - let balance_a = 40u128; - let balance_b = 20u128; - let main_token = definition_token_b_id.clone(); - let (post_states, chained_calls) = add_liquidity(&pre_states, &[balance_a,balance_b], main_token); - - let chained_call_lp = chained_calls[0].clone(); - let chained_call_b = chained_calls[1].clone(); - let chained_call_a = chained_calls[2].clone(); - - //Expected amounts - let expected_actual_amount_b = balance_b; - //Uses: (pool_def_data.reserve_b*actual_amount_a)/pool_def_data.reserve_a - let expected_actual_amount_a = (reserve_a*expected_actual_amount_b)/reserve_b; - let expected_delta_lp = (reserve_a * expected_actual_amount_b)/reserve_b; - - //Expected chain_call for Token A - let mut instruction: [u8;23] = [0; 23]; - instruction[0] = 1; - instruction[1..17].copy_from_slice(&expected_actual_amount_a.to_le_bytes()); - let instruction_data = risc0_zkvm::serde::to_vec(&instruction).unwrap(); - let expected_chained_call_a = ChainedCall{ - program_id: token_program_id, - instruction_data, - pre_states: vec![user_holding_a.clone(), vault_a.clone()], - }; - - //Expected chain call for Token B - let mut instruction: [u8;23] = [0; 23]; - instruction[0] = 1; - instruction[1..17].copy_from_slice(&expected_actual_amount_b.to_le_bytes()); - let instruction_data = risc0_zkvm::serde::to_vec(&instruction).unwrap(); - let expected_chained_call_b = ChainedCall{ - program_id: token_program_id, - instruction_data, - pre_states: vec![user_holding_b.clone(), vault_b.clone()], - }; - - //Expected chain call for LP - let mut instruction: [u8;23] = [0; 23]; - instruction[0] = 1; - instruction[1..17].copy_from_slice(&expected_delta_lp.to_le_bytes()); - let instruction_data = risc0_zkvm::serde::to_vec(&instruction).unwrap(); - let expected_chained_call_lp = ChainedCall{ - program_id: token_program_id, - instruction_data, - pre_states: vec![pool_lp.clone(), user_holding_lp.clone()], - }; - - assert!(chained_call_a.program_id == expected_chained_call_a.program_id); - assert!(chained_call_a.instruction_data == expected_chained_call_a.instruction_data); - assert!(chained_call_a.pre_states[0].account == expected_chained_call_a.pre_states[0].account); - assert!(chained_call_a.pre_states[1].account == expected_chained_call_a.pre_states[1].account); - assert!(chained_call_b.program_id == expected_chained_call_b.program_id); - assert!(chained_call_b.instruction_data == expected_chained_call_b.instruction_data); - assert!(chained_call_b.pre_states[0].account == expected_chained_call_b.pre_states[0].account); - assert!(chained_call_b.pre_states[1].account == expected_chained_call_b.pre_states[1].account); - assert!(chained_call_lp.program_id == expected_chained_call_lp.program_id); - assert!(chained_call_lp.instruction_data == expected_chained_call_lp.instruction_data); - assert!(chained_call_lp.pre_states[0].account == expected_chained_call_lp.pre_states[0].account); - assert!(chained_call_lp.pre_states[1].account == expected_chained_call_lp.pre_states[1].account); + assert!(chained_call_a == helper_chained_call_constructor(ChainedCallsEnum::cc_add_token_a)); + assert!(chained_call_b == helper_chained_call_constructor(ChainedCallsEnum::cc_add_token_b)); + assert!(chained_call_lp == helper_chained_call_constructor(ChainedCallsEnum::cc_add_pool_lp)); } #[should_panic(expected = "Invalid number of input accounts")] #[test] fn test_call_swap_with_invalid_number_of_accounts_1() { - let pre_states = vec![AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([1; 32]), - }]; - - let amount = 15u128; - let vault_addr = AccountId::new([1;32]); - let _post_states = swap(&pre_states, amount, vault_addr); + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + ]; + let _post_states = swap(&pre_states, + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::min_amount_out)], + helper_id_constructor(IdEnum::token_a_definition_id), + ); } #[should_panic(expected = "Invalid number of input accounts")] #[test] fn test_call_swap_with_invalid_number_of_accounts_2() { - let pre_states = vec![AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([1; 32])}, - AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([2; 32])}, - ]; - let amount = 15u128; - let vault_addr = AccountId::new([1;32]); - let _post_states = swap(&pre_states, amount, vault_addr); + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_init), + ]; + let _post_states = swap(&pre_states, + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::min_amount_out)], + helper_id_constructor(IdEnum::token_a_definition_id), + ); } #[should_panic(expected = "Invalid number of input accounts")] #[test] fn test_call_swap_with_invalid_number_of_accounts_3() { - let pre_states = vec![AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([1; 32])}, - AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([2; 32])}, - AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([3; 32])}, - ]; - let amount = 15u128; - let vault_addr = AccountId::new([1;32]); - let _post_states = swap(&pre_states, amount, vault_addr); + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::vault_b_init), + ]; + let _post_states = swap(&pre_states, + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::min_amount_out)], + helper_id_constructor(IdEnum::token_a_definition_id), + ); } #[should_panic(expected = "Invalid number of input accounts")] #[test] fn test_call_swap_with_invalid_number_of_accounts_4() { - let pre_states = vec![AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([1; 32])}, - AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([2; 32])}, - AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([3; 32])}, - AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([4; 32])}, - ]; - let amount = 15u128; - let vault_addr = AccountId::new([1;32]); - let _post_states = swap(&pre_states, amount, vault_addr); + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::user_holding_a), + ]; + let _post_states = swap(&pre_states, + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::min_amount_out)], + helper_id_constructor(IdEnum::token_a_definition_id), + ); + } + + #[should_panic(expected = "Invalid number of amounts provided")] + #[test] + fn test_call_swap_with_invalid_number_of_amounts() { + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + ]; + let _post_states = swap(&pre_states, + &[helper_balance_constructor(BalanceEnum::add_max_amount_a)], + helper_id_constructor(IdEnum::token_lp_definition_id), + ); } #[should_panic(expected = "AccountId is not a token type for the pool")] #[test] fn test_call_swap_incorrect_token_type() { - let mut pool = Account::default(); - let mut vault_a = Account::default(); - let mut vault_b = Account::default(); - let mut pool_lp = Account::default(); - let mut user_holding_a = Account::default(); - let mut user_holding_b = Account::default(); - - let definition_token_a_id = AccountId::new([1;32]); - let definition_token_b_id = AccountId::new([2;32]); - - vault_a.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 15u128 } - ); - - vault_b.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_b_id.clone(), - balance: 20u128 } - ); - - pool_lp.data = vec![ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; - user_holding_a.data = vec![ - 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; - user_holding_b.data = vec![ - 1, 1, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; - - let definition_token_a_id = AccountId::new([1;32]); - let definition_token_b_id = AccountId::new([2;32]); - let vault_a_addr = AccountId::new([5;32]); - let vault_b_addr = AccountId::new([6;32]); - let liquidity_pool_id = AccountId::new([7;32]); - let liquidity_pool_supply: u128 = 30u128; - let reserve_a: u128 = 15; - let reserve_b: u128 = 20; - let token_program_id: [u32;8] = [5; 8]; - - pool.data = PoolDefinition::into_data( - PoolDefinition { - definition_token_a_id: definition_token_a_id.clone(), - definition_token_b_id: definition_token_b_id.clone(), - vault_a_addr: vault_a_addr.clone(), - vault_b_addr: vault_b_addr.clone(), - liquidity_pool_id, - liquidity_pool_supply, - reserve_a, - reserve_b, - token_program_id, - } - ); - - let pre_states = vec![AccountWithMetadata { - account: pool.clone(), - is_authorized: true, - account_id: AccountId::new([0; 32])}, - AccountWithMetadata { - account: vault_a.clone(), - is_authorized: true, - account_id: vault_a_addr.clone()}, - AccountWithMetadata { - account: vault_b.clone(), - is_authorized: true, - account_id: vault_b_addr.clone()}, - AccountWithMetadata { - account: user_holding_a.clone(), - is_authorized: true, - account_id: AccountId::new([4; 32])}, - AccountWithMetadata { - account: user_holding_b.clone(), - is_authorized: true, - account_id: AccountId::new([5; 32])} - ]; - let amount = 15u128; - let token_addr = AccountId::new([42;32]); - let (post_accounts, chain_calls) = swap(&pre_states, amount, token_addr); + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + ]; + let _post_states = swap(&pre_states, + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::min_amount_out)], + helper_id_constructor(IdEnum::token_lp_definition_id), + ); } #[should_panic(expected = "Vault A was not provided")] #[test] fn test_call_swap_vault_a_omitted() { - let mut pool = Account::default(); - let mut vault1 = Account::default(); - let mut vault2 = Account::default(); - let mut pool_lp = Account::default(); - - - let definition_token_a_id = AccountId::new([1;32]); - let definition_token_b_id = AccountId::new([2;32]); - - vault1.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 15u128 } - ); - - vault2.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_b_id.clone(), - balance: 15u128 } - ); - - pool_lp.data = vec![ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; - - - let vault_a_addr = AccountId::new([5;32]); - let vault_b_addr = AccountId::new([6;32]); - let liquidity_pool_id = AccountId::new([7;32]); - let liquidity_pool_supply: u128 = 30u128; - let reserve_a: u128 = 10; - let reserve_b: u128 = 20; - let token_program_id: [u32;8] = [0; 8]; - - pool.data = PoolDefinition::into_data( PoolDefinition { - definition_token_a_id, - definition_token_b_id, - vault_a_addr: vault_a_addr.clone(), - vault_b_addr: vault_b_addr.clone(), - liquidity_pool_id, - liquidity_pool_supply, - reserve_a, - reserve_b, - token_program_id, - }); - - let pre_states = vec![AccountWithMetadata { - account: pool, - is_authorized: true, - account_id: AccountId::new([0; 32])}, - AccountWithMetadata { - account: vault1, - is_authorized: true, - account_id: vault_b_addr.clone()}, - AccountWithMetadata { - account: vault2, - is_authorized: true, - account_id: vault_b_addr.clone()}, - AccountWithMetadata { - account: pool_lp, - is_authorized: true, - account_id: AccountId::new([4; 32])}, - AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([5; 32])} - ]; - let amount = 15u128; - let vault_addr = AccountId::new([0;32]); - let _post_states = swap(&pre_states, amount, vault_addr); + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_wrong_acc_id), + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + ]; + let _post_states = swap(&pre_states, + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::min_amount_out)], + helper_id_constructor(IdEnum::token_a_definition_id), + ); } #[should_panic(expected = "Vault B was not provided")] #[test] fn test_call_swap_vault_b_omitted() { - let mut pool = Account::default(); - let mut vault1 = Account::default(); - let mut vault2 = Account::default(); - let mut pool_lp = Account::default(); + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::vault_b_wrong_acc_id), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + ]; + let _post_states = swap(&pre_states, + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::min_amount_out)], + helper_id_constructor(IdEnum::token_a_definition_id), + ); + } + #[should_panic(expected = "Reserve for Token A exceeds vault balance")] + #[test] + fn test_call_swap_reserves_vault_mismatch_1() { + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_init_low), + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + ]; + let _post_states = swap(&pre_states, + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::min_amount_out)], + helper_id_constructor(IdEnum::token_a_definition_id), + ); + } - let definition_token_a_id = AccountId::new([1;32]); - let definition_token_b_id = AccountId::new([2;32]); + #[should_panic(expected = "Reserve for Token B exceeds vault balance")] + #[test] + fn test_call_swap_reserves_vault_misatch_2() { + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::vault_b_init_low), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + ]; + let _post_states = swap(&pre_states, + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::min_amount_out)], + helper_id_constructor(IdEnum::token_a_definition_id), + ); + } - vault1.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 15u128 } - ); - - vault2.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_b_id.clone(), - balance: 15u128 } - ); - - pool_lp.data = vec![ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; - - let definition_token_a_id = AccountId::new([1;32]); - let definition_token_b_id = AccountId::new([2;32]); - let vault_a_addr = AccountId::new([5;32]); - let vault_b_addr = AccountId::new([6;32]); - let liquidity_pool_id = AccountId::new([7;32]); - let liquidity_pool_supply: u128 = 30u128; - let reserve_a: u128 = 10; - let reserve_b: u128 = 20; - let token_program_id: [u32;8] = [0; 8]; - - pool.data = PoolDefinition::into_data( PoolDefinition { - definition_token_a_id, - definition_token_b_id, - vault_a_addr: vault_a_addr.clone(), - vault_b_addr: vault_b_addr.clone(), - liquidity_pool_id, - liquidity_pool_supply, - reserve_a, - reserve_b, - token_program_id, - }); - - let pre_states = vec![AccountWithMetadata { - account: pool, - is_authorized: true, - account_id: AccountId::new([0; 32])}, - AccountWithMetadata { - account: vault1, - is_authorized: true, - account_id: vault_a_addr.clone()}, - AccountWithMetadata { - account: vault2, - is_authorized: true, - account_id: vault_a_addr.clone()}, - AccountWithMetadata { - account: pool_lp, - is_authorized: true, - account_id: AccountId::new([4; 32])}, - AccountWithMetadata { - account: Account::default(), - is_authorized: true, - account_id: AccountId::new([5; 32])} - ]; - let amount = 15u128; - let vault_addr = AccountId::new([0;32]); - let _post_states = swap(&pre_states, amount, vault_addr); + #[should_panic(expected = "Withdraw amount is less than minimal amount out")] + #[test] + fn test_call_swap_below_min_out() { + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + ]; + let _post_states = swap(&pre_states, + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::min_amount_out)], + helper_id_constructor(IdEnum::token_a_definition_id), + ); } #[test] fn test_call_swap_successful_chain_call_1() { - let mut pool = Account::default(); - let mut vault_a = Account::default(); - let mut vault_b = Account::default(); - let mut pool_lp = Account::default(); - let mut user_holding_a = Account::default(); - let mut user_holding_b = Account::default(); + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + ]; + let (post_states, chained_calls) = swap(&pre_states, + &[helper_balance_constructor(BalanceEnum::add_max_amount_a), + helper_balance_constructor(BalanceEnum::add_max_amount_a_low)], + helper_id_constructor(IdEnum::token_a_definition_id), + ); + + let pool_post = post_states[0].clone(); - let definition_token_a_id = AccountId::new([1;32]); - let definition_token_b_id = AccountId::new([2;32]); + assert!(helper_account_constructor(AccountEnum::pool_definition_swap_test_1).account == + pool_post); - vault_a.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 15u128 } - ); + let chained_call_a = chained_calls[0].clone(); + let chained_call_b = chained_calls[1].clone(); - vault_b.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_b_id.clone(), - balance: 20u128 } - ); - - pool_lp.data = vec![ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; - user_holding_a.data = vec![ - 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; - user_holding_b.data = vec![ - 1, 1, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; - - let definition_token_a_id = AccountId::new([1;32]); - let definition_token_b_id = AccountId::new([2;32]); - let vault_a_addr = AccountId::new([5;32]); - let vault_b_addr = AccountId::new([6;32]); - let liquidity_pool_id = AccountId::new([7;32]); - let liquidity_pool_supply: u128 = 30u128; - let reserve_a: u128 = 15; - let reserve_b: u128 = 20; - let token_program_id: [u32;8] = [5; 8]; - - user_holding_a.program_owner = token_program_id; - user_holding_b.program_owner = token_program_id; - vault_a.program_owner = token_program_id; - vault_b.program_owner = token_program_id; - - pool.data = PoolDefinition::into_data( - PoolDefinition { - definition_token_a_id: definition_token_a_id.clone(), - definition_token_b_id: definition_token_b_id.clone(), - vault_a_addr: vault_a_addr.clone(), - vault_b_addr: vault_b_addr.clone(), - liquidity_pool_id, - liquidity_pool_supply, - reserve_a, - reserve_b, - token_program_id, - } - ); - - let pre_states = vec![AccountWithMetadata { - account: pool.clone(), - is_authorized: true, - account_id: AccountId::new([0; 32])}, - AccountWithMetadata { - account: vault_a.clone(), - is_authorized: true, - account_id: vault_a_addr.clone()}, - AccountWithMetadata { - account: vault_b.clone(), - is_authorized: true, - account_id: vault_b_addr.clone()}, - AccountWithMetadata { - account: user_holding_a.clone(), - is_authorized: true, - account_id: AccountId::new([4; 32])}, - AccountWithMetadata { - account: user_holding_b.clone(), - is_authorized: true, - account_id: AccountId::new([5; 32])} - ]; - let amount = 15u128; - - let token_addr = definition_token_a_id; - let (post_accounts, chain_calls) = swap(&pre_states, amount, token_addr); - - let pool_post = post_accounts[0].clone(); - let pool_pre_data = PoolDefinition::parse(&pool.data).unwrap(); - let pool_post_data = PoolDefinition::parse(&pool_post.data).unwrap(); - assert!(pool_post_data.reserve_a == pool_pre_data.reserve_a + amount); - - let expected_withdraw = (pool_pre_data.reserve_b * amount)/(pool_pre_data.reserve_a + amount); - assert!(pool_post_data.reserve_b == pool_pre_data.reserve_b - expected_withdraw); - - let chain_call_a = chain_calls[0].clone(); - let chain_call_b = chain_calls[1].clone(); - - assert!(chain_call_b.program_id == token_program_id); - assert!(chain_call_a.program_id == token_program_id); - - let mut instruction_data = [0; 23]; - instruction_data[0] = 1; - instruction_data[1..17].copy_from_slice(&amount.to_le_bytes()); - let expected_instruction_data_0 = risc0_zkvm::serde::to_vec(&instruction_data).unwrap(); - let mut instruction_data = [0; 23]; - instruction_data[0] = 1; - instruction_data[1..17].copy_from_slice(&expected_withdraw.to_le_bytes()); - let expected_instruction_data_1 = risc0_zkvm::serde::to_vec(&instruction_data).unwrap(); - - let chain_call_a_account0 = chain_call_a.pre_states[0].account.clone(); - let chain_call_a_account1 = chain_call_a.pre_states[1].account.clone(); - - let chain_call_b_account0 = chain_call_b.pre_states[0].account.clone(); - let chain_call_b_account1 = chain_call_b.pre_states[1].account.clone(); - - assert!(chain_call_a.instruction_data == expected_instruction_data_0); - assert!(chain_call_a_account0 == user_holding_a); - assert!(chain_call_a_account1 == vault_a); - assert!(chain_call_b.instruction_data == expected_instruction_data_1); - assert!(chain_call_b_account0 == vault_b); - assert!(chain_call_b_account1 == user_holding_b); + assert!(chained_call_a == helper_chained_call_constructor(ChainedCallsEnum::cc_swap_token_a_test_1)); + assert!(chained_call_b == helper_chained_call_constructor(ChainedCallsEnum::cc_swap_token_b_test_1)); } #[test] fn test_call_swap_successful_chain_call_2() { - let mut pool = Account::default(); - let mut vault_a = Account::default(); - let mut vault_b = Account::default(); - let mut pool_lp = Account::default(); - let mut user_holding_a = Account::default(); - let mut user_holding_b = Account::default(); + let pre_states = vec![ + helper_account_constructor(AccountEnum::pool_definition_init), + helper_account_constructor(AccountEnum::vault_a_init), + helper_account_constructor(AccountEnum::vault_b_init), + helper_account_constructor(AccountEnum::user_holding_a), + helper_account_constructor(AccountEnum::user_holding_b), + ]; + let (post_states, chained_calls) = swap(&pre_states, + &[helper_balance_constructor(BalanceEnum::add_max_amount_b), + helper_balance_constructor(BalanceEnum::min_amount_out)], + helper_id_constructor(IdEnum::token_b_definition_id), + ); + + let pool_post = post_states[0].clone(); - let definition_token_a_id = AccountId::new([1;32]); - let definition_token_b_id = AccountId::new([2;32]); + assert!(helper_account_constructor(AccountEnum::pool_definition_swap_test_2).account == + pool_post); - vault_a.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_a_id.clone(), - balance: 15u128 } - ); - - vault_b.data = TokenHolding::into_data( - TokenHolding { account_type: TOKEN_HOLDING_TYPE, - definition_id:definition_token_b_id.clone(), - balance: 20u128 } - ); - - pool_lp.data = vec![ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; - user_holding_a.data = vec![ - 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; - user_holding_b.data = vec![ - 1, 1, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ]; - - let definition_token_a_id = AccountId::new([1;32]); - let definition_token_b_id = AccountId::new([2;32]); - let vault_a_addr = AccountId::new([5;32]); - let vault_b_addr = AccountId::new([6;32]); - let liquidity_pool_id = AccountId::new([7;32]); - let liquidity_pool_supply: u128 = 30u128; - let reserve_a: u128 = 15; - let reserve_b: u128 = 20; - let token_program_id: [u32;8] = [5; 8]; - - user_holding_a.program_owner = token_program_id; - user_holding_b.program_owner = token_program_id; - vault_a.program_owner = token_program_id; - vault_b.program_owner = token_program_id; - - pool.data = PoolDefinition::into_data( - PoolDefinition { - definition_token_a_id: definition_token_a_id.clone(), - definition_token_b_id: definition_token_b_id.clone(), - vault_a_addr: vault_a_addr.clone(), - vault_b_addr: vault_b_addr.clone(), - liquidity_pool_id, - liquidity_pool_supply, - reserve_a, - reserve_b, - token_program_id, - } - ); - - let pre_states = vec![AccountWithMetadata { - account: pool.clone(), - is_authorized: true, - account_id: AccountId::new([0; 32])}, - AccountWithMetadata { - account: vault_a.clone(), - is_authorized: true, - account_id: vault_a_addr.clone()}, - AccountWithMetadata { - account: vault_b.clone(), - is_authorized: true, - account_id: vault_b_addr.clone()}, - AccountWithMetadata { - account: user_holding_a.clone(), - is_authorized: true, - account_id: AccountId::new([4; 32])}, - AccountWithMetadata { - account: user_holding_b.clone(), - is_authorized: true, - account_id: AccountId::new([5; 32])} - ]; - let amount = 15u128; - let token_addr = definition_token_b_id; - let (post_accounts, chain_calls) = swap(&pre_states, amount, token_addr); - - let pool_post = post_accounts[0].clone(); - let pool_pre_data = PoolDefinition::parse(&pool.data).unwrap(); - let pool_post_data = PoolDefinition::parse(&pool_post.data).unwrap(); - assert!(pool_post_data.reserve_b == pool_pre_data.reserve_b + amount); - - let expected_withdraw = (pool_pre_data.reserve_a * amount)/(pool_pre_data.reserve_b + amount); - assert!(pool_post_data.reserve_a == pool_pre_data.reserve_a - expected_withdraw); - - let chain_call_b = chain_calls[0].clone(); - let chain_call_a = chain_calls[1].clone(); - - assert!(chain_call_b.program_id == token_program_id); - assert!(chain_call_a.program_id == token_program_id); - - let mut instruction_data = [0; 23]; - instruction_data[0] = 1; - instruction_data[1..17].copy_from_slice(&expected_withdraw.to_le_bytes()); - let expected_instruction_data_0 = risc0_zkvm::serde::to_vec(&instruction_data).unwrap(); - let mut instruction_data = [0; 23]; - instruction_data[0] = 1; - instruction_data[1..17].copy_from_slice(&amount.to_le_bytes()); - let expected_instruction_data_1 = risc0_zkvm::serde::to_vec(&instruction_data).unwrap(); - - let chain_call_a_account0 = chain_call_a.pre_states[0].account.clone(); - let chain_call_a_account1 = chain_call_a.pre_states[1].account.clone(); - - let chain_call_b_account0 = chain_call_b.pre_states[0].account.clone(); - let chain_call_b_account1 = chain_call_b.pre_states[1].account.clone(); - - assert!(chain_call_a.instruction_data == expected_instruction_data_0); - assert!(chain_call_a_account0 == vault_a); - assert!(chain_call_a_account1 == user_holding_a); - assert!(chain_call_b.instruction_data == expected_instruction_data_1); - assert!(chain_call_b_account0 == user_holding_b); - assert!(chain_call_b_account1 == vault_b); + let chained_call_a = chained_calls[1].clone(); + let chained_call_b = chained_calls[0].clone(); + assert!(chained_call_a == helper_chained_call_constructor(ChainedCallsEnum::cc_swap_token_a_test_2)); + assert!(chained_call_b == helper_chained_call_constructor(ChainedCallsEnum::cc_swap_token_b_test_2)); } - - */ + } \ No newline at end of file diff --git a/nssa/src/state.rs b/nssa/src/state.rs index 4686d9d..7c1775e 100644 --- a/nssa/src/state.rs +++ b/nssa/src/state.rs @@ -2225,504 +2225,716 @@ pub mod tests { } } - const POOL_DEFINITION_DATA_SIZE: usize = 240; - struct PoolDefinition { - definition_token_a_id: AccountId, - definition_token_b_id: AccountId, - vault_a_addr: AccountId, - vault_b_addr: AccountId, - liquidity_pool_id: AccountId, - liquidity_pool_cap: u128, - reserve_a: u128, - reserve_b: u128, - token_program_id: ProgramId, +const POOL_DEFINITION_DATA_SIZE: usize = 225; +const MAX_NUMBER_POOLS: usize = 31; +const AMM_DEFINITION_DATA_SIZE: usize = 1024; + +struct AMMDefinition { + name: [u8;32], + pool_ids: Vec, +} + +impl AMMDefinition { + fn new(name: &[u8;32]) -> Vec { + + let mut bytes = [0; AMM_DEFINITION_DATA_SIZE]; + bytes[0..32].copy_from_slice(name); + bytes.into() } - impl PoolDefinition { - fn into_data(self) -> Vec { - let u8_token_program_id: [u8; 32] = bytemuck::cast(self.token_program_id); + fn into_data(self) -> Vec { + let size_of_pool: usize = self.pool_ids.len(); - let mut bytes = [0; POOL_DEFINITION_DATA_SIZE]; - bytes[0..32].copy_from_slice(&self.definition_token_a_id.to_bytes()); - bytes[32..64].copy_from_slice(&self.definition_token_b_id.to_bytes()); - bytes[64..96].copy_from_slice(&self.vault_a_addr.to_bytes()); - bytes[96..128].copy_from_slice(&self.vault_b_addr.to_bytes()); - bytes[128..160].copy_from_slice(&self.liquidity_pool_id.to_bytes()); - bytes[160..176].copy_from_slice(&self.liquidity_pool_cap.to_le_bytes()); - bytes[176..192].copy_from_slice(&self.reserve_a.to_le_bytes()); - bytes[192..208].copy_from_slice(&self.reserve_b.to_le_bytes()); - bytes[208..].copy_from_slice(&u8_token_program_id); - bytes.into() + let mut bytes = [0; AMM_DEFINITION_DATA_SIZE]; + for i in 0..size_of_pool-1 { + bytes[32*i..32*(i+1)].copy_from_slice(&self.pool_ids[i].to_bytes()) } - fn parse(data: &[u8]) -> Option { - if data.len() != POOL_DEFINITION_DATA_SIZE { - None - } else { - let definition_token_a_id = AccountId::new(data[0..32].try_into().unwrap()); - let definition_token_b_id = AccountId::new(data[32..64].try_into().unwrap()); - let vault_a_addr = AccountId::new(data[64..96].try_into().unwrap()); - let vault_b_addr = AccountId::new(data[96..128].try_into().unwrap()); - let liquidity_pool_id = AccountId::new(data[128..160].try_into().unwrap()); - let liquidity_pool_cap = u128::from_le_bytes(data[160..176].try_into().unwrap()); - let reserve_a = u128::from_le_bytes(data[176..192].try_into().unwrap()); - let reserve_b = u128::from_le_bytes(data[192..208].try_into().unwrap()); + for i in size_of_pool..MAX_NUMBER_POOLS { + bytes[32*i..32*(i+1)].copy_from_slice(&AccountId::default().to_bytes()) + } - let token_program_id: &[u32] = bytemuck::cast_slice(&data[208..]); - let token_program_id: ProgramId = token_program_id[0..8].try_into().unwrap(); - Some(Self { - definition_token_a_id, - definition_token_b_id, - vault_a_addr, - vault_b_addr, - liquidity_pool_id, - liquidity_pool_cap, - reserve_a, - reserve_b, - token_program_id, - }) - } + bytes.into() + } + + fn parse(data: &[u8]) -> Option { + if data.len() % 32 != 0 { + panic!("AMM data should be divisible by 32 (number of bytes per of AccountId"); + } + + let size_of_pool = data.len()/32; + + let mut name: [u8;32] = [0;32]; + name.copy_from_slice(&data[0..32]); + + let mut pool_ids = Vec::::new(); + + for i in 1..size_of_pool+1 { + pool_ids.push( + AccountId::new(data[i*32..(i+1)*32].try_into().expect("Parse data: The AMM program must be provided a valid AccountIds")) + ); + } + + for _ in size_of_pool..MAX_NUMBER_POOLS { + pool_ids.push( AccountId::default() ); + } + + Some( Self{ + name, + pool_ids + }) + } +} + +struct PoolDefinition{ + definition_token_a_id: AccountId, + definition_token_b_id: AccountId, + vault_a_addr: AccountId, + vault_b_addr: AccountId, + liquidity_pool_id: AccountId, + liquidity_pool_supply: u128, + reserve_a: u128, + reserve_b: u128, + fees: u128, + active: bool +} + +impl PoolDefinition { + fn into_data(self) -> Vec { + let mut bytes = [0; POOL_DEFINITION_DATA_SIZE]; + bytes[0..32].copy_from_slice(&self.definition_token_a_id.to_bytes()); + bytes[32..64].copy_from_slice(&self.definition_token_b_id.to_bytes()); + bytes[64..96].copy_from_slice(&self.vault_a_addr.to_bytes()); + bytes[96..128].copy_from_slice(&self.vault_b_addr.to_bytes()); + bytes[128..160].copy_from_slice(&self.liquidity_pool_id.to_bytes()); + bytes[160..176].copy_from_slice(&self.liquidity_pool_supply.to_le_bytes()); + bytes[176..192].copy_from_slice(&self.reserve_a.to_le_bytes()); + bytes[192..208].copy_from_slice(&self.reserve_b.to_le_bytes()); + bytes[208..224].copy_from_slice(&self.fees.to_le_bytes()); + bytes[224] = self.active as u8; + bytes.into() + } + + fn parse(data: &[u8]) -> Option { + if data.len() != POOL_DEFINITION_DATA_SIZE { + None + } else { + let definition_token_a_id = AccountId::new(data[0..32].try_into().expect("Parse data: The AMM program must be provided a valid AccountId for Token A definition")); + let definition_token_b_id = AccountId::new(data[32..64].try_into().expect("Parse data: The AMM program must be provided a valid AccountId for Vault B definition")); + let vault_a_addr = AccountId::new(data[64..96].try_into().expect("Parse data: The AMM program must be provided a valid AccountId for Vault A")); + let vault_b_addr = AccountId::new(data[96..128].try_into().expect("Parse data: The AMM program must be provided a valid AccountId for Vault B")); + let liquidity_pool_id = AccountId::new(data[128..160].try_into().expect("Parse data: The AMM program must be provided a valid AccountId for Token liquidity pool definition")); + let liquidity_pool_supply = u128::from_le_bytes(data[160..176].try_into().expect("Parse data: The AMM program must be provided a valid u128 for liquidity cap")); + let reserve_a = u128::from_le_bytes(data[176..192].try_into().expect("Parse data: The AMM program must be provided a valid u128 for reserve A balance")); + let reserve_b = u128::from_le_bytes(data[192..208].try_into().expect("Parse data: The AMM program must be provided a valid u128 for reserve B balance")); + let fees = u128::from_le_bytes(data[208..224].try_into().expect("Parse data: The AMM program must be provided a valid u128 for fees")); + + let active = match data[224] { + 0 => false, + 1 => true, + _ => panic!("Parse data: The AMM program must be provided a valid bool for active"), + }; + + Some(Self { + definition_token_a_id, + definition_token_b_id, + vault_a_addr, + vault_b_addr, + liquidity_pool_id, + liquidity_pool_supply, + reserve_a, + reserve_b, + fees, + active, + }) + } + } +} + + enum AccountsEnum { + amm, //TODO + pool_definition_uninit, //TODO + pool_definition_diff_amm, //Should point to AMM + user_token_a_holding, + user_token_a_holding_auth, + user_token_b_holding, + user_token_b_holding_auth, + //TODO all below (unless noted) + user_token_lp_holding, + user_token_lp_holding_auth, + pool_definition_init, + user_token_a_holding_init, + user_token_b_holding_init, + user_token_lp_holding_init, + pool_definition_remove, + user_token_a_holding_remove, + user_token_b_holding_remove, + user_token_lp_holding_remove, + token_a_definition_acc,// added + token_b_definition_acc,//added + token_lp_definition_acc,//added + vault_a_init, + vault_b_init, + vault_a_swap_1, + vault_b_swap_1, + user_token_a_holding_swap_1, + user_token_b_holding_swap_1, + pool_definition_swap_1, + vault_a_swap_2, + vault_b_swap_2, + user_token_a_holding_swap_2, + user_token_b_holding_swap_2, + pool_definition_swap_2, + vault_a_add, + vault_b_add, + user_token_a_holding_add, + user_token_b_holding_add, + user_token_lp_holding_add, + pool_definition_add, + token_lp_definition_add, + } + + enum BalancesEnum { + user_token_a_holding_init, + user_token_b_holding_init, + user_token_lp_holding_init, + vault_a_balance_init, + vault_b_balance_init, + pool_lp_supply_init, + token_a_supply, + token_b_supply, + token_lp_supply, + remove_lp, + remove_min_amount_a, + remove_min_amount_b, + add_min_amount_lp, + add_max_amount_a, + add_max_amount_b, + swap_amount_in, + swap_min_amount_out, + vault_a_balance_swap_1, + vault_b_balance_swap_1, + user_token_a_holding_swap_1, + user_token_b_holding_swap_1, + vault_a_balance_swap_2, + vault_b_balance_swap_2, + user_token_a_holding_swap_2, + user_token_b_holding_swap_2, + vault_a_balance_add, + vault_b_balance_add, + user_token_a_holding_add, + user_token_b_holding_add, + user_token_lp_holding_add, + token_lp_supply_add, + } + + enum IdEnum { + amm_id, + pool_definition_id, + pool_definition_diff_id, + token_lp_definition_id, + token_a_definition_id, + token_b_definition_id, + user_token_a_id, + user_token_b_id, + user_token_lp_id, + vault_a_id, + vault_b_id, + } + + enum PrivateKeysEnum { + amm_key, + pool_definition_key, + pool_definition_diff_key, + token_lp_definition_key, + token_a_definition_key, + token_b_definition_key, + user_token_a_key, + user_token_b_key, + user_token_lp_key, + vault_a_key, + vault_b_key, + } + + fn helper_balances_constructor(selection: BalancesEnum) -> u128 { + match selection { + BalancesEnum::user_token_a_holding_init => 10_000, + BalancesEnum::user_token_b_holding_init => 10_000, + BalancesEnum::user_token_lp_holding_init => 2_000, + BalancesEnum::vault_a_balance_init => 5_000, + BalancesEnum::vault_b_balance_init => 2_500, + BalancesEnum::pool_lp_supply_init => 5_000, + BalancesEnum::token_a_supply => 100_000, + BalancesEnum::token_b_supply => 100_000, + BalancesEnum::token_lp_supply => 5_000, + BalancesEnum::remove_lp => 1_000, + BalancesEnum::remove_min_amount_a => 500, + BalancesEnum::remove_min_amount_b => 500, + BalancesEnum::add_min_amount_lp => 1_000, + BalancesEnum::add_max_amount_a => 2_000, + BalancesEnum::add_max_amount_b => 1_000, + BalancesEnum::swap_amount_in => 1_000, + BalancesEnum::swap_min_amount_out => 200, + BalancesEnum::vault_a_balance_swap_1 => 3_572, + BalancesEnum::vault_b_balance_swap_1 => 3_500, + BalancesEnum::user_token_a_holding_swap_1 => 11_428, + BalancesEnum::user_token_b_holding_swap_1 => 9_000, + BalancesEnum::vault_a_balance_swap_2 => 6_000, + BalancesEnum::vault_b_balance_swap_2 => 2_084, + BalancesEnum::user_token_a_holding_swap_2 => 9_000, + BalancesEnum::user_token_b_holding_swap_2 => 10_416, + BalancesEnum::vault_a_balance_add => 0, + BalancesEnum::vault_b_balance_add => 0, + BalancesEnum::user_token_a_holding_add => 8_000, + BalancesEnum::user_token_b_holding_add => 9_000, + BalancesEnum::user_token_lp_holding_add => 4_000, + BalancesEnum::token_lp_supply_add => 7_000, + _ => panic!("Invalid selection"), } } - /// Used for each amm test to initialize - /// an AMM pool - fn initialize_amm() -> (V02State, Vec, Vec, Vec) { + fn helper_private_keys_constructor(selection: PrivateKeysEnum) -> PrivateKey { + match selection { + PrivateKeysEnum::amm_key => PrivateKey::try_new([1; 32]).expect("Keys constructor expects valid private key"), + PrivateKeysEnum::pool_definition_key => PrivateKey::try_new([2; 32]).expect("Keys constructor expects valid private key"), + PrivateKeysEnum::pool_definition_diff_key => PrivateKey::try_new([3; 32]).expect("Keys constructor expects valid private key"), + PrivateKeysEnum::vault_a_key => PrivateKey::try_new([4; 32]).expect("Keys constructor expects valid private key"), + PrivateKeysEnum::vault_b_key => PrivateKey::try_new([5; 32]).expect("Keys constructor expects valid private key"), + PrivateKeysEnum::token_lp_definition_key => PrivateKey::try_new([11; 32]).expect("Keys constructor expects valid private key"), + PrivateKeysEnum::token_a_definition_key => PrivateKey::try_new([12; 32]).expect("Keys constructor expects valid private key"), + PrivateKeysEnum::token_b_definition_key => PrivateKey::try_new([13; 32]).expect("Keys constructor expects valid private key"), + PrivateKeysEnum::user_token_a_key => PrivateKey::try_new([31; 32]).expect("Keys constructor expects valid private key"), + PrivateKeysEnum::user_token_b_key => PrivateKey::try_new([32; 32]).expect("Keys constructor expects valid private key"), + PrivateKeysEnum::user_token_lp_key => PrivateKey::try_new([33; 32]).expect("Keys constructor expects valid private key"), + _ => panic!("Invalid selection TODO2"), + } + } + + fn helper_id_constructor(selection: IdEnum) -> AccountId { + match selection { + IdEnum::amm_id => AccountId::from( + &PublicKey::new_from_private_key(&helper_private_keys_constructor(PrivateKeysEnum::amm_key))), + IdEnum::pool_definition_id => AccountId::from( + &PublicKey::new_from_private_key(&helper_private_keys_constructor(PrivateKeysEnum::pool_definition_key))), + IdEnum::pool_definition_diff_id => AccountId::from( + &PublicKey::new_from_private_key(&helper_private_keys_constructor(PrivateKeysEnum::pool_definition_diff_key))), + IdEnum::vault_a_id => AccountId::from( + &PublicKey::new_from_private_key(&helper_private_keys_constructor(PrivateKeysEnum::vault_a_key))), + IdEnum::vault_b_id => AccountId::from( + &PublicKey::new_from_private_key(&helper_private_keys_constructor(PrivateKeysEnum::vault_b_key))), + IdEnum::token_lp_definition_id => AccountId::from( + &PublicKey::new_from_private_key(&helper_private_keys_constructor(PrivateKeysEnum::token_lp_definition_key))), + IdEnum::token_a_definition_id => AccountId::from( + &PublicKey::new_from_private_key(&helper_private_keys_constructor(PrivateKeysEnum::token_a_definition_key))), + IdEnum::token_b_definition_id => AccountId::from( + &PublicKey::new_from_private_key(&helper_private_keys_constructor(PrivateKeysEnum::token_b_definition_key))), + IdEnum::user_token_a_id => AccountId::from( + &PublicKey::new_from_private_key(&helper_private_keys_constructor(PrivateKeysEnum::user_token_a_key))), + IdEnum::user_token_b_id => AccountId::from( + &PublicKey::new_from_private_key(&helper_private_keys_constructor(PrivateKeysEnum::user_token_b_key))), + IdEnum::user_token_lp_id => AccountId::from( + &PublicKey::new_from_private_key(&helper_private_keys_constructor(PrivateKeysEnum::user_token_lp_key))), + _ => panic!("Invalid selection"), + } + } + + fn helper_account_constructor(selection: AccountsEnum) -> Account { + //TODO + match selection { + AccountsEnum::amm => panic!("TODO"), + AccountsEnum::pool_definition_uninit => panic!("TODO"), + AccountsEnum::user_token_a_holding => Account { + program_owner: Program::token().id(), + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_a_definition_id), + balance: helper_balances_constructor(BalancesEnum::user_token_a_holding_init), + }), + nonce: 0, + }, + AccountsEnum::user_token_b_holding => Account { + program_owner: Program::token().id(), + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_b_definition_id), + balance: helper_balances_constructor(BalancesEnum::user_token_b_holding_init), + }), + nonce: 0, + }, + AccountsEnum::pool_definition_init => Account { + program_owner: Program::amm().id(), + balance: 0u128, + data: PoolDefinition::into_data( + PoolDefinition { + definition_token_a_id: helper_id_constructor(IdEnum::token_a_definition_id), + definition_token_b_id: helper_id_constructor(IdEnum::token_b_definition_id), + vault_a_addr: helper_id_constructor(IdEnum::vault_a_id), + vault_b_addr: helper_id_constructor(IdEnum::vault_b_id), + liquidity_pool_id: helper_id_constructor(IdEnum::token_lp_definition_id), + liquidity_pool_supply: helper_balances_constructor(BalancesEnum::pool_lp_supply_init), + reserve_a: helper_balances_constructor(BalancesEnum::vault_a_balance_init), + reserve_b: helper_balances_constructor(BalancesEnum::vault_b_balance_init), + fees: 0u128, + active: true, + }), + nonce: 0, + }, + AccountsEnum::token_a_definition_acc => Account { + program_owner: Program::token().id(), + balance: 0u128, + data: TokenDefinition::into_data( + TokenDefinition { + account_type: 0u8, + name: [1u8;6], + total_supply: helper_balances_constructor(BalancesEnum::token_a_supply) + } + ), + nonce: 0, + }, + AccountsEnum::token_b_definition_acc => Account { + program_owner: Program::token().id(), + balance: 0u128, + data: TokenDefinition::into_data( + TokenDefinition { + account_type: 0u8, + name: [1u8;6], + total_supply: helper_balances_constructor(BalancesEnum::token_b_supply) + } + ), + nonce: 0, + }, + AccountsEnum::token_lp_definition_acc => Account { + program_owner: Program::token().id(), + balance: 0u128, + data: TokenDefinition::into_data( + TokenDefinition { + account_type: 0u8, + name: [1u8;6], + total_supply: helper_balances_constructor(BalancesEnum::token_lp_supply) + } + ), + nonce: 0, + }, + AccountsEnum::vault_a_init => Account { + program_owner: Program::token().id(), + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_a_definition_id), + balance: helper_balances_constructor(BalancesEnum::vault_a_balance_init), + }), + nonce: 0, + }, + AccountsEnum::vault_b_init => Account { + program_owner: Program::token().id(), + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_b_definition_id), + balance: helper_balances_constructor(BalancesEnum::vault_b_balance_init), + }), + nonce: 0, + }, + AccountsEnum::user_token_lp_holding => Account { + program_owner: Program::token().id(), + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_lp_definition_id), + balance: helper_balances_constructor(BalancesEnum::user_token_lp_holding_init), + }), + nonce: 0, + }, + AccountsEnum::vault_a_swap_1 => Account { + program_owner: Program::token().id(), + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_a_definition_id), + balance: helper_balances_constructor(BalancesEnum::vault_a_balance_swap_1), + }), + nonce: 1, + }, + AccountsEnum::vault_b_swap_1 => Account { + program_owner: Program::token().id(), + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_b_definition_id), + balance: helper_balances_constructor(BalancesEnum::vault_b_balance_swap_1), + }), + nonce: 0, + }, + AccountsEnum::pool_definition_swap_1 => Account { + program_owner: Program::amm().id(), + balance: 0u128, + data: PoolDefinition::into_data( + PoolDefinition { + definition_token_a_id: helper_id_constructor(IdEnum::token_a_definition_id), + definition_token_b_id: helper_id_constructor(IdEnum::token_b_definition_id), + vault_a_addr: helper_id_constructor(IdEnum::vault_a_id), + vault_b_addr: helper_id_constructor(IdEnum::vault_b_id), + liquidity_pool_id: helper_id_constructor(IdEnum::token_lp_definition_id), + liquidity_pool_supply: helper_balances_constructor(BalancesEnum::pool_lp_supply_init), + reserve_a: helper_balances_constructor(BalancesEnum::vault_a_balance_swap_1), + reserve_b: helper_balances_constructor(BalancesEnum::vault_b_balance_swap_1), + fees: 0u128, + active: true, + }), + nonce: 0, + }, + AccountsEnum::user_token_a_holding_swap_1 => Account { + program_owner: Program::token().id(), + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_a_definition_id), + balance: helper_balances_constructor(BalancesEnum::user_token_a_holding_swap_1), + }), + nonce: 0, + }, + AccountsEnum::user_token_b_holding_swap_1 => Account { + program_owner: Program::token().id(), + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_b_definition_id), + balance: helper_balances_constructor(BalancesEnum::user_token_b_holding_swap_1), + }), + nonce: 1, + }, + AccountsEnum::vault_a_swap_2 => Account { + program_owner: Program::token().id(), + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_a_definition_id), + balance: helper_balances_constructor(BalancesEnum::vault_a_balance_swap_2), + }), + nonce: 0, + }, + AccountsEnum::vault_b_swap_2 => Account { + program_owner: Program::token().id(), + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_b_definition_id), + balance: helper_balances_constructor(BalancesEnum::vault_b_balance_swap_2), + }), + nonce: 1, + }, + AccountsEnum::pool_definition_swap_2 => Account { + program_owner: Program::amm().id(), + balance: 0u128, + data: PoolDefinition::into_data( + PoolDefinition { + definition_token_a_id: helper_id_constructor(IdEnum::token_a_definition_id), + definition_token_b_id: helper_id_constructor(IdEnum::token_b_definition_id), + vault_a_addr: helper_id_constructor(IdEnum::vault_a_id), + vault_b_addr: helper_id_constructor(IdEnum::vault_b_id), + liquidity_pool_id: helper_id_constructor(IdEnum::token_lp_definition_id), + liquidity_pool_supply: helper_balances_constructor(BalancesEnum::pool_lp_supply_init), + reserve_a: helper_balances_constructor(BalancesEnum::vault_a_balance_swap_2), + reserve_b: helper_balances_constructor(BalancesEnum::vault_b_balance_swap_2), + fees: 0u128, + active: true, + }), + nonce: 0, + }, + AccountsEnum::user_token_a_holding_swap_2 => Account { + program_owner: Program::token().id(), + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_a_definition_id), + balance: helper_balances_constructor(BalancesEnum::user_token_a_holding_swap_2), + }), + nonce: 1, + }, + AccountsEnum::user_token_b_holding_swap_2 => Account { + program_owner: Program::token().id(), + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_b_definition_id), + balance: helper_balances_constructor(BalancesEnum::user_token_b_holding_swap_2), + }), + nonce: 0, + }, + AccountsEnum::vault_a_add => Account { + program_owner: Program::token().id(), + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_a_definition_id), + balance: helper_balances_constructor(BalancesEnum::vault_a_balance_add), + }), + nonce: 0, + }, + AccountsEnum::vault_b_add => Account { + program_owner: Program::token().id(), + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_b_definition_id), + balance: helper_balances_constructor(BalancesEnum::vault_b_balance_add), + }), + nonce: 0, + }, + AccountsEnum::pool_definition_add => Account { + program_owner: Program::amm().id(), + balance: 0u128, + data: PoolDefinition::into_data( + PoolDefinition { + definition_token_a_id: helper_id_constructor(IdEnum::token_a_definition_id), + definition_token_b_id: helper_id_constructor(IdEnum::token_b_definition_id), + vault_a_addr: helper_id_constructor(IdEnum::vault_a_id), + vault_b_addr: helper_id_constructor(IdEnum::vault_b_id), + liquidity_pool_id: helper_id_constructor(IdEnum::token_lp_definition_id), + liquidity_pool_supply: helper_balances_constructor(BalancesEnum::token_lp_supply_add), + reserve_a: helper_balances_constructor(BalancesEnum::vault_a_balance_add), + reserve_b: helper_balances_constructor(BalancesEnum::vault_b_balance_add), + fees: 0u128, + active: true, + }), + nonce: 0, + }, + AccountsEnum::user_token_a_holding_add => Account { + program_owner: Program::token().id(), + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_a_definition_id), + balance: helper_balances_constructor(BalancesEnum::user_token_a_holding_add), + }), + nonce: 1, + }, + AccountsEnum::user_token_b_holding_add => Account { + program_owner: Program::token().id(), + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_b_definition_id), + balance: helper_balances_constructor(BalancesEnum::user_token_b_holding_add), + }), + nonce: 1, + }, + AccountsEnum::user_token_lp_holding_add => Account { + program_owner: Program::token().id(), + balance: 0u128, + data: TokenHolding::into_data( + TokenHolding{ + account_type: 1u8, + definition_id: helper_id_constructor(IdEnum::token_b_definition_id), + balance: helper_balances_constructor(BalancesEnum::user_token_b_holding_add), + }), + nonce: 0, + }, + _ => panic!("Invalid selection TODO1") + } + } + +/* + let expected_pool = helper_account_constructor(AccountsEnum::pool_definition_add); + let expected_vault_a = helper_account_constructor(AccountsEnum::vault_a_add); + let expected_vault_b = helper_account_constructor(AccountsEnum::vault_b_add); + let expected_token_lp = helper_account_constructor(AccountsEnum::token_lp_holding_add); + let expected_user_token_a = helper_account_constructor(AccountsEnum::user_token_a_holding_add); + let expected_user_token_b = helper_account_constructor(AccountsEnum::user_token_b_holding_add); + let expected_user_token_lp = helper_account_constructor(AccountsEnum::user_token_lp_holding_add); + +*/ + + + fn amm_state_constructor() -> V02State { let initial_data = []; let mut state = V02State::new_with_genesis_accounts(&initial_data, &[]).with_test_programs(); - - let token_a_holding_key = PrivateKey::try_new([1; 32]).unwrap(); - let token_a_definition_key = PrivateKey::try_new([2; 32]).unwrap(); - let token_a_holding_id = - AccountId::from(&PublicKey::new_from_private_key(&token_a_holding_key)); - let token_a_definition_id = - AccountId::from(&PublicKey::new_from_private_key(&token_a_definition_key)); - let token_a_supply: u128 = 30000; - - let token_b_holding_key = PrivateKey::try_new([3; 32]).unwrap(); - let token_b_definition_key = PrivateKey::try_new([4; 32]).unwrap(); - let token_b_holding_id = - AccountId::from(&PublicKey::new_from_private_key(&token_b_holding_key)); - let token_b_definition_id = - AccountId::from(&PublicKey::new_from_private_key(&token_b_definition_key)); - let token_b_supply: u128 = 50000; - - let pool_lp_holding_key = PrivateKey::try_new([5; 32]).unwrap(); - let pool_lp_definition_key = PrivateKey::try_new([6; 32]).unwrap(); - let pool_lp_holding_id = - AccountId::from(&PublicKey::new_from_private_key(&pool_lp_holding_key)); - let pool_lp_definition_id = - AccountId::from(&PublicKey::new_from_private_key(&pool_lp_definition_key)); - let token_lp_supply: u128 = 300000; - - let user_a_holding_key = PrivateKey::try_new([7; 32]).unwrap(); - let user_a_holding_id = - AccountId::from(&PublicKey::new_from_private_key(&user_a_holding_key)); - let user_a_amount: u128 = 10000; - - let user_b_holding_key = PrivateKey::try_new([8; 32]).unwrap(); - let user_b_holding_id = - AccountId::from(&PublicKey::new_from_private_key(&user_b_holding_key)); - let user_b_amount: u128 = 10000; - - let vault_a_key = PrivateKey::try_new([9; 32]).unwrap(); - let vault_a_id = AccountId::from(&PublicKey::new_from_private_key(&vault_a_key)); - - let vault_b_key = PrivateKey::try_new([10; 32]).unwrap(); - let vault_b_id = AccountId::from(&PublicKey::new_from_private_key(&vault_b_key)); - - let user_lp_holding_key = PrivateKey::try_new([11; 32]).unwrap(); - let user_lp_holding_id = - AccountId::from(&PublicKey::new_from_private_key(&user_lp_holding_key)); - - - let pool_key = PrivateKey::try_new([13; 32]).unwrap(); - let pool_id = AccountId::from(&PublicKey::new_from_private_key(&pool_key)); - - //initialize Token A - let mut instruction: [u8; 23] = [0; 23]; - instruction[1..17].copy_from_slice(&token_a_supply.to_le_bytes()); - instruction[18] = 0x01; //name is not default. - instruction[19] = 0x02; - - let message = public_transaction::Message::try_new( - Program::token().id(), - vec![token_a_definition_id, token_a_holding_id], - vec![], - instruction, - ) - .unwrap(); - - let witness_set = public_transaction::WitnessSet::for_message(&message, &[]); - let tx = PublicTransaction::new(message, witness_set); - state.transition_from_public_transaction(&tx).unwrap(); - - //initialize Token B - instruction[1..17].copy_from_slice(&token_b_supply.to_le_bytes()); - instruction[18] = 0x03; //name is not default. - instruction[19] = 0x02; - - let message = public_transaction::Message::try_new( - Program::token().id(), - vec![token_b_definition_id, token_b_holding_id], - vec![], - instruction, - ) - .unwrap(); - - let witness_set = public_transaction::WitnessSet::for_message(&message, &[]); - let tx = PublicTransaction::new(message, witness_set); - state.transition_from_public_transaction(&tx).unwrap(); - - - //initialize Token LP - instruction[1..17].copy_from_slice(&token_lp_supply.to_le_bytes()); - instruction[18] = 0x03; //name is not default. - instruction[19] = 0x04; - - let message = public_transaction::Message::try_new( - Program::token().id(), - vec![pool_lp_definition_id, pool_lp_holding_id], - vec![], - instruction, - ) - .unwrap(); - - let witness_set = public_transaction::WitnessSet::for_message(&message, &[]); - let tx = PublicTransaction::new(message, witness_set); - state.transition_from_public_transaction(&tx).unwrap(); - - // Initialize User accounts for Token A - let mut instruction: [u8; 23] = [0; 23]; - instruction[0] = 1; //transfer - instruction[1..17].copy_from_slice(&user_a_amount.to_le_bytes()); - - let message = public_transaction::Message::try_new( - Program::token().id(), - vec![token_a_holding_id, user_a_holding_id], - vec![0], - instruction, - ) - .unwrap(); - - let witness_set = - public_transaction::WitnessSet::for_message(&message, &[&token_a_holding_key]); - let tx = PublicTransaction::new(message, witness_set); - state.transition_from_public_transaction(&tx).unwrap(); - - - // Initialize User accounts for Token A - instruction[0] = 1; //transfer - instruction[1..17].copy_from_slice(&user_b_amount.to_le_bytes()); - - let message = public_transaction::Message::try_new( - Program::token().id(), - vec![token_b_holding_id, user_b_holding_id], - vec![0], - instruction, - ) - .unwrap(); - - let witness_set = - public_transaction::WitnessSet::for_message(&message, &[&token_b_holding_key]); - let tx = PublicTransaction::new(message, witness_set); - state.transition_from_public_transaction(&tx).unwrap(); - - //TODO: initialize vaults - ideally, we won't need to do this. - // Initialize Vault A - let mut instruction: [u8; 23] = [0; 23]; - instruction[0] = 2; //initialize - - let message = public_transaction::Message::try_new( - Program::token().id(), - vec![token_a_definition_id, vault_a_id], - vec![1], - instruction, - ) - .unwrap(); - - let witness_set = - public_transaction::WitnessSet::for_message(&message, &[&token_a_holding_key]); - let tx = PublicTransaction::new(message, witness_set); - state.transition_from_public_transaction(&tx).unwrap(); - - // Initialize Vault B - let message = public_transaction::Message::try_new( - Program::token().id(), - vec![token_b_definition_id, vault_b_id], - vec![1], - instruction, - ) - .unwrap(); - - let witness_set = - public_transaction::WitnessSet::for_message(&message, &[&token_b_holding_key]); - let tx = PublicTransaction::new(message, witness_set); - state.transition_from_public_transaction(&tx).unwrap(); - - // Initialize User LP - let message = public_transaction::Message::try_new( - Program::token().id(), - vec![pool_lp_definition_id, user_lp_holding_id], - vec![0], - instruction, - ) - .unwrap(); - - let witness_set = - public_transaction::WitnessSet::for_message(&message, &[&pool_lp_holding_key]); - let tx = PublicTransaction::new(message, witness_set); - state.transition_from_public_transaction(&tx).unwrap(); - - //Set up instruction to initialize AMM for (Token-A, Token-B) - let init_balance_a: u128 = 1000; - let init_balance_b: u128 = 1000; - let token_program_u8: [u8; 32] = bytemuck::cast(Program::token().id()); - - let mut instruction: Vec = Vec::new(); - instruction.push(0); - instruction.extend_from_slice(&init_balance_a.to_le_bytes()); - instruction.extend_from_slice(&init_balance_b.to_le_bytes()); - instruction.extend_from_slice(&token_program_u8); - - let message = public_transaction::Message::try_new( - Program::amm().id(), - vec![ - pool_id, - vault_a_id, - vault_b_id, - pool_lp_holding_id, - user_a_holding_id, - user_b_holding_id, - user_lp_holding_id, - ], - vec![0, 1, 0, 0], - instruction, - ) - .unwrap(); - - let witness_set = public_transaction::WitnessSet::for_message( - &message, - &[ - &pool_key, - &pool_lp_holding_key, - &user_a_holding_key, - &user_b_holding_key, - ], + state.force_insert_account( + helper_id_constructor(IdEnum::pool_definition_id), + helper_account_constructor(AccountsEnum::pool_definition_init) + ); + state.force_insert_account( + helper_id_constructor(IdEnum::token_a_definition_id), + helper_account_constructor(AccountsEnum::token_a_definition_acc) + ); + state.force_insert_account( + helper_id_constructor(IdEnum::token_b_definition_id), + helper_account_constructor(AccountsEnum::token_b_definition_acc) + ); + state.force_insert_account( + helper_id_constructor(IdEnum::token_lp_definition_id), + helper_account_constructor(AccountsEnum::token_lp_definition_acc) + ); + state.force_insert_account( + helper_id_constructor(IdEnum::user_token_a_id), + helper_account_constructor(AccountsEnum::user_token_a_holding) + ); + state.force_insert_account( + helper_id_constructor(IdEnum::user_token_b_id), + helper_account_constructor(AccountsEnum::user_token_b_holding) + ); + state.force_insert_account( + helper_id_constructor(IdEnum::user_token_lp_id), + helper_account_constructor(AccountsEnum::user_token_lp_holding) + ); + state.force_insert_account( + helper_id_constructor(IdEnum::vault_a_id), + helper_account_constructor(AccountsEnum::vault_a_init) + ); + state.force_insert_account( + helper_id_constructor(IdEnum::vault_b_id), + helper_account_constructor(AccountsEnum::vault_b_init) ); - let tx = PublicTransaction::new(message, witness_set); - state.transition_from_public_transaction(&tx).unwrap(); - - let mut vec_id = Vec::new(); - vec_id.push(token_a_holding_id); - vec_id.push(token_a_definition_id); - vec_id.push(token_b_holding_id); - vec_id.push(token_b_definition_id); - vec_id.push(pool_lp_definition_id); - vec_id.push(user_a_holding_id); - vec_id.push(user_b_holding_id); - vec_id.push(vault_a_id); - vec_id.push(vault_b_id); - vec_id.push(user_lp_holding_id); - vec_id.push(pool_id); - vec_id.push(pool_lp_holding_id); - - let mut vec_private_keys = Vec::new(); - vec_private_keys.push(token_a_holding_key); - vec_private_keys.push(token_a_definition_key); - vec_private_keys.push(token_b_holding_key); - vec_private_keys.push(token_b_definition_key); - vec_private_keys.push(pool_lp_definition_key); - vec_private_keys.push(user_a_holding_key); - vec_private_keys.push(user_b_holding_key); - vec_private_keys.push(vault_a_key); - vec_private_keys.push(vault_b_key); - vec_private_keys.push(user_lp_holding_key); - vec_private_keys.push(pool_key); - vec_private_keys.push(pool_lp_holding_key); - - let mut vec_amounts = Vec::new(); - vec_amounts.push(init_balance_a); - vec_amounts.push(init_balance_b); - vec_amounts.push(user_a_amount); - vec_amounts.push(user_b_amount); - - (state, vec_private_keys, vec_id, vec_amounts) - } - - #[test] - fn test_simple_amm_initialize() { - let (state, _vec_private_keys, vec_id, vec_amounts) = initialize_amm(); - - let init_balance_a = vec_amounts[0]; - let init_balance_b = vec_amounts[1]; - let user_a_amount = vec_amounts[2]; - let user_b_amount = vec_amounts[3]; - - let token_a_holding_id = vec_id[0]; - let token_a_definition_id = vec_id[1]; - let token_b_holding_id = vec_id[2]; - let token_b_definition_id = vec_id[3]; - let token_lp_definition_id = vec_id[4]; - let user_a_holding_id = vec_id[5]; - let user_b_holding_id = vec_id[6]; - let vault_a_id = vec_id[7]; - let vault_b_id = vec_id[8]; - let user_lp_holding_id = vec_id[9]; - let pool_id = vec_id[10]; - let pool_lp_holding_id = vec_id[11]; - - let pool_post = state.get_account_by_id(&pool_id); - let vault_a_post = state.get_account_by_id(&vault_a_id); - let vault_b_post = state.get_account_by_id(&vault_b_id); - let user_a_post = state.get_account_by_id(&user_a_holding_id); - let user_b_post = state.get_account_by_id(&user_b_holding_id); - let user_lp_post = state.get_account_by_id(&user_lp_holding_id); - - let expected_pool = Account { - program_owner: Program::amm().id(), - balance: 0u128, - data: PoolDefinition::into_data( - PoolDefinition { - definition_token_a_id: token_a_definition_id, - definition_token_b_id: token_b_definition_id, - vault_a_addr: vault_a_id, - vault_b_addr: vault_b_id, - liquidity_pool_id: token_lp_definition_id, - liquidity_pool_cap: init_balance_a, - reserve_a: init_balance_a, - reserve_b: init_balance_b, - token_program_id: Program::token().id(), - }), - nonce: 1, - }; - - let expected_vault_a = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_a_definition_id, - balance: init_balance_a, - }), - nonce: 0 - }; - - let expected_vault_b = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_b_definition_id, - balance: init_balance_b, - }), - nonce: 0 - }; - - let expected_user_a = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_a_definition_id, - balance: user_a_amount - init_balance_a, - }), - nonce: 1 - }; - - let expected_user_b = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_b_definition_id, - balance: user_b_amount - init_balance_b, - }), - nonce: 1 - }; - - let expected_user_lp = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_lp_definition_id, - balance: init_balance_a, - }), - nonce: 0 - }; - - assert!(vault_a_post == expected_vault_a); - assert!(vault_b_post == expected_vault_b); - assert!(user_a_post == expected_user_a); - assert!(user_b_post == expected_user_b); - assert!(user_lp_post == expected_user_lp); - assert!(pool_post == expected_pool); + state } #[test] fn test_simple_amm_remove() { - let (state, vec_private_keys, vec_id, vec_amounts) = initialize_amm(); - let mut state: V02State = state; - - let init_balance_a = vec_amounts[0]; - let init_balance_b = vec_amounts[1]; - let user_a_amount = vec_amounts[2]; - let user_b_amount = vec_amounts[3]; - - let token_a_holding_key = &vec_private_keys[0]; - let token_a_definition_key = &vec_private_keys[1]; - let token_b_holding_key = &vec_private_keys[2]; - let token_b_definition_key = &vec_private_keys[3]; - let pool_lp_definition_key = &vec_private_keys[4]; - let user_a_holding_key = &vec_private_keys[5]; - let user_b_holding_key = &vec_private_keys[6]; - let vault_a_key = &vec_private_keys[7]; - let vault_b_key = &vec_private_keys[8]; - let user_lp_holding_key = &vec_private_keys[9]; - let pool_key = &vec_private_keys[10]; - let pool_lp_holding_key = &vec_private_keys[11]; - - let token_a_holding_id = vec_id[0]; - let token_a_definition_id = vec_id[1]; - let token_b_holding_id = vec_id[2]; - let token_b_definition_id = vec_id[3]; - let token_lp_definition_id = vec_id[4]; - let user_a_holding_id = vec_id[5]; - let user_b_holding_id = vec_id[6]; - let vault_a_id = vec_id[7]; - let vault_b_id = vec_id[8]; - let user_lp_holding_id = vec_id[9]; - let pool_id = vec_id[10]; - let pool_lp_holding_id = vec_id[11]; + let mut state = amm_state_constructor(); let mut instruction: Vec = Vec::new(); instruction.push(3); + instruction.extend_from_slice(&helper_balances_constructor(BalancesEnum::remove_lp).to_le_bytes()); + instruction.extend_from_slice(&helper_balances_constructor(BalancesEnum::remove_min_amount_a).to_le_bytes()); + instruction.extend_from_slice(&helper_balances_constructor(BalancesEnum::remove_min_amount_b).to_le_bytes()); let message = public_transaction::Message::try_new( Program::amm().id(), vec![ - pool_id, - vault_a_id, - vault_b_id, - pool_lp_holding_id, - user_a_holding_id, - user_b_holding_id, - user_lp_holding_id, + helper_id_constructor(IdEnum::pool_definition_id), + helper_id_constructor(IdEnum::vault_a_id), + helper_id_constructor(IdEnum::vault_b_id), + helper_id_constructor(IdEnum::token_lp_definition_id), + helper_id_constructor(IdEnum::user_token_a_id), + helper_id_constructor(IdEnum::user_token_b_id), + helper_id_constructor(IdEnum::user_token_lp_id), ], vec![ - state.get_account_by_id(&pool_id).nonce, - state.get_account_by_id(&user_lp_holding_id).nonce, - state.get_account_by_id(&vault_a_id).nonce, - state.get_account_by_id(&vault_b_id).nonce, + 0, + 0, + 0, ], instruction, ) @@ -2730,170 +2942,44 @@ pub mod tests { let witness_set = public_transaction::WitnessSet::for_message( &message, - &[&pool_key, &user_lp_holding_key, &vault_a_key, &vault_b_key], + &[ + // &helper_private_keys_constructor(PrivateKeysEnum::pool_definition_key), + &helper_private_keys_constructor(PrivateKeysEnum::vault_a_key), + &helper_private_keys_constructor(PrivateKeysEnum::vault_b_key), + &helper_private_keys_constructor(PrivateKeysEnum::user_token_lp_key), + ], ); let tx = PublicTransaction::new(message, witness_set); state.transition_from_public_transaction(&tx).unwrap(); - - let pool_post = state.get_account_by_id(&pool_id); - let vault_a_post = state.get_account_by_id(&vault_a_id); - let vault_b_post = state.get_account_by_id(&vault_b_id); - let user_a_post = state.get_account_by_id(&user_a_holding_id); - let user_b_post = state.get_account_by_id(&user_b_holding_id); - let user_lp_post = state.get_account_by_id(&user_lp_holding_id); - - //TODO: this accounts for the initial balance for User_LP - let delta_lp : u128 = (init_balance_a*init_balance_a)/init_balance_a; - - let expected_pool = Account { - program_owner: Program::amm().id(), - balance: 0u128, - data: PoolDefinition::into_data( - PoolDefinition { - definition_token_a_id: token_a_definition_id, - definition_token_b_id: token_b_definition_id, - vault_a_addr: vault_a_id, - vault_b_addr: vault_b_id, - liquidity_pool_id: token_lp_definition_id, - liquidity_pool_cap: init_balance_a - delta_lp, - reserve_a: 0, - reserve_b: 0, - token_program_id: Program::token().id(), - }), - nonce: 2, - }; - - let expected_vault_a = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_a_definition_id, - balance: 0, - }), - nonce: 1 - }; - - let expected_vault_b = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_b_definition_id, - balance: 0, - }), - nonce: 1 - }; - - let expected_user_a = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_a_definition_id, - balance: user_a_amount, - }), - nonce: 1 - }; - - let expected_user_b = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_b_definition_id, - balance: user_b_amount, - }), - nonce: 1 - }; - - let expected_user_lp = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_lp_definition_id, - balance: 0, - }), - nonce: 1 - }; - - assert!(vault_a_post == expected_vault_a); - assert!(vault_b_post == expected_vault_b); - assert!(user_a_post == expected_user_a); - assert!(user_b_post == expected_user_b); - assert!(user_lp_post == expected_user_lp); - assert!(pool_post.data == expected_pool.data); + //TODO: add asserts to check results } #[test] fn test_simple_amm_add() { - let (state, vec_private_keys, vec_id, vec_amounts) = initialize_amm(); - let mut state: V02State = state; + let mut state = amm_state_constructor(); - let init_balance_a = vec_amounts[0]; - let init_balance_b = vec_amounts[1]; - let user_a_amount = vec_amounts[2]; - let user_b_amount = vec_amounts[3]; - - let _token_a_holding_key = &vec_private_keys[0]; - let _token_a_definition_key = &vec_private_keys[1]; - let _token_b_holding_key = &vec_private_keys[2]; - let _token_b_definition_key = &vec_private_keys[3]; - let pool_lp_definition_key = &vec_private_keys[4]; - let user_a_holding_key = &vec_private_keys[5]; - let user_b_holding_key = &vec_private_keys[6]; - let vault_a_key = &vec_private_keys[7]; - let vault_b_key = &vec_private_keys[8]; - let user_lp_holding_key = &vec_private_keys[9]; - let pool_key = &vec_private_keys[10]; - let pool_lp_holding_key = &vec_private_keys[11]; - - let token_a_holding_id = vec_id[0]; - let token_a_definition_id = vec_id[1]; - let token_b_holding_id = vec_id[2]; - let token_b_definition_id = vec_id[3]; - let token_lp_definition_id = vec_id[4]; - let user_a_holding_id = vec_id[5]; - let user_b_holding_id = vec_id[6]; - let vault_a_id = vec_id[7]; - let vault_b_id = vec_id[8]; - let user_lp_holding_id = vec_id[9]; - let pool_id = vec_id[10]; - let pool_lp_holding_id = vec_id[11]; - - - let add_a: u128 = 500; - let add_b: u128 = 500; - let main_addr = token_a_definition_id; let mut instruction: Vec = Vec::new(); instruction.push(2); - instruction.extend_from_slice(&add_a.to_le_bytes()); - instruction.extend_from_slice(&add_b.to_le_bytes()); - instruction.extend_from_slice(main_addr.value()); + instruction.extend_from_slice(&helper_balances_constructor(BalancesEnum::add_min_amount_lp).to_le_bytes()); + instruction.extend_from_slice(&helper_balances_constructor(BalancesEnum::add_max_amount_a).to_le_bytes()); + instruction.extend_from_slice(&helper_balances_constructor(BalancesEnum::add_max_amount_b).to_le_bytes()); let message = public_transaction::Message::try_new( Program::amm().id(), vec![ - pool_id, - vault_a_id, - vault_b_id, - pool_lp_holding_id, - user_a_holding_id, - user_b_holding_id, - user_lp_holding_id, + helper_id_constructor(IdEnum::pool_definition_id), + helper_id_constructor(IdEnum::vault_a_id), + helper_id_constructor(IdEnum::vault_b_id), + helper_id_constructor(IdEnum::token_lp_definition_id), + helper_id_constructor(IdEnum::user_token_a_id), + helper_id_constructor(IdEnum::user_token_b_id), + helper_id_constructor(IdEnum::user_token_lp_id), ], vec![ - state.get_account_by_id(&pool_id).nonce, - state.get_account_by_id(&pool_lp_holding_id).nonce, - state.get_account_by_id(&user_a_holding_id).nonce, - state.get_account_by_id(&user_b_holding_id).nonce, + 0, + 0, + 0, ], instruction, ) @@ -2902,533 +2988,158 @@ pub mod tests { let witness_set = public_transaction::WitnessSet::for_message( &message, &[ - &pool_key, - &pool_lp_holding_key, - &user_a_holding_key, - &user_b_holding_key, + &helper_private_keys_constructor(PrivateKeysEnum::token_lp_definition_key), + &helper_private_keys_constructor(PrivateKeysEnum::user_token_a_key), + &helper_private_keys_constructor(PrivateKeysEnum::user_token_b_key), ], ); let tx = PublicTransaction::new(message, witness_set); state.transition_from_public_transaction(&tx).unwrap(); - let pool_post = state.get_account_by_id(&pool_id); - let vault_a_post = state.get_account_by_id(&vault_a_id); - let vault_b_post = state.get_account_by_id(&vault_b_id); - let user_a_post = state.get_account_by_id(&user_a_holding_id); - let user_b_post = state.get_account_by_id(&user_b_holding_id); - let user_lp_post = state.get_account_by_id(&user_lp_holding_id); + let pool_post = state.get_account_by_id(&helper_id_constructor(IdEnum::pool_definition_id)); + let vault_a_post = state.get_account_by_id(&helper_id_constructor(IdEnum::vault_a_id)); + let vault_b_post = state.get_account_by_id(&helper_id_constructor(IdEnum::vault_b_id)); + let token_lp_post = state.get_account_by_id(&helper_id_constructor(IdEnum::token_lp_definition_id)); + let user_token_a_post = state.get_account_by_id(&helper_id_constructor(IdEnum::user_token_a_id)); + let user_token_b_post = state.get_account_by_id(&helper_id_constructor(IdEnum::user_token_b_id)); + let user_token_lp_post = state.get_account_by_id(&helper_id_constructor(IdEnum::user_token_lp_id)); - let expected_pool = Account { - program_owner: Program::amm().id(), - balance: 0u128, - data: PoolDefinition::into_data( - PoolDefinition { - definition_token_a_id: token_a_definition_id, - definition_token_b_id: token_b_definition_id, - vault_a_addr: vault_a_id, - vault_b_addr: vault_b_id, - liquidity_pool_id: token_lp_definition_id, - liquidity_pool_cap: init_balance_a + add_a, - reserve_a: init_balance_a + add_a, - reserve_b: init_balance_b + add_b, - token_program_id: Program::token().id(), - }), - nonce: 2, - }; - - let expected_vault_a = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_a_definition_id, - balance: init_balance_a + add_a, - }), - nonce: 0 - }; - - let expected_vault_b = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_b_definition_id, - balance: init_balance_b + add_b, - }), - nonce: 0 - }; - - let expected_user_a = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_a_definition_id, - balance: user_a_amount - init_balance_a - add_a, - }), - nonce: 2 - }; - - let expected_user_b = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_b_definition_id, - balance: user_b_amount - init_balance_b - add_b, - }), - nonce: 2 - }; - - let expected_user_lp = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_lp_definition_id, - balance: init_balance_a + add_a, - }), - nonce: 0 - }; + let expected_pool = helper_account_constructor(AccountsEnum::pool_definition_add); + let expected_vault_a = helper_account_constructor(AccountsEnum::vault_a_add); + let expected_vault_b = helper_account_constructor(AccountsEnum::vault_b_add); + let expected_token_lp = helper_account_constructor(AccountsEnum::token_lp_definition_add); + let expected_user_token_a = helper_account_constructor(AccountsEnum::user_token_a_holding_add); + let expected_user_token_b = helper_account_constructor(AccountsEnum::user_token_b_holding_add); + let expected_user_token_lp = helper_account_constructor(AccountsEnum::user_token_lp_holding_add); + assert!(pool_post == expected_pool); assert!(vault_a_post == expected_vault_a); assert!(vault_b_post == expected_vault_b); - assert!(user_a_post == expected_user_a); - assert!(user_b_post == expected_user_b); - assert!(user_lp_post == expected_user_lp); - assert!(pool_post == expected_pool); - + assert!(token_lp_post == expected_token_lp); + assert!(user_token_a_post == expected_user_token_a); + assert!(user_token_b_post == expected_user_token_b); + assert!(user_token_lp_post == expected_user_token_lp); } - + #[test] fn test_simple_amm_swap_1() { - let (state, vec_private_keys, vec_id, vec_amounts) = initialize_amm(); - let mut state: V02State = state; - - let init_balance_a = vec_amounts[0]; - let init_balance_b = vec_amounts[1]; - let user_a_amount = vec_amounts[2]; - let user_b_amount = vec_amounts[3]; - - let token_a_holding_key = &vec_private_keys[0]; - let token_a_definition_key = &vec_private_keys[1]; - let token_b_holding_key = &vec_private_keys[2]; - let token_b_definition_key = &vec_private_keys[3]; - let pool_lp_definition_key = &vec_private_keys[4]; - let user_a_holding_key = &vec_private_keys[5]; - let user_b_holding_key = &vec_private_keys[6]; - let vault_a_key = &vec_private_keys[7]; - let vault_b_key = &vec_private_keys[8]; - let user_lp_holding_key = &vec_private_keys[9]; - let pool_key = &vec_private_keys[10]; - let pool_lp_holding_key = &vec_private_keys[11]; - - let token_a_holding_id = vec_id[0]; - let token_a_definition_id = vec_id[1]; - let token_b_holding_id = vec_id[2]; - let token_b_definition_id = vec_id[3]; - let token_lp_definition_id = vec_id[4]; - let user_a_holding_id = vec_id[5]; - let user_b_holding_id = vec_id[6]; - let vault_a_id = vec_id[7]; - let vault_b_id = vec_id[8]; - let user_lp_holding_id = vec_id[9]; - let pool_id = vec_id[10]; - let pool_lp_holding_id = vec_id[11]; - - //Initialize swap user accounts - let swap_user_a_holding_key = PrivateKey::try_new([21; 32]).unwrap(); - let swap_user_a_holding_id = - AccountId::from(&PublicKey::new_from_private_key(&swap_user_a_holding_key)); - let swap_user_a_amount: u128 = 5000; - - let swap_user_b_holding_key = PrivateKey::try_new([22; 32]).unwrap(); - let swap_user_b_holding_id = - AccountId::from(&PublicKey::new_from_private_key(&swap_user_b_holding_key)); - let swap_user_b_amount: u128 = 5000; - - // Initialize Swap User account for Token A - let mut instruction: [u8; 23] = [0; 23]; - instruction[0] = 1; //transfer - instruction[1..17].copy_from_slice(&swap_user_a_amount.to_le_bytes()); - - let message = public_transaction::Message::try_new( - Program::token().id(), - vec![token_a_holding_id, swap_user_a_holding_id], - vec![2], - instruction, - ) - .unwrap(); - - let witness_set = - public_transaction::WitnessSet::for_message(&message, &[&token_a_holding_key]); - let tx = PublicTransaction::new(message, witness_set); - state.transition_from_public_transaction(&tx).unwrap(); - - // Initialize Swap User account for Token B - let mut instruction: [u8; 23] = [0; 23]; - instruction[0] = 1; //transfer - instruction[1..17].copy_from_slice(&swap_user_b_amount.to_le_bytes()); - - let message = public_transaction::Message::try_new( - Program::token().id(), - vec![token_b_holding_id, swap_user_b_holding_id], - vec![state.get_account_by_id(&token_b_holding_id).nonce], - instruction, - ) - .unwrap(); - - let witness_set = - public_transaction::WitnessSet::for_message(&message, &[&token_b_holding_key]); - let tx = PublicTransaction::new(message, witness_set); - state.transition_from_public_transaction(&tx).unwrap(); - - // Initialize Swap - let main_addr = token_a_definition_id; - let swap_a: u128 = 500; + let mut state = amm_state_constructor(); let mut instruction: Vec = Vec::new(); instruction.push(1); - instruction.extend_from_slice(&swap_a.to_le_bytes()); - instruction.extend_from_slice(main_addr.value()); + instruction.extend_from_slice(&helper_balances_constructor(BalancesEnum::swap_amount_in).to_le_bytes()); + instruction.extend_from_slice(&helper_balances_constructor(BalancesEnum::swap_min_amount_out).to_le_bytes()); + instruction.extend_from_slice(&helper_id_constructor(IdEnum::token_b_definition_id).to_bytes()); let message = public_transaction::Message::try_new( Program::amm().id(), vec![ - pool_id, - vault_a_id, - vault_b_id, - swap_user_a_holding_id, - swap_user_b_holding_id, + helper_id_constructor(IdEnum::pool_definition_id), + helper_id_constructor(IdEnum::vault_a_id), + helper_id_constructor(IdEnum::vault_b_id), + helper_id_constructor(IdEnum::user_token_a_id), + helper_id_constructor(IdEnum::user_token_b_id), ], vec![ - state.get_account_by_id(&pool_id).nonce, - state.get_account_by_id(&vault_a_id).nonce, - state.get_account_by_id(&vault_b_id).nonce, - state - .get_account_by_id(&swap_user_a_holding_id) - .nonce, - state - .get_account_by_id(&swap_user_b_holding_id) - .nonce, + 0, + 0, ], instruction, ) .unwrap(); + //TODO: make note that token_name refers to token we're adding, not requesting let witness_set = public_transaction::WitnessSet::for_message( &message, &[ - &pool_key, - &vault_a_key, - &vault_b_key, - &swap_user_a_holding_key, - &swap_user_b_holding_key, + &helper_private_keys_constructor(PrivateKeysEnum::vault_a_key), + &helper_private_keys_constructor(PrivateKeysEnum::user_token_b_key), ], ); let tx = PublicTransaction::new(message, witness_set); state.transition_from_public_transaction(&tx).unwrap(); + + let pool_post = state.get_account_by_id(&helper_id_constructor(IdEnum::pool_definition_id)); + let vault_a_post = state.get_account_by_id(&helper_id_constructor(IdEnum::vault_a_id)); + let vault_b_post = state.get_account_by_id(&helper_id_constructor(IdEnum::vault_b_id)); + let user_token_a_post = state.get_account_by_id(&helper_id_constructor(IdEnum::user_token_a_id)); + let user_token_b_post = state.get_account_by_id(&helper_id_constructor(IdEnum::user_token_b_id)); + + let expected_pool = helper_account_constructor(AccountsEnum::pool_definition_swap_1); + let expected_vault_a = helper_account_constructor(AccountsEnum::vault_a_swap_1); + let expected_vault_b = helper_account_constructor(AccountsEnum::vault_b_swap_1); + let expected_user_token_a = helper_account_constructor(AccountsEnum::user_token_a_holding_swap_1); + let expected_user_token_b = helper_account_constructor(AccountsEnum::user_token_b_holding_swap_1); - let pool_post = state.get_account_by_id(&pool_id); - let vault_a_post = state.get_account_by_id(&vault_a_id); - let vault_b_post = state.get_account_by_id(&vault_b_id); - let swap_user_a_post = state.get_account_by_id(&swap_user_a_holding_id); - let swap_user_b_post = state.get_account_by_id(&swap_user_b_holding_id); - - - let withdraw_b = (init_balance_b * swap_a)/(init_balance_a + swap_a); - - let expected_pool = Account { - program_owner: Program::amm().id(), - balance: 0u128, - data: PoolDefinition::into_data( - PoolDefinition { - definition_token_a_id: token_a_definition_id, - definition_token_b_id: token_b_definition_id, - vault_a_addr: vault_a_id, - vault_b_addr: vault_b_id, - liquidity_pool_id: token_lp_definition_id, - liquidity_pool_cap: init_balance_a, - reserve_a: init_balance_a + swap_a, - reserve_b: init_balance_b - withdraw_b, - token_program_id: Program::token().id(), - }), - nonce: 2, - }; - - let expected_vault_a = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_a_definition_id, - balance: init_balance_a + swap_a, - }), - nonce: 1 - }; - - let expected_vault_b = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_b_definition_id, - balance: init_balance_b - withdraw_b, - }), - nonce: 1 - }; - - let expected_swap_user_a = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_a_definition_id, - balance: swap_user_a_amount - swap_a, - }), - nonce: 1 - }; - - let expected_swap_user_b = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_b_definition_id, - balance: swap_user_b_amount + withdraw_b, - }), - nonce: 1 - }; - + assert!(pool_post == expected_pool); assert!(vault_a_post == expected_vault_a); assert!(vault_b_post == expected_vault_b); - assert!(swap_user_a_post == expected_swap_user_a); - assert!(swap_user_b_post == expected_swap_user_b); - assert!(pool_post == expected_pool); - + assert!(user_token_a_post == expected_user_token_a); + assert!(user_token_b_post == expected_user_token_b); } - + #[test] fn test_simple_amm_swap_2() { - let (state, vec_private_keys, vec_id, vec_amounts) = initialize_amm(); - let mut state: V02State = state; - - let init_balance_a = vec_amounts[0]; - let init_balance_b = vec_amounts[1]; - let user_a_amount = vec_amounts[2]; - let user_b_amount = vec_amounts[3]; - - let token_a_holding_key = &vec_private_keys[0]; - let token_a_definition_key = &vec_private_keys[1]; - let token_b_holding_key = &vec_private_keys[2]; - let token_b_definition_key = &vec_private_keys[3]; - let pool_lp_definition_key = &vec_private_keys[4]; - let user_a_holding_key = &vec_private_keys[5]; - let user_b_holding_key = &vec_private_keys[6]; - let vault_a_key = &vec_private_keys[7]; - let vault_b_key = &vec_private_keys[8]; - let user_lp_holding_key = &vec_private_keys[9]; - let pool_key = &vec_private_keys[10]; - let pool_lp_holding_key = &vec_private_keys[11]; - - let token_a_holding_id = vec_id[0]; - let token_a_definition_id = vec_id[1]; - let token_b_holding_id = vec_id[2]; - let token_b_definition_id = vec_id[3]; - let token_lp_definition_id = vec_id[4]; - let user_a_holding_id = vec_id[5]; - let user_b_holding_id = vec_id[6]; - let vault_a_id = vec_id[7]; - let vault_b_id = vec_id[8]; - let user_lp_holding_id = vec_id[9]; - let pool_id = vec_id[10]; - let pool_lp_holding_id = vec_id[11]; - - //Initialize swap user accounts - let swap_user_a_holding_key = PrivateKey::try_new([21; 32]).unwrap(); - let swap_user_a_holding_id = - AccountId::from(&PublicKey::new_from_private_key(&swap_user_a_holding_key)); - let swap_user_a_amount: u128 = 5000; - - let swap_user_b_holding_key = PrivateKey::try_new([22; 32]).unwrap(); - let swap_user_b_holding_id = - AccountId::from(&PublicKey::new_from_private_key(&swap_user_b_holding_key)); - let swap_user_b_amount: u128 = 5000; - - // Initialize Swap User account for Token A - let mut instruction: [u8; 23] = [0; 23]; - instruction[0] = 1; //transfer - instruction[1..17].copy_from_slice(&swap_user_a_amount.to_le_bytes()); - - let message = public_transaction::Message::try_new( - Program::token().id(), - vec![token_a_holding_id, swap_user_a_holding_id], - vec![2], - instruction, - ) - .unwrap(); - - let witness_set = - public_transaction::WitnessSet::for_message(&message, &[&token_a_holding_key]); - let tx = PublicTransaction::new(message, witness_set); - state.transition_from_public_transaction(&tx).unwrap(); - - // Initialize Swap User account for Token B - let mut instruction: [u8; 23] = [0; 23]; - instruction[0] = 1; //transfer - instruction[1..17].copy_from_slice(&swap_user_b_amount.to_le_bytes()); - - let message = public_transaction::Message::try_new( - Program::token().id(), - vec![token_b_holding_id, swap_user_b_holding_id], - vec![state.get_account_by_id(&token_b_holding_id).nonce], - instruction, - ) - .unwrap(); - - let witness_set = - public_transaction::WitnessSet::for_message(&message, &[&token_b_holding_key]); - let tx = PublicTransaction::new(message, witness_set); - state.transition_from_public_transaction(&tx).unwrap(); - - // Swap - let main_addr = token_b_definition_id; - let swap_b: u128 = 500; + let mut state = amm_state_constructor(); let mut instruction: Vec = Vec::new(); instruction.push(1); - instruction.extend_from_slice(&swap_b.to_le_bytes()); - instruction.extend_from_slice(main_addr.value()); + instruction.extend_from_slice(&helper_balances_constructor(BalancesEnum::swap_amount_in).to_le_bytes()); + instruction.extend_from_slice(&helper_balances_constructor(BalancesEnum::swap_min_amount_out).to_le_bytes()); + instruction.extend_from_slice(&helper_id_constructor(IdEnum::token_a_definition_id).to_bytes()); let message = public_transaction::Message::try_new( Program::amm().id(), vec![ - pool_id, - vault_a_id, - vault_b_id, - swap_user_a_holding_id, - swap_user_b_holding_id, + helper_id_constructor(IdEnum::pool_definition_id), + helper_id_constructor(IdEnum::vault_a_id), + helper_id_constructor(IdEnum::vault_b_id), + helper_id_constructor(IdEnum::user_token_a_id), + helper_id_constructor(IdEnum::user_token_b_id), ], vec![ - state.get_account_by_id(&pool_id).nonce, - state.get_account_by_id(&vault_a_id).nonce, - state.get_account_by_id(&vault_b_id).nonce, - state - .get_account_by_id(&swap_user_a_holding_id) - .nonce, - state - .get_account_by_id(&swap_user_b_holding_id) - .nonce, + 0, + 0, ], instruction, ) .unwrap(); + //TODO: make note that token_name refers to token we're adding, not requesting let witness_set = public_transaction::WitnessSet::for_message( &message, &[ - &pool_key, - &vault_a_key, - &vault_b_key, - &swap_user_a_holding_key, - &swap_user_b_holding_key, + &helper_private_keys_constructor(PrivateKeysEnum::vault_b_key), + &helper_private_keys_constructor(PrivateKeysEnum::user_token_a_key), ], ); let tx = PublicTransaction::new(message, witness_set); state.transition_from_public_transaction(&tx).unwrap(); + + let pool_post = state.get_account_by_id(&helper_id_constructor(IdEnum::pool_definition_id)); + let vault_a_post = state.get_account_by_id(&helper_id_constructor(IdEnum::vault_a_id)); + let vault_b_post = state.get_account_by_id(&helper_id_constructor(IdEnum::vault_b_id)); + let user_token_a_post = state.get_account_by_id(&helper_id_constructor(IdEnum::user_token_a_id)); + let user_token_b_post = state.get_account_by_id(&helper_id_constructor(IdEnum::user_token_b_id)); - let pool_post = state.get_account_by_id(&pool_id); - let vault_a_post = state.get_account_by_id(&vault_a_id); - let vault_b_post = state.get_account_by_id(&vault_b_id); - let swap_user_a_post = state.get_account_by_id(&swap_user_a_holding_id); - let swap_user_b_post = state.get_account_by_id(&swap_user_b_holding_id); + let expected_pool = helper_account_constructor(AccountsEnum::pool_definition_swap_2); + let expected_vault_a = helper_account_constructor(AccountsEnum::vault_a_swap_2); + let expected_vault_b = helper_account_constructor(AccountsEnum::vault_b_swap_2); + let expected_user_token_a = helper_account_constructor(AccountsEnum::user_token_a_holding_swap_2); + let expected_user_token_b = helper_account_constructor(AccountsEnum::user_token_b_holding_swap_2); - let withdraw_a = (init_balance_a * swap_b)/(init_balance_b + swap_b); - - let expected_pool = Account { - program_owner: Program::amm().id(), - balance: 0u128, - data: PoolDefinition::into_data( - PoolDefinition { - definition_token_a_id: token_a_definition_id, - definition_token_b_id: token_b_definition_id, - vault_a_addr: vault_a_id, - vault_b_addr: vault_b_id, - liquidity_pool_id: token_lp_definition_id, - liquidity_pool_cap: init_balance_a, - reserve_a: init_balance_a - withdraw_a, - reserve_b: init_balance_b + swap_b, - token_program_id: Program::token().id(), - }), - nonce: 2, - }; - - let expected_vault_a = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_a_definition_id, - balance: init_balance_a - withdraw_a, - }), - nonce: 1 - }; - - let expected_vault_b = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_b_definition_id, - balance: init_balance_b + swap_b, - }), - nonce: 1 - }; - - let expected_swap_user_a = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_a_definition_id, - balance: swap_user_a_amount + withdraw_a, - }), - nonce: 1 - }; - - let expected_swap_user_b = Account { - program_owner: Program::token().id(), - balance: 0u128, - data: TokenHolding::into_data( - TokenHolding{ - account_type: TOKEN_HOLDING_TYPE, - definition_id: token_b_definition_id, - balance: swap_user_b_amount - swap_b, - }), - nonce: 1 - }; + assert!(pool_post == expected_pool); assert!(vault_a_post == expected_vault_a); assert!(vault_b_post == expected_vault_b); - assert!(swap_user_a_post == expected_swap_user_a); - assert!(swap_user_b_post == expected_swap_user_b); - assert!(pool_post == expected_pool); + assert!(user_token_a_post == expected_user_token_a); + assert!(user_token_b_post == expected_user_token_b); } + + }