Hawk High

First Flight #39
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Impact: high
Likelihood: medium
Invalid

Division by Zero in graduateAndUpgrade() When No Teachers Exist

Description:
The graduateAndUpgrade() function in the LevelOne contract contains a critical flaw that causes the function to revert when no teachers exist in the system. The function calculates payPerTeacher by dividing a portion of the bursary by the total number of teachers (totalTeachers). However, if listOfTeachers.length is zero, this calculation will cause a division by zero error, reverting the entire transaction and preventing both the contract upgrade and principal payment distribution.

Code Snippet:

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);
for (uint256 n = 0; n < totalTeachers; n++) {
usdc.safeTransfer(listOfTeachers[n], payPerTeacher);
}
usdc.safeTransfer(principal, principalPay);
}

Impact: This vulnerability creates a situation where the contract becomes permanently locked in its current implementation if all teachers are removed. This would:

  1. Prevent contract upgrades, blocking critical improvements or bugfixes

  2. Lock the principal's payment in the contract

  3. Freeze the remaining bursary funds indefinitely

  4. Force the school system to remain in its current state without possibility for advancement

Proof of Concept:

  1. The principal removes all teachers using the removeTeacher() function

  2. The principal attempts to call graduateAndUpgrade() with a valid new implementation address

  3. The transaction reverts with a "division by zero" error when executing the for loop

  4. The principal cannot receive their payment, and the contract upgrade fails

Recommended Mitigation: Add a check to handle the zero-teacher case separately:

function graduateAndUpgrade(address _levelTwo, bytes memory) public onlyPrincipal {
if (_levelTwo == address(0)) {
revert HH__ZeroAddress();
}
uint256 totalTeachers = listOfTeachers.length;
uint256 principalPay = (bursary * PRINCIPAL_WAGE) / PRECISION;
_authorizeUpgrade(_levelTwo);
// Handle the case where there are no teachers
if (totalTeachers > 0) {
uint256 payPerTeacher = (bursary * TEACHER_WAGE) / PRECISION / totalTeachers;
for (uint256 n = 0; n < totalTeachers; n++) {
usdc.safeTransfer(listOfTeachers[n], payPerTeacher);
}
}
usdc.safeTransfer(principal, principalPay);
}
Updates

Lead Judging Commences

yeahchibyke Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.