4

so because of reentrancy attacks I'm structuring my function to not get hacked. So first updating mappings and so on and then sending the payment.

My question is what if the payment fails to go through. Will entire function be reverted of just the payment?

Because if only the payment than that would mean my mappings would be updated as if the payment went through.

Is this the case?

Thanks for answers!

Kuly14
  • 496
  • 3
  • 12

2 Answers2

5
function withdraw(uint256 _amount) external {
    balances[msg.sender] -= _amount;
    (bool success, ) = payable(msg.sender).call{value: _amount}("");
}

If the low-level .call() is unsuccessful, the value of success is set to false but that doesn't revert the whole transaction. So the balances value would be reflected even though the payment didn't go through.

You can add a require() condition to check the result of the payment. This will make the parent transaction fail if the internal transaction fails.

(bool success, ) = payable(msg.sender).call{value: _amount}("");
require(success);

Or you can use the .transfer() function (member of address payable, do not confuse with token transfers) that also fails the parent transaction if the internal transaction fals:

function withdraw(uint256 _amount) external {
    balances[msg.sender] -= _amount;
    payable(msg.sender).transfer(_amount);
}
Petr Hejda
  • 40,554
  • 8
  • 72
  • 100
0

If you're preventing the reentrancy attacks, you might probably use the modifiers. Therefore, when the Reentrancy is detected, the function would be reverted and even not allowed to enter the function. That is, there would be no other parameters updated.

Besides, I can show you some demo code to answer your question.

contract test {
    uint public a = 0;

    // a will still be a
    function addRevert() public{
        a += 1;
        goRevert();
    }

    // a = a + 1
    function addNoRevert() public{
        a += 1;
    }

    function goRevert() pure public{
        revert();
    }
}
kaiyee0
  • 41
  • 2