Mystery Box

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

Owner Can Withdraw All Funds, Leaving Winners Without Payouts

[L-01] Owner Can Withdraw All Funds, Leaving Winners Without Payouts

Summary

The withdrawFunds function allows the owner to withdraw the entire contract balance without considering pending rewards owed to winners. This creates a risk where the owner can withdraw all funds, leaving the winners without the ability to claim their prizes.

Vulnerability Details

The current implementation of the withdrawFunds function enables the owner to transfer all funds from the contract, as shown below:

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

This function does not account for the rewards owed to users (winners). As a result, the owner could drain all funds, even if there are outstanding rewards to be claimed by users. This creates a serious vulnerability where users could be defrauded.

Impact

The owner could potentially perform a "rug pull" by withdrawing all the funds from the contract, leaving winners unable to claim their rewards. This could lead to loss of trust and financial harm to the participants.

Tools Used

Manual Review

Recommendations

  1. Implement a mechanism that ensures the contract always retains enough funds to cover outstanding rewards. For example, keep track of the total pending rewards and ensure that the owner can only withdraw the amount that exceeds the pending payouts.

  2. Suggested modification:

function withdrawFunds() public {
require(msg.sender == owner, "Only owner can withdraw");
// Calculate the total amount of rewards owed to users
uint256 totalPendingRewards = calculatePendingRewards();
// Ensure owner can only withdraw excess funds
uint256 withdrawableAmount = address(this).balance - totalPendingRewards;
require(withdrawableAmount > 0, "No funds available for withdrawal");
(bool success, ) = payable(owner).call{value: withdrawableAmount}("");
require(success, "Transfer failed");
}
function calculatePendingRewards() internal view returns (uint256) {
uint256 totalPending = 0;
// Logic to sum up all rewards owed to users
.
.
.
// Iterate over rewardsOwned and calculate the total amount of pending rewards
return totalPending;
}

This implementation ensures that the owner can only withdraw funds that are not reserved for winners' rewards, preventing any possibility of rug-pulling users.

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!