The graduateAndUpgrade
function authorizes an upgrade but does not execute the upgrade, leaving the system running on the old implementation despite the function’s name suggesting otherwise.
The graduateAndUpgrade
function is shown below:
While _authorizeUpgrade(_levelTwo)
ensures that the caller is allowed to perform an upgrade, it does not actually perform the upgrade. In UUPSUpgradeable contracts, an upgrade must be explicitly triggered using upgradeTo
or upgradeToAndCall
.
Since upgradeToAndCall
is not invoked, the contract remains on the old implementation, despite its appearance of performing an upgrade. This introduces confusion and could lead to serious deployment issues if the contract is assumed to be running upgraded logic when it is not.
Upgrade to _levelTwo
is not executed
The contract stays on the old implementation
Misleading function behavior
Possible failure to patch vulnerabilities or activate new logic
Manual code review
OpenZeppelin UUPSUpgradeable documentation
To properly execute the upgrade, modify the function to include a call to upgradeToAndCall
at the end. Update the function to accept the bytes memory data
argument and invoke the upgrade:
This ensures that the upgrade is not only authorized but also executed with any optional initialization logic included in data
.
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.