Instruction
buy_v2
buy_v2 buys exactly `amount` tokens from a pump.fun bonding curve. It works for SOL-priced curves (native lamports, quote_mint must be wSOL) and for curves priced in another SPL token (payment by transfer_checked from your quote token account). Anyone can call it. You pay the constant-product price plus 1 lamport, a 0.95% protocol fee and a 0.30% creator fee (both rounded up; the rates come from a CPI to pump's fee program). Half of the protocol fee goes to a buyback recipient, except on mayhem curves. The creator fee goes to the creator vault, or back to you as cashback on cashback curves. One wallet stored in Global pays no fees. It fails if the curve is complete (6005), amount is 0 (6020), too few tokens remain (6021, unless the hidden cap flag byte is set), the quote mint is wrong (6063), or the total exceeds max_sol_cost (6002).
- Discriminator
- 0xb817ee6167c5d33d
- Calls in the sample
- 3
- Reproduced, seen by the agent
- 0 / 1
- Reproduced, never shown to the agent
- 0 / 2
0 of 3 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.
2425amov64 r6, r52425bmov64 r8, r42425cmov64 r9, r32425dmov64 r7, r22425estxdw [r10-952], r12425flddw r1, 0x1ae3aa ; "Instruction: BuyV2"24261mov64 r2, 0x1224262call sol_log_24263ldxdw r1, [r6-4088]24264jlt r1, 0x8, +109 ; -> 242d224265mov64 r2, r124266and64 r2, -0x824267jeq r2, 0x8, +106 ; -> 242d224268ldxdw r2, [r6-4096]24269ldxdw r3, [r2+0]2426amov64 r5, 0x02426bldxdw r4, [r2+8]2426cjeq r1, 0x10, +4 ; -> 242712426dldxb r1, [r2+16]2426ejeq r1, 0x0, +2 ; -> 242712426fjne r1, 0x1, +153 ; -> 2430924270mov64 r5, 0x124271stxdw [r10-976], r524272stxdw [r10-968], r424273stxdw [r10-960], r324274stdw [r10-891], -0x124275stdw [r10-896], -0x124276stxdw [r10-8], r824277stxdw [r10-16], r924278mov64 r1, r1024279add64 r1, -0x3802427astxdw [r10-4088], r12427bmov64 r1, r102427cadd64 r1, -0x1c02427dmov64 r3, r102427eadd64 r3, -0x102427fmov64 r5, r1024280mov64 r2, r724281call fn_13be624282ldxdw r8, [r10-432]24283ldxdw r6, [r10-440]24284ldxdw r9, [r10-448]24285lddw r1, 0x800000000000000024287jeq r9, r1, +93 ; -> 242e524288mov64 r1, r1024289add64 r1, -0x3582428amov64 r2, r102428badd64 r2, -0x1a82428cmov64 r3, 0x1982428dcall fn_353672428estxdw [r10-864], r82428fstxdw [r10-872], r624290stxdw [r10-880], r924291ldxdw r1, [r10-896]24292stxdw [r10-416], r124293ldxdw r1, [r10-891]24294stxdw [r10-411], r124295ldxdw r1, [r10-8]24296stxdw [r10-424], r124297ldxdw r1, [r10-16]24298stxdw [r10-432], r124299mov64 r1, r102429aadd64 r1, -0x3702429bstxdw [r10-440], r12429cstxdw [r10-448], r72429dmov64 r1, r102429eadd64 r1, -0x3902429fmov64 r2, r10242a0add64 r2, -0x1c0242a1ldxdw r3, [r10-960]242a2ldxdw r4, [r10-968]242a3ldxdw r5, [r10-976]242a4call fn_26aef242a5ldxdw r6, [r10-912]242a6jeq r6, 0x2, +1 ; -> 242a8242a7ja +65 ; -> 242e9242a8mov64 r1, r10242a9add64 r1, -0x3a0242aamov64 r2, r10242abadd64 r2, -0x370242acmov64 r3, r7242adcall fn_14b46242aeldxdw r1, [r10-720]242afldxdw r2, [r10-728]242b0ldxdw r3, [r2+0]242b1add64 r3, -0x1242b2ldxdw r8, [r10-920]242b3ldxdw r6, [r10-928]242b4stxdw [r2+0], r3242b5jne r3, 0x0, +3 ; -> 242b9242b6ldxdw r3, [r2+8]242b7add64 r3, -0x1242b8stxdw [r2+8], r3242b9ldxdw r2, [r1+0]242baadd64 r2, -0x1242bbstxdw [r1+0], r2242bcldxdw r4, [r10-952]242bdjne r2, 0x0, +3 ; -> 242c1242beldxdw r2, [r1+8]242bfadd64 r2, -0x1242c0stxdw [r1+8], r2242c1ldxdw r1, [r10-672]242c2ldxdw r2, [r10-680]242c3ldxdw r3, [r2+0]242c4add64 r3, -0x1242c5stxdw [r2+0], r3242c6jne r3, 0x0, +3 ; -> 242ca242c7ldxdw r3, [r2+8]242c8add64 r3, -0x1242c9stxdw [r2+8], r3242caldxdw r2, [r1+0]242cbadd64 r2, -0x1242ccstxdw [r1+0], r2242cdjne r2, 0x0, +24 ; -> 242e6242celdxdw r2, [r1+8]242cfadd64 r2, -0x1242d0stxdw [r1+8], r2242d1ja +20 ; -> 242e6242d2lddw r1, 0x1b3c60242d4call fn_33e71242d5mov64 r1, r0242d6and64 r1, 0x3242d7mov64 r2, r1242d8add64 r2, -0x2242d9jlt r2, 0x2, +5 ; -> 242df242dajeq r1, 0x0, +4 ; -> 242df242dbldxdw r1, [r0-1]242dcldxdw r2, [r0+7]242ddldxdw r2, [r2+0]242decallx r2242dfmov64 r1, r10242e0add64 r1, -0x3b0242e1mov64 r2, 0x66242e2call fn_32b09242e3ldxdw r8, [r10-936]242e4ldxdw r6, [r10-944]242e5ldxdw r4, [r10-952]242e6stxdw [r4+8], r8242e7stxdw [r4+0], r6242e8exit242e9ldxdw r8, [r10-904]242ealdxdw r1, [r10-720]242ebldxdw r2, [r10-728]242ecldxdw r3, [r2+0]242edadd64 r3, -0x1242eestxdw [r2+0], r3242efjne r3, 0x0, +3 ; -> 242f3242f0ldxdw r3, [r2+8]242f1add64 r3, -0x1242f2stxdw [r2+8], r3242f3ldxdw r2, [r1+0]242f4add64 r2, -0x1242f5stxdw [r1+0], r2242f6ldxdw r4, [r10-952]242f7jne r2, 0x0, +3 ; -> 242fb242f8ldxdw r2, [r1+8]242f9add64 r2, -0x1242fastxdw [r1+8], r2242fbldxdw r1, [r10-672]242fcldxdw r2, [r10-680]242fdldxdw r3, [r2+0]242feadd64 r3, -0x1242ffstxdw [r2+0], r324300jne r3, 0x0, +3 ; -> 2430424301ldxdw r3, [r2+8]24302add64 r3, -0x124303stxdw [r2+8], r324304ldxdw r2, [r1+0]24305add64 r2, -0x124306stxdw [r1+0], r224307jne r2, 0x0, -34 ; -> 242e624308ja -59 ; -> 242ce24309stxb [r10-896], r12430alddw r1, 0x1b3d302430cstxdw [r10-448], r12430dmov64 r1, r102430eadd64 r1, -0x102430fstxdw [r10-432], r124310lddw r1, 0x1a96e024312stxdw [r10-8], r124313mov64 r1, r1024314add64 r1, -0x38024315stxdw [r10-16], r124316stdw [r10-416], 0x024317stdw [r10-440], 0x124318stdw [r10-424], 0x124319mov64 r6, r102431aadd64 r6, -0x3702431bmov64 r2, r102431cadd64 r2, -0x1c02431dmov64 r1, r62431ecall fn_342ee2431fmov64 r1, 0x1524320mov64 r2, r624321call fn_0149524322ja -78 ; -> 242d5
// discriminator b817ee6167c5d33d handler fn_2425a -> buy_v2_logic fn_26aef// args: amount: u64, max_sol_cost: u64, [optional u8 cap_to_remaining: 0|1] (3rd byte not in IDL)pub fn buy_v2(ctx, amount: u64, max_sol_cost: u64, cap_to_remaining: Option<bool>) -> Result<()> {msg!("Instruction: BuyV2");BuyV2Accounts::try_accounts(ctx)?; // fn_13be6 (shared with buy_exact_quote_in_v2): PDAs, ATAs, mints, programslet curve = &mut ctx.bonding_curve;require!(!curve.complete, BondingCurveComplete /*6005*/); // pc 26afblet mut amount = amount;if cap_to_remaining == Some(true) { amount = min(amount, curve.real_token_reserves); } // pc 26aferequire!(amount != 0, 6020); // pc 26b01require!(curve.real_token_reserves >= amount, 6021 /*not enough tokens*/); // pc 26b04check_global_state(global)?; // fn_078efcheck_mints(global, base_mint, ...)?; // fn_123felet token_quoted = curve.quote_mint != Pubkey::default(); // pc 26bc1if token_quoted {// create-idempotent the quote ATAs as needed (fn_029be / fn_02cb6):// associated_quote_bonding_curve, associated_quote_user, associated_creator_vault,// associated_user_volume_accumulator, associated_quote_fee_recipient, associated_quote_buyback_fee_recipient} else {require!(quote_mint.key == WSOL_MINT, 6063 /*wrong quote mint*/); // pc 26d42}// constant-product price, rounded up by one unit (fn_13385)require!(curve.virtual_token_reserves > amount, 6024/6026);let cost = (amount as u128 * curve.virtual_quote_reserves as u128/ (curve.virtual_token_reserves - amount) as u128) as u64 + 1;let whitelisted = user.key == global.whitelist; // Global data @451, pc 26d84let (protocol_fee, creator_fee) = if whitelisted { (0, 0) } else {// CPI fee_program::GetFeesWithQuoteMint(fee_config, curve, market cap) -> bps (fn_10820)// currently protocol 95 bps, creator 30 bps(ceil_div(cost * protocol_bps, 10_000), ceil_div(cost * creator_bps, 10_000))};let total = cost.checked_add(protocol_fee)?.checked_add(creator_fee)?; // overflow -> panic helpersrequire!(total <= max_sol_cost, TooMuchSolRequired /*6002*/); // pc 26dc6curve_apply_buy(curve, amount, cost); // fn_134f5: vtok-=amt, rtok-=amt, vquote+=cost, rquote+=cost// base tokens out: transfer_checked(associated_base_bonding_curve -> associated_base_user, amount),// signed by PDA ["bonding-curve", base_mint, bump] // fn_1148atransfer_base_from_curve_signed(amount)?;if whitelisted { // pc 26e37 -> 26f34// re-read both token accounts and sync curve via fn_137f5; no fees charged} else {if global_volume_accumulator.field_8 == default { /* copied from accounts struct (unclear) */ }if creator_fee != 0 { // pc 26e56 -> 26ef9if curve.cashback_enabled { // curve byte 163quote_xfer(user -> user_volume_accumulator (or its quote ATA), creator_fee); // fn_1234drecord_cashback(user_volume_accumulator, creator_fee); // fn_0f055} else {quote_xfer(user -> creator_vault (or associated_creator_vault), creator_fee); // fn_1234d}}// SOL curve: system_program::transfer; token curve: transfer_checked from associated_quote_userquote_xfer(user -> bonding_curve | associated_quote_bonding_curve, cost); // fn_1229dlet buyback = if curve.mayhem_mode /*byte 162*/ { 0 }else { protocol_fee * global.buyback_bps(5000) / 10_000 }; // fn_12780, floorquote_xfer(user -> fee_recipient | associated_quote_fee_recipient, protocol_fee - buyback); // fn_122f5quote_xfer(user -> buyback_fee_recipient | associated_quote_buyback_fee_recipient, buyback); // fn_122f5}// volume tracking (user_volume_accumulator), completion flag when real_token_reserves hits 0,// TradeEvent emitted via CPI to self through event_authority ("__event_authority")Ok(())}
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;}// Global (4wTV1Ymi...) @451: whitelisted trader (pays no fees)const WHITELIST=b58('a28b5fd26ab479a6a9cc6cbf6b0b23eb61885a371e0120aca913beef3d138a78');// Global @483.. reserved (mayhem) fee recipientsconst RESERVED=['e893141fb18e9f1574d810e178e19e30604e3175aa2e4a32dfc8600727d10709','3584536256094f912819127efa4e446b4333721793d13876f9aadbf3dc7d0b5f','6e75018220f942677003237b4d6b453759b4a5c690b59c35d9bb187a090cbd2a','33987a9ebb136799ab59925b13e5dc8b3081df005db427c1478fa46ff8c347a0','74e9543f3e37a2d046227addcb4e9c774c44258c43edf24aa8aae1f00214665b','da4c38cd6db7438f59b408bb9ec3b4ca9e8ad1f1f24653c499b5796c20dbf9b3','2ddd9eea3f39b372115c71847c1845cfa536c685074e030e44d021de3ef9e35c','4cb780f08ee2fee84bec446a577825da68d439fa8a5da3b0c5cff50f63f4546b'].map(b58);const WSOL='So11111111111111111111111111111111111111112';function u64(d,o){let v=0n;for(let i=7;i>=0;i--)v=(v<<8n)|BigInt(d[o+i]);return v;}const ceilDiv=(a,b)=>(a+b-1n)/b;function model(ctx){const d=ctx.data; let amount=u64(d,8); const maxCost=u64(d,16);const capFlag = d.length>24 && d[24]===1;const A=ctx.accounts;const curveTokens=A[11].token.amount;// virtual token reserves = curve ATA balance + 73e12 (1073e12 initial virtual - 1e15 supply)const vtr=curveTokens+73000000000000n;const K=1073000000000000n*30000000000n;const vsr=ceilDiv(K,vtr);const realTok = vtr - 279900000000000n; // real token reserves (793.1e12 initial)if(capFlag && amount>realTok) amount=realTok;const whitelisted = A[13].pubkey===WHITELIST;let cost = whitelisted ? maxCost : amount*vsr/(vtr-amount)+1n;let pf=0n,cf=0n;if(!whitelisted){ pf=ceilDiv(cost*95n,10000n); cf=ceilDiv(cost*30n,10000n); }const mayhem=RESERVED.includes(A[6].pubkey);const buyback = mayhem?0n: pf*5000n/10000n;const sol = A[2].pubkey===WSOL;const lam={}, tok={11:-amount,14:amount};if(sol){lam[10]=cost; lam[6]=pf-buyback; lam[8]=buyback; lam[16]=cf;lam[7]=0n; lam[9]=0n; lam[11]=0n; lam[20]=0n;tok[7]=0n; tok[9]=0n;} else {tok[12]=cost; tok[7]=pf-buyback; tok[9]=buyback; tok[17]=cf; tok[15]=-(cost+pf+cf);}return {lamports:lam,tokens:tok};}
Accounts
- 0global
- 1base_mint
- 2quote_mint
- 3base_token_program
- 4quote_token_program
- 5associated_token_program
- 6fee_recipientwritten
- 7associated_quote_fee_recipientwritten
- 8buyback_fee_recipientwritten
- 9associated_quote_buyback_fee_recipientwritten
- 10bonding_curvewritten
- 11associated_base_bonding_curvewritten
- 12associated_quote_bonding_curvewritten
- 13usersigns, written
- 14associated_base_userwritten
- 15associated_quote_userwritten
- 16creator_vaultwritten
- 17associated_creator_vaultwritten
- 18sharing_config
- 19global_volume_accumulator
- 20user_volume_accumulatorwritten
- 21associated_user_volume_accumulatorwritten
- 22fee_config
- 23fee_program
- 24system_program
- 25event_authority
- 26program
args: amount: u64, max_sol_cost: u64
program 6EF8rr…BEwF6P