Hawk High

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

[H-1] LevelTwo Contract Breaks UUPS Upgradeability Chain

Severity

Critical

Impact

When the system is upgraded from LevelOne to LevelTwo, the contract will permanently lose its upgradeability feature. This will lock the remaining 60% of the bursary funds in the LevelTwo contract with no way to access them, as there is no mechanism to upgrade further or withdraw these funds.

Description

In the UUPS pattern, both the current implementation and any future implementation must inherit from UUPSUpgradeable to maintain the upgradeability chain.

The current implementation has the following critical flaws:

  • LevelOne.sol correctly inherits from UUPSUpgradeable and Initializable

  • LevelTwo.sol only inherits from Initializable and not from UUPSUpgradeable

  • LevelTwo.sol doesn't implement the required _authorizeUpgrade function

When the graduateAndUpgrade function in LevelOne is called, the system will upgrade to LevelTwo. However, since LevelTwo doesn't implement the UUPS pattern, it will not be possible to upgrade the system further.

According to the readme requirements, the bursary should maintain 60% of its value after the upgrade (after paying 35% to teachers and 5% to the principal). Without the ability to upgrade from LevelTwo or a withdrawal mechanism, these funds will be permanently locked.

Tools Used

Manual code review

Recommended Mitigation

// LevelTwo.sol
- contract LevelTwo is Initializable {
+ contract LevelTwo is Initializable, UUPSUpgradeable {
using SafeERC20 for IERC20;
// ... rest of contract code ...
+ function _authorizeUpgrade(address newImplementation) internal override {
+ require(msg.sender == principal, "Not authorized");
+ }
}

These changes ensure LevelTwo correctly maintains the UUPS upgradeability pattern by:

  1. Adding the UUPSUpgradeable inheritance

  2. Implementing the required _authorizeUpgrade function with appropriate access control

A PoC isn't necessary as the missing inheritance and function are structural issues evident in the code. Static analysis is sufficient to confirm that upgradeability will be broken after deployment.

Updates

Lead Judging Commences

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

stuck funds in system

Funds are stuck in `LevelOne()` contract after upgrade.

Support

FAQs

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