chore: fix lints, fmt and artifacts

This commit is contained in:
Daniil Polyakov 2025-12-24 03:39:39 +03:00
parent e6a73a02b5
commit 2e82d2ddb8
18 changed files with 114 additions and 378 deletions

2
Cargo.lock generated
View File

@ -2657,6 +2657,7 @@ name = "nssa"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"borsh", "borsh",
"bytemuck",
"hex", "hex",
"hex-literal 1.1.0", "hex-literal 1.1.0",
"log", "log",
@ -3025,6 +3026,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"clap", "clap",
"nssa", "nssa",
"nssa_core",
"tokio", "tokio",
"wallet", "wallet",
] ]

Binary file not shown.

View File

@ -5,6 +5,7 @@ edition = "2024"
[dependencies] [dependencies]
nssa.workspace = true nssa.workspace = true
nssa_core.workspace = true
wallet.workspace = true wallet.workspace = true
tokio = { workspace = true, features = ["macros"] } tokio = { workspace = true, features = ["macros"] }

View File

@ -45,7 +45,16 @@ impl AccountWithMetadata {
} }
#[derive( #[derive(
Copy, Clone, Default, Serialize, Deserialize, PartialEq, Eq, Hash, BorshSerialize, BorshDeserialize, Copy,
Clone,
Default,
Serialize,
Deserialize,
PartialEq,
Eq,
Hash,
BorshSerialize,
BorshDeserialize,
)] )]
#[cfg_attr(any(feature = "host", test), derive(Debug, PartialOrd, Ord))] #[cfg_attr(any(feature = "host", test), derive(Debug, PartialOrd, Ord))]
pub struct AccountId { pub struct AccountId {
@ -184,7 +193,7 @@ mod tests {
#[test] #[test]
fn default_account_id() { fn default_account_id() {
let default_account_id = AccountId::default(); let default_account_id = AccountId::default();
let expected_account_id = AccountId::new([0;32]); let expected_account_id = AccountId::new([0; 32]);
assert!(default_account_id == expected_account_id); assert!(default_account_id == expected_account_id);
} }
} }

View File

@ -2281,12 +2281,10 @@ pub mod tests {
)); ));
} }
//TODO: repeated code needs to be cleaned up // TODO: repeated code needs to be cleaned up
//from token.rs (also repeated in amm.rs) // from token.rs (also repeated in amm.rs)
const TOKEN_DEFINITION_TYPE: u8 = 0;
const TOKEN_DEFINITION_DATA_SIZE: usize = 23; const TOKEN_DEFINITION_DATA_SIZE: usize = 23;
const TOKEN_HOLDING_TYPE: u8 = 1;
const TOKEN_HOLDING_DATA_SIZE: usize = 49; const TOKEN_HOLDING_DATA_SIZE: usize = 49;
struct TokenDefinition { struct TokenDefinition {
@ -2314,29 +2312,6 @@ pub mod tests {
} }
impl TokenHolding { impl TokenHolding {
fn new(definition_id: &AccountId) -> Self {
Self {
account_type: TOKEN_HOLDING_TYPE,
definition_id: *definition_id,
balance: 0,
}
}
fn parse(data: &[u8]) -> Option<Self> {
if data.len() != TOKEN_HOLDING_DATA_SIZE || data[0] != TOKEN_HOLDING_TYPE {
None
} else {
let account_type = data[0];
let definition_id = AccountId::new(data[1..33].try_into().unwrap());
let balance = u128::from_le_bytes(data[33..].try_into().unwrap());
Some(Self {
definition_id,
balance,
account_type,
})
}
}
fn into_data(self) -> Data { fn into_data(self) -> Data {
let mut bytes = [0; TOKEN_HOLDING_DATA_SIZE]; let mut bytes = [0; TOKEN_HOLDING_DATA_SIZE];
bytes[0] = self.account_type; bytes[0] = self.account_type;
@ -2349,7 +2324,7 @@ pub mod tests {
} }
} }
//TODO repeated code should ultimately be removed; // TODO repeated code should ultimately be removed;
fn compute_pool_pda( fn compute_pool_pda(
amm_program_id: ProgramId, amm_program_id: ProgramId,
definition_token_a_id: AccountId, definition_token_a_id: AccountId,
@ -2478,52 +2453,6 @@ pub mod tests {
.try_into() .try_into()
.expect("225 bytes should fit into Data") .expect("225 bytes should fit into Data")
} }
fn parse(data: &[u8]) -> Option<Self> {
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_id = 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_id = 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_id,
vault_b_id,
liquidity_pool_id,
liquidity_pool_supply,
reserve_a,
reserve_b,
fees,
active,
})
}
}
} }
struct PrivateKeysForTests; struct PrivateKeysForTests;
@ -2720,6 +2649,7 @@ pub mod tests {
fn token_a_definition_id() -> AccountId { fn token_a_definition_id() -> AccountId {
AccountId::new([3; 32]) AccountId::new([3; 32])
} }
fn token_b_definition_id() -> AccountId { fn token_b_definition_id() -> AccountId {
AccountId::new([4; 32]) AccountId::new([4; 32])
} }

View File

@ -7,56 +7,59 @@ use nssa_core::{
}; };
// The AMM program has five functions (four directly accessible via instructions): // The AMM program has five functions (four directly accessible via instructions):
// 1. New AMM definition. // 1. New AMM definition. Arguments to this function are:
// Arguments to this function are: // * Seven accounts: [amm_pool, vault_holding_a, vault_holding_b, pool_lp, user_holding_a,
// * Seven accounts: [amm_pool, vault_holding_a, vault_holding_b, pool_lp, user_holding_a, user_holding_b, user_holding_lp]. // user_holding_b, user_holding_lp]. For new AMM Pool: amm_pool, vault_holding_a,
// For new AMM Pool: amm_pool, vault_holding_a, vault_holding_b, pool_lp and user_holding_lp are default accounts. // vault_holding_b, pool_lp and user_holding_lp are default accounts. amm_pool is a default
// amm_pool is a default account that will initiate the amm definition account values // account that will initiate the amm definition account values vault_holding_a is a token
// vault_holding_a is a token holding account for token a // holding account for token a vault_holding_b is a token holding account for token b pool_lp
// vault_holding_b is a token holding account for token b // is a token holding account for the pool's lp token user_holding_a is a token holding
// pool_lp is a token holding account for the pool's lp token // account for token a user_holding_b is a token holding account for token b user_holding_lp
// user_holding_a is a token holding account for token a // is a token holding account for lp token
// user_holding_b is a token holding account for token b // * PDA remark: Accounts amm_pool, vault_holding_a, vault_holding_b and pool_lp are PDA. The
// user_holding_lp is a token holding account for lp token // AccountId for these accounts must be computed using: amm_pool AccountId <-
// * PDA remark: Accounts amm_pool, vault_holding_a, vault_holding_b and pool_lp are PDA. // compute_pool_pda vault_holding_a, vault_holding_b <- compute_vault_pda pool_lp
// The AccountId for these accounts must be computed using: // <-compute_liquidity_token_pda
// amm_pool AccountId <- compute_pool_pda
// vault_holding_a, vault_holding_b <- compute_vault_pda
// pool_lp <-compute_liquidity_token_pda
// * Requires authorization: user_holding_a, user_holding_b // * Requires authorization: user_holding_a, user_holding_b
// * An instruction data of 65-bytes, indicating the initial amm reserves' balances and token_program_id with // * An instruction data of 65-bytes, indicating the initial amm reserves' balances and
// the following layout: // token_program_id with the following layout: [0x00 || array of balances (little-endian 16
// [0x00 || array of balances (little-endian 16 bytes) || AMM_PROGRAM_ID)] // bytes) || AMM_PROGRAM_ID)]
// * Internally, calls compute_liquidity_token_pda_seed, compute_vault_pda_seed to authorize transfers. // * Internally, calls compute_liquidity_token_pda_seed, compute_vault_pda_seed to authorize
// * Internally, calls compute_pool_da, compute_vault_pda and compute_vault_pda to check various AccountIds are correct. // transfers.
// 2. Swap assets // * Internally, calls compute_pool_da, compute_vault_pda and compute_vault_pda to check
// Arguments to this function are: // various AccountIds are correct.
// * Five accounts: [amm_pool, vault_holding_a, vault_holding_b, user_holding_a, user_holding_b]. // 2. Swap assets Arguments to this function are:
// * Requires authorization: user holding account associated to TOKEN_DEFINITION_ID (either user_holding_a or user_holding_b) // * Five accounts: [amm_pool, vault_holding_a, vault_holding_b, user_holding_a,
// * An instruction data byte string of length 65, indicating which token type to swap, quantity of tokens put into the swap // user_holding_b].
// (of type TOKEN_DEFINITION_ID) and min_amount_out. // * Requires authorization: user holding account associated to TOKEN_DEFINITION_ID (either
// user_holding_a or user_holding_b)
// * 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]. // [0x01 || amount (little-endian 16 bytes) || TOKEN_DEFINITION_ID].
// * Internally, calls swap logic. // * Internally, calls swap logic.
// * Four accounts: [user_deposit, vault_deposit, vault_withdraw, user_withdraw]. // * Four accounts: [user_deposit, vault_deposit, vault_withdraw, user_withdraw].
// user_deposit and vault_deposit define deposit transaction. // user_deposit and vault_deposit define deposit transaction. vault_withdraw and
// vault_withdraw and user_withdraw define withdraw transaction. // user_withdraw define withdraw transaction.
// * deposit_amount is the amount for user_deposit -> vault_deposit transfer. // * deposit_amount is the amount for user_deposit -> vault_deposit transfer.
// * reserve_amounts is the pool's reserves; used to compute the withdraw amount. // * reserve_amounts is the pool's reserves; used to compute the withdraw amount.
// * Outputs the token transfers as a Vec<ChainedCall> and the withdraw amount. // * Outputs the token transfers as a Vec<ChainedCall> and the withdraw amount.
// 3. Add liquidity // 3. Add liquidity Arguments to this function are:
// Arguments to this function are: // * Seven accounts: [amm_pool, vault_holding_a, vault_holding_b, pool_lp, user_holding_a,
// * Seven accounts: [amm_pool, vault_holding_a, vault_holding_b, pool_lp, user_holding_a, user_holding_a, user_holding_lp]. // user_holding_a, user_holding_lp].
// * Requires authorization: user_holding_a, user_holding_b // * Requires authorization: user_holding_a, user_holding_b
// * An instruction data byte string of length 49, amounts for minimum amount of liquidity from add (min_amount_lp), // * An instruction data byte string of length 49, amounts for minimum amount of liquidity from
// * max amount added for each token (max_amount_a and max_amount_b); indicate // add (min_amount_lp),
// [0x02 || array of of balances (little-endian 16 bytes)]. // * 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. // * Internally, calls compute_liquidity_token_pda_seed to compute liquidity pool PDA seed.
// 4. Remove liquidity // 4. Remove liquidity
// * Seven accounts: [amm_pool, vault_holding_a, vault_holding_b, pool_lp, user_holding_a, user_holding_a, user_holding_lp]. // * 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 // * Requires authorization: user_holding_lp
// * An instruction data byte string of length 49, amounts for minimum amount of liquidity to redeem (balance_lp), // * An instruction data byte string of length 49, amounts for minimum amount of liquidity to
// * minimum balance of each token to remove (min_amount_a and min_amount_b); indicate // redeem (balance_lp),
// [0x03 || array of balances (little-endian 16 bytes)]. // * minimum balance of each token to remove (min_amount_a and min_amount_b); indicate [0x03 ||
// array of balances (little-endian 16 bytes)].
// * Internally, calls compute_vault_pda_seed to compute vault_a and vault_b's PDA seed. // * Internally, calls compute_vault_pda_seed to compute vault_a and vault_b's PDA seed.
const POOL_DEFINITION_DATA_SIZE: usize = 225; const POOL_DEFINITION_DATA_SIZE: usize = 225;
@ -74,7 +77,8 @@ struct PoolDefinition {
/// Fees are currently not used /// Fees are currently not used
fees: u128, fees: u128,
/// A pool becomes inactive (active = false) /// A pool becomes inactive (active = false)
/// once all of its liquidity has been removed (e.g., reserves are emptied and liquidity_pool_supply = 0) /// once all of its liquidity has been removed (e.g., reserves are emptied and
/// liquidity_pool_supply = 0)
active: bool, active: bool,
} }
@ -148,66 +152,19 @@ impl PoolDefinition {
} }
} }
//TODO: remove repeated code for Token_Definition and TokenHoldling // TODO: remove repeated code for Token_Definition and TokenHoldling
const TOKEN_DEFINITION_TYPE: u8 = 0;
const TOKEN_DEFINITION_DATA_SIZE: usize = 23;
const TOKEN_HOLDING_TYPE: u8 = 1; const TOKEN_HOLDING_TYPE: u8 = 1;
const TOKEN_HOLDING_DATA_SIZE: usize = 49; const TOKEN_HOLDING_DATA_SIZE: usize = 49;
struct TokenDefinition {
account_type: u8,
name: [u8; 6],
total_supply: u128,
}
struct TokenHolding { struct TokenHolding {
#[cfg_attr(not(test), expect(dead_code, reason = "TODO: fix later"))]
account_type: u8, account_type: u8,
definition_id: AccountId, definition_id: AccountId,
balance: u128, balance: u128,
} }
impl TokenDefinition {
fn into_data(self) -> Data {
let mut bytes = [0; TOKEN_DEFINITION_DATA_SIZE];
bytes[0] = self.account_type;
bytes[1..7].copy_from_slice(&self.name);
bytes[7..].copy_from_slice(&self.total_supply.to_le_bytes());
bytes
.to_vec()
.try_into()
.expect("23 bytes should fit into Data")
}
fn parse(data: &[u8]) -> Option<Self> {
if data.len() != TOKEN_DEFINITION_DATA_SIZE || data[0] != TOKEN_DEFINITION_TYPE {
None
} else {
let account_type = data[0];
let name = data[1..7].try_into().unwrap();
let total_supply = u128::from_le_bytes(
data[7..]
.try_into()
.expect("Total supply must be 16 bytes little-endian"),
);
Some(Self {
account_type,
name,
total_supply,
})
}
}
}
impl TokenHolding { impl TokenHolding {
fn new(definition_id: &AccountId) -> Self {
Self {
account_type: TOKEN_HOLDING_TYPE,
definition_id: *definition_id,
balance: 0,
}
}
fn parse(data: &[u8]) -> Option<Self> { fn parse(data: &[u8]) -> Option<Self> {
if data.len() != TOKEN_HOLDING_DATA_SIZE || data[0] != TOKEN_HOLDING_TYPE { if data.len() != TOKEN_HOLDING_DATA_SIZE || data[0] != TOKEN_HOLDING_TYPE {
None None
@ -231,6 +188,7 @@ impl TokenHolding {
} }
} }
#[cfg(test)]
fn into_data(self) -> Data { fn into_data(self) -> Data {
let mut bytes = [0; TOKEN_HOLDING_DATA_SIZE]; let mut bytes = [0; TOKEN_HOLDING_DATA_SIZE];
bytes[0] = self.account_type; bytes[0] = self.account_type;
@ -393,9 +351,7 @@ fn compute_pool_pda_seed(
.cmp(definition_token_b_id.value()) .cmp(definition_token_b_id.value())
{ {
std::cmp::Ordering::Less => (definition_token_b_id, definition_token_a_id), std::cmp::Ordering::Less => (definition_token_b_id, definition_token_a_id),
std::cmp::Ordering::Greater => { std::cmp::Ordering::Greater => (definition_token_a_id, definition_token_b_id),
(definition_token_a_id, definition_token_b_id)
}
std::cmp::Ordering::Equal => panic!("Definitions match"), std::cmp::Ordering::Equal => panic!("Definitions match"),
}; };
@ -487,9 +443,9 @@ fn new_definition(
balance_in: &[u128], balance_in: &[u128],
amm_program_id: ProgramId, amm_program_id: ProgramId,
) -> (Vec<AccountPostState>, Vec<ChainedCall>) { ) -> (Vec<AccountPostState>, Vec<ChainedCall>) {
//Pool accounts: pool itself, and its 2 vaults and LP token // Pool accounts: pool itself, and its 2 vaults and LP token
//2 accounts for funding tokens // 2 accounts for funding tokens
//initial funder's LP account // initial funder's LP account
if pre_states.len() != 7 { if pre_states.len() != 7 {
panic!("Invalid number of input accounts") panic!("Invalid number of input accounts")
} }
@ -534,34 +490,20 @@ fn new_definition(
} }
if pool.account_id if pool.account_id
!= compute_pool_pda( != compute_pool_pda(amm_program_id, definition_token_a_id, definition_token_b_id)
amm_program_id,
definition_token_a_id,
definition_token_b_id,
)
{ {
panic!("Pool Definition Account ID does not match PDA"); panic!("Pool Definition Account ID does not match PDA");
} }
if vault_a.account_id if vault_a.account_id
!= compute_vault_pda( != compute_vault_pda(amm_program_id, pool.account_id, definition_token_a_id)
amm_program_id,
pool.account_id,
definition_token_a_id,
)
|| vault_b.account_id || vault_b.account_id
!= compute_vault_pda( != compute_vault_pda(amm_program_id, pool.account_id, definition_token_b_id)
amm_program_id,
pool.account_id,
definition_token_b_id,
)
{ {
panic!("Vault ID does not match PDA"); panic!("Vault ID does not match PDA");
} }
if pool_lp.account_id if pool_lp.account_id != compute_liquidity_token_pda(amm_program_id, pool.account_id) {
!= compute_liquidity_token_pda(amm_program_id, pool.account_id)
{
panic!("Liquidity pool Token Definition Account ID does not match PDA"); panic!("Liquidity pool Token Definition Account ID does not match PDA");
} }
@ -590,7 +532,7 @@ fn new_definition(
liquidity_pool_supply: amount_a, liquidity_pool_supply: amount_a,
reserve_a: amount_a, reserve_a: amount_a,
reserve_b: amount_b, reserve_b: amount_b,
fees: 0u128, //TODO: we assume all fees are 0 for now. fees: 0u128, // TODO: we assume all fees are 0 for now.
active: true, active: true,
}; };
@ -603,7 +545,7 @@ fn new_definition(
let mut chained_calls = Vec::<ChainedCall>::new(); let mut chained_calls = Vec::<ChainedCall>::new();
//Chain call for Token A (user_holding_a -> Vault_A) // Chain call for Token A (user_holding_a -> Vault_A)
let call_token_a = initialize_token_transfer_chained_call( let call_token_a = initialize_token_transfer_chained_call(
TOKEN_PROGRAM_TRANSFER, TOKEN_PROGRAM_TRANSFER,
user_holding_a.clone(), user_holding_a.clone(),
@ -611,7 +553,7 @@ fn new_definition(
amount_a, amount_a,
Vec::<PdaSeed>::new(), Vec::<PdaSeed>::new(),
); );
//Chain call for Token B (user_holding_b -> Vault_B) // Chain call for Token B (user_holding_b -> Vault_B)
let call_token_b = initialize_token_transfer_chained_call( let call_token_b = initialize_token_transfer_chained_call(
TOKEN_PROGRAM_TRANSFER, TOKEN_PROGRAM_TRANSFER,
user_holding_b.clone(), user_holding_b.clone(),
@ -620,7 +562,7 @@ fn new_definition(
Vec::<PdaSeed>::new(), Vec::<PdaSeed>::new(),
); );
//Chain call for liquidity token (TokenLP definition -> User LP Holding) // Chain call for liquidity token (TokenLP definition -> User LP Holding)
let mut instruction_data = [0; 23]; let mut instruction_data = [0; 23];
instruction_data[0] = if pool.account == Account::default() { instruction_data[0] = if pool.account == Account::default() {
TOKEN_PROGRAM_NEW TOKEN_PROGRAM_NEW
@ -770,6 +712,7 @@ fn swap(
(post_states, chained_calls) (post_states, chained_calls)
} }
#[expect(clippy::too_many_arguments, reason = "TODO: Fix later")]
fn swap_logic( fn swap_logic(
user_deposit: AccountWithMetadata, user_deposit: AccountWithMetadata,
vault_deposit: AccountWithMetadata, vault_deposit: AccountWithMetadata,
@ -789,7 +732,7 @@ fn swap_logic(
let withdraw_amount = (reserve_withdraw_vault_amount * deposit_amount) let withdraw_amount = (reserve_withdraw_vault_amount * deposit_amount)
/ (reserve_deposit_vault_amount + deposit_amount); / (reserve_deposit_vault_amount + deposit_amount);
//Slippage check // Slippage check
if min_amount_out > withdraw_amount { if min_amount_out > withdraw_amount {
panic!("Withdraw amount is less than minimal amount out"); panic!("Withdraw amount is less than minimal amount out");
} }
@ -1085,7 +1028,7 @@ fn remove_liquidity(
let mut chained_calls = Vec::new(); let mut chained_calls = Vec::new();
//Chaincall for Token A withdraw // Chaincall for Token A withdraw
let call_token_a = initialize_token_transfer_chained_call( let call_token_a = initialize_token_transfer_chained_call(
TOKEN_PROGRAM_TRANSFER, TOKEN_PROGRAM_TRANSFER,
running_vault_a, running_vault_a,
@ -1096,7 +1039,7 @@ fn remove_liquidity(
pool_def_data.definition_token_a_id, pool_def_data.definition_token_a_id,
)], )],
); );
//Chaincall for Token B withdraw // Chaincall for Token B withdraw
let call_token_b = initialize_token_transfer_chained_call( let call_token_b = initialize_token_transfer_chained_call(
TOKEN_PROGRAM_TRANSFER, TOKEN_PROGRAM_TRANSFER,
running_vault_b, running_vault_b,
@ -1107,7 +1050,7 @@ fn remove_liquidity(
pool_def_data.definition_token_b_id, pool_def_data.definition_token_b_id,
)], )],
); );
//Chaincall for LP adjustment // Chaincall for LP adjustment
let mut pool_definition_lp_auth = pool_definition_lp.clone(); let mut pool_definition_lp_auth = pool_definition_lp.clone();
pool_definition_lp_auth.is_authorized = true; pool_definition_lp_auth.is_authorized = true;
let call_token_lp = initialize_token_transfer_chained_call( let call_token_lp = initialize_token_transfer_chained_call(
@ -1138,22 +1081,38 @@ fn remove_liquidity(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use nssa_core::{ use nssa_core::{
program::ProgramId, account::{Account, AccountId, AccountWithMetadata, Data},
{ program::{ChainedCall, PdaSeed, ProgramId},
account::{Account, AccountId, AccountWithMetadata},
program::ChainedCall,
program::PdaSeed,
},
}; };
use crate::{ use crate::{
PoolDefinition, TokenDefinition, TokenHolding, add_liquidity, compute_liquidity_token_pda, PoolDefinition, TokenHolding, add_liquidity, compute_liquidity_token_pda,
compute_liquidity_token_pda_seed, compute_pool_pda, compute_pool_pda_seed, compute_liquidity_token_pda_seed, compute_pool_pda, compute_vault_pda,
compute_vault_pda, compute_vault_pda_seed, new_definition, remove_liquidity, swap, compute_vault_pda_seed, new_definition, remove_liquidity, swap,
}; };
const TOKEN_PROGRAM_ID: ProgramId = [15; 8]; const TOKEN_PROGRAM_ID: ProgramId = [15; 8];
const AMM_PROGRAM_ID: ProgramId = [42; 8]; const AMM_PROGRAM_ID: ProgramId = [42; 8];
const TOKEN_DEFINITION_DATA_SIZE: usize = 23;
struct TokenDefinition {
account_type: u8,
name: [u8; 6],
total_supply: u128,
}
impl TokenDefinition {
fn into_data(self) -> Data {
let mut bytes = [0; TOKEN_DEFINITION_DATA_SIZE];
bytes[0] = self.account_type;
bytes[1..7].copy_from_slice(&self.name);
bytes[7..].copy_from_slice(&self.total_supply.to_le_bytes());
bytes
.to_vec()
.try_into()
.expect("23 bytes should fit into Data")
}
}
struct BalanceForTests; struct BalanceForTests;
@ -1226,10 +1185,6 @@ mod tests {
200 200
} }
fn add_max_amount_b_high() -> u128 {
20_000
}
fn add_max_amount_a_low() -> u128 { fn add_max_amount_a_low() -> u128 {
10 10
} }
@ -1290,60 +1245,6 @@ mod tests {
struct ChainedCallForTests; struct ChainedCallForTests;
impl ChainedCallForTests { impl ChainedCallForTests {
fn cc_token_a_initialization() -> ChainedCall {
let mut instruction: [u8; 23] = [0; 23];
instruction[0] = 1;
instruction[1..17]
.copy_from_slice(&BalanceForTests::user_token_a_balance().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_uninit(),
],
pda_seeds: Vec::<PdaSeed>::new(),
}
}
fn cc_token_b_initialization() -> ChainedCall {
let mut instruction: [u8; 23] = [0; 23];
instruction[0] = 1;
instruction[1..17]
.copy_from_slice(&BalanceForTests::user_token_b_balance().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_b(),
AccountForTests::vault_b_uninit(),
],
pda_seeds: Vec::<PdaSeed>::new(),
}
}
fn cc_pool_lp_initialization() -> ChainedCall {
let mut instruction: [u8; 23] = [0; 23];
instruction[0] = 1;
instruction[1..17]
.copy_from_slice(&BalanceForTests::user_token_a_balance().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_uninit(),
AccountForTests::user_holding_lp_uninit(),
],
pda_seeds: Vec::<PdaSeed>::new(),
}
}
fn cc_swap_token_a_test_1() -> ChainedCall { fn cc_swap_token_a_test_1() -> ChainedCall {
let mut instruction_data: [u8; 23] = [0; 23]; let mut instruction_data: [u8; 23] = [0; 23];
instruction_data[0] = 1; instruction_data[0] = 1;
@ -1690,40 +1591,6 @@ mod tests {
} }
} }
fn vault_a_uninit() -> AccountWithMetadata {
AccountWithMetadata {
account: Account {
program_owner: TOKEN_PROGRAM_ID,
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
definition_id: IdForTests::token_a_definition_id(),
balance: 0,
}),
nonce: 0,
},
is_authorized: true,
account_id: IdForTests::vault_a_id(),
}
}
fn vault_b_uninit() -> AccountWithMetadata {
AccountWithMetadata {
account: Account {
program_owner: TOKEN_PROGRAM_ID,
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
definition_id: IdForTests::token_b_definition_id(),
balance: 0,
}),
nonce: 0,
},
is_authorized: true,
account_id: IdForTests::vault_b_id(),
}
}
fn vault_a_init() -> AccountWithMetadata { fn vault_a_init() -> AccountWithMetadata {
AccountWithMetadata { AccountWithMetadata {
account: Account { account: Account {
@ -1860,57 +1727,6 @@ mod tests {
} }
} }
fn vault_a_wrong_id() -> AccountWithMetadata {
AccountWithMetadata {
account: Account {
program_owner: TOKEN_PROGRAM_ID,
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
definition_id: IdForTests::token_a_definition_id(),
balance: BalanceForTests::vault_a_reserve_init(),
}),
nonce: 0,
},
is_authorized: true,
account_id: IdForTests::vault_b_id(),
}
}
fn vault_b_wrong_id() -> AccountWithMetadata {
AccountWithMetadata {
account: Account {
program_owner: TOKEN_PROGRAM_ID,
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
definition_id: IdForTests::token_b_definition_id(),
balance: BalanceForTests::vault_b_reserve_init(),
}),
nonce: 0,
},
is_authorized: true,
account_id: IdForTests::vault_a_id(),
}
}
fn pool_lp_uninit() -> AccountWithMetadata {
AccountWithMetadata {
account: Account {
program_owner: TOKEN_PROGRAM_ID,
balance: 0u128,
data: TokenDefinition::into_data(TokenDefinition {
account_type: 0u8,
name: [1; 6],
total_supply: 0u128,
}),
nonce: 0,
},
is_authorized: true,
account_id: IdForTests::token_lp_definition_id(),
}
}
fn pool_lp_init() -> AccountWithMetadata { fn pool_lp_init() -> AccountWithMetadata {
AccountWithMetadata { AccountWithMetadata {
account: Account { account: Account {
@ -2107,30 +1923,6 @@ mod tests {
} }
} }
fn pool_definition_unauth() -> AccountWithMetadata {
AccountWithMetadata {
account: Account {
program_owner: ProgramId::default(),
balance: 0u128,
data: PoolDefinition::into_data(PoolDefinition {
definition_token_a_id: IdForTests::token_a_definition_id(),
definition_token_b_id: IdForTests::token_b_definition_id(),
vault_a_id: IdForTests::vault_a_id(),
vault_b_id: IdForTests::vault_b_id(),
liquidity_pool_id: IdForTests::token_lp_definition_id(),
liquidity_pool_supply: BalanceForTests::vault_a_reserve_init(),
reserve_a: BalanceForTests::vault_a_reserve_init(),
reserve_b: BalanceForTests::vault_b_reserve_init(),
fees: 0u128,
active: true,
}),
nonce: 0,
},
is_authorized: false,
account_id: IdForTests::pool_definition_id(),
}
}
fn pool_definition_swap_test_1() -> AccountWithMetadata { fn pool_definition_swap_test_1() -> AccountWithMetadata {
AccountWithMetadata { AccountWithMetadata {
account: Account { account: Account {
@ -2360,7 +2152,8 @@ mod tests {
#[test] #[test]
fn test_pool_pda_produces_unique_id_for_token_pair() { fn test_pool_pda_produces_unique_id_for_token_pair() {
//compute_pool_pda(amm_program_id: ProgramId, definition_token_a_id: AccountId, definition_token_b_id: AccountId) // compute_pool_pda(amm_program_id: ProgramId, definition_token_a_id: AccountId,
// definition_token_b_id: AccountId)
assert!( assert!(
compute_pool_pda( compute_pool_pda(
AMM_PROGRAM_ID, AMM_PROGRAM_ID,
@ -2407,7 +2200,7 @@ mod tests {
#[should_panic(expected = "Invalid number of input accounts")] #[should_panic(expected = "Invalid number of input accounts")]
#[test] #[test]
fn test_call_new_definition__with_invalid_number_of_accounts_3() { fn test_call_new_definition_with_invalid_number_of_accounts_3() {
let pre_states = vec![ let pre_states = vec![
AccountForTests::pool_definition_init(), AccountForTests::pool_definition_init(),
AccountForTests::vault_a_init(), AccountForTests::vault_a_init(),
@ -2425,7 +2218,7 @@ mod tests {
#[should_panic(expected = "Invalid number of input accounts")] #[should_panic(expected = "Invalid number of input accounts")]
#[test] #[test]
fn test_call_new_definition__with_invalid_number_of_accounts_4() { fn test_call_new_definition_with_invalid_number_of_accounts_4() {
let pre_states = vec![ let pre_states = vec![
AccountForTests::pool_definition_init(), AccountForTests::pool_definition_init(),
AccountForTests::vault_a_init(), AccountForTests::vault_a_init(),
@ -2444,7 +2237,7 @@ mod tests {
#[should_panic(expected = "Invalid number of input accounts")] #[should_panic(expected = "Invalid number of input accounts")]
#[test] #[test]
fn test_call_new_definition__with_invalid_number_of_accounts_5() { fn test_call_new_definition_with_invalid_number_of_accounts_5() {
let pre_states = vec![ let pre_states = vec![
AccountForTests::pool_definition_init(), AccountForTests::pool_definition_init(),
AccountForTests::vault_a_init(), AccountForTests::vault_a_init(),
@ -2877,7 +2670,8 @@ mod tests {
AccountForTests::pool_lp_init(), AccountForTests::pool_lp_init(),
AccountForTests::user_holding_a(), AccountForTests::user_holding_a(),
AccountForTests::user_holding_b(), AccountForTests::user_holding_b(),
AccountForTests::user_holding_a(), //different token account than lp to create desired error AccountForTests::user_holding_a(), /* different token account than lp to create
* desired error */
]; ];
let _post_states = remove_liquidity( let _post_states = remove_liquidity(
&pre_states, &pre_states,