The LevelTwo
contract contains a graduate()
function marked with the reinitializer(2)
modifier but lacks any access control mechanisms. This critical security oversight allows any address to call this privileged function, which should be restricted to authorized system administrators (like the principal) or the proxy contract during an upgrade process.
This vulnerability completely undermines the security model of the upgradeable contract system. The unrestricted graduate()
function creates several severe risks:
Unauthorized System Reinitialization: Any external actor can trigger the reinitialization process, potentially corrupting the system state
Upgrade Hijacking: Malicious actors can front-run legitimate upgrade transactions by calling this function first
Denial of Service: Since the reinitializer can only be called once, attackers can permanently block legitimate initialization by calling it first
Financial Risk: Given that bursary
funds are carried over from LevelOne
, unauthorized control of reinitialization could potentially redirect or lock these funds
The exploitation likelihood is high because:
The vulnerability requires minimal technical expertise to exploit (single function call)
The function is public with no parameters, presenting a trivial attack vector
No access controls exist whatsoever to prevent unauthorized calls
The function is named in an intuitive way that indicates its purpose
The vulnerable implementation in the LevelTwo
contract:
Key security issues:
No Access Modifier: Unlike other administrative functions in both LevelOne
and LevelTwo
contracts, this critical function lacks any access control modifier
Empty Implementation: The function body is empty, suggesting it's meant to be a placeholder for initialization logic during an upgrade
Reinitializer Version: The reinitializer(2)
indicates this is for the second initialization after an upgrade from LevelOne
When compared to the LevelOne
contract's initialization function:
The LevelTwo
contract's graduate()
function lacks both the necessary access controls and implementation logic.
A simple attack scenario:
LevelOne
contract is deployed and operational with students, teachers, and accumulated bursary funds
The system administrator prepares for an upgrade to LevelTwo
Before the legitimate upgrade transaction is processed, an attacker monitors the mempool and calls graduate()
on the LevelTwo
implementation
The reinitialization is marked as complete but with none of the required state migration or setup
The legitimate upgrade fails or results in a corrupted system state
Implement proper access control and initialization logic:
For enhanced security in the upgrade process, consider one of these approaches:
Use a specific upgrade manager role that's separate from day-to-day administration
Implement a time-lock mechanism for upgrade operations
Add validation to ensure the function is called in the context of a proxy upgrade transaction
These changes would ensure that only authorized entities can perform the critical reinitialization during the upgrade process.
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.