MyCut

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

High: Missing Input Validation in Pot Constructor

Root + Impact

Description

  • The `Pot` constructor does not validate that the `players` and `rewards` arrays have matching lengths, that the sum of rewards equals `totalRewards`, or that the arrays are non-empty. This can lead to creation of invalid Pot contracts with mismatched data, causing incorrect reward distribution, division by zero errors, or accounting discrepancies.

    The constructor directly uses the arrays without validation, which can result in silent failures or incorrect state initialization.

```solidity
// Root cause in the codebase
22| constructor(address[] memory players, uint256[] memory rewards, IERC20 token, uint256 totalRewards) {
23| i_players = players;
24| i_rewards = rewards;
25| i_token = token;
26| i_totalRewards = totalRewards;
27| remainingRewards = totalRewards;
28| i_deployedAt = block.timestamp;
29|
30| for (uint256 i = 0; i < i_players.length; i++) {
31| playersToRewards[i_players[i]] = i_rewards[i];
32| }
33| }
```

Risk

Likelihood:

  • * This occurs when a Pot is created with invalid input parameters

    * The issue manifests when arrays are mismatched, empty, or reward sums don't align

Impact:

  • * Invalid Pot contracts can be created, leading to incorrect reward distribution

    * Division by zero in `closePot()` if `i_players.length` is 0 (though this is now fixed in issue #1)

    * Players may not receive their intended rewards due to array misalignment

    * Accounting errors can occur if sum of rewards doesn't match totalRewards

    * Funds can be locked or incorrectly distributed

Proof of Concept

```solidity
// Scenario 1: Mismatched array lengths
address[] memory players = [player1, player2, player3];
uint256[] memory rewards = [100, 200]; // Only 2 rewards for 3 players
// Loop only processes first 2 players, player3 has reward = 0
// player3 cannot claim, but was intended to receive a reward
// Scenario 2: Sum doesn't match totalRewards
address[] memory players = [player1, player2];
uint256[] memory rewards = [100, 200]; // Sum = 300
uint256 totalRewards = 500;
// Pot initialized with remainingRewards = 500, but only 300 should exist
// Accounting becomes incorrect
// Scenario 3: Empty arrays
address[] memory players = [];
uint256[] memory rewards = [];
// Pot created with no players, closePot() divides by i_players.length = 0
// This causes division by zero error
```

Recommended Mitigation

```diff
constructor(address[] memory players, uint256[] memory rewards, IERC20 token, uint256 totalRewards) {
+ require(players.length > 0, "Players array cannot be empty");
+ require(players.length == rewards.length, "Players and rewards arrays must have same length");
+ require(address(token) != address(0), "Token address cannot be zero");
+ require(totalRewards > 0, "Total rewards must be greater than zero");
+
+ uint256 sumRewards = 0;
+ for (uint256 i = 0; i < rewards.length; i++) {
+ require(rewards[i] > 0, "Each reward must be greater than zero");
+ sumRewards += rewards[i];
+ }
+ require(sumRewards == totalRewards, "Sum of rewards must equal totalRewards");
+
i_players = players;
i_rewards = rewards;
i_token = token;
i_totalRewards = totalRewards;
remainingRewards = totalRewards;
i_deployedAt = block.timestamp;
for (uint256 i = 0; i < i_players.length; i++) {
+ require(i_players[i] != address(0), "Player address cannot be zero");
playersToRewards[i_players[i]] = i_rewards[i];
}
}
```
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!