MyCut

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

Error in claiming reward if sum of rewards is not equal to total rewards

Summary

When a Pot contract is created, the amount of rewards each player should receive and total rewards are recorded in the contract. However, these are two separate variables updated independently. Misconfiguration will result in at least one player to not be able to claim the reward from the Pot contract after it is funded.

Vulnerability Details

The vulnerability lies in the constructor function of the Pot contract, specifically in line 27 and line 33 of the contract.

The playersToRewards mapping and remainingRewards variable is updated separately and there are no checks done to ensure that sum of rewards received by players is equivalent to the expected total rewards. This would lead to a potential arithmetic underflow revert at line 44 when a player tries to call claimCut.

Proof of Concept

Working Test Case

function testTotalRewardsUnchecked() public mintAndApproveTokens {
address player3 = makeAddr("player3");
players = [player1, player2, player3];
// Sum of rewards != totalRewards
rewards = [2, 1, 1];
totalRewards = 3;
// Create contest and fund pot
vm.startPrank(user);
contest = ContestManager(conMan).createContest(players, rewards, IERC20(ERC20Mock(weth)), totalRewards);
ContestManager(conMan).fundContest(0);
vm.stopPrank();
// Player 1 and player 2 claim their cut
vm.startPrank(player1);
Pot(contest).claimCut();
vm.stopPrank();
vm.startPrank(player2);
Pot(contest).claimCut();
vm.stopPrank();
// Player 3 tries to claim their cut but failed
assertEq(Pot(contest).checkCut(player3), 1);
vm.startPrank(player3);
vm.expectRevert();
Pot(contest).claimCut();
vm.stopPrank();
}

Impact

The result of this vulnerability would lead to at least one player not being able to claim the expected reward from the Pot contract after it is funded.

Tools Used

Foundry, manual review

Recommended Mitigation

To mitigate this vulnerability, the sum of the rewards array should be calculated and verified to be equivalent to totalRewards in the constructor function.

constructor(address[] memory players, uint256[] memory rewards, IERC20 token, uint256 totalRewards) {
+ uint256 sum = 0;
+ for (uint256 i = 0; i < rewards.length; i++) {
+ sum += rewards[i];
+ }
+ require(sum == totalRewards, "Sum of rewards should be equal to total rewards");
i_players = players;
i_rewards = rewards;
i_token = token;
i_totalRewards = totalRewards;
remainingRewards = totalRewards;
i_deployedAt = block.timestamp;
// i_token.transfer(address(this), i_totalRewards);
for (uint256 i = 0; i < i_players.length; i++) {
playersToRewards[i_players[i]] = i_rewards[i];
}
}
Updates

Lead Judging Commences

equious Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

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