The enroll()
function is prone to a reentrancy attack due to an unsafe order of operations. The function makes an external token transfer usdc.safeTransferFrom()
before updating the contract state. This allows a malicious contract to re-enter the function and bypass security checks or manipulate state variables.
The function makes an external call usdc.safeTransferFrom
before updating the contract’s state isStudent
, studentScore
, bursary
.
A malicious contract can interact with usdc.safeTransferFrom
, and it could call back into enroll()
before state updates occur, allowing:
Multiple enrollments without deducting fees.
Bypassing the isStudent check
, leading to duplicates.
Manipulation of bursary or other state variables.
Attack Scenario
An attacker deploys a malicious token contract that makes a callack in transferFrom
.
The attacker reenters enroll()
when usdc.safeTransferFrom
is executed and pays school fees multiple times.
The callback happens before isStudent[msg.sender]
is updated.
Since isStudent[msg.sender]
is still false, the attacker can enroll multiple times, possibly draining funds or corrupting state.
Unauthorized enrollments.
Manipulation of state.
Loss of funds.
Manual Review
Static analysis
Use OpenZeppelin’s ReentrancyGuard modifier (nonReentrant) on functions that involve external calls.
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.