The new implementation (LevelTwo) alters the order, removes, and omits state variables compared to the original (LevelOne). Because the system uses an ERC1967 UUPS proxy (via delegatecall), these changes corrupt the proxy’s storage layout and lead to unpredictable behavior immediately after upgrade.
Storage Slots Are Positional
Upgradeable proxies do not match variables by name; they read and write storage by slot index.
Reordering & Removal
LevelTwo moves schoolFees and sessionEnd out of their original slots, drops mappings (reviewCount, lastReviewTime), and omits immutable/constants in between.
Slot Misalignment
After upgrade, when LevelTwo reads slot 2, it expects schoolFees but finds the old sessionEnd. Mappings now point at wrong bases and arrays (listOfStudents, listOfTeachers) read from unrelated slots.
Broken Token Reference
The usdc address (formerly slot 13) becomes stale or zero, since LevelTwo reads it from a shifted slot.
Corrupted State: Core variables like bursary, cutOffScore, and mappings (isStudent, studentScore) return nonsensical values or defaults.
Loss of Functionality: Enrollment, payment distribution, and review features will silently malfunction or revert.
Fund Loss / Misrouting: usdc.safeTransfer may send tokens to the zero address or an unintended contract.
Denial of Service: Broken loops or invalid state may permanently lock the contract.
Manual Review
Preserve Storage Layout
Do not reorder or remove existing state variables.
Append New Variables Only
Add any new state variables at the end of the declaration list.
Use Storage Gaps
Reserve uint256[XX] private __gap; slots for future expansion.
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.