Hawk High

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

No check for student reviews or sessionEnd validation. Which violates the Invariants rule

Summary

No check for student reviews or sessionEnd validation. Which violates the Invariants rule

Vulnerability Details

The contract intends to follow these rules:
System upgrade cannot take place unless school's sessionEnd has reached
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)
But there's no check for student reviews or sessionEnd validation in LevelOne::graduateAndUpgrade, which allows the system to upgrade when there remains students who haven't gotten 4 reviews or the school's sessionEnd has not reached.
Proof of Code Run the following test in LevelOneAndGraduateTest.t.sol

function test_lack_of_checks() public schoolInSession {
levelTwoImplementation = new LevelTwo();
levelTwoImplementationAddress = address(levelTwoImplementation);
bytes memory data = abi.encodeCall(LevelTwo.graduate, ());
// prints "100", unreviewed student
console2.log(levelOneProxy.studentScore(clara));
// unreached session end
assertGt(levelOneProxy.getSessionEnd(), block.timestamp);
vm.prank(principal);
levelOneProxy.graduateAndUpgrade(levelTwoImplementationAddress, data);
LevelTwo levelTwoProxy = LevelTwo(proxyAddress);
console2.log(levelTwoProxy.bursary());
console2.log(levelTwoProxy.getTotalStudents());
}

Impact

Breaks the invariant rules.

Tools Used

Manual.

Recommendations

Add checks and validations for student reviews and sessionEnd in LevelOne::graduateAndUpgrade

function graduateAndUpgrade(address _levelTwo, bytes memory) public onlyPrincipal {
if (_levelTwo == address(0)) {
revert HH__ZeroAddress();
}
+ // validate session end
+ require(block.timestamp >= sessionEnd, "Session not ended");
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
7 months ago
yeahchibyke Lead Judge 7 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.

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.

Give us feedback!