The graduateAndUpgrade function in the LevelOne contract distributes 40% of funds to teachers and principal but fails to reset the bursary value afterward. This creates an accounting inconsistency where the full bursary amount persists in state after partial distribution, potentially leading to overpayment in future distributions if additional upgrades are implemented.
In the graduateAndUpgrade function, tokens are distributed to teachers and principal based on percentages of the bursary value:
The critical issue is that after distributing 40% of the funds (35% to teachers, 5% to principal), the bursary state variable is never updated to reflect this distribution. The value remains unchanged, creating a discrepancy between:
The actual USDC balance in the contract (60% of original bursary)
The bursary state variable value (still 100% of original bursary)
This discrepancy carries over to the LevelTwo contract since the storage layout preserves the bursary value:
This vulnerability has high severity because:
It creates a permanent accounting inconsistency between actual token balance and recorded bursary value
It could lead to attempt to distribute funds that don't exist if any future implementation uses the bursary value
If LevelTwo or a subsequent upgrade attempts to distribute funds based on bursary, it would try to distribute more than is available, causing transactions to fail
The accounting error could hide other balance issues or complicate auditing
The likelihood is high because:
The issue occurs 100% of the time during upgrade
The missing reset is a fundamental part of fund distribution logic
There's no mechanism to correct this after the upgrade
Quantifiable impact:
If bursary shows 100,000 USDC but actual balance is 60,000 USDC, any function using bursary would overestimate available funds by 40,000 USDC
Manual code review
Reset Bursary After Distribution:
2.Add Bursary Reconciliation in LevelTwo:
3.Add Post-Upgrade Check in LevelTwo's graduate():
The bursary is not updated after wages have been paid in `graduateAndUpgrade()` function
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.