MyCut

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

fundContest() Can Be Called Multiple Times, Over-Funding Pots

Root + Impact

Description

  • The `fundContest()` function does not check whether a contest has already been funded. It can be called multiple times for the same contest, transferring additional tokens to the Pot each time. This leads to over-funding, where the Pot receives more tokens than intended, breaking the accounting system and potentially allowing players to claim more than their allocated rewards.

    The function transfers `totalRewards` amount every time it's called, without tracking whether funding has already occurred.

```solidity
// Root cause in the codebase
28| function fundContest(uint256 index) public onlyOwner {
29| Pot pot = Pot(contests[index]);
30| IERC20 token = pot.getToken();
31| uint256 totalRewards = contestToTotalRewards[address(pot)];
32|
33| if (token.balanceOf(msg.sender) < totalRewards) {
34| revert ContestManager__InsufficientFunds();
35| }
36|
37| token.transferFrom(msg.sender, address(pot), totalRewards);
38| }
```

Risk

Likelihood:

  • * This occurs when the owner calls `fundContest()` multiple times for the same contest index

    * The issue manifests every time the function is called after the initial funding

Impact:

  • I* Pots can be over-funded with more tokens than intended

    * Accounting becomes incorrect as `remainingRewards` in Pot doesn't account for extra funding

    * Players may be able to claim more than their allocated rewards if extra funds are available

    * Manager may lose additional tokens due to repeated funding

    * No way to track or prevent duplicate funding

Proof of Concept

```solidity
// Scenario: Contest created with totalRewards = 1000
// 1. Owner calls fundContest(0) - transfers 1000 tokens to Pot
// 2. Owner accidentally calls fundContest(0) again - transfers another 1000 tokens
// 3. Pot now has 2000 tokens, but remainingRewards = 1000
// 4. Players can claim their rewards, but 1000 extra tokens remain
// 5. When closePot() is called, extra tokens are distributed incorrectly
```

Recommended Mitigation

```diff
contract ContestManager is Ownable {
address[] public contests;
mapping(address => uint256) public contestToTotalRewards;
+ mapping(address => bool) public contestFunded;
error ContestManager__InsufficientFunds();
+ error ContestManager__AlreadyFunded();
function fundContest(uint256 index) public onlyOwner {
Pot pot = Pot(contests[index]);
+ require(!contestFunded[address(pot)], "Contest already funded");
IERC20 token = pot.getToken();
uint256 totalRewards = contestToTotalRewards[address(pot)];
if (token.balanceOf(msg.sender) < totalRewards) {
revert ContestManager__InsufficientFunds();
}
token.transferFrom(msg.sender, address(pot), totalRewards);
+ contestFunded[address(pot)] = true;
}
```
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge 16 days 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!