Hawk High

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

L-07: Unclear Specification for Teacher's 35% Share if No Teachers Exist at Payout

Summary

The README states "teachers share of 35% of bursary". If listOfTeachers is empty at the time of graduateAndUpgrade, the H-02 fix ensures no division by zero occurs and no payments are attempted to teachers. However, the 35% share allocated for teachers effectively remains in the bursary (as totalTeacherShare calculated from the bursary isn't paid out). It's unclear if this retention is the intended behavior or if this share should be handled differently (e.g., rolled over, reallocated).

Vulnerability Details

In graduateAndUpgrade (after H-02 fix):

// uint256 totalTeachers = listOfTeachers.length;
// uint256 totalTeacherShare = (currentBursary * TEACHER_WAGE) / PRECISION;
// if (totalTeachers == 0) {
// // payPerTeacher remains 0, no payments to teachers.
// // totalTeacherShare is calculated but not distributed to teachers.
// }
// bursary = currentBursary - principalPay - totalTeacherShare; // If totalTeacherShare is not fully paid out
// (e.g. no teachers, or dust from division)
// this line would still subtract the full share.
// It should be:
// bursary = currentBursary - principalPay - actualTeacherPayout;
// where actualTeacherPayout is sum of payPerTeacher * totalTeachers.
// Or simpler: after H-02 fix where payPerTeacher is calculated,
// total amount paid to teachers = payPerTeacher * totalTeachers.
// The `bursary` update in the H-04 consolidated fix is:
// bursary = currentBursary - principalPay - totalTeacherShare;
// This means the 35% (totalTeacherShare) IS deducted from the conceptual bursary
// for calculating the remaining 60%.
// If totalTeacherShare isn't paid out (e.g. no teachers), it simply means the contract
// physically holds more USDC than the `bursary` state var implies for "remaining".
// This is a subtle point. The *funds* remain if not paid. The *accounting* in `bursary` (post L-03 fix)
// assumes 35% is "spent" from perspective of calculating 60% remainder.

The bursary variable, after the L-03 fix, is updated to reflect the 60% remaining after accounting for the principal's 5% and the teachers' 35% nominal shares. If the teachers' 35% isn't actually paid out (due to no teachers), those funds physically remain in the contract's USDC balance but are conceptually "spent" from the bursary state variable's perspective when calculating the 60% for LevelTwo. This behavior might be acceptable, but it's not explicitly stated.

Impact

  • Potential Misalignment with Unstated Financial Policies: If there are specific off-chain agreements or expectations about how unallocated teacher wages should be handled, the current on-chain behavior (funds remain in contract, bursary state var reflects 60% of original total) might not match.

  • Clarity for Stakeholders: Stakeholders (principal, future system designers) might benefit from explicit documentation on this scenario.

This is more an informational point about specification clarity than a direct vulnerability causing loss of funds or incorrect calculations given the current logic. The funds are safe; their accounting and intended use in this specific scenario could be clearer.

Tools Used

Manual Review, Logical Analysis.

Recommendations

Clarify in the project documentation or specifications how the teachers' 35% share of the bursary should be handled if no teachers are eligible for payment during graduateAndUpgrade.
Options include:

  1. Current Behavior (Implicit): The funds remain in the contract, and the bursary state variable for LevelTwo reflects 60% of the original LevelOne bursary. This is acceptable if documented.

  2. Rollover: Explicitly state that these funds are part of the LevelTwo bursary (effectively making LevelTwo's bursary 95% of LevelOne's if no teachers were paid). This would require adjusting the bursary update logic in LevelOne.

  3. Reallocation: Specify if this share should go to the principal or another designated address/purpose.

No code change is strictly necessary if the current implicit behavior is acceptable, but documentation should reflect it. If a different behavior is desired, LevelOne.sol#graduateAndUpgrade would need adjustment in how bursary is updated when totalTeacherShare isn't fully paid out to teachers. The current L-03 fix proposal (bursary = currentBursary - principalPay - totalTeacherShare;) correctly implements the "60% should reflect" invariant, assuming the 35% is "spoken for" whether or not it's paid out.

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.