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.