Hawk High

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

Review Requirement Bypass Allows Unqualified Graduation

Summary

System upgrade can occur if any student has not gotten 4 reviews.

Vulnerability Details

This vulnerability stems from two missing checks/updates:

  1. The giveReview() function fails to increment the reviewCount mapping for students when a review is given. This means the reviewCount for every student remains at 0, regardless of how many reviews they actually receive.

  2. The graduateAndUpgrade() function does not include a check to ensure that all students have accumulated the necessary 4 reviews before the upgrade process is allowed to proceed.

In order to get the review count from students, implement this geter in contract LevelOne

function getStudentReviewCount(address _student) external view returns (uint256) {
return reviewCount[_student];
}

Then below test demonstrates system can graduate to level two with review count zero.

function test_can_graduate_without_review() public schoolInSession {
levelTwoImplementation = new LevelTwo();
levelTwoImplementationAddress = address(levelTwoImplementation);
console2.log("Clara's review count: ", levelOneProxy.getStudentReviewCount(clara));
assertEq(levelOneProxy.getStudentReviewCount(clara), 0);
bytes memory data = abi.encodeCall(LevelTwo.graduate, ());
vm.prank(principal);
levelOneProxy.graduateAndUpgrade(levelTwoImplementationAddress, data);
}

Impact

  • Bypasses Graduation Prerequisite: Students can advance to the next level without fulfilling the required review criteria.

  • Renders Review System Meaningless: The review mechanism fails as a mandatory gating factor for progression.

Tools Used

Recommendations

Implement the missing update in giveReview() and add a check in graduateAndUpgrade() to enforce the requirement that all students must have exactly 4 reviews before graduation can occur.

function giveReview(address _student, bool review) public onlyTeacher {
if (!isStudent[_student]) {
revert HH__StudentDoesNotExist();
}
+ reviewCount[_student] += 1;
// @audit did not update reviewCount, reviewCount will always less than 5
require(reviewCount[_student] < 5, "Student review count exceeded!!!");
require(block.timestamp >= lastReviewTime[_student] + reviewTime, "Reviews can only be given once per week");
// where `false` is a bad review and true is a good review
if (!review) {
studentScore[_student] -= 10; // q only bad review will affect score, good review will not change anything
}
// Update last review time
lastReviewTime[_student] = block.timestamp;
emit ReviewGiven(_student, review, studentScore[_student]);
}
function graduateAndUpgrade(address _levelTwo, bytes memory) public onlyPrincipal {
if (_levelTwo == address(0)) {
revert HH__ZeroAddress();
}
// @audit should check if all stduents got 4 reviews
+ uint256 totalStudents = listOfStudents.length;
+ for (uint256 n = 0; n < totalStudents; n++) {
+ if (reviewCount[listOfStudents[n]] != 4) {
+ revert HH__DoesNotReviewAllStudents();
+ }
+ }
// ..skip
}
Updates

Lead Judging Commences

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