Description:
uint256 payPerTeacher = (bursary * TEACHER_WAGE) / PRECISION;
This computes 35% of bursary per teacher, not total. Distributing that to N teachers pays out bursary _ 0.35 _ N, which can exceed available funds and revert.
Impact: With multiple teachers, total payouts can exceed bursary, causing underflow.
Proof of Concept: Include the following test in the LevelOneAndGraduateTest.t.sol
file:
function testOverpaymentRevert() public {
vm.startPrank(principal);
levelOneProxy.addTeacher(alice);
levelOneProxy.addTeacher(bob);
levelOneProxy.addTeacher(harriet);
vm.stopPrank();
vm.startPrank(clara);
usdc.approve(address(levelOneProxy), schoolFees);
levelOneProxy.enroll();
vm.stopPrank();
vm.prank(principal);
levelOneProxy.startSession(70);
levelTwoImplementation = new LevelTwo();
levelTwoImplementationAddress = address(levelTwoImplementation);
bytes memory data = abi.encodeCall(LevelTwo.graduate, ());
vm.startPrank(principal);
vm.expectRevert();
levelOneProxy.graduateAndUpgrade(levelTwoImplementationAddress, data);
vm.stopPrank();
}
Recommended Mitigation:
function graduateAndUpgrade(address _levelTwo, bytes memory) public onlyPrincipal {
…
uint256 totalTeachers = listOfTeachers.length;
+ uint256 totalTeacherShare = (bursary * TEACHER_WAGE) / PRECISION;
+ uint256 payPerTeacher = totalTeacherShare / totalTeachers;
- uint256 payPerTeacher = (bursary * TEACHER_WAGE) / PRECISION;
…
}