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!
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);
}