debpf
pump.fun / instructions

Instruction

sell

Partly proven

Sells `amount` of a pump.fun token back into its bonding curve for SOL. Anyone holding the token can call it. The SOL comes straight out of the curve account. The price is the constant-product quote floor(vSOL·amount/(vTOKEN+amount)). From that, a 0.95% protocol fee and a 0.30% creator fee are taken, both rounded up; the rates come from a CPI to pump's fee program. Half the protocol fee (Global.buyback_bps = 5000, rounded down) goes to a buyback recipient passed as an extra account. The other half goes to fee_recipient, and the creator fee goes to creator_vault. One exception: when the seller is Global.whitelist_pda (a PDA that pump's admin sets), every fee is skipped and it gets the full gross amount. The sell fails if the curve has already completed or migrated (6005), if amount is 0 (6022), if you hold fewer tokens than amount (6023), or if the net SOL is below min_sol_output (6003).

Discriminator
0x33e685a4017f83ad
Calls in the sample
91
Reproduced, seen by the agent
1 / 64
Reproduced, never shown to the agent
3 / 27

4 of 91 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_24a0e
24a0emov64 r6, r5
24a0fmov64 r9, r4
24a10mov64 r8, r3
24a11mov64 r7, r2
24a12stxdw [r10-2128], r1
24a13lddw r1, 0x1ae4a1 ; "Instruction: Sell"
24a15mov64 r2, 0x11
24a16call sol_log_
24a17ldxdw r1, [r6-4088]
24a18jlt r1, 0x8, +97 ; -> 24a7a
24a19and64 r1, -0x8
24a1ajeq r1, 0x8, +95 ; -> 24a7a
24a1bldxdw r1, [r6-4096]
24a1cldxdw r2, [r1+0]
24a1dstxdw [r10-2136], r2
24a1eldxdw r1, [r1+8]
24a1fstxdw [r10-2144], r1
24a20mov64 r1, -0x1
24a21stxb [r10-2068], r1
24a22stxw [r10-2072], r1
24a23stxdw [r10-2056], r9
24a24stxdw [r10-2064], r8
24a25mov64 r1, r10
24a26add64 r1, -0x818
24a27stxdw [r10-4088], r1
24a28mov64 r1, r10
24a29add64 r1, -0x400
24a2amov64 r3, r10
24a2badd64 r3, -0x810
24a2cmov64 r5, r10
24a2dmov64 r2, r7
24a2ecall fn_2d927
24a2fldxdw r8, [r10-1008]
24a30ldxdw r6, [r10-1016]
24a31ldxdw r9, [r10-1024]
24a32lddw r1, 0x8000000000000000
24a34jeq r9, r1, +88 ; -> 24a8d
24a35mov64 r1, r10
24a36add64 r1, -0x7e8
24a37mov64 r2, r10
24a38add64 r2, -0x3e8
24a39mov64 r3, 0x3e8
24a3acall fn_35367
24a3bstxdw [r10-2032], r8
24a3cstxdw [r10-2040], r6
24a3dstxdw [r10-2048], r9
24a3eldxw r1, [r10-2072]
24a3fstxw [r10-992], r1
24a40ldxb r1, [r10-2068]
24a41stxb [r10-988], r1
24a42ldxdw r1, [r10-2056]
24a43stxdw [r10-1000], r1
24a44ldxdw r1, [r10-2064]
24a45stxdw [r10-1008], r1
24a46mov64 r1, r10
24a47add64 r1, -0x800
24a48stxdw [r10-1016], r1
24a49stxdw [r10-1024], r7
24a4amov64 r1, r10
24a4badd64 r1, -0x828
24a4cmov64 r2, r10
24a4dadd64 r2, -0x400
24a4eldxdw r3, [r10-2136]
24a4fldxdw r4, [r10-2144]
24a50call fn_295ee
24a51ldxdw r6, [r10-2088]
24a52jeq r6, 0x2, +1 ; -> 24a54
24a53ja +61 ; -> 24a91
24a54mov64 r1, r10
24a55add64 r1, -0x838
24a56mov64 r2, r10
24a57add64 r2, -0x800
24a58mov64 r3, r7
24a59call fn_2deaa
24a5aldxdw r1, [r10-1328]
24a5bldxdw r2, [r10-1336]
24a5cldxdw r3, [r2+0]
24a5dadd64 r3, -0x1
24a5eldxdw r8, [r10-2096]
24a5fldxdw r6, [r10-2104]
24a60stxdw [r2+0], r3
24a61jne r3, 0x0, +3 ; -> 24a65
24a62ldxdw r3, [r2+8]
24a63add64 r3, -0x1
24a64stxdw [r2+8], r3
24a65ldxdw r2, [r1+0]
24a66add64 r2, -0x1
24a67stxdw [r1+0], r2
24a68jne r2, 0x0, +3 ; -> 24a6c
24a69ldxdw r2, [r1+8]
24a6aadd64 r2, -0x1
24a6bstxdw [r1+8], r2
24a6cldxdw r1, [r10-1280]
24a6dldxdw r2, [r10-1288]
24a6eldxdw r3, [r2+0]
24a6fadd64 r3, -0x1
24a70stxdw [r2+0], r3
24a71jne r3, 0x0, +3 ; -> 24a75
24a72ldxdw r3, [r2+8]
24a73add64 r3, -0x1
24a74stxdw [r2+8], r3
24a75ldxdw r2, [r1+0]
24a76add64 r2, -0x1
24a77stxdw [r1+0], r2
24a78jne r2, 0x0, +20 ; -> 24a8d
24a79ja +53 ; -> 24aaf
24a7alddw r1, 0x1b3c60
24a7ccall fn_33e71
24a7dmov64 r1, r0
24a7eand64 r1, 0x3
24a7fmov64 r2, r1
24a80add64 r2, -0x2
24a81jlt r2, 0x2, +5 ; -> 24a87
24a82jeq r1, 0x0, +4 ; -> 24a87
24a83ldxdw r1, [r0-1]
24a84ldxdw r2, [r0+7]
24a85ldxdw r2, [r2+0]
24a86callx r2
24a87mov64 r1, r10
24a88add64 r1, -0x848
24a89mov64 r2, 0x66
24a8acall fn_32b09
24a8bldxdw r8, [r10-2112]
24a8cldxdw r6, [r10-2120]
24a8dldxdw r1, [r10-2128]
24a8estxdw [r1+8], r8
24a8fstxdw [r1+0], r6
24a90exit
24a91ldxdw r8, [r10-2080]
24a92ldxdw r1, [r10-1328]
24a93ldxdw r2, [r10-1336]
24a94ldxdw r3, [r2+0]
24a95add64 r3, -0x1
24a96stxdw [r2+0], r3
24a97jne r3, 0x0, +3 ; -> 24a9b
24a98ldxdw r3, [r2+8]
24a99add64 r3, -0x1
24a9astxdw [r2+8], r3
24a9bldxdw r2, [r1+0]
24a9cadd64 r2, -0x1
24a9dstxdw [r1+0], r2
24a9ejne r2, 0x0, +3 ; -> 24aa2
24a9fldxdw r2, [r1+8]
24aa0add64 r2, -0x1
24aa1stxdw [r1+8], r2
24aa2ldxdw r1, [r10-1280]
24aa3ldxdw r2, [r10-1288]
24aa4ldxdw r3, [r2+0]
24aa5add64 r3, -0x1
24aa6stxdw [r2+0], r3
24aa7jne r3, 0x0, +3 ; -> 24aab
24aa8ldxdw r3, [r2+8]
24aa9add64 r3, -0x1
24aaastxdw [r2+8], r3
24aabldxdw r2, [r1+0]
24aacadd64 r2, -0x1
24aadstxdw [r1+0], r2
24aaejne r2, 0x0, -34 ; -> 24a8d
24aafldxdw r2, [r1+8]
24ab0add64 r2, -0x1
24ab1stxdw [r1+8], r2
24ab2ja -38 ; -> 24a8d
Reconstructedsell
// discriminator 33e685a4017f83ad — handler fn_24a0e -> sell_logic fn_295ee
pub fn sell(ctx: Context<Sell>, amount: u64, min_sol_output: u64) -> Result<()> {
msg!("Instruction: Sell");
// fn_2d927 (Anchor try_accounts): global PDA, bonding_curve PDA ["bonding-curve", mint],
// associated_bonding_curve = ATA(bonding_curve, mint), associated_user owned by user,
// creator_vault PDA ["creator-vault", bonding_curve.creator], event_authority, fee_config/fee_program.
ensure_curve_size_166(&ctx.bonding_curve)?; // fn_076ea: realloc to >=166 bytes
validate_fee_recipient(&ctx.fee_recipient, &global, &curve)?; // fn_078ef
// !curve.is_mayhem_mode -> fee_recipient ∈ {global.fee_recipient} ∪ global.fee_recipients[7]
// curve.is_mayhem_mode -> fee_recipient ∈ {global.reserved_fee_recipient} ∪ global.reserved_fee_recipients[7]
let curve = &mut ctx.bonding_curve;
require!(!curve.complete, BondingCurveComplete /*6005*/); // pc 2960f
require!(amount != 0, SellZeroAmount /*6022*/); // pc 29658
require!(ctx.associated_user.amount >= amount, NotEnoughTokensToSell /*6023*/); // pc 29659
// fn_1341e: u128 math, floor
let denom = curve.virtual_token_reserves.checked_add(amount)?; // 6026 if 0
let gross_sol = (curve.virtual_sol_reserves as u128 * amount as u128 / denom as u128) as u64;
// fn_10820: CPI fee_program "GetFeesWithQuoteMint"(fee_config, mint/curve state) -> {lp_bps, protocol_bps, creator_bps}
// (current fee_config 8Wf5TiAh…: flat 0 / 95 / 30 bps, single tier)
let mut creator_bps = ret.creator_bps;
if global.creator_fee_override_enabled /*Global byte @1086*/ && curve.creator_fee_bps_override != 0 {
creator_bps = curve.creator_fee_bps_override;
}
let mut protocol_fee = ceil_div(gross_sol as u128 * ret.protocol_bps, 10_000); // fn_107c7
let mut creator_fee = if curve.creator == Pubkey::default() { 0 }
else { ceil_div(gross_sol as u128 * creator_bps, 10_000) };
// pc 29714: fee exemption for the whitelisted router PDA
if ctx.user.key == global.whitelist_pda { // Global borsh offset 451 (BwWK17cb…)
protocol_fee = 0; creator_fee = 0; /* bps reported as 0 too */
}
let after_protocol = gross_sol.checked_sub(protocol_fee)?; // 29a53
let net_sol = after_protocol.checked_sub(creator_fee)?; // 29a94
require!(net_sol >= min_sol_output, TooLittleSolReceived /*6003*/); // pc 29737
// reserve updates (all checked)
curve.virtual_token_reserves += amount; // 6024 on overflow
curve.real_token_reserves += amount;
curve.virtual_sol_reserves -= gross_sol;
curve.real_sol_reserves -= gross_sol; // error if real_sol_reserves < gross_sol
// fn_1179d: token CPI transfer_checked(associated_user -> associated_bonding_curve, amount, authority=user)
if ctx.user.key != global.whitelist_pda {
if creator_fee > 0 {
if !curve.fee_sharing_flag /*byte 963*/ {
move_lamports(curve -> creator_vault, creator_fee); // fn_11fc7
} else {
// fn_0d290: creator fee routed through the fee-sharing path (not seen in samples)
}
}
// cashback flag (curve byte 965) only changes the event fields here
}
move_lamports_from_curve(curve -> user, net_sol); // fn_11ef2
if protocol_fee > 0 {
// fn_12780
let buyback = if curve.is_mayhem_mode { 0 }
else { protocol_fee * global.buyback_bps /*5000*/ / 10_000 }; // floor
if buyback > 0 {
let r = get_buyback_recipient(remaining_accounts)?; // fn_0d75e; 6062 if missing; must be in Global buyback list
move_lamports_from_curve(curve -> r, buyback); // fn_11f5e
}
move_lamports_from_curve(curve -> fee_recipient, protocol_fee - buyback); // fee_recipient gets the rounding-up half
}
emit_cpi!(TradeEvent { mint, sol_amount: gross_sol, token_amount: amount, is_buy: false, user,
timestamp, virtual_sol_reserves, virtual_token_reserves, real_sol_reserves, real_token_reserves,
fee_recipient, fee_basis_points, fee: protocol_fee, creator, creator_fee_basis_points, creator_fee,
ix_name: "sell", buyback_fee, ... });
Ok(())
}

