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

The Reentrancy Vulnerability Can Result in the Loss of All Ether in the Contract

Summary

The refund function is vulnerable to a reentrancy attack.

Vulnerability Details

When the refund function sends ETH to an address, if that address is a contract with a fallback function, that fallback function can be executed. If this fallback function in turn calls the refund function before the initial call to refund completes, the result is a reentrancy attack. In this case, the vulnerable line in the refund function is:

Assume there's a malicious contract called Attacker. This contract's fallback function is designed to call the refund() function again:

solidity
Copy code
contract Attacker {
PuppyRaffle public raffle;

constructor(PuppyRaffle _raffle) {
    raffle = _raffle;
}

// This function is used to initiate the attack
function attack() external payable {
    raffle.refund(someKnownIndex);
}

// Fallback function
fallback() external payable {
    if (address(raffle).balance >= entranceFee) {
        raffle.refund(someKnownIndex);
    }
}

}
When the attack() function of the Attacker contract is called, it'll trigger the refund() in PuppyRaffle, which in turn will send ETH back to the Attacker's fallback function. The fallback function then immediately calls refund() again, leading to the reentrancy loop.

Impact

An attacker can repeatedly call the refund function and drain more ETH than they are entitled to. This can result in significant financial losses for the contract and its users.

Tools Used

Code Review

Recommendations

  1. Use Reentrancy Guard: A common pattern to prevent reentrancy attacks is the use of a reentrancy guard.

  2. Update State Before Transfers: Another common best practice to prevent reentrancy is to update the contract's state before sending out any ETH.
    In your function, you'd move the players[playerIndex] = address(0); line before the payable(msg.sender).sendValue(entranceFee); line.

Updates

Lead Judging Commences

Hamiltonite Lead Judge over 1 year 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.