Hawk High

First Flight #39
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: high
Valid

Missing Cutoff Score Validation in Upgrade

Summary

The graduateAndUpgrade function allows students to graduate regardless of their score, violating the invariant that students must meet the cutoff score to advance.

Vulnerability Details

The contract's invariants state that "Any student who doesn't meet the cutOffScore should not be upgraded". However, the graduateAndUpgrade function does not validate student scores against the cutOffScore before proceeding with the upgrade.

Impact

  • Students can graduate without meeting minimum score requirements

  • Violates the core grading invariant of the system

  • Could lead to unqualified students advancing to LevelTwo

  • May result in unfair advancement criteria

Proof of Concept

modifier schoolInSession() {
_teachersAdded();
_studentsEnrolled();
vm.prank(principal);
levelOneProxy.startSession(70);
_;
}
function test_graduate_below_cutoff() public schoolInSession {
// Give bad reviews to drop score below cutoff
vm.warp(block.timestamp + 1 weeks);
vm.prank(alice);
levelOneProxy.giveReview(harriet, false); // -10
vm.warp(block.timestamp + 1 weeks);
vm.prank(alice);
levelOneProxy.giveReview(harriet, false); // -10
vm.warp(block.timestamp + 1 weeks);
vm.prank(alice);
levelOneProxy.giveReview(harriet, false); // -10
vm.warp(block.timestamp + 1 weeks);
vm.prank(alice);
levelOneProxy.giveReview(harriet, false); // -10
// Score is now 60, below cutoff of 70
// Try to upgrade
levelTwoImplementation = new LevelTwo();
levelTwoImplementationAddress = address(levelTwoImplementation);
bytes memory data = abi.encodeCall(LevelTwo.graduate, ());
vm.prank(principal);
levelOneProxy.graduateAndUpgrade(levelTwoImplementationAddress, data);
// Student graduated despite being below cutoff
LevelTwo levelTwoProxy = LevelTwo(proxyAddress);
assert(levelTwoProxy.isStudent(harriet));
}

Tools Used

  • Manual code review

  • Foundry for testing

Recommendations

Add score validation in the graduateAndUpgrade function:

for (uint256 i = 0; i < listOfStudents.length; i++) {
require(studentScore[listOfStudents[i]] >= cutOffScore, "Student below cutoff");
}
Updates

Lead Judging Commences

yeahchibyke Lead Judge about 1 month ago
Submission Judgement Published
Validated
Assigned finding tags:

cut-off criteria not applied

All students are graduated when the graduation function is called as the cut-off criteria is not applied.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.