Mystery Box

First Flight #25
Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: high
Invalid

Centralization Risk in withdrawFunds() Function

Summary

The withdrawFunds() function allows the owner to withdraw all the funds from the contract. There are no restrictions to prevent the owner from doing this before users can claim their rewards, potentially resulting in users losing access to their expected rewards

Vulnerability Details

The function withdrawFunds() allows only the owner to withdraw the contract's balance. Since there are no mechanisms to ensure that users have claimed their rewards before the owner withdraws funds, the owner could potentially drain the contract, leaving users unable to claim their rightful rewards.

  • Steps to Reproduce:

    1. Deploy the contract and allow users to accumulate rewards.

    2. Before any user claims their rewards, the owner calls withdrawFunds().

    3. The entire contract balance is transferred to the owner, and users can no longer claim their rewards as the contract has no funds
      left.

  • Vulnerable Code Snippet

    function withdrawFunds() public {
    require(msg.sender == owner, "Only owner can withdraw");
    (bool success,) = payable(owner).call{value: address(this).balance}("");
    require(success, "Transfer failed");
    }

Impact

  • Consequences: The owner can withdraw all the funds in the contract, potentially preventing users from claiming their token rewards or other entitlements. This creates a centralization risk where the owner could act maliciously and drain the contract, undermining the trust of users and potentially leading to a "rug pull" scenario.

  • Affected Parties: All users interacting with the contract who are eligible to receive rewards could lose their entitlements if the owner drains the contract before users can claim their rewards.

Tools Used

Manual review

Recommendations

Consider Implementing safeguards to ensure that users have claimed their rewards before the owner can withdraw funds. This could be done by :

  • locking funds that belong to users

  • adding a withdrawal mechanism that prevents the owner from accessing funds until user obligations are fulfilled.

As I have shown below:

- function withdrawFunds() public {
+ function withdrawFunds() public {
+ require(usersHaveClaimedAllRewards(), "Users have unclaimed rewards");
require(msg.sender == owner, "Only owner can withdraw");
(bool success,) = payable(owner).call{value: address(this).balance}("");
require(success, "Transfer failed");
}

  • using a multisig wallet for withdrawals

Updates

Appeal created

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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

Give us feedback!