[M-01] Players can claim even after the 90 day period set by the Contest Manager
Description: The protocol assumes that the contest manager calls the Pot::closePot
after 90 days. If the contest manager doesn't close the pot players can still call Pot::claimCut
function to claim their rewards even after the 90 day period of the contest. This allows any player to claim their rewards whenever they want.
Impact: This functionality goes against the protocol's functionality. Allowing players to claim whenever they want is unfair to claimants who claimed their rewards in time.
Proof of code:
Add the below function to test/TestMyCut.t.sol
function test90dayPeriod() public mintAndApproveTokens {
ContestManager cm = ContestManager(conMan);
address[] memory p = new address[](1);
uint256[] memory r = new uint256[](1);
uint tr = 13;
p[0] = makeAddr("_player1");
r[0] = 5;
vm.startPrank(user);
uint deployedAt = block.timestamp;
address pot = cm.createContest(p, r, weth, tr);
cm.fundContest(0);
vm.stopPrank();
vm.warp(deployedAt + 90 days + 1);
vm.prank(p[0]);
Pot(pot).claimCut();
}
Run the below test command in the terminal
forge test --mt test90dayPeriod -vv
Which will result in output
[⠑] Compiling...
[⠑] Compiling 3 files with 0.8.20
[⠃] Solc 0.8.20 finished in 2.94s
Compiler run successful!
Ran 1 test for test/TestMyCut.t.sol:TestMyCut
[PASS] test90dayPeriod() (gas: 726792)
Logs:
User Address: 0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D
Contest Manager Address 1: 0x7BD1119CEC127eeCDBa5DCA7d1Bd59986f6d7353
Minting tokens to: 0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D
Approved tokens to: 0x7BD1119CEC127eeCDBa5DCA7d1Bd59986f6d7353
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.05ms (449.10µs CPU time)
Ran 1 test suite in 297.43ms (2.05ms CPU time): 1 tests passed, 0 failed, 0 skipped (1 total tests)
The output above shows the test has succeeded which means that player is able to claim after 90 days.
Recommended Mitigations: Add a condition to check if the contest is alive for more than 90 days.
function claimCut() public {
+ if (block.timestamp - i_deployedAt > 90 days) {
+ revert Pot__ContestClosed();
+ }
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);
}