MyCut

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

Empty players array causes closePot() division by zero and lock

Root + Impact

Description

  • Normal behavior: closing should distribute remaining rewards without reverting.

  • Issue: `closePot() divides by i_players.length` with no zero-length guard.

function closePot() external onlyOwner {
...
@> uint256 claimantCut = (remainingRewards - managerCut) / i_players.length;
for (uint256 i = 0; i < claimants.length; i++) {
_transferReward(claimants[i], claimantCut);
}
}

Risk

Likelihood:

  • Contest is created with an empty players array.

  • Owner calls `closePot()` after the claim window.

Impact:

  • `closePot()` reverts permanently.

  • Funds remain locked in the Pot.

Proof of Concept

function testCloseRevertsWithEmptyPlayersArray() public {
address owner = makeAddr("owner");
ContestManager manager = _deployManager(owner);
ERC20Mock token = new ERC20Mock("T", "T", owner, 0);
token.mint(owner, 100);
vm.prank(owner);
token.approve(address(manager), 100);
address[] memory players = new address[](0);
uint256[] memory rewards = new uint256[](0);
vm.startPrank(owner);
address potAddr = manager.createContest(players, rewards, IERC20(token), 100);
manager.fundContest(0);
vm.stopPrank();
vm.warp(block.timestamp + 91 days);
vm.prank(owner);
vm.expectRevert(stdError.divisionError);
manager.closeContest(potAddr);
}

Recommended Mitigation

+ require(players.length > 0, "no players");
...
- uint256 claimantCut = (remainingRewards - managerCut) / i_players.length;
+ uint256 claimantCut = (remainingRewards - managerCut) / i_players.length;
Updates

Lead Judging Commences

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