Instruction
buy_exact_sol_in
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.
24931mov64 r6, r524932mov64 r9, r424933mov64 r8, r324934mov64 r7, r224935stxdw [r10-2160], r124936lddw r1, 0x1ae487 ; "Instruction: BuyExactSolIn"24938mov64 r2, 0x1a24939call sol_log_2493aldxdw r1, [r6-4088]2493bjlt r1, 0x8, +35 ; -> 2495f2493cmov64 r2, r12493dand64 r2, -0x82493ejeq r2, 0x8, +32 ; -> 2495f2493fldxdw r2, [r6-4096]24940ldxdw r3, [r2+0]24941ldxdw r4, [r2+8]24942jne r1, 0x10, +51 ; -> 2497624943mov64 r6, 0x024944mov64 r5, 0x024945stxdw [r10-2184], r524946stxdw [r10-2176], r424947stxdw [r10-2168], r324948mov64 r1, -0x124949stxw [r10-2101], r12494astxw [r10-2104], r12494bstxdw [r10-8], r92494cstxdw [r10-16], r82494dmov64 r1, r102494eadd64 r1, -0x8382494fstxdw [r10-4088], r124950mov64 r1, r1024951add64 r1, -0x42024952mov64 r3, r1024953add64 r3, -0x1024954mov64 r5, r1024955mov64 r2, r724956call fn_2cd8124957ldxdw r8, [r10-1056]24958lddw r1, 0x80000000000000002495ajeq r8, r1, +1 ; -> 2495c2495bja +36 ; -> 249802495cldxdw r2, [r10-1040]2495dldxdw r1, [r10-1048]2495eja +19 ; -> 249722495flddw r1, 0x1b3c6024961call fn_33e7124962mov64 r1, r024963and64 r1, 0x324964mov64 r2, r124965add64 r2, -0x224966jlt r2, 0x2, +5 ; -> 2496c24967jeq r1, 0x0, +4 ; -> 2496c24968ldxdw r1, [r0-1]24969ldxdw r2, [r0+7]2496aldxdw r2, [r2+0]2496bcallx r22496cmov64 r1, r102496dadd64 r1, -0x8682496emov64 r2, 0x662496fcall fn_32b0924970ldxdw r2, [r10-2144]24971ldxdw r1, [r10-2152]24972ldxdw r3, [r10-2160]24973stxdw [r3+8], r224974stxdw [r3+0], r124975exit24976ldxb r6, [r2+16]24977jlt r6, 0x2, +1 ; -> 2497924978ja +87 ; -> 249d024979mov64 r5, 0x02497ajeq r1, 0x11, -54 ; -> 249452497bldxb r1, [r2+17]2497cjeq r1, 0x0, -56 ; -> 249452497djne r1, 0x1, +142 ; -> 24a0c2497emov64 r5, 0x12497fja -59 ; -> 2494524980ldxdw r1, [r10-1048]24981stxdw [r10-2192], r124982ldxdw r9, [r10-1040]24983mov64 r1, r1024984add64 r1, -0x81824985mov64 r2, r1024986add64 r2, -0x40824987mov64 r3, 0x3f824988call fn_3536724989mov64 r1, 0x12498ajne r6, 0x0, +1 ; -> 2498c2498bmov64 r1, 0x02498cstxdw [r10-2080], r92498dldxdw r2, [r10-2192]2498estxdw [r10-2088], r22498fstxdw [r10-2096], r824990ldxw r2, [r10-2104]24991stxw [r10-1024], r224992ldxw r2, [r10-2101]24993stxw [r10-1021], r224994ldxdw r2, [r10-8]24995stxdw [r10-1032], r224996ldxdw r2, [r10-16]24997stxdw [r10-1040], r224998mov64 r2, r1024999add64 r2, -0x8302499astxdw [r10-1048], r22499bstxdw [r10-1056], r72499cstxdw [r10-4096], r12499dldxdw r1, [r10-2184]2499estxdw [r10-4088], r12499fmov64 r1, r10249a0add64 r1, -0x848249a1mov64 r2, r10249a2add64 r2, -0x420249a3mov64 r5, r10249a4ldxdw r3, [r10-2168]249a5ldxdw r4, [r10-2176]249a6call fn_28f7a249a7ldxdw r1, [r10-2120]249a8jeq r1, 0x2, +1 ; -> 249aa249a9ja +64 ; -> 249ea249aamov64 r1, r10249abadd64 r1, -0x858249acmov64 r2, r10249adadd64 r2, -0x830249aemov64 r3, r7249afcall fn_2d89d249b0ldxdw r3, [r10-1376]249b1ldxdw r4, [r10-1384]249b2ldxdw r5, [r4+0]249b3add64 r5, -0x1249b4ldxdw r2, [r10-2128]249b5ldxdw r1, [r10-2136]249b6stxdw [r4+0], r5249b7jne r5, 0x0, +3 ; -> 249bb249b8ldxdw r5, [r4+8]249b9add64 r5, -0x1249bastxdw [r4+8], r5249bbldxdw r4, [r3+0]249bcadd64 r4, -0x1249bdstxdw [r3+0], r4249bejne r4, 0x0, +3 ; -> 249c2249bfldxdw r4, [r3+8]249c0add64 r4, -0x1249c1stxdw [r3+8], r4249c2ldxdw r3, [r10-1328]249c3ldxdw r4, [r10-1336]249c4ldxdw r5, [r4+0]249c5add64 r5, -0x1249c6stxdw [r4+0], r5249c7jne r5, 0x0, +3 ; -> 249cb249c8ldxdw r5, [r4+8]249c9add64 r5, -0x1249castxdw [r4+8], r5249cbldxdw r4, [r3+0]249ccadd64 r4, -0x1249cdstxdw [r3+0], r4249cejne r4, 0x0, -93 ; -> 24972249cfja +56 ; -> 24a08249d0stxb [r10-2104], r6249d1lddw r1, 0x1b3d30249d3stxdw [r10-1056], r1249d4mov64 r1, r10249d5add64 r1, -0x10249d6stxdw [r10-1040], r1249d7lddw r1, 0x1a96e0249d9stxdw [r10-8], r1249damov64 r1, r10249dbadd64 r1, -0x838249dcstxdw [r10-16], r1249ddstdw [r10-1024], 0x0249destdw [r10-1048], 0x1249dfstdw [r10-1032], 0x1249e0mov64 r6, r10249e1add64 r6, -0x830249e2mov64 r2, r10249e3add64 r2, -0x420249e4mov64 r1, r6249e5call fn_342ee249e6mov64 r1, 0x15249e7mov64 r2, r6249e8call fn_01495249e9ja -136 ; -> 24962249ealdxdw r2, [r10-2112]249ebldxdw r3, [r10-1376]249ecldxdw r4, [r10-1384]249edldxdw r5, [r4+0]249eeadd64 r5, -0x1249efstxdw [r4+0], r5249f0jne r5, 0x0, +3 ; -> 249f4249f1ldxdw r5, [r4+8]249f2add64 r5, -0x1249f3stxdw [r4+8], r5249f4ldxdw r4, [r3+0]249f5add64 r4, -0x1249f6stxdw [r3+0], r4249f7jne r4, 0x0, +3 ; -> 249fb249f8ldxdw r4, [r3+8]249f9add64 r4, -0x1249fastxdw [r3+8], r4249fbldxdw r3, [r10-1328]249fcldxdw r4, [r10-1336]249fdldxdw r5, [r4+0]249feadd64 r5, -0x1249ffstxdw [r4+0], r524a00jne r5, 0x0, +3 ; -> 24a0424a01ldxdw r5, [r4+8]24a02add64 r5, -0x124a03stxdw [r4+8], r524a04ldxdw r4, [r3+0]24a05add64 r4, -0x124a06stxdw [r3+0], r424a07jne r4, 0x0, -150 ; -> 2497224a08ldxdw r4, [r3+8]24a09add64 r4, -0x124a0astxdw [r3+8], r424a0bja -154 ; -> 2497224a0cstxb [r10-2104], r124a0dja -61 ; -> 249d1
// 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 28fb2require!(spendable_sol_in != 0, 6041); // pc 28fb4// fee bps from pump fee program CPI (GetFeesWithQuoteMint), by market cap: currently 95 / 30let (protocol_bps, creator_bps) = get_fees_cpi(fee_config, fee_program, c); // fn_10820let whitelisted = user.key == g.whitelist_pda; // pc 2905f memcmp Global+0x288let (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; // checkedif total > spendable_sol_in { net -= total - spendable_sol_in; } // pc 290d7 trim rounding excessrequire!(net != 0, 6042); // pc 2910a// fn_1347e: constant product, sol_in - 1let 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 29143tokens = c.real_token_reserves;sol_in = tokens * c.virtual_sol_reserves / (c.virtual_token_reserves - tokens) + 1; // fn_13385pfee = 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..29218c.virtual_token_reserves -= tokens;c.virtual_sol_reserves += sol_in;c.real_token_reserves -= tokens;c.real_sol_reserves += sol_in;// CPIstoken::transfer_checked(assoc_bonding_curve → associated_user, tokens, signer = ["bonding-curve", mint, bump]); // fn_118a3system::transfer(user → bonding_curve, sol_in); // fn_10ff2let buyback = if c.is_mayhem_mode {0} else { pfee * g.buyback_bps(5000) / 10000 }; // fn_12780 floorsystem::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 5000const 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
- 0global
- 1fee_recipientwritten
- 2mint
- 3bonding_curvewritten
- 4associated_bonding_curvewritten
- 5associated_userwritten
- 6usersigns, written
- 7system_program
- 8token_program
- 9creator_vaultwritten
- 10event_authority
- 11program
- 12global_volume_accumulator
- 13user_volume_accumulatorwritten
- 14fee_config
- 15fee_program
args: spendable_sol_in: u64, min_tokens_out: u64, track_volume: {"defined":{"name":"OptionBool"}}
program 6EF8rr…BEwF6P