Puppy Raffle

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

## [M-2] `_safeMint()` Allows Malicious Contract to Block Raffle

Root + Impact

Description

  • The selectWinner() function is intended to mint an NFT to the winner after distributing the prize pool

  • The function uses _safeMint() which calls onERC721Received() on the recipient if it's a contract; a malicious contract can revert this call

delete players;
raffleStartTime = block.timestamp;
previousWinner = winner;
(bool success,) = winner.call{value: prizePool}("");
require(success, "PuppyRaffle: Failed to send prize pool to winner");
@> _safeMint(winner, tokenId); // Reverts if winner contract doesn't implement onERC721Received

Risk

Likelihood:

  • Requires a smart contract to win the raffle

  • Attacker must predict/manipulate winner selection (see H-2)

Impact:

  • Entire transaction reverts, raffle cannot complete

  • Players array is not reset, so raffle is stuck

  • All player funds remain locked until issue is resolved

Proof of Concept

contract MaliciousWinner {
// No onERC721Received implementation
// OR explicitly revert:
function onERC721Received(address, address, uint256, bytes calldata) external pure returns (bytes4) {
revert("Blocking raffle");
}
}

Recommended Mitigation

- _safeMint(winner, tokenId);
+ _mint(winner, tokenId);
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge 17 days 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!