Hawk High

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

Incorrect teacher payment calculation leads to overpayment and function failure

Summary

In the graduateAndUpgrade function, the teacher payment is calculated as (bursary * TEACHER_WAGE) / PRECISION and applied to each teacher individually. This does not split the teacher wage among all teachers, causing the total payment to exceed the bursary when there are multiple teachers, leading to transaction failure.

Vulnerability Details

The current code defines:

uint256 payPerTeacher = (bursary * TEACHER_WAGE) / PRECISION;

Where TEACHER_WAGE is 35 and PRECISION is 100, meaning each teacher receives 35% of the bursary. The function then transfers this amount to each teacher:

for (uint256 n = 0; n < totalTeachers; n++) {
usdc.safeTransfer(listOfTeachers[n], payPerTeacher);
}

For example:

  • 1 teacher: 35% (teachers) + 5% (principal) = 40% of bursary

  • 2 teachers: 70% (teachers) + 5% (principal) = 75% of bursary

  • 3 teachers: 105% (teachers) + 5% (principal) = 110% of bursary

With three or more teachers, the total exceeds 100%, causing the safeTransfer to revert due to insufficient funds.

https://github.com/CodeHawks-Contests/2025-05-hawk-high/blob/3a7251910c31739505a8699c7a0fc1b7de2c30b5/src/LevelOne.sol#L302-L310

add thos test to LevelOneAndGraduateTest:

function test_graduate_fails_with_three_teachers() public {
// Add three teachers
address thirdTeacher = makeAddr("third_teacher");
vm.startPrank(principal);
levelOneProxy.addTeacher(alice);
levelOneProxy.addTeacher(bob);
levelOneProxy.addTeacher(thirdTeacher);
vm.stopPrank();
// Enroll students (6 students, each paying schoolFees)
_studentsEnrolled();
// Start session
vm.prank(principal);
levelOneProxy.startSession(70);
// Deploy level two implementation
levelTwoImplementation = new LevelTwo();
levelTwoImplementationAddress = address(levelTwoImplementation);
bytes memory data = abi.encodeCall(LevelTwo.graduate, ());
// Expect revert when calling graduateAndUpgrade due to insufficient funds
vm.prank(principal);
vm.expectRevert();
levelOneProxy.graduateAndUpgrade(levelTwoImplementationAddress, data);
}

Impact

  • The graduateAndUpgrade function fails with three or more teachers, halting fund distribution and contract upgrades.

  • Funds may remain locked in the contract, leading to potential financial loss.

Tools Used

Recommendations

Adjust the payment logic to distribute the teacher wage among all teachers.

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.