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.
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.
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.
Manual Review
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.
reentrancy in refund() function
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.