LevelOne::graduateAndUpgrade()
upgrades the proxy to LevelTwo
and finalises the academic session but never checks each student’s studentScore
against cutOffScore
. Because cutOffScore
is only set (in LevelOne::startSession
) and never read/compared, the invariant "Any student whose score is below the cut‑off must not be upgraded" is violated.
Logical integrity broken — students who failed the session still exist in LevelTwo
, undermining the core business rule of the system.
Follow-on bugs — later Level Two logic may assume every student passed the cut‑off, leading to incorrect calculations or privilege escalation.
Severity is marked High as one of the fundamental business rules is bypassed.
Add to LevelOneAndGraduateTest.t.sol
and run `forge test --match-test test_student_below_cutoff_still_graduates -vvv` => The test will pass, proving that the student Harriet is still present in LevelTwo despite having a score of 60 (cutoff is 70).
Multiple mitigation options exist: either revert or automatically expel students who are under the cutoff at the time of the upgrade/graduation.
Revert if any student is below the cut‑off
Add a pre‑check before the upgrade:
Automatic expulsion option
Iterate through listOfStudents
and levelOne::expel()
every address with a score below cutOffScore
before authorising the upgrade. This keeps the single‑transaction UX while upholding the invariant:
Either approach ensures no student with a score lower than the cutoff can pass into Level Two.
All students are graduated when the graduation function is called as the cut-off criteria is not applied.
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.