How does transferFrom(), in ERC20.sol, enforce that the caller must have allowance for `sender`'s tokens of at least `amount`?

Hi @Steve_L
Welcome to the community and Solidity.

The enforcement still exists but is more gas efficient. The improvement was made in OpenZeppelin 2.1.1

https://github.com/OpenZeppelin/openzeppelin-solidity/releases/tag/v2.1.1

  • ERC20 and ERC721 are now more gas efficient due to removed redundant SSTORE s and require s. (#1409 and #1549)

The allowance check is handled by the subtraction from _allowances using SafeMath.
If the allowance is not sufficient then there is a revert with reason "SafeMath: subtraction overflow"

ERC20.sol

The check is performed in SafeMath sub function.

    function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount));
        return true;
    }

SafeMath.sol

    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        uint256 c = a - b;

        return c;
    }

ERC20.test.js

An example of one of the tests

          it('reverts when more than the full allowance is removed', async function () {
            await expectRevert(
              this.token.decreaseAllowance(spender, approvedAmount.addn(1), { from: initialHolder }),
              'SafeMath: subtraction overflow'
            );
          });

For information on how require works you can read the Solidity documentation:
https://solidity.readthedocs.io/en/latest/control-structures.html#error-handling-assert-require-revert-and-exceptions

For more detail on the Pull Request which removed the redundant require statements:


Please ask all the questions that you need. :smile:

When you have a moment it would be awesome if you could introduce yourself to the community.

1 Like