Why is it safe for ERC20.sol transferFrom() to be public?

Hi @Steve_L

  1. Tokens can only be transferred from the senders account, please note, it is the sender who sets the allowance (the withdrawer calls transferFrom not the sender). transferFrom needs to be public to be called by other contracts and external accounts.
  2. There is meant to be no way for an account to withdraw tokens that they do not have an allowance for.

I have provided more detail to clarify my answer below:

https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#transferfrom
The transferFrom method is used for a withdraw workflow, allowing contracts to transfer tokens on your behalf. This can be used for example to allow a contract to transfer tokens on your behalf and/or to charge fees in sub-currencies.

The withdraw workflow:

  1. An account (token holder) sets an allowance for an account
  2. The account with an allowance (a contract or an external account) can then transfer (withdraw) an amount of tokens within the set allowance.

The allowance is set by an account (token holder) calling the approve function (token holder is the msg.sender).

    function approve(address spender, uint256 value) public returns (bool) {
        _approve(msg.sender, spender, value);
        return true;
    }

An account can only transfer an amount of tokens within the set allowance by calling transferFrom (withdrawer is the msg.sender)

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

The withdraw is deemed safe because tokens can only be transferred within the amount of tokens that the sender holds (checked when _balances is decreased) and within the set allowance for the account (checked when _allowances is decreased). (Otherwise either transaction would revert with reason "SafeMath: subtraction overflow").

transferFrom needs to be public to allow the function to be called by other contracts and external accounts.

Please note, the sender (the token holder) doesn't call transferFrom, the sender (the token holder) sets the allowance by calling approve.

Let me know if you need more information.

2 Likes