Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
LABS
Glossary

Storage Collision

A storage collision is a smart contract vulnerability where two different variables or contracts incorrectly share the same storage slot, leading to unintended data corruption.
Chainscore © 2026
definition
BLOCKCHAIN INFRASTRUCTURE

What is Storage Collation?

A technical mechanism for organizing and indexing blockchain data to enable efficient querying and retrieval.

Storage collation is the process of collecting, ordering, and indexing transaction data from a blockchain's execution layer (like Ethereum) into structured batches for efficient long-term storage and retrieval. It is a core function of data availability layers and modular blockchain architectures, transforming raw, sequential block data into an optimized format for historical queries. This process is distinct from block production (consensus) and execution (state updates), focusing solely on data packaging for accessibility.

The primary goal is to solve the data availability problem by ensuring historical transaction data is permanently accessible and verifiable. Collators, or similar nodes, take executed transaction data and package it with cryptographic proofs—such as Merkle roots or KZG commitments—into collated batches often called data blobs or shares. These batches are then made available to a broader network, like a data availability layer (e.g., Celestia, EigenDA) or a dedicated storage chain, which guarantees the data's presence without needing to re-execute the transactions.

This architecture is fundamental to modular blockchains, where roles are separated. A rollup's execution layer produces transactions, but relies on a separate collation and data availability layer for publishing its data. This separation allows for significant scalability, as the execution layer is not burdened with data storage and availability guarantees. It also enables light clients and other nodes to efficiently verify data availability by sampling small portions of the collated data, thanks to erasure coding and cryptographic proofs.

For developers, understanding storage collation is key when building on Layer 2 rollups (Optimistic or ZK). The cost, security, and finality of their applications are directly tied to how and where this collated data is published. The design choices in collation—such as batch size, proof system, and data availability layer—directly impact throughput, latency, and the trust assumptions of the entire system.

how-it-works
MECHANISM

How Storage Collations Occur

An explanation of the deterministic process by which two different smart contracts can map their variables to the same physical storage slot, leading to critical vulnerabilities.

A storage collision occurs when two distinct smart contracts, when deployed, map their state variables to the same physical storage slot on the Ethereum Virtual Machine (EVM). This happens because the EVM calculates storage locations for variables using a deterministic hashing algorithm based on the variable's declared position within the contract and the contract's own address. If two contracts use an identical storage layout—meaning variables are declared in the same order and types—their hashed slot assignments will be identical, causing their data to overlap and corrupt each other.

The core mechanism relies on the keccak256 hash function. For a state variable at position n (starting from 0) in contract C, its storage slot is typically computed as keccak256(encodePacked(C.address, n)) for complex types like dynamic arrays and mappings, or simply n for simpler, packed variables. When Contract A and Contract B share the same bytecode or are deployed from the same factory using CREATE2 with identical salt and initcode, they can have identical addresses, making their storage layouts perfectly aligned and guaranteeing collisions for every variable slot.

This is not merely a theoretical concern. A prominent real-world example is the OpenZeppelin TransparentUpgradeableProxy pattern. The proxy and its logic contract both have an _implementation state variable declared at the first storage slot (slot 0). To avoid a catastrophic collision that would overwrite the proxy's admin address, the pattern uses a specific, non-standard storage layout, offsetting the logic contract's variables to a pseudorandom slot derived from keccak256('eip1967.proxy.implementation') - 1. Without such deliberate safeguards, a storage collision would allow the logic contract to overwrite the proxy's critical administration data.

Beyond identical contracts, collisions can also arise from storage layout incompatibility during upgrades. If a new version of a logic contract reorders, removes, or changes the types of existing state variables, the upgraded contract's variable assignments will shift, causing the new code to read and write to slots containing different, legacy data from the previous version. This is why maintaining storage layout preservation is the cardinal rule of upgradeable contract design, often enforced by tools that compare storage layouts between versions.

For developers, preventing storage collisions requires deliberate strategy. Key practices include: using established upgradeability patterns (like the Universal Upgradeable Proxy Standard, UUPS), employing storage gap variables to reserve slots for future use, and rigorously auditing storage layouts, especially when using delegatecall or CREATE2 for deterministic deployment. Understanding this low-level mechanism is essential for building secure, complex, and upgradeable smart contract systems.

key-features
BLOCKCHAIN SECURITY

Key Characteristics of Storage Collisions

A storage collision is a vulnerability where two distinct variables in a smart contract map to the same storage slot, leading to unintended data overwrites. This occurs due to how the Ethereum Virtual Machine (EVM) calculates storage addresses.

01

