Dria

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

Potential Storage Collision Due to Missing Storage Gaps in Upgradeable Contracts

Potential Storage Collision Due to Missing Storage Gaps in Upgradeable Contracts

Summary

In the current implementation of the Swan and SwanManager contracts, which utilize the UUPS upgradeable pattern, there are missing storage gaps (__gap) that are crucial for maintaining a consistent storage layout across contract upgrades. This omission can lead to potential storage collisions when adding new state variables in future upgrades.

Vulnerability Details

In upgradeable contracts using the UUPS pattern, it is vital to maintain storage alignment between the contract versions. Currently, the Swan and SwanManager contracts lack reserved storage slots (__gap), which means that any newly added state variables in a contract upgrade may overwrite existing variables. This can corrupt the contract state, leading to unintended and unpredictable behavior.

Proof of Concept

  • When a new version of the Swan contract is deployed with additional state variables:

    • Without a storage gap, the new variables might overwrite existing storage slots occupied by inherited contracts.

    • This scenario can lead to unintended overwriting of critical data such as ownership information or mappings.

Impact

  • State Corruption: Critical variables, such as ownership or mappings, could be overwritten, resulting in the loss of state integrity and potential contract failure.

  • Security Breaches: Attackers might exploit the corrupted state to gain unauthorized access or manipulate contract data maliciously.

  • Contract Failure: The contract could become unusable due to inconsistent state, affecting all users of the system and causing irreparable data loss.

Tools Used

  • Manual code review

  • Reference to OpenZeppelin upgradeability best practices

Recommendations

  1. Introduce Storage Gaps:

    • Add a storage gap to both the SwanManager and Swan contracts to reserve storage slots for future variable additions.

    contract SwanManager is OwnableUpgradeable {
    // Existing storage variables...
    // Reserve 50 slots
    uint256[50] private __gap;
    }
    contract Swan is SwanManager, UUPSUpgradeable {
    // Existing storage variables...
    // Reserve 50 slots
    uint256[50] private __gap;
    }
  2. Follow OpenZeppelin's Guidelines:

    • Ensure that the storage layout remains consistent and compatible across upgrades.

    • Avoid changing the order or types of existing state variables to prevent misalignment issues during future contract upgrades.

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.