
A storage collision occurs when an upgradeto a proxy contract's implementation changes its storage layout in a way thatmisaligns with the storage layout of the proxy contract.
Since proxy contracts are designed todelegate calls to implementation contracts, maintaining a consistent storagelayout across upgrades is critical.
The proxy contract itself holds the state,while the implementation contract contains the logic. If the storage layout inthe implementation contract changes, it can lead to mismatches when the proxycontract tries to access or modify state variables.
Previous Implementation Storage Layout:
address USDC public (slot[0])
address USDT public (slot[1])
address DAI public (slot[2])
New Implementation Storage Layout:
address ETH public (slot[0])
address USDC public (slot[1])
address USDT public (slot[2])
address DAI public (slot[3])
In this example, by introducing a newstorage variable ETH at the beginning of the contract, we've inadvertentlyshifted the original variables down one slot. This means the ETH variable wouldnow occupy what was previously the USDC storage slot (slot[0]), and so forth.
As a result, the contract would try to readETH's address as USDC, USDC as USDT, and so on.
This misalignment effectively breaks thestorage pattern and, by extension, the whole contract's functionality.
To prevent such storage collisions,developers should follow these guidelines:
Always add new state variables to the endof the storage layout in the implementation contract. This approach ensuresthat the original storage slots are not altered, preserving the alignment withthe proxy contract.
For contracts designed to be inherited andpotentially extended, include a "gap" array. This array acts as abuffer of reserved storage slots. When a new variable is added in a derivedcontract, reduce the size of the gap array correspondingly. This techniquemaintains the storage layout's integrity across different versions.
Notably, @OpenZeppelin added a specificcustom storage slot for their newer versions, effectively mitigating thisissue.
Proxy collisions present a significant riskto the upgradeability and functionality of smart contracts. By understandingand employing best practices, such as careful planning of storage layouts andutilizing gap arrays, developers can mitigate these risks. This ensures thatsmart contracts remain robust, secure, and functional across upgrades,safeguarding the interests of all stakeholders involved.

