The Vault contract currently implements a storage gap to maintain compatibility for future upgrades. However, the size of the storage gap (uint256[9]) is relatively small and might not provide sufficient space for adding new state variables in future upgrades. This report recommends expanding the storage gap to a larger size while taking into account the already defined variables, aligning the implementation with OpenZeppelin's best practices for upgradeable contracts.
In upgradeable contracts, a storage gap is used to reserve storage slots to ensure that future versions of the contract can add new state variables without affecting the existing storage layout. This helps prevent storage collisions, which could lead to unintended behavior or vulnerabilities in the upgradeable proxy pattern.
State Variables Defined in the Vault Contract:
IERC20Upgradeable public token; — 1 storage slot
address public vaultController; — 1 storage slot
IStaking public stakeController; — 1 storage slot
IStakingRewards public rewardsController; — 1 storage slot
The current storage gap is defined as:
This gap reserves 9 slots for future variables, but considering the existing variables already defined and inherited in the contract, this size might be inadequate for future upgrades. According to OpenZeppelin's guidelines, it is recommended to provide a larger gap (e.g., uint256[50]) to better accommodate new state variables in future upgrades.
A storage gap of only 9 slots might not be enough for future-proofing, as future upgrades might require more slots to accommodate additional variables. OpenZeppelin's recommended approach suggests subtracting the number of existing storage slots from the gap size to ensure that the contract's layout remains consistent with the gap size recommendation.
If the storage gap runs out of reserved slots, adding new state variables in future upgrades could lead to storage collisions, which may overwrite existing data and cause unexpected behavior or security vulnerabilities. A small storage gap restricts the ability to make significant upgrades to the contract without risking the storage layout's integrity.
Manual Review
For simplicity and to ensure a larger buffer for future upgrades, it is recommended to use a gap size of uint256[50], adjusted for the existing variables.
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.