Description:
Ideally the number of players should be equal to the number of rewards, but there isn't a check of this.
Impact:
If by mistake the owner miss a player but create the contest with the rewards of that player, first the missing player won't be able to claim their reward and second after the clamming period the rewards of that missing player will be distributed to the rest claimants.
Proof of Concept:
Paste next code in the TestMyCut.sol file
As you see in the assert player1 and player2 receive part of the rewards that were planned to be given to the player3
function testLackOfNumOfPlayersAndNumOfRewardsEqualityCheckEndsInLostOfFunds() mintAndApproveTokens public {
address player3 = makeAddr("player3");
vm.startPrank(user);
rewards = [20, 50, 100];
players = [player1, player2];
totalRewards = 170;
contest = ContestManager(conMan).createContest(players, rewards, IERC20(ERC20Mock(weth)), totalRewards);
ContestManager(conMan).fundContest(0);
vm.stopPrank();
vm.startPrank(player1);
Pot(contest).claimCut();
vm.stopPrank();
vm.startPrank(player2);
Pot(contest).claimCut();
vm.stopPrank();
vm.warp(91 days);
vm.startPrank(user);
ContestManager(conMan).closeContest(contest);
vm.stopPrank();
uint256 finalPlayer1Balance = IERC20(ERC20Mock(weth)).balanceOf(player1);
uint256 finalPlayer2Balance = IERC20(ERC20Mock(weth)).balanceOf(player2);
uint256 expectedFinalPlayer1Balance = rewards[0] + ((rewards[2] - (rewards[2]/ 10))/players.length);
uint256 expectedFinalPlayer2Balance = rewards[1] + ((rewards[2] - (rewards[2]/ 10))/players.length);
assertEq(finalPlayer1Balance, expectedFinalPlayer1Balance);
assertEq(finalPlayer2Balance, expectedFinalPlayer2Balance);
}
Recommended Mitigation:
Add a condition to check if the number of players is the same than the number of rewards.
function createContest(address[] memory players, uint256[] memory rewards, IERC20 token, uint256 totalRewards)
public
onlyOwner
returns (address)
{
+ if (players.length != rewards.length) {
+ revert ContestManager__RewardsAndPlayersNotMatch();
+ }
Pot pot = new Pot(players, rewards, token, totalRewards);
contests.push(address(pot));
contestToTotalRewards[address(pot)] = totalRewards;
return address(pot);
}