Hawk High

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

Incorrect `payPerTeacher` Calculation in `LevelOne::graduateAndUpgrade`, Teacher receive more than the correct share of bursary, it leads to outage of funds and leads to disturbe core functionaliy of the smart contract.

Description

The LevelOne::graduateAndUpgrade function incorrectly calculates payPerTeacher by applying the bursary and TEACHER_WAGE factor without distributing the result among the number of teachers. This miscalculation causes incorrect fund allocation, either overpaying or underpaying teachers depending on their count.

Vulnerable Function

function graduateAndUpgrade(address _levelTwo, bytes memory) public onlyPrincipal {
...
uint256 totalTeachers = listOfTeachers.length;
uint256 payPerTeacher = (bursary * TEACHER_WAGE) / PRECISION; // Incorrect
for (uint256 n = 0; n < totalTeachers; n++) {
usdc.safeTransfer(listOfTeachers[n], payPerTeacher); // Miscalculated payout
}
}

Impact

  • Financial Risk: Teachers may receive more or less than the correct share of the bursary.

  • Overdraft: The contract may transfer more than it holds or intends to pay.

  • Unfair Distribution: Rewards are misaligned with teacher contribution and count.

  • Bursary Drain: Future levels may receive reduced funding due to overpayment.

Proof of Concept

function test_confirm_OnwerCanCompleteSessionBeforeTime() public schoolInSession {
vm.warp(block.timestamp + 1 weeks); // setting time duration less than a week.
levelTwoImplementation = new LevelTwo();
levelTwoImplementationAddress = address(levelTwoImplementation);
bytes memory data = abi.encodeCall(LevelTwo.graduate, ());
vm.prank(principal);
levelOneProxy.graduateAndUpgrade(levelTwoImplementationAddress, data);
LevelTwo levelTwoProxy = LevelTwo(proxyAddress);
console2.log(IERC20(usdc).balanceOf(address(alice))); // Teacher 1 receiveing 10,500 -> correct value must be 5,250
console2.log(IERC20(usdc).balanceOf(address(bob))); // Teacher 2 receiving 10,500 - correct value must be 5,250
console2.log(IERC20(address(usdc)).balanceOf(address(proxyAddress))); // Proxy contract holding contract states it must receive 18,000
}

Recommendation

Correct the calculation by dividing the total teacher wages by the number of teachers:

uint256 totalTeachers = listOfTeachers.length;
require(totalTeachers > 0, "HH: No teachers registered");
uint256 totalTeacherWages = (bursary * TEACHER_WAGE) / PRECISION;
uint256 payPerTeacher = totalTeacherWages / totalTeachers;
for (uint256 n = 0; n < totalTeachers; n++) {
usdc.safeTransfer(listOfTeachers[n], payPerTeacher);
}
Updates

Lead Judging Commences

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