4

In @openZeppelin's ERC20 implementation here is the code for function transferFrom:

function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
    _transfer(sender, recipient, amount);
    _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
    return true;
}

function _transfer(address sender, address recipient, uint256 amount) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

The amount is reduced from the balance of sender and added to the balance of recipient. Also the caller's allowance from sender is reduced by amount. The implementation puzzles me in that there is no sender and recipient verification and that means sender and recipient can be any 2 arbitrary addresses. What if the sender and caller msg.sender are not the same address? What is the use case for transferFrom?

0

2 Answers 2

15

The use-case is that you give permission for someone else to transfer from your account.

That someone else can be either an externally-owned account or a smart-contract account.

For example, suppose you want to convert some TKN to ETH on Uniswap.

You could theoretically transfer your TKN to the Uniswap contract and then call some function on it to send you ETH in return, however:

  1. That requires two separate transactions, during which, things like exchange rate (on the blockchain) may change
  2. When you call the Uniswap contract function, it will not even "know" that you have previously transferred TKN to the contract

The mechanism of approve/transferFrom solves both problems as follows:

  • You call the approve function on the TKN contract in order to allow for the Uniswap contract to transfer an amount of N tokens from your account
  • You call some exchangeTKN function on the Uniswap contract, specifying an amount of N tokens; In turn, this function calls the transferFrom function on the TKN contract in order to transfer N tokens from your account to the contract, and then sends ETH from the contract to your account, both within the same transaction
2
  • goodvibration, Uniswap is an good example. Many thanks.
    – user938363
    Dec 28, 2020 at 18:31
  • why could the "transfer" function not have all that logic of (contract receives the TKN and sends back ETH straightaway)? @goodvibration
    – expertCode
    Sep 12, 2021 at 22:23
1

To add to goodvibration's answer, think of the transferFrom function as a callback that's invoked by the previously approved smart contract or EOA to ensure an atomic transaction (movement of tokens/value). By having a callback that works upon an already approved amount of tokens, any use case can be implemented that needs to consume the tokens and do something in return (or even not).

To address expertcode's question, there are multiple reasons for not putting all the logic in transfer function itself:

  1. Each function should do one single thing and do it right
  2. Transfer function has to simply transfer the tokens from one address to another - it does not know and does not need to know the functionality or chain of invocations that have gotten to it ie. the lineage. It simply does the transfer. Invoking functionality is responsible for doing all the preceding and following tasks.
  3. Transfer is NOT created to take a token and provide ETH in return. It's interpretation is simply to move the token in question from the invoker's account to the to's account. Overloading Transfer for a particular use case based functionality would be incorrect.

Hope this clarifies.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.