I'm learning about the ERC20 contract by OpenZeppelin and curious about the approve function:
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
uint256 currentAllowance = _allowances[sender][_msgSender()];
require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
_approve(sender, _msgSender(), currentAllowance - amount);
return true;
}
Logically, it would make sense that you're only able to transfer amount
from sender
to recipient
only if currentAllowance >= amount
.
However, as you can see in this function body, the require(currentAllowance >= amount)
occurs after the call to _transfer(sender, recipient, amount)
.
Now I remember reading that ethereum transactions are atomic. In this context, does it mean that if the require condition fails, then the _transfer
is also not executed?
does it mean that if the require condition fails, then the _transfer is also not executed
Technically, it gets executed, but then it reverts because of the invalid opcode that failed require
condition produces.
So there is no state change (this is what you probably mean by the "not executed"), but the gas has been used (for the execution).
Edit to clarify: No state change in this case means that no tokens are transfered.