Skip to content

Instantly share code, notes, and snippets.

@allenhark
Created April 7, 2026 11:54
Show Gist options
  • Select an option

  • Save allenhark/9937f3a546a6114f7903cdadfab1c410 to your computer and use it in GitHub Desktop.

Select an option

Save allenhark/9937f3a546a6114f7903cdadfab1c410 to your computer and use it in GitHub Desktop.
Pumpfun 6024 error fix example
// test_pumpfun.rs - Integration test: buy a PumpFun token, verify balance, then sell
// Usage: cargo run --bin test_pumpfun -- --token <MINT> [--amount <SOL>]
use anyhow::{bail, Context, Result};
use colored::*;
use dotenv::dotenv;
use solana_sdk::{pubkey::Pubkey, signature::Signer};
use std::str::FromStr;
use sniperbot::platform::{self, get_platform, PlatformData, PlatformId, TokenCreateEvent};
use sniperbot::rpc_helpers::*;
#[tokio::main]
async fn main() -> Result<()> {
dotenv().ok();
let (keypair_path, rpc_url) = load_config()?;
let args: Vec<String> = std::env::args().collect();
let mut token_address: Option<String> = None;
let mut sol_amount: f64 = 0.001;
let mut i = 1;
while i < args.len() {
match args[i].as_str() {
"--token" | "-t" => { token_address = Some(args[i + 1].clone()); i += 2; }
"--amount" | "-a" => { sol_amount = args[i + 1].parse()?; i += 2; }
"--help" | "-h" => {
println!("Usage: cargo run --bin test_pumpfun -- --token <MINT> [--amount <SOL>]");
return Ok(());
}
_ => {
if token_address.is_none() && !args[i].starts_with("--") {
token_address = Some(args[i].clone());
}
i += 1;
}
}
}
let mint_str = token_address.ok_or_else(|| anyhow::anyhow!("Token address required"))?;
let mint = Pubkey::from_str(&mint_str).context("Invalid mint address")?;
let payer = load_keypair(&keypair_path)?;
let sol_lamports = (sol_amount * LAMPORTS_PER_SOL as f64) as u64;
println!("{}", "═══════════════════════════════════════".cyan());
println!("{}", " PumpFun Buy + Sell Test".cyan().bold());
println!("{}", "═══════════════════════════════════════".cyan());
println!(" Payer: {}", payer.pubkey());
println!(" Token: {}", mint);
println!(" Amount: {} SOL ({} lamports)", sol_amount, sol_lamports);
println!();
// Detect token program
let token_program = detect_token_program(&mint, &rpc_url).await?;
let platform_impl = get_platform(PlatformId::PumpFun);
let user_ata = platform_impl.user_token_account(&payer.pubkey(), &mint, &token_program);
// Build PlatformData from on-chain bonding curve
let bonding_curve = platform::pumpfun::derive_bonding_curve(&mint);
let bc_data = get_account_info(&bonding_curve, &rpc_url)
.await
.context("Bonding curve not found — token may have migrated")?;
if bc_data.len() < 81 {
bail!("Bonding curve data too short");
}
let creator_bytes: [u8; 32] = bc_data[49..81].try_into().unwrap();
let creator = Pubkey::new_from_array(creator_bytes);
let cashback_enabled = bc_data.len() > 82 && bc_data[82] != 0;
let platform_data = PlatformData::PumpFun {
is_create_v2: false,
token_program,
bonding_curve,
associated_bonding_curve: platform::pumpfun::get_associated_token_address(
&bonding_curve, &mint, &token_program,
),
creator_vault: platform::pumpfun::derive_creator_vault(&creator),
fee_recipient: *platform::pumpfun::FEE_RECIPIENT,
fee_config: platform::pumpfun::get_fee_config(),
global_volume_accumulator: Pubkey::default(),
user_volume_accumulator: platform::pumpfun::derive_user_volume_accumulator(&payer.pubkey()),
bonding_curve_v2: platform::pumpfun::derive_bonding_curve_v2(&mint),
cashback_enabled,
};
// Check initial balance
let initial_balance = get_token_account_balance(&user_ata, &rpc_url).await.unwrap_or(0);
println!("{}", format!("Initial token balance: {}", initial_balance).dimmed());
// ── BUY ──
println!();
println!("{}", "▸ BUYING...".green().bold());
// Build synthetic TokenCreateEvent for buy instruction
let event = TokenCreateEvent {
platform: PlatformId::PumpFun,
slot: 0,
signature: [0u8; 64],
processed_at_ns: 0,
mint,
creator,
name: None,
symbol: None,
uri: None,
pool: bonding_curve,
initial_buy: None,
create_accounts: vec![],
platform_data: platform_data.clone(),
};
// PumpFun buy uses SOL directly (no WSOL wrapping needed)
let buy_ix = platform_impl.build_buy_instruction(
&payer.pubkey(),
&event,
sol_lamports,
1, // min_tokens = 1 (accept any)
)?;
let buy_sig = send_and_confirm(&payer, vec![buy_ix], &rpc_url).await?;
println!("{}", format!(" Buy signature: {}", buy_sig).green());
println!("{}", format!(" https://solscan.io/tx/{}", buy_sig).dimmed());
// Wait and verify purchase
println!("{}", " Waiting for confirmation...".yellow());
tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
let post_buy_balance = get_token_account_balance(&user_ata, &rpc_url).await?;
let tokens_bought = post_buy_balance.saturating_sub(initial_balance);
if tokens_bought == 0 {
bail!("❌ Buy failed — no tokens received");
}
println!(
"{}",
format!(
" ✅ Bought {} tokens ({:.6})",
tokens_bought,
tokens_bought as f64 / 1e6
)
.green()
);
// ── SELL ──
println!();
println!("{}", "▸ SELLING...".red().bold());
let sell_ix = platform_impl.build_sell_instruction(
&payer.pubkey(),
&platform_data,
&mint,
&user_ata,
post_buy_balance, // sell entire balance
1,
)?;
let sell_sig = send_and_confirm(&payer, vec![sell_ix], &rpc_url).await?;
println!("{}", format!(" Sell signature: {}", sell_sig).green());
println!("{}", format!(" https://solscan.io/tx/{}", sell_sig).dimmed());
// Verify sell
println!("{}", " Waiting for confirmation...".yellow());
tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
let final_balance = get_token_account_balance(&user_ata, &rpc_url).await.unwrap_or(0);
if final_balance == 0 {
println!("{}", " ✅ All tokens sold!".green());
} else {
println!(
"{}",
format!(" ⚠️ Remaining: {} tokens", final_balance).yellow()
);
}
println!();
println!("{}", "═══════════════════════════════════════".cyan());
println!("{}", " Test Complete".cyan().bold());
println!("{}", "═══════════════════════════════════════".cyan());
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment