Severity depends on reachable impact and deployment context. Listed tools are review aids; their applicability depends on language, version and configuration.
A proxy storage collision occurs when code executed through delegatecall interprets a storage slot differently from the proxy state that already occupies it. Because delegated code runs against the proxy's storage and balance, writing an ordinary implementation variable can overwrite an admin, implementation address, owner, balance, or another unrelated value.
Two collision classes matter. A proxy/implementation collision places proxy metadata in slots the implementation compiler may allocate. An upgrade-layout collision changes the order, type, packing, or inheritance position of existing variables, so old bytes acquire new meanings after an upgrade.
ERC-1967 defines implementation, beacon, and optional admin slots selected to avoid compiler-allocated state variables. It also recommends events when these slots change. Using those slots prevents the naive proxy pattern where implementation lives in slot 0, but it does not make later implementation layouts compatible with earlier ones.
Uninitialized implementations are an adjacent upgradeability risk, not a storage collision by definition. An attacker who initializes an exposed implementation may gain privileges or affect the proxy depending on its design. OpenZeppelin's upgradeable-contract guidance recommends locking the implementation with _disableInitializers() and explains why existing state variables cannot be reordered or have their types changed.
Identify the proxy pattern, implementation address, admin or beacon, and upgrade authority from source and deployment state. Generate compiler storage layouts for the current and candidate implementations using identical compiler settings. Compare slot, offset, type, variable order, inheritance linearization, structs, mappings, and reserved namespaced or gap storage.
Test an upgrade from realistic pre-upgrade state, not a fresh deployment. Seed every variable, upgrade, then assert that balances, roles, configuration, checkpoints, mappings, and packed values are unchanged. Exercise initialization and reinitialization through both proxy and implementation addresses. Verify that unauthorized callers cannot upgrade and that the authorized path cannot install a noncontract or incompatible implementation.
Storage gaps and namespaced storage help only when their conventions are followed consistently. They do not repair already-colliding layouts.
Firepan can compare submitted proxy and implementation sources, flag low-slot proxy metadata, exposed initializers, and candidate layout drift. It cannot prove the live implementation or admin state from source alone, and it cannot guarantee compatibility with versions or facets that were not submitted.
Can adding one variable break an upgrade?
Yes. Inserting it before existing variables or changing base-contract layout can shift later slots. Appending may be safe only under the system's documented layout rules.
Does ERC-1967 prevent all storage collisions?
No. It protects proxy metadata slots. Implementation-to-implementation layout compatibility remains the upgrade author's responsibility.
Firepan
Run a free scan — results in minutes, no credit card required.
Run Free Scan →Understand missing and incorrect smart contract authorization checks, how to review privileged paths, and how to test role boundaries.
Review cross-chain message authentication, replay protection, finality, accounting, and operational trust boundaries.
Understand untrusted delegatecall targets, proxy upgrade boundaries, storage hazards, and practical review and test guidance.
Understand how atomic liquidity amplifies oracle, accounting, governance, and callback defects, with review and test guidance.
Understand governance capture, flash-loan voting, unsafe proposal execution, and the review and testing needed for on-chain governance systems.