Rollback safety limits when an upgraded Solidity contract changes its storage layout
0 reputation · 09 Oct 2021, 04:23 UTC
Goal
I am designing an upgrade path for an OpenZeppelin-style upgradeable proxy and want to understand the exact limits of safe rollback after a storage schema change. The documented rule is append-only: new state variables go after existing ones, order and types are preserved, and storage gaps reserve slots in base contracts.
Constraint
There is no on-chain schema versioning in Solidity or the EVM, so layout safety is a tooling discipline enforced by validators like the OpenZeppelin Upgrades plugin, not the compiler. My concern: if V2 appends a new variable, writes to it, and I then roll the proxy back to V1, the old code ignores that slot, which seems safe. But if V2 ever reorders, retypes, or consumes a gap incorrectly, rollback would make V1 misread live state.
Questions
Is append-only layout change the precise and complete condition under which a rollback to a previous implementation remains safe, or are there edge cases (structs, mappings, inheritance changes) where even an append-only upgrade breaks rollback?
Does the OpenZeppelin Upgrades plugin offer any documented way to validate a V2-to-V1 downgrade, or does it only validate forward upgrades?
Is shrinking a __gap array by the number of consumed slots sufficient to keep child contract layouts stable across a rollback?