Hawk High

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

Wrong calculation of `payPerTeacher` at `LevelOne::graduateAndUpgrade` which breaks the payment structure.

**Description:** The `graduateAndUpgrade` function is responsible for upgrading the system to level two and paying wages to the principal at 5% and 35% shared among the teachers evenly. However the function does not share the 35% evenly to every teacher
​
```js
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 principalPay = (bursary * PRINCIPAL_WAGE) / PRECISION;
​
_authorizeUpgrade(_levelTwo); // @audit this seems to nothing
​
for (uint256 n = 0; n < totalTeachers; n++) {
usdc.safeTransfer(listOfTeachers[n], payPerTeacher);
}
​
usdc.safeTransfer(principal, principalPay);
}
```
​
​
**Impact:** This causes the contract to break the following invariant
- Payment structure is as follows:
- `principal` gets 5% of `bursary`
- `teachers` share of 35% of bursary
- remaining 60% should reflect in the bursary after upgrade
​
<details>
<summary> Proof of Code </summary>
​
Add the following in the `LevelOneAndGraduateTest.t.sol`
​
```js
function test_can_pay_wages() public schoolInSession{
levelTwoImplementation = new LevelTwo();
levelTwoImplementationAddress = address(levelTwoImplementation);
uint256 remainingBursary = (levelOneProxy.bursary() * 60) / levelOneProxy.PRECISION();
​
bytes memory data = abi.encodeCall(LevelTwo.graduate, ());
​
vm.prank(principal);
levelOneProxy.graduateAndUpgrade(levelTwoImplementationAddress, data);
​
assertEq(remainingBursary, usdc.balanceOf(address(levelOneProxy)));
}
```
</details>
​
**Tools Used** Manual Review and Foundry
​
**Recommended Mitigation:** This update should be made on the `graduateAndUpgrade` function
​
```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 = ((bursary * TEACHER_WAGE) / PRECISION)/totalTeachers;
​
uint256 principalPay = (bursary * PRINCIPAL_WAGE) / PRECISION;
​
_authorizeUpgrade(_levelTwo); // @audit this seems to nothing
​
for (uint256 n = 0; n < totalTeachers; n++) {
usdc.safeTransfer(listOfTeachers[n], payPerTeacher);
}
​
usdc.safeTransfer(principal, principalPay);
}
```
Updates

Lead Judging Commences

yeahchibyke Lead Judge over 1 year 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.

Give us feedback!