debpf
pump.fun / instructions

Instruction

buy_v3

Partly provenHidden

Hidden (not in the IDL) exact-tokens-out buy for pump's new "v3" quote-mint bonding curves. Any user can call it: you name how many tokens you want and the most quote (SOL) you're willing to pay. The cost is the constant-product price plus 1 lamport, plus a 0.95% protocol fee and a 0.30% creator fee (both rounded up). Half of the protocol fee (Global.buyback_bps = 5000) goes straight to a buyback fee recipient. The rest of the protocol fee and the creator fee are not paid out on the spot: they stay in the bonding-curve account and are counted in curve fields until the hidden sweep instructions pay them out. The trade fails if the total is above max_quote_cost (6002), if amount is 0 (6020), or if the curve has fewer tokens left than requested (6021), unless the optional flag is set; then the amount is cut down to what is left.

Discriminator
0x07051dc4f5176550
Calls in the sample
5
Reproduced, seen by the agent
2 / 3
Reproduced, never shown to the agent
—

2 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.

Bytecodefn_24491
24491mov64 r6, r5
24492mov64 r8, r4
24493mov64 r9, r3
24494mov64 r7, r2
24495stxdw [r10-432], r1
24496lddw r1, 0x1ae3ed ; "Instruction: BuyV3"
24498mov64 r2, 0x12
24499call sol_log_
2449aldxdw r1, [r6-4088]
2449bjlt r1, 0x8, +96 ; -> 244fc
2449cmov64 r2, r1
2449dand64 r2, -0x8
2449ejeq r2, 0x8, +93 ; -> 244fc
2449fldxdw r2, [r6-4096]
244a0ldxdw r3, [r2+0]
244a1mov64 r5, 0x0
244a2ldxdw r4, [r2+8]
244a3jeq r1, 0x10, +4 ; -> 244a8
244a4ldxb r1, [r2+16]
244a5jeq r1, 0x0, +2 ; -> 244a8
244a6jne r1, 0x1, +124 ; -> 24523
244a7mov64 r5, 0x1
244a8stxdw [r10-456], r5
244a9stxdw [r10-448], r4
244aastxdw [r10-440], r3
244abmov64 r1, -0x1
244acstxb [r10-372], r1
244adstxw [r10-376], r1
244aestxdw [r10-8], r8
244afstxdw [r10-16], r9
244b0mov64 r1, r10
244b1add64 r1, -0x178
244b2stxdw [r10-4088], r1
244b3mov64 r1, r10
244b4add64 r1, -0xc0
244b5mov64 r3, r10
244b6add64 r3, -0x10
244b7mov64 r5, r10
244b8mov64 r2, r7
244b9call fn_1f826
244baldxdw r8, [r10-184]
244bbldxdw r6, [r10-192]
244bcldxb r9, [r10-22]
244bdjeq r9, 0x2, +81 ; -> 2450f
244bemov64 r1, r10
244bfadd64 r1, -0x160
244c0mov64 r2, r10
244c1add64 r2, -0xb0
244c2mov64 r3, 0x9a
244c3call fn_35367
244c4ldxw r1, [r10-21]
244c5stxw [r10-197], r1
244c6ldxb r1, [r10-17]
244c7stxb [r10-193], r1
244c8stxb [r10-198], r9
244c9stxdw [r10-360], r8
244castxdw [r10-368], r6
244cbldxw r1, [r10-376]
244ccstxw [r10-160], r1
244cdldxb r1, [r10-372]
244cestxb [r10-156], r1
244cfldxdw r1, [r10-8]
244d0stxdw [r10-168], r1
244d1ldxdw r1, [r10-16]
244d2stxdw [r10-176], r1
244d3mov64 r1, r10
244d4add64 r1, -0x170
244d5stxdw [r10-184], r1
244d6stxdw [r10-192], r7
244d7mov64 r1, r10
244d8add64 r1, -0x188
244d9mov64 r2, r10
244daadd64 r2, -0xc0
244dbldxdw r3, [r10-440]
244dcldxdw r4, [r10-448]
244ddldxdw r5, [r10-456]
244decall fn_28189
244dfldxdw r6, [r10-392]
244e0jeq r6, 0x2, +1 ; -> 244e2
244e1ja +49 ; -> 24513
244e2mov64 r1, r10
244e3add64 r1, -0x198
244e4mov64 r2, r10
244e5add64 r2, -0x170
244e6mov64 r3, r7
244e7call fn_202de
244e8ldxdw r1, [r10-224]
244e9ldxdw r2, [r10-232]
244ealdxdw r3, [r2+0]
244ebadd64 r3, -0x1
244ecldxdw r8, [r10-400]
244edldxdw r6, [r10-408]
244eestxdw [r2+0], r3
244efjne r3, 0x0, +3 ; -> 244f3
244f0ldxdw r3, [r2+8]
244f1add64 r3, -0x1
244f2stxdw [r2+8], r3
244f3ldxdw r2, [r1+0]
244f4add64 r2, -0x1
244f5stxdw [r1+0], r2
244f6ldxdw r4, [r10-432]
244f7jne r2, 0x0, +24 ; -> 24510
244f8ldxdw r2, [r1+8]
244f9add64 r2, -0x1
244fastxdw [r1+8], r2
244fbja +20 ; -> 24510
244fclddw r1, 0x1b3c60
244fecall fn_33e71
244ffmov64 r1, r0
24500and64 r1, 0x3
24501mov64 r2, r1
24502add64 r2, -0x2
24503jlt r2, 0x2, +5 ; -> 24509
24504jeq r1, 0x0, +4 ; -> 24509
24505ldxdw r1, [r0-1]
24506ldxdw r2, [r0+7]
24507ldxdw r2, [r2+0]
24508callx r2
24509mov64 r1, r10
2450aadd64 r1, -0x1a8
2450bmov64 r2, 0x66
2450ccall fn_32b09
2450dldxdw r8, [r10-416]
2450eldxdw r6, [r10-424]
2450fldxdw r4, [r10-432]
24510stxdw [r4+8], r8
24511stxdw [r4+0], r6
24512exit
24513ldxdw r8, [r10-384]
24514ldxdw r1, [r10-224]
24515ldxdw r2, [r10-232]
24516ldxdw r3, [r2+0]
24517add64 r3, -0x1
24518stxdw [r2+0], r3
24519ldxdw r4, [r10-432]
2451ajne r3, 0x0, +3 ; -> 2451e
2451bldxdw r3, [r2+8]
2451cadd64 r3, -0x1
2451dstxdw [r2+8], r3
2451eldxdw r2, [r1+0]
2451fadd64 r2, -0x1
24520stxdw [r1+0], r2
24521jne r2, 0x0, -18 ; -> 24510
24522ja -43 ; -> 244f8
24523stxb [r10-376], r1
24524lddw r1, 0x1b3d30
24526stxdw [r10-192], r1
24527mov64 r1, r10
24528add64 r1, -0x10
24529stxdw [r10-176], r1
2452alddw r1, 0x1a96e0
2452cstxdw [r10-8], r1
2452dmov64 r1, r10
2452eadd64 r1, -0x178
2452fstxdw [r10-16], r1
24530stdw [r10-160], 0x0
24531stdw [r10-184], 0x1
24532stdw [r10-168], 0x1
24533mov64 r6, r10
24534add64 r6, -0x170
24535mov64 r2, r10
24536add64 r2, -0xc0
24537mov64 r1, r6
24538call fn_342ee
24539mov64 r1, 0x15
2453amov64 r2, r6
2453bcall fn_01495
2453cja -62 ; -> 244ff
Reconstructedbuy_v3
// discriminator 07051dc4f5176550 ("Instruction: BuyV3") handler fn_24491 -> trade_v3_buy_logic fn_28189
// args: amount: u64, max_quote_cost: u64, clamp_to_reserves: Option<bool> (byte 16 of args; absent = false; >1 => error)
// accounts (fn_1f826): 0 global, 1 base_mint, 2 quote_mint, 3 base_token_program, 4 quote_token_program,
// 5 bonding_curve (mut, PDA "bonding-curve"), 6 associated_base_bonding_curve (mut), 7 associated_quote_bonding_curve (mut),
// 8 user (signer, mut), 9 associated_base_user (mut), 10 associated_quote_user (mut), 11 user_volume_accumulator (mut),
// 12 fee_config (pfee program), 13 buyback_fee_recipient (mut, must be one of Global's buyback recipients),
// 14 system_program, 15 event_authority, 16 program
pub fn buy_v3(ctx, amount: u64, max_quote_cost: u64, clamp: bool) -> Result<()> {
msg!("Instruction: BuyV3");
let curve = &mut ctx.bonding_curve; // must not be complete, mint/quote must match (fn_076ea / fn_0f4b6)
let mut amount = amount;
let rtr = curve.real_token_reserves;
// pc 281b0..281e3 : clamp / overflow-to-next-curve handling
let mut excess = 0;
if !global.flag_162 && curve.some_key != global.key_0x288 && amount > rtr {
excess = amount - rtr; amount = rtr; // remainder handled by fn_0fad6/fn_0fc10 path (not seen in samples)
}
if clamp && amount >= rtr { amount = rtr; }
require!(amount != 0, BuyZeroAmount /*6020*/); // pc 281e4
require!(amount <= rtr, NotEnoughTokensToBuy /*6021*/); // pc 281ba
// fn_13385 : price (u128 math)
require!(curve.virtual_token_reserves > amount, Overflow/DivisionByZero);
let quote_cost = (amount as u128 * curve.virtual_quote_reserves as u128
/ (curve.virtual_token_reserves - amount) as u128) as u64 + 1;
// fn_0f803 -> fn_13496 / fn_109ae : fee tier picked by market cap = vqr * supply / vtr from fee_config
// (current fee_config: every tier = protocol 95 bps, creator 30 bps); creator fee only if the curve has a creator
let protocol_fee = ceil_div(quote_cost * fees.protocol_bps, 10_000);
let creator_fee = ceil_div(quote_cost * fees.creator_bps, 10_000);
let total = checked_add3(quote_cost, protocol_fee, creator_fee) + extra_fee; // fn_0f885
require!(total <= max_quote_cost, TooMuchSolRequired /*6002*/); // pc 282e7
// fn_0fd9b settle
curve.virtual_token_reserves -= amount; curve.real_token_reserves -= amount; // fn_134f5
curve.virtual_quote_reserves += quote_cost; curve.real_quote_reserves += quote_cost;
token::transfer_checked(associated_base_bonding_curve -> associated_base_user, amount,
signer = ["bonding-curve", base_mint, bump]); // fn_1148a
// fn_136f2
let buyback = if curve.flag_154 { 0 } else { protocol_fee * global.buyback_bps /*5000*/ / 10_000 }; // floor
curve.accrued_protocol_fee /*+120*/ += protocol_fee - buyback;
curve.accrued_creator_fee /*+112*/ += creator_fee;
// fn_1229d : quote transfers from user (system transfer for native SOL, token transfer otherwise)
transfer(user -> bonding_curve, quote_cost + (protocol_fee - buyback) + creator_fee);
transfer(user -> buyback_fee_recipient, buyback);
// fn_11ad5 / fn_1202e : user volume accumulator update
// fn_10150 : emit TradeEvent { mint, sol_amount: quote_cost, token_amount: amount, is_buy: true, user, timestamp,
// reserves, fee_recipient: default, fee_basis_points, fee: protocol_fee, creator, creator_fee_basis_points,
// creator_fee, ..., ix_name: "buy", ..., buyback_bps, buyback_fee, ... }
Ok(())
}

Replay model

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

function model(ctx){
const d=ctx.data; const rd=(o)=>{let v=0n;for(let i=7;i>=0;i--)v=(v<<8n)|BigInt(d[o+i]);return v;};
const amount=rd(8);
const ata=ctx.accounts[6].token.amount;
const RESERVED=1000000000000000n-793100000000000n; // supply - initial real token reserves
const rtr=ata-RESERVED;
const vtr=rtr+(1073000000000000n-793100000000000n);
const k=30000000000n*1073000000000000n;
const vsr=(k+vtr-1n)/vtr;
const S=amount*vsr/(vtr-amount)+1n;
const ceil=(a,b)=>(a+b-1n)/b;
const fee=ceil(S*95n,10000n), cfee=ceil(S*30n,10000n);
const buyback=fee*5000n/10000n;
return {lamports:{5:S+(fee-buyback)+cfee,13:buyback,6:0n,11:0n},tokens:{6:-amount,9:amount}};
}

Accounts

Not published. The accounts and arguments were recovered from the bytecode; see the reconstruction.

program 6EF8rr…BEwF6P