MyCut

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

Multiple Funding Proplem

Root + Impact

The fundContest function does not check if a contest has already been funded. An owner can accidentally call this function multiple times for the same index, draining their own wallet and trapping excess tokens in the Pot contract.

Description

  • The function logic is:

function fundContest(uint256 index) public onlyOwner {
// ... logic ...
token.transferFrom(msg.sender, address(pot), totalRewards);
}

There is no state variable (like mapping(address -> bool) isFunded) to track if the transfer has already occurred. Since the Pot logic is strictly based on the totalRewards value set at construction, any extra tokens sent to the Pot are not accounted for in remainingRewards and cannot be claimed or distributed


Risk

Likelihood:

  • Operational errors are common especially for unware users

Impact:

  • Funds are trapped in the child Pot contracts with no way to recover

Proof of Concept

1. Admin creates a contest with totalRewards = 1,000 USDC.
2. Admin calls fundContest(0).
token.transferFrom(Admin, Pot, 1,000) executes.
Pot Balance: 1,000 USDC.
3. Due to a UI glitch or manual error, Admin calls fundContest(0) again.
The function does not check if the pot is already funded.
token.transferFrom(Admin, Pot, 1,000) executes again.
Pot Balance: 2,000 USDC.
Final State
Pot.remainingRewards (Storage): 1,000.
Pot Actual Token Balance: 2,000.
Result: Because all logic in claimCut() and closePot() is based on the remainingRewards variable (which is 1,000),
the extra 1,000 USDC is invisible to the contract. It can never be claimed by players or taken as a manager cut.
It is effectively "donated" to the contract's address forever.

Recommended Mitigation

Add a tracking mechanism to ensure each contest is funded exactly once.

+ mapping(address => bool) public isFunded;
++ function fundContest(uint256 index) public onlyOwner {
Pot pot = Pot(contests[index]);
+ require(!isFunded[address(pot)], "Already funded");
// ... transfer logic ...
+ isFunded[address(pot)] = true;
}
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 2 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!