Storage Gap Explained in Detail
A storage gap reserves storage slots for future variables. OpenZeppelin upgradeable contracts often use arrays like uint256[50] private __gap;.
When a future version adds variables, the gap can be reduced so child contract storage does not shift.
Smart contract example
uint256[50] private __gap;
The array is intentionally unused.
Storage Gap in Auditing
Storage gaps help prevent storage collisions, but they do not make upgrades automatically safe. Developers can still reorder variables, shrink gaps incorrectly, or add variables in the wrong inheritance layer.
Auditors compare storage layouts across versions.
Red flags in code
-
Gap is reduced by the wrong number of slots.
-
New variables are inserted before inherited storage.
-
Existing variables are reordered or deleted.
-
Multiple inheritance creates confusing gaps.
-
Upgrade tooling warnings are ignored.
How to test or review it
-
Compare compiler storage layout before and after upgrade.
-
Deploy old version, set state, upgrade, and verify state remains correct.
-
Check inheritance order.
-
Count slots added and gap slots removed.
-
Review structs, mappings, and arrays for slot-size assumptions.
Keep learning this topic
Storage Collision
A storage collision happens when two variables or contracts use the same storage slot, corrupting state in upgradeable or delegatecall-based systems.
Storage Slot
A storage slot is a 32-byte indexed location in EVM contract storage used to hold state variables and derived storage data.
Upgradeable Proxy
An upgradeable proxy is a smart contract pattern where users call a stable proxy address while execution is delegated to replaceable implementation logic.
Practice this in real audit scenarios
Definitions help, but auditors need reps. SCH turns concepts like Storage Gap into exploit labs, code review habits, and report-writing practice.
Start the free trial or see the full smart contract auditing course.