https://github.com/OpenEdenHQ/openeden.usdoexpress.audit/tree/f3f31d2ac15e3253cba342229f9d05495f95d6fd
Multiple UUPS upgradeable contracts (USDOExpressV2, AssetRegistry, UsycRedemption, LiquidityController) lack storage gap reservations, creating significant risks for future upgrades and potential storage collision vulnerabilities when these contracts are extended or modified.
The codebase implements several contracts inheriting from UUPSUpgradeable, but there is an inconsistency in storage gap implementation:
Contracts WITH storage gaps:
USDO - implements uint256[41] private __gap;Contracts WITHOUT storage gaps:
USDOExpressV2AssetRegistryUsycRedemptionLiquidityControllerStorage gaps are reserved storage slots that allow future versions of upgradeable contracts to add new state variables without causing storage collisions with child contracts.
Note! Storage gap in UUPS contract Only Protects UUPS Variables
Upgrade Path Limitations: Future versions cannot safely add new state variables without risking storage collisions
Inheritance Issues: If any of these contracts are extended by child contracts (now or in the future), adding state variables to the parent will corrupt child contract storage
Data Corruption Risk: Upgrades that add state variables could overwrite existing data in derived contracts or create unexpected storage collisions
Implement storage gaps (calculatedOnes) in all upgradeable contracts following OpenZeppelin's recommended pattern:
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;