MyCut

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

M-06 Missing Index Validation in fundContest() and closeContest()

Root + Impact:

Description:

The fundContest() and closeContest() functions accept an index parameter or address without validating that it corresponds to a valid contest. This can lead to invalid calls or calls to wrong contracts.

In fundContest(), the index is used directly to access the contests array without bounds checking. If the index is out of bounds, the transaction will revert, but a more graceful check would be better.

In closeContest(), the contest address is passed directly to Pot(contest).closePot() without verifying that this address is actually a valid contest created by the ContestManager.

@> function fundContest(uint256 index) public onlyOwner {
@> Pot pot = Pot(contests[index]); // No bounds check on index
IERC20 token = pot.getToken();
uint256 totalRewards = contestToTotalRewards[address(pot)];
// ...
}
@> function closeContest(address contest) public onlyOwner {
@> _closeContest(contest); // No validation that contest is from our list
}
function _closeContest(address contest) internal {
@> Pot pot = Pot(contest);
@> pot.closePot(); // Could be any contract with closePot() function
}

Risk:

Likelihood: High - The owner may accidentally pass wrong index or address.

Impact:

  • fundContest() with invalid index will revert (out of bounds)

  • closeContest() can be called on arbitrary addresses that have a closePot() function

  • No validation that the contest was created by this ContestManager

  • Potential for interacting with malicious contracts

Proof of Concept:

This POC demonstrates that fundContest() and closeContest() accept invalid inputs without proper validation, causing reverts or allowing calls to arbitrary addresses.

function testValidateImpact() public {
// Create a valid contest first
vm.prank(owner);
address pot = contestManager.createContest(players, rewards, token, totalRewards);
// Now try to close an invalid contest (random address)
address fakeContest = makeAddr("fakeContest");
// This will revert because fakeContest doesn't have closePot()
// But there's no validation that the contest is from our list
vm.prank(owner);
vm.expectRevert(); // Will revert because fakeContest is not a Pot
contestManager.closeContest(fakeContest);
console.log("BUG: closeContest accepts any address without validation");
}

Recommended Mitigation:

Adding bounds checks for array indices and validating that contest addresses belong to this ContestManager prevents invalid operations and ensures only legitimate contests are managed.

function fundContest(uint256 index) public onlyOwner {
+ require(index < contests.length, "invalid index");
Pot pot = Pot(contests[index]);
IERC20 token = pot.getToken();
uint256 totalRewards = contestToTotalRewards[address(pot)];
// ...
}
function closeContest(address contest) public onlyOwner {
+ require(contestToTotalRewards[contest] > 0, "not a valid contest");
_closeContest(contest);
}
Updates

Lead Judging Commences

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