2021-04-08 14:52:10 +00:00
# Nimbus
2024-02-20 07:16:12 +00:00
# Copyright (c) 2018-2024 Status Research & Development GmbH
2021-04-08 14:52:10 +00:00
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import
math , eth / common / eth_types ,
2021-04-22 16:05:58 +00:00
. / utils / [ macros_gen_opcodes , utils_numeric ] ,
2024-06-07 08:24:32 +00:00
. / op_codes , .. / .. / common / evmforks ,
.. / evm_errors
2021-04-08 14:52:10 +00:00
# Gas Fee Schedule
# Yellow Paper Appendix G - https://ethereum.github.io/yellowpaper/paper.pdf
type
GasFeeKind * = enum
GasZero , # Nothing paid for operations of the set Wzero.
GasBase , # Amount of gas to pay for operations of the set Wbase.
GasVeryLow , # Amount of gas to pay for operations of the set Wverylow.
GasLow , # Amount of gas to pay for operations of the set Wlow.
GasMid , # Amount of gas to pay for operations of the set Wmid.
GasHigh , # Amount of gas to pay for operations of the set Whigh.
GasExtCode , # Amount of gas to pay for operations of the set Wextcode.
GasBalance , # Amount of gas to pay for a BALANCE operation.
GasSload , # Paid for a SLOAD operation.
GasJumpDest , # Paid for a JUMPDEST operation.
GasSset , # Paid for an SSTORE operation when the storage value is set to non-zero from zero.
GasSreset , # Paid for an SSTORE operation when the storage value’ s zeroness remains unchanged or is set to zero.
2022-04-08 04:54:11 +00:00
RefundsClear , # Refund given (added into refund counter) when the storage value is set to zero from non-zero.
2021-04-08 14:52:10 +00:00
RefundSelfDestruct , # Refund given (added into refund counter) for self-destructing an account.
GasSelfDestruct , # Amount of gas to pay for a SELFDESTRUCT operation.
GasCreate , # Paid for a CREATE operation.
GasCodeDeposit , # Paid per byte for a CREATE operation to succeed in placing code into state.
GasCall , # Paid for a CALL operation.
GasCallValue , # Paid for a non-zero value transfer as part of the CALL operation.
GasCallStipend , # A stipend for the called contract subtracted from Gcallvalue for a non-zero value transfer.
GasNewAccount , # Paid for a CALL or SELFDESTRUCT operation which creates an account.
GasExp , # Partial payment for an EXP operation.
GasExpByte , # Partial payment when multiplied by ⌈log256(exponent)⌉ for the EXP operation.
GasMemory , # Paid for every additional word when expanding memory.
GasTXCreate , # Paid by all contract-creating transactions after the Homestead transition.
GasTXDataZero , # Paid for every zero byte of data or code for a transaction.
GasTXDataNonZero , # Paid for every non-zero byte of data or code for a transaction.
GasTransaction , # Paid for every transaction.
GasLog , # Partial payment for a LOG operation.
GasLogData , # Paid for each byte in a LOG operation’ s data.
GasLogTopic , # Paid for each topic of a LOG operation.
GasSha3 , # Paid for each SHA3 operation.
GasSha3Word , # Paid for each word (rounded up) for input data to a SHA3 operation.
GasCopy , # Partial payment for COPY operations, multiplied by words copied, rounded up.
GasBlockhash , # Payment for BLOCKHASH operation.
2023-01-04 13:11:33 +00:00
GasExtCodeHash , # Payment for contract's code hashing
GasInitcodeWord # Payment for each word (rounded up) for initcode
2023-03-21 13:27:12 +00:00
GasWarmStorageRead # Transient storage read and write cost.
2021-04-08 14:52:10 +00:00
2024-07-07 06:52:11 +00:00
GasFeeSchedule = array [ GasFeeKind , Natural ]
2021-04-08 14:52:10 +00:00
GasParams * = object
# Yellow Paper, Appendix H - https://ethereum.github.io/yellowpaper/paper.pdf
# GasCost is a function of (σ , μ):
# - σ is the full system state
# - μ is the machine state
# In practice, we often require the following from
# - σ : an account address
# - μ: a value popped from the stack or its size.
2024-07-05 04:55:13 +00:00
kind * : Op
isNewAccount * : bool
2024-07-06 01:39:22 +00:00
gasLeft * : GasInt
gasCallEIP2929 * : GasInt
2024-07-05 04:55:13 +00:00
contractGas * : UInt256
currentMemSize * : GasNatural
memOffset * : GasNatural
memLength * : GasNatural
GasParamsSs * = object
currentValue * : UInt256
originalValue * : UInt256
GasParamsCr * = object
currentMemSize * : GasNatural
memOffset * : GasNatural
memLength * : GasNatural
2021-04-08 14:52:10 +00:00
GasCostKind * = enum
GckInvalidOp ,
GckFixed ,
GckDynamic ,
GckMemExpansion ,
2024-06-07 08:24:32 +00:00
GckCreate ,
2024-07-05 04:55:13 +00:00
GckCall ,
GckLater ,
GckSuicide ,
GckSstore
2021-04-08 14:52:10 +00:00
2024-07-05 04:55:13 +00:00
# gasRefund of sstore can be a negative number
2024-07-06 01:39:38 +00:00
SStoreGasResult * = object
gasCost * : GasInt
2024-07-07 06:52:11 +00:00
gasRefund * : int64
2024-07-06 01:39:38 +00:00
2024-07-05 04:55:13 +00:00
CallGasResult = tuple [ gasCost , childGasLimit : GasInt ]
2021-04-08 14:52:10 +00:00
GasCost = object
case kind * : GasCostKind
of GckInvalidOp :
discard
2023-08-27 06:13:37 +00:00
of GckFixed , GckLater :
2021-04-08 14:52:10 +00:00
cost * : GasInt
of GckDynamic :
2023-02-14 14:37:21 +00:00
d_handler * : proc ( value : UInt256 ) : GasInt
2024-06-07 08:24:32 +00:00
{. nimcall , gcsafe , raises : [ ] . }
2021-04-08 14:52:10 +00:00
of GckMemExpansion :
2023-02-14 14:37:21 +00:00
m_handler * : proc ( currentMemSize , memOffset , memLength : GasNatural ) : GasInt
2024-06-07 08:24:32 +00:00
{. nimcall , gcsafe , raises : [ ] . }
of GckCreate :
2024-07-05 04:55:13 +00:00
cr_handler * : proc ( value : UInt256 , params : GasParamsCr ) : GasInt
2024-06-07 08:24:32 +00:00
{. nimcall , gcsafe , raises : [ ] . }
2024-07-05 04:55:13 +00:00
of GckCall :
c_handler * : proc ( value : UInt256 , params : GasParams ) : EvmResult [ CallGasResult ]
2024-06-07 08:24:32 +00:00
{. nimcall , gcsafe , raises : [ ] . }
2021-04-08 14:52:10 +00:00
# We use gasCost/gasRefund for:
# - Properly log and order cost and refund (for Sstore especially)
# - Allow to use unsigned integer in the future
# - CALL instruction requires passing the child message gas (Ccallgas in yellow paper)
2024-07-05 04:55:13 +00:00
of GckSuicide :
sc_handler * : proc ( condition : bool ) : GasInt
{. nimcall , gcsafe , raises : [ ] . }
of GckSstore :
ss_handler * : proc ( value : UInt256 , params : GasParamsSs ) : SStoreGasResult
{. nimcall , gcsafe , raises : [ ] . }
2021-04-08 14:52:10 +00:00
GasCosts * = array [ Op , GasCost ]
const
2021-06-28 13:06:29 +00:00
# From EIP-2929
2021-04-08 14:52:10 +00:00
ColdSloadCost * = 2100
ColdAccountAccessCost * = 2600
WarmStorageReadCost * = 100
2021-06-28 13:06:29 +00:00
# From EIP-2930 (Berlin).
ACCESS_LIST_STORAGE_KEY_COST * = 1900 . GasInt
ACCESS_LIST_ADDRESS_COST * = 2400 . GasInt
2022-12-02 04:35:41 +00:00
template gasCosts ( fork : EVMFork , prefix , ResultGasCostsName : untyped ) =
2021-04-08 14:52:10 +00:00
## Generate the gas cost for each forks and store them in a const
## named `ResultGasCostsName`
const FeeSchedule = gasFees [ fork ]
# ############### Helper functions ##############################
func ` prefix gasMemoryExpansion ` ( currentMemSize , memOffset , memLength : GasNatural ) : GasInt {. inline . } =
# Input: size (in bytes)
# Yellow Paper:
# Memory expansion cost
# = Cmem(μ′ i) − Cmem(μi)
# μi is memory size before opcode execution
# μ'i is the memory size after opcode execution
# Cmem(a) ≡ Gmemory · a + a² / 512
#
# Except when memLength = 0, where per eq (297),
# M(currentMemSize, f, l) = currentMemSize
let
2024-07-07 06:52:11 +00:00
prevWords = currentMemSize . wordCount
newWords = ( memOffset + memLength ) . wordCount
2021-04-08 14:52:10 +00:00
if memLength = = 0 or newWords < = prevWords :
# Special subcase of memory-expansion cost
# currentMemSize - currentMemSize = 0
# "Referencing a zero length range ... does not require memory to be extended
# to the beginning of the range."
#
# Also, don't credit EVM code for allocating memory
# then accessing lots of low memory. memoryGasCost,
# via go-ethereum, checks for this as special case.
return 0
let
prevCost = prevWords * static ( FeeSchedule [ GasMemory ] ) +
( prevWords ^ 2 ) shr 9 # div 512
newCost = newWords * static ( FeeSchedule [ GasMemory ] ) +
( newWords ^ 2 ) shr 9 # div 512
# TODO: add logging
2024-07-07 06:52:11 +00:00
result = GasInt ( max ( newCost - prevCost , 0 ) )
2021-04-08 14:52:10 +00:00
when fork > = FkTangerine :
func ` prefix all_but_one_64th ` ( gas : GasInt ) : GasInt {. inline . } =
## Computes all but 1/64th
## L(n) ≡ n − ⌊n/64⌋ - (floored(n/64))
# Introduced in EIP-150 - https://github.com/ethereum/EIPs/blob/master/EIPS/eip-150.md
# Note: The all-but-one-64th calculation should occur after the memory expansion fee is taken
# https://github.com/ethereum/yellowpaper/pull/442
result = gas - ( gas shr 6 )
# ############### Opcode gas functions ##############################
2022-04-08 04:54:11 +00:00
func ` prefix gasExp ` ( value : UInt256 ) : GasInt {. nimcall . } =
2021-04-08 14:52:10 +00:00
## Value is the exponent
2024-07-07 06:52:11 +00:00
result = GasInt ( static FeeSchedule [ GasExp ] )
2021-04-08 14:52:10 +00:00
if not value . isZero :
2024-07-07 06:52:11 +00:00
result + = GasInt ( static ( FeeSchedule [ GasExpByte ] ) * ( 1 + log256 ( value ) ) )
2021-04-08 14:52:10 +00:00
2024-07-05 04:55:13 +00:00
func ` prefix gasCreate ` ( value : UInt256 , params : GasParamsCr ) : GasInt {. nimcall . } =
2021-04-08 14:52:10 +00:00
if value . isZero :
2024-07-07 06:52:11 +00:00
result = GasInt ( static ( FeeSchedule [ GasCodeDeposit ] ) * params . memLength )
2021-04-08 14:52:10 +00:00
else :
2024-07-07 06:52:11 +00:00
result = GasInt ( static ( FeeSchedule [ GasCreate ] ) +
( static ( FeeSchedule [ GasInitcodeWord ] ) * params . memLength . wordCount ) ) +
2024-07-05 04:55:13 +00:00
` prefix gasMemoryExpansion ` ( params . currentMemSize , params . memOffset , params . memLength )
2021-04-08 14:52:10 +00:00
func ` prefix gasSha3 ` ( currentMemSize , memOffset , memLength : GasNatural ) : GasInt {. nimcall . } =
result = ` prefix gasMemoryExpansion ` ( currentMemSize , memOffset , memLength )
2024-07-07 06:52:11 +00:00
result + = GasInt ( static ( FeeSchedule [ GasSha3 ] ) +
static ( FeeSchedule [ GasSha3Word ] ) * ( memLength ) . wordCount )
2021-04-08 14:52:10 +00:00
func ` prefix gasCopy ` ( currentMemSize , memOffset , memLength : GasNatural ) : GasInt {. nimcall . } =
2024-07-07 06:52:11 +00:00
result = GasInt ( static ( FeeSchedule [ GasVeryLow ] ) +
static ( FeeSchedule [ GasCopy ] ) * memLength . wordCount )
result + = GasInt ( ` prefix gasMemoryExpansion ` ( currentMemSize , memOffset , memLength ) )
2021-04-08 14:52:10 +00:00
func ` prefix gasExtCodeCopy ` ( currentMemSize , memOffset , memLength : GasNatural ) : GasInt {. nimcall . } =
2024-07-07 06:52:11 +00:00
result = GasInt ( static ( FeeSchedule [ GasExtCode ] ) +
static ( FeeSchedule [ GasCopy ] ) * memLength . wordCount )
2021-04-08 14:52:10 +00:00
result + = ` prefix gasMemoryExpansion ` ( currentMemSize , memOffset , memLength )
func ` prefix gasLoadStore ` ( currentMemSize , memOffset , memLength : GasNatural ) : GasInt {. nimcall . } =
2024-07-07 06:52:11 +00:00
result = GasInt ( static ( FeeSchedule [ GasVeryLow ] ) )
2021-04-08 14:52:10 +00:00
result + = ` prefix gasMemoryExpansion ` ( currentMemSize , memOffset , memLength )
2024-07-05 04:55:13 +00:00
func ` prefix gasSstore ` ( value : UInt256 , params : GasParamsSs ) : SStoreGasResult {. nimcall . } =
2021-04-08 14:52:10 +00:00
## Value is word to save
2024-07-05 04:55:13 +00:00
var res : SStoreGasResult
2024-07-05 00:00:03 +00:00
when fork > = FkBerlin :
# EIP2929
const
SLOAD_GAS = WarmStorageReadCost
SSTORE_RESET_GAS = 5000 - ColdSloadCost
2021-04-08 14:52:10 +00:00
else :
2022-09-26 04:56:54 +00:00
const
2024-07-05 00:00:03 +00:00
SLOAD_GAS = FeeSchedule [ GasSload ]
SSTORE_RESET_GAS = FeeSchedule [ GasSreset ]
const
2024-07-07 06:52:11 +00:00
NoopGas {. used . } = GasInt SLOAD_GAS # if the value doesn't change.
DirtyGas {. used . } = GasInt SLOAD_GAS # if a dirty value is changed.
InitGas {. used . } = GasInt FeeSchedule [ GasSset ] # from clean zero to non-zero
2024-07-05 00:00:03 +00:00
InitRefund {. used . } = FeeSchedule [ GasSset ] - SLOAD_GAS # resetting to the original zero value
2024-07-07 06:52:11 +00:00
CleanGas {. used . } = GasInt SSTORE_RESET_GAS # from clean non-zero to something else
2024-07-05 00:00:03 +00:00
CleanRefund {. used . } = SSTORE_RESET_GAS - SLOAD_GAS # resetting to the original non-zero value
ClearRefund {. used . } = FeeSchedule [ RefundsClear ] # clearing an originally existing storage slot
when fork < FkConstantinople or fork = = FkPetersburg :
2024-07-05 04:55:13 +00:00
let isStorageEmpty = params . currentValue . isZero
2024-07-05 00:00:03 +00:00
# Gas cost - literal translation of Yellow Paper
res . gasCost = if value . isZero . not and isStorageEmpty :
2024-07-05 04:55:13 +00:00
InitGas
else :
CleanGas
2024-07-05 00:00:03 +00:00
# Refund
if value . isZero and not isStorageEmpty :
res . gasRefund = ClearRefund
else :
# 0. If *gasleft* is less than or equal to 2300, fail the current call.
# 1. If current value equals new value (this is a no-op), SSTORE_NOOP_GAS gas is deducted.
# 2. If current value does not equal new value:
# 2.1. If original value equals current value (this storage slot has not been changed by the current execution context):
# 2.1.1. If original value is 0, SSTORE_INIT_GAS gas is deducted.
# 2.1.2. Otherwise, SSTORE_CLEAN_GAS gas is deducted. If new value is 0, add SSTORE_CLEAR_REFUND to refund counter.
# 2.2. If original value does not equal current value (this storage slot is dirty), SSTORE_DIRTY_GAS gas is deducted. Apply both of the following clauses:
# 2.2.1. If original value is not 0:
# 2.2.1.1. If current value is 0 (also means that new value is not 0), subtract SSTORE_CLEAR_REFUND gas from refund counter. We can prove that refund counter will never go below 0.
# 2.2.1.2. If new value is 0 (also means that current value is not 0), add SSTORE_CLEAR_REFUND gas to refund counter.
# 2.2.2. If original value equals new value (this storage slot is reset):
# 2.2.2.1. If original value is 0, add SSTORE_INIT_REFUND to refund counter.
# 2.2.2.2. Otherwise, add SSTORE_CLEAN_REFUND gas to refund counter.
# Gas sentry honoured, do the actual gas calculation based on the stored value
2024-07-05 04:55:13 +00:00
if params . currentValue = = value : # noop (1)
2024-07-05 00:00:03 +00:00
res . gasCost = NoopGas
2024-07-05 04:55:13 +00:00
return res
2024-07-05 00:00:03 +00:00
2024-07-05 04:55:13 +00:00
if params . originalValue = = params . currentValue :
if params . originalValue . isZero : # create slot (2.1.1)
2024-07-05 00:00:03 +00:00
res . gasCost = InitGas
2024-07-05 04:55:13 +00:00
return res
2021-04-08 14:52:10 +00:00
2024-07-05 00:00:03 +00:00
if value . isZero : # delete slot (2.1.2b)
res . gasRefund = ClearRefund
2021-04-08 14:52:10 +00:00
2024-07-05 00:00:03 +00:00
res . gasCost = CleanGas # write existing slot (2.1.2)
2024-07-05 04:55:13 +00:00
return res
2021-04-08 14:52:10 +00:00
2024-07-05 04:55:13 +00:00
if not params . originalValue . isZero :
if params . currentValue . isZero : # recreate slot (2.2.1.1)
2024-07-07 06:52:11 +00:00
res . gasRefund - = ClearRefund
2024-07-05 00:00:03 +00:00
if value . isZero : # delete slot (2.2.1.2)
res . gasRefund + = ClearRefund
2021-04-08 14:52:10 +00:00
2024-07-05 04:55:13 +00:00
if params . originalValue = = value :
if params . originalValue . isZero : # reset to original inexistent slot (2.2.2.1)
2024-07-05 00:00:03 +00:00
res . gasRefund + = InitRefund
else : # reset to original existing slot (2.2.2.2)
res . gasRefund + = CleanRefund
2021-04-08 14:52:10 +00:00
2024-07-05 00:00:03 +00:00
res . gasCost = DirtyGas # dirty update (2.2)
2024-07-05 04:55:13 +00:00
res
2021-04-08 14:52:10 +00:00
func ` prefix gasLog0 ` ( currentMemSize , memOffset , memLength : GasNatural ) : GasInt {. nimcall . } =
result = ` prefix gasMemoryExpansion ` ( currentMemSize , memOffset , memLength )
2024-07-07 06:52:11 +00:00
result + = GasInt ( static ( FeeSchedule [ GasLog ] ) +
static ( FeeSchedule [ GasLogData ] ) * memLength )
2021-04-08 14:52:10 +00:00
func ` prefix gasLog1 ` ( currentMemSize , memOffset , memLength : GasNatural ) : GasInt {. nimcall . } =
result = ` prefix gasMemoryExpansion ` ( currentMemSize , memOffset , memLength )
2024-07-07 06:52:11 +00:00
result + = GasInt ( static ( FeeSchedule [ GasLog ] ) +
2021-04-08 14:52:10 +00:00
static ( FeeSchedule [ GasLogData ] ) * memLength +
2024-07-07 06:52:11 +00:00
static ( FeeSchedule [ GasLogTopic ] ) )
2021-04-08 14:52:10 +00:00
func ` prefix gasLog2 ` ( currentMemSize , memOffset , memLength : GasNatural ) : GasInt {. nimcall . } =
result = ` prefix gasMemoryExpansion ` ( currentMemSize , memOffset , memLength )
2024-07-07 06:52:11 +00:00
result + = GasInt ( static ( FeeSchedule [ GasLog ] ) +
2021-04-08 14:52:10 +00:00
static ( FeeSchedule [ GasLogData ] ) * memLength +
2024-07-07 06:52:11 +00:00
static ( 2 * FeeSchedule [ GasLogTopic ] ) )
2021-04-08 14:52:10 +00:00
func ` prefix gasLog3 ` ( currentMemSize , memOffset , memLength : GasNatural ) : GasInt {. nimcall . } =
result = ` prefix gasMemoryExpansion ` ( currentMemSize , memOffset , memLength )
2024-07-07 06:52:11 +00:00
result + = GasInt ( static ( FeeSchedule [ GasLog ] ) +
2021-04-08 14:52:10 +00:00
static ( FeeSchedule [ GasLogData ] ) * memLength +
2024-07-07 06:52:11 +00:00
static ( 3 * FeeSchedule [ GasLogTopic ] ) )
2021-04-08 14:52:10 +00:00
func ` prefix gasLog4 ` ( currentMemSize , memOffset , memLength : GasNatural ) : GasInt {. nimcall . } =
result = ` prefix gasMemoryExpansion ` ( currentMemSize , memOffset , memLength )
2024-07-07 06:52:11 +00:00
result + = GasInt ( static ( FeeSchedule [ GasLog ] ) +
2021-04-08 14:52:10 +00:00
static ( FeeSchedule [ GasLogData ] ) * memLength +
2024-07-07 06:52:11 +00:00
static ( 4 * FeeSchedule [ GasLogTopic ] ) )
2021-04-08 14:52:10 +00:00
2024-07-05 04:55:13 +00:00
func ` prefix gasCall ` ( value : UInt256 , params : GasParams ) : EvmResult [ CallGasResult ] {. nimcall . } =
2021-04-08 14:52:10 +00:00
# From the Yellow Paper, going through the equation from bottom to top
# https://ethereum.github.io/yellowpaper/paper.pdf#appendix.H
#
# More readable info on the subtleties wiki page: https://github.com/ethereum/wiki/wiki/Subtleties#other-operations
# CALL has a multi-part gas cost:
#
# - 700 base
# - 9000 additional if the value is nonzero
# - 25000 additional if the destination account does not yet exist
#
# The child message of a nonzero-value CALL operation (NOT the top-level message arising from a transaction!)
# gains an additional 2300 gas on top of the gas supplied by the calling account;
# this stipend can be considered to be paid out of the 9000 mandatory additional fee for nonzero-value calls.
# This ensures that a call recipient will always have enough gas to log that it received funds.
#
# EIP150 goes over computation: https://github.com/ethereum/eips/issues/150
#
# The discussion for the draft EIP-5, which proposes to change the CALL opcode also goes over
# the current implementation - https://github.com/ethereum/EIPs/issues/8
2024-07-06 01:39:22 +00:00
# Both gasCost and childGasLimit are always on positive side
var gasLeft = params . gasLeft
if gasLeft < params . gasCallEIP2929 :
return err ( opErr ( OutOfGas ) )
gasLeft - = params . gasCallEIP2929
2021-04-08 14:52:10 +00:00
2024-07-06 01:39:22 +00:00
var gasCost : GasInt = ` prefix gasMemoryExpansion ` (
2024-07-05 04:55:13 +00:00
params . currentMemSize ,
params . memOffset ,
params . memLength )
2024-07-06 01:39:22 +00:00
var childGasLimit : GasInt
2021-04-08 14:52:10 +00:00
# Cnew_account
2024-07-05 04:55:13 +00:00
if params . isNewAccount and params . kind = = Call :
2021-04-08 14:52:10 +00:00
when fork < FkSpurious :
# Pre-EIP161 all account creation calls consumed 25000 gas.
2024-07-07 06:52:11 +00:00
gasCost + = static ( GasInt ( FeeSchedule [ GasNewAccount ] ) )
2021-04-08 14:52:10 +00:00
else :
# Afterwards, only those transfering value:
# https://github.com/ethereum/EIPs/blob/master/EIPS/eip-158.md
# https://github.com/ethereum/EIPs/blob/master/EIPS/eip-161.md
if not value . isZero :
2024-07-07 06:52:11 +00:00
gasCost + = static ( GasInt ( FeeSchedule [ GasNewAccount ] ) )
2021-04-08 14:52:10 +00:00
# Cxfer
2024-07-05 04:55:13 +00:00
if not value . isZero and params . kind in { Call , CallCode } :
2024-07-07 06:52:11 +00:00
gasCost + = static ( GasInt ( FeeSchedule [ GasCallValue ] ) )
2021-04-08 14:52:10 +00:00
# Cextra
2024-07-07 06:52:11 +00:00
gasCost + = static ( GasInt ( FeeSchedule [ GasCall ] ) )
2021-04-08 14:52:10 +00:00
2024-07-06 01:39:22 +00:00
if gasLeft < gasCost :
return err ( opErr ( OutOfGas ) )
gasLeft - = gasCost
2021-04-08 14:52:10 +00:00
# Cgascap
when fork > = FkTangerine :
# https://github.com/ethereum/EIPs/blob/master/EIPS/eip-150.md
2024-07-06 01:39:22 +00:00
let gas = ` prefix all_but_one_64th ` ( gasLeft )
if params . contractGas > high ( GasInt ) . u256 or
gas < params . contractGas . truncate ( GasInt ) :
2024-07-05 04:55:13 +00:00
childGasLimit = gas
2021-04-08 14:52:10 +00:00
else :
2024-07-06 01:39:22 +00:00
childGasLimit = params . contractGas . truncate ( GasInt )
2021-04-08 14:52:10 +00:00
else :
2024-07-06 01:39:22 +00:00
if params . contractGas > high ( GasInt ) . u256 :
2024-06-07 08:24:32 +00:00
return err ( gasErr ( GasIntOverflow ) )
2024-07-06 01:39:22 +00:00
childGasLimit = params . contractGas . truncate ( GasInt )
2021-04-08 14:52:10 +00:00
2024-07-06 01:39:22 +00:00
if gasCost . u256 + childGasLimit . u256 + params . gasCallEIP2929 . u256 > high ( GasInt ) . u256 :
return err ( gasErr ( GasIntOverflow ) )
2023-12-04 02:55:31 +00:00
2024-07-05 04:55:13 +00:00
gasCost + = childGasLimit
2024-07-06 01:39:22 +00:00
gasCost + = params . gasCallEIP2929
2021-04-08 14:52:10 +00:00
# Ccallgas - Gas sent to the child message
2024-07-05 04:55:13 +00:00
if not value . isZero and params . kind in { Call , CallCode } :
2024-07-07 06:52:11 +00:00
childGasLimit + = static ( GasInt ( FeeSchedule [ GasCallStipend ] ) )
2024-07-05 04:55:13 +00:00
# at this point gasCost and childGasLimit is always > 0
ok ( ( gasCost , childGasLimit ) )
2021-04-08 14:52:10 +00:00
func ` prefix gasHalt ` ( currentMemSize , memOffset , memLength : GasNatural ) : GasInt {. nimcall . } =
` prefix gasMemoryExpansion ` ( currentMemSize , memOffset , memLength )
2024-07-05 04:55:13 +00:00
func ` prefix gasSelfDestruct ` ( condition : bool ) : GasInt {. nimcall . } =
2024-07-07 06:52:11 +00:00
result + = static ( GasInt ( FeeSchedule [ GasSelfDestruct ] ) )
2021-04-08 14:52:10 +00:00
when fork > = FkTangerine :
2024-07-05 04:55:13 +00:00
if condition :
2024-07-07 06:52:11 +00:00
result + = static ( GasInt ( FeeSchedule [ GasNewAccount ] ) )
2021-04-08 14:52:10 +00:00
func ` prefix gasCreate2 ` ( currentMemSize , memOffset , memLength : GasNatural ) : GasInt {. nimcall . } =
2024-07-07 06:52:11 +00:00
result = GasInt ( static ( FeeSchedule [ GasSha3Word ] ) * ( memLength ) . wordCount )
2021-04-08 14:52:10 +00:00
# ###################################################################################################
let ` ResultGasCostsName ` * {. inject , compileTime . } : GasCosts = block :
# We use a block expression to avoid name redefinition conflicts
# with "fixed" and "dynamic"
# Syntactic sugar
func fixed ( gasFeeKind : static [ GasFeeKind ] ) : GasCost =
2024-07-07 06:52:11 +00:00
GasCost ( kind : GckFixed , cost : static ( GasInt ( FeeSchedule [ gasFeeKind ] ) ) )
2021-04-08 14:52:10 +00:00
2023-08-27 06:13:37 +00:00
func fixedOrLater ( gasFeeKind : static [ GasFeeKind ] ) : GasCost =
when fork < FkBerlin :
2024-07-07 06:52:11 +00:00
GasCost ( kind : GckFixed , cost : static ( GasInt ( FeeSchedule [ gasFeeKind ] ) ) )
2023-08-27 06:13:37 +00:00
else :
# GckLater is processed by the opcode
2024-07-07 06:52:11 +00:00
GasCost ( kind : GckLater , cost : static ( GasInt ( FeeSchedule [ gasFeeKind ] ) ) )
2023-08-27 06:13:37 +00:00
2023-02-14 14:37:21 +00:00
func dynamic ( handler : proc ( value : UInt256 ) : GasInt
2024-06-07 08:24:32 +00:00
{. nimcall , gcsafe , raises : [ ] . } ) : GasCost =
2023-02-14 14:37:21 +00:00
GasCost ( kind : GckDynamic , d_handler : handler )
2021-04-08 14:52:10 +00:00
2023-02-14 14:37:21 +00:00
func memExpansion ( handler : proc ( currentMemSize , memOffset , memLength : GasNatural ) : GasInt
2024-06-07 08:24:32 +00:00
{. nimcall , gcsafe , raises : [ ] . } ) : GasCost =
2021-04-08 14:52:10 +00:00
GasCost ( kind : GckMemExpansion , m_handler : handler )
2024-07-05 04:55:13 +00:00
func handleCall ( handler : proc ( value : UInt256 , gasParams : GasParams ) : EvmResult [ CallGasResult ]
2024-06-07 08:24:32 +00:00
{. nimcall , gcsafe , raises : [ ] . } ) : GasCost =
2024-07-05 04:55:13 +00:00
GasCost ( kind : GckCall , c_handler : handler )
2021-04-08 14:52:10 +00:00
2024-07-05 04:55:13 +00:00
func handleCreate ( handler : proc ( value : UInt256 , gasParams : GasParamsCr ) : GasInt
2024-06-07 08:24:32 +00:00
{. nimcall , gcsafe , raises : [ ] . } ) : GasCost =
GasCost ( kind : GckCreate , cr_handler : handler )
2024-07-05 04:55:13 +00:00
func handleSuicide ( handler : proc ( condition : bool ) : GasInt
{. nimcall , gcsafe , raises : [ ] . } ) : GasCost =
GasCost ( kind : GckSuicide , sc_handler : handler )
func handleSstore ( handler : proc ( value : UInt256 , gasParams : GasParamsSs ) : SStoreGasResult
{. nimcall , gcsafe , raises : [ ] . } ) : GasCost =
GasCost ( kind : GckSstore , ss_handler : handler )
2021-04-08 14:52:10 +00:00
# Returned value
fill_enum_table_holes ( Op , GasCost ( kind : GckInvalidOp ) ) :
[
# 0s: Stop and Arithmetic Operations
Stop : fixed GasZero ,
Add : fixed GasVeryLow ,
Mul : fixed GasLow ,
Sub : fixed GasVeryLow ,
Div : fixed GasLow ,
Sdiv : fixed GasLow ,
Mod : fixed GasLow ,
Smod : fixed GasLow ,
Addmod : fixed GasMid ,
Mulmod : fixed GasMid ,
Exp : dynamic ` prefix gasExp ` ,
SignExtend : fixed GasLow ,
# 10s: Comparison & Bitwise Logic Operations
Lt : fixed GasVeryLow ,
Gt : fixed GasVeryLow ,
Slt : fixed GasVeryLow ,
Sgt : fixed GasVeryLow ,
Eq : fixed GasVeryLow ,
IsZero : fixed GasVeryLow ,
And : fixed GasVeryLow ,
Or : fixed GasVeryLow ,
Xor : fixed GasVeryLow ,
Not : fixed GasVeryLow ,
Byte : fixed GasVeryLow ,
Shl : fixed GasVeryLow ,
Shr : fixed GasVeryLow ,
Sar : fixed GasVeryLow ,
# 20s: SHA3
Sha3 : memExpansion ` prefix gasSha3 ` ,
# 30s: Environmental Information
Address : fixed GasBase ,
2023-08-27 06:13:37 +00:00
Balance : fixedOrLater GasBalance ,
2021-04-08 14:52:10 +00:00
Origin : fixed GasBase ,
Caller : fixed GasBase ,
CallValue : fixed GasBase ,
CallDataLoad : fixed GasVeryLow ,
CallDataSize : fixed GasBase ,
CallDataCopy : memExpansion ` prefix gasCopy ` ,
CodeSize : fixed GasBase ,
CodeCopy : memExpansion ` prefix gasCopy ` ,
GasPrice : fixed GasBase ,
2023-08-27 06:13:37 +00:00
ExtCodeSize : fixedOrLater GasExtCode ,
2021-04-08 14:52:10 +00:00
ExtCodeCopy : memExpansion ` prefix gasExtCodeCopy ` ,
ReturnDataSize : fixed GasBase ,
ReturnDataCopy : memExpansion ` prefix gasCopy ` ,
2023-08-27 06:13:37 +00:00
ExtCodeHash : fixedOrLater GasExtCodeHash ,
2021-04-08 14:52:10 +00:00
# 40s: Block Information
Blockhash : fixed GasBlockhash ,
Coinbase : fixed GasBase ,
Timestamp : fixed GasBase ,
Number : fixed GasBase ,
Difficulty : fixed GasBase ,
GasLimit : fixed GasBase ,
2021-05-15 08:31:58 +00:00
ChainIdOp : fixed GasBase ,
2021-04-08 14:52:10 +00:00
SelfBalance : fixed GasLow ,
2021-06-27 13:19:22 +00:00
BaseFee : fixed GasBase ,
2023-06-24 13:56:44 +00:00
BlobHash : fixed GasVeryLow ,
2023-10-01 07:24:15 +00:00
BlobBaseFee : fixed GasBase ,
2021-04-08 14:52:10 +00:00
# 50s: Stack, Memory, Storage and Flow Operations
Pop : fixed GasBase ,
Mload : memExpansion ` prefix gasLoadStore ` ,
Mstore : memExpansion ` prefix gasLoadStore ` ,
Mstore8 : memExpansion ` prefix gasLoadStore ` ,
2023-08-27 06:13:37 +00:00
Sload : fixedOrLater GasSload ,
2024-07-05 04:55:13 +00:00
Sstore : handleSstore ` prefix gasSstore ` ,
2021-04-08 14:52:10 +00:00
Jump : fixed GasMid ,
JumpI : fixed GasHigh ,
Pc : fixed GasBase ,
Msize : fixed GasBase ,
Gas : fixed GasBase ,
JumpDest : fixed GasJumpDest ,
2023-06-25 01:24:45 +00:00
# 5c & 5d: Transient storage operations
Tload : fixed GasWarmStorageRead ,
Tstore : fixed GasWarmStorageRead ,
2023-08-27 06:13:37 +00:00
2023-06-26 09:58:59 +00:00
# 5e: Memory copy
Mcopy : memExpansion ` prefix gasCopy ` ,
2021-04-08 14:52:10 +00:00
2023-01-04 13:11:33 +00:00
# 5f, 60s & 70s: Push Operations
Push0 : fixed GasBase ,
2021-04-08 14:52:10 +00:00
Push1 : fixed GasVeryLow ,
Push2 : fixed GasVeryLow ,
Push3 : fixed GasVeryLow ,
Push4 : fixed GasVeryLow ,
Push5 : fixed GasVeryLow ,
Push6 : fixed GasVeryLow ,
Push7 : fixed GasVeryLow ,
Push8 : fixed GasVeryLow ,
Push9 : fixed GasVeryLow ,
Push10 : fixed GasVeryLow ,
Push11 : fixed GasVeryLow ,
Push12 : fixed GasVeryLow ,
Push13 : fixed GasVeryLow ,
Push14 : fixed GasVeryLow ,
Push15 : fixed GasVeryLow ,
Push16 : fixed GasVeryLow ,
Push17 : fixed GasVeryLow ,
Push18 : fixed GasVeryLow ,
Push19 : fixed GasVeryLow ,
Push20 : fixed GasVeryLow ,
Push21 : fixed GasVeryLow ,
Push22 : fixed GasVeryLow ,
Push23 : fixed GasVeryLow ,
Push24 : fixed GasVeryLow ,
Push25 : fixed GasVeryLow ,
Push26 : fixed GasVeryLow ,
Push27 : fixed GasVeryLow ,
Push28 : fixed GasVeryLow ,
Push29 : fixed GasVeryLow ,
Push30 : fixed GasVeryLow ,
Push31 : fixed GasVeryLow ,
Push32 : fixed GasVeryLow ,
# 80s: Duplication Operations
Dup1 : fixed GasVeryLow ,
Dup2 : fixed GasVeryLow ,
Dup3 : fixed GasVeryLow ,
Dup4 : fixed GasVeryLow ,
Dup5 : fixed GasVeryLow ,
Dup6 : fixed GasVeryLow ,
Dup7 : fixed GasVeryLow ,
Dup8 : fixed GasVeryLow ,
Dup9 : fixed GasVeryLow ,
Dup10 : fixed GasVeryLow ,
Dup11 : fixed GasVeryLow ,
Dup12 : fixed GasVeryLow ,
Dup13 : fixed GasVeryLow ,
Dup14 : fixed GasVeryLow ,
Dup15 : fixed GasVeryLow ,
Dup16 : fixed GasVeryLow ,
# 90s: Exchange Operations
Swap1 : fixed GasVeryLow ,
Swap2 : fixed GasVeryLow ,
Swap3 : fixed GasVeryLow ,
Swap4 : fixed GasVeryLow ,
Swap5 : fixed GasVeryLow ,
Swap6 : fixed GasVeryLow ,
Swap7 : fixed GasVeryLow ,
Swap8 : fixed GasVeryLow ,
Swap9 : fixed GasVeryLow ,
Swap10 : fixed GasVeryLow ,
Swap11 : fixed GasVeryLow ,
Swap12 : fixed GasVeryLow ,
Swap13 : fixed GasVeryLow ,
Swap14 : fixed GasVeryLow ,
Swap15 : fixed GasVeryLow ,
Swap16 : fixed GasVeryLow ,
# a0s: Logging Operations
Log0 : memExpansion ` prefix gasLog0 ` ,
Log1 : memExpansion ` prefix gasLog1 ` ,
Log2 : memExpansion ` prefix gasLog2 ` ,
Log3 : memExpansion ` prefix gasLog3 ` ,
Log4 : memExpansion ` prefix gasLog4 ` ,
# f0s: System operations
2024-06-07 08:24:32 +00:00
Create : handleCreate ` prefix gasCreate ` ,
2024-07-05 04:55:13 +00:00
Call : handleCall ` prefix gasCall ` ,
CallCode : handleCall ` prefix gasCall ` ,
2021-04-08 14:52:10 +00:00
Return : memExpansion ` prefix gasHalt ` ,
2024-07-05 04:55:13 +00:00
DelegateCall : handleCall ` prefix gasCall ` ,
2021-04-08 14:52:10 +00:00
Create2 : memExpansion ` prefix gasCreate2 ` ,
2024-07-05 04:55:13 +00:00
StaticCall : handleCall ` prefix gasCall ` ,
2021-04-08 14:52:10 +00:00
Revert : memExpansion ` prefix gasHalt ` ,
Invalid : fixed GasZero ,
2024-07-05 04:55:13 +00:00
SelfDestruct : handleSuicide ` prefix gasSelfDestruct `
2021-04-08 14:52:10 +00:00
]
# Generate the fork-specific gas costs tables
const
BaseGasFees : GasFeeSchedule = [
# Fee Schedule for the initial Ethereum forks
2024-07-07 06:52:11 +00:00
GasZero : 0 ,
2021-04-08 14:52:10 +00:00
GasBase : 2 ,
GasVeryLow : 3 ,
GasLow : 5 ,
GasMid : 8 ,
GasHigh : 10 ,
GasExtCode : 20 , # Changed to 700 in Tangerine (EIP150)
GasBalance : 20 , # Changed to 400 in Tangerine (EIP150)
GasSload : 50 , # Changed to 200 in Tangerine (EIP150)
GasJumpDest : 1 ,
GasSset : 20_000 ,
GasSreset : 5_000 ,
2022-04-08 04:54:11 +00:00
RefundsClear : 15_000 ,
2021-04-08 14:52:10 +00:00
RefundSelfDestruct : 24_000 ,
GasSelfDestruct : 0 , # Changed to 5000 in Tangerine (EIP150)
GasCreate : 32000 ,
GasCodeDeposit : 200 ,
GasCall : 40 , # Changed to 700 in Tangerine (EIP150)
GasCallValue : 9000 ,
GasCallStipend : 2300 ,
GasNewAccount : 25_000 ,
GasExp : 10 ,
GasExpByte : 10 , # Changed to 50 in Spurious Dragon (EIP160)
GasMemory : 3 ,
GasTXCreate : 0 , # Changed to 32000 in Homestead (EIP2)
GasTXDataZero : 4 ,
GasTXDataNonZero : 68 ,
GasTransaction : 21000 ,
GasLog : 375 ,
GasLogData : 8 ,
GasLogTopic : 375 ,
GasSha3 : 30 ,
GasSha3Word : 6 ,
GasCopy : 3 ,
GasBlockhash : 20 ,
2023-01-04 13:11:33 +00:00
GasExtCodeHash : 400 ,
2023-03-21 13:27:12 +00:00
GasInitcodeWord : 0 , # Changed to 2 in EIP-3860
GasWarmStorageRead : WarmStorageReadCost
2021-04-08 14:52:10 +00:00
]
# Create the schedule for each forks
func homesteadGasFees ( previousFees : GasFeeSchedule ) : GasFeeSchedule =
# https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.md
result = previousFees
result [ GasTXCreate ] = 32000
func tangerineGasFees ( previousFees : GasFeeSchedule ) : GasFeeSchedule =
# https://github.com/ethereum/EIPs/blob/master/EIPS/eip-150.md
result = previousFees
result [ GasExtCode ] = 700
result [ GasSload ] = 200
result [ GasSelfDestruct ] = 5000
result [ GasBalance ] = 400
result [ GasCall ] = 700
func spuriousGasFees ( previousFees : GasFeeSchedule ) : GasFeeSchedule =
# https://github.com/ethereum/EIPs/blob/master/EIPS/eip-160.md
result = previousFees
result [ GasExpByte ] = 50
func istanbulGasFees ( previousFees : GasFeeSchedule ) : GasFeeSchedule =
# https://eips.ethereum.org/EIPS/eip-1884
result = previousFees
result [ GasSload ] = 800
result [ GasExtCodeHash ] = 700
result [ GasBalance ] = 700
result [ GasTXDataNonZero ] = 16
func berlinGasFees ( previousFees : GasFeeSchedule ) : GasFeeSchedule =
# https://eips.ethereum.org/EIPS/eip-2929
result = previousFees
2021-09-22 02:34:13 +00:00
# these opcodes gas are calculated inside opcode
result [ GasBalance ] = 0
result [ GasExtCodeHash ] = 0
result [ GasExtCode ] = 0
2021-04-08 14:52:10 +00:00
# SLOAD gasCost become fully dynamic, see sloadEIP2929
2022-04-08 04:54:11 +00:00
result [ GasSload ] = 0
2021-04-08 14:52:10 +00:00
result [ GasCall ] = WarmStorageReadCost
2021-06-28 13:06:29 +00:00
func londonGasFees ( previousFees : GasFeeSchedule ) : GasFeeSchedule =
result = previousFees
# EIP-3529 RefundsClear(4800) =
# EIP-2929(5000 - ColdSloadCost) +
# EIP-2930(ACCESS_LIST_STORAGE_KEY_COST)
result [ RefundsClear ] =
5000 - ColdSloadCost +
ACCESS_LIST_STORAGE_KEY_COST
2023-01-04 13:11:33 +00:00
func shanghaiGasFees ( previousFees : GasFeeSchedule ) : GasFeeSchedule =
result = previousFees
result [ GasInitcodeWord ] = 2 . GasInt # INITCODE_WORD_COST from EIP-3860
2021-04-08 14:52:10 +00:00
const
HomesteadGasFees = BaseGasFees . homesteadGasFees
TangerineGasFees = HomesteadGasFees . tangerineGasFees
SpuriousGasFees = TangerineGasFees . spuriousGasFees
IstanbulGasFees = SpuriousGasFees . istanbulGasFees
BerlinGasFees = IstanbulGasFees . berlinGasFees
2021-06-28 13:06:29 +00:00
LondonGasFees = BerlinGasFees . londonGasFees
2023-01-04 13:11:33 +00:00
ShanghaiGasFees = LondonGasFees . shanghaiGasFees
2021-04-08 14:52:10 +00:00
2022-12-02 04:35:41 +00:00
gasFees * : array [ EVMFork , GasFeeSchedule ] = [
2021-04-08 14:52:10 +00:00
FkFrontier : BaseGasFees ,
FkHomestead : HomesteadGasFees ,
FkTangerine : TangerineGasFees ,
FkSpurious : SpuriousGasFees ,
FkByzantium : SpuriousGasFees ,
FkConstantinople : SpuriousGasFees ,
FkPetersburg : SpuriousGasFees ,
FkIstanbul : IstanbulGasFees ,
2021-06-28 02:01:18 +00:00
FkBerlin : BerlinGasFees ,
2022-09-26 12:23:54 +00:00
FkLondon : LondonGasFees ,
FkParis : LondonGasFees ,
2023-01-04 13:11:33 +00:00
FkShanghai : ShanghaiGasFees ,
FkCancun : ShanghaiGasFees ,
2024-03-28 06:47:02 +00:00
FkPrague : ShanghaiGasFees ,
2021-04-08 14:52:10 +00:00
]
gasCosts ( FkFrontier , base , BaseGasCosts )
gasCosts ( FkHomestead , homestead , HomesteadGasCosts )
gasCosts ( FkTangerine , tangerine , TangerineGasCosts )
gasCosts ( FkSpurious , spurious , SpuriousGasCosts )
gasCosts ( FkConstantinople , constantinople , ConstantinopleGasCosts )
gasCosts ( FkIstanbul , istanbul , IstanbulGasCosts )
gasCosts ( FkBerlin , berlin , BerlinGasCosts )
2021-06-28 02:01:18 +00:00
gasCosts ( FkLondon , london , LondonGasCosts )
2023-01-04 13:11:33 +00:00
gasCosts ( FkShanghai , shanghai , ShanghaiGasCosts )
2021-04-08 14:52:10 +00:00
2023-08-30 13:38:32 +00:00
type
OpGck * = array [ Op , GasCostKind ]
func opGck ( gc : GasCosts ) : OpGck {. compileTime . } =
for op , x in gc :
result [ op ] = x . kind
# Map fork to GasCostKind
# used in op_dispatcher.nim
const forkToGck * : array [ EVMFork , OpGck ] = [
opGck BaseGasCosts , # FkFrontier
opGck HomesteadGasCosts , # FkHomestead
opGck TangerineGasCosts , # kTangerine
opGck SpuriousGasCosts , # FkSpurious
opGck SpuriousGasCosts , # FkByzantium
opGck ConstantinopleGasCosts , # FkConstantinople
opGck SpuriousGasCosts , # FkPetersburg
opGck IstanbulGasCosts , # FkIstanbul
opGck BerlinGasCosts , # FkBerlin
opGck LondonGasCosts , # FkLondon
opGck LondonGasCosts , # FkParis
opGck ShanghaiGasCosts , # FkShanghai
opGck ShanghaiGasCosts , # FkCancun
2024-03-28 06:47:02 +00:00
opGck ShanghaiGasCosts , # FkPrague
2023-08-30 13:38:32 +00:00
]
2022-12-02 04:35:41 +00:00
proc forkToSchedule * ( fork : EVMFork ) : GasCosts =
2021-04-08 14:52:10 +00:00
if fork < FkHomestead :
BaseGasCosts
elif fork < FkTangerine :
HomesteadGasCosts
elif fork < FkSpurious :
TangerineGasCosts
elif fork = = FkConstantinople :
ConstantinopleGasCosts # with EIP-1283
elif fork < FkIstanbul :
SpuriousGasCosts
elif fork < FkBerlin :
IstanbulGasCosts
2021-06-28 02:01:18 +00:00
elif fork < FkLondon :
2021-04-08 14:52:10 +00:00
BerlinGasCosts
2023-01-04 13:11:33 +00:00
elif fork < FkShanghai :
2022-02-08 09:17:59 +00:00
LondonGasCosts
2023-01-04 13:11:33 +00:00
else :
ShanghaiGasCosts
2021-04-08 14:52:10 +00:00
const
## Precompile costs
2024-06-14 07:31:08 +00:00
GasSHA256 * = GasInt 60
GasSHA256Word * = GasInt 12
GasRIPEMD160 * = GasInt 600
GasRIPEMD160Word * = GasInt 120
GasIdentity * = GasInt 15
GasIdentityWord * = GasInt 3
GasECRecover * = GasInt 3000
GasECAdd * = GasInt 500
GasECAddIstanbul * = GasInt 150
GasECMul * = GasInt 40000
GasECMulIstanbul * = GasInt 6000
GasECPairingBase * = GasInt 100000
GasECPairingBaseIstanbul * = GasInt 45000
GasECPairingPerPoint * = GasInt 80000
GasECPairingPerPointIstanbul * = GasInt 34000
2021-04-08 14:52:10 +00:00
# The Yellow Paper is special casing the GasQuadDivisor.
# It is defined in Appendix G with the other GasFeeKind constants
# instead of Appendix E for precompiled contracts
GasQuadDivisor * = 20
GasQuadDivisorEIP2565 * = 3
2024-06-08 00:39:53 +00:00
# https://eips.ethereum.org/EIPS/eip-2537
2024-06-14 07:31:08 +00:00
Bls12381G1AddGas * = GasInt 500
Bls12381G1MulGas * = GasInt 12000
Bls12381G2AddGas * = GasInt 800
Bls12381G2MulGas * = GasInt 45000
Bls12381PairingBaseGas * = GasInt 115000
Bls12381PairingPerPairGas * = GasInt 23000
Bls12381MapG1Gas * = GasInt 5500
Bls12381MapG2Gas * = GasInt 110000