debpf
pump.fun / instructions

Instruction

buy_exact_sol_in

Decompiled

Spends an exact amount of SOL (spendable_sol_in) on a pump.fun bonding curve and gives the buyer whatever tokens that buys, as long as it is at least min_tokens_out. Anyone can call it. Fees come out of the amount spent: 95 bps protocol fee and 30 bps creator fee, each rounded up. Net = floor(spend·10000/10125), trimmed so the total never goes over spend. Half of the protocol fee goes to a buyback recipient (none on mayhem-mode curves), the creator fee goes to the creator vault (or back as cashback on cashback curves), and the wallet stored in Global as the whitelist key pays no fees. Fails if the curve is complete (6005), min_tokens_out = 0 (6020), spend = 0 (6041), output below min_tokens_out (6042), or not enough tokens left (6021) unless the optional partial-fill byte is set; in that case the buy is capped, and it fails with 6002 if the capped cost is above spend.

Discriminator
0x38fc74089edfcd5f
Calls in the sample
13
Reproduced, seen by the agent
0 / 8
Reproduced, never shown to the agent
0 / 5

0 of 13 real mainnet calls reproduced exactly. Every SOL and token movement the model predicted matched the chain to the last unit. Unseen calls were never shown to the agent.

Bytecodefn_24931
24931mov64 r6, r5
24932mov64 r9, r4
24933mov64 r8, r3
24934mov64 r7, r2
24935stxdw [r10-2160], r1
24936lddw r1, 0x1ae487 ; "Instruction: BuyExactSolIn"
24938mov64 r2, 0x1a
24939call sol_log_
2493aldxdw r1, [r6-4088]
2493bjlt r1, 0x8, +35 ; -> 2495f
2493cmov64 r2, r1
2493dand64 r2, -0x8
2493ejeq r2, 0x8, +32 ; -> 2495f
2493fldxdw r2, [r6-4096]
24940ldxdw r3, [r2+0]
24941ldxdw r4, [r2+8]
24942jne r1, 0x10, +51 ; -> 24976
24943mov64 r6, 0x0
24944mov64 r5, 0x0
24945stxdw [r10-2184], r5
24946stxdw [r10-2176], r4
24947stxdw [r10-2168], r3
24948mov64 r1, -0x1
24949stxw [r10-2101], r1
2494astxw [r10-2104], r1
2494bstxdw [r10-8], r9
2494cstxdw [r10-16], r8
2494dmov64 r1, r10
2494eadd64 r1, -0x838
2494fstxdw [r10-4088], r1
24950mov64 r1, r10
24951add64 r1, -0x420
24952mov64 r3, r10
24953add64 r3, -0x10
24954mov64 r5, r10
24955mov64 r2, r7
24956call fn_2cd81
24957ldxdw r8, [r10-1056]
24958lddw r1, 0x8000000000000000
2495ajeq r8, r1, +1 ; -> 2495c
2495bja +36 ; -> 24980
2495cldxdw r2, [r10-1040]
2495dldxdw r1, [r10-1048]
2495eja +19 ; -> 24972
2495flddw r1, 0x1b3c60
24961call fn_33e71
24962mov64 r1, r0
24963and64 r1, 0x3
24964mov64 r2, r1
24965add64 r2, -0x2
24966jlt r2, 0x2, +5 ; -> 2496c
24967jeq r1, 0x0, +4 ; -> 2496c
24968ldxdw r1, [r0-1]
24969ldxdw r2, [r0+7]
2496aldxdw r2, [r2+0]
2496bcallx r2
2496cmov64 r1, r10
2496dadd64 r1, -0x868
2496emov64 r2, 0x66
2496fcall fn_32b09
24970ldxdw r2, [r10-2144]
24971ldxdw r1, [r10-2152]
24972ldxdw r3, [r10-2160]
24973stxdw [r3+8], r2
24974stxdw [r3+0], r1
24975exit
24976ldxb r6, [r2+16]
24977jlt r6, 0x2, +1 ; -> 24979
24978ja +87 ; -> 249d0
24979mov64 r5, 0x0
2497ajeq r1, 0x11, -54 ; -> 24945
2497bldxb r1, [r2+17]
2497cjeq r1, 0x0, -56 ; -> 24945
2497djne r1, 0x1, +142 ; -> 24a0c
2497emov64 r5, 0x1
2497fja -59 ; -> 24945
24980ldxdw r1, [r10-1048]
24981stxdw [r10-2192], r1
24982ldxdw r9, [r10-1040]
24983mov64 r1, r10
24984add64 r1, -0x818
24985mov64 r2, r10
24986add64 r2, -0x408
24987mov64 r3, 0x3f8
24988call fn_35367
24989mov64 r1, 0x1
2498ajne r6, 0x0, +1 ; -> 2498c
2498bmov64 r1, 0x0
2498cstxdw [r10-2080], r9
2498dldxdw r2, [r10-2192]
2498estxdw [r10-2088], r2
2498fstxdw [r10-2096], r8
24990ldxw r2, [r10-2104]
24991stxw [r10-1024], r2
24992ldxw r2, [r10-2101]
24993stxw [r10-1021], r2
24994ldxdw r2, [r10-8]
24995stxdw [r10-1032], r2
24996ldxdw r2, [r10-16]
24997stxdw [r10-1040], r2
24998mov64 r2, r10
24999add64 r2, -0x830
2499astxdw [r10-1048], r2
2499bstxdw [r10-1056], r7
2499cstxdw [r10-4096], r1
2499dldxdw r1, [r10-2184]
2499estxdw [r10-4088], r1
2499fmov64 r1, r10
249a0add64 r1, -0x848
249a1mov64 r2, r10
249a2add64 r2, -0x420
249a3mov64 r5, r10
249a4ldxdw r3, [r10-2168]
249a5ldxdw r4, [r10-2176]
249a6call fn_28f7a
249a7ldxdw r1, [r10-2120]
249a8jeq r1, 0x2, +1 ; -> 249aa
249a9ja +64 ; -> 249ea
249aamov64 r1, r10
249abadd64 r1, -0x858
249acmov64 r2, r10
249adadd64 r2, -0x830
249aemov64 r3, r7
249afcall fn_2d89d
249b0ldxdw r3, [r10-1376]
249b1ldxdw r4, [r10-1384]
249b2ldxdw r5, [r4+0]
249b3add64 r5, -0x1
249b4ldxdw r2, [r10-2128]
249b5ldxdw r1, [r10-2136]
249b6stxdw [r4+0], r5
249b7jne r5, 0x0, +3 ; -> 249bb
249b8ldxdw r5, [r4+8]
249b9add64 r5, -0x1
249bastxdw [r4+8], r5
249bbldxdw r4, [r3+0]
249bcadd64 r4, -0x1
249bdstxdw [r3+0], r4
249bejne r4, 0x0, +3 ; -> 249c2
249bfldxdw r4, [r3+8]
249c0add64 r4, -0x1
249c1stxdw [r3+8], r4
249c2ldxdw r3, [r10-1328]
249c3ldxdw r4, [r10-1336]
249c4ldxdw r5, [r4+0]
249c5add64 r5, -0x1
249c6stxdw [r4+0], r5
249c7jne r5, 0x0, +3 ; -> 249cb
249c8ldxdw r5, [r4+8]
249c9add64 r5, -0x1
249castxdw [r4+8], r5
249cbldxdw r4, [r3+0]
249ccadd64 r4, -0x1
249cdstxdw [r3+0], r4
249cejne r4, 0x0, -93 ; -> 24972
249cfja +56 ; -> 24a08
249d0stxb [r10-2104], r6
249d1lddw r1, 0x1b3d30
249d3stxdw [r10-1056], r1
249d4mov64 r1, r10
249d5add64 r1, -0x10
249d6stxdw [r10-1040], r1
249d7lddw r1, 0x1a96e0
249d9stxdw [r10-8], r1
249damov64 r1, r10
249dbadd64 r1, -0x838
249dcstxdw [r10-16], r1
249ddstdw [r10-1024], 0x0
249destdw [r10-1048], 0x1
249dfstdw [r10-1032], 0x1
249e0mov64 r6, r10
249e1add64 r6, -0x830
249e2mov64 r2, r10
249e3add64 r2, -0x420
249e4mov64 r1, r6
249e5call fn_342ee
249e6mov64 r1, 0x15
249e7mov64 r2, r6
249e8call fn_01495
249e9ja -136 ; -> 24962
249ealdxdw r2, [r10-2112]
249ebldxdw r3, [r10-1376]
249ecldxdw r4, [r10-1384]
249edldxdw r5, [r4+0]
249eeadd64 r5, -0x1
249efstxdw [r4+0], r5
249f0jne r5, 0x0, +3 ; -> 249f4
249f1ldxdw r5, [r4+8]
249f2add64 r5, -0x1
249f3stxdw [r4+8], r5
249f4ldxdw r4, [r3+0]
249f5add64 r4, -0x1
249f6stxdw [r3+0], r4
249f7jne r4, 0x0, +3 ; -> 249fb
249f8ldxdw r4, [r3+8]
249f9add64 r4, -0x1
249fastxdw [r3+8], r4
249fbldxdw r3, [r10-1328]
249fcldxdw r4, [r10-1336]
249fdldxdw r5, [r4+0]
249feadd64 r5, -0x1
249ffstxdw [r4+0], r5
24a00jne r5, 0x0, +3 ; -> 24a04
24a01ldxdw r5, [r4+8]
24a02add64 r5, -0x1
24a03stxdw [r4+8], r5
24a04ldxdw r4, [r3+0]
24a05add64 r4, -0x1
24a06stxdw [r3+0], r4
24a07jne r4, 0x0, -150 ; -> 24972
24a08ldxdw r4, [r3+8]
24a09add64 r4, -0x1
24a0astxdw [r3+8], r4
24a0bja -154 ; -> 24972
24a0cstxb [r10-2104], r1
24a0dja -61 ; -> 249d1
Reconstructedbuy_exact_sol_in
// discriminator 38fc74089edfcd5f — handler fn_24931 → buy_rs_logic fn_28f7a (programs/pump/src/buy.rs)
// data: [8 disc][u64 spendable_sol_in][u64 min_tokens_out][opt u8 track_volume (must be 0/1)][opt u8 allow_partial_fill (0/1)]
// len < 16 → InstructionDidNotDeserialize; track_volume>=2 or flag>=2 → deserialize error (fn_01495, 0x15)
pub fn buy_exact_sol_in(ctx, spendable_sol_in: u64, min_tokens_out: u64,
track_volume: OptionBool, allow_partial: bool) -> Result<()> {
msg!("Instruction: BuyExactSolIn");
// fn_2cd81: Anchor account validation (global PDA, bonding_curve PDA ["bonding-curve", mint],
// ATAs, creator_vault PDA, event_authority, volume accumulators, fee_config/fee_program)
let g = &ctx.global; let c = &mut ctx.bonding_curve;
require!(!c.complete, BondingCurveComplete /*6005*/); // pc 28faf [curve+961]
require!(min_tokens_out != 0, 6020); // pc 28fb2
require!(spendable_sol_in != 0, 6041); // pc 28fb4
// fee bps from pump fee program CPI (GetFeesWithQuoteMint), by market cap: currently 95 / 30
let (protocol_bps, creator_bps) = get_fees_cpi(fee_config, fee_program, c); // fn_10820
let whitelisted = user.key == g.whitelist_pda; // pc 2905f memcmp Global+0x288
let (pbps, cbps) = if whitelisted { (0,0) } else { (protocol_bps, creator_bps_if_creator_set) };
// pc 2908b: net = floor(spend * 10000 / (10000 + total_bps)) (u128)
let mut net = (spendable_sol_in as u128 * 10000 / (10000 + pbps + cbps)) as u64;
let pfee = ceil_div(net * pbps, 10000); // fn_107c7 (round up)
let cfee = ceil_div(net * cbps, 10000);
let total = net + pfee + cfee; // checked
if total > spendable_sol_in { net -= total - spendable_sol_in; } // pc 290d7 trim rounding excess
require!(net != 0, 6042); // pc 2910a
// fn_1347e: constant product, sol_in - 1
let mut tokens = (net - 1) as u128 * c.virtual_token_reserves / (c.virtual_sol_reserves + net - 1);
let (mut sol_in, mut pfee, mut cfee) = (net, pfee, cfee);
if tokens > c.real_token_reserves && allow_partial { // pc 29143
tokens = c.real_token_reserves;
sol_in = tokens * c.virtual_sol_reserves / (c.virtual_token_reserves - tokens) + 1; // fn_13385
pfee = ceil_div(sol_in*pbps,10000); cfee = ceil_div(sol_in*cbps,10000);
require!(sol_in + pfee + cfee <= spendable_sol_in, TooMuchSolRequired /*6002*/); // pc 291c2
} else {
require!(tokens >= min_tokens_out, 6042 /*slippage*/); // pc 29155
}
require!(c.real_token_reserves >= tokens, 6021); // pc 291c5
// reserve updates (checked) pc 291f2..29218
c.virtual_token_reserves -= tokens;
c.virtual_sol_reserves += sol_in;
c.real_token_reserves -= tokens;
c.real_sol_reserves += sol_in;
// CPIs
token::transfer_checked(assoc_bonding_curve → associated_user, tokens, signer = ["bonding-curve", mint, bump]); // fn_118a3
system::transfer(user → bonding_curve, sol_in); // fn_10ff2
let buyback = if c.is_mayhem_mode {0} else { pfee * g.buyback_bps(5000) / 10000 }; // fn_12780 floor
system::transfer(user → fee_recipient, pfee - buyback); // fee_recipient must be in Global list
// (reserved list for mayhem curves)
system::transfer(user → buyback_fee_recipient /*remaining acct*/, buyback);
if c.cashback_enabled { credit user_volume_accumulator (cashback) with cfee } // [curve+963]
else { system::transfer(user → creator_vault, cfee); }
if track_volume { update global/user volume accumulators (no lamport change) }
emit_cpi!(TradeEvent{ mint, sol_amount: sol_in, token_amount: tokens, is_buy: true, user, ts,
virtual/real reserves, fee_recipient, fee_bps, fee, creator, creator_fee_bps, creator_fee,
track_volume, ..., ix_name: "buy_exact_sol_in", ... });
// complete flag set when real_token_reserves hits 0 (shared buy.rs path)
}

