Instruction
sell_v2
Sells `amount` base tokens back into a pump.fun bonding curve. The curve can be priced in SOL or in an SPL quote token (e.g. PUMP). Anyone holding the token can call it. Payout = floor(vQuote·amount/(vToken+amount)), minus a protocol fee (95 bps) and a creator fee (30 bps by default; a per-curve override can raise it, e.g. 100 bps was seen on a PUMP-quoted curve). Both fees come from a CPI to pump's fee program and are rounded up. Unlike sell_v3, all fees are paid out right away: on normal curves Global.buyback_bps (5000) of the protocol fee goes to the buyback recipient and the rest to fee_recipient. On mayhem-mode curves (fee recipient must be one of Global's reserved recipients) all of it goes to fee_recipient. The creator fee goes to creator_vault (or its quote ATA). Fails if the curve is complete (6005), amount is 0 (6022), the seller holds fewer tokens than amount (6023), or the net payout is below min_sol_output (6003).
- Discriminator
- 0x5df6823ce7e940b2
- Calls in the sample
- 63
- Reproduced, seen by the agent
- 9 / 37
- Reproduced, never shown to the agent
- 4 / 25
13 of 62 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.
243ecmov64 r6, r5243edmov64 r9, r4243eemov64 r8, r3243efmov64 r7, r2243f0stxdw [r10-936], r1243f1lddw r1, 0x1ae3da ; "Instruction: SellV2"243f3mov64 r2, 0x13243f4call sol_log_243f5ldxdw r1, [r6-4088]243f6jlt r1, 0x8, +97 ; -> 24458243f7and64 r1, -0x8243f8jeq r1, 0x8, +95 ; -> 24458243f9ldxdw r1, [r6-4096]243faldxdw r2, [r1+0]243fbstxdw [r10-944], r2243fcldxdw r1, [r1+8]243fdstxdw [r10-952], r1243femov64 r1, -0x1243ffstxw [r10-872], r124400stdw [r10-880], -0x124401stxdw [r10-856], r924402stxdw [r10-864], r824403mov64 r1, r1024404add64 r1, -0x37024405stxdw [r10-4088], r124406mov64 r1, r1024407add64 r1, -0x1a824408mov64 r3, r1024409add64 r3, -0x3602440amov64 r5, r102440bmov64 r2, r72440ccall fn_1bfcc2440dldxdw r8, [r10-408]2440eldxdw r6, [r10-416]2440fldxdw r9, [r10-424]24410lddw r1, 0x800000000000000024412jeq r9, r1, +88 ; -> 2446b24413mov64 r1, r1024414add64 r1, -0x33824415mov64 r2, r1024416add64 r2, -0x19024417mov64 r3, 0x19024418call fn_3536724419stxdw [r10-832], r82441astxdw [r10-840], r62441bstxdw [r10-848], r92441cldxdw r1, [r10-880]2441dstxdw [r10-392], r12441eldxw r1, [r10-872]2441fstxw [r10-384], r124420ldxdw r1, [r10-856]24421stxdw [r10-400], r124422ldxdw r1, [r10-864]24423stxdw [r10-408], r124424mov64 r1, r1024425add64 r1, -0x35024426stxdw [r10-416], r124427stxdw [r10-424], r724428mov64 r1, r1024429add64 r1, -0x3802442amov64 r2, r102442badd64 r2, -0x1a82442cldxdw r3, [r10-944]2442dldxdw r4, [r10-952]2442ecall fn_27b252442fldxdw r6, [r10-896]24430jeq r6, 0x2, +1 ; -> 2443224431ja +61 ; -> 2446f24432mov64 r1, r1024433add64 r1, -0x39024434mov64 r2, r1024435add64 r2, -0x35024436mov64 r3, r724437call fn_1cec324438ldxdw r1, [r10-688]24439ldxdw r2, [r10-696]2443aldxdw r3, [r2+0]2443badd64 r3, -0x12443cldxdw r8, [r10-904]2443dldxdw r6, [r10-912]2443estxdw [r2+0], r32443fjne r3, 0x0, +3 ; -> 2444324440ldxdw r3, [r2+8]24441add64 r3, -0x124442stxdw [r2+8], r324443ldxdw r2, [r1+0]24444add64 r2, -0x124445stxdw [r1+0], r224446jne r2, 0x0, +3 ; -> 2444a24447ldxdw r2, [r1+8]24448add64 r2, -0x124449stxdw [r1+8], r22444aldxdw r1, [r10-640]2444bldxdw r2, [r10-648]2444cldxdw r3, [r2+0]2444dadd64 r3, -0x12444estxdw [r2+0], r32444fjne r3, 0x0, +3 ; -> 2445324450ldxdw r3, [r2+8]24451add64 r3, -0x124452stxdw [r2+8], r324453ldxdw r2, [r1+0]24454add64 r2, -0x124455stxdw [r1+0], r224456jne r2, 0x0, +20 ; -> 2446b24457ja +53 ; -> 2448d24458lddw r1, 0x1b3c602445acall fn_33e712445bmov64 r1, r02445cand64 r1, 0x32445dmov64 r2, r12445eadd64 r2, -0x22445fjlt r2, 0x2, +5 ; -> 2446524460jeq r1, 0x0, +4 ; -> 2446524461ldxdw r1, [r0-1]24462ldxdw r2, [r0+7]24463ldxdw r2, [r2+0]24464callx r224465mov64 r1, r1024466add64 r1, -0x3a024467mov64 r2, 0x6624468call fn_32b0924469ldxdw r8, [r10-920]2446aldxdw r6, [r10-928]2446bldxdw r1, [r10-936]2446cstxdw [r1+8], r82446dstxdw [r1+0], r62446eexit2446fldxdw r8, [r10-888]24470ldxdw r1, [r10-688]24471ldxdw r2, [r10-696]24472ldxdw r3, [r2+0]24473add64 r3, -0x124474stxdw [r2+0], r324475jne r3, 0x0, +3 ; -> 2447924476ldxdw r3, [r2+8]24477add64 r3, -0x124478stxdw [r2+8], r324479ldxdw r2, [r1+0]2447aadd64 r2, -0x12447bstxdw [r1+0], r22447cjne r2, 0x0, +3 ; -> 244802447dldxdw r2, [r1+8]2447eadd64 r2, -0x12447fstxdw [r1+8], r224480ldxdw r1, [r10-640]24481ldxdw r2, [r10-648]24482ldxdw r3, [r2+0]24483add64 r3, -0x124484stxdw [r2+0], r324485jne r3, 0x0, +3 ; -> 2448924486ldxdw r3, [r2+8]24487add64 r3, -0x124488stxdw [r2+8], r324489ldxdw r2, [r1+0]2448aadd64 r2, -0x12448bstxdw [r1+0], r22448cjne r2, 0x0, -34 ; -> 2446b2448dldxdw r2, [r1+8]2448eadd64 r2, -0x12448fstxdw [r1+8], r224490ja -38 ; -> 2446b
// Instruction: sell_v2(amount: u64, min_sol_output: u64) disc 5df6823ce7e940b2// handler fn_243ec -> validate accounts (fn_1bfcc) -> sell_v2_logic fn_27b25pub fn sell_v2(ctx: Context<SellV2>, amount: u64, min_sol_output: u64) -> Result<()> {msg!("Instruction: SellV2");let curve = &mut ctx.accounts.bonding_curve; // PDA ["bonding-curve", base_mint]// fn_076ea: curve/global sanity + migration-state checkrequire!(!curve.complete, BondingCurveComplete /*6005*/); // pc 27b3drequire!(amount > 0, ZeroAmount /*6022 0x1786*/); // pc 27b83require!(ctx.accounts.associated_base_user.amount >= amount,InsufficientTokens /*6023 0x1787*/); // pc 27b86// fn_078ef / fn_123fe / fn_029be x4: create-idempotent quote ATAs// (fee recipient, curve, user, creator vault, volume accumulator), payer = user// quote mint must be the curve's quote mint, else error 6063 (0x17af) // pc 27d92// ---- price (fn_1341e, u128) ----let gross = (curve.virtual_quote_reserves as u128 * amount as u128/ (curve.virtual_token_reserves as u128 + amount as u128)) as u64; // floor// ---- fees (fn_10820): CPI pump_fees::GetFeesWithQuoteMint(fee_config, quote_mint, ...) ----let (protocol_bps, mut creator_bps) = fee_program::get_fees_with_quote_mint(...);if global.creator_fee_override_enabled /*byte 1086*/ && curve.creator_fee_bps_override != 0 {creator_bps = curve.creator_fee_bps_override; // e.g. 100 bps seen}let protocol_fee = ceil_div(gross * protocol_bps, 10_000); // fn_107c7 (95 bps observed)let creator_fee = if curve.creator != Pubkey::default() { ceil_div(gross * creator_bps, 10_000) } else { 0 };require!(gross >= protocol_fee + creator_fee, ...); // pc 27df3 / 27e02let net = gross - protocol_fee - creator_fee;require!(net >= min_sol_output, TooLittleSolReceived /*6003 0x1773*/); // pc 27e0f// ---- move base tokens user -> curve (fn_135f3: transfer_checked, user signs) ----token::transfer_checked(associated_base_user -> associated_base_bonding_curve, amount);// ---- reserves update (fn_11594) ----curve.virtual_token_reserves += amount; curve.real_token_reserves += amount;curve.virtual_quote_reserves -= gross; curve.real_quote_reserves -= gross;// ---- payouts ----// quote == native SOL (wSOL mint): lamports debited directly from bonding_curve// other quote mint: transfer_checked from associated_quote_bonding_curve, curve PDA signs (fn_137f5)pay(user, net); // fn_12780if protocol_fee > 0 { // pc 27e61if !curve.is_mayhem_mode /* curve byte 163 */ {let buyback = protocol_fee * global.buyback_bps /*5000*/ / 10_000; // floor, fn_073f3pay(buyback_fee_recipient /*or its quote ATA*/, buyback); // fn_12196pay(fee_recipient /*or quote ATA*/, protocol_fee - buyback);} else {// mayhem: fee_recipient must be a Global reserved fee recipient; no buyback splitpay(fee_recipient, protocol_fee); // fn_12196 + fn_0f055}}pay(creator_vault /*or associated_creator_vault*/, creator_fee); // fn_12120 / fn_12227// volume tracking: user_volume_accumulator updated if track_volume (fn_10d03)emit!(TradeEvent { mint, sol_amount: gross, 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: protocol_bps, fee: protocol_fee, creator, creator_fee_basis_points,creator_fee, ix_name: "sell", mayhem_mode, buyback_fee_basis_points, buyback_fee, .. });Ok(())}
Replay model
The executable model the agent wrote. Every tally above comes from running it against mainnet.
const ALPH='123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';function b58hex(s){let n=0n;for(const c of s){n=n*58n+BigInt(ALPH.indexOf(c));}let h=n.toString(16);while(h.length<64)h='0'+h;return h;}const RESERVED=new Set(['e893141fb18e9f1574d810e178e19e30604e3175aa2e4a32dfc8600727d10709','3584536256094f912819127efa4e446b4333721793d13876f9aadbf3dc7d0b5f','6e75018220f942677003237b4d6b453759b4a5c690b59c35d9bb187a090cbd2a','33987a9ebb136799ab59925b13e5dc8b3081df005db427c1478fa46ff8c347a0','74e9543f3e37a2d046227addcb4e9c774c44258c43edf24aa8aae1f00214665b','da4c38cd6db7438f59b408bb9ec3b4ca9e8ad1f1f24653c499b5796c20dbf9b3','2ddd9eea3f39b372115c71847c1845cfa536c685074e030e44d021de3ef9e35c','4cb780f08ee2fee84bec446a577825da68d439fa8a5da3b0c5cff50f63f4546b']);const WSOL='So11111111111111111111111111111111111111112';const RENT=1493520n, VSOL0=30000000000n, VTOK0=1073000000000000n, TOKOFF=73000000000000n;const K0=VSOL0*VTOK0;function cdiv(a,b){return (a+b-1n)/b;}function model(ctx){const by={}; for(const a of ctx.accounts) by[a.name]=a;const amount=BigInt(ctx.args.amount);const vtok=by.associated_base_bonding_curve.token.amount+TOKOFF;const isSol=by.quote_mint.pubkey===WSOL;const mayhem=RESERVED.has(b58hex(by.fee_recipient.pubkey));let vsol;if(isSol){const vA=by.bonding_curve.lamports-RENT+VSOL0; // exact if no fees accrued in curveconst vB=cdiv(K0,vtok); // k only grows -> lower boundconst band=vB/20000000n; // ~5e-8 drift allowanceif(mayhem || (vA>=vB && vA-vB<=band)) vsol=vA; else vsol=vB+vB/100000000n;} else {vsol=by.associated_quote_bonding_curve.token.amount+VSOL0;}const gross=vsol*amount/(vtok+amount);const cbps = 30n;const prot=cdiv(gross*95n,10000n), cre=cdiv(gross*cbps,10000n);const bb = mayhem?0n:prot*5000n/10000n;const fr=prot-bb;const L={},T={};T.associated_base_bonding_curve=amount; T.associated_base_user=-amount;if(isSol){ L.bonding_curve=-gross; L.fee_recipient=fr; L.buyback_fee_recipient=bb; L.creator_vault=cre; }else { T.associated_quote_bonding_curve=-gross; T.associated_quote_fee_recipient=fr; T.associated_quote_buyback_fee_recipient=bb; T.associated_creator_vault=cre; T.associated_quote_user=gross-prot-cre; }return {lamports:L,tokens:T};}
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
- 19user_volume_accumulatorwritten
- 20associated_user_volume_accumulatorwritten
- 21fee_config
- 22fee_program
- 23system_program
- 24event_authority
- 25program
args: amount: u64, min_sol_output: u64
program 6EF8rr…BEwF6P