fundContest() Allows Repeated Funding of the Same Contest Without State GuardContestManager.fundContest() transfers totalRewards into a pot every time the function is called for a given index.
There is no funded-state guard, no per-contest funding cap, and no check that the pot is still in a funding phase. As a result, the same contest can be funded repeatedly with full totalRewards each time.
While this is an admin-only action, it is still a lifecycle integrity issue. The funding action is effectively unbounded and can accidentally or operationally over-capitalize a single contest.
Only the owner can trigger this path, so it is not externally exploitable by arbitrary users. Still, repeated calls are straightforward and can occur due to retries or incorrect operator scripts.
Repeated full funding breaks expected per-contest budgeting and can lock or misallocate protocol treasury tokens. In combination with weak close-finalization semantics, overfunded balances can amplify downstream payout errors.
The behavior is demonstrated by the following PoC test:
Run:
Output:
The test confirms the same contest balance moves from 4 to 8 after two consecutive fundContest(0) calls.
Add per-contest funding state so full funding can happen only once unless an explicit top-up flow is designed.
If top-ups are intended by design, implement an explicit topUpContest() path with separate accounting and events, instead of reusing initial funding logic.
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.