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.