Build OpenHL Precompiles — connecting CLOB state to smart contracts
Question
Build openhl's precompile layer in Rust. Precompiles bridge the CLOB matching engine to the EVM — Solidity contracts read live orderbook state and submit orders via precompile calls. Pinned to openhl SHAs 1761d4d (Stage 9a) → d19ba1b (Stage 9c+).
Principle (minimum model)
- 12 lessons across 6 modules. Orientation → Custom EVM bootstrap → Read precompile (3 lessons, reaching live state) → Write precompile (2 lessons, order submission) → Bridge integration (2 lessons, fills flow back) → Capstone.
- Precompiles = Rust functions at magic addresses. Solidity calls address
0x...0c1b; Reth dispatches to your Rust function instead of executing bytecode. - Three milestones. (1) read_best_bid hardcoded → wired through NodeBuilder. (2) read_best_bid reads live CLOB state. (3) place_order submits live + fills flow back via install_fill_sink.
- Pinned to SHAs
1761d4d(Stage 9a) →d19ba1b(Stage 9c+). Every example reproducible. Capstone answer-key atd19ba1b. - Prerequisites. the openhl CLOB course (matching engine state machine). No Solidity or Foundry is needed — every test is Rust.
- Architecture.
OpenHlEvmFactoryhooks into Reth's EVM creation and injects the precompiles;LiveRethEvmBridge::newcallsinstall_clob/install_fill_sinkso the precompiles see the bridge's own state. At these SHAs the custom EVM is exercised through Reth dev nodes in the test harness (bin/openhldoesn't wire it). - Production parallel. Hyperliquid HyperEVM uses this exact pattern (different code, same shape).
Worked example + steps
Build OpenHL Precompiles — connecting CLOB state to smart contracts
The openhl CLOB course ended with the bridge owning a CLOB matching engine. Orders submit, fills flow into payloads, the integration test exercises the whole pipeline against a real Reth node. But the fills are still a parallel list. Smart contracts running inside that same Reth node can't see them. The CLOB state and the EVM state live in two different worlds.
This course closes that gap. You'll add custom EVM precompiles — EVM-native Rust functions registered at fixed addresses, callable from Solidity exactly like external contracts but executing native Rust (no EVM bytecode in between). Ethereum already reserves 0x01–0x0a for standard precompiles like ECDSA recovery and SHA-256; we'll register our CLOB precompiles in a custom range starting at 0x0c1b (openhl reserves 0x...0c1b upwards, mnemonic "CLB"). After this course:
- A smart contract can call
0x...0c1b(in our custom range) to read the current best bid. - A smart contract can call
0x...0c1c(in the same range) to place an order that the matching engine processes.
Once these two paths exist, the CLOB stops being a parallel structure beside the EVM and starts being a state extension the EVM can interact with. That's what makes the chain "Hyperliquid-shape" — Hyperliquid's whole novelty is that the perp matching engine is callable from smart contracts running on the same chain.
By the end of this course, cargo test -p openhl-evm bridge_against_custom_evm_node_shares_clob_with_precompile passes — a place_order precompile call places an order, the order matches against existing book state, and the resulting fill flows back into the bridge.
1. What you'll have at the end
A new crates/evm/src/precompiles/ module containing:
- Two custom precompiles registered at well-known EVM addresses:
clob_read_best_bid(read): returns(price, qty)of the best bid as a 64-byte response.clob_place_order(write): decodes an order from calldata, submits it to the CLOB, returns the allocatedorder_idas a 32-byte response (0 = rejected).
- Custom EVM machinery (
openhl_evm.rs) — anEvmFactory+ExecutorBuilderthat wires the precompiles into Reth's executor. - Bridge integration —
LiveRethEvmBridgespawns its underlying Reth node with the custom EVM, so smart contract calls to the precompiles touch the same CLOB instance the bridge owns.
About 6 commits worth of work in openhl (~860 LOC), broken into 12 lessons (Lessons 0–11, with Lesson 11 as the capstone). The end-to-end test takes ~3 seconds: bootstrap Reth, call the precompile function directly (no Solidity deployment — openhl descopes the RPC eth_call roundtrip), assert the fill.
2. What you won't have at the end
This course covers openhl Stage 9 (9a-9e) only. It does NOT cover:
- Encoding Fill → real EVM transaction in the block body. The fills are still a parallel list attached to payloads (the situation at the end of the CLOB course). This course makes them accessible from EVM execution, but doesn't make them part of the block body. That's outside these courses.
- Funding state machine. That's Stage 8b / the openhl funding course.
- Liquidations, oracles, perp-specific math. Not in Stage 9.
- Multi-market precompiles. Stage 9 has one CLOB; production would have one precompile per market or one with market-id calldata.
When you finish this course you have a chain where smart contracts can read and write the CLOB. That's a massive capability jump — it's the difference between "the chain has an orderbook somewhere" and "the chain is an orderbook + EVM." But fully closing the loop (fills back into block body as txs) is downstream work.
3. Prerequisites
You need:
- The openhl CLOB course complete — or, equivalently, a workspace at the state where the CLOB course ends. Your
LiveRethEvmBridge<P>should haveclob,pending_fills,submit_order,payload_fills, andpending_fill_countfrom that course's bridge-integration lessons. If yours doesn't, work through the openhl CLOB course first. - Rust 1.95+, same as before.
- Familiarity with REVM at the trait level. You don't need to have written precompiles before — Lesson 1 explains the pattern — but if you've never seen REVM's
Precompile,PrecompileFn, orPrecompilestypes, skim the revm precompile docs first. - Comfort with
Arc<Mutex<T>>for shared state across thread boundaries. Precompiles need to read the CLOB from the EVM's execution context, which is a different async/sync boundary than the bridge's normal call sites.
You do not need:
- Any prior
EvmFactoryorExecutorBuilderknowledge (Lessons 1–2 explain them). - Any Solidity (we don't write Solidity — we just exercise the precompiles via raw calldata).
- Knowledge of Reth's internal block-execution pipeline beyond what the openhl consensus course covered.
4. Setup confirmation (do this now)
You should already have the two-directory workflow from the openhl consensus and CLOB courses:
~/code/my-openhl/— your workspace~/code/openhl-reference/— read-onlypsyto/openhlclone
Bring the reference repo up to date in case Stage 9 commits are newer than your clone:
cd ~/code/openhl-reference
git fetch origin
git log --oneline | head -25
# You should see commits up to and including SHA d19ba1b (Stage 9c+).
# `git log` defaults to reverse-chronological order (newest first); the
# Stage 9 commits appear in this order (9e landed right after 9a, and
# 9d before 9c+):
# d19ba1b — Stage 9c+
# 2f796c3 — Stage 9d
# a8823a1 — Stage 9c
# b635ef7 — Stage 9b
# 2ba97c6 — Stage 9e
# 1761d4d — Stage 9a
Then confirm your workspace is at the end-of-CLOB-course state:
cd ~/code/my-openhl
cargo test -p openhl-evm clob_fills_flow_into_payload --release 2>&1 | tail -5
# Expect: test passes (this is the CLOB course's milestone test).
If that passes, you're at the right starting point.
5. The 12-lesson map
| # | Module | What you build | End-of-lesson test |
|---|---|---|---|
| Lesson 0 | Orientation | (this lesson) | setup confirmed |
| Lesson 1 | Custom EVM bootstrap | openhl_evm.rs — EvmFactory pattern + dependencies | cargo check -p openhl-evm |
| Lesson 2 | Custom EVM bootstrap | precompiles/mod.rs — Stage 9a's hardcoded read precompile + registry | precompile compiles |
| Lesson 3 | Custom EVM bootstrap | OpenHlExecutorBuilder + NodeBuilder wiring; smoke test that calls the precompile (Stage 9e) | registered_precompile_is_invokable_via_registry passes |
| Lesson 4 | Read precompile | install_clob() — Arc-shared CLOB state, ready for precompile injection | bridge compiles with shared state |
| Lesson 5 | Read precompile | wire the read precompile to live CLOB state (Stage 9b proper) | precompile returns real best_bid |
| Lesson 6 | Read precompile | end-to-end test: read precompile reflects bridge.submit_order results | integration test passes |
| Lesson 7 | Write precompile | clob_place_order signature + calldata decoding (Stage 9c part 1) | precompile decodes correctly |
| Lesson 8 | Write precompile | implementation: submit to CLOB + return the allocated order id (Stage 9c part 2) | precompile writes correctly |
| Lesson 9 | Bridge integration | install_fill_sink() — fills produced by precompile flow back to bridge's pending_fills (Stage 9c+) | precompile-placed fills reach bridge |
| Lesson 10 | Bridge integration | bridge spawns against the custom-EVM Reth node (Stage 9d, with its 9c+ extension) | bridge_against_custom_evm_node_shares_clob_with_precompile passes |
| Lesson 11 | Capstone | recap, what's next (funding via the openhl funding course, fill-as-EVM-tx outside these courses) | (no test — recap) |
Lesson 10 is the milestone. Finishing Lesson 10, you have an EVM-callable CLOB on a live Reth node: smart contracts call precompiles, the matching engine runs, fills emerge through the bridge into payloads. Lesson 11 names what's still missing (the fills aren't yet EVM transactions — that's beyond Stage 9).
6. The answer-key discipline (same as before)
Each lesson from Lesson 1 to Lesson 10 cites one of the 6 Stage 9 commits:
| Lessons | Stage | SHA |
|---|---|---|
| Lessons 1–3 | 9a + 9e | 1761d4d, 2ba97c6 |
| Lessons 4–6 | 9b | b635ef7 |
| Lessons 7–8 | 9c | a8823a1 |
| Lesson 9 | 9c+ | d19ba1b |
| Lesson 10 | 9d (+ 9c+ extension) | 2f796c3; answer key d19ba1b |
After each lesson's test passes:
cd ~/code/openhl-reference
git checkout <SHA>
diff -u ~/code/my-openhl/crates/evm/src/precompiles/mod.rs ./crates/evm/src/precompiles/mod.rs
Match meaningfully — same types, same control flow. Whitespace and naming will differ.
7. Setup confirmation — the actual Lesson 0 exercise
Before Lesson 1, run all of these and confirm they pass:
# 1. Rust version
rustc --version # expect: rustc 1.95.x or later
# 2. End-of-CLOB-course state
cd ~/code/my-openhl && cargo test -p openhl-evm clob_fills_flow_into_payload --release 2>&1 | tail -3
# Expect: 1 test passing
# 3. Reference repo has Stage 9 commits
cd ~/code/openhl-reference && git log --oneline | grep -E "(1761d4d|b635ef7|a8823a1)"
# Expect: all three SHAs appear
If all three pass, you're ready for Lesson 1.
Final check. In one sentence, what does this course add that the CLOB course didn't? If your answer doesn't mention "smart contracts can read and write the CLOB," re-read §1.
Summary (3 lines)
- Build openhl precompiles = read/write bridge between CLOB matching engine and EVM. 12 lessons / 6 modules.
- Three milestones: hardcoded read → live read → live write + fill sink. Pinned to SHAs
1761d4d(Stage 9a) →d19ba1b(Stage 9c+). - Prerequisites: openhl CLOB + Foundry. Production parallel: Hyperliquid HyperEVM.