Hawk High

First Flight #39
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Impact: high
Likelihood: high
Invalid

Uncoverable Funds in LevelOne to LevelTwo Migration

Summary

The upgrade from LevelOne to LevelTwo creates a permanent loss of 60% of the collected funds which remain trapped in the proxy contract. This occurs because only 40% of funds are distributed during the upgrade, and LevelTwo lacks mechanisms to access the remaining funds.

Vulnerability Details

During the upgrade from LevelOne to LevelTwo via the graduateAndUpgrade() function, only 40% of the funds (35% to teachers, 5% to principal) are distributed. The remaining 60% of funds become permanently locked in the proxy because:

  1. Missing Recovery Logic: LevelTwo does not implement any function to access the remaining 60% of funds.

    // LevelOne.sol - line 389-408
    function graduateAndUpgrade(address _levelTwo, bytes memory) public onlyPrincipal {
    if (_levelTwo == address(0)) {
    revert HH__ZeroAddress();
    }
    uint256 totalTeachers = listOfTeachers.length;
    uint256 payPerTeacher = (bursary * TEACHER_WAGE) / PRECISION; // 35%
    uint256 principalPay = (bursary * PRINCIPAL_WAGE) / PRECISION; // 5%
    _authorizeUpgrade(_levelTwo);
    for (uint256 n = 0; n < totalTeachers; n++) {
    usdc.safeTransfer(listOfTeachers[n], payPerTeacher);
    }
    usdc.safeTransfer(principal, principalPay);
    }

2.No Fund Management in LevelTwo: The LevelTwo contract has declarations matching LevelOne but lacks implementation of fund withdrawal or management:

// LevelTwo.sol - relevant parts
contract LevelTwo is Initializable {
using SafeERC20 for IERC20;
address principal;
uint256 public bursary;
IERC20 usdc;
// Empty initialization function
function graduate() public reinitializer(2) {}
// No functions to manage or withdraw remaining funds
}

Impact

High Impact: This issue results in permanent loss of 60% of all collected school fees, directly impacting the school's financial resources and sustainability.

The financial impact scales with the number of enrolled students. For example:

  • With 100 students paying 1000 USDC each: 60,000 USDC permanently locked

  • With 1000 students paying 1000 USDC each: 600,000 USDC permanently locked

Tools Used

Manual code review

Recommendations

Add Fund Management to LevelTwo: Implement functions to manage the remaining 60% of funds in the LevelTwo contract.

// Add to LevelTwo.sol
function withdrawRemainingFunds() public onlyPrincipal {
uint256 remainingFunds = usdc.balanceOf(address(this));
if (remainingFunds > 0) {
usdc.safeTransfer(principal, remainingFunds);
}
}
Updates

Lead Judging Commences

yeahchibyke Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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