Summary
The function PuppyRaffle::getActivePlayerIndex()
responds with 0 for the status notAPlayer
. Consequently, notAPlayer
holds the same index as the initial player in the array. As a result, notAPlayer
can participate in the Raffle without paying and potentially win if the PuppyRaffle::winnerIndex
is 0.
Vulnerability Details
function getActivePlayerIndex(address player) external view returns (uint256) {
for (uint256 i = 0; i < players.length; i++) {
if (players[i] == player) {
return i;
}
}
@> return 0;
}
Impact
function testGetActivePlayerIndex() public {
address[] memory players = new address[](4);
players[0] = playerOne;
players[1] = playerTwo;
players[2] = playerThree;
players[3] = playerFour;
puppyRaffle.enterRaffle{value: entranceFee * 4}(players);
assertEq(puppyRaffle.getActivePlayerIndex(playerOne), 0);
console.log("The playerOne index:", puppyRaffle.getActivePlayerIndex(playerOne));
assertEq(puppyRaffle.getActivePlayerIndex(playerTwo), 1);
assertEq(puppyRaffle.getActivePlayerIndex(playerThree), 2);
assertEq(puppyRaffle.getActivePlayerIndex(playerFour), 3);
assertEq(puppyRaffle.getActivePlayerIndex(playerFive), 0);
console.log("The playerFive index:", puppyRaffle.getActivePlayerIndex(playerFive));
}
Logs:
The playerOne index: 0
The playerFive index: 0
[PASS] testGetActivePlayerIndexManyPlayers() (gas: 93540)
Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 7.95ms
Tools Used
Manual review.
Recommendations
It's recommended to consider reverting the function rather than returning a value of 0.
function getActivePlayerIndex(address player) external view returns (uint256) {
for (uint256 i = 0; i < players.length; i++) {
if (players[i] == player) {
return i;
}
}
- return 0;
+ revert("Player not found");
}