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

[H-01] Reentrancy Vulnerability in the `refund` Function of PuppyRaffle Contract

Summary

The refund function in the PuppyRaffle contract exhibits a reentrancy vulnerability due to the lack of state modification before the external call to transfer Ether. This vulnerability could potentially be exploited by an attacker to re-enter the refund function and withdraw more funds than they are entitled to.

Vulnerability Details

The vulnerability arises from the ordering of operations in the refund function. The function first transfers Ether to msg.sender using the sendValue method and then nullifies the player's address in the contract's state by setting players[playerIndex] to the zero address. The correct pattern to prevent reentrancy would be to modify the state before making the external call.

function refund(uint256 playerIndex) public {
address playerAddress = players[playerIndex];
require(playerAddress == msg.sender, "PuppyRaffle: Only the player can refund");
require(playerAddress != address(0), "PuppyRaffle: Player already refunded, or is not active");
players[playerIndex] = address(0); // Move this line up
payable(msg.sender).sendValue(entranceFee); // Move this line down
emit RaffleRefunded(playerAddress);
}

Impact

A malicious actor could exploit this vulnerability to drain funds from the contract. By creating a contract that calls back into the refund function in its fallback function, the attacker could trigger multiple refunds in a single transaction, depleting the contract's Ether balance.

Tools Used

  • Manual Review

Recommendations

To mitigate this vulnerability, it is recommended to follow the "Checks-Effects-Interactions" pattern. This pattern suggests that contract state should be updated before making external calls. In the refund function, the line players[playerIndex] = address(0); should be moved before the line payable(msg.sender).sendValue(entranceFee);. Furthermore, it's advisable to use the transfer method instead of sendValue as transfer is considered safer for sending Ether.

Updates

Lead Judging Commences

Hamiltonite Lead Judge almost 2 years ago
Submission Judgement Published
Validated
Assigned finding tags:

reentrancy-in-refund

reentrancy in refund() function

Support

FAQs

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