solana_tx_decoding/instruction/raydium/
process_raydium_cpmm_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_central::get_cpmm_fee_amount_from_config_account;
7use solana_sdk::pubkey::Pubkey;
8use solana_sdk::signature::Signature;
9use std::collections::HashMap;
10use std::collections::HashSet;
11
12pub fn process_raydium_cpmm_swap_instruction(
16 instruction: &Instruction,
18 transfers: &[Instruction],
20 running_token_balances: &mut HashMap<u8, u64>,
21 block_time: u64,
22 slot: u64,
23 index: u64,
24 atomic_instruction_index: u8,
25 signers: &HashSet<Pubkey>,
26 signature: &Signature,
27) -> SwapTx {
28 let market_address = instruction.tx_account_keys[instruction.accounts[3] as usize];
29 let input_token_mint = instruction.tx_account_keys[instruction.accounts[10] as usize];
30 let output_token_mint = instruction.tx_account_keys[instruction.accounts[11] as usize];
31 let input_token_vault = instruction.accounts[6];
32 let output_token_vault = instruction.accounts[7];
33
34 let swapped_amount_in = u64::from_le_bytes(transfers[0].data[1..9].try_into().unwrap());
36 if let Some(running_token_balance) = running_token_balances.get_mut(&input_token_vault) {
37 *running_token_balance += swapped_amount_in;
38 }
39
40 let swapped_amount_received = u64::from_le_bytes(transfers[1].data[1..9].try_into().unwrap());
42 if let Some(running_token_balance) = running_token_balances.get_mut(&output_token_vault) {
43 *running_token_balance -= swapped_amount_received;
44 }
45
46 let direction;
47 let token_a_address;
48 let token_b_address;
49 let token_a_vault_address;
50 let token_b_vault_address;
51
52 if input_token_mint < output_token_mint {
55 token_a_address = input_token_mint;
56 token_a_vault_address = input_token_vault;
57 token_b_address = output_token_mint;
58 token_b_vault_address = output_token_vault;
59 direction = SwapDirection::AToB;
60 }
61 else {
63 token_a_address = output_token_mint;
64 token_a_vault_address = output_token_vault;
65 token_b_address = input_token_mint;
66 token_b_vault_address = input_token_vault;
67 direction = SwapDirection::BToA;
68 }
69
70 let fee_fraction_lp = get_cpmm_fee_amount_from_config_account(
73 instruction.tx_account_keys[instruction.accounts[2] as usize],
74 &market_address,
75 );
76
77 let pool_token_a_vault_amount = running_token_balances[&token_a_vault_address];
78 let pool_token_b_vault_amount = running_token_balances[&token_b_vault_address];
79 let price_b_a_lp =
80 LAMPORTS_PER_SOL * pool_token_b_vault_amount as u128 / pool_token_a_vault_amount as u128;
81 let price_a_b_lp =
82 LAMPORTS_PER_SOL * pool_token_a_vault_amount as u128 / pool_token_b_vault_amount as u128;
83
84 SwapTx {
85 pool: Pools::RaydiumCpmm,
86 direction,
87 block_time,
88 slot,
89 index,
90 atomic_instruction_index,
91 fee_fraction_lp,
93 swapped_amount_in,
94 swapped_amount_received,
95 pool_token_a_vault_amount,
96 pool_token_b_vault_amount,
97 price_a_b_lp,
98 price_b_a_lp,
99 token_a_address,
100 token_b_address,
101 market_address,
102 signature: signature.clone(),
103 signers: signers.clone(),
104 }
105}