Replay model

The executable model the agent wrote. Every tally above comes from running it against mainnet.

const B58='123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
function b58(hex){let n=BigInt('0x'+hex);let s='';while(n>0n){s=B58[Number(n%58n)]+s;n/=58n;}for(let i=0;i<hex.length&&hex.substr(i,2)==='00';i+=2)s='1'+s;return s;}
const WHITELIST=b58('a28b5fd26ab479a6a9cc6cbf6b0b23eb61885a371e0120aca913beef3d138a78');
const RESERVED=['e893141fb18e9f1574d810e178e19e30604e3175aa2e4a32dfc8600727d10709','3584536256094f912819127efa4e446b4333721793d13876f9aadbf3dc7d0b5f','6e75018220f942677003237b4d6b453759b4a5c690b59c35d9bb187a090cbd2a','33987a9ebb136799ab59925b13e5dc8b3081df005db427c1478fa46ff8c347a0','74e9543f3e37a2d046227addcb4e9c774c44258c43edf24aa8aae1f00214665b','da4c38cd6db7438f59b408bb9ec3b4ca9e8ad1f1f24653c499b5796c20dbf9b3','2ddd9eea3f39b372115c71847c1845cfa536c685074e030e44d021de3ef9e35c','4cb780f08ee2fee84bec446a577825da68d439fa8a5da3b0c5cff50f63f4546b'].map(b58);
function u64(d,o){let v=0n;for(let i=7;i>=0;i--)v=(v<<8n)|BigInt(d[o+i]);return v;}
// Global: initial_virtual_token 1.073e15, initial_virtual_sol 30e9, initial_real_token 7.931e14, supply 1e15, fee bps 95, buyback_bps 5000
const IVT=1073000000000000n, IVS=30000000000n, OFFS=IVT-(1000000000000000n-793100000000000n);
function model(ctx){
const d=ctx.data, A=ctx.accounts;
const spend=u64(d,8);
const wl = A[6].pubkey===WHITELIST;
const PB = wl?0n:95n, CB = wl?0n:30n;
let net = spend*10000n/(10000n+PB+CB);
const ceil=(a,b)=>(a*b+9999n)/10000n;
let pf=ceil(net,PB), cf=ceil(net,CB);
const tot=net+pf+cf; if(tot>spend){ net-= (tot-spend); }
const vtok=A[4].token.amount+OFFS;
const K=IVT*IVS;
const vsol=(K+vtok-1n)/vtok;
const tokens=(net-1n)*vtok/(vsol+net-1n);
const mayhem=RESERVED.includes(A[1].pubkey);
const bb = mayhem?0n: pf*5000n/10000n;
const lam={3:net,1:pf-bb,9:cf,4:0n,13:0n};
if(A.length>17) lam[17]=bb;
return {lamports:lam,tokens:{4:-tokens,5:tokens}};
}

Accounts

  1. 0global
  2. 1fee_recipientwritten
  3. 2mint
  4. 3bonding_curvewritten
  5. 4associated_bonding_curvewritten
  6. 5associated_userwritten
  7. 6usersigns, written
  8. 7system_program
  9. 8token_program
  10. 9creator_vaultwritten
  11. 10event_authority
  12. 11program
  13. 12global_volume_accumulator
  14. 13user_volume_accumulatorwritten
  15. 14fee_config
  16. 15fee_program

args: spendable_sol_in: u64, min_tokens_out: u64, track_volume: {"defined":{"name":"OptionBool"}}

program 6EF8rr…BEwF6P