SCWE-150: Storage Slot Collision When Upgrading Implementation
Stable Version v1.0
This content is in the version-(v1.0) and still under active development, so it is subject to change any time (e.g. structure, IDs, content, URLs, etc.).
Relationships¶
- CWE-682: Incorrect Calculation
https://cwe.mitre.org/data/definitions/682.html
Description¶
When upgrading a proxy's implementation, the new implementation's storage layout must be compatible with the proxy's storage. Appending variables in the implementation without accounting for the proxy's own storage (e.g., admin, implementation address) can cause slot collisions. Similarly, inherited contracts that add state variables can overwrite slots used by the base or proxy. SCWE-099 covers same-contract layout; this addresses cross-contract layout (proxy + implementation, inheritance chain).
Remediation¶
- Use a single storage contract or follow a consistent storage layout convention (e.g., EIP-1967).
- Reserve gaps (
uint256[50] private __gap) in base contracts for future expansion. - Run storage layout diff tools before upgrading.
Examples¶
Vulnerable¶
// Proxy
contract Proxy {
address public implementation; // slot 0
address public admin; // slot 1
}
// Implementation V2 - assumes it "owns" slots from 0
contract ImplV2 {
address public owner; // slot 0 - COLLIDES with proxy's implementation
uint256 public newValue; // slot 1 - COLLIDES with proxy's admin
}