The LevelOne and LevelTwo contracts, using OpenZeppelin's Initializable, lack a constructor with _disableInitializers(), enabling direct initialization of the implementation contracts outside the proxy. This could allow attackers to set themselves as principal or block legitimate proxy initialization.
The implementation contracts do not include a constructor calling _disableInitializers(). As a result, attackers can directly call initialize on the implementation contract, modifying state variables like principal or schoolFees, or incrementing version counters to prevent proxy initialization. This violates the invariant that initializers run only once, as per OpenZeppelin’s guidelines.
High impact: Attackers could gain unauthorized control over the implementation contract’s state or lock out proxy initialization, disrupting upgrades or contract functionality. While proxy storage remains separate, this risks security breaches if the implementation is exposed.
Add the following constructor to both LevelOne and LevelTwo contracts:
Ensure compliance with OpenZeppelin’s UUPS/Proxy patterns and validate deployments using OpenZeppelin Upgrades Plugin.
The system can be re-initialized by an attacker and its integrity tampered with due to lack of `disableInitializer()`
The system can be re-initialized by an attacker and its integrity tampered with due to lack of `disableInitializer()`
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.