- Category: storage_limits
- Severity: Medium
- Rule name:
ledger_size
S004 estimates the serialized size of each #[contracttype] struct and enum and compares it against the configured ledger entry limit (default 64 kB, with an "approaching" threshold at 80%). It reports two levels:
- ExceedsLimit — the estimated entry size is over the hard limit.
- ApproachingLimit — the estimated size is within the configured fraction of the limit.
The limit and threshold are configurable via .sanctify.toml.
Soroban rejects a ledger entry write when the serialized value exceeds the network's size limit. Because the rejection happens at write time, a struct that grows over time (for example a Vec of holders or a Map keyed by user) will eventually cause mid-transaction failures that brick the affected code path — often only on mainnet, under real load, after audit.
#![no_std]
use soroban_sdk::{contracttype, Address, Map, String, Vec};
#[contracttype]
pub struct Registry {
// S004: an unbounded list/map embedded in one entry grows past the limit.
pub members: Vec<Address>,
pub metadata: Map<Address, String>,
pub audit_log: Vec<String>,
}#![no_std]
use soroban_sdk::{contracttype, Address, String};
// Split the data across per-key entries instead of one giant struct.
#[contracttype]
pub enum DataKey {
Member(Address), // one small entry per member
Metadata(Address), // one small entry per member's metadata
MemberCount, // a single counter, not the full list
}
#[contracttype]
pub struct MemberRecord {
pub joined_ledger: u32,
pub label: String,
}- Vector:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Base score: 5.3
- Rating: Medium
The dominant impact is availability: writes to an oversized entry fail, denying the affected operation. There is no direct confidentiality or integrity loss.
- Reduce the size of the flagged
#[contracttype]by removing or shrinking large fields. - Split monolithic structures across multiple keyed entries (one entry per user/item) instead of one collection in a single entry.
- Store counters and indexes separately from bulk data.
- If the estimate is a false positive for your network, raise
ledger_limitin.sanctify.toml.