Replay model

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

function rd(d,o){let x=0n;for(let i=7;i>=0;i--)x=(x<<8n)|BigInt(d[o+i]);return x;}
const WHITELIST="BwWK17cbHxwWBKZkUYvzxLcNQ1YVyaFezduWbtm2de6s"; // Global.whitelist_pda
function model(ctx){
const A=ctx.accounts, d=ctx.data;
const amount=rd(d,8);
const ata=A[4].token.amount;
const vtok=ata+73000000000000n;
const k=30000000000n*1073000000000000n;
const vsol=(k+vtok-1n)/vtok;
const gross=vsol*amount/(vtok+amount);
const ceil=(a,b)=>(a+b-1n)/b;
const out={lamports:{},tokens:{}};
out.tokens[4]=amount; out.tokens[5]=-amount;
const user=A[6];
if(user.pubkey===WHITELIST){ out.lamports[3]=-gross; out.lamports[6]=gross; out.lamports[1]=0n; out.lamports[8]=0n; return out; }
const prot=ceil(gross*95n,10000n), cre=ceil(gross*30n,10000n);
const buyback=prot*5000n/10000n;
out.lamports[3]=-gross; out.lamports[1]=prot-buyback; out.lamports[8]=cre;
if(A.length>15) out.lamports[15]=buyback;
if(!user.signer) out.lamports[6]=gross-prot-cre;
return out;
}

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. 8creator_vaultwritten
  10. 9token_program
  11. 10event_authority
  12. 11program
  13. 12fee_config
  14. 13fee_program

args: amount: u64, min_sol_output: u64

program 6EF8rr…BEwF6P