Hawk High

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

Missing Student Requirements Validation Before System Upgrade

Summary

The graduateAndUpgrade function in the LevelOne contract lacks critical validation checks required by the project's invariants. It does not verify that students have received all required reviews, met the cutoff score, or that the session end time has been reached, allowing premature or invalid graduations that violate core system rules.

Vulnerability Details

According to the project invariants specified in the README.md:

- Students must have gotten all reviews before system upgrade. System upgrade should not occur if any student has not gotten 4 reviews (one for each week)
- Any student who doesn't meet the `cutOffScore` should not be upgraded
- System upgrade cannot take place unless school's `sessionEnd` has reached

However, the graduateAndUpgrade function does not implement any of these required checks:

// @audit-high lack of check students all gotten reviews and meet `cutOffScore` and `sessionEnd` before upgrade
function graduateAndUpgrade(address _levelTwo, bytes memory) public onlyPrincipal {
if (_levelTwo == address(0)) {
revert HH__ZeroAddress();
}
uint256 totalTeachers = listOfTeachers.length;
// @written payPerTeacher calculated error causing the contract can't upgrade and can't graduate
uint256 payPerTeacher = (bursary * TEACHER_WAGE) / PRECISION;
uint256 principalPay = (bursary * PRINCIPAL_WAGE) / PRECISION;
_authorizeUpgrade(_levelTwo);
for (uint256 n = 0; n < totalTeachers; n++) {
// will revert here because the insufficient usdc
usdc.safeTransfer(listOfTeachers[n], payPerTeacher);
}
usdc.safeTransfer(principal, principalPay);
// @written didn't send the 60% of bursary to the new contract.
}

This omission allows the principal to initiate an upgrade at any time, even if:

  1. Students haven't received all their required weekly reviews

  2. Students below the cutoff score are incorrectly allowed to graduate

  3. The session hasn't properly ended (before the 4-week period is complete)

These violations undermine the core academic integrity of the system and can result in inappropriate graduations and fund distribution.

Impact

The lack of validation has severe consequences for the system:

  1. Students who haven't met the academic requirements could be improperly graduated

  2. The school session could be prematurely ended without completing the required review process

  3. Core project invariants are violated, breaking the contract's fundamental rules

  4. The payment system might distribute funds before all required educational services are provided

This issue is rated High severity because it breaks the fundamental academic rules of the system and allows the principal to bypass critical contract invariants, potentially defrauding students.

Tools Used

Manual code review

Recommendation

Add all required validation checks to the graduateAndUpgrade function:

function graduateAndUpgrade(address _levelTwo, bytes memory) public onlyPrincipal {
if (_levelTwo == address(0)) {
revert HH__ZeroAddress();
}
// Check that session end time has been reached
require(block.timestamp >= sessionEnd, "School session has not ended yet");
// Check that all students have received all required reviews (4 weeks)
uint256 studentCount = listOfStudents.length;
for (uint256 i = 0; i < studentCount; i++) {
address student = listOfStudents[i];
require(reviewCount[student] >= 4, "Not all students have received all required reviews");
}
// Filter out students who didn't meet the cutoff score
address[] memory graduatingStudents = new address[](studentCount);
uint256 graduatingCount = 0;
for (uint256 i = 0; i < studentCount; i++) {
address student = listOfStudents[i];
if (studentScore[student] >= cutOffScore) {
graduatingStudents[graduatingCount] = student;
graduatingCount++;
}
}
// Rest of the function (payment distribution logic, etc.)
uint256 totalTeachers = listOfTeachers.length;
uint256 totalTeacherShare = (bursary * TEACHER_WAGE) / PRECISION;
uint256 payPerTeacher = totalTeachers > 0 ? totalTeacherShare / totalTeachers : 0;
uint256 principalPay = (bursary * PRINCIPAL_WAGE) / PRECISION;
_authorizeUpgrade(_levelTwo);
// Transfer funds to teachers
for (uint256 n = 0; n < totalTeachers; n++) {
usdc.safeTransfer(listOfTeachers[n], payPerTeacher);
}
// Transfer funds to principal
usdc.safeTransfer(principal, principalPay);
// Handle the 60% remaining funds and track graduating students
// (Refer to H-03 report for how to handle the remaining funds)
emit Graduated(_levelTwo);
}

This implementation ensures that all required conditions are met before the system can be upgraded, maintaining the integrity of the educational system and compliance with the project's invariants.

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.