Summary
In Pot::claimCut
, there is no mechanism to prevent a user from claiming their cut after the 90-day deadline, as there is no check for this condition.
Vulnerability Details
The protocol's functionality ensures that players have 90 days to claim their cut. However, since there is no restriction in the code that prevents an authorized player from claiming after the deadline, it breaks the fundamental functionality of the protocol.
Proof of Code
function testUserCanClaimAfterDeadline() public mintAndApproveTokens {
vm.startPrank(user);
contest = ContestManager(conMan).createContest(
players,
rewards,
IERC20(ERC20Mock(weth)),
4
);
ContestManager(conMan).fundContest(0);
vm.stopPrank();
vm.startPrank(player1);
Pot(contest).claimCut();
vm.stopPrank();
vm.warp(95 days);
uint256 balancePlayer2AfterDeadline = ERC20Mock(weth).balanceOf(player2);
vm.startPrank(player2);
Pot(contest).claimCut();
vm.stopPrank();
uint256 balancePlayer2AfterDeadlineClaim = ERC20Mock(weth).balanceOf(player2);
console.log("Balance Player 2 After Post-Deadline Claim: ", balancePlayer2AfterDeadlineClaim);
assert(balancePlayer2AfterDeadline < balancePlayer2AfterDeadlineClaim);
}
Impact
This vulnerability breaks the protocol's declared logic, making all efforts to create contests useless and removing the incentive for other users to claim in time.
Tools Used
Manual analysis.
Recommendations
Ideally, the Pot contract should have a constant variable for the deadline. Alternatively, to mitigate the damage and prevent claiming after the deadline, at a minimum, I recommend adding a check in the Pot::claimCut
function:
function claimCut() public {
+ if (block.timestamp - i_deployedAt > 90 days) {
+ revert Pot__ClosedForClaim();
+ }
// Check if msg.sender is in the playersToRewards list
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);
}