Hawk High

First Flight #39
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: high
Valid

Uninitialized State in UUPS Upgrade Process in LevelTwo.sol

Summary

The graduate() function in LevelTwo.sol lacks state migration logic, causing loss of critical data (students, teachers, bursary) during UUPS proxy upgrades. This breaks contract continuity and violates upgrade pattern requirements.

Vulnerability Details

Affected Files:

  • LevelTwo.sol (Line 26: function graduate() public reinitializer(2) {})

  • LevelOne.sol (Lines 284-302: graduateAndUpgrade function)

Technical Analysis:
The UUPS upgrade pattern requires explicit state migration when changing implementations. The current implementation:

  1. Empty Hook: LevelTwo::graduate() contains no logic to copy storage from previous implementation

  2. State Isolation: Proxy storage remains isolated from new implementation

  3. Critical Data Loss:

    • Student/teacher lists reset to empty arrays

    • Bursary balance becomes zero

    • Access control roles are not preserved

Proof of Concept:

function test_graduate_leaves_state_uninitialized() public schoolInSession {
// Pre-upgrade state
uint256 preUpgradeStudents = levelOneProxy.getTotalStudents(); // 6
uint256 preUpgradeBursary = levelOneProxy.bursary(); // 60,000 USDC
// Execute upgrade
levelTwoImplementation = new LevelTwo();
vm.prank(principal);
levelOneProxy.graduateAndUpgrade(address(levelTwoImplementation), "");
// Post-upgrade assertions
LevelTwo levelTwo = LevelTwo(proxyAddress);
assertEq(levelTwo.getTotalStudents(), 0); // Fails if >0 [4]
assertEq(levelTwo.bursary(), preUpgradeBursary); // Fails if >0 [4]
}

PoC Result:

[FAIL] test_graduate_leaves_state_uninitialized()
[1] Students not migrated: 6 != 0
[2] Bursary mismatch: 0 != 60000000000000000000000

Impact

  • Permanent loss of student records and funds

  • Broken access control system

  • Contract becomes unusable post-upgrade

  • Requires emergency snapshot restoration

Tools Used

Foundry (Forge)

Manual code review

Recommendations

Implement explicit state migration in LevelTwo::graduate():

function graduate() public reinitializer(2) {
// Migrate core state from previous implementation
LevelOne previous = LevelOne(msg.sender);
listOfStudents = previous.getListOfStudents();
listOfTeachers = previous.getListOfTeachers();
bursary = previous.bursary();
cutOffScore = previous.cutOffScore();
principal = previous.getPrincipal();
// Preserve storage layout compatibility
inSession = previous.getSessionStatus();
sessionEnd = previous.getSessionEnd();
}
Updates

Lead Judging Commences

yeahchibyke Lead Judge 6 months ago
Submission Judgement Published
Validated
Assigned finding tags:

failed upgrade

The system doesn't implement UUPS properly.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.