selectWinner() sends the prize pool to the winner address via winner.call{value: prizePool}(""). If winner is a smart contract that does not implement receive() or fallback() payable, the call reverts — and since selectWinner() has no fallback logic, the entire transaction reverts. No winner is selected, no NFT is minted, and the raffle cannot progress.
Any player who entered via a smart contract wallet without a receive() function can permanently block winner selection. The ETH and the ability to draw a winner are locked in the contract until all other players call refund().
Likelihood:
Smart contract wallets (multisigs, Gnosis Safe, custom contracts) are common. A player who enters via such a wallet — intentionally or inadvertently — blocks the raffle if selected as winner.
Impact:
All legitimate players are denied their winnings. The raffle must be unwound via refund() calls, and the protocol's core function (selecting a winner and minting an NFT) fails permanently for that round.
A NoFallback contract enters the raffle. When selected as winner, selectWinner() reverts because the prize transfer fails.
The revert confirms a non-payable contract winner permanently blocks raffle completion.
Restrict enterRaffle() to EOAs only, or implement a pull-payment pattern so the winner claims their prize rather than having it pushed:
With pull-payment, a winner who cannot receive ETH simply never claims — the raffle still completes and the NFT is minted.
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.