Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: high
Invalid

`snek_raffle::fulfillRandomWords` Does Not Check the Success of the Prize Transfer, Allowing the Raffle to Conclude without the Winner Receiving the Prize Money

Summary

snek_raffle::fulfillRandomWords does not check the success of the money prize transfer. If the transfer does fail, the raffle can still conclude without the winner ever receiving the prize money.

Vulnerability Details

snek_raffle::fulfillRandomWords is supposed to select the winner of a raffle, and then transfer the raffle prices (an NFT and the prize money, i.e. the sum of entrance fees). However, it does not check the success of the transfer of the prize money. The transfer can fail for multiple reasons, including

  • the recipient's inability to receive funds due to gas constraints,

  • contract code execution failure.

Given that the success of the transfer is not checked, if the transfer does fail, the raffle can still conclude.

Proof of Code

To simulate the transfer failure, this contract will intentionally fail when ether is sent to it:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract FailingRecipient {
// Fallback function that fails
receive() external payable {
revert("Cannot receive ETH");
}
}

Impact

If the transfer fails, the raffle can still conclude without the winner receiving the prize money. In such a case, the prize money remains in the raffle contract, and will be given to the winner of the next raffle, provided that the transfer transaction to that winner is successful.

Tools Used

ChatGPT.

Recommendations

There are multiple potential solutions to this issue:

  1. Use pull over push: implement a withdrawal pattern where winner withdraw their prizes themselves, or

  2. Check the success of the ether transfer and revert the transaction if the transfer fails.

To implement the second option, change the code as follows:

...
- send(recent_winner, self.balance)
+ if not send(recent_winner, self.balance):
+ revert("Transfer failed")
...
Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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