Skip to main content

percli_program/instructions/
reclaim_account.rs

1use anchor_lang::prelude::*;
2
3use crate::error::{from_risk_error, PercolatorError};
4use crate::instructions::events;
5use crate::state::{engine_from_account_data, MARKET_ACCOUNT_SIZE};
6
7#[derive(Accounts)]
8pub struct ReclaimAccount<'info> {
9    /// Permissionless — anyone can reclaim dead accounts.
10    pub reclaimer: Signer<'info>,
11
12    /// CHECK: Validated via owner, discriminator, and size.
13    #[account(
14        mut,
15        owner = crate::ID @ PercolatorError::AccountNotFound,
16        constraint = market.data_len() >= MARKET_ACCOUNT_SIZE @ PercolatorError::AccountNotFound,
17    )]
18    pub market: UncheckedAccount<'info>,
19}
20
21pub fn handler(ctx: Context<ReclaimAccount>, account_idx: u16) -> Result<()> {
22    let market = &ctx.accounts.market;
23    let mut data = market.try_borrow_mut_data()?;
24
25    require!(
26        &data[0..8] == b"percmrkt",
27        PercolatorError::AccountNotFound
28    );
29
30    let engine = engine_from_account_data(&mut data);
31    let clock = Clock::get()?;
32
33    engine
34        .reclaim_empty_account_not_atomic(account_idx, clock.slot)
35        .map_err(from_risk_error)?;
36
37    emit!(events::AccountReclaimed {
38        reclaimer: ctx.accounts.reclaimer.key(),
39        account_idx,
40    });
41
42    Ok(())
43}