Oracle

MegaETH Oracle system contract — address, storage layout, hint forwarding, and gas detention trigger.

This page specifies the Oracle system contract. It defines the address, interface, restricted write behavior, storage access semantics, and hint forwarding.

Motivation

MegaETH needs a canonical protocol-level storage backend for externally sourced data such as timestamps and other oracle-fed values. That storage must be readable by contracts, writable by protocol-controlled maintenance transactions, and stable across specs.

Specification

Address

The Oracle system contract MUST exist at ORACLE_CONTRACT_ADDRESS.

Bytecode

A node MUST deploy the bytecode version corresponding to the active spec. Versions 1.0.0 and 1.1.0 take MEGA_SYSTEM_ADDRESS as a constructor immutable. Version 2.0.0 reads the authorized address from SequencerRegistry.currentSystemAddress() via a constant reference.

Version 1.0.0

Since: MiniRex

Code hash: 0xe9b044afb735a0f569faeb248088b4f267578f60722f87d06ec3867b250a2c34

Deployed bytecode:

0x608060405234801561000f575f5ffd5b506004361061006f575f3560e01c80637eba7ba61161004d5780637eba7ba614610118578063a21e2d6914610138578063fbc0d03514610158575f5ffd5b806301caec13146100735780630dc9b5da1461008857806354fd4d50146100d9575b5f5ffd5b610086610081366004610324565b61016b565b005b6100af7f000000000000000000000000a887dcb9d5f39ef79272801d05abdf707cfbbd1d81565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b604080518082018252600581527f312e302e30000000000000000000000000000000000000000000000000000000602082015290516100d09190610390565b61012a6101263660046103e3565b5490565b6040519081526020016100d0565b61014b6101463660046103fa565b6101e6565b6040516100d09190610439565b61008661016636600461047b565b61025c565b8281146101b2576040517f5b7232fa000000000000000000000000000000000000000000000000000000008152600481018490526024810182905260440160405180910390fd5b8382845f5b818110156101d457602081028381013590850135556001016101b7565b505050506101e061026b565b50505050565b60608167ffffffffffffffff8111156102015761020161049b565b60405190808252806020026020018201604052801561022a578160200160208202803683370190505b5090506020810183835f5b818110156102525760208102838101355490850152600101610235565b5050505092915050565b80825561026761026b565b5050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a887dcb9d5f39ef79272801d05abdf707cfbbd1d16146102da576040517f5e742c5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f5f83601f8401126102ec575f5ffd5b50813567ffffffffffffffff811115610303575f5ffd5b6020830191508360208260051b850101111561031d575f5ffd5b9250929050565b5f5f5f5f60408587031215610337575f5ffd5b843567ffffffffffffffff81111561034d575f5ffd5b610359878288016102dc565b909550935050602085013567ffffffffffffffff811115610378575f5ffd5b610384878288016102dc565b95989497509550505050565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b5f602082840312156103f3575f5ffd5b5035919050565b5f5f6020838503121561040b575f5ffd5b823567ffffffffffffffff811115610421575f5ffd5b61042d858286016102dc565b90969095509350505050565b602080825282518282018190525f918401906040840190835b81811015610470578351835260209384019390920191600101610452565b509095945050505050565b5f5f6040838503121561048c575f5ffd5b50508035926020909101359150565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffdfea26469706673582212205bb66f27c8ccdec3b5bbd6071d5f516754488531634a3ad38e6c7ffacf47a02464736f6c634300081e0033

Version 1.1.0

Since: Rex2

Code hash: 0x06df675a69e53ea2a3c948521e330b3801740fede324a1cef2044418f8e09242

Deployed bytecode:

Version 2.0.0

Unstable — Rex5 semantics described here are under active development and may change before network activation.

Since: Rex5

The onlySystemAddress modifier reads the authorized address from SequencerRegistry.currentSystemAddress() instead of a constructor immutable. This enables system address change without redeploying the Oracle contract. All other functionality is preserved from v1.1.0.

Code hash: 0xcdc4cffc96a152777dd4952a5446bc5402fcfeec16a6b4b458ddee2e0b7af525

Public Read Interface

The Oracle contract MUST expose the following externally callable read methods:

getSlot MUST return the storage value at the specified slot. getSlots MUST return the storage values at the specified slots in the same order as the input array.

Restricted Write Interface

The Oracle contract MUST expose the following write and log-emission methods:

The methods above MUST be callable only by MEGA_SYSTEM_ADDRESS. Calls from any other sender MUST revert with NotSystemAddress().

For setSlots, if the slots and values array lengths differ, the call MUST revert with InvalidLength(uint256 slotsLength, uint256 valuesLength).

Auxiliary Interface

The Oracle contract MUST expose the following auxiliary methods:

multiCall MUST execute each payload by DELEGATECALL into the Oracle contract and MUST return the results in order. If any delegated call fails, multiCall MUST revert and MUST bubble up the revert data if present.

sendHint MUST be externally callable and MUST be a no-op at the Solidity bytecode level.

Storage Access Semantics

Reads. getSlot and getSlots read Oracle storage via SLOAD. The node MAY serve Oracle reads from an external data source that provides realtime, per-transaction values. When an SLOAD targets ORACLE_CONTRACT_ADDRESS, the node MUST first consult the external data source. If it provides a value for the requested slot, that value MUST be returned. Otherwise, the node MUST return the on-chain storage value.

Writes. setSlot and setSlots write Oracle storage via SSTORE. These methods are restricted to MEGA_SYSTEM_ADDRESS (see Restricted Write Interface).

On-chain persistence. When the external data source provides a value for a read, the sequencer MUST persist that value on-chain by inserting a Mega System Transaction that calls setSlot or setSlots. This system transaction MUST be ordered before the user transaction that triggered the read, so that full nodes replaying the block observe the same storage state.

Hint Forwarding

sendHint is the only function in Oracle system contract that participates in call interception. All other Oracle functions (getSlot, getSlots, setSlot, setSlots, emitLog, emitLogs, multiCall) execute via ordinary contract bytecode only.

When a CALL or STATICCALL targets ORACLE_CONTRACT_ADDRESS and the input matches the sendHint(bytes32,bytes) selector, the node MUST forward the decoded topic and data to the external oracle backend as a side effect. The call MUST then fall through — the Oracle contract's deployed sendHint function body executes as ordinary bytecode.

Because the Solidity implementation of sendHint is a no-op view function, the net observable behavior is the combination of:

  • hint forwarding to the oracle backend (side effect), and

  • normal bytecode execution of the no-op function body (which returns successfully with no output).

Calls to ORACLE_CONTRACT_ADDRESS that do not match the sendHint selector MUST fall through without any side effect.

If a transaction calls sendHint and subsequently reads an Oracle slot, the hint MUST be delivered to the oracle backend before the read is served.

Gas and Detention Semantics

The following gas and detention rules MUST apply:

  • SLOAD against Oracle storage MUST use the cold access gas cost.

  • Oracle storage reads MUST participate in gas detention.

  • CALL or STATICCALL to the Oracle contract address alone MUST NOT trigger oracle detention unless Oracle storage is actually read.

  • DELEGATECALL to the Oracle contract MUST NOT trigger oracle detention solely by targeting the Oracle address.

Versioning

Pre-Rex2, the deployed Oracle bytecode does not include sendHint. From Rex2 onward, the stable Oracle bytecode includes sendHint.

Upgrade storage semantics. When the Oracle account's bytecode is upgraded, the fate of existing Oracle storage is consensus-critical.

Pre-Rex5, each bytecode upgrade MUST mark the Oracle account as newly created. This clears any storage accumulated under the previous bytecode version. Canonical mainnet state reflects this: Oracle storage present at the Rex2 activation boundary was cleared by the Rex2 upgrade.

From Rex5 onward, a bytecode upgrade MUST NOT mark the Oracle account as newly created. Existing Oracle storage MUST be preserved across the upgrade.

Constants

Constant
Value
Description

ORACLE_CONTRACT_ADDRESS

0x6342000000000000000000000000000000000001

Stable Oracle system-contract address

Rationale

Why centralize oracle-backed data in one contract? Oracle-backed protocol data needs a single canonical storage location so all contracts and all nodes observe the same values under the same addressing scheme.

Why restrict writes to MEGA_SYSTEM_ADDRESS? Externally sourced oracle values are part of protocol-maintained state. Allowing arbitrary writes would destroy the meaning of oracle-backed data and make the values untrustworthy as protocol inputs.

Why use a per-transaction external data source instead of pre-populating all oracle data? Traditional oracle designs require all data to be written on-chain before any transaction can read it, even if most transactions never access oracle data. The external data source enables a realtime lazy oracle: values are only fetched and persisted when a transaction actually reads them. This avoids unnecessary system transactions for data that no one consumes, reduces block overhead, and allows oracle data to be as fresh as the moment of access rather than the moment of block construction. The sequencer's frontrunning system transaction ensures that the lazily served value is still persisted on-chain for full nodes and verifiers that replay the block.

Why intercept sendHint during call interception? Hint forwarding depends on external backend behavior that cannot be expressed by on-chain bytecode alone. The no-op Solidity body provides a stable interface, while the call interception mechanism supplies the protocol-level side effect.

Spec History

  • MiniRex introduced the Oracle contract.

  • Rex2 added the sendHint entry point to the deployed Oracle bytecode.

  • Rex3 changed oracle detention to SLOAD-based triggering and raised the oracle detention cap to 20M.

  • Rex5 replaced the constructor immutable authority with a dynamic read from SequencerRegistry.currentSystemAddress() (Oracle v2.0.0).

Last updated