LevelTwo.sol does not maintain the same storage layout as LevelOne.sol by omitting several state variables (schoolFees, reviewCount, lastReviewTime). This mismatch will cause state corruption upon upgrade, as LevelTwo will read data from incorrect storage slots, rendering it non-functional and leading to data integrity loss.
The UUPS proxy pattern requires that the new implementation contract preserves the storage layout of the previous contract for all inherited state variables. LevelOne.sol declares state variables like schoolFees, reviewCount, and lastReviewTime. LevelTwo.sol omits these. When an upgrade occurs, the storage slots are interpreted by the new contract's layout. For example:
LevelOne storage order (simplified):
0. principal (address)
inSession (bool)
schoolFees (uint256)
sessionEnd (uint256) (immutable reviewTime doesn't occupy a standard storage slot here)
bursary (uint256)
cutOffScore (uint256)
isTeacher (mapping)
isStudent (mapping)
studentScore (mapping)
reviewCount (mapping)
lastReviewTime (mapping)
listOfStudents (array)
listOfTeachers (array)
usdc (address)
If LevelTwo omits schoolFees, then its sessionEnd variable (if it's the second uint256 after inSession in LevelTwo's declaration) would try to read from slot 2, which actually holds LevelOne.schoolFees. This misalignment continues for subsequent variables, corrupting all inherited state.
State corruption upon upgrade will render LevelTwo non-functional. Its state variables will hold entirely incorrect values, breaking all logic within LevelTwo. This can lead to a complete loss of data integrity for critical information such as the bursary amount, studentScores, sessionEnd times, and teacher/student lists. The school system would become unusable and funds could be misinterpreted or locked.
Manual Review, Understanding of EVM storage layout and UUPS proxy patterns.
Ensure LevelTwo.sol declares all state variables in the exact same order and type as LevelOne.sol up to the last variable of LevelOne. If variables like schoolFees, reviewCount, and lastReviewTime are intentionally deprecated for LevelTwo's logic, they must still be declared (e.g., as private) to preserve the storage layout. New state variables for LevelTwo must be appended after all of LevelOne's variables.
Code Modification for LevelTwo.sol (State Variable Section):
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.