Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: high
Valid

excluding empty addresses from Raffle Winner Selection

Summary

The selectWinner function in the smart contract uses the modulo operation with the size of the players array to calculate the winnerIndex. However, if there are zero addresses present in the players array, it is possible for an empty address to be selected as the winner. This can lead to unfair outcomes for active players.

Vulnerability Details

The issue lies in the selectWinner function, the winner select calculation does not consider the presence of empty addresses within the array. Consequently, an empty address can be chosen as the winner, causing active players to be unfairly excluded from winning. To resolve this, the function should create a separate array that only includes non-empty addresses for selecting the winner.

Impact

  • Unfair Results: The presence of empty addresses allows the selection of an empty address as the winner, which is unjust for active participants.

  • Loss of Trust: Unfair outcomes undermine trust in the smart contract and the integrity of the raffle system.

  • Manipulation: Malicious actors may exploit this vulnerability by intentionally adding empty addresses to increase their chances of winning or disrupt the fairness of the raffle.

Tools Used

Manual Review

Recommendations

To address this vulnerability, the selectWinner function should be modified as follows:

  1. Create a new array, named activePlayers, to store the non-empty addresses from the players array.

  2. Iterate over the players array and populate the activePlayers array with the non-empty addresses.

  3. Calculate the winnerIndex using the size of the activePlayers array instead of the players array.

  4. Select the winner from the activePlayers array using the calculated winnerIndex.

function selectWinner() public {
require(block.timestamp >= raffleStartTime + raffleDuration, "PuppyRaffle: Raffle not over");
address[] memory activePlayers = new address[](players.length);
uint activeCount = 0;
// Populate activePlayers array with non-empty addresses
for (uint i = 0; i < players.length; i++) {
if (players[i] != address(0)) {
activePlayers[activeCount] = players[i];
activeCount++;
}
}
// Ensure at least one active player exists
require(activeCount >= 4, "PuppyRaffle: Need at least 4 players");
uint256 winnerIndex = uint256(keccak256(abi.encodePacked(msg.sender, block.timestamp, block.difficulty))) % activeCount;
address winner = activePlayers[winnerIndex];
// Perform additional logic with the winner...
}
Updates

Lead Judging Commences

Hamiltonite Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

refund-doesnt-reduce-players-array-size-causing-protocol-to-freeze

zero address can win the raffle

Funds are locked to no one. If someone gets the refund issue, they also got this issue. IMPACT: High Likelihood: High

Support

FAQs

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