MyCut

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

Lack of Check for Duplicate Claims (Players Can Claim Rewards Multiple Times)

Description:

The claimCut function does not include a mechanism to prevent players from claiming their rewards more than once. While the function sets the player's reward to zero after a claim, it does not explicitly check if the player has already claimed their reward before allowing the operation. This omission could lead to scenarios where a player could attempt to claim their reward multiple times before the state is fully updated.

https://github.com/Cyfrin/2024-08-MyCut/blob/946231db0fe717039429a11706717be568d03b54/src/Pot.sol#L37-L51

function claimCut() public {
//Vul1
//there should be a check here for when the pot is closed
address player = msg.sender;
uint256 reward = playersToRewards[player];
if (reward <= 0) {
revert Pot__RewardNotFound();
}
playersToRewards[player] = 0;
remainingRewards -= reward;
claimants.push(player);
_transferReward(player, reward);
}

Impact:

Allowing players to claim rewards multiple times could lead to double dipping, where a player unfairly receives more than their allocated reward. This behavior could deplete the remaining rewards, reducing the total available to other players or disrupting the intended distribution of funds. In a worst-case scenario, it could lead to an uneven distribution of rewards and potential financial loss to the system.

Proof of Concept:

  1. Deploy the contract and allocate rewards to several players.

  2. A player claims their reward using the claimCut function.

  3. Without any checks, the player attempts to call claimCut again.

  4. Observe that the function allows the player to initiate a claim, potentially leading to unexpected behavior and state inconsistencies.

Recommended Mitigation:

Add a check at the beginning of the claimCut function to ensure that a player cannot claim their reward more than once. This can be achieved by verifying that the player’s reward is greater than zero before proceeding with the claim:

Example Fix:

function claimCut() public {
uint256 reward = playersToRewards[msg.sender];
require(reward > 0, "Reward already claimed or not available");
playersToRewards[msg.sender] = 0;
remainingRewards -= reward;
claimants.push(msg.sender);
_transferReward(msg.sender, reward);
}

This mitigation ensures that each player can only claim their reward once, preventing multiple claims and maintaining the integrity of the reward distribution process.

Updates

Lead Judging Commences

equious Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Other

Support

FAQs

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