Dria

Swan
NFTHardhat
21,000 USDC
View results
Submission Details
Severity: high
Invalid

Missing Storage Gap for Future Variables

Summary

Upgradeable contracts rely on consistent storage layouts across different versions to prevent storage collisions, which can lead to corrupted contract states during upgrades. In the provided codebase, contracts such as LLMOracleRegistry, LLMOracleCoordinator, SwanManager, and Swan inherit from OwnableUpgradeable and UUPSUpgradeable to facilitate upgradeability.

However, none of these upgradeable contracts include reserved storage gaps. Without these storage gaps, adding new state variables in future contract versions can inadvertently overwrite existing storage slots, leading to unpredictable behavior, loss of data, and potential security vulnerabilities.

Vulnerability Details

https://github.com/Cyfrin/2024-10-swan-dria/blob/main/contracts/llm/LLMOracleRegistry.sol
https://github.com/Cyfrin/2024-10-swan-dria/blob/main/contracts/llm/LLMOracleManager.sol
https://github.com/Cyfrin/2024-10-swan-dria/blob/main/contracts/llm/LLMOracleCoordinator.sol
https://github.com/Cyfrin/2024-10-swan-dria/blob/main/contracts/swan/Swan.sol
https://github.com/Cyfrin/2024-10-swan-dria/blob/main/contracts/swan/SwanManager.sol

  • The contract is deployed as an upgradeable proxy using the UUPS pattern.

  • The contract owner or an authorized upgrader initiates an upgrade to a new implementation.

  • The new implementation introduces additional state variables without reserving storage gaps in the previous contracts.

  • Due to the absence of storage gaps, these new variables overwrite existing storage slots, leading to data corruption.

  • Critical variables (e.g., owner, platformFee, generationFee, etc.) get overwritten with unintended values.

  • This can result in loss of control over contract ownership, incorrect fee calculations, and other operational disruptions.

Impact

Upgradeable contracts, especially those following the UUPS pattern, require that storage layouts remain consistent across upgrades to prevent slot mismatches. Without reserved storage gaps, introducing new variables can shift the storage slot assignments, causing new variables to overwrite existing ones. This collision disrupts the intended state of the contract, leading to vulnerabilities and functional failures.

Tools Used

Manual Review

Recommendations

Incorporate reserved storage slots in each upgradeable contract to accommodate future state variable additions without disrupting existing storage layouts.

contract LLMOracleRegistry is OwnableUpgradeable, UUPSUpgradeable {
// Existing state variables...
+ // Reserved storage space to allow for layout changes in the future.
+ uint256[50] private __gap;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 8 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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