debpf
pump.fun / instructions

Instruction

close_user_volume_accumulator

Decompiled

Lets a user close their own UserVolumeAccumulator PDA (seeds ["user_volume_accumulator", user]) and get its rent-exempt lamports back. Only the wallet the PDA is derived from can do it, because it has to sign and the seeds are checked. There are no fees and no admin involvement. The program never checks that unclaimed rewards are zero: whatever is recorded (total unclaimed tokens, current SOL volume) is lost when the account closes. Those values only show up in the emitted event.

Discriminator
0xf945a4da9667548a
Calls in the sample
5
Reproduced, seen by the agent
—
Reproduced, never shown to the agent
—
Bytecodefn_25325
25325mov64 r8, r4
25326mov64 r9, r3
25327mov64 r7, r2
25328stxdw [r10-496], r1
25329lddw r1, 0x1ae626 ; "Instruction: CloseUserVolumeAccumulator"
2532bmov64 r2, 0x27
2532ccall sol_log_
2532dsth [r10-450], 0xffff
2532estxdw [r10-440], r8
2532fstxdw [r10-448], r9
25330mov64 r1, r10
25331add64 r1, -0x1c2
25332stxdw [r10-4088], r1
25333mov64 r1, r10
25334add64 r1, -0xd8
25335mov64 r3, r10
25336add64 r3, -0x1c0
25337mov64 r5, r10
25338mov64 r2, r7
25339call fn_1ea08
2533aldxdw r9, [r10-208]
2533bldxdw r8, [r10-216]
2533cldxb r6, [r10-6]
2533djeq r6, 0x2, +103 ; -> 253a5
2533emov64 r1, r10
2533fadd64 r1, -0x1a0
25340mov64 r2, r10
25341add64 r2, -0xc8
25342mov64 r3, 0xc2
25343call fn_35367
25344ldxw r1, [r10-5]
25345stxw [r10-221], r1
25346ldxb r1, [r10-1]
25347stxb [r10-217], r1
25348stxb [r10-222], r6
25349stxdw [r10-424], r9
2534astxdw [r10-432], r8
2534bldxb r1, [r10-449]
2534cstxb [r10-183], r1
2534dldxb r1, [r10-450]
2534estxb [r10-184], r1
2534fldxdw r1, [r10-440]
25350stxdw [r10-192], r1
25351ldxdw r1, [r10-448]
25352stxdw [r10-200], r1
25353mov64 r1, r10
25354add64 r1, -0x1b0
25355stxdw [r10-208], r1
25356stxdw [r10-216], r7
25357mov64 r1, r10
25358add64 r1, -0x1d8
25359mov64 r2, r10
2535aadd64 r2, -0xd8
2535bcall fn_0ec18
2535cldxdw r8, [r10-472]
2535djeq r8, 0x2, +1 ; -> 2535f
2535eja +37 ; -> 25384
2535fmov64 r1, r10
25360add64 r1, -0x1e8
25361mov64 r2, r10
25362add64 r2, -0x1b0
25363call fn_1ec03
25364ldxdw r1, [r10-296]
25365ldxdw r2, [r10-304]
25366ldxdw r3, [r2+0]
25367add64 r3, -0x1
25368ldxdw r9, [r10-480]
25369ldxdw r8, [r10-488]
2536astxdw [r2+0], r3
2536bjne r3, 0x0, +3 ; -> 2536f
2536cldxdw r3, [r2+8]
2536dadd64 r3, -0x1
2536estxdw [r2+8], r3
2536fldxdw r2, [r1+0]
25370add64 r2, -0x1
25371stxdw [r1+0], r2
25372jne r2, 0x0, +3 ; -> 25376
25373ldxdw r2, [r1+8]
25374add64 r2, -0x1
25375stxdw [r1+8], r2
25376ldxdw r1, [r10-248]
25377ldxdw r2, [r10-256]
25378ldxdw r3, [r2+0]
25379add64 r3, -0x1
2537astxdw [r2+0], r3
2537bjne r3, 0x0, +3 ; -> 2537f
2537cldxdw r3, [r2+8]
2537dadd64 r3, -0x1
2537estxdw [r2+8], r3
2537fldxdw r2, [r1+0]
25380add64 r2, -0x1
25381stxdw [r1+0], r2
25382jne r2, 0x0, +34 ; -> 253a5
25383ja +30 ; -> 253a2
25384ldxdw r9, [r10-464]
25385ldxdw r1, [r10-296]
25386ldxdw r2, [r10-304]
25387ldxdw r3, [r2+0]
25388add64 r3, -0x1
25389stxdw [r2+0], r3
2538ajne r3, 0x0, +3 ; -> 2538e
2538bldxdw r3, [r2+8]
2538cadd64 r3, -0x1
2538dstxdw [r2+8], r3
2538eldxdw r2, [r1+0]
2538fadd64 r2, -0x1
25390stxdw [r1+0], r2
25391jne r2, 0x0, +3 ; -> 25395
25392ldxdw r2, [r1+8]
25393add64 r2, -0x1
25394stxdw [r1+8], r2
25395ldxdw r1, [r10-248]
25396ldxdw r2, [r10-256]
25397ldxdw r3, [r2+0]
25398add64 r3, -0x1
25399stxdw [r2+0], r3
2539ajne r3, 0x0, +3 ; -> 2539e
2539bldxdw r3, [r2+8]
2539cadd64 r3, -0x1
2539dstxdw [r2+8], r3
2539eldxdw r2, [r1+0]
2539fadd64 r2, -0x1
253a0stxdw [r1+0], r2
253a1jne r2, 0x0, +3 ; -> 253a5
253a2ldxdw r2, [r1+8]
253a3add64 r2, -0x1
253a4stxdw [r1+8], r2
253a5ldxdw r1, [r10-496]
253a6stxdw [r1+8], r9
253a7stxdw [r1+0], r8
253a8exit
Reconstructedclose_user_volume_accumulator
// discriminator f945a4da9667548a
#[derive(Accounts)]
#[event_cpi] // adds event_authority + program
pub struct CloseUserVolumeAccumulator<'info> {
#[account(mut)] // 2000 ConstraintMut "user" (pc 1eb17)
pub user: Signer<'info>, // signer check in fn_02590
#[account(
mut, // 2000 ConstraintMut (pc 1ebb5)
seeds = [b"user_volume_accumulator", user.key().as_ref()],
bump, // find_program_address, 2006 ConstraintSeeds (pc 1eac9)
close = user // 2011 ConstraintClose if accumulator == user (pc 1ebc4)
)]
pub user_volume_accumulator: Account<'info, UserVolumeAccumulator>, // owner==program (3007), initialized (3012), discriminator
// event_authority: PDA ["__event_authority"] -> 2006 ConstraintSeeds (pc 1eb8e)
// program: must be this program id
}
pub fn close_user_volume_accumulator(ctx: Context<CloseUserVolumeAccumulator>) -> Result<()> {
msg!("Instruction: CloseUserVolumeAccumulator");
let acc = &ctx.accounts.user_volume_accumulator;
let clock = Clock::get()?; // fn_32dcc
// emit_cpi!: self-CPI signed by __event_authority, data = EVENT_IX_TAG(e4 45 a5 2e 51 cb 9a 1d) ++ event
emit_cpi!(CloseUserVolumeAccumulatorEvent { // event disc 929fbdac925838f4
user: ctx.accounts.user.key(),
timestamp: clock.unix_timestamp,
// the accumulator's four u64/i64 fields, copied as stored
// (struct offsets +48,+56,+64,+72; per the IDL these are total_unclaimed_tokens,
// total_claimed_tokens, current_sol_volume, last_update_timestamp)
total_unclaimed_tokens: acc.total_unclaimed_tokens,
total_claimed_tokens: acc.total_claimed_tokens,
current_sol_volume: acc.current_sol_volume,
last_update_timestamp: acc.last_update_timestamp,
});
Ok(())
// exit (fn_1ec03 -> fn_32372), Anchor `close = user`:
// user.lamports += accumulator.lamports; accumulator.lamports = 0;
// accumulator.assign(system_program); accumulator.realloc(0)
// NOTE: no check that total_unclaimed_tokens == 0. Unclaimed rewards are lost.
}

Replay model

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

// no model entered yet

Accounts

  1. 0usersigns, written
  2. 1user_volume_accumulatorwritten
  3. 2event_authority
  4. 3program

program 6EF8rr…BEwF6P