The contract implements an initialize function that lacks proper access control mechanisms. While the function uses the initializer
modifier to prevent multiple initializations, it is declared as public
without any additional access control, making it vulnerable to front-running attacks during deployment.
An attacker could monitor the mempool for the contract deployment transaction and front-run the legitimate initialization by calling the initialize
function before the intended owner. This would allow the attacker to:
Set themselves as the principal
with administrative privileges
Control critical parameters like schoolFees
Specify the usdcAddress
to potentially point to a malicious token contract
Since this is a UUPS upgradeable contract (as evidenced by the __UUPSUpgradeable_init()
call), the consequences are particularly severe. The attacker would gain permanent control over the contract, including the ability to upgrade it to malicious implementations.
Manual Review
Implement proper access control for the initialize function by using OpenZeppelin's OwnableUpgradeable pattern:
This implementation follows industry best practices and provides several security benefits:
Proper initialization sequence for all inherited contracts
Ownership control through OpenZeppelin's well-tested patterns
Protection against front-running through the initializer pattern
External visibility for better gas optimization
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.