solana_tx_decoding/instruction/raydium/
process_raydium_launchpad_swap_instruction.rs

1use borsh::BorshDeserialize;
2use solana_central::Instruction;
3use solana_central::Pools;
4use solana_central::SwapDirection;
5use solana_central::SwapTx;
6use solana_central::constants::LAMPORTS_PER_SOL;
7use solana_central::protocol_idls::raydium::LaunchpadTradeEventIdl;
8use solana_sdk::pubkey::Pubkey;
9use solana_sdk::signature::Signature;
10use std::collections::HashSet;
11
12/// Process a Raydium launchpad swap instruction and create a SwapTx. Assumes the instruction has
13/// been validated as a valid Raydium launchpad swap. Requires both the swap instruction and its
14/// corresponding event instruction because the platform config cannot be derived from the event
15/// data alone.
16pub fn process_raydium_launchpad_swap_instruction(
17  instruction: &Instruction,
18  event: &Instruction,
19  direction: SwapDirection,
20  block_time: u64,
21  slot: u64,
22  index: u64,
23  atomic_instruction_index: u8,
24  signers: &HashSet<Pubkey>,
25  signature: &Signature,
26) -> SwapTx {
27  let token_a_address = instruction.tx_account_keys[instruction.accounts[9] as usize];
28  let token_b_address = instruction.tx_account_keys[instruction.accounts[10] as usize];
29  let market_address = instruction.tx_account_keys[instruction.accounts[4] as usize];
30  let swap_event = LaunchpadTradeEventIdl::try_from_slice(&event.data).unwrap();
31
32  let swapped_amount_in = swap_event.amount_in;
33  let swapped_amount_received = swap_event.amount_out;
34  let total_swap_fee = (swap_event.protocol_fee
35    + swap_event.platform_fee
36    + swap_event.share_fee
37    + swap_event.creator_fee) as u128;
38  let fee_fraction_lp;
39
40  // If sell, charged on way out, if buy, charged on way in
41  if direction == SwapDirection::AToB {
42    fee_fraction_lp = (total_swap_fee * LAMPORTS_PER_SOL
43      / (swapped_amount_received as u128 + total_swap_fee)) as u64;
44  } else {
45    fee_fraction_lp = (total_swap_fee * LAMPORTS_PER_SOL / swapped_amount_in as u128) as u64;
46  }
47
48  let pool_token_a_vault_amount = swap_event.virtual_base - swap_event.real_base_after;
49  let pool_token_b_vault_amount = swap_event.virtual_quote + swap_event.real_quote_after;
50
51  let price_a_b_lp =
52    pool_token_a_vault_amount as u128 * LAMPORTS_PER_SOL / pool_token_b_vault_amount as u128;
53  let price_b_a_lp =
54    pool_token_b_vault_amount as u128 * LAMPORTS_PER_SOL / pool_token_a_vault_amount as u128;
55
56  SwapTx {
57    pool: Pools::RaydiumLaunchpad,
58    direction,
59    block_time,
60    slot,
61    index,
62    atomic_instruction_index,
63    fee_fraction_lp,
64    swapped_amount_in,
65    swapped_amount_received,
66    pool_token_a_vault_amount,
67    pool_token_b_vault_amount,
68    price_a_b_lp,
69    price_b_a_lp,
70    token_a_address,
71    token_b_address,
72    market_address,
73    signature: signature.clone(),
74    signers: signers.clone(),
75  }
76}