A normal ERC-20 token transfer transaction takes about 51,000 gas.
The function that does the transfer is this one (this is the OpenZeppelin ERC-20 implementation):
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");
_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
What I noticed is that if the recipient token change line is commented out, the gas cost comes down very significantly, to about 30,000 gas:
// _balances[recipient] = _balances[recipient].add(amount);
It seems the problem is that we have to go through the same _balances hashmap twice (for sender and for recipient). Could this be somehow improved so that both sender’s and recipient’s balances could be updated in one iteration?