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
?
Best Answer
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:
The mechanism of
approve
/transferFrom
solves both problems as follows:approve
function on the TKN contract in order to allow for the Uniswap contract to transfer an amount of N tokens from your accountexchangeTKN
function on the Uniswap contract, specifying an amount of N tokens; In turn, this function calls thetransferFrom
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