diff --git a/nssa/core/src/account.rs b/nssa/core/src/account.rs index 86f70b5..d24dc8a 100644 --- a/nssa/core/src/account.rs +++ b/nssa/core/src/account.rs @@ -15,7 +15,7 @@ pub type Nonce = u128; /// Account to be used both in public and private contexts #[derive( - Serialize, Deserialize, Clone, Default, PartialEq, Eq, BorshSerialize, BorshDeserialize, + Clone, Default, Eq, PartialEq, Serialize, Deserialize, BorshSerialize, BorshDeserialize, )] #[cfg_attr(any(feature = "host", test), derive(Debug))] pub struct Account { @@ -25,7 +25,7 @@ pub struct Account { pub nonce: Nonce, } -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)] +#[derive(Clone, Eq, PartialEq, Serialize, Deserialize)] #[cfg_attr(any(feature = "host", test), derive(Debug))] pub struct AccountWithMetadata { pub account: Account, @@ -44,7 +44,7 @@ impl AccountWithMetadata { } } -#[derive(Serialize, Deserialize, Clone, Default, PartialEq, Eq, Hash, BorshSerialize, BorshDeserialize)] +#[derive(Default, Clone, Eq, Hash, PartialEq, Serialize, Deserialize, BorshSerialize, BorshDeserialize)] #[cfg_attr( any(feature = "host", test), derive(Debug, Copy, PartialOrd, Ord) diff --git a/nssa/program_methods/guest/src/bin/amm.rs b/nssa/program_methods/guest/src/bin/amm.rs index 2f18ddd..7d0bf97 100644 --- a/nssa/program_methods/guest/src/bin/amm.rs +++ b/nssa/program_methods/guest/src/bin/amm.rs @@ -10,7 +10,7 @@ use nssa_core::{ // 1. New AMM definition. // Arguments to this function are: // * Seven accounts: [amm_pool, vault_holding_a, vault_holding_b, pool_lp, user_holding_a, user_holding_b, user_holding_lp]. -// For new AMM Pool: amm_pool, vault_holding_a, vault_holding_b, pool_lp and user_holding_lp are default accounts. +// For new AMM Pool: amm_pool, vault_holding_a, vault_holding_b, pool_lp and user_holding_lp are default accounts. // 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 @@ -27,6 +27,8 @@ use nssa_core::{ // * An instruction data of 65-bytes, indicating the initial amm reserves' balances and token_program_id with // the following layout: // [0x00 || array of balances (little-endian 16 bytes) || AMM_PROGRAM_ID)] +// * Internally, calls compute_liquidity_token_pda_seed, compute_vault_pda_seed to authorize transfers. +// * Internally, calls compute_pool_da, compute_vault_pda and compute_vault_pda to check various AccountIds are correct. // 2. Swap assets // Arguments to this function are: // * Five accounts: [amm_pool, vault_holding_a, vault_holding_b, user_holding_a, user_holding_b]. @@ -34,6 +36,13 @@ use nssa_core::{ // * An instruction data byte string of length 65, indicating which token type to swap, quantity of tokens put into the swap // (of type TOKEN_DEFINITION_ID) and min_amount_out. // [0x01 || amount (little-endian 16 bytes) || TOKEN_DEFINITION_ID]. +// * Internally, calls swap logic. +// * Four accounts: [user_deposit, vault_deposit, vault_withdraw, user_withdraw]. +// user_deposit and vault_deposit define deposit transaction. +// vault_withdraw and user_withdraw define withdraw transaction. +// * deposit_amount is the amount for user_deposit -> vault_deposit transfer. +// * reserve_amounts is the pool's reserves; used to compute the withdraw amount. +// * Outputs the token transfers as a Vec and the withdraw amount. // 3. Add liquidity // Arguments to this function are: // * Seven accounts: [amm_pool, vault_holding_a, vault_holding_b, pool_lp, user_holding_a, user_holding_a, user_holding_lp]. @@ -41,33 +50,18 @@ use nssa_core::{ // * An instruction data byte string of length 49, amounts for minimum amount of liquidity from add (min_amount_lp), // * max amount added for each token (max_amount_a and max_amount_b); indicate // [0x02 || array of of balances (little-endian 16 bytes)]. +// * Internally, calls compute_liquidity_token_pda_seed to compute liquidity pool PDA seed. // 4. Remove liquidity // * Seven accounts: [amm_pool, vault_holding_a, vault_holding_b, pool_lp, user_holding_a, user_holding_a, user_holding_lp]. // * Requires authorization: user_holding_lp // * An instruction data byte string of length 49, amounts for minimum amount of liquidity to redeem (balance_lp), // * minimum balance of each token to remove (min_amount_a and min_amount_b); indicate // [0x03 || array of balances (little-endian 16 bytes)]. -// - Internal functions: -// - Swap logic -// Arguments of this function are: -// * Four accounts: [user_deposit, vault_deposit, vault_withdraw, user_withdraw]. -// user_deposit and vault_deposit define deposit transaction. -// vault_withdraw and user_withdraw define withdraw transaction. -// * deposit_amount is the amount for user_deposit -> vault_deposit transfer. -// * reserve_amounts is the pool's reserves; used to compute the withdraw amount. -// * Outputs the token transfers as a Vec and the withdraw amount. -// - PDA computations: -// * compute_pool_pda: AMM_PROGRAM_ID, token definitions for the pool pair -// * compute_vault_pda: AMM_PROGRAM_ID, pool definition id, definition token id -// * compute_liquidity_token_pda: AMM_PROGRAM, pool definition id, pool definition id -// - PDA seed computations: -// * compute_pool_pda_seed: token definitions for the pool pair -// * compute_vault_pda_seed: pool definition id, definition token id, -// * compute_liquidity_token_pda_seed: pool definition id +// * Internally, calls compute_vault_pda_seed to compute vault_a and vault_b's PDA seed. const POOL_DEFINITION_DATA_SIZE: usize = 225; -#[derive(Default)] +#[derive(Clone, Default)] struct PoolDefinition { definition_token_a_id: AccountId, definition_token_b_id: AccountId, @@ -77,8 +71,9 @@ struct PoolDefinition { liquidity_pool_supply: u128, reserve_a: u128, reserve_b: u128, - fees: u128, - active: bool, + fees: u128, // fees are currently not used + active: bool, // a pool becomes inactive (active = false) + // once all of its liquidity has been removed (e.g., reserves are emptied and liquidity_pool_supply = 0) } impl PoolDefinition { @@ -391,23 +386,13 @@ fn compute_pool_pda_seed( ) -> PdaSeed { use risc0_zkvm::sha::{Impl, Sha256}; - let mut i: usize = 0; - let (token_1, token_2) = loop { - if definition_token_a_id.value()[i] > definition_token_b_id.value()[i] { - let token_1 = definition_token_a_id.clone(); - let token_2 = definition_token_b_id.clone(); - break (token_1, token_2); - } else if definition_token_a_id.value()[i] < definition_token_b_id.value()[i] { - let token_1 = definition_token_b_id.clone(); - let token_2 = definition_token_a_id.clone(); - break (token_1, token_2); - } + //let mut i: usize = 0; + //TODO - if i == 32 { - panic!("Definitions match"); - } else { - i += 1; - } + let (token_1, token_2) = match definition_token_a_id.value().cmp(definition_token_b_id.value()) { + std::cmp::Ordering::Less => (definition_token_b_id.clone(), definition_token_a_id.clone()), + std::cmp::Ordering::Greater => (definition_token_a_id.clone(), definition_token_b_id.clone()), + std::cmp::Ordering::Equal => panic!("Definitions match"), }; let mut bytes = [0; 64]; @@ -467,6 +452,32 @@ fn compute_liquidity_token_pda_seed(pool_id: AccountId) -> PdaSeed { ) } +const TOKEN_PROGRAM_NEW: u8 = 0; +const TOKEN_PROGRAM_TRANSFER: u8 = 1; +const TOKEN_PROGRAM_MINT: u8 = 4; +const TOKEN_PROGRAM_BURN: u8 = 3; + +fn initialize_token_transfer_chained_call( + token_program_command: u8, + sender: AccountWithMetadata, + recipient: AccountWithMetadata, + amount_to_move: u128, + pda_seed: Vec, +) -> ChainedCall { + let mut instruction_data = [0; 23]; + instruction_data[0] = token_program_command; + instruction_data[1..17].copy_from_slice(&amount_to_move.to_le_bytes()); + let instruction_data = risc0_zkvm::serde::to_vec(&instruction_data) + .expect("AMM Program expects valid token transfer instruction data"); + + ChainedCall { + program_id: sender.account.program_owner, + instruction_data, + pre_states: vec![sender, recipient], + pda_seeds: pda_seed, + } +} + fn new_definition( pre_states: &[AccountWithMetadata], balance_in: &[u128], @@ -510,6 +521,10 @@ fn new_definition( // both instances of the same token program let token_program = user_holding_a.account.program_owner; + if user_holding_b.account.program_owner != token_program { + panic!("User Token holdings must use the same Token Program"); + } + if definition_token_a_id == definition_token_b_id { panic!("Cannot set up a swap for a token with itself") } @@ -557,10 +572,10 @@ fn new_definition( panic!("Cannot initialize an active Pool Definition") } - //3. LP Token minting calculation + // LP Token minting calculation // We assume LP is based on the initial deposit amount for Token_A. - // 5. Update pool account + // Update pool account let mut pool_post = pool.account.clone(); let pool_post_definition = PoolDefinition { definition_token_a_id, @@ -585,38 +600,28 @@ fn new_definition( let mut chained_calls = Vec::::new(); //Chain call for Token A (user_holding_a -> Vault_A) - let mut instruction_data = [0; 23]; - instruction_data[0] = 1; - instruction_data[1..17].copy_from_slice(&amount_a.to_le_bytes()); - let instruction_data = risc0_zkvm::serde::to_vec(&instruction_data) - .expect("New definition: AMM Program expects valid token transfer instruction data"); - let call_token_a = ChainedCall { - program_id: user_holding_a.account.program_owner, - instruction_data, - pre_states: vec![user_holding_a.clone(), vault_a.clone()], - pda_seeds: Vec::::new(), - }; - + let call_token_a = initialize_token_transfer_chained_call( + TOKEN_PROGRAM_TRANSFER, + user_holding_a.clone(), + vault_a.clone(), + amount_a, + Vec::::new(), + ); //Chain call for Token B (user_holding_b -> Vault_B) - let mut instruction_data = [0; 23]; - instruction_data[0] = 1; - instruction_data[1..17].copy_from_slice(&amount_b.to_le_bytes()); - let instruction_data = risc0_zkvm::serde::to_vec(&instruction_data) - .expect("New definition: AMM Program expects valid instruction_data"); - - let call_token_b = ChainedCall { - program_id: user_holding_b.account.program_owner, - instruction_data, - pre_states: vec![user_holding_b.clone(), vault_b.clone()], - pda_seeds: Vec::::new(), - }; + let call_token_b = initialize_token_transfer_chained_call( + TOKEN_PROGRAM_TRANSFER, + user_holding_b.clone(), + vault_b.clone(), + amount_b, + Vec::::new(), + ); //Chain call for liquidity token (TokenLP definition -> User LP Holding) let mut instruction_data = [0; 23]; instruction_data[0] = if pool.account == Account::default() { - 0 + TOKEN_PROGRAM_NEW } else { - 4 + TOKEN_PROGRAM_MINT }; //new or mint let nme = if pool.account == Account::default() { [1u8; 6] @@ -712,12 +717,10 @@ fn swap( let (chained_calls, [deposit_a, withdraw_a], [deposit_b, withdraw_b]) = if token_in_id == pool_def_data.definition_token_a_id { let (chained_calls, deposit_a, withdraw_b) = swap_logic( - &[ - user_holding_a.clone(), - vault_a.clone(), - vault_b.clone(), - user_holding_b.clone(), - ], + user_holding_a.clone(), + vault_a.clone(), + vault_b.clone(), + user_holding_b.clone(), &amounts, &[pool_def_data.reserve_a, pool_def_data.reserve_b], pool.account_id.clone(), @@ -726,12 +729,10 @@ fn swap( (chained_calls, [deposit_a, 0], [0, withdraw_b]) } else if token_in_id == pool_def_data.definition_token_b_id { let (chained_calls, deposit_b, withdraw_a) = swap_logic( - &[ - user_holding_b.clone(), - vault_b.clone(), - vault_a.clone(), - user_holding_a.clone(), - ], + user_holding_b.clone(), + vault_b.clone(), + vault_a.clone(), + user_holding_a.clone(), &amounts, &[pool_def_data.reserve_b, pool_def_data.reserve_a], pool.account_id.clone(), @@ -745,16 +746,9 @@ fn swap( // Update pool account let mut pool_post = pool.account.clone(); let pool_post_definition = PoolDefinition { - definition_token_a_id: pool_def_data.definition_token_a_id.clone(), - definition_token_b_id: pool_def_data.definition_token_b_id.clone(), - vault_a_id: pool_def_data.vault_a_id.clone(), - vault_b_id: pool_def_data.vault_b_id.clone(), - liquidity_pool_id: pool_def_data.liquidity_pool_id.clone(), - 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, + ..pool_def_data }; pool_post.data = pool_post_definition.into_data(); @@ -771,16 +765,14 @@ fn swap( } fn swap_logic( - pre_states: &[AccountWithMetadata], + user_deposit: AccountWithMetadata, + vault_deposit: AccountWithMetadata, + vault_withdraw: AccountWithMetadata, + user_withdraw: AccountWithMetadata, balances: &[u128], reserve_amounts: &[u128], pool_id: AccountId, ) -> (Vec, u128, u128) { - let user_deposit = pre_states[0].clone(); - let vault_deposit = pre_states[1].clone(); - let vault_withdraw = pre_states[2].clone(); - let user_withdraw = pre_states[3].clone(); - let reserve_deposit_vault_amount = reserve_amounts[0]; let reserve_withdraw_vault_amount = reserve_amounts[1]; @@ -788,8 +780,8 @@ fn swap_logic( let min_amount_out = balances[1]; // Compute withdraw amount - // Compute pool's exchange constant - // let k = pool_def_data.reserve_a * pool_def_data.reserve_b; + // Maintains pool constant product + // k = pool_def_data.reserve_a * pool_def_data.reserve_b; let withdraw_amount = (reserve_withdraw_vault_amount * deposit_amount) / (reserve_deposit_vault_amount + deposit_amount); @@ -803,37 +795,29 @@ fn swap_logic( } let mut chained_calls = Vec::new(); - let mut instruction_data = [0; 23]; - instruction_data[0] = 1; - instruction_data[1..17].copy_from_slice(&deposit_amount.to_le_bytes()); - let instruction_data = risc0_zkvm::serde::to_vec(&instruction_data) - .expect("Swap Logic: AMM Program expects valid transaction instruction data"); - chained_calls.push(ChainedCall { - program_id: vault_deposit.account.program_owner, - instruction_data, - pre_states: vec![user_deposit.clone(), vault_deposit.clone()], - pda_seeds: Vec::::new(), - }); + chained_calls.push(initialize_token_transfer_chained_call( + TOKEN_PROGRAM_TRANSFER, + user_deposit.clone(), + vault_deposit.clone(), + deposit_amount, + Vec::::new(), + )); let mut vault_withdraw = vault_withdraw.clone(); vault_withdraw.is_authorized = true; - let mut instruction_data = [0; 23]; - instruction_data[0] = 1; - instruction_data[1..17].copy_from_slice(&withdraw_amount.to_le_bytes()); - let instruction_data = risc0_zkvm::serde::to_vec(&instruction_data) - .expect("Swap Logic: AMM Program expects valid transaction instruction data"); - chained_calls.push(ChainedCall { - program_id: vault_deposit.account.program_owner, - instruction_data, - pre_states: vec![vault_withdraw.clone(), user_withdraw.clone()], - pda_seeds: vec![compute_vault_pda_seed( + chained_calls.push(initialize_token_transfer_chained_call( + TOKEN_PROGRAM_TRANSFER, + vault_withdraw.clone(), + user_withdraw.clone(), + withdraw_amount, + vec![compute_vault_pda_seed( pool_id, TokenHolding::parse(&vault_withdraw.account.data) .expect("Swap Logic: AMM Program expects valid token data") .definition_id, )], - }); + )); (chained_calls, deposit_amount, withdraw_amount) } @@ -941,62 +925,41 @@ fn add_liquidity( // 5. Update pool account let mut pool_post = pool.account.clone(); let pool_post_definition = PoolDefinition { - definition_token_a_id: pool_def_data.definition_token_a_id.clone(), - definition_token_b_id: pool_def_data.definition_token_b_id.clone(), - vault_a_id: pool_def_data.vault_a_id.clone(), - vault_b_id: pool_def_data.vault_b_id.clone(), - liquidity_pool_id: pool_def_data.liquidity_pool_id.clone(), 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, + ..pool_def_data }; pool_post.data = pool_post_definition.into_data(); let mut chained_call = Vec::new(); // Chain call for Token A (UserHoldingA -> Vault_A) - let mut instruction_data = [0; 23]; - instruction_data[0] = 1; - instruction_data[1..17].copy_from_slice(&actual_amount_a.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_a = ChainedCall { - program_id: vault_a.account.program_owner, - instruction_data, - pre_states: vec![user_holding_a.clone(), vault_a.clone()], - pda_seeds: Vec::::new(), - }; - + let call_token_a = initialize_token_transfer_chained_call( + TOKEN_PROGRAM_TRANSFER, + user_holding_a.clone(), + vault_a.clone(), + actual_amount_a, + Vec::::new(), + ); // Chain call for Token B (UserHoldingB -> Vault_B) - let mut instruction_data = [0; 23]; - instruction_data[0] = 1; - instruction_data[1..17].copy_from_slice(&actual_amount_b.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_b = ChainedCall { - program_id: vault_b.account.program_owner, - instruction_data, - pre_states: vec![user_holding_b.clone(), vault_b.clone()], - pda_seeds: Vec::::new(), - }; - + let call_token_b = initialize_token_transfer_chained_call( + TOKEN_PROGRAM_TRANSFER, + user_holding_b.clone(), + vault_b.clone(), + actual_amount_b, + Vec::::new(), + ); // Chain call for LP (mint new tokens for user_holding_lp) let mut pool_definition_lp_auth = pool_definition_lp.clone(); pool_definition_lp_auth.is_authorized = true; - - let mut instruction_data = [0; 23]; - 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_definition_lp.account.program_owner, - instruction_data, - pre_states: vec![pool_definition_lp_auth.clone(), user_holding_lp.clone()], - pda_seeds: vec![compute_liquidity_token_pda_seed(pool.account_id.clone())], - }; + let call_token_lp = initialize_token_transfer_chained_call( + TOKEN_PROGRAM_MINT, + pool_definition_lp_auth.clone(), + user_holding_lp.clone(), + delta_lp, + vec![compute_liquidity_token_pda_seed(pool.account_id.clone())], + ); chained_call.push(call_token_lp); chained_call.push(call_token_b); @@ -1111,16 +1074,10 @@ fn remove_liquidity( // 5. Update pool account let mut pool_post = pool.account.clone(); let pool_post_definition = PoolDefinition { - definition_token_a_id: pool_def_data.definition_token_a_id.clone(), - definition_token_b_id: pool_def_data.definition_token_b_id.clone(), - vault_a_id: pool_def_data.vault_a_id.clone(), - vault_b_id: pool_def_data.vault_b_id.clone(), - liquidity_pool_id: pool_def_data.liquidity_pool_id.clone(), 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, - fees: 0u128, - active, + ..pool_def_data.clone() }; pool_post.data = pool_post_definition.into_data(); @@ -1128,52 +1085,37 @@ fn remove_liquidity( let mut chained_calls = Vec::new(); //Chaincall for Token A withdraw - let mut instruction: [u8; 23] = [0; 23]; - instruction[0] = 1; // token transfer - 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"); - let call_token_a = ChainedCall { - program_id: vault_a.account.program_owner, - instruction_data, - pre_states: vec![running_vault_a, user_holding_a.clone()], - pda_seeds: vec![compute_vault_pda_seed( + let call_token_a = initialize_token_transfer_chained_call( + TOKEN_PROGRAM_TRANSFER, + running_vault_a, + user_holding_a.clone(), + withdraw_amount_a, + vec![compute_vault_pda_seed( pool.account_id.clone(), pool_def_data.definition_token_a_id.clone(), )], - }; - + ); //Chaincall for Token B withdraw - let mut instruction: [u8; 23] = [0; 23]; - instruction[0] = 1; // token transfer - 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"); - let call_token_b = ChainedCall { - program_id: vault_b.account.program_owner, - instruction_data, - pre_states: vec![running_vault_b, user_holding_b.clone()], - pda_seeds: vec![compute_vault_pda_seed( + let call_token_b = initialize_token_transfer_chained_call( + TOKEN_PROGRAM_TRANSFER, + running_vault_b, + user_holding_b.clone(), + withdraw_amount_b, + vec![compute_vault_pda_seed( pool.account_id.clone(), pool_def_data.definition_token_b_id.clone(), )], - }; - + ); //Chaincall for LP adjustment let mut pool_definition_lp_auth = pool_definition_lp.clone(); pool_definition_lp_auth.is_authorized = true; - - let mut instruction: [u8; 23] = [0; 23]; - instruction[0] = 3; // token burn - 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_definition_lp.account.program_owner, - instruction_data, - pre_states: vec![pool_definition_lp_auth.clone(), user_holding_lp.clone()], - pda_seeds: vec![compute_liquidity_token_pda_seed(pool.account_id.clone())], - }; + let call_token_lp = initialize_token_transfer_chained_call( + TOKEN_PROGRAM_BURN, + pool_definition_lp_auth.clone(), + user_holding_lp.clone(), + delta_lp, + vec![compute_liquidity_token_pda_seed(pool.account_id.clone())], + ); chained_calls.push(call_token_lp); chained_calls.push(call_token_b); @@ -1267,11 +1209,6 @@ mod tests { 50 } - //TODO used??? BalanceEnum::RemoveMinAmountBAow => 10, - fn remove_min_amount_a_low() -> u128 { - 10 - } - fn remove_amount_lp() -> u128 { 100 } @@ -1586,7 +1523,7 @@ mod tests { fn cc_remove_pool_lp() -> ChainedCall { let mut pool_lp_auth = AccountForTests::pool_lp_init(); pool_lp_auth.is_authorized = true; - + let mut instruction: [u8; 23] = [0; 23]; instruction[0] = 3; instruction[1..17] @@ -1607,38 +1544,60 @@ mod tests { } fn cc_new_definition_token_a() -> ChainedCall { - let mut instruction: [u8;23] = [0; 23]; + let mut instruction: [u8; 23] = [0; 23]; instruction[0] = 1; - instruction[1..17].copy_from_slice( - &BalanceForTests::add_successful_amount_a() - .to_le_bytes()); - let instruction_data = risc0_zkvm::serde::to_vec(&instruction).expect("AMM Program expects valid transaction instruction data"); - ChainedCall{ + instruction[1..17] + .copy_from_slice(&BalanceForTests::add_successful_amount_a().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![ - AccountForTests::user_holding_a(), - AccountForTests::vault_a_init()], + AccountForTests::user_holding_a(), + AccountForTests::vault_a_init(), + ], pda_seeds: Vec::::new(), } } - + fn cc_new_definition_token_b() -> ChainedCall { - let mut instruction: [u8;23] = [0; 23]; + let mut instruction: [u8; 23] = [0; 23]; instruction[0] = 1; - instruction[1..17].copy_from_slice( - &BalanceForTests::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{ + instruction[1..17] + .copy_from_slice(&BalanceForTests::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![ - AccountForTests::user_holding_b(), - AccountForTests::vault_b_init()], + AccountForTests::user_holding_b(), + AccountForTests::vault_b_init(), + ], pda_seeds: Vec::::new(), } } + + fn cc_new_definition_token_lp() -> ChainedCall { + let mut instruction: [u8; 23] = [0; 23]; + instruction[0] = 1; + instruction[1..17] + .copy_from_slice(&BalanceForTests::add_successful_amount_a().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![ + AccountForTests::pool_lp_init(), + AccountForTests::user_holding_lp_uninit(), + ], + pda_seeds: vec![compute_liquidity_token_pda_seed( + IdForTests::pool_definition_id(), + )], + } + } } struct IdForTests; @@ -2373,23 +2332,6 @@ mod tests { } } - /*TODO-delete fn pool_lp_with_wrong_id() -> AccountWithMetadata { - AccountWithMetadata { - account: Account { - program_owner: TOKEN_PROGRAM_ID, - balance: 0u128, - data: TokenDefinition::into_data(TokenDefinition { - account_type: 0u8, - name: [1; 6], - total_supply: BalanceForTests::vault_a_reserve_init(), - }), - nonce: 0, - }, - is_authorized: true, - account_id: AccountId::new([4; 32]), - } - }*/ - fn pool_definition_active() -> AccountWithMetadata { AccountWithMetadata { account: Account { @@ -2760,8 +2702,7 @@ mod tests { assert!(chained_call_a == ChainedCallForTests::cc_new_definition_token_a()); assert!(chained_call_b == ChainedCallForTests::cc_new_definition_token_b()); - //TODO: this is bad - // assert!(chained_call_lp == ChainedCallForTests::cc_new_definition_token_lp()); + assert!(chained_call_lp == ChainedCallForTests::cc_new_definition_token_lp()); } #[should_panic(expected = "Invalid number of input accounts")] @@ -3219,7 +3160,7 @@ mod tests { ]; let _post_states = add_liquidity(&pre_states, &[BalanceForTests::add_min_amount_lp()]); } - + #[should_panic(expected = "Invalid number of input balances")] #[test] fn test_call_add_liquidity_invalid_number_of_balances_2() { @@ -3232,11 +3173,13 @@ mod tests { AccountForTests::user_holding_b(), AccountForTests::user_holding_lp_init(), ]; - let _post_states = add_liquidity(&pre_states, + let _post_states = add_liquidity( + &pre_states, &[ BalanceForTests::add_min_amount_lp(), BalanceForTests::add_max_amount_a(), - ]); + ], + ); } #[should_panic(expected = "Vault A was not provided")] @@ -3385,7 +3328,7 @@ mod tests { ]; let _post_states = add_liquidity( &pre_states, - &[ //todo UGH + &[ BalanceForTests::add_max_amount_a(), BalanceForTests::add_max_amount_b(), BalanceForTests::add_min_amount_lp(), @@ -3451,7 +3394,7 @@ mod tests { ]; let _post_states = add_liquidity( &pre_states, - &[ + &[ BalanceForTests::add_min_amount_lp(), BalanceForTests::add_max_amount_a_low(), BalanceForTests::add_max_amount_b_low(), @@ -3517,7 +3460,7 @@ mod tests { ]; let _post_states = add_liquidity( &pre_states, - &[ + &[ BalanceForTests::add_min_amount_lp(), BalanceForTests::add_max_amount_a_low(), BalanceForTests::add_max_amount_b_low(), @@ -3538,9 +3481,11 @@ mod tests { ]; let (post_states, chained_calls) = add_liquidity( &pre_states, - &[BalanceForTests::add_min_amount_lp(), - BalanceForTests::add_max_amount_a(), - BalanceForTests::add_max_amount_b(),], + &[ + BalanceForTests::add_min_amount_lp(), + BalanceForTests::add_max_amount_a(), + BalanceForTests::add_max_amount_b(), + ], ); let pool_post = post_states[0].clone(); @@ -3795,7 +3740,7 @@ mod tests { &[ BalanceForTests::add_max_amount_a(), BalanceForTests::add_max_amount_a_low(), - ], //TODO: should be b? + ], IdForTests::token_a_definition_id(), ); diff --git a/nssa/src/state.rs b/nssa/src/state.rs index 589512e..bf5d857 100644 --- a/nssa/src/state.rs +++ b/nssa/src/state.rs @@ -2442,6 +2442,7 @@ pub mod tests { .expect("Hash output must be exactly 32 bytes long"), ) } + const POOL_DEFINITION_DATA_SIZE: usize = 225; #[derive(Default)] @@ -3647,7 +3648,7 @@ pub mod tests { let expected_pool = AccountForTests::pool_definition_init(); let expected_vault_a = AccountForTests::vault_a_init(); let expected_vault_b = AccountForTests::vault_b_init(); - let expected_token_lp = AccountForTests::token_lp_definition_new_init(); //TODO? + let expected_token_lp = AccountForTests::token_lp_definition_new_init(); let expected_user_token_a = AccountForTests::user_token_a_holding_new_init(); let expected_user_token_b = AccountForTests::user_token_b_holding_new_init(); let expected_user_token_lp = AccountForTests::user_token_lp_holding_new_init();