Different slot interpretations can turn an ordinary write into corruption.
LET’S PICTURE IT
A borrowed manual can label the same drawer as both owner and counter.
SEE IT FOR YOURSELF
Pack small values into Solidity storage slotsStep 1 / 4
In this simple default-layout example, two uint128 values come before one uint256. Each slot holds thirty-two bytes.
In this simple default-layout example, two uint128 values come before one uint256. Each slot holds thirty-two bytes.The first sixteen-byte value occupies the low-order half of slot zero. Low-order bytes are shown on the right.The second uint128 fits in the remaining sixteen bytes. Both values now share slot zero.C needs a complete thirty-two-byte slot, so it begins at slot one. Two packed small values plus C use two slots.
Animated local teaching model. No wallet, RPC or live blockchain data. Some labels and hashes are abbreviated for readability.
Separate code and state
Delegated code uses the caller’s storage. The implementation’s source declaration does not allocate an independent safe cabinet during delegate execution.
Compare field positions
If one layout treats slot zero as an address and another treats it as an integer, a write can change the wrong logical field. Packed offsets create similar risks within one slot.
Include every inherited field
Compatibility checks need the complete compiled layout, not just newly added declarations. Base contracts and struct changes can alter existing positions.
Test an actual upgrade state
Populate representative old state, apply the proposed upgrade locally and assert preserved meanings. Passing compilation alone does not establish compatibility.