Rent Exempt Initialization
Detects account data writes before rent-exempt funding.
Rent Exempt Initialization
Overview
Remediation Guide: How to Fix Rent Exempt Initialization
The rent-exempt initialization detector identifies account initialization patterns where data is written before the account receives sufficient lamports for rent exemption. If an account is written to before being funded, the Solana runtime may purge it before the transaction completes, causing data loss and denial of service.
Sigvex tracks StoreAccountData events and TransferLamports events per account, reporting cases where the earliest data write precedes the earliest lamport transfer.
Why This Is an Issue
- Account purging: the runtime may reclaim an unfunded account mid-transaction, destroying the data just written.
- Data loss: initialization data is permanently lost if the account is garbage-collected before funding.
- Denial of service: repeated failed initializations waste compute budget and user fees.
CWE mapping: CWE-665 (Improper Initialization).
How to Resolve
Native Solana
// CORRECT: Fund first, then write
let rent = Rent::get()?;
let required = rent.minimum_balance(account_size);
// Step 1: Fund the account
**payer.try_borrow_mut_lamports()? -= required;
**account.try_borrow_mut_lamports()? += required;
// Step 2: Write data (now safe)
let mut data = account.data.borrow_mut();
data[0..8].copy_from_slice(MY_DISCRIMINATOR);
Anchor
// SystemProgram::create_account atomically allocates, funds, and assigns
#[account(init, payer = user, space = 8 + 64)]
pub state: Account<'info, MyState>,
Examples
Vulnerable
// Write BEFORE funding — account may be purged
let mut data = account.data.borrow_mut();
data[0..8].copy_from_slice(MY_DISCRIMINATOR);
// Funding happens too late
**payer.try_borrow_mut_lamports()? -= required;
**account.try_borrow_mut_lamports()? += required;
Fixed
// Fund FIRST
**payer.try_borrow_mut_lamports()? -= required;
**account.try_borrow_mut_lamports()? += required;
// Then write
let mut data = account.data.borrow_mut();
data[0..8].copy_from_slice(MY_DISCRIMINATOR);
JSON Finding
{
"detector": "rent-exempt-initialization",
"severity": "High",
"confidence": 0.65,
"title": "Account Data Written Before Rent-Exempt Funding",
"description": "Account has data written to it before receiving lamports for rent exemption.",
"cwe": [665]
}
Detection Methodology
The detector collects two event types per account variable: data writes and lamport transfers. It compares the earliest write and earliest transfer using (block_idx, stmt_idx) ordering. If the write precedes the transfer, a finding is generated. CPI calls that may write to accounts are also tracked.
Limitations
- The detector cannot track funding that occurs in a separate instruction within the same transaction.
SystemProgram::create_accountatomically funds and allocates, but may not be distinguishable in decompiled bytecode.- Accounts that receive lamports from sources outside the current function are not tracked.
Related Detectors
- Missing Rent Check - detects transfers without rent-exemption checks.
- Rent Exempt Reallocation - detects realloc without rent adjustment.