Hawk High

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

LevelOne::graduateAndUpgrade function could be called by the Principal before the end of a school session which breaks one of the Protocol Invariant

Summary

The LevelOne::graduateAndUpgrade function can be called by the principal prematurely before the expiry of a school session, The protocol doesn't consider checking the LevelOne::sessionEnd variable before graduating students and performing other actions like disbursing the shares and upgrading the contracts

Vulnerability Details

At the start of the LevelOne:graduateAndUpgrade function there are no checks if current block.timestamp is greater than the LevelOne::sessionEnd which was set while calling LevelOne:startSession

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

Failure to check LevelOne::sessionEnd variable when calling the LevelOne::graduateAndUpgrade function will disrupt the intent of the protocol, which could be exploited by an unfair principal, preventing more potential students from joining a particular school session, in a way this affects the increase in shares of teachers

Tools Used

Manual Review

Recommendations

One of the few Solutions the protocol could do includes adding a check and a custom revert at the start of the function as seen below

error HH_schoolInSession(uint256 currentTime)
function graduateAndUpgrade(address \_levelTwo, bytes memory) public onlyPrincipal {
if (_levelTwo == address(0)) {
revert HH__ZeroAddress();
}
+ if(block.timestamp < sessionEnd) revert HH_schoolInSession(block.timestamp)
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 19 days 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

yeahchibyke Lead Judge 19 days 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

Support

FAQs

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