Puppy Raffle

AI First Flight #1
Beginner FriendlyFoundrySolidityNFT
EXP
Submission Details
Impact: low
Likelihood: high

`getActivePlayerIndex()` returns 0 for non-players, ambiguous with index 0

Author Revealed upon completion

Root + Impact

Description

getActivePlayerIndex() returns 0 both for the player at index 0 and for any address that is not in the raffle. Callers (and the refund() flow, which takes an index from this function) cannot distinguish "first player" from "not a player".

function getActivePlayerIndex(address player) external view returns (uint256) {
for (uint256 i = 0; i < players.length; i++) {
if (players[i] == player) {
return i;
}
}
@> return 0;
}

Risk

Likelihood: High — anyone calling this function with a non-player address gets the misleading 0.

Impact: Low — no funds are directly at risk, but integrations relying on this function can target the wrong index (e.g. a non-player looking up their index gets 0, the first player's slot).

Proof of Concept

The test enters one player (index 0) and shows that a non-player address returns the exact same value, 0.

function test_L2_GetActivePlayerIndexReturnsZeroForNobody() public {
address[] memory players = _enterPlayers(1, 100);
assertEq(raffle.getActivePlayerIndex(players[0]), 0, "first player is index 0");
assertEq(
raffle.getActivePlayerIndex(address(0xDEAD)), 0, "a non-player ALSO returns 0 - ambiguous"
);
}

Recommended Mitigation

Return a sentinel (e.g. type(uint256).max) or revert when the player is not found, so "not found" can never be confused with a valid index.

- return 0;
+ revert("PuppyRaffle: Player not found");

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!