Skip to content

feat(evm): add L1SLOAD and L1STATICCALL precompiles#195

Open
jmadibekov wants to merge 7 commits into
taikoxyz:mainfrom
jmadibekov:jmadibekov/l1-precompiles
Open

feat(evm): add L1SLOAD and L1STATICCALL precompiles#195
jmadibekov wants to merge 7 commits into
taikoxyz:mainfrom
jmadibekov:jmadibekov/l1-precompiles

Conversation

@jmadibekov

@jmadibekov jmadibekov commented Jun 1, 2026

Copy link
Copy Markdown

Adds L1SLOAD at 0x10001 and L1STATICCALL at 0x10002 precompiles gated at TaikoSpecId::UNZEN. On chains where Unzen is Never, the addresses stay unregistered and calls fall through to the standard "no code at address" path.

Companion prover PR: taikoxyz/raiko2#72. The prover imports alethia-reth-evm as a library so guest and live execution share one precompile binary.

Both precompiles share the live shape: input validation → window check → cache lookup → on miss invoke the fetcher → cache the result → return. The pieces that differ between the two:

L1SLOAD (0x10001) L1STATICCALL (0x10002)
Input 84B fixed: addr + slot + block 52B+ variable: target + block + calldata
Cache key (addr, slot, block) (target, block, keccak(calldata))
Live RPC eth_getStorageAt debug_traceCall (storage/stack/memory disabled)
Cache value B256 (gas, output, reverted)
Gas 2000 + 2000 (fixed) 2000 + 10000 + 16/byte + l1_gas (dynamic)
Output 32B value variable bytes (≤24 KiB)
Reverts n/a (always succeeds) sanitized to (gas=0, empty) before cache
L1SLOAD live path
sequenceDiagram
  participant T as L2 tx
  participant EVM as alethia-reth EVM
  participant F as Live fetcher<br/>(crates/l1-client)
  participant L1 as L1 EL

  T->>EVM: CALL 0x10001<br/>input = 84B (addr + slot + block)
  EVM->>EVM: window check [origin−256, origin]
  EVM->>EVM: cache lookup<br/>key = (addr, slot, block) → miss
  EVM->>F: invoke installed closure
  F->>L1: eth_getStorageAt(addr, slot, block)
  L1-->>F: U256 value
  F-->>EVM: cache + return B256
  EVM-->>T: gas = 2000 + 2000, output = 32B value
Loading
L1STATICCALL live path
sequenceDiagram
  participant T as L2 tx
  participant EVM as alethia-reth EVM
  participant F as Live fetcher<br/>(crates/l1-client)
  participant L1 as L1 EL

  T->>EVM: CALL 0x10002<br/>input = 52B+ (target + block + calldata)
  EVM->>EVM: window check [origin−256, origin]
  EVM->>EVM: calldata size check ≤ 64 KiB
  EVM->>EVM: cache lookup<br/>key = (target, block, keccak(calldata)) → miss
  EVM->>F: invoke installed closure
  F->>L1: debug_traceCall<br/>(disable storage/stack/memory)
  L1-->>F: gas, returnValue, failed
  F->>F: sanitize reverts → (gas=0, empty data)
  F-->>EVM: cache + return (gas, output, reverted)
  EVM-->>T: gas = 2000 + 10000 + 16/byte + l1_gas<br/>output = variable bytes (≤24 KiB)
Loading

Note: Operational caveats, the devnet runbook, and the cross-cutting behavior notes (EL + prover) are consolidated in the companion prover PR taikoxyz/raiko2#72 to keep them in one place.

@jmadibekov
jmadibekov force-pushed the jmadibekov/l1-precompiles branch from 005937a to 14f88ae Compare June 1, 2026 09:10
@jmadibekov
jmadibekov force-pushed the jmadibekov/l1-precompiles branch 2 times, most recently from 4b9fab3 to 83659a1 Compare June 1, 2026 14:48
@jmadibekov jmadibekov changed the title Add L1 precompiles and proof_call RPC Add L1Sload and L1Staticcall precompiles Jun 1, 2026
@jmadibekov jmadibekov changed the title Add L1Sload and L1Staticcall precompiles Add L1SLOAD and L1STATICCALL precompiles Jun 2, 2026
@jmadibekov
jmadibekov marked this pull request as ready for review June 2, 2026 08:45
@jmadibekov
jmadibekov force-pushed the jmadibekov/l1-precompiles branch from a066500 to d80f878 Compare June 4, 2026 10:33
@jmadibekov jmadibekov changed the title Add L1SLOAD and L1STATICCALL precompiles feat(evm): add L1SLOAD and L1STATICCALL precompiles Jun 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants