Hawk High

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

Bursary Amount Not Updated After Fee Distribution

Summary

In the graduateAndUpgrade function of contract LevelOne, the bursary variable is not updated after distributing fees to teachers and principal. This leaves 60% of the funds in the bursary account even after graduation, potentially allowing those funds to be reused in future operations, leading to accounting discrepancies.

Vulnerability Details

When the graduation process occurs, 35% of the bursary is distributed to teachers and 5% to the principal. However, the bursary state variable remains unchanged:

function graduateAndUpgrade(
address _levelTwo,
bytes memory data
) public onlyPrincipal {
// Calculate payments
uint256 totalTeachers = listOfTeachers.length;
uint256 payPerTeacher = (bursary * TEACHER_WAGE) / PRECISION;
uint256 principalPay = (bursary * PRINCIPAL_WAGE) / PRECISION;
// Distribute funds
for (uint256 n = 0; n < totalTeachers; n++) {
usdc.safeTransfer(listOfTeachers[n], payPerTeacher);
}
usdc.safeTransfer(principal, principalPay);
// The bursary amount is not updated here
// Should have: bursary = bursary * (100 - TEACHER_WAGE - PRINCIPAL_WAGE) / PRECISION;
// Rest of the function...
}

After paying out 40% of the bursary funds (35% to teachers and 5% to the principal), the remaining 60% should either be:

  1. Set aside for the next school session

  2. Clearly accounted for in the state variables

  3. Sent to another account for safekeeping

Instead, the bursary variable remains at its original value, suggesting those funds are still available.

Impact

  • Inconsistent accounting: The system thinks it still has 100% of the bursary when only 60% remains

  • Potential for double-spending: If the graduation process is somehow repeated (e.g., in a new session), more funds than available might be allocated

  • Misleading financial reporting: Reports of available funds would be inflated by 40%

  • Potential loss of funds: The unaccounted 60% might be forgotten or misused

Tools Used

  • Manual code review

  • Logic analysis

Recommendations

Update the bursary variable after distributing funds to accurately reflect the remaining amount:

function graduateAndUpgrade(
address _levelTwo,
bytes memory data
) public onlyPrincipal {
// Calculate payments
uint256 totalTeachers = listOfTeachers.length;
uint256 payPerTeacher = (bursary * TEACHER_WAGE) / PRECISION;
uint256 principalPay = (bursary * PRINCIPAL_WAGE) / PRECISION;
// Distribute funds
for (uint256 n = 0; n < totalTeachers; n++) {
usdc.safeTransfer(listOfTeachers[n], payPerTeacher);
}
usdc.safeTransfer(principal, principalPay);
// Update bursary to reflect remaining amount (60%)
bursary = (bursary * (PRECISION - TEACHER_WAGE - PRINCIPAL_WAGE)) / PRECISION;
// Rest of the function...
}
Updates

Lead Judging Commences

yeahchibyke Lead Judge 6 months ago
Submission Judgement Published
Validated
Assigned finding tags:

bursary not updated

The bursary is not updated after wages have been paid in `graduateAndUpgrade()` function

yeahchibyke Lead Judge 6 months ago
Submission Judgement Published
Validated
Assigned finding tags:

bursary not updated

The bursary is not updated after wages have been paid in `graduateAndUpgrade()` function

Support

FAQs

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