Two USDC transfers in the same block, both between non-contract addresses. Both call the same smart contract function transfer()
but used very different gas. Some differences I can explain (see below) but others I can't.
- tx1. https://etherscan.io/tx/0x27f9973f560584df2d3abdd8d55fdefe598a0d3d1279dc9380476cb6f60a2963
- tx2. https://etherscan.io/tx/0x250b59352747b186e2cbe17f59048e9adaac9556d50b9a598d4a8356f04b800d
Gas usage for tx1 is 65625 and for tx2 is 43725. That's a difference of 21900.
Both transactions transfer between non-contract addresses.
GETH debug traces:
- tx1. https://etherscan.io/vmtrace?txhash=0x27f9973f560584df2d3abdd8d55fdefe598a0d3d1279dc9380476cb6f60a2963
- tx2. https://etherscan.io/vmtrace?txhash=0x250b59352747b186e2cbe17f59048e9adaac9556d50b9a598d4a8356f04b800d
Before step [1], the remaining gas (the
Gas
column) isGasLimit - 21605
(where I recall that the 21605 comes from the minimum 21600 plus 5 gas from somewhere else I forgot). So in the GETH debug trace tx1 starts with 66163-21605=44558 gas and tx2 starts with 73188-21605=51583. So far so good.At step [122] when executing DELEGATECALL tx1 used 39328 gas and tx2 used 46243 gas. This accounts for -6915 of the difference.
At step [435] when executing SSTORE tx1 used 20000 and tx2 used 2900. This accounts for 17100 of the difference. The yellow paper says SSTORE uses 20000 gas when the storage value is set to non-zero from zero (this is the 2nd SSTORE call, and given it goes from 0 to >0 then I take it it's the destination address that is receiving funds).
The above are the only two differences in GasCost
, which account for 17100-6915=10185 so they do not explain the full difference of 21900 gas. There is still 11715 gas difference that remains unexplained.
Questions:
Why does DELEGATECALL use different gas at step [122]?
Can someone explain where the rest of the gas usage difference of 11715 gas comes from?
EDIT: See the comments below from @Nulik regarding gas refund, which is the main culprit (and doesn't show in the VM opcode trace). @Nulik please post an answer so I can accept and upvote it.