Hawk High

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

Incorrect Calculation of `payPerTeacher` in `LevelOne::graduateAndUpgrade()` will pay out the total allocated wages for all teachers to each teacher grossly mismanaging the bursary funds.

Summary

Incorrect Calculation of payPerTeacher in LevelOne::graduateAndUpgrade() will mismanage and could potentially drain the Bursary funds before all Teachers and the Principal can be paid. payPerTeacheris calculated as a whooping 35% of the entire bursarywhich is actually supposed to be the total wage amount to be distributed among all the teachers. This inevitably breaks the Payment Structure in the protocols Invariants.

Vulnerability Details

payPerTeacher is wrongly calculated here in:

uint256 payPerTeacher = (bursary * TEACHER_WAGE) / PRECISION;

this calculation only gives the general percentage of bursary to be distributed among all the teachers. Whereas it should also be divided by the variable totalTeachersvariable to get the accurate payPerTeacher

Impact

Incorrect payPerTeacherleads to all the bursaryfunds getting depleted rapidly as teachers are paid. This breaks the Payment Structure in the invariants.

poc

consider the test code below for 2 teachers added and 6 students enrolled written into the available LevelOneAndGraduateTest.t.sol . This test passes and proves that payPerTeacheris wrongly calculated as the total wages for all teachers which breaks the payment structure invariant.

function test_wrongPayPerTeacher_poc() public {
_teachersAdded();
_studentsEnrolled();
uint256 bursary = levelOneProxy.bursary();
uint256 totalTeachers = levelOneProxy.getTotalTeachers();
uint256 teacherWagePercentage = levelOneProxy.TEACHER_WAGE();
uint256 remainingBursaryPercentage = 65;
uint256 precision = levelOneProxy.PRECISION();
uint256 wrongPayPerTeacher = (bursary * teacherWagePercentage) / precision;
uint256 actualPayPerTeacher = (bursary * teacherWagePercentage) / (precision * levelOneProxy.getTotalTeachers());
uint256 expectedRainingBursaryAfterPayingTeachers = (bursary * remainingBursaryPercentage) / precision;
uint256 actualRemainingBursaryAfterPayingTeachers = bursary - (actualPayPerTeacher * totalTeachers);
uint256 wrongRemainingBursaryAfterPayingTeachers = bursary - (wrongPayPerTeacher * totalTeachers);
console2.log("bursary:", levelOneProxy.bursary());
console2.log("wrongPayPerTeacher:", wrongPayPerTeacher);
console2.log("actualPayPerTeacher:", actualPayPerTeacher);
assert(actualPayPerTeacher < wrongPayPerTeacher);
assert(actualPayPerTeacher * totalTeachers == wrongPayPerTeacher);
assert(actualRemainingBursaryAfterPayingTeachers == expectedRainingBursaryAfterPayingTeachers);
assert(wrongRemainingBursaryAfterPayingTeachers != expectedRainingBursaryAfterPayingTeachers);
}

Tools Used

Manual Review

Recommendations

Consider replacing the calculation of payPerTeacher with the correct calculation as shown below;

uint256 totalTeachers = listOfTeachers.length;
-uint256 payPerTeacher = (bursary * TEACHER_WAGE) / PRECISION;
+uint256 payPerTeacher = (bursary * TEACHER_WAGE) / PRECISION * totalTeachers;
Updates

Lead Judging Commences

yeahchibyke Lead Judge 16 days ago
Submission Judgement Published
Validated
Assigned finding tags:

incorrect teacher pay calculation

`payPerTeacher` in `graduateAndUpgrade()` is incorrectly calculated.

yeahchibyke Lead Judge 16 days ago
Submission Judgement Published
Validated
Assigned finding tags:

incorrect teacher pay calculation

`payPerTeacher` in `graduateAndUpgrade()` is incorrectly calculated.

Support

FAQs

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