Puppy Raffle

AI First Flight #1
Beginner FriendlyFoundrySolidityNFT
EXP
View results
Submission Details
Impact: medium
Likelihood: low
Invalid

selectWinner reverts when the selected winner is a contract that cannot receive ETH or the ERC721

Description

  • Normally, selectWinner() should always be able to pay the prize and mint the puppy to the selected winner.

  • However, it pays with winner.call{value: prizePool} (and require(success)) and then calls _safeMint(winner, tokenId). If a contract enters the raffle and is selected as winner, but it rejects ETH (no receive/fallback) or does not implement onERC721Received, the call or _safeMint reverts, so the raffle round cannot be finalized for that selection.

(bool success,) = winner.call{value: prizePool}(""); // line 151
require(success, "PuppyRaffle: Failed to send prize pool to winner"); // line 152
_safeMint(winner, tokenId); // line 153: reverts if winner is a non-ERC721-receiver contract

Risk

Likelihood: Low

  • Requires a contract that cannot receive ETH or the ERC721 to be the randomly-selected winner (it can be deliberately entered to grief the round).

Impact: Medium

  • Prize distribution for that round is blocked / reverts, delaying or denying winner payout and puppy minting.

Proof of Concept

contract BadWinner {
// no receive() / fallback(), no onERC721Received
function enter(PuppyRaffle r) external payable {
address[] memory me = new address[](1); me[0] = address(this);
r.enterRaffle{value: msg.value}(me);
}
}
// If BadWinner is selected, winner.call returns success=false (require reverts),
// or _safeMint reverts -> selectWinner() reverts for that selection.

Recommended Mitigation

Use a pull-payment pattern (let the winner withdraw the prize) and _mint instead of _safeMint, or skip/re-roll a winner that cannot receive the prize/NFT.

Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 8 hours ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!