The graduateAndUpgrade
function in the LevelOne
contract lacks any enforcement that the school session has ended before allowing an upgrade. As a result, the contract can be upgraded—and graduation logic executed—immediately after deployment, bypassing the intended time-based lockout controlled by sessionEnd
. This single flaw breaks the invariant that graduation may only occur once the session has concluded.
In the UUPS proxy pattern, the implementation contract bears responsibility for both business and upgrade logic, delegating calls from the proxy to itself for upgradeTo
and _authorizeUpgrade
handling Documentation - OpenZeppelin Docs. While the contract correctly restricts _authorizeUpgrade
to the principal
, it entirely omits any check of block.timestamp
against sessionEnd
within either graduateAndUpgrade
or _authorizeUpgrade
. Consequently, a call to
can be made at any time, irrespective of whether the period defined by
has elapsed. This defeats the very purpose of sessionEnd
, rendering the time-based control over graduation a no-op and allowing premature or repeated upgrades.
A malicious or compromised principal
can trigger graduation immediately, without waiting the intended 4-week term.
In order to fix this issue, consider using a modifier that checks whether the session has ended or not:
`graduateAndUpgrade()` can be called successfully even when the school session has not ended
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.