Deterministic Slot Calculation

Storage collisions arise from the EVM's deterministic storage layout. The slot for a state variable is calculated based on its declared position within the contract and, for mappings/arrays, a hash of the key/index. If two different logical paths (e.g., in a proxy pattern) use the same calculation, they can collide.

  • Example: A proxy contract and its implementation logic contract might both define a variable at storage slot 0, causing a clash.
02

Proxy Pattern Vulnerability

This is the most common real-world scenario for storage collisions. When an upgradeable proxy contract delegates calls to a logic contract, both contracts share the same storage context. If the storage layouts between proxy and implementation, or between two implementation versions, are not strictly aligned, variables will overwrite each other.

  • Mitigation: Use established patterns like EIP-1967 or Transparent Proxy with reserved storage slots.
03

Hash Collisions in Mappings

While extremely rare in practice due to the size of the Keccak-256 hash space, a theoretical storage collision can occur if two different keys in a mapping (keccak256(key, slot)) or two elements in dynamic arrays resolve to the identical storage slot. This is a cryptographic collision, not a layout issue.

  • Key Insight: The risk is negligible for standard use but underscores the importance of the hash function's collision resistance.
04

Inheritance & Packing Conflicts

Inheritance chains and storage packing can introduce subtle collisions. The EVM packs multiple small-sized variables (like uint8, bool) into a single 32-byte slot. If a parent and child contract, or two base contracts, incorrectly define variables that are packed, they can corrupt each other's data.

  • Best Practice: Maintain a consistent and documented storage layout across all inherited contracts.
05

Uninitialized Pointer Risk

In complex structures, an uninitialized storage pointer (e.g., within a struct) can default to slot 0. Subsequent writes using this pointer will corrupt whatever data resides at that foundational slot, which is often a critical variable like the contract owner or a total supply.

  • Prevention: Always explicitly initialize storage pointers and be mindful of the storage keyword's behavior.
06

Detection & Prevention

Storage collisions are a critical security concern, often leading to loss of funds or control.

  • Detection Tools: Use static analyzers like Slither or MythX to identify layout inconsistencies.
  • Prevention Standards: Adopt upgradeability patterns with explicit storage gap reservations (uint256[50] private __gap;) to allow for future layout extensions without collisions.
  • Verification: Always verify storage layouts after contract upgrades using solc --storage-layout.
visual-explainer
BLOCKCHAIN SECURITY

Visualizing a Storage Collision

A conceptual breakdown of how storage collisions occur in smart contract development and their critical security implications.

A storage collision is a critical vulnerability in smart contract development where two distinct variables unintentionally map to the same location in a contract's persistent storage. This occurs due to the deterministic way the Ethereum Virtual Machine (EVM) calculates storage slots for state variables. When a collision happens, writing to one variable will overwrite the value of another, leading to corrupted state, unexpected behavior, and severe security exploits. Visualizing this overlap is key to understanding how seemingly independent data can become dangerously entangled.

The root cause lies in the EVM's storage layout rules. For elementary variables, the slot is determined by their declaration order. However, for dynamically-sized types like mapping or array, the slot calculation uses a keccak256 hash of the key and the base slot. A collision can be forced by a malicious actor who finds an input that causes two different logical storage paths—such as entries in two separate mappings—to resolve to the same physical slot. This is a common attack vector in delegatecall proxy patterns or when using low-level sstore/sload operations.

To visualize the risk, consider a contract with a public mapping(address => uint256) for user balances starting at slot 0, and an address owner variable at slot 1. These are safe. However, if a bytes32[] public array is naively added, its length is stored at a predetermined slot (e.g., slot 2), but its elements are stored at keccak256(2) + index. An attacker could calculate an index where this hashed location overlaps with slot 0 or 1, allowing them to manipulate a user's balance or the owner address by calling array.push().

Preventing storage collisions requires disciplined development practices. Key strategies include: using established, audited proxy patterns like the Transparent Proxy or UUPS, which carefully manage storage layouts; employing storage pointers with extreme caution; and utilizing tools like the Slither static analyzer or Ethers.js's getStorageAt to inspect and verify a contract's storage layout. Understanding and visualizing these collisions is fundamental for developers building upgradeable contracts or complex state management systems.

code-example
STORAGE COLLISION

Code Example: A Simple Collision

A practical demonstration of how a storage collision occurs when two different variables in a smart contract map to the same storage slot.

