The Curve Block Oracle is a decentralized system for securely providing Ethereum mainnet block hashes and state roots to other blockchain networks. This enables permissionless storage proofs and cross-chain verification of Ethereum state, which is essential for a variety of use cases, including cross-chain governance, bridge security, and DeFi protocols.
The system is designed to be highly reliable and secure, leveraging a multi-committer consensus mechanism and LayerZero's cross-chain messaging protocol. It is currently deployed on over 20 EVM-compatible chains.
- Permissionless Access: Anyone can use the oracle to verify Ethereum state on supported chains.
- Multi-Chain Support: Deployed across a wide range of EVM-compatible chains.
- Decentralized Security: Utilizes a multi-committer consensus mechanism with threshold validation to ensure the integrity of block data.
- LayerZero Integration: Leverages LayerZero for secure and efficient cross-chain messaging.
- Storage Proof Ready: Provides the necessary block hashes and state roots for Ethereum storage proofs.
- Resilient Design: The system is designed to be resilient to reorgs and other network disruptions.
The Curve Block Oracle consists of four main smart contracts:
-
MainnetBlockView(Ethereum only):- Address:
0xb10cface00696B1390875DB2a0113B3ab99752a4 - Provides access to historical block hashes on the Ethereum mainnet.
- To prevent reorg-related issues, it only returns hashes for blocks that are at least 65 blocks old.
- This contract is called off-chain via LayerZero's
lzReadfunctionality.
- Address:
-
BlockOracle(All supported chains):- Address:
0xb10cface698eBbEeda6Fd1aC3e1687a8a3f5c5Df - Stores confirmed block hashes and decoded block headers.
- Uses a threshold-based consensus mechanism to validate block data. Currently, the threshold is set to 1, with
LZBlockRelayas the sole committer. - Once a block hash is confirmed, it is immutable.
- Address:
-
LZBlockRelay(All supported chains):- Address:
0xfacefeed69e0eb9dB6Ad8Cb0883fC45Df7561Dc2 - Handles cross-chain messaging via LayerZero.
- Commits block hashes to the
BlockOracle. - Supports read-enabled chains for direct queries to Ethereum.
- Address:
-
HeaderVerifier(All supported chains):- Address:
0xb10CdEc0dE69a227307053bEbBFd80864B71ec27 - Decodes RLP-encoded Ethereum block headers.
- Extracts key information, such as the state root, parent hash, and other fields.
- Address:
The process of retrieving and verifying a block hash is as follows:
- Request: A user initiates a request for a block hash by calling the
request_block_hash()function on a read-enabled chain'sLZBlockRelaycontract. - Read: LayerZero reads the requested block hash from the
MainnetBlockViewcontract on the Ethereum mainnet. - Commit: The
LZBlockRelaycontract receives the response from LayerZero and commits the block hash to theBlockOracle. - Broadcast: The
LZBlockRelaycan optionally broadcast the block hash to other specified chains. - Verify: Once the block hash is confirmed, anyone can submit the RLP-encoded block header to the
HeaderVerifierto extract the state root and other data.
To use the block hashes for storage proofs, you can interact with the BlockOracle contract as follows:
// Get the confirmed block hash for a given block number
bytes32 blockHash = IBlockOracle(ORACLE_ADDRESS).get_block_hash(blockNumber);
// Get the state root for storage proofs
bytes32 stateRoot = IBlockOracle(ORACLE_ADDRESS).get_state_root(blockNumber);On read-enabled chains (such as Optimism, Arbitrum, and Base), you can request a block hash using the following steps:
# 1. Quote the required fees
read_fee = relay.quote_read_fee(read_gas_limit=200000, value=0)
broadcast_fees = relay.quote_broadcast_fees(target_chains, gas_limit=100000)
# 2. Request the block hash
relay.request_block_hash(
target_chains,
broadcast_fees,
lz_receive_gas_limit=100000,
read_gas_limit=200000,
block_number=0, # 0 indicates the latest safe block
value=read_fee + sum(broadcast_fees)
)Anyone can submit a block header for a confirmed block hash:
# Get the RLP-encoded header from an Ethereum node
encoded_header = eth.get_block(block_number).rawHeader
# Submit the header to the HeaderVerifier
verifier.submit_block_header(oracle_address, encoded_header)MainnetBlockView:0xb10cface00696B1390875DB2a0113B3ab99752a4
BlockOracle:0xb10cface698eBbEeda6Fd1aC3e1687a8a3f5c5DfLZBlockRelay:0xfacefeed69e0eb9dB6Ad8Cb0883fC45Df7561Dc2HeaderVerifier:0xb10CdEc0dE69a227307053bEbBFd80864B71ec27
The Curve Block Oracle is deployed on the following chains:
- Ethereum
- Optimism
- XDC
- BSC
- Gnosis
- Polygon
- Sonic
- XLayer
- TAC
- Fantom
- Fraxtal
- Hyperliquid
- Moonbeam
- Kava
- Mantle
- Base
- Arbitrum
- Celo
- Avalanche
- Ink
- Plume
- Taiko
- Corn
- Aurora
- Curve DAO: The Curve DAO controls the ownership of the oracle and the management of committers.
- LayerZero: LayerZero is trusted for message delivery and the
lzReadfunctionality. - Threshold Security: The system requires a threshold of committers to agree on a block hash before it is confirmed.
- Chain Security: The overall security of the system is dependent on the security of the least secure supported chain.
- Threshold: 1 committer (with
LZBlockRelayas the sole committer). - Read-Enabled Chains: Can query Ethereum directly.
- Non-Read-Enabled Chains: Rely on broadcasts from read-enabled chains.
- Minimum Age: 65 blocks (for reorg protection).
- Maximum Age: 8192 blocks (due to the EVM limit post-EIP-2935).
- Default:
block.number - 65for safety.
- Read Operations: Approximately 200,000 gas is recommended.
- Broadcast Receive: Approximately 100,000 gas per chain.
- Header Size: Headers must be under 1024 bytes.
The system extracts the following fields from the RLP-encoded block header:
block_hash: The Keccak256 hash of the header.parent_hash: A reference to the previous block.state_root: The Merkle root for storage proofs.receipt_root: The root of the transaction receipt trie.block_number: The block height.timestamp: The block timestamp.
- Cross-Chain Governance: Verify mainnet votes on L2s.
- Bridge Security: Validate token locks on Ethereum.
- State Synchronization: Prove account balances across different chains.
- DeFi Protocols: Access mainnet price feeds on L2s.
- Cross-Chain dApps: Build applications that utilize mainnet state.
- Python 3.12+
- uv
-
Clone the repository:
git clone https://github.com/curvefi/blockhash-oracle.git cd blockhash-oracle -
Install dependencies:
uv sync
To run the test suite:
pytestThe scripts/deployment directory contains scripts for deploying and configuring the contracts. The DeploymentManager.py class helps manage the deployment state across multiple sessions.
- Example Scripts:
/scripts/deployment/ - Contract Source Code:
/contracts/ - Security Audit:
/report/
Copyright (c) Curve.Fi, 2025 - All Rights Reserved.