claimCut never checks whether the 90 day window has expired or the pot was already closed. Impact: players who missed the deadline still take their full reward afterwards, and whoever arrives last is brickedThe README puts a hard boundary on the claim period. Claimants get "90 days to claim before the manager takes a cut of the remaining pool and the remainder is distributed equally to those who claimed in time". Two things follow: after the window a player has forfeited his reward, and the leftover is settled among those who did claim in time. closePot enforces half of that deal by refusing to run before 90 days.
claimCut enforces nothing. It reads the mapping, checks the reward is non zero, and pays. There is no timestamp comparison, no flag recording that the pot has been closed, and closePot does not clear playersToRewards, so every entry survives the close untouched. A player who ignored the entire window can walk in afterwards and collect in full, which contradicts the deadline the rest of the contract is built around.
The two periods overlap instead of meeting: at exactly 90 days closePot is already permitted while claimCut is still wide open. And because the manager cut has already left the same balance, the pot can no longer cover every outstanding reward. Late players race each other for what is left, and whoever arrives after it runs dry simply reverts.
Likelihood:
Any registered player who missed the window can do this at any moment after the close, with an ordinary call and no special conditions.
It costs nothing to attempt and there is no guard to trip, so a player watching the pot has every incentive to send the transaction the moment the close lands.
Impact:
Rewards the protocol treats as forfeited leave the pot anyway, so the leftover the spec reserves for punctual claimants is drained by the people who ignored the deadline.
The pot is short by the manager cut, so late claims become first come first served and a player loses his entire allocation to whoever transacts first. In the run below one late player takes his full 500 and the equally entitled second one is left with nothing recoverable.
Two players are registered for 500 each and the contest is funded with 1000. Nobody claims during the window, so claimants stays empty and the payout loop inside closePot never executes, which keeps this independent of how the leftover is divided. The manager closes after 91 days and his cut of 100 leaves the pot. Player one then claims his full reward three months past the deadline, and player two, who has exactly the same entitlement, is left with a pot holding 400 against a reward of 500. Run with forge test --match-test test_claimAfterClose_independentOfDivisorBug -vv.
Output:
Give the pot an explicit closed state and refuse claims once the window is over. Storing a flag also makes the intent readable rather than leaving it implied by a timestamp:
With the guard in place both late calls revert, the forfeited rewards stay in the pot and are settled through the leftover distribution, which is the behaviour the README describes.
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.