The LevelTwo contract omits the schoolFees variable that exists in LevelOne, breaking the expected storage layout. Since Solidity stores state variables sequentially in storage slots, removing or reordering inherited variables in an upgradeable contract leads to storage collisions, where new variables overwrite existing data. This can cause unpredictable behavior, including fund misrouting, broken access control, or permanent data corruption.
Shared Storage via Proxy
Upgradeable contracts share one storage layout defined by the proxy. Changing that layout in newer implementations causes serious inconsistencies.
Slot Misalignment
By removing schoolFees, the usdc variable is now occupying the original slot for schoolFees, and its expected value becomes corrupted.
Downstream Corruption
Calls to usdc.safeTransfer(...) will likely fail, misroute tokens, or interact with an invalid address.
Fund Corruption: Transfers using usdc may go to unintended addresses due to corrupted address values.
Broken Logic: Access control, balances, and other logic relying on overwritten slots will malfunction.
Irrecoverable State: Once data is corrupted by a storage collision, it cannot be restored.
Manual Code Review
To prevent storage collisions, preserve the exact variable layout from previous versions:
If new variables are needed, append them after all existing ones.
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.