Normal behavior:
The raffle tracks participants using the players array.
Each address in this array represents a valid ticket holder and contributes exactly entranceFee to the prize pool.
When a participant calls refund(), their ticket should be removed such that:
they are no longer eligible to win
they no longer contribute to prize or fee calculations
Issue
The refund() function does not remove the refunded player from the players array.
Instead, it replaces the player’s address with address(0):
However, the protocol continues to rely on players.length as the source of truth for:
prize pool calculation
protocol fee calculation
winner selection range
As a result, inactive refunded players (“ghost players”) are still counted as active participants, breaking the raffle’s economic and logical integrity.
Likelihood:
Reason 1: Refunds are a documented and intended feature of the protocol.
Reason 2: Any participant can refund at any time before winner selection.
Impact:
Impact 1: Prize pool and fee calculations become incorrect, overstating the amount of ETH collected.
Impact 2: The raffle completes successfully without reverting, silently violating fairness guarantees.
Result:
ETH prize is sent to address(0) or NFT is minted to address(0)
Funds and NFTs are permanently lost
No revert, no recovery path
Ensure refunded players are fully removed from raffle accounting.
Instead of relying on players.length, track only active participants and update this value on entry and refund.
Update activePlayers when users enter or refund to prevent inactive players from affecting prize and fee calculations.
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.