Liquid Staking

Stakelink
DeFiHardhatOracle
50,000 USDC
View results
Submission Details
Severity: medium
Invalid

Incorrect Storage Gap Implementation in the Vault Contract

Github

Summary

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.

Vulnerability Details

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:

uint256[9] private __gap;

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.

Impact

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.

Tools Used

Manual Review

Recommendations

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.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.