### Root + Impact
**Normal behavior:** NatSpec requires at least four players before a draw. Refunded users should not count toward that minimum.
**Issue:** The guard uses `players.length`, which still includes `address(0)` holes left by `refund()`. After two refunds in a four-player round, only two paying entrants remain, yet `players.length` is still `4`, so the minimum-player check passes and execution continues into broken payout logic ([C-01]()).
```solidity
// @> length includes refunded zero slots
require(players.length >= 4, "PuppyRaffle: Need at least 4 players");
```
**Interacts with:** C-01
## Risk
**Likelihood:**
- Two refunds in a four-player round are enough to drop below the intended minimum while still passing this guard.
- Refunds are an explicit, encouraged user action per NatSpec.
**Impact:**
- Raffle proceeds with fewer than four paying participants, violating protocol rules.
- Composes with C-01 to reach reverting or unfair settlement states.
Proof of Concept
pragma solidity ^0.7.6;
pragma experimental ABIEncoderV2;
import {Test} from "forge-std/Test.sol";
import {PuppyRaffle} from "../src/PuppyRaffle.sol";
contract H_01_ActivePlayerCountNotEnforced is Test {
function test_poc() public {
PuppyRaffle raffle = new PuppyRaffle(1 ether, address(99), 1 days);
address[] memory players = new address[](4);
players[0] = address(1);
players[1] = address(2);
players[2] = address(3);
players[3] = address(4);
raffle.enterRaffle{value: 4 ether}(players);
vm.prank(players[0]);
raffle.refund(0);
vm.prank(players[1]);
raffle.refund(1);
vm.warp(block.timestamp + 1 days + 1);
vm.roll(block.number + 1);
vm.expectRevert("PuppyRaffle: Failed to send prize pool to winner");
raffle.selectWinner();
}
}
Recommended Mitigation
```diff
function selectWinner() external {
- require(players.length >= 4, "PuppyRaffle: Need at least 4 players");
+ require(activePlayerCount >= 4, "PuppyRaffle: Need at least 4 active players");
}
```
Pair with compacting `players` on refund