1

As the title says, I am wondering if the following ether refund(using .call) can be hackable. I am not entirely sure no reentrancy attack can be performed in it, but I think so since I am not updating any storage for the contract nor checking any value that's outside the tx or that is not a constant in the storage.

Here's the stack:

uint256 requiredAmount = 1 ether; // just using 1 ether as sample

function myPayableFunc() external payable {
 require(msg.value > requiredAmount); 
 _processEther(msg.value);
}

function _processEther(uint256 etherValue) internal {
 if(etherValue > requiredAmount) {
  uint256 refundAmount = etherValue - requiredAmount;
  address(msg.sender).call{ value: refundAmount }("");
 }
}

I've just written it so I'm not sure it's completely "runnable" but guess gives the required details;

Basically what it does is:

  1. Receive ether in a function
  2. If received ether are more than needed, refund the remnant.

So my concern is: Is this somehow hackable via the reentrancy hack pattern(or some other one)? If possible, please describe why.

Thank you so much in advance for the answers

1
  • Try to run it through your mind, what would happen if you tried to reenter this?
    – Foxxxey
    Jun 17, 2023 at 18:31

2 Answers 2

0

When implementing the Check Effect Interaction pattern and adhering to its guidelines, you can protect yourself against reentrancy attacks, at least for simpler scenarios.

uint256 requiredAmount = 1 ether;

function myPayableFunc() external payable {
    // Check: Ensure that the sent value is greater than the required amount
    require(msg.value > requiredAmount); 

    // Effect: Perform any necessary storage updates (none in this code sample)

    // Interaction: Make an external call
    if (address(this).balance > requiredAmount) {
        uint256 refundAmount = address(this).balance - requiredAmount;
        address(msg.sender).call{ value: refundAmount }("");
    }
}

However, since the provided code sample does not include any storage updates, it is already inherently safe from reentrancy attacks.

0

If a contract set up a reentrancy attack to call myPayableFunc() every time they received the refunded ether, they would be left with 1 ether less than their initial deposit each time they looped through. In the end, they would be left with an amount less than the requiredAmount and the loop would eventually stop/fail. (and you would have all the attacker's ether)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.