eosnetworkfoundation/eos-evm-contract

Higher gas limit required than what is actually consumed

Closed this issue · 3 comments

Example: https://explorer.testnet.evm.eosnetwork.com/tx/0x5f6c24668a4a8f3509002754d46f7718470f47a929002a0acb57d57aeccf479c/raw-trace

The transaction used 84,812 gas but the transaction required a gas limit of 105,242 gas for it to successfully execute.

If the gas limit was any lower, the EOS EVM Contract would revert the transaction and in doing so actually use more gas than would normally be necessary to successfully execute it. See: https://explorer.testnet.evm.eosnetwork.com/tx/0x40848c1643950ddc70e0b7de953ebeea8d18c6525ad66eaf0eb0334dbfaf90cd.

We believe this is not a bug and the difference is due to gas refund. We may still want to investigate how a gas refund could explain the exact difference for the linked example transaction to feel confident that the gas refund is the only reason for the difference.

The break out of the example https://explorer.testnet.evm.eosnetwork.com/tx/0x5f6c24668a4a8f3509002754d46f7718470f47a929002a0acb57d57aeccf479c/raw-trace is as following:

input 105242
-> (21000 basic + 864 for data intrinsic fee)
-> 83378
-> 82148 used (80302 inside the delegate call)
-> 1230 left
-> refund for the sstore 19200
-> 20430 retuned
-> actual cost = 105242 - 20430 = 84812

explain for the 19200 refund:

During the transfer, we will first transfer the balance to the account "to" then burn it. So basically we set some value from zero to non-zero then set it back.
The refund in this case is calculated as
e[EVMC_STORAGE_ADDED_DELETED] = {
c.warm_access, static_cast<int16_t>(c.set - c.warm_access)};

where c.set = 20000 and c.warm_access = 800

20000 - 800 = 19200

Thanks @yarkinwho. Looks good.

We can close this issue.