The Distribution
contract is designed to be upgradeable and inherits from UUPSUpgradeable
. However, it imports and uses the non-upgradeable version of the SafeERC20
library from OpenZeppelin's contracts package.
While SafeERC20 itself is stateless and does not require initialization, which typically makes it safe to use in upgradeable contracts, best practices suggest using the upgradeable versions of libraries when working with upgradeable contracts to ensure full compatibility and to prevent potential issues with storage layout and initialization.
https://github.com/Cyfrin/2024-01-Morpheus/blob/07c900d22073911afa23b7fa69a4249ab5b713c8/contracts/Distribution.sol#L4C1-L4C91
The impact is considered low because SafeERC20 is a stateless library that does not have constructors or store state. It is used to safely interact with ERC20 tokens by wrapping the token's methods with additional checks. Since it does not rely on contract storage, it does not pose the same risks as using non-upgradeable stateful contracts in an upgradeable contract.
It is important to maintain consistency and follow best practices by using upgradeable versions of libraries and contracts when working within an upgradeable contract framework. This ensures that all parts of the contract are designed with upgradeability in mind and reduces the risk of future compatibility issues.
Manual Review
To align with best practices and ensure full compatibility with the upgradeable contract pattern, consider replacing the non-upgradeable SafeERC20 import with the upgradeable version from OpenZeppelin's upgradeable contracts package:
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.