Anchor Init/Close Patterns
Detects unsafe account initialization and closing patterns in Anchor programs.
Anchor Init/Close Patterns
Overview
The Anchor init/close patterns detector identifies unsafe initialization and account closing patterns including close without balance check (rent drain), initialize without proper space allocation, missing close_authority validation, reinitialization vulnerabilities, and unvalidated close destination.
For remediation guidance, see Anchor Init/Close Patterns Remediation.
Why This Is an Issue
Account initialization without proper space allocation leads to data truncation. Account closing without balance checks allows rent drain attacks where an attacker closes accounts and redirects remaining lamports. Missing reinitialization guards allow closed accounts to be recreated with attacker-controlled data, potentially corrupting protocol state.
How to Resolve
Before (Vulnerable)
// Vulnerable: close without proper validation
pub fn close_vault(ctx: Context<Close>) -> Result<()> {
let vault = &ctx.accounts.vault;
// No check that recipient is authorized
**ctx.accounts.recipient.lamports.borrow_mut() += vault.to_account_info().lamports();
**vault.to_account_info().lamports.borrow_mut() = 0;
Ok(())
}
After (Fixed)
// Fixed: Anchor's close attribute handles everything safely
#[derive(Accounts)]
pub struct CloseVault<'info> {
#[account(
mut,
close = authority, // Anchor zeroes data and transfers lamports
has_one = authority,
)]
pub vault: Account<'info, Vault>,
#[account(mut)]
pub authority: Signer<'info>,
}
Example JSON Finding
{
"detector": "anchor-init-close-patterns",
"severity": "high",
"confidence": 0.7,
"message": "Account close operation without close_authority validation",
"location": { "function": "close_vault", "block": 0, "statement": 2 }
}
Detection Methodology
- Close operation detection: Identifies account closing patterns (lamport zeroing, data clearing).
- Authority validation check: Verifies close operations validate the close destination authority.
- Space allocation analysis: Checks init operations for proper space calculation including discriminator.
- Reinitialization guard detection: Flags init operations without is_initialized checks.
Limitations
False positives: Programs with custom close patterns that validate authority through different mechanisms. False negatives: Reinitialization through separate transaction sequences is not detected.
Related Detectors
- Account Resurrection — account revival after close
- Anchor Space Allocation — init space calculation
- Close Account Drain — close account balance theft