Hawk High

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

System is able to upgrade even if not all students have 4 reviews.

Summary

The system is able to upgrade through use of the 'graduateAndUpgrade' function even if not all students have 4 reviews as there is not check for it, breaking a key invariant.

Vulnerability Details

The protocol states that each student is required to have 4 reviews in order for the system to be able to upgrade (through the use of the 'graduateAndUpgrade' function. Within this function there are no require or revert statements that prevent the upgrade from occurring if any students don't have 4 reviews.

function graduateAndUpgrade(address _levelTwo, bytes memory) public onlyPrincipal {
if (_levelTwo == address(0)) {
revert HH__ZeroAddress();
}
uint256 totalTeachers = listOfTeachers.length;
uint256 payPerTeacher = (bursary * TEACHER_WAGE) / PRECISION;
uint256 principalPay = (bursary * PRINCIPAL_WAGE) / PRECISION;
_authorizeUpgrade(_levelTwo);
for (uint256 n = 0; n < totalTeachers; n++) {
usdc.safeTransfer(listOfTeachers[n], payPerTeacher);
}
usdc.safeTransfer(principal, principalPay);
}

Impact

This allows the system to be upgraded when it should not be allowed to. Ultimately this could prevent students from being able to graduate if a teacher hasn't given them all necessary reviews even if they would have a passing grade. A malicious prinicpal could also call this function to force wages to be paid out earlier than they should.

Tools Used

Manual review and Foundry

Recommendations

Implement a check that will cause the function to revert if not all students have the required amount of reviews (optional but recommended: create a custom error named HH__InsufficientReviews() and a public constant uint256 variable with the name and value REQUIRED_REVIEWS = 4):

function graduateAndUpgrade(address _levelTwo, bytes memory) public onlyPrincipal {
if (_levelTwo == address(0)) {
revert HH__ZeroAddress();
}
+ // Check all students have exactly 4 reviews
+ for (uint256 i = 0; i < listOfStudents.length; i++) {
+ address student = listOfStudents[i];
+ if (reviewCount[student] != REQUIRED_REVIEWS) {
+ revert HH__InsufficientReviews();
+ }
+ }
uint256 totalTeachers = listOfTeachers.length;
uint256 payPerTeacher = (bursary * TEACHER_WAGE) / PRECISION;
uint256 principalPay = (bursary * PRINCIPAL_WAGE) / PRECISION;
_authorizeUpgrade(_levelTwo);
for (uint256 n = 0; n < totalTeachers; n++) {
usdc.safeTransfer(listOfTeachers[n], payPerTeacher);
}
usdc.safeTransfer(principal, principalPay);
}
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.