MyCut

First Flight #23
Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: high
Valid

Locked funds due to missing withdraw function in ContestManager contract

Summary

The ContestManager contract lacks a withdraw function that allows the owner to retrieve tokens from the Pot contracts once the closePot() function has been executed. As a result, when the pot is closed and the manager's cut is transferred, the funds remain locked in the ContestManager contract, preventing access to them.

Vulnerability Details

The ContestManager contract is designed to manage multiple contest Pot contracts, and when a contest is closed using the closeContest() function, the Pot contract calculates and transfers the manager's cut of the remaining rewards using this line in the closePot() function:

i_token.transfer(msg.sender, managerCut);

However, the ContestManager contract does not include a function that allows the owner to withdraw these transferred funds. As a result, the funds become locked in the contract, and the owner is unable to access them. This missing withdrawal mechanism leads to a permanent loss of tokens unless the ContestManager contract is updated.

Example Scenario:

  1. Initial Setup:

    • The ContestManager contract creates a new Pot with 1000 tokens in total rewards.

    • The manager closes the contest after the claim period ends, transferring the manager’s cut to the contract’s owner address.

  2. Scenario:

    • The i_token.transfer(msg.sender, managerCut) in closePot() successfully transfers the manager's cut (e.g., 100 tokens).

    • However, the ContestManager contract does not have a withdraw function to retrieve these tokens, locking them inside the contract.

  3. Impact:

    • The 100 tokens remain locked in the ContestManager contract, inaccessible to the manager, causing a permanent loss of funds.

Impact

  1. Locked Funds: Without a withdraw function, the tokens transferred to the manager's address during closePot() remain locked inside the contract, making them inaccessible.

  2. Inability to Access Rewards: The manager cannot access the rewards earned, reducing the usability and flexibility of the system.

Steps to Reproduce the Issue:

  1. Step 1: Deploy the ContestManager contract.

  2. Step 2: Create a Pot contract with tokens.

  3. Step 3: Close the contest using the closeContest() function.

  4. Expected Outcome: The manager should be able to withdraw the funds transferred during the closePot() function call.

  5. Actual Outcome: The funds are locked inside the contract with no method to withdraw them.

Tools Used

Manual Review

Recommendations

To resolve this issue, implement a withdraw function that allows the manager to withdraw the transferred tokens from the ContestManager contract.

Steps to Fix:

  1. Add a withdraw Function: This function will allow the owner to withdraw tokens from the contract after the Pot contract has transferred the manager's cut:

    function withdraw(IERC20 token, uint256 amount) external onlyOwner {
    uint256 balance = token.balanceOf(address(this));
    require(amount <= balance, "Insufficient contract balance");
    token.transfer(owner(), amount);
    }

    This ensures the owner can retrieve any tokens that have been transferred to the contract during the closing of contests.

  2. After the Pot transfers the manager’s cut to the ContestManager contract, the manager can use the new withdraw function to retrieve these funds.

Updates

Lead Judging Commences

equious Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Owner's cut is stuck in ContestManager

Support

FAQs

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