Hawk High

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

There is no way for the school session to end, breaking the entire protocol.

Summary

The 'inSession' variable is only able to become true when a session is started but has no way of becoming false again. This causes multiple invariants to be broken as well as allowing only 1 school session to run.

Vulnerability Details

At the start of a school session, the 'inSession' variable is set to true, allowing for students to enroll and preventing students from being expelled, but it is also supposed to prevent 'graduateAndUpgrade' from successfully being called but there is not require statement or revert preventing that from happening:

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

Breaks 2 key invariants:

  • A school session lasts 4 weeks

  • System upgrade cannot take place unless school's sessionEnd has reached

This can allow students to receive reviews and have their grades changed after the session was supposed to end, allows the system to upgrade at any time (this is also due to another bug that allows upgrades even if all of the students haven't gotten their 4 reviews yet, which breaks another variant), and will cause the 'inSession' variable to not be reset meaning there will only ever be 1 active game that is always in session, even past the 'sessionEnd' date.

Tools Used

Manual review and Foundry

Recommendations

In the 'graduateAndUpgrade' function, include a line that resets the 'inSession' variable to false:

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;
+ inSession = false;
_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 about 1 month ago
Submission Judgement Published
Validated
Assigned finding tags:

can graduate without session end

`graduateAndUpgrade()` can be called successfully even when the school session has not ended

session state not updated

`inSession` not updated after during upgrade

Support

FAQs

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