Conditional Storage Collision
Detects storage slot collisions in proxy contracts that occur only under specific execution paths or conditions, leading to intermittent state corruption.
Conditional Storage Collision
Overview
Remediation Guide: How to Fix Conditional Storage Collision
The conditional storage collision detector identifies storage slot conflicts between proxy and implementation contracts that manifest only under certain execution conditions. Unlike straightforward storage collisions (where two variables always occupy the same slot), conditional collisions occur when a variable is written only in specific code paths — for example, when a mapping entry is created for the first time, or when a branch is taken based on an external condition.
Sigvex analyzes the storage layout of both proxy and implementation contracts, identifying slots that are written in conditional branches and overlap with the other contract’s declared storage.
Why This Is an Issue
Conditional collisions are harder to detect than unconditional ones because they may not manifest during normal testing. A proxy’s admin slot might collide with a mapping entry that only exists for certain token IDs, or an implementation’s emergency flag might share a slot with the proxy’s upgrade timestamp. The corruption only appears when the specific condition triggers, making it a ticking time bomb.
How to Resolve
// Before: Vulnerable — implementation slot 0 may collide with proxy admin
contract Implementation {
address public admin; // Slot 0 — collides with proxy's implementation slot
}
// After: Fixed — use EIP-1967 storage slots
contract Implementation {
// Admin stored at keccak256("eip1967.proxy.admin") - 1
bytes32 private constant _ADMIN_SLOT =
0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
function _getAdmin() internal view returns (address admin) {
assembly { admin := sload(_ADMIN_SLOT) }
}
}
Detection Methodology
- Storage layout extraction: Decompiles both proxy and implementation bytecode to identify all storage slot accesses (
SLOAD/SSTORE). - Conditional path analysis: For each storage access, determines whether it occurs unconditionally or within a branch (after a
JUMPI). - Slot collision check: Compares slot addresses between proxy and implementation, flagging overlaps that occur in at least one conditional path.
- EIP-1967 validation: Checks whether the proxy uses standard EIP-1967 slots, which are designed to avoid collisions.
Limitations
False positives:
- Proxy patterns that intentionally share state between proxy and implementation may be flagged.
False negatives:
- Collisions involving dynamically computed slots (complex mapping key derivations) may not be detected.
- Diamond proxy facet-to-facet collisions require cross-facet analysis.
Related Detectors
- Storage Collision — detects unconditional proxy storage collisions
- Diamond Collision — detects EIP-2535 diamond proxy facet collisions
- UUPS Initialization — detects uninitialized UUPS proxies