claimCut + late players take value reserved for "those who claimed in time"The README says that MyCut allows "authorized claimants 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". A player who misses the 90-day window forfeits their reward. It becomes part of the remaining pool, 10% goes to the manager and 90% goes to the in-time claimants.
claimCut only checks playersToRewards[msg.sender] > 0. It never compares block.timestamp with i_deployedAt + 90 days, and Pot has no closed state. The 90 days appear only as a lower bound in closePot.
Closing is a separate, manual owner transaction. So a player who missed the window can still claim on day 95, or front-run the admin's closeContest. They receive their full reward, are pushed into claimants, and then also receive the in-time bonus at close.
Their claim also reduces remainingRewards, so both the manager cut and the real in-time claimants' bonus shrink.
Likelihood:
There is always a gap between day 90 and the admin's manual closeContest, and any player who missed the deadline can call claimCut in it. No privileges are required, and the admin cannot prevent it, because the close transaction can be front-run.
Late claims also succeed after the close whenever the Pot still holds a balance. Because of the separate bonus-divisor issue, a balance remains after any close where some player did not claim.
Impact:
Value moves from in-time claimants and the manager to players who were not "in time". In the PoC there are three players at 100 each. p1 claims on day 1 and p2 claims on day 95. p1's bonus drops from 60 to 30, the manager cut drops from 20 to 10, and p2 ends with 130: the full reward plus an in-time bonus.
After close, the outcome depends on transaction order. p2 withdraws 100 from the 120 left in the Pot. p3 has an identical entitlement but reverts with ERC20InsufficientBalance(pot, 20, 100). This post-close limb depends on the residue left by the separate i_players.length divisor issue. The late reward is paid once, out of tokens that would otherwise stay stranded.
The test deploys ContestManager and the repo's test/ERC20Mock.sol and uses the real flow. All four tests pass:
test_Baseline_OnlyInTimeClaimantSharesForfeit (spec behaviour): only p1 claims, and after the day-95 close p1 holds 160 (100 + 60 bonus) and the manager holds 20.
test_Limb1_LateClaimBeforeClose_DilutesInTimeClaimantAndManager: p2's day-95 claim succeeds with 100. After the close, p2 holds 130, p1 holds 130 instead of 160, and the manager holds 10 instead of 20.
test_Limb2_3_ClaimAfterClose_OrderDependent: after the close, p2 claims 100 on day 200. p3's claim reverts with ERC20InsufficientBalance(pot, 20, 100), while checkCut(p3) still reports 100.
test_Limb4_PostCloseClaimerGetsBonusOnRepeatedClose: five players. A player who claims after the first close is pushed into claimants and receives a 54 bonus on a second close. This needs the owner to close twice, which is the separate non-terminal-close issue.
Save the file as test/PoC_MC-03.t.sol and run from the repository root:
Reject claims once the 90 days have elapsed. closePot only succeeds when block.timestamp - i_deployedAt >= 90 days, so this single check also rejects every post-close claim, and the claim window and the close window no longer overlap.
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.