MyCut

AI First Flight #8
Beginner FriendlyFoundry
EXP
View results
Submission Details
Impact: medium
Likelihood: medium
Invalid

claimCut has no deadline: players can still claim their full reward after the pot is closed

Root + Impact

Description

  • Players have 90 days to claim; after that the Pot is closed and the unclaimed rewards are split between the manager and those who claimed in time.

  • claimCut has no deadline and closePot does not mark the Pot closed or reset playersToRewards / remainingRewards. A player who missed the window can still call claimCut after the Pot was closed and take their full original reward, even though that money was already treated as forfeited and distributed (or is owed to others).

function claimCut() public {
address player = msg.sender;
uint256 reward = playersToRewards[player];
@> // no check that the 90-day claim period is still open / pot not closed
if (reward <= 0) {
revert Pot__RewardNotFound();
}
playersToRewards[player] = 0;
remainingRewards -= reward;
claimants.push(player);
_transferReward(player, reward);
}

Risk

Likelihood:

  • Any allocated player who did not claim within 90 days can do it any time after close, no special conditions.

Impact:

  • The late claimer takes tokens that were already accounted as distributed. The accounting no longer matches the balance: either the late claim drains funds that belong to others, or (once the payout bug is fixed) late claims and timely claimants compete for a pot that cannot cover both.

  • The documented 90-day rule is not enforced.

Proof of Concept

function test_F3_lateClaimAfterClose() public {
(address[] memory ps, uint256[] memory rs) = _four(); // 4 x 100 ether
Pot pot = _pot(ps, rs, 400 ether);
vm.prank(p1);
pot.claimCut();
vm.warp(block.timestamp + 91 days);
vm.prank(owner);
cm.closeContest(address(pot));
// p2 missed the window, yet can still claim the full 100 after close
vm.prank(p2);
pot.claimCut();
assertEq(token.balanceOf(p2), 100 ether);
assertEq(pot.getRemainingRewards(), 200 ether); // never zeroed on close
}

Recommended Mitigation

+ bool private s_closed;
+ error Pot__ClaimPeriodOver();
function claimCut() public {
+ if (s_closed || block.timestamp - i_deployedAt >= 90 days) revert Pot__ClaimPeriodOver();
...
}
function closePot() external onlyOwner {
...
+ s_closed = true;
+ remainingRewards = 0;
}
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 9 hours ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!