MyCut

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

Player Can Claim After Deadline

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 {
// Creating a contest
vm.startPrank(user);
contest = ContestManager(conMan).createContest(
players,
rewards,
IERC20(ERC20Mock(weth)),
4
);
ContestManager(conMan).fundContest(0);
vm.stopPrank();
// Claiming cut by player1
vm.startPrank(player1);
Pot(contest).claimCut();
vm.stopPrank();
// Wait 95 days
vm.warp(95 days);
uint256 balancePlayer2AfterDeadline = ERC20Mock(weth).balanceOf(player2);
// Claiming cut by 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);
}
Updates

Lead Judging Commences

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

Support

FAQs

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