A storage collision is a critical vulnerability in Ethereum smart contracts where two distinct state variables are unintentionally assigned to the same storage slot. This occurs due to the deterministic way the Ethereum Virtual Machine (EVM) calculates storage positions. In this simple example, we examine a contract with two array variables, address[] public owners; and uint256[] public balances;, both declared at consecutive storage indices. Because dynamic arrays store their length in their declared slot and their data in sequentially hashed slots, a specific interaction can cause their data regions to overlap.

The collision manifests when the first array, owners, is initialized. Its length is stored at slot 0, and its data begins at slot keccak256(0). If the contract then attempts to push an element to the second array, balances, its length is stored at slot 1, but its data region is calculated to start at keccak256(1). Crucially, for certain values of keccak256(0) and keccak256(1), these hashed starting points can be adjacent or even identical under specific conditions, leading to a slot collision. Writing to one array will corrupt the data of the other, causing unpredictable and often catastrophic contract behavior.

This example highlights the non-obvious nature of storage layout. Developers might assume declared variables occupy separate memory, but the EVM's use of cryptographic hashing for dynamic types can create hidden intersections. To prevent such collisions, best practices include: - Using the pragma experimental ABIEncoderV2; for clearer struct handling, - Explicitly defining storage layouts with storage pointers, and - Thoroughly auditing storage interactions, especially in upgradeable contracts using delegatecall or complex inheritance patterns where multiple contracts share a single storage space.

security-considerations
STORAGE COLLISION

Security Considerations & Risks

Storage collision is a critical smart contract vulnerability where two distinct variables map to the same storage slot, causing unintended data overwrites and contract logic failures.

01

Core Mechanism

A storage collision occurs when the EVM storage layout algorithm assigns the same storage slot to two different state variables. This happens due to incorrect inheritance ordering or misaligned variable packing within structs or arrays. The EVM calculates storage positions based on declaration order, making the contract's bytecode reference the wrong data.

02

Inheritance Pitfall

This is a common cause in upgradeable contracts or complex inheritance chains. If a parent contract's variables are reordered in a new version, or a child contract declares variables without considering the parent's layout, collisions occur.

  • Example: A parent contract has variables in slots 0 and 1. A child contract adding a variable might incorrectly assume it starts at slot 0, overwriting the parent's data.
03

Uninitialized Pointer Risk

A specific, dangerous case involves uninitialized storage pointers in complex types. When a pointer within a struct or array is declared but not explicitly initialized, it defaults to pointing at storage slot 0. Subsequent writes via this pointer can corrupt critical contract state, like the owner address, leading to loss of funds or control.

04

Exploit Impact

Successful exploitation can lead to:

  • Arbitrary state corruption: Overwriting owner, balances, or access controls.
  • Logic bypass: Changing constants or configuration values.
  • Fund theft: Redirecting payments or unlocking locked tokens.
  • Contract bricking: Rendering core functions inoperable.
06

Related Vulnerability: Delegatecall

Storage collisions are intrinsically linked to delegatecall vulnerabilities. When Contract A delegatecalls to Contract B, Contract B's code executes in A's storage context. If the storage layouts of A and B do not match perfectly, B's code will read and write to the wrong slots in A's storage, causing catastrophic data corruption.

examples
STORAGE COLLISION

Real-World Examples & Incidents

Storage collisions are not just theoretical; they have led to significant financial losses and protocol failures. These incidents highlight the critical importance of secure storage layout design in smart contract development.

02

Uninitialized Storage Pointer Vulnerabilities

A common pattern leading to collisions involves uninitialized storage pointers in complex structs or arrays within functions. When a local variable of struct/array type is declared without explicit storage location, it defaults to storage and points to slot 0. Subsequent writes can corrupt critical contract state variables like the owner. This was a widespread vulnerability in early Solidity code, explicitly warned against in security guides.

03

Proxy Pattern & Implementation Upgrades

The widely used Proxy Upgrade Pattern is fundamentally built on controlled storage collisions. A proxy contract's storage layout must exactly match the implementation contract's layout. The proxy delegates calls to the implementation, but both execute in the proxy's storage context. An upgrade that changes the implementation's variable order or types will cause catastrophic data corruption, as the new logic will read/write to the wrong slots.

04

ERC-1167 Minimal Proxy Clones

Minimal Proxy contracts (ERC-1167) create cheap clones that share logic but have independent storage. Each clone's storage is isolated, but the clone factory must ensure the master logic contract uses a predictable, collision-free storage layout. If the master contract is upgraded with a new layout, all existing clones will experience storage collisions, reading old data as incorrect types. This necessitates immutable logic or very careful versioning.

05

Prevention: Storage Layout Diagrams & Tools

