solana_exec/pumpswap/
push_pumpswap_swap_instruction.rs1use crate::constants::COMPUTE_UNITS;
2use crate::types::swap_config::SwapConfig;
3use crate::utilities::get_min_amount_out::get_min_amount_out;
4use solana_central::PoolTrait;
5use solana_central::PumpswapPool;
6use solana_central::SwapDirection;
7use solana_central::constants::{PUMP_CONSTANTS, SOLANA_PROGRAMS};
8use solana_sdk::instruction::{AccountMeta, Instruction};
9use solana_sdk::pubkey::Pubkey;
10use spl_associated_token_account::get_associated_token_address;
11
12pub fn push_pumpswap_swap_instruction(
15 swap_config: &SwapConfig,
16 use_manual_instruction_args: bool,
18 mut index_zero_arg: u64,
19 mut index_one_arg: u64,
20 instructions: &mut Vec<Instruction>,
21 compute_unit_budget: &mut u32,
22 pool: &PumpswapPool,
23) {
24 if swap_config.slippage_lp == u64::MAX && swap_config.direction == SwapDirection::BToA {
25 println!(
26 "pumpswap_innerinstructions: Infinite slippage is not allowed for pumpfun buy \
27 direction swaps (B to A, quote to base) because it authorizes the protocol to take all of the \
28 base tokens available in the wallet. Base token address: {}",
29 pool.token_a_address()
30 );
31 }
32 let mut data: Vec<u8> = Vec::with_capacity(25);
39
40 if !use_manual_instruction_args {
50 if swap_config.direction == SwapDirection::AToB {
51 let a_amount_in = swap_config.amount_in;
52 let min_b_amount_out = get_min_amount_out(swap_config, pool);
53 index_zero_arg = a_amount_in;
54 index_one_arg = min_b_amount_out;
55 data.extend_from_slice(&PUMP_CONSTANTS.sell_instruction_discriminator);
56 } else {
57 index_zero_arg = swap_config.amount_in;
58 index_one_arg = get_min_amount_out(swap_config, pool);
59 data.extend_from_slice(&PUMP_CONSTANTS.pumpswap_buy_exact_quote_in_instruction_discriminator);
60 }
61 }
62 data.extend_from_slice(&index_zero_arg.to_le_bytes());
63 data.extend_from_slice(&index_one_arg.to_le_bytes());
64 if swap_config.direction == SwapDirection::BToA {
66 data.push(1);
67 }
68
69 let mut accounts: Vec<AccountMeta> = vec![
87 AccountMeta::new(pool.info.pool_address, false),
88 AccountMeta::new(swap_config.wallet, true),
89 AccountMeta::new_readonly(PUMP_CONSTANTS.pump_swap_global_config, false),
90 AccountMeta::new_readonly(pool.info.token_a_address, false),
91 AccountMeta::new_readonly(pool.info.token_b_address, false),
92 AccountMeta::new(
93 get_associated_token_address(&swap_config.wallet, &pool.info.token_a_address),
94 false,
95 ),
96 AccountMeta::new(
97 get_associated_token_address(&swap_config.wallet, &pool.info.token_b_address),
98 false,
99 ),
100 AccountMeta::new(pool.info.token_a_vault_address, false),
101 AccountMeta::new(pool.info.token_b_vault_address, false),
102 AccountMeta::new_readonly(pool.fee_vault, false),
103 AccountMeta::new(pool.fee_vault_token_account, false),
104 AccountMeta::new_readonly(SOLANA_PROGRAMS.token_program, false),
105 AccountMeta::new_readonly(SOLANA_PROGRAMS.token_program, false),
106 AccountMeta::new_readonly(SOLANA_PROGRAMS.system_program, false),
107 AccountMeta::new_readonly(SOLANA_PROGRAMS.associated_token_program, false),
108 AccountMeta::new_readonly(PUMP_CONSTANTS.pump_swap_event_authority, false),
109 AccountMeta::new_readonly(PUMP_CONSTANTS.pump_swap_program, false),
110 AccountMeta::new(pool.coin_creator_vault_authority_token_account, false),
111 AccountMeta::new_readonly(pool.coin_creator_vault_authority, false),
112 ];
113
114 if swap_config.direction == SwapDirection::BToA {
116 accounts.push(AccountMeta::new(
117 PUMP_CONSTANTS.pumpswap_global_volume_accumulator,
118 false,
119 ));
120 let user_volume_accumulator = Pubkey::find_program_address(
122 &[b"user_volume_accumulator", swap_config.wallet.as_ref()],
123 &PUMP_CONSTANTS.pump_swap_program,
124 )
125 .0;
126 accounts.push(AccountMeta::new(user_volume_accumulator, false));
127 }
128
129 accounts.push(AccountMeta::new_readonly(
131 PUMP_CONSTANTS.pumpswap_fee_config,
132 false,
133 ));
134 accounts.push(AccountMeta::new_readonly(PUMP_CONSTANTS.fee_program, false));
135
136 instructions.push(Instruction {
137 program_id: PUMP_CONSTANTS.pump_swap_program,
138 accounts,
139 data,
140 });
141 *compute_unit_budget += COMPUTE_UNITS.pumpswap_swap;
142}