Hawk High

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

Payment Disrbursement When `LevelOne:graduateAndUpgrade` Called Is Incorrect

Description:
When wages are paid out during the call to LevelOne:graduateAndUpgrade, the structure is supposed to follow the invariant:

* `principal` gets 5% of `bursary`
* `teachers` share of 35% of bursary
* remaining 60% should reflect in the bursary after upgrade

However this is not the case as teachers are each receiving 35% of the bursary, rather than collectively sharing 35%.

Impact:
This violates the invariant given and would also cause the contract to run out of funds if there are 3 teachers or more.

Proof of Concept:
The following test shows that the remaining funds within the contract is less than expected, which should be 60% of the initial bursary before wages are paid.

function test_payment_structure_wrong() public schoolInSession {
levelTwoImplementation = new LevelTwo();
levelTwoImplementationAddress = address(levelTwoImplementation);
bytes memory data = abi.encodeCall(LevelTwo.graduate, ());
uint256 initialBursary = schoolFees * 6;
assertEq(usdc.balanceOf(proxyAddress), initialBursary);
vm.prank(principal);
levelOneProxy.graduateAndUpgrade(levelTwoImplementationAddress, data);
// 5% of 30k = 1500 -> principal
// 35% of 30k = 10500 -> shared by teachers
// 60% of 30k = 18000 -> remaining in bursary
uint256 bursaryRemaining = 60 * initialBursary / 100;
assertLt(usdc.balanceOf(proxyAddress), bursaryRemaining);
}

Recommended Mitigation:
The payPerTeacher variable should be further divided by the number of teachers in the school as shown below:

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 payPerTeacher = (bursary * TEACHER_WAGE) / (PRECISION * listOfTeachers.length);
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 27 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.