shank_parse::shank_parse!("../idl/vault.json");
#[cfg(test)]
mod tests {
use super::vault::accounts::*;
use super::vault::events::*;
use super::vault::instructions::*;
use super::vault::ID;
use shank_parse::__private::{base64_encode, Pubkey};
#[test]
fn test_program_id() {
assert_eq!(ID.to_string(), "9pq4Z25ahsUMFZ9TrKH1yhmibLbGkxxAdbTn7FUJ7reV");
}
#[test]
fn test_vault_from_account_data() {
let owner = [1u8; 32];
let vault_id = [2u8; 32];
let token_mint_a = [3u8; 32];
let token_mint_b = [4u8; 32];
let token_account_a = [5u8; 32];
let token_account_b = [6u8; 32];
let token_program_a = [7u8; 32];
let token_program_b = [8u8; 32];
let reserve_a: u64 = 1000;
let reserve_b: u64 = 2000;
let k: u128 = 2_000_000;
let bump: u8 = 255;
let mut data = Vec::new();
data.extend_from_slice(&owner);
data.extend_from_slice(&vault_id);
data.extend_from_slice(&token_mint_a);
data.extend_from_slice(&token_mint_b);
data.extend_from_slice(&token_account_a);
data.extend_from_slice(&token_account_b);
data.extend_from_slice(&token_program_a);
data.extend_from_slice(&token_program_b);
data.extend_from_slice(&reserve_a.to_le_bytes());
data.extend_from_slice(&reserve_b.to_le_bytes());
data.extend_from_slice(&k.to_le_bytes());
data.push(bump);
let vault = Vault::from_account_data(&data).unwrap();
assert_eq!(vault.owner, owner);
assert_eq!(vault.vault_id, vault_id);
assert_eq!(vault.token_mint_a, token_mint_a);
assert_eq!(vault.reserve_a, reserve_a);
assert_eq!(vault.reserve_b, reserve_b);
assert_eq!(vault.k, k);
assert_eq!(vault.bump, bump);
}
#[test]
fn test_create_vault_instruction() {
let program_id = Pubkey::new_from_array([1u8; 32]);
let accounts = CreateVaultAccounts {
owner: Pubkey::new_from_array([2u8; 32]),
vault: Pubkey::new_from_array([3u8; 32]),
user_token_account_a: Pubkey::new_from_array([4u8; 32]),
user_token_account_b: Pubkey::new_from_array([5u8; 32]),
vault_token_account_a: Pubkey::new_from_array([6u8; 32]),
vault_token_account_b: Pubkey::new_from_array([7u8; 32]),
token_program_a: Pubkey::new_from_array([8u8; 32]),
token_program_b: Pubkey::new_from_array([9u8; 32]),
system_program: Pubkey::new_from_array([10u8; 32]),
};
let args = CreateVaultArgs {
vault_id: [11u8; 32],
token_mint_a: [12u8; 32],
token_mint_b: [13u8; 32],
amount_a: 500,
amount_b: 1000,
};
let ix = create_vault(&program_id, &accounts, &args);
assert_eq!(ix.program_id, program_id);
assert_eq!(ix.accounts.len(), 9);
assert_eq!(ix.data[0], 0); assert!(ix.accounts[0].is_signer); assert!(ix.accounts[1].is_writable); }
#[test]
fn test_swap_exact_in_instruction() {
let program_id = Pubkey::new_from_array([1u8; 32]);
let accounts = SwapExactInAccounts {
user: Pubkey::new_from_array([2u8; 32]),
vault: Pubkey::new_from_array([3u8; 32]),
user_token_in: Pubkey::new_from_array([4u8; 32]),
vault_token_in: Pubkey::new_from_array([5u8; 32]),
user_token_out: Pubkey::new_from_array([6u8; 32]),
vault_token_out: Pubkey::new_from_array([7u8; 32]),
token_program_in: Pubkey::new_from_array([8u8; 32]),
token_program_out: Pubkey::new_from_array([9u8; 32]),
};
let args = SwapExactInArgs {
amount_in: 100,
min_amount_out: 90,
};
let ix = swap_exact_in(&program_id, &accounts, &args);
assert_eq!(ix.data[0], 1); assert_eq!(ix.accounts.len(), 8);
assert_eq!(
u64::from_le_bytes(ix.data[1..9].try_into().expect("slice")),
100
);
assert_eq!(
u64::from_le_bytes(ix.data[9..17].try_into().expect("slice")),
90
);
}
#[test]
fn test_swap_exact_out_instruction() {
let program_id = Pubkey::new_from_array([1u8; 32]);
let accounts = SwapExactOutAccounts {
user: Pubkey::new_from_array([2u8; 32]),
vault: Pubkey::new_from_array([3u8; 32]),
user_token_in: Pubkey::new_from_array([4u8; 32]),
vault_token_in: Pubkey::new_from_array([5u8; 32]),
user_token_out: Pubkey::new_from_array([6u8; 32]),
vault_token_out: Pubkey::new_from_array([7u8; 32]),
token_program_in: Pubkey::new_from_array([8u8; 32]),
token_program_out: Pubkey::new_from_array([9u8; 32]),
};
let args = SwapExactOutArgs {
amount_out: 200,
max_amount_in: 250,
};
let ix = swap_exact_out(&program_id, &accounts, &args);
assert_eq!(ix.data[0], 2); }
#[test]
fn test_vault_created_from_logs() {
let vault_addr = [42u8; 32];
let owner_addr = [43u8; 32];
let mut event_data = vec![0u8]; event_data.extend_from_slice(&vault_addr);
event_data.extend_from_slice(&owner_addr);
event_data.extend_from_slice(&1000u64.to_le_bytes());
event_data.extend_from_slice(&2000u64.to_le_bytes());
event_data.extend_from_slice(&2_000_000u128.to_le_bytes());
let log = format!("Program data: {}", base64_encode(&event_data));
let events = VaultCreated::from_logs(&[log.as_str()]);
assert_eq!(events.len(), 1);
assert_eq!(events[0].vault, vault_addr);
assert_eq!(events[0].owner, owner_addr);
assert_eq!(events[0].reserve_a, 1000);
assert_eq!(events[0].k, 2_000_000);
}
#[test]
fn test_vault_event_enum_from_logs() {
let mut data0 = vec![0u8];
data0.extend_from_slice(&[1u8; 32]); data0.extend_from_slice(&[2u8; 32]); data0.extend_from_slice(&100u64.to_le_bytes());
data0.extend_from_slice(&200u64.to_le_bytes());
data0.extend_from_slice(&20000u128.to_le_bytes());
let log0 = format!("Program data: {}", base64_encode(&data0));
let mut data1 = vec![1u8];
data1.extend_from_slice(&[3u8; 32]); data1.extend_from_slice(&50u64.to_le_bytes());
data1.extend_from_slice(&45u64.to_le_bytes());
data1.extend_from_slice(&150u64.to_le_bytes());
data1.extend_from_slice(&155u64.to_le_bytes());
let log1 = format!("Program data: {}", base64_encode(&data1));
let events = VaultEvent::from_logs(&[log0.as_str(), log1.as_str()]);
assert_eq!(events.len(), 2);
match &events[0] {
VaultEvent::VaultCreated(e) => assert_eq!(e.reserve_a, 100),
_ => panic!("expected VaultCreated"),
}
match &events[1] {
VaultEvent::SwapExactInExecuted(e) => {
assert_eq!(e.amount_in, 50);
assert_eq!(e.amount_out, 45);
}
_ => panic!("expected SwapExactInExecuted"),
}
}
}