Hawk High

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

Payment calculation in `LevelOne::graduateAndUpgrade` is incorrect, causing the payment to be incorrect

[H-3] Payment calculation in LevelOne::graduateAndUpgrade is incorrect, causing the payment to be incorrect

Description: As described in the documentation, the payment should be calculated as follows:

  • Principal - 5% of bursary

  • Teachers - share 35% of bursary

  • The remainig 60% is left in the bursary

Impact: Calculations in LevelOne::graduateAndUpgrade are incorrect, causing usdc payment to be mishandled

Proof of Concepts:

Code For example:
  1. 6 students enter with 5 000 USDC fee each. That brings 30 000 USDC to the bursary.

  2. There is 1 principal and 2 teachers

  3. Given then the bursary is split as follows:

    • Principal - 5% of bursary = 1 500 USDC

    • Teachers - share 35% of bursary = 10 500 USDC total or 5 250 each

    • Bursary should be left with 18 000

After adding logs to LevelOne::graduateAndUpgrade we get the following:

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;
@> console2.log("Principal pay: ", principalPay / 1e18);
@> console2.log("Pay per teacher: ", payPerTeacher / 1e18);
_authorizeUpgrade(_levelTwo);
for (uint256 n = 0; n < totalTeachers; n++) {
usdc.safeTransfer(listOfTeachers[n], payPerTeacher);
}
usdc.safeTransfer(principal, principalPay);
@> console2.log("Bursary: ", bursary / 1e18);
}
Principal pay: 1500
Pay per teacher: 10500
Bursary: 30000

As we can see, principal is calculated correctly, pay per teacher is incorrect, which is the total sum for all teachers but its called payPerTeacher and bursary is never updated, leading future upgrades to calculate incorrecly wages.

Recommended mitigation:

Given the invariants, we recommend to update LevelOne::graduateAndUpgrade as follows:

function graduateAndUpgrade(address _levelTwo, bytes memory) public onlyPrincipal {
if (_levelTwo == address(0)) {
revert HH__ZeroAddress();
}
uint256 totalTeachers = listOfTeachers.length;
+ uint256 principalPay = (bursary * PRINCIPAL_WAGE) / PRECISION;
+ uint256 payPerTeacher = ((bursary * TEACHER_WAGE) / totalTeachers) / PRECISION;
+ bursary -= principalPay;
+ bursary -= payPerTeacher * totalTeachers;
usdc.safeTransfer(principal, principalPay);
for (uint256 n = 0; n < totalTeachers; n++) {
usdc.safeTransfer(listOfTeachers[n], payPerTeacher);
}
_authorizeUpgrade(_levelTwo);
}

And running the previous test now give:

Principal pay: 1500
Pay per teacher: 5250
Bursary: 18000
Updates

Lead Judging Commences

yeahchibyke Lead Judge 3 months ago
Submission Judgement Published
Validated
Assigned finding tags:

incorrect teacher pay calculation

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

yeahchibyke Lead Judge 3 months 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.