Hawk High

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

High Severity - Incorrect Wage Calculation in `LevelOne::graduateAndUpgrade` (Overpayment to Teachers + Bursary Underfunding)

Summary

The graduateAndUpgrade function incorrectly calculates teacher wages, paying each teacher 35% of the bursary instead of splitting 35% among all teachers, leading to overpayment and underfunding the bursary.

Vulnerability Details

  • Root Cause: The calculation payPerTeacher = (bursary * TEACHER_WAGE) / PRECISION applies 35% per teacher, not divided among them.

  • Attack Path: With 2 teachers, each receives 35% (total 70%) + 5% for the Principal = 75%, leaving only 25% for the bursary instead of 60%.

  • Affected Component: Wage distribution logic and bursary balance.

Proof of Concept

function test_wage_overpayment() public schoolInSession {
vm.warp(block.timestamp + 5 weeks);
uint256 initialBursary = levelOneProxy.bursary();
uint256 expectedTeacherTotal = (initialBursary * 35) / 100 / 2; // Split 35%
vm.prank(principal);
levelOneProxy.graduateAndUpgrade(address(new LevelTwo()), "");
assertGt(usdc.balanceOf(alice), expectedTeacherTotal); // Gets 35% alone
assertEq(levelOneProxy.bursary(), initialBursary * 25 / 100); // Expected: 60%
}
  • Expected: Teachers split 35% (e.g., 17.5% each for 2 teachers), bursary retains 60%.

  • Actual: Each teacher gets 35%, bursary drops to 25%.

Impact

  • Financial Imbalance: Overpays teachers, reducing the bursary below the intended 60%.

  • Invariant Violation: Breaks the rule that 60% of the bursary should remain post-upgrade.

Recommendations

Correct the wage calculation to split the 35% among teachers. Here’s the diff:

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 = totalTeachers > 0 ? (bursary * TEACHER_WAGE / PRECISION) / totalTeachers : 0;
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:

incorrect teacher pay calculation

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

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