For upgradeable contracts, inheriting contracts may introduce new variables. In order to be able to add new variables to the upgradeable contract without causing storage collisions, a storage gap should be added to the upgradeable contract.
Storage gaps are a convention for reserving storage slots in a base contract, allowing future versions of that contract to use up those slots without affecting the storage layout of child contracts. To create a storage gap, declare a fixed-size array in the base contract with an initial number of slots. This can be an array of uint256 so that each element reserves a 32 byte slot.
Using Foundry, you can run the following command to inspect the storage of contract SmartVaultManagerV5
:
forge inspect SmartVaultManagerV5 storage --pretty --via-ir
Observe there is no storage GAP at the end of it.
Similar findings from other contests:
https://solodit.xyz/issues/l-11-upgradeable-contract-is-missing-a-code4rena-alchemix-alchemix-contest-git
https://solodit.xyz/issues/l-07-upgradeable-contract-is-missing-a-code4rena-badgerdao-badger-citadel-contest-git
https://solodit.xyz/issues/l-09-upgradeable-contract-is-missing-a-code4rena-backd-backd-contest-git
https://solodit.xyz/issues/no-storage-gap-for-upgradeable-contract-halborn-savvy-defi-pdf
If no storage gap is added, when the upgradable contract introduces new variables, it may override the variables in the inheriting contract.
Manual Analysis and Foundry.
Consider adding a storage gap at the end of the upgradeable SmartVaultManagerV5
contract.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.