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:
0xb10CfacE69cc0B7F1AE0Dc8E6aD186914f6e7EEA - 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:
0xb10cface69821Ff7b245Cf5f28f3e714fDbd86b8 - 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:
0xFacEFeeD696BFC0ebe7EaD3FFBb9a56290d31752 - 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:
0xB10CDEC0DE69c88a47c280a97A5AEcA8b0b83385 - 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:0xb10CfacE69cc0B7F1AE0Dc8E6aD186914f6e7EEA
BlockOracle:0xb10cface69821Ff7b245Cf5f28f3e714fDbd86b8LZBlockRelay:0xFacEFeeD696BFC0ebe7EaD3FFBb9a56290d31752HeaderVerifier:0xB10CDEC0DE69c88a47c280a97A5AEcA8b0b83385
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.