solana_tx_decoding/instruction/raydium/
process_raydium_ammv4_swap_instruction.rs1use solana_central::Instruction;
2use solana_central::Pools;
3use solana_central::SwapDirection;
4use solana_central::SwapTx;
5use solana_central::constants::LAMPORTS_PER_SOL;
6use solana_sdk::pubkey::Pubkey;
7use solana_sdk::signature::Signature;
8use std::collections::HashMap;
9use std::collections::HashSet;
10
11pub fn process_raydium_ammv4_swap_instruction(
15 instruction: &Instruction,
17 transfers: &[Instruction],
20 ta_mint: &HashMap<u8, Pubkey>,
21 running_token_balances: &mut HashMap<u8, u64>,
22 block_time: u64,
23 slot: u64,
24 index: u64,
25 atomic_instruction_index: u8,
26 signers: &HashSet<Pubkey>,
27 signature: &Signature,
28) -> SwapTx {
29 let market_address = instruction.tx_account_keys[instruction.accounts[1] as usize];
30
31 let token_a_vault_address;
33 let token_b_vault_address;
34 if instruction.accounts.len() == 17 {
35 token_a_vault_address = instruction.accounts[4];
36 token_b_vault_address = instruction.accounts[5];
37 } else if instruction.accounts.len() == 18 {
38 token_a_vault_address = instruction.accounts[5];
39 token_b_vault_address = instruction.accounts[6];
40 } else {
41 panic!(
42 "process_raydium_ammv4_swap_instruction: Invalid number of accounts in swap instruction, signature: {}",
43 signature
44 );
45 }
46 let token_a_address = *ta_mint.get(&token_a_vault_address).expect(format!("process_raydium_ammv4_swap_instruction: Token a vault address not found in ta_mint, signature: {}", signature).as_str());
48 let token_b_address = *ta_mint.get(&token_b_vault_address).expect(format!("process_raydium_ammv4_swap_instruction: Token b vault address not found in ta_mint, signature: {}", signature).as_str());
49
50 let swapped_amount_in = u64::from_le_bytes(transfers[0].data[1..9].try_into().unwrap());
58 let swapped_amount_received = u64::from_le_bytes(transfers[1].data[1..9].try_into().unwrap());
59
60 let direction: SwapDirection;
65 if transfers[0].accounts[1] == token_a_vault_address {
66 direction = SwapDirection::AToB;
67 if let Some(running_token_balance) = running_token_balances.get_mut(&token_a_vault_address) {
68 *running_token_balance += swapped_amount_in;
69 }
70 if let Some(running_token_balance) = running_token_balances.get_mut(&token_b_vault_address) {
71 *running_token_balance -= swapped_amount_received;
72 }
73 } else {
74 direction = SwapDirection::BToA;
75 if let Some(running_token_balance) = running_token_balances.get_mut(&token_b_vault_address) {
76 *running_token_balance += swapped_amount_in;
77 }
78 if let Some(running_token_balance) = running_token_balances.get_mut(&token_a_vault_address) {
79 *running_token_balance -= swapped_amount_received;
80 }
81 };
82
83 let pool_token_a_vault_amount: u64 = running_token_balances[&token_a_vault_address];
84 let pool_token_b_vault_amount: u64 = running_token_balances[&token_b_vault_address];
85 let price_b_a_lp =
86 LAMPORTS_PER_SOL * pool_token_b_vault_amount as u128 / pool_token_a_vault_amount as u128;
87 let price_a_b_lp =
88 LAMPORTS_PER_SOL * pool_token_a_vault_amount as u128 / pool_token_b_vault_amount as u128;
89
90 SwapTx {
91 pool: Pools::RaydiumAmmV4,
92 direction,
93 block_time,
94 slot,
95 index,
96 atomic_instruction_index,
97 fee_fraction_lp: 2500000,
99 swapped_amount_in,
100 swapped_amount_received,
101 pool_token_a_vault_amount,
102 pool_token_b_vault_amount,
103 price_a_b_lp,
104 price_b_a_lp,
105 token_a_address,
106 token_b_address,
107 market_address,
108 signature: signature.clone(),
109 signers: signers.clone(),
110 }
111}