MyCut

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

Stuck funds due to updating the storage variable `remainingRewards`

Summary

The intention of the Protocol is transfering remaining rewards to all claimants. However, the remaining rewards is a storage variable, which is calculated by using its own value instead of using the actual balance of the contest. If the actual remaining funds in the contest differ from that variable, it is possible that funds are stuck or not enough funds are available to be distributed to the claimants, which leads to failing transfers (insufficient funds of the Pot).

Vulnerability Details

If somehow the calculation of Pot::remainingRewards is messed up, the Pot::managerCut and Pot::claimantCut are not calculated correctly, which breaks the intended functionality of the protocol.

Impact

The distribution of the remaining rewards is not calculated correctly in Pot::closePot, which leads to stuck funds and incorrect distribution — either the manager and claimants receive smaller cuts, or they receive disproportionately large fractions of the pot, leaving the last claimants in the loop with nothing.

Tools Used

Manual Review

Recommendations

Don't update the storage variable to track the rewards in the pot by calculating the remaining rewards with the value itself.

Instead, use actual balance of the contest and calculate the cuts based on this value.

function claimCut() public {
address player = msg.sender;
uint256 reward = playersToRewards[player];
if (reward <= 0) {
revert Pot__RewardNotFound();
}
playersToRewards[player] = 0;
- remainingRewards -= reward;
+ remainingRewards = i_token.balanceOf(address(this)) - reward;
claimants.push(player);
_transferReward(player, reward);
}
function closePot() external onlyOwner {
if (block.timestamp - i_deployedAt < 90 days) {
revert Pot__StillOpenForClaim();
}
if (remainingRewards > 0) {
- uint256 managerCut = remainingRewards / managerCutPercent;
+ uint256 managerCut = i_token.balanceOf(address(this)) / managerCutPercent;
i_token.transfer(msg.sender, managerCut);
- uint256 claimantCut = (remainingRewards - managerCut) / i_players.length;
+ uint256 claimantCut = (i_token.balanceOf(address(this)) - managerCut) / i_players.length;
for (uint256 i = 0; i < claimants.length; i++) {
_transferReward(claimants[i], claimantCut);
}
}
}
Updates

Lead Judging Commences

equious Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Too generic

Support

FAQs

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