This proposal revises the gas cost schedule for opcodes, precompiles, memory expansion, and data access, prioritizing computational complexity, while excluding network-related costs such as state persistence. The adjustments aim to enhance gas cost accuracy and rebalance the cost structure.
Gas costs compromise of two components: network (social) cost and computation cost. Network cost reflects the blockchain’s effort to maintain state, including adding transactions, storage, logs, calldata, and receipts, while computation cost represents the non-durable processing effort of smart contracts.
The importance of adequate gas costs arises from the nature of computations done on the Ethereum blockchain, and has been discussed in many research papers. Moreover it is paramount from the perspective of security and network stability. Gas cost is a natural deterrent from abusing the network's capacity. On the other hand, the network needs to be affordable and efficient to use. Adequate gas cost strikes a balance between these two requirements.
While several EIPs (e.g., EIP-160, EIP-1884) have refined network-related gas costs, computational costs have remained largely static since Ethereum’s inception. With multiple EVM implementations now stable and optimized, alongside advanced tools, we can assess how well the current gas schedule aligns with hardware workload profiles.
Measurements and estimations depend on various factors, including hardware, OS, virtualization, compiler, memory management, EVM, and more. The execution of a single opcode impacts or depends on caching, block preparation, block finalization, garbage collectors, code analysis, parsing etc. Consequently, the individual computational cost is a sum of multiple factors spread over the software stack. Despite this complexity, examinations have shown that the computational cost outline is consistent across EVM implementations, technology stacks, and contexts.
For instance, experimental data might reveal that the computational effort required to execute one opcode is consistently twice that of another opcode across most EVM implementations. In such cases, the gas cost ratio between these opcodes should be set at 2:1 to reflect their relative computational complexity. This approach relies on empirical measurements rather than theoretical assumptions. The gas cost schedule should, therefore, accurately reflect computational complexity.
The current gas cost schedule differs in many places from the experimentally determined computational complexity. Many significant outliers have been identified, indicating a need for rebalancing. Many others are reasonable candidates to be rebalanced. The unbalanced gas cost schedule can: expose a risk to the network, open an attack vector, lead to false optimization, and break the principle that gas is the abstract unit of transaction execution effort.
The gas cost schedule is inherently relative, adjustable as long as proportions hold. A substantial reduction in the gas costs contained in this proposal has two significant effects: it increases blockchain throughput in terms of transactions per block, and it increases the proportional weight of the network storage costs.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
Constant | Value |
---|---|
WARM_STORAGE_READ_COST |
5 |
BASE_OPCODE_COST |
1 |
FAST_OPCODE_COST |
2 |
MID_OPCODE_COST |
3 |
EXP_BASE_COST |
2 |
EXP_PER_BYTE_COST |
4 |
COPY_PER_WORD_COST |
1 |
Name | Formula | Description |
---|---|---|
data_size | len(data) | The size of the data expressed as number of bytes |
data_word_size | (len(data) + 31) / 32 | The size of the data expressed as number of words |
exponent_byte_size | len(exponent) | The size in bytes of the exponent in the EXP opcode. |
sets_count | len(data) / 192 | The number of pair sets in the ECPAIRING precompile. |
memory_expansion_cost | memory_cost(current_word_size) - memory_cost(previous_word_size) | The cost of expanding memory to current_word_size words from previous_word_size words. In a single context memory cannot contract, so the formula is always non-negative |
memory_cost | (memory_word_size ** 2) / 512 | The cost of memory for data_word_size words. |
memory_word_size | (memory_size + 31) / 32 | The size of the allocated memory expressed as number of words |
address_access_cost | 5 (warm) | 2600 (cold) | The cost of accessing warm and cold address data. |
storage_access_cost | 5 (warm) | 2100 (cold) | The cost of accessing warm and cold storage data. |
Opcode | Name | Pre-change Gas | Gas Cost |
---|---|---|---|
0x01 | ADD | 3 | BASE_OPCODE_COST |
0x02 | MUL | 5 | BASE_OPCODE_COST |
0x03 | SUB | 3 | BASE_OPCODE_COST |
0x04 | DIV | 5 | BASE_OPCODE_COST |
0x05 | SDIV | 5 | BASE_OPCODE_COST |
0x06 | MOD | 5 | BASE_OPCODE_COST |
0x07 | SMOD | 5 | BASE_OPCODE_COST |
0x08 | ADDMOD | 8 | FAST_OPCODE_COST |
0x09 | MULMOD | 8 | MID_OPCODE_COST |
0x0A | EXP | 10 + 50 * exponent_byte_size | EXP_BASE_COST + EXP_PER_BYTE_COST * exponent_byte_size |
0x0B | SIGNEXTEND | 5 | BASE_OPCODE_COST |
0x10 | LT | 3 | BASE_OPCODE_COST |
0x11 | GT | 3 | BASE_OPCODE_COST |
0x12 | SLT | 3 | BASE_OPCODE_COST |
0x13 | SGT | 3 | BASE_OPCODE_COST |
0x14 | EQ | 3 | BASE_OPCODE_COST |
0x15 | ISZERO | 3 | BASE_OPCODE_COST |
0x16 | AND | 3 | BASE_OPCODE_COST |
0x17 | OR | 3 | BASE_OPCODE_COST |
0x18 | XOR | 3 | BASE_OPCODE_COST |
0x19 | NOT | 3 | BASE_OPCODE_COST |
0x1A | BYTE | 3 | BASE_OPCODE_COST |
0x1B | SHL | 3 | BASE_OPCODE_COST |
0x1C | SHR | 3 | BASE_OPCODE_COST |
0x1D | SAR | 3 | BASE_OPCODE_COST |
0x30 | ADDRESS | 2 | BASE_OPCODE_COST |
0x31 | BALANCE | address_access_cost | address_access_cost |
0x32 | ORIGIN | 2 | BASE_OPCODE_COST |
0x33 | CALLER | 2 | BASE_OPCODE_COST |
0x34 | CALLVALUE | 2 | BASE_OPCODE_COST |
0x35 | CALLDATALOAD | 3 | BASE_OPCODE_COST |
0x36 | CALLDATASIZE | 2 | BASE_OPCODE_COST |
0x37 | CALLDATACOPY | 3 + 3 * data_word_size + memory_expansion_cost | BASE_OPCODE_COST + COPY_PER_WORD_COST * data_word_size + memory_expansion_cost |
0x38 | CODESIZE | 2 | BASE_OPCODE_COST |
0x39 | CODECOPY | 3 + 3 * data_word_size + memory_expansion_cost | BASE_OPCODE_COST + COPY_PER_WORD_COST * data_word_size + memory_expansion_cost |
0x3A | GASPRICE | 2 | BASE_OPCODE_COST |
0x3B | EXTCODESIZE | address_access_cost | address_access_cost |
0x3C | EXTCODECOPY | 0 + 3 * data_word_size + memory_expansion_cost + address_access_cost | COPY_PER_WORD_COST * data_word_size + memory_expansion_cost + address_access_cost |
0x3D | RETURNDATASIZE | 2 | BASE_OPCODE_COST |
0x3E | RETURNDATACOPY | 3 + 3 * data_word_size + memory_expansion_cost | BASE_OPCODE_COST + COPY_PER_WORD_COST * data_word_size + memory_expansion_cost |
0x3F | EXTCODEHASH | address_access_cost | address_access_cost |
0x41 | COINBASE | 2 | BASE_OPCODE_COST |
0x42 | TIMESTAMP | 2 | BASE_OPCODE_COST |
0x43 | NUMBER | 2 | BASE_OPCODE_COST |
0x45 | GASLIMIT | 2 | BASE_OPCODE_COST |
0x46 | CHAINID | 2 | BASE_OPCODE_COST |
0x47 | SELFBALANCE | 5 | BASE_OPCODE_COST |
0x50 | POP | 2 | BASE_OPCODE_COST |
0x51 | MLOAD | 3 | BASE_OPCODE_COST |
0x52 | MSTORE | 3 + memory_expansion_cost | BASE_OPCODE_COST + memory_expansion_cost |
0x53 | MSTORE8 | 3 + memory_expansion_cost | BASE_OPCODE_COST + memory_expansion_cost |
0x56 | JUMP | 8 | BASE_OPCODE_COST |
0x57 | JUMPI | 10 | BASE_OPCODE_COST |
0x58 | PC | 2 | BASE_OPCODE_COST |
0x59 | MSIZE | 2 | BASE_OPCODE_COST |
0x5A | GAS | 2 | BASE_OPCODE_COST |
0x5C | TLOAD | 100 | WARM_STORAGE_READ_COST |
0x5D | TSTORE | 100 | WARM_STORAGE_READ_COST |
0x5B | JUMPDEST | 1 | BASE_OPCODE_COST |
0x5E | MCOPY | 3 + 3 * data_word_size + memory_expansion_cost | BASE_OPCODE_COST + COPY_PER_WORD_COST * data_word_size + memory_expansion_cost |
0x5F | PUSH0 | 2 | BASE_OPCODE_COST |
0x60 - 0x7F | PUSHx | 3 | BASE_OPCODE_COST |
0x80 - 0x8F | DUPx | 3 | BASE_OPCODE_COST |
0x90 - 0x9F | SWAPx | 3 | BASE_OPCODE_COST |
Precompile | Name | Current Gas | Proposed Gas |
---|---|---|---|
0x07 | ECMUL | 6000 | 2700 |
0x08 | ECPAIRING | 45000 + 34000 * sets_count | 8000 + 7000 * sets_count |
0x0A | POINTEVAL | 50000 | 21000 |
The calculated and rescaled cost of 0x06 (ECADD) is higher than the current cost. Still this cost is left unchanged to maintain compatibility with existing contracts.
The remaining precompiles remains unchanged.
Additionally, all precompiles benefit from the lowered cost of *CALL opcodes (see below).
The formula for these opcodes remains the same, but the total cost calculated is affected by changes to some components.
Opcode | Name | Affected formula component |
---|---|---|
0x54 | SLOAD | storage_access_cost |
0x55 | SSTORE | storage_access_cost |
0xF0 | CREATE | memory_expansion_cost |
0xF5 | CREATE2 | memory_expansion_cost |
0xF1 | CALL | memory_expansion_cost, address_access_cost |
0xFA | STATICCALL | memory_expansion_cost, address_access_cost |
0xF4 | DELEGATECALL | memory_expansion_cost, address_access_cost |
0xF3 | RETURN | memory_expansion_cost |
0xFD | REVERT | memory_expansion_cost |
The Gas Cost Estimator project serves as the empirical foundation for this EIP. This project conducted extensive testing across seven widely-used EVM implementations to measure the actual computational effort required by various opcodes and operations. Conducted in a controlled environment to eliminate external variables, the tests produced accurate and reproducible results. The findings highlight misalignments between the current gas cost schedule and the real-world computational complexity of EVM operations. By recalibrating gas costs based on these measurements, this EIP seeks to align pricing with computational reality, thereby improving Ethereum’s performance and resilience.
This EIP is based on the radical proposal from the Gas Cost Estimator project. This means that all estimates have been additionally rescaled so that basic arithmetic operations cost just 1 gas unit. The rescale factor
used is 0.217391304 as defined in the Gas Cost Estimator project. This factor should be used when comparing this proposals to other EIPs or projects.
Several initiatives have explored the real gas costs of EVM operations, providing valuable context for this EIP. Notable examples include:
rescale factor
, its costs align with this proposal, requiring no further changes. This consistency validates our measuring approach.memory_expansion_cost
formula.These projects collectively affirm the need to reassess gas costs and demonstrate broad alignment with our approach.
An alternative considered during this EIP’s development was fractional gas pricing, which would enable more granular cost assignments based on computational effort.
Given these trade-offs, we opted against fractional pricing in favor of a simpler, more feasible recalibration.
This EIP intentionally focuses on computational complexity—measured as execution time on a bare CPU — while excluding network-related costs like state persistency. This ensures the proposed gas cost adjustments remain implementation-agnostic, applicable across diverse EVM clients regardless of their technological stack. By leveraging empirical data from multiple EVM implementations, we establish a universal, verifiable benchmark for computational effort. Unlike network costs, which fluctuate with factors like long-term state persistency or blockchain size, computational complexity is directly quantifiable. This focus simplifies estimation and enhances the proposal’s clarity and applicability within Ethereum’s varied ecosystem.
Note that, it is safer to decrease because of Backwards Compatibility issues related to gas limits and hard-coded gas limits (see below). Deciding whether to increase or decrease gas costs for specific operations requires balancing efficiency and security.
This EIP adopts a conservative strategy, prioritizing decreases for operations that empirical data show as overpriced, while ensuring no reductions compromise security. This approach aims to optimize efficiency without introducing new vulnerabilities.
This proposal introduces a simplified memory_expansion_cost
formula. The current formula combines a constant cost per word and an additional quadratic cost. The latter is added to prevent attacks exploiting excessive memory usage. Our findings, supported by related projects, indicate the constant cost per word is negligible and already accounted for in opcodes that expand memory. Thus, the revised formula retains only the quadratic cost, preserving security while reducing overall gas costs. As a result, the first 22 words of memory incur no additional cost, as the quadratic penalty begins beyond this threshold.
The tables below compare the maximum memory allocations under the current and proposed gas schedules, showed for different block gas limits.
Single Opcode Memory Allocation: This table shows the estimated maximum memory allocation achievable with a single opcode:
Block Gas Limit | Current Gas Schedule | Proposed Gas Schedule |
---|---|---|
30M | 123,169 words | 123,935 words |
36M | 134,998 words | 135,764 words |
60M | 174,504 words | 175,271 words |
Multiple Calls Memory Allocation: This table estimates the maximum memory allocation achievable with a transaction that repeatedly makes subcalls in a loop, until block gas limit is reached. Each subcall allocates memory in the most effective way balancing call costs and memory expansion costs. For the current gas schedule, it is 278 words per call, and for the proposed gas schedule, it is 93 words per call.
Block Gas Limit | Current Gas Schedule | Proposed Gas Schedule |
---|---|---|
30M | 7,459,574 words | 82,058,736 words |
36M | 8,951,600 words | 98,470,539 words |
60M | 14,919,426 words | 164,117,565 words |
Experiments with stack depth and recursive calls showed that the maximal total allocated memory at a single moment increases less than 10% comparing Current and Proposed Gas Schedule.
EIP-7667 proposes an alternative framework for measuring resource consumption, emphasizing the demands of generating ZK-SNARK proofs — an area of growing importance for Ethereum. This includes hashing opcodes and precompiles, which are computationally intensive in ZK-SNARK contexts. Two motivations drive EIP-7667: first, the long-term vision of a ZK-SNARKed Ethereum Layer 1 (L1), where such operations will be critical; second, the immediate challenges faced by ZK-based Layer 2 (L2) solutions, which often limit hashing operations to manage costs. In contrast, this EIP uses a bare CPU as its reference point, focusing on general computational complexity rather than ZK-specific needs. The proposed changes are not expected to significantly alter the average case for ZK-based L2s but may impact worst-case scenarios. While acknowledging the relevance of ZK-SNARKs, this EIP argues that their systemic challenges require distinct solutions beyond the scope of this proposal. There are efforts and progress in the space, still the vision of a ZK-SNARKed L1 seems to be distant enough, to justify the focus on optimizing the current setup for broader network benefits.
Reducing computational gas costs aims to increase transaction throughput, allowing more transactions per block. EIP-7783 and EIP-7790 pursue a similar outcome by raising the block gas limit — a simpler approach with a controlled impact. However, they do not address mispriced opcodes and precompiles. Our proposal complements these efforts by correcting pricing inaccuracies, and both strategies should be implemented together to maximize throughput while ensuring cost accuracy.
By implementing the proposal, the overall computational cost will decrease, while the storage costs remains the same. This reflects the improvements in EVM software efficiency and the cost of ever growing state. By increasing the relative gap between computational and storage costs, the proposal indirectly incentivizes developers to optimize their contracts and reduce the state size. This is a positive side effect of the proposal.
The proposal modifies two formulas for address_access_cost
and storage_access_cost
, but for the warm data only. This is because it can be estimated using the same methodology used here. The cold access cost is multi-layered, and depends on the blockchain state, its size and data structure. Accurate measurements would require to devise more suitable methodology.
The two storage opcodes, SLOAD and STORE, are indirectly updated. Their cost formulas are complex and only the warm/cold data access cost ratio is modified. Similarly for CREATE and CREATE2. Only the memory expansion cost factor is modified, which is computational and is consistent with other opcodes that may expand memory.
For the MODEXP precompile, this proposal assumes EIP-7883 is adopted, and its gas cost remains unchanged. For ECPAIRING, the gas cost is reduced by approximately a factor of 5, consistent with similar adjustments in this proposal. Precompiles such as ECRECOVER, IDENTITY, ECADD, ECMUL, BLAKE2F, and POINTEVAL either retain their current gas costs or see moderate reductions.
Projects like Nethermind's Gas Benchmarks highlight a security concern: lowering the gas cost for ECRECOVER could lead to the worst-case scenario where the block computation time exceeds safety threshold. A similar issue applies to MODEXP. As the result, the rescale factor
cannot be lower that the proposed 0.217391304
even though there is a room for further reduction. Note that the maximum number of operations in a block depends on the gas cost schedule and the block gas limit.
The Gas Cost Estimator project suggests a slight increase in ECRECOVER’s gas cost, but this proposal avoids that change to maintain backward compatibility and because the impact would be minor.
The hashing operations, the precompiles SHA2-256, RIPEMD-160, BLAKE2F, and the KECCAK256 opcode, are not updated here deliberately. The examinations based on current Mainnet EVM implementations discovered settings that could and should be modified. Assuming changes proposed in this EIP as reference, the key findings include:
On the other hand, ZK based EVMs emerged for both Layer 2s recently and Mainnet in the future. And these solutions play important role in the ecosystem. Moreover, the situation is dynamic as there are efforts to optimize ZK proofs regarding the hashing operations. Changes in gas cost for these operations should be proposed in another EIP.
Additionally, the potential changes revealed by the examinations might seem substantial, but would not worsen the edge cases outlined in EIP-7667 for instance - they are scenarios for generating ZK proofs in blocks filled entirely with hashing operations.
The proposed changes to the gas cost schedule will require a hardfork due to their significant impact on the Ethereum network's operational mechanics. Below, we outline the key consequences of these changes and highlight areas where further research is needed to ensure a smooth transition.
The changes have the following consequences:
Further research might be required to ensure that contracts that use hard coded limits are not broken.
Code:
PUSH1 0x60
Gas cost: 1
Code:
PUSH2 0x0202
PUSH2 0x1000
EXP
Gas cost: 1 + 1 + (2 + 4 * 2) = 12
TODO: This EIP is a relatively simple change, but requires updates in many tests (spec, execution API, etc.). Due to the effort needed to update the tests, this will be provided only after the EIP is accepted
The reference implementation in Go-Ethereum provides new instruction set and new memoryGasCost
function. Additionally it contains a set of overrides for specific gas elements. The actual implementation requires proper versioning of the overrides.
const (
RepricedGasBaseStep uint64 = 1
RepricedGasFastStep uint64 = 2
RepricedGasMidStep uint64 = 3
//overrides
WarmStorageReadCost uint64 = 100 // WARM_STORAGE_READ_COST
ExpGas uint64 = 2 // Once per EXP instruction
ExpByteGas uint64 = 4 // One per byte of the EXP exponent
CopyGas uint64 = 1 // One per word of the copied code
// (CALLDATACOPY, CODECOPY, EXTCODECOPY,
// RETURNDATACOPY, MCOPY)
)
func newRepricedInstructionSet() JumpTable {
instructionSet := newPragueInstructionSet()
for _, op := range instructionSet {
if op.isPush || op.isDup || op.isSwap ||
op.constantGas == GasFastestStep || op.constantGas == GasFastStep {
op.constantGas = RepricedGasBaseStep
}
}
instructionSet[ADDMOD].constantGas = RepricedGasFastStep
instructionSet[MULMOD].constantGas = RepricedGasMidStep
instructionSet[TLOAD].constantGas = WarmStorageReadCost
instructionSet[TSTORE].constantGas = WarmStorageReadCost
validateAndFillMaxStack(&instructionSet)
return instructionSet
}
func memoryGasCost(mem *Memory, newMemSize uint64) (uint64, error) {
if newMemSize == 0 {
return 0, nil
}
if newMemSize > 0x1FFFFFFFE0 {
return 0, ErrGasUintOverflow
}
newMemSizeWords := ToWordSize(newMemSize)
newMemSize = newMemSizeWords * 32
if newMemSize > uint64(mem.Len()) {
square := newMemSizeWords * newMemSizeWords
newTotalFee := square / params.QuadCoeffDiv
fee := newTotalFee - mem.lastGasCost
mem.lastGasCost = newTotalFee
return fee, nil
}
return 0, nil
}
The main risk associated with this proposal is the potential for DoS attacks. By reducing gas costs, the proposal could inadvertently make certain operations more affordable, enabling attackers to exploit them for malicious purposes. To mitigate this risk, the proposal focuses on decreasing the gas costs of overpriced operations, ensuring that the adjustments do not compromise network security. By maintaining the relative cost of operations, the proposal makes sure that the reduced prices do not create new vulnerabilities even in the worst-case scenarios.
The reduced memory expansion cost still keeps the quadratic nature of the cost, which prevents attacks exploiting excessive memory usage. Any existing considerations are addressed by EIP‑7825.
The proposal does not address concerns raised in EIP-7667, but it does not worsen the edge cases outlined in that EIP.
Copyright and related rights waived via CC0.