The graduateAndUpgrade function in the LevelOne contract misuses the UUPS pattern by calling _authorizeUpgrade without executing upgradeTo or upgradeToAndCall. This prevents the contract from upgrading to LevelTwo, leaving it on outdated logic and risking fund mismanagement or loss of functionality.
The LevelOne contract uses OpenZeppelin’s UUPSUpgradeable for upgradeability. The graduateAndUpgrade function, restricted to the principal, authorizes an upgrade to _levelTwo via _authorizeUpgrade and distributes bursary funds but fails to call upgradeTo or upgradeToAndCall. Per OpenZeppelin’s documentation, _authorizeUpgrade only checks permissions, and the upgrade requires a separate upgradeTo call on the proxy. This omission means the proxy remains on LevelOne logic, and LevelTwo’s reinitializers (e.g., graduate) are never executed. The function also lacks the onlyProxy modifier and does not emit a Graduated event for transparency.
Add this function to LevelOneAndGraduateTest:
run: forge test --match-test test_graduateAndUpgradeFailsToUpgrade -vvv
High impact due to:
Persistent old logic, potentially with vulnerabilities or missing features.
Possible fund mismanagement if LevelTwo is needed for proper fund handling.
Undetectable failure due to no events or state changes, risking prolonged issues.
Add Upgrade Call: Modify graduateAndUpgrade to call upgradeTo(_levelTwo) on the proxy after _authorizeUpgrade.
The system doesn't implement UUPS properly.
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.