ContestManager.fundContest() transfers totalRewards tokens from the owner into the Pot every time it is called. There is no state variable, mapping, or flag tracking whether a particular Pot has already been funded. A second call deposits another full totalRewards amount, but the Pot's remainingRewards is set once at construction — so any tokens beyond the original totalRewards can never be distributed.
Likelihood:
An owner script with a retry-on-failure pattern, a frontend double-click, or a scripting error easily triggers a second fundContest() call on the same index.
Because there is no on-chain feedback (no event on first fund, no isFunded view), the owner has no cheap way to verify whether funding already occurred before calling again.
Impact:
All tokens deposited above the original totalRewards are permanently stuck: closePot() only distributes remainingRewards (the constructor snapshot), never the actual ERC20 balance.
For large reward pools this can represent substantial token loss with no recovery path.
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.