MyCut

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

Contest Can Be Funded Multiple Times, Causing Accounting and Distribution Mismatch

Contest Can Be Funded Multiple Times, Causing Accounting and Distribution Mismatch

Description

Normal behavior

A contest should normally be funded once with its configured totalRewards.

Specific issue

fundContest() does not record that a contest has already been funded.

Therefore, the owner can call:

fundContest(index)

multiple times.

Every call transfers the full totalRewards amount into the same Pot.

However, remainingRewards inside the Pot is initialized only once and does not increase when additional tokens are deposited.

function fundContest(uint256 index) public onlyOwner {
Pot pot = Pot(contests[index]);
​
IERC20 token = pot.getToken();
uint256 totalRewards = contestToTotalRewards[address(pot)];
​
...
​
// @> No funded/amount-funded state is updated
token.transferFrom(msg.sender, address(pot), totalRewards);
}
​

Risk

Likelihood:

  • fundContest() has no one-time funding restriction.

  • The owner can invoke the function repeatedly.

Impact:

  • Extra tokens become unaccounted-for.

  • Closing logic can operate on stale accounting.

  • Repeated funding can interact with repeated closing to create unexpected distributions.

Proof of Concept

function testContestCanBeFundedTwice() public {
// First funding
manager.fundContest(0);
​
assertEq(token.balanceOf(address(pot)), 1000);
​
// Second funding
manager.fundContest(0);
​
assertEq(token.balanceOf(address(pot)), 2000);
​
// But Pot's internal accounting is still 1000.
assertEq(pot.getRemainingRewards(), 1000);
}
​

Recommended Mitigation

Track whether the contest has already been funded.
+ mapping(address => bool) public contestFunded;
​
function fundContest(uint256 index) public onlyOwner {
Pot pot = Pot(contests[index]);
​
+ if (contestFunded[address(pot)]) {
+ revert ContestAlreadyFunded();
+ }
​
IERC20 token = pot.getToken();
uint256 totalRewards = contestToTotalRewards[address(pot)];
​
token.transferFrom(msg.sender, address(pot), totalRewards);
​
+ contestFunded[address(pot)] = true;
}
​
Updates

Lead Judging Commences

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