players.length remain unchanged after calling refund() which may cause loss of funds to address(0) and create calculation errors in selectWinner().
Here, the refund() function is called to refund the player at playerIndex and set the player's address to address(0). However, the players.length is not changed, which means that the players array will have a address(0) at playerIndex . This may cause loss of funds to address(0) if selectWinner() is selected as the winner to playerIndex.
Also, this may cause calculation errors in selectWinner() . Given in blow Code.
In the above code, players.length is used to calculate totalAmountCollected. If players.length is not changed, totalAmountCollected will be calculated incorrectly. for example, initially players.length is 5, and player call refund function to refund the player at playerIndex 2, then players.length is still 5, but the players array will have a address(0) at playerIndex 2. So, totalAmountCollected = 5 * entranceFee, but it should be equal to totalAmountCollected = 4 * entranceFee.
Pass the require check, for example, players.length is 4, and player call refund function to refund the player at playerIndex 2, then players.length is still 4, but the players array will have a address(0) at playerIndex 2. So, players.length >= 4, but the actual number of players is 3.
Calculate winnerIndex is uint256(keccak256(abi.encodePacked(msg.sender, block.timestamp, block.difficulty))) % players.length; , so if players.length is not changed, the winnerIndex will be calculated incorrectly. for example, initially players.length is 5, and player call refund function to refund the player at playerIndex 2, then players.length is still 5, but the players array will have a address(0) at playerIndex 2. So, winnerIndex = uint256(keccak256(abi.encodePacked(msg.sender, block.timestamp, block.difficulty))) % 5; , but it should be equal to winnerIndex = uint256(keccak256(abi.encodePacked(msg.sender, block.timestamp, block.difficulty))) % 4;. Also, winnerIndex may be equal to 2, which is the address(0) in our exmaple. This may cause loss of funds to address(0).
Loss of funds to address(0) and create calculation errors in selectWinner().
Manual Review
Remix
Add require(playerIndex < players.length, "PuppyRaffle: Player index out of bounds"); to check whether the playerIndex is out of bounds.
Change players[playerIndex] = address(0); to players[playerIndex] = players[players.length-1]; and players.pop(); to delete the player at playerIndex and change the length of players array.
Funds are locked to no one. If someone gets the refund issue, they also got this issue. IMPACT: High Likelihood: High
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.