Rent Exempt Initialization Remediation
How to fix account data writes that occur before rent-exempt funding.
Rent Exempt Initialization Remediation
Overview
Detector Reference: Rent Exempt Initialization
This guide explains how to ensure accounts are funded with rent-exempt lamports before any data is written to them.
Recommended Fix
Use SystemProgram::create_account which atomically allocates, funds, and assigns ownership:
invoke(
&system_instruction::create_account(
payer.key,
account.key,
rent.minimum_balance(space),
space as u64,
program_id,
),
&[payer.clone(), account.clone()],
)?;
// Now safe to write
let mut data = account.data.borrow_mut();
data[0..8].copy_from_slice(MY_DISCRIMINATOR);
Alternative Mitigations
- Anchor init:
#[account(init, payer = user, space = ...)]handles atomic creation. - Manual ordering: if not using
create_account, always transfer lamports before writing data. - Pre-fund accounts: have users fund accounts in a prior transaction before initialization.
Common Mistakes
- Writing discriminator before funding: even a single byte write is risky if the account has zero lamports.
- Using CPI before funding: CPI calls that write to the account must also occur after funding.
- Assuming transaction atomicity protects against rent: while transactions are atomic, the runtime may validate rent at various points during execution.