Developers use specific tools to visualize and verify storage layouts to prevent collisions:

  • solc --storage-layout: Outputs a JSON map of contract storage.
  • OpenZeppelin Upgrades Plugins: Automatically validate storage compatibility during upgrades.
  • Storage Layout Diagrams: Manually mapping variables to slots, especially for inherited contracts. The rule is: inherited contracts' variables are packed from slot 0 in the order of inheritance (C3 Linearization).
06

The "Append-Only" Storage Rule

A cardinal rule for upgradeable contracts is append-only storage modification. When upgrading a contract, you may only:

  • Add new variables at the end of existing ones.
  • Never remove, reorder, or change the type of existing variables. This ensures the new implementation's variable n still points to the same slot k as the old one, preserving all stored data. Violating this rule is a guaranteed storage collision.
VULNERABILITY MATRIX

Storage Collation vs. Related Vulnerabilities

A comparison of storage collision with other common smart contract vulnerabilities that involve state manipulation or unintended data access.

Core VulnerabilityPrimary MechanismKey TriggerTypical ImpactPrevention Paradigm

Storage Collision

Hash collision in storage layout

Inheritance/delegatecall with mismatched storage variables

Critical state corruption

Strict inheritance ordering & storage isolation

Unchecked Call Return Values

Ignoring failure of low-level calls

External call to a failing contract

Funds locked or logic bypass

Use higher-level abstractions or explicit checks

Reentrancy

Recursive callback during state transition

External call to untrusted contract before state update

Funds drained, state inconsistency

Checks-Effects-Interactions pattern

Delegatecall to Untrusted Code

Context-preserving execution of external code

Delegatecall to user-controlled address

Complete contract takeover

Never delegatecall to user-supplied addresses

Storage Pointer Aliasing

Multiple pointers referencing same storage slot

Complex struct/array operations in assembly

Unintended state overwrites

Explicit slot calculation, avoid assembly for storage

Arbitrary Storage Write (e.g., Parity Wallet Hack)

Delegatecall to a function performing selfdestruct

Malicious initialization or library call

Contract destruction or permanent DoS

Secure initialization & immutable libraries

prevention-mitigation
STORAGE COLLISION

Prevention and Mitigation Strategies

Storage collisions are a critical vulnerability in smart contract development. The following strategies are essential for developers to prevent unintended data overwrites and ensure contract integrity.

06

Understand Compiler Layout Rules

Prevention starts with understanding how the Solidity compiler packs variables. Key rules:

  • Variables are placed in order of declaration.
  • Items in contiguous 32-byte slots are packed together.
  • Inherited contracts: variables from base contracts come first.
  • mapping and dynamic arrays always start on a new slot. Misunderstanding these rules is a primary cause of unintended storage collisions.
DEBUNKED

Common Misconceptions About Storage Collisions

Storage collisions are a critical concept in smart contract security and optimization, but they are often misunderstood. This section clarifies persistent myths about how storage slots are calculated, the role of compiler versions, and the real-world impact of these low-level interactions.

A storage collision occurs when two distinct variables in a smart contract are unintentionally assigned to the same storage slot in the Ethereum Virtual Machine's (EVM) persistent state. This happens due to the deterministic rules of the EVM's storage layout, which maps state variables to sequential 32-byte slots based on their declaration order and size. For example, if a developer incorrectly packs variables or inherits from contracts with overlapping storage layouts, a write to one variable can corrupt the data of another, leading to critical bugs and security vulnerabilities. The collision is not random; it is a predictable outcome of the contract's structure as compiled.

STORAGE COLLISION

Frequently Asked Questions (FAQ)

Storage collisions are a critical low-level vulnerability in smart contract development, arising from how the Ethereum Virtual Machine (EVM) manages state. This FAQ addresses common questions about their cause, impact, and prevention.

A storage collision is a vulnerability where two distinct variables in a smart contract unintentionally map to the same storage slot in the EVM's persistent memory. This occurs due to incorrect calculation of storage positions, often when using inheritance or unstructured storage patterns in upgradeable contracts. When a collision happens, writing to one variable will overwrite the value of the other, leading to corrupted state, unexpected behavior, and potential loss of funds. It is a fundamental flaw in the contract's storage layout that can be exploited or cause the contract to malfunction.

ENQUIRY

Get In Touch
today.

Our experts will offer a free quote and a 30min call to discuss your project.

NDA Protected
24h Response
Directly to Engineering Team
10+
Protocols Shipped
$20M+
TVL Overall
NDA Protected direct pipeline
Storage Collision: Smart Contract Security Risk | ChainScore Glossary