Hawk High

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

`LevelOne::graduateAndUpgrade` does not validate that students have been reviewed 4 times

Drscription

The graduateAndUpgrade() function can be executed by the principal without any prior verification that students have been fully reviewed.

This omission allows the session to end and the system to upgrade even with students pending review or with scores below the required minimum.

This breaks an invariant defined in the documentation, which states that "the system upgrade must not occur if any student has not received 4 grades."

Impact:

  • Students who have not been reviewed can graduate.

  • The system can advance to LevelTwo with an incomplete educational state.

  • The integrity of the selection process and trust in the evaluation are compromised.

Proof of Concept:

  1. Deploy the LevelOne contract via proxy.

  2. Six students enroll by paying the tuition fee.

  3. No student receives any reviews (reviewCount == 0).

  4. The principal calls graduateAndUpgrade() with a new implementation (LevelTwo).

function test_CannotGraduateWithUnevaluatedStudents() public {
address proxy = ERC1967Proxy_Deployed_LevelOne();
address[] memory students = new address[](6);
students[0] = clara;
students[1] = dan;
students[2] = eli;
students[3] = fin;
students[4] = grey;
students[5] = harriet;
for (uint256 i; i < students.length; i++) {
vm.startPrank(students[i]);
usdc.approve(proxy, schoolFees);
LevelOne(proxy).enroll();
vm.stopPrank();
}
LevelTwo levelTwo = new LevelTwo();
vm.startPrank(principal);
bytes memory data = abi.encodeWithSignature("graduate()");
LevelOne(proxy).graduateAndUpgrade(address(levelTwo), data);
}

The upgrade completes successfully despite no student being reviewed.
Log:

@> ├─ emit Upgraded(implementation: LevelTwo: [0x5991A2dF15A8F6A256D3Ec51E99254Cd3fb576A9])

Tools Used:

Manual Review, Foundry

Recommended Mitigation:

Introduce an internal function checkStudentsEvaluated() that verifies each student has received exactly 4 reviews before allowing graduation. If any student does not meet the requirement, the function reverts with the error HH__StudentHasNotBeenFullyReviewed().

+ error HH__StudentHasNotBeenFullyReviewed(address);
+ function _checkStudentsEvaluated() internal view {
+ uint256 totalStudents = listOfStudents.length;
+ for (uint256 i; i < totalStudents; i++) {
+ address student = listOfStudents[i];
+ if (reviewCount[student] < 4) {
+ revert HH__StudentHasNotBeenFullyReviewed(student);
+ }
+ }
+ }
function graduateAndUpgrade(address _levelTwo, bytes memory) public onlyPrincipal {
...
+ _checkStudentsEvaluated();
...
}
Updates

Lead Judging Commences

yeahchibyke Lead Judge 4 months 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.