MyCut

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

## M-4 — `fundContest` is repeatable and over-funding is unaccounted

Root + Impact

fundContest transfers contestToTotalRewards[pot] on every call with no funded-once guard and no post-transfer balance check. remainingRewards is fixed at construction, so any extra tokens are unaccounted and become permanently stranded (or drained by repeated closes).

Description

// src/ContestManager.sol
function fundContest(uint256 index) public onlyOwner {
Pot pot = Pot(contests[index]);
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); // @> repeatable, no funded flag / balance delta check
}

Risk

Likelihood: Calling fundContest twice on the same pot.

Impact: Excess tokens are stranded in the pot and never claimable.

Proof of Concept

// test/Exploits.t.sol
function testRepeatedFundingStrandsTokens() public {
Pot pot = _createFundClose(100e18, 100e18, 200e18);
vm.prank(owner);
manager.fundContest(0); // funds a second time
​
assertEq(token.balanceOf(address(pot)), 400e18, "pot holds double the accounted total");
}

Recommended Mitigation

+ mapping(address => bool) public contestFunded;
function fundContest(uint256 index) public onlyOwner {
Pot pot = Pot(contests[index]);
+ require(!contestFunded[address(pot)], "already funded");
+ contestFunded[address(pot)] = true;
...
+ uint256 before = token.balanceOf(address(pot));
token.transferFrom(msg.sender, address(pot), totalRewards);
+ require(token.balanceOf(address(pot)) - before == totalRewards, "unexpected received amount");
}

Updates

Lead Judging Commences

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