The contract deployment logic in DeployLevelOne.sol uses a proxy pattern (ERC1967Proxy) to deploy and initialize a LevelOne logic contract. However, the initialization process does not safeguard against potential re-initialization, especially if deployed without atomic setup. This introduces a critical vulnerability that can lead to ownership hijacking or role abuse, especially in production environments.
Type: Unprotected Initialization / Insecure Proxy Setup
Location: DeployLevelOne.sol, deployLevelOne() function
The proxy is created with an empty initializer data payload, and the initialize() function is called only afterward.
the initialize() in LevelOne is not protected with OpenZeppelin's initializer modifier (from Initializable), any address can front-run this call and take over the contract.
Ownership Takeover: An attacker could call initialize() on the proxy before the deployer, assigning themselves as principal.
Logic Abuse: Misconfiguration or state manipulation, such as setting an arbitrary USDC token address or fee value.
DoS Potential: Re-initialization with invalid parameters could render the contract unusable.
Irreversible: If initialization occurs maliciously once, it cannot be undone without contract migration or proxy upgrade.
 initialize() is not protected:
attackerAddress becomes the principal
fakeUSDCAddress may be a malicious token
schoolFees is arbitrarily low or zero
This can happen on-chain in a race condition if the deployer delays calling initialize().
Manual code review
Use OpenZeppelin's Initializable contract
Perform atomic proxy deployment with initialization
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.