Anchor Init/Close Patterns Remediation
How to fix unsafe Anchor init and close patterns.
Anchor Init/Close Patterns Remediation
Overview
Related Detector: Anchor Init/Close Patterns
Unsafe init/close patterns enable rent drain and reinitialization attacks. The fix is to use Anchor’s close attribute for safe account closing and proper init with correct space allocation.
Recommended Fix
#[derive(Accounts)]
pub struct InitVault<'info> {
#[account(init, payer = authority, space = 8 + Vault::INIT_SPACE)]
pub vault: Account<'info, Vault>,
#[account(mut)]
pub authority: Signer<'info>,
pub system_program: Program<'info, System>,
}
#[derive(Accounts)]
pub struct CloseVault<'info> {
#[account(mut, close = authority, has_one = authority)]
pub vault: Account<'info, Vault>,
#[account(mut)]
pub authority: Signer<'info>,
}
Alternative Mitigations
Manual Close with Full Safety
If not using Anchor’s close attribute:
// Zero discriminator to prevent reinitialization
vault.to_account_info().data.borrow_mut()[..8].fill(0);
// Transfer all lamports
**authority.lamports.borrow_mut() += vault.to_account_info().lamports();
**vault.to_account_info().lamports.borrow_mut() = 0;
Common Mistakes
Mistake: Close Without Data Zeroing
// WRONG: transfers lamports but leaves data intact
**recipient.lamports.borrow_mut() += vault.lamports();
**vault.lamports.borrow_mut() = 0;
// Discriminator intact -- account can be resurrected with 1 lamport
Always zero the discriminator bytes to prevent reinitialization.