The UUPSOwnableProxied contract inherits from Ownable and UUPSUpgradeable. However, the Ownable contract is not designed to be used in an upgradable context, as it is not a part of the OpenZeppelin upgradable contract library. Upgradable contracts should utilize upgradable versions of parent contracts to ensure correct functionality when the contract is upgraded.
In the contract UUPSOwnableProxied, the following inheritance is used:
Here, the Ownable contract is inherited directly. However, the Ownable contract from the OpenZeppelin library is designed for non-upgradable contracts. When used in an upgradable contract context, it can cause issues because its storage layout and initialization are not designed to work with proxy patterns.
The correct approach is to use OwnableUpgradeable, which is part of the OpenZeppelin upgradable contracts library. This version of the Ownable contract is specifically designed to be compatible with upgradable contracts, ensuring that ownership functionality works correctly across contract upgrades.
Using a non-upgradable version of Ownable in an upgradable contract can lead to several issues:
Ownership Loss: If the contract is upgraded and the Ownable contract is not properly initialized, the ownership functionality might not work correctly, potentially leading to loss of ownership or the inability to transfer ownership.
Storage Layout Conflicts: The Ownable contract might have a different storage layout compared to its upgradable counterpart, leading to storage conflicts and bugs when the contract is upgraded.
Manual code Review
Use Upgradable Parent Contracts: Replace the Ownable contract with OwnableUpgradeable to ensure compatibility with the UUPSUpgradeable pattern. The correct inheritance would look like this:
Known issue: Lightchaser
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.