Rent Exempt Reallocation
Detects account reallocations without rent-exemption lamport adjustments.
Rent Exempt Reallocation
Overview
Remediation Guide: How to Fix Rent Exempt Reallocation
The rent-exempt reallocation detector identifies account reallocations that do not properly adjust lamport balances to maintain rent exemption. When an account is resized, the rent-exemption requirement changes proportionally: growing requires additional lamports, and shrinking may leave excess lamports that should be returned. Failing to adjust can cause the runtime to garbage-collect the account.
Sigvex tracks realloc syscalls and checks whether corresponding lamport transfers, lamport reads, or rent sysvar accesses exist in the same function.
Why This Is an Issue
- Garbage collection: growing an account without adding lamports leaves it below rent exemption, risking deletion.
- Trapped funds: shrinking an account without returning excess lamports locks user funds in an over-funded account.
- Silent failure: the account is deleted asynchronously, making the root cause difficult to trace.
CWE mapping: CWE-400 (Uncontrolled Resource Consumption).
How to Resolve
Native Solana
let rent = Rent::get()?;
let old_balance = account.lamports();
let required = rent.minimum_balance(new_size);
account.realloc(new_size, false)?;
if required > old_balance {
let shortfall = required - old_balance;
**payer.try_borrow_mut_lamports()? -= shortfall;
**account.try_borrow_mut_lamports()? += shortfall;
} else if old_balance > required {
let excess = old_balance - required;
**account.try_borrow_mut_lamports()? -= excess;
**destination.try_borrow_mut_lamports()? += excess;
}
Anchor
#[account(mut, realloc = new_size, realloc::payer = payer, realloc::zero = true)]
pub my_account: Account<'info, MyAccount>,
Examples
Vulnerable
account.realloc(new_size, false)?;
// No lamport adjustment — may lose rent exemption
Fixed
let rent = Rent::get()?;
let required = rent.minimum_balance(new_size);
account.realloc(new_size, true)?;
let shortfall = required.saturating_sub(account.lamports());
if shortfall > 0 {
**payer.try_borrow_mut_lamports()? -= shortfall;
**account.try_borrow_mut_lamports()? += shortfall;
}
JSON Finding
{
"detector": "rent-exempt-reallocation",
"severity": "High",
"confidence": 0.75,
"title": "Account Reallocation Without Rent-Exemption Adjustment",
"description": "Account is reallocated without adjusting lamports for the new rent-exemption requirement.",
"cwe": [400]
}
Detection Methodology
The detector identifies realloc syscalls and checks for lamport transfers, AccountLamports reads, or Rent sysvar access in the same function. If none of these indicators of rent awareness exist, a finding is generated for each realloc operation.
Limitations
- Rent adjustments in helper functions or CPI calls are not tracked.
- Anchor’s realloc constraint automatically handles rent but may not be distinguishable in decompiled code.
- The detector flags all reallocations without rent handling, including shrinks where rent excess is acceptable.
Related Detectors
- Account Reallocation - detects general reallocation safety issues.
- Account Realloc Corruption - detects data corruption from reallocation.