debpf
pump.fun / instructions

Instruction

sweep_protocol_fee

DecompiledHidden

Hidden instruction, not in the public IDL. It pays out the protocol fee that v3 buys and sells leave sitting inside a bonding curve. Anyone can submit it and there are no arguments, but the money can only go to an approved recipient stored in Global: the main fee_recipient or one of the 7 fee_recipients, or for mayhem-mode curves one of the 8 reserved recipients. Any other recipient fails with error 6000. The full accrued amount is set to zero and sent as SOL straight from the curve's lamports, or for token-quoted curves as a PDA-signed transfer_checked from the curve's quote ATA. If those ATAs don't exist, the caller pays rent to create them, and also pays rent if the curve account must be grown to 166 bytes. If nothing has accrued, it only writes a log line.

Discriminator
0x0830be07b644b7e5
Calls in the sample
0
Reproduced, seen by the agent
—
Reproduced, never shown to the agent
—
Bytecodefn_2472e
2472emov64 r8, r4
2472fmov64 r9, r3
24730mov64 r7, r2
24731stxdw [r10-448], r1
24732lddw r1, 0x1ae44e ; "Instruction: SweepProtocolFee"
24734mov64 r2, 0x1d
24735call sol_log_
24736mov64 r1, -0x1
24737stxb [r10-388], r1
24738stxw [r10-392], r1
24739stxdw [r10-376], r8
2473astxdw [r10-384], r9
2473bmov64 r1, r10
2473cadd64 r1, -0x188
2473dstxdw [r10-4088], r1
2473emov64 r1, r10
2473fadd64 r1, -0xb8
24740mov64 r3, r10
24741add64 r3, -0x180
24742mov64 r5, r10
24743mov64 r2, r7
24744call fn_1d135
24745ldxdw r9, [r10-176]
24746ldxdw r8, [r10-184]
24747ldxb r6, [r10-6]
24748jeq r6, 0x2, +116 ; -> 247bd
24749mov64 r1, r10
2474aadd64 r1, -0x160
2474bmov64 r2, r10
2474cadd64 r2, -0xa8
2474dmov64 r3, 0xa2
2474ecall fn_35367
2474fldxw r1, [r10-5]
24750stxw [r10-189], r1
24751ldxb r1, [r10-1]
24752stxb [r10-185], r1
24753stxb [r10-190], r6
24754stxdw [r10-360], r9
24755stxdw [r10-368], r8
24756ldxw r1, [r10-392]
24757stxw [r10-152], r1
24758ldxb r1, [r10-388]
24759stxb [r10-148], r1
2475aldxdw r1, [r10-376]
2475bstxdw [r10-160], r1
2475cldxdw r1, [r10-384]
2475dstxdw [r10-168], r1
2475emov64 r1, r10
2475fadd64 r1, -0x170
24760stxdw [r10-176], r1
24761stxdw [r10-184], r7
24762mov64 r1, r10
24763add64 r1, -0x198
24764mov64 r2, r10
24765add64 r2, -0xb8
24766mov64 r3, 0x0
24767call fn_0dda2
24768ldxdw r8, [r10-408]
24769jeq r8, 0x2, +1 ; -> 2476b
2476aja +49 ; -> 2479c
2476bldxdw r2, [r10-312]
2476cmov64 r1, r10
2476dadd64 r1, -0x1a8
2476elddw r3, 0x1adff9
24770mov64 r4, r7
24771call fn_00bc8
24772mov64 r8, 0x2
24773ldxdw r2, [r10-424]
24774jeq r2, 0x2, +9 ; -> 2477e
24775ldxdw r3, [r10-416]
24776mov64 r1, r10
24777add64 r1, -0x1b8
24778lddw r4, 0x1ad9f2 ; "bonding_curve"
2477amov64 r5, 0xd
2477bcall fn_005a9
2477cldxdw r9, [r10-432]
2477dldxdw r8, [r10-440]
2477eldxdw r1, [r10-264]
2477fldxdw r2, [r10-272]
24780ldxdw r3, [r2+0]
24781add64 r3, -0x1
24782stxdw [r2+0], r3
24783jne r3, 0x0, +3 ; -> 24787
24784ldxdw r3, [r2+8]
24785add64 r3, -0x1
24786stxdw [r2+8], r3
24787ldxdw r2, [r1+0]
24788add64 r2, -0x1
24789stxdw [r1+0], r2
2478ajne r2, 0x0, +3 ; -> 2478e
2478bldxdw r2, [r1+8]
2478cadd64 r2, -0x1
2478dstxdw [r1+8], r2
2478eldxdw r1, [r10-216]
2478fldxdw r2, [r10-224]
24790ldxdw r3, [r2+0]
24791add64 r3, -0x1
24792stxdw [r2+0], r3
24793jne r3, 0x0, +3 ; -> 24797
24794ldxdw r3, [r2+8]
24795add64 r3, -0x1
24796stxdw [r2+8], r3
24797ldxdw r2, [r1+0]
24798add64 r2, -0x1
24799stxdw [r1+0], r2
2479ajne r2, 0x0, +34 ; -> 247bd
2479bja +30 ; -> 247ba
2479cldxdw r9, [r10-400]
2479dldxdw r1, [r10-264]
2479eldxdw r2, [r10-272]
2479fldxdw r3, [r2+0]
247a0add64 r3, -0x1
247a1stxdw [r2+0], r3
247a2jne r3, 0x0, +3 ; -> 247a6
247a3ldxdw r3, [r2+8]
247a4add64 r3, -0x1
247a5stxdw [r2+8], r3
247a6ldxdw r2, [r1+0]
247a7add64 r2, -0x1
247a8stxdw [r1+0], r2
247a9jne r2, 0x0, +3 ; -> 247ad
247aaldxdw r2, [r1+8]
247abadd64 r2, -0x1
247acstxdw [r1+8], r2
247adldxdw r1, [r10-216]
247aeldxdw r2, [r10-224]
247afldxdw r3, [r2+0]
247b0add64 r3, -0x1
247b1stxdw [r2+0], r3
247b2jne r3, 0x0, +3 ; -> 247b6
247b3ldxdw r3, [r2+8]
247b4add64 r3, -0x1
247b5stxdw [r2+8], r3
247b6ldxdw r2, [r1+0]
247b7add64 r2, -0x1
247b8stxdw [r1+0], r2
247b9jne r2, 0x0, +3 ; -> 247bd
247baldxdw r2, [r1+8]
247bbadd64 r2, -0x1
247bcstxdw [r1+8], r2
247bdldxdw r1, [r10-448]
247bestxdw [r1+8], r9
247bfstxdw [r1+0], r8
247c0exit
Reconstructedsweep_protocol_fee
// discriminator 0830be07b644b7e5 (hidden: not in the public IDL)
// handler fn_2472e -> SweepFees::try_accounts (fn_1d135) -> sweep_fees(ctx, is_creator=false) (fn_0dda2)
// No instruction arguments.
#[derive(Accounts)]
pub struct SweepFees<'info> {
#[account(mut)] payer: Signer<'info>, // ConstraintMut(2000) "payer"
#[account(seeds=[b"global"], bump)] global: Account<Global>, // ConstraintSeeds(2006)
base_mint: InterfaceAccount<Mint>,
quote_mint: InterfaceAccount<Mint>,
quote_token_program: Interface<TokenInterface>,
associated_token_program: Program<AssociatedToken>,
system_program: Program<System>,
#[account(mut, seeds=[b"bonding-curve", base_mint.key()], bump,
// pc 1d39c..1d3d3: curve must be quoted in this quote_mint, or (legacy SOL curve)
// curve.quote_mint == Pubkey::default() AND quote_mint == <const @0x1ac310, presumably the wSOL mint>
constraint = bonding_curve.quote_mint == quote_mint.key()
|| (bonding_curve.quote_mint == Pubkey::default() && quote_mint.key() == NATIVE_MINT))]
bonding_curve: Box<Account<BondingCurve>>,
#[account(mut, address = get_associated_token_address_with_program_id(
bonding_curve.key(), quote_mint.key(), quote_token_program.key()))] // ConstraintSeeds
associated_quote_bonding_curve: UncheckedAccount<'info>,
#[account(mut)] recipient: UncheckedAccount<'info>,
#[account(mut, address = ata(recipient, quote_mint, quote_token_program))]
associated_quote_recipient: UncheckedAccount<'info>,
#[account(seeds=[b"__event_authority"], bump)] event_authority: UncheckedAccount<'info>,
program: Program<Pump>,
}
pub fn sweep_protocol_fee(ctx: Context<SweepFees>) -> Result<()> {
msg!("Instruction: SweepProtocolFee");
sweep_fees(ctx, /*is_creator=*/ false)
}
// programs/pump/src/sweep_fees.rs
fn sweep_fees(ctx: Context<SweepFees>, is_creator: bool) -> Result<()> {
let a = ctx.accounts;
// fn_076ea: grow bonding curve account to >= 166 (0xa6) bytes; payer funds extra rent via system_program
ensure_account_len(&a.bonding_curve, 166, &a.payer, &a.system_program)?;
// pc dda0..ddc8
require!(a.recipient.key() != Pubkey::default(), Error(6000)); // sweep_fees.rs:123
// is_creator == false -> pc de66
// fn_078ef (fee_recipient.rs): recipient must be an authorised protocol fee recipient
if !a.bonding_curve.is_mayhem_mode {
require!(a.recipient.key() == global.fee_recipient
|| global.fee_recipients[0..7].binary_search(&a.recipient.key()).is_ok(),
Error(6000)); // fee_recipient.rs:35
} else {
require!(global.reserved_fee_recipients[0..8].contains(&a.recipient.key()), Error(6000));
}
// pc de6f: take and clear the accrued protocol fee
let amount = a.bonding_curve.protocol_fee_accrued; // in-memory field @+128
a.bonding_curve.protocol_fee_accrued = 0;
if amount == 0 { // pc de72 -> dedc
msg!(<"nothing to sweep" message, formats is_creator>);
return Ok(());
}
let is_native = a.bonding_curve.quote_mint == Pubkey::default(); // pc de7e
if is_native {
// pc e00d -> fn_12196 -> fn_1202e: direct lamport move (curve is program-owned)
**bonding_curve.lamports -= amount; // InsufficientFunds if curve lamports < amount
**recipient.lamports += amount; // checked add
} else {
// pc de82..dfc2: fn_029be x2 = create-idempotent the two quote ATAs, payer pays rent
create_ata_idempotent(payer, associated_quote_bonding_curve, bonding_curve, quote_mint, quote_token_program)?;
create_ata_idempotent(payer, associated_quote_recipient, recipient, quote_mint, quote_token_program)?;
// fn_12196 -> fn_119af: token transfer_checked signed by bonding curve PDA
transfer_checked(
CpiContext::new_with_signer(quote_token_program,
TransferChecked { from: associated_quote_bonding_curve, mint: quote_mint,
to: associated_quote_recipient, authority: bonding_curve },
&[&[b"bonding-curve", base_mint.key().as_ref(), &[bump]]]),
amount, quote_mint.decimals)?;
}
// pc e0ad..e143: emit_cpi! via event_authority (self-CPI)
emit_cpi!(SweepFeeEvent {
base_mint, bonding_curve, recipient, amount, is_creator: false,
timestamp: Clock::get()?.unix_timestamp, /* exact field order not verified */
});
Ok(())
}

Replay model

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

// no model entered yet

Accounts

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

program 6EF8rr…BEwF6P