I would like to understand the rather large difference in gas costs of transfer
operations of the same ERC-20 token. I know that all ETH transactions cost 21000 gas, and I know that all ERC-20 transfer functions have to make a "transaction" call plus some Smart Contract operations, which will generally lead to transfer functions costing ~40 000 to ~60 000 gas. At least, gas cost in that range is what I have observed for USDC, USDT, LINK, OMG and a few others.
Check the ETH Yellow Paper, page 27, where it says that Gtransaction is indeed 21000: https://ethereum.github.io/yellowpaper/paper.pdf. It also details the costs of all other operations.
Smart Contract operations are encoded in the "data" property of an ETH transaction. The transfer
operation takes 2 inputs, the destination address and the value to send.
Examples
Here are 2 USDT transfer operations with a 12 gas difference, along with the "data" property value.
-
https://etherscan.io/tx/0x9ace5449eb6e06869811160970ae80df6c78303996f37aaef7ed48bbf55d6b18
- 41,309 gas
0xa9059cbb00000000000000000000000075e89d5979e4f6fba9f97c104c2f0afb3f1dcb88000000000000000000000000000000000000000000000000000000000a811f4c
-
https://etherscan.io/tx/0x1457259843cfbab3b412aedd58ad6baa88fca5ecc9392fedeea444cc72e7e56c
- 41,297 gas
0xa9059cbb00000000000000000000000086bc4655bf0dd2433e32055d00a9c96dadb0e22f00000000000000000000000000000000000000000000000000000000471bbc40
In the ETH Yellow Paper page 27 it says a non-zero byte (Gtxdatanonzero) is worth 16 gas, and a zero-byte (Gtxdatazero) 4 so I was guessing that (16 – 4) might be the difference, though I don't see it in the "data" property strings. They seem to be exactly the same amount of bytes.
Here are transactions that cost way more:
- 63,221: https://etherscan.io/tx/0x3fe51993e9840baa36089a930303126848054ee4e574af26e421b51298dd97be
- 46,109: https://etherscan.io/tx/0x3b797e304fc1dce2829d971a72247ead31ad891b08dc94c641e3b49e7e27ea80
Is it the list in the Yellow Paper that explains the differences? If so, which operations exactly are being called? And how would I figure this out?
Related SE posts
- Why does zero to non-zero in storage take higher gas? (thx to @Lauri Peltonen)
- Why do these two Ethereum transactions have different gas usages? Can't explain it from the GETH EVM debug traces
- Calculate transaction costs for storing data
Helpful links
- Explanation on 4800 gas refunds: https://growingdata.com.au/how-to-calculate-gas-fees-on-ethereum/
- Specifics on operations and exact gas costs: https://medium.com/coinmonks/on-efficient-ethereum-addresses-3fef0596e263
- Detailed gas consumption analyzer: https://dashboard.tenderly.co/tx/mainnet/0x9ace5449eb6e06869811160970ae80df6c78303996f37aaef7ed48bbf55d6b18/gas-usage
Best Answer
To explain the first difference of 12, you found the correct answer. See the non-zero bytes in the first example, where in the second example those are zero. Since nonzero costs 16 and zero 4, the difference in calldata cost should be 12, which it is.
0xa9059cbb00000000000000000000000075e89d5979e4f6fba9f97c104c2f0afb3f1dcb88000000000000000000000000000000000000000000000000000000000a811f4c
0xa9059cbb00000000000000000000000086bc4655bf0dd2433e32055d00a9c96dadb0e22f00000000000000000000000000000000000000000000000000000000471bbc40
For your second question, it can have many reasons but this is most likely due to the 63k costing call setting the balance of the receiver from zero to non-zero, which costs 20k gas. When we don't change a storage slot zeroness it only costs 2.9k gas. This would almost perfectly explain the difference.
Edit
Check step [524] of the stack traces of both transactions. For the first transaction it costs 20000, whereas for the 2nd transaction it costs 2900.
63,221: https://etherscan.io/vmtrace?txhash=0x3fe51993e9840baa36089a930303126848054ee4e574af26e421b51298dd97be
46,109: https://etherscan.io/vmtrace?txhash=0x3b797e304fc1dce2829d971a72247ead31ad891b08dc94c641e3b49e7e27ea80