Summary
In LevelOne::graduateAndUpgrade the protocol should calculate the amount that should be sent to the principal and all teachers. The issue is that the protocol send 35% of the bursary to every single teacher instead of share these 35% to all teachers.This simply means that we are sending more than what we need to send and also the bursary wont be 60% for LevelTwo.
In other words these two requirements will be broken with the current logic:
Impact
The protocol will send more money than it should be sending to teachers, and lose that money for LevelTwo.
Tools Used
Manual Review
Proof Of Code: Add this test and run it. If it passes it means that bigger amount of money(35% of bursary instead) than should
function test_money_sent_when_graduate() public schoolInSession {
levelTwoImplementation = new LevelTwo();
levelTwoImplementationAddress = address(levelTwoImplementation);
bytes memory data = abi.encodeCall(LevelTwo.graduate, ());
uint256 startBursary = levelOneProxy.bursary();
uint256 aliceStartBalance = usdc.balanceOf(alice);
vm.prank(principal);
levelOneProxy.graduateAndUpgrade(levelTwoImplementationAddress, data);
LevelTwo levelTwoProxy = LevelTwo(proxyAddress);
uint256 payForTeachers = (startBursary * TEACHER_WAGE) / PRECISION;
uint256 principalPay = (startBursary * PRINCIPAL_WAGE) / PRECISION;
uint256 alicePayment = payForTeachers / levelTwoProxy.getTotalTeachers();
console2.log('startBursary', startBursary);
console2.log('payForTeachers', payForTeachers);
console2.log('alicePayment', alicePayment);
console2.log('aliceStartBalance', aliceStartBalance);
console2.log('aliceEndBalance', usdc.balanceOf(alice));
uint256 aliceEndBalance = usdc.balanceOf(alice);
assertEq(aliceStartBalance, 0);
assertLt(aliceStartBalance, aliceEndBalance);
assertGt(aliceEndBalance, alicePayment);
}
Recommendations
Devide the part of the bursary for teaches between all teachers
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 teachersPayment = (bursary * TEACHER_WAGE) / PRECISION;
+ uint256 payPerTeacher = teachersPayment / listOfTeachers.length;
uint256 principalPay = (bursary * PRINCIPAL_WAGE) / PRECISION;
_authorizeUpgrade(_levelTwo);
for (uint256 n = 0; n < totalTeachers; n++) {
usdc.safeTransfer(listOfTeachers[n], payPerTeacher);
}
usdc.safeTransfer(principal, principalPay);
}