EIP-7907: Meter Contract Code Size And Increase Limit
Qi Zhou
May 28, 2025
Outline
Motivation
Motivation
Splitting a Large Contract to Smaller Ones
contract LargeContract {
function func1() {
…
}
…
function func2() {
…
}
}
contract SubContract0 {
function func2() {
….
}
}
contract SubContract1 {
function func1() {
…
}
function func2() {
call ABC0.func2()
}
}
EIP-7907 Solution
Avoid DoS Attack: Charge Gas Before Consuming Resources
// call a contract in EIP-170
evm.use_gas(2600) // if not enough gas, then the tx will be revert
account = evm.read_account(contract_addr)
code = evm.read_contract(account.codehash) // expensive operation, EIP-170 guarantees code.size <= 24KB
evm.call_contract(...)
Avoid DoS Attack: Incorrect EIP-7907 Implementation
// call a contract in EIP-170
evm.use_gas(2600)
account = evm.read_account(contract_addr)
code = evm.read_contract(account.codehash) // code.size <= 24KB
evm.call_contract(...)
// call a contract (EIP-7907 wrong impl)
evm.use_gas(2600)
account = evm.read_account(contract_addr)
code = evm.read_contract(account.codehash) // DoS attack if code.size >> 24KB
excess_gas = max(0, code.size-24KB) * 2 // 32
evm.use_gas(excess_gas)
evm.call_contract(...)
Avoid DoS Attack: Indexing Approach
// call a contract (EIP-7907 wrong impl)
evm.use_gas(2600)
account = evm.read_account(contract_addr)
code = evm.read_contract(account.codehash) // DoS attack if code.size >> 24KB
excess_gas = max(0, code.size-24KB) * 2 // 32
evm.use_gas(excess_gas)
evm.call_contract(...)
// call a contract (EIP-7907 right impl)
evm.use_gas(2600)
account = evm.read_account(contract_addr)
codesize = evm.read_codesize(account.codehash) // additional index of codehash=>size
excess_gas = max(0, codesize-24KB) * 2 // 32
evm.use_gas(excess_gas)
code = evm.read_contract(contract_addr) // can be >> 24KB
evm.call_contract(contract_addr, code)
Advanced Topics
Cold/Warm State
// call the contract first time
evm.use_gas(2600)
account = evm.read_account(contract_addr)
code = evm.read_contract(account.codehash)
evm.call_contract(...)
…
// call the contract second time
evm.use_gas(100)
// read from memory/cache
account = evm.read_account(contract_addr)
code = evm.read_contract(account.codehash)
evm.call_contract(...)
Cold/Warm State
// call the contract first time
evm.use_gas(2600)
account = evm.read_account(contract_addr)
code = evm.read_contract(account.codehash)
evm.call_contract(...)
…
// call the contract second time
evm.use_gas(100)
// read from memory/cache
account = evm.read_account(contract_addr)
code = evm.read_contract(account.codehash)
evm.call_contract(...)
Added Cold/Warm State for Code in EIP-7907
Read Code Size Efficiently
Read Code Size Efficiently
JUMPDEST Analysis
Large Contract Impact to Cache
References:
Acknowledgement