From 0fdb684122c694f6a34ddeeae94e877645a9aa2c Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Thu, 6 Aug 2026 05:31:33 +0200 Subject: [PATCH] Better code --- src/executor/pump_fun.rs | 140 ++++++++++++++++++++++----------------- 1 file changed, 81 insertions(+), 59 deletions(-) diff --git a/src/executor/pump_fun.rs b/src/executor/pump_fun.rs index fe15774..fe8ccf2 100644 --- a/src/executor/pump_fun.rs +++ b/src/executor/pump_fun.rs @@ -2,76 +2,98 @@ use solana_sdk::{ instruction::{AccountMeta, Instruction}, pubkey::Pubkey, }; -use std::str::FromStr; -pub mod system_program { - use solana_sdk::declare_id; +use spl_associated_token_account::ID as ASSOCIATED_TOKEN_PROGRAM_ID; +use spl_token::ID as TOKEN_PROGRAM_ID; - declare_id!("11111111111111111111111111111111"); +macro_rules! declare_id { + ($name:ident = $l:literal) => { + #[cfg(not(target_arch = "bpf"))] + #[doc = r" The const program ID."] + pub const $name: solana_sdk::pubkey::Pubkey = + solana_sdk::pubkey::Pubkey::from_str_const($l); + #[cfg(target_arch = "bpf")] + #[doc = r" The const program ID."] + pub static $name: solana_sdk::pubkey::Pubkey = + solana_sdk::pubkey::Pubkey::from_str_const($l); + }; } -/// Derives the bonding curve and associated bonding curve tokens for a given mint. -pub fn derive_bonding_curve_pdas(mint: &Pubkey, program_id: &Pubkey) -> (Pubkey, Pubkey) { - let (bonding_curve, _) = - Pubkey::find_program_address(&[b"bonding-curve", mint.as_ref()], program_id); +declare_id!(PUMP_FUN_PROGRAM_ID = "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5AMX787Nz"); +declare_id!(GLOBAL_ACCOUNT = "4wTV1YmiEkRvAtN4S7mJP2bXax2p18e4LK8LCHWwEQ2F"); +declare_id!(FEE_RECIPIENT = "CebN5WG3QfR6EPEDZgbu6wN6sfg92v7S759DcGTR8b61"); +declare_id!(EVENT_AUTHORITY = "Ce6TQqeHC9p8KBAayQr27Pyy6wJaCdE7wXw8msu3vA8Q"); +declare_id!(SYS_PROGRAM_ID = "11111111111111111111111111111111"); - let (associated_bonding_curve, _) = Pubkey::find_program_address( - &[ - bonding_curve.as_ref(), - spl_token::ID.as_ref(), - mint.as_ref(), - ], - &spl_associated_token_account::ID, - ); +const BUY_DISCRIMINATOR: [u8; 8] = [102, 139, 25, 211, 85, 210, 149, 228]; - (bonding_curve, associated_bonding_curve) -} +pub struct PumpFun; -/// Constructs a raw pump.fun buy instruction -pub fn create_pump_buy_instruction( - payer: Pubkey, - mint: Pubkey, - ata_token_account: Pubkey, // User's associated token account for this mint - token_amount: u64, // Amount of tokens to purchase - max_sol_cost: u64, // Max lamports to spend (Slippage protection) -) -> Instruction { - let program_id = Pubkey::from_str("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5AMX787Nz").unwrap(); +impl PumpFun { + pub fn bonding_curve(mint: &Pubkey) -> (Pubkey, Pubkey) { + let (curve, _) = + Pubkey::find_program_address(&[b"bonding-curve", mint.as_ref()], &PUMP_FUN_PROGRAM_ID); - // Constant global state accounts used by pump.fun - let global_account = Pubkey::from_str("4wTV1YmiEkRvAtN4S7mJP2bXax2p18e4LK8LCHWwEQ2F").unwrap(); - let fee_recipient = Pubkey::from_str("CebN5WG3QfR6EPEDZgbu6wN6sfg92v7S759DcGTR8b61").unwrap(); + let (curve_ata, _) = Pubkey::find_program_address( + &[curve.as_ref(), TOKEN_PROGRAM_ID.as_ref(), mint.as_ref()], + &ASSOCIATED_TOKEN_PROGRAM_ID, + ); - // Derive the PDAs for the bonding curves - let (bonding_curve, associated_bonding_curve) = derive_bonding_curve_pdas(&mint, &program_id); + (curve, curve_ata) + } - // 1. Build the data payload (Discriminator + Args) - // Anchor discriminator for 'buy': [102, 139, 25, 211, 85, 210, 149, 228] - let mut instruction_data = vec![102, 139, 25, 211, 85, 210, 149, 228]; - instruction_data.extend_from_slice(&token_amount.to_le_bytes()); - instruction_data.extend_from_slice(&max_sol_cost.to_le_bytes()); + pub fn buy( + payer: Pubkey, + mint: Pubkey, + user_token_account: Pubkey, + amount: u64, + max_sol_cost: u64, + ) -> Instruction { + let (bonding_curve, bonding_curve_token) = Self::bonding_curve(&mint); - // 2. Map required accounts in correct order - let accounts = vec![ - AccountMeta::new_readonly(global_account, false), - AccountMeta::new(fee_recipient, false), - AccountMeta::new_readonly(mint, false), - AccountMeta::new(bonding_curve, false), - AccountMeta::new(associated_bonding_curve, false), - AccountMeta::new(ata_token_account, false), - AccountMeta::new(payer, true), // Signer - AccountMeta::new_readonly(system_program::ID, false), - AccountMeta::new_readonly(spl_token::ID, false), - AccountMeta::new_readonly(solana_program::sysvar::rent::ID, false), - AccountMeta::new_readonly( - Pubkey::from_str("Ce6TQqeHC9p8KBAayQr27Pyy6wJaCdE7wXw8msu3vA8Q").unwrap(), - false, - ), // Event Authority - AccountMeta::new_readonly(program_id, false), - ]; + Instruction { + program_id: PUMP_FUN_PROGRAM_ID, + accounts: Self::buy_accounts( + payer, + mint, + user_token_account, + bonding_curve, + bonding_curve_token, + ), + data: Self::buy_data(amount, max_sol_cost), + } + } - Instruction { - program_id, - accounts, - data: instruction_data, + fn buy_data(token_amount: u64, max_sol_cost: u64) -> Vec { + let mut data = Vec::with_capacity(24); + + data.extend_from_slice(&BUY_DISCRIMINATOR); + data.extend_from_slice(&token_amount.to_le_bytes()); + data.extend_from_slice(&max_sol_cost.to_le_bytes()); + + data + } + + fn buy_accounts( + payer: Pubkey, + mint: Pubkey, + user_token_account: Pubkey, + bonding_curve: Pubkey, + bonding_curve_token: Pubkey, + ) -> Vec { + vec![ + AccountMeta::new_readonly(GLOBAL_ACCOUNT, false), + AccountMeta::new(FEE_RECIPIENT, false), + AccountMeta::new_readonly(mint, false), + AccountMeta::new(bonding_curve, false), + AccountMeta::new(bonding_curve_token, false), + AccountMeta::new(user_token_account, false), + AccountMeta::new(payer, true), + AccountMeta::new_readonly(SYS_PROGRAM_ID, false), + AccountMeta::new_readonly(TOKEN_PROGRAM_ID, false), + AccountMeta::new_readonly(solana_sdk::sysvar::rent::ID, false), + AccountMeta::new_readonly(EVENT_AUTHORITY, false), + AccountMeta::new_readonly(PUMP_FUN_PROGRAM_ID, false), + ] } }