From 9b630a4e29e4a44e748e2127f2155628fcb4c301 Mon Sep 17 00:00:00 2001 From: TroublorBot Date: Wed, 6 May 2026 02:48:53 +0000 Subject: [PATCH 1/3] docs: address audit findings from issue #281 Apply documentation audit fixes covering correctness, freshness, and readability: - Oracle v2.0.0 code hash corrected to match source artifacts (C-001). - Rex5 unstable content moved into
blocks across keyless-deploy, oracle, system-tx, evm/overview, evm/resource-accounting (R-001..R-004, C-005); affected pages reverted to spec: Rex4 in frontmatter. - Rex5 behavioral summary added to hardfork-spec.md, upgrades/overview.md, and spec/overview.md spec progression (C-002, C-003, R-007, R-008). - Glossary updated: spec progression includes REX5, Detained limit reordered with Rex4+ relative-cap definition leading, MEGA_SYSTEM_ADDRESS Rex5 bullet marked _(Rex5, unstable)_ (R-009, R-010, R-015). - SequencerRegistry doc gains v1.0.0 code hash and ActivationBlockTooLarge() error in interface and Change Scheduling rule (F-002). - KeylessDeploy doc gains Rex5 trailing-bytes rejection rule in
block plus Spec History entry (F-001, R-001). - rex5.md adds the trailing-bytes change to What Changed; References now point to spec pages instead of crate file paths (F-001, R-014). - hardfork-spec.md drops MegaHardfork/MegaSpecId reference-impl mentions and rewrites Backward Compatibility bullets in plain English (R-005, R-006). - block-environment.md uses relative link to gas-detention spec (R-012). - mega-access-control.md and mega-limit-control.md drop the Source: line pointing at Solidity files (R-013). - AGENTS.md test-organization list now includes rex5/ (C-004). Generated-by: engineer-agent --- AGENTS.md | 2 +- .../configuration/block-environment.md | 2 +- docs/spec/evm/overview.md | 9 ++++++++ docs/spec/evm/resource-accounting.md | 16 ++++++++++--- docs/spec/glossary.md | 13 ++++++----- docs/spec/hardfork-spec.md | 19 ++++++++------- docs/spec/overview.md | 3 ++- docs/spec/system-contracts/keyless-deploy.md | 10 +++++++- .../system-contracts/mega-access-control.md | 2 -- .../system-contracts/mega-limit-control.md | 2 -- docs/spec/system-contracts/oracle.md | 23 ++++++++++++------- .../system-contracts/sequencer-registry.md | 13 ++++++++++- docs/spec/system-contracts/system-tx.md | 14 +++++++---- docs/spec/upgrades/overview.md | 4 ++-- docs/spec/upgrades/rex5.md | 21 +++++++++++++---- 15 files changed, 107 insertions(+), 46 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index e31bd87c..fc398404 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -211,7 +211,7 @@ When adding a new per-frame gas mechanism, verify that all three paths handle it ## Test Organization (`crates/mega-evm/tests/`) -Tests are organized by spec: `equivalence/`, `mini_rex/` (12 modules), `rex/`, `rex2/`, `rex3/`, `rex4/`, and `block_executor/`. +Tests are organized by spec: `equivalence/`, `mini_rex/` (12 modules), `rex/`, `rex2/`, `rex3/`, `rex4/`, `rex5/`, and `block_executor/`. Each module tests specific features of that spec. ## Version Control diff --git a/docs/mega-evme/configuration/block-environment.md b/docs/mega-evme/configuration/block-environment.md index 73ded564..3ab887a7 100644 --- a/docs/mega-evme/configuration/block-environment.md +++ b/docs/mega-evme/configuration/block-environment.md @@ -42,5 +42,5 @@ mega-evme run 0x41 --block.coinbase 0x1111111111111111111111111111111111111111 The block environment affects opcodes like `NUMBER`, `TIMESTAMP`, `COINBASE`, `BASEFEE`, `DIFFICULTY` / `PREVRANDAO`, and `BLOBBASEFEE`. -In MegaETH specs (MiniRex and above), accessing block environment fields triggers [gas detention](https://megaeth-labs.github.io/mega-evm/spec/evm/gas-detention.html) — the remaining compute gas is capped to reduce parallel execution conflicts. +In MegaETH specs (MiniRex and above), accessing block environment fields triggers [gas detention](../../spec/evm/gas-detention.md) — the remaining compute gas is capped to reduce parallel execution conflicts. This is normal MegaETH behavior and is reflected in `mega-evme` execution. diff --git a/docs/spec/evm/overview.md b/docs/spec/evm/overview.md index e28bef08..a1adfbac 100644 --- a/docs/spec/evm/overview.md +++ b/docs/spec/evm/overview.md @@ -101,4 +101,13 @@ MegaETH predeploys the following stable system contracts: | [MegaAccessControl](../system-contracts/mega-access-control.md) | `0x6342000000000000000000000000000000000004` | [Rex4](../upgrades/rex4.md) | Volatile-data access control | | [MegaLimitControl](../system-contracts/mega-limit-control.md) | `0x6342000000000000000000000000000000000005` | [Rex4](../upgrades/rex4.md) | Query remaining compute-gas budget | +
+Rex5 (unstable): SequencerRegistry + +| Contract | Address | Since | Purpose | +| -------------------------------------------------------------- | -------------------------------------------- | --------------------------- | -------------------------------------------------------- | +| [SequencerRegistry](../system-contracts/sequencer-registry.md) | `0x6342000000000000000000000000000000000006` | [Rex5](../upgrades/rex5.md) | Dual-role registry for system address and sequencer keys | + +
+ For the full registry and behavioral semantics, see [System Contracts Overview](../system-contracts/overview.md). diff --git a/docs/spec/evm/resource-accounting.md b/docs/spec/evm/resource-accounting.md index 54eeeae2..c7a62d09 100644 --- a/docs/spec/evm/resource-accounting.md +++ b/docs/spec/evm/resource-accounting.md @@ -1,6 +1,6 @@ --- description: MegaETH resource accounting specification — counter semantics, revert behavior, and per-opcode metering for compute gas, data size, KV updates, and state growth. -spec: Rex5 +spec: Rex4 --- # Resource Accounting @@ -110,10 +110,15 @@ The following contributions MUST be tracked within call frames and MUST be disca | Account update (CREATE/CREATE2) | `ACCOUNT_UPDATE_DATA_SIZE` | Successful account creation path | | Deployed bytecode | `code.len()` | Successful `CREATE` or `CREATE2` | +
+Rex5 (unstable): Caller account update deduplication for data-size tracking + #### Account Update Deduplication Within a single call frame, a node MUST count a given account update at most once for data-size tracking. -If the same account is updated multiple times within the same call frame, subsequent updates in that call frame MUST NOT add additional `ACCOUNT_UPDATE_DATA_SIZE` bytes. +If the same account is updated multiple times within the same call frame — including the caller account across multiple value-transferring sub-calls or creates — subsequent updates in that call frame MUST NOT add additional `ACCOUNT_UPDATE_DATA_SIZE` bytes. + +
### KV Updates @@ -141,11 +146,16 @@ The following contributions MUST be tracked within call frames and MUST be disca | CREATE/CREATE2 | `1` or `2` | Created account plus caller update if caller not yet counted in the current call frame | | CALL with value | `1` or `2` | Callee update plus caller update if caller not yet counted in the current call frame | +
+Rex5 (unstable): Caller account update deduplication for KV-update tracking + #### Account Update Deduplication Within a single call frame, a node MUST deduplicate caller account updates for KV-update tracking in the same way it does for data-size tracking. When a CALL with value or CREATE occurs, the caller's update MUST be counted only if it has not already been counted in the current call frame. +
+ ### State Growth #### Definition @@ -217,4 +227,4 @@ Allowing the counter to go negative during intermediate steps keeps the accounti This page describes the current accounting behavior. - [Rex4](../upgrades/rex4.md) — introduced per-call-frame runtime budgets for all four resource dimensions. -- [Rex5](../upgrades/rex5.md) — corrected caller-account update deduplication: pre-Rex5, the caller's `ACCOUNT_UPDATE_DATA_SIZE` (data size) and KV-update count were re-charged on every value-transferring sub-call or create from the same parent frame because the `target_updated` flag was never set after the first charge; Rex5 marks the flag after the first charge so subsequent operations from the same parent frame do not re-count the caller account. +- [Rex5](../upgrades/rex5.md) (**unstable**) — corrected caller-account update deduplication: pre-Rex5, the caller's `ACCOUNT_UPDATE_DATA_SIZE` (data size) and KV-update count were re-charged on every value-transferring sub-call or create from the same parent frame because the `target_updated` flag was never set after the first charge; Rex5 marks the flag after the first charge so subsequent operations from the same parent frame do not re-count the caller account. diff --git a/docs/spec/glossary.md b/docs/spec/glossary.md index a8523fc6..50a0620a 100644 --- a/docs/spec/glossary.md +++ b/docs/spec/glossary.md @@ -116,10 +116,10 @@ These are frequently accessed by many transactions and are a major source of par The effective compute gas cap imposed by [gas detention](evm/gas-detention.md). -An absolute cap on total compute gas for the transaction; if the transaction has already consumed more gas than the cap when the volatile access occurs, execution halts immediately. +A relative cap of `current_usage + cap` set at the time of volatile access; if the transaction's compute gas usage later exceeds this cap, execution halts immediately. -In Rex4 and later, this is a relative cap — `current_usage + cap` at the time of volatile access. -See the [Rex4 upgrade page](upgrades/rex4.md) for details. +In Rex3 and earlier, this was an absolute cap on total compute gas for the transaction: if the transaction had already consumed more gas than the cap when the volatile access occurred, execution halted immediately at that point. +The relative-cap definition above was introduced in [Rex4](upgrades/rex4.md). ## Beneficiary @@ -161,7 +161,8 @@ A set of MegaETH verifiable behaviors: the complete definition of what a correct Captures the execution-layer semantics that determine node correctness. -Progression: `EQUIVALENCE → MINI_REX → REX → REX1 → REX2 → REX3 → REX4`. +Progression: `EQUIVALENCE → MINI_REX → REX → REX1 → REX2 → REX3 → REX4 → REX5`. +REX5 is the current unstable spec under active development. See [Hardforks and Specs](hardfork-spec.md). @@ -177,7 +178,7 @@ Multiple hardforks can map to the same spec (e.g., MiniRex1 → EQUIVALENCE, Min The authorized sender for [Mega System Transactions](system-contracts/system-tx.md). -- Pre-[Rex5](upgrades/rex5.md): the fixed constant `0xA887dCB9D5f39Ef79272801d05Abdf707CFBbD1d` (defined in [system-tx.md § Constants](system-contracts/system-tx.md#constants)). -- Rex5 onward: resolved per block from [`SequencerRegistry.currentSystemAddress()`](system-contracts/sequencer-registry.md). +- The fixed constant `0xA887dCB9D5f39Ef79272801d05Abdf707CFBbD1d` (defined in [system-tx.md § Constants](system-contracts/system-tx.md#constants)). +- _(Rex5, unstable)_ Resolved per block from [`SequencerRegistry.currentSystemAddress()`](system-contracts/sequencer-registry.md) instead of the fixed constant. Exempt from oracle [gas detention](evm/gas-detention.md); carries [Oracle](system-contracts/oracle.md) write authority. diff --git a/docs/spec/hardfork-spec.md b/docs/spec/hardfork-spec.md index 3b0d0260..cabac3a9 100644 --- a/docs/spec/hardfork-spec.md +++ b/docs/spec/hardfork-spec.md @@ -12,8 +12,8 @@ This page defines both concepts and summarizes what each spec introduces. The protocol distinguishes between two related concepts: -- **[Hardfork](glossary.md#hardfork-megahardfork)** — A network upgrade event: _when_ changes are activated on the chain. A hardfork may include protocol-level changes beyond MegaEVM (e.g., networking, state sync, RPC behavior). Represented as `MegaHardfork` in the reference implementation. -- **[Spec](glossary.md#spec-megaspecid)** — A set of MegaETH verifiable behaviors: _what_ a correct node does. A spec captures the execution-layer semantics that determine node correctness. Represented as `MegaSpecId` in the reference implementation. +- **[Hardfork](glossary.md#hardfork-megahardfork)** — A network upgrade event: _when_ changes are activated on the chain. A hardfork may include protocol-level changes beyond MegaEVM (e.g., networking, state sync, RPC behavior). +- **[Spec](glossary.md#spec-megaspecid)** — A set of MegaETH verifiable behaviors: _what_ a correct node does. A spec captures the execution-layer semantics that determine node correctness. Multiple hardforks can map to the same spec. A hardfork can also map to an older spec. @@ -37,14 +37,14 @@ All other specs are stable (frozen). EVM semantics for stable (activated) specs are frozen. A new spec may add behavior or change the unstable spec, but it never alters what an existing stable spec does. -Every spec carries the invariant: "Stable pre-{Spec} semantics MUST remain unchanged." +Every spec carries the invariant that stable pre-{Spec} semantics remain unchanged. This means: -- Contracts deployed under a given spec will continue to behave identically after future upgrades. +- Contracts deployed under a given spec continue to behave identically after future upgrades. - Adding or modifying a system contract requires introducing a new spec. - Changing gas costs, opcode behavior, or resource limits requires a new spec. -- Implementations MUST gate spec-specific behavior on the active spec. +- Implementations gate spec-specific behavior on the active spec. ## Spec Summary @@ -117,7 +117,10 @@ _See [Rex4 Network Upgrade](upgrades/rex4.md) for full details._ > **Unstable** — This spec is under active development. > Its semantics may change before network activation. -No behavioral changes have been defined yet. -This spec serves as the placeholder for the next upgrade cycle. +- **[SequencerRegistry](system-contracts/sequencer-registry.md) system contract** — Tracks the system address and sequencer roles independently with on-chain change scheduling and history. +- **Dynamic system address** — `MEGA_SYSTEM_ADDRESS` is resolved per block from `SequencerRegistry.currentSystemAddress()` instead of a hardcoded constant. +- **Oracle v2.0.0** — `onlySystemAddress` reads the authority from `SequencerRegistry`. In-place Oracle bytecode upgrades preserve existing storage instead of clearing it. +- **Caller-account update deduplication** — Fixes overcounting of caller-account data-size and KV updates across multiple value-transferring sub-calls or creates from the same parent frame. +- **[KeylessDeploy](system-contracts/keyless-deploy.md) trailing-bytes rejection** — RLP encodings with trailing bytes after the signed payload are rejected with `MalformedEncoding()`. -_See [Rex5 Network Upgrade](upgrades/rex5.md) for the latest status._ +_See [Rex5 Network Upgrade](upgrades/rex5.md) for full details._ diff --git a/docs/spec/overview.md b/docs/spec/overview.md index 19130485..35eadda1 100644 --- a/docs/spec/overview.md +++ b/docs/spec/overview.md @@ -53,7 +53,7 @@ MegaETH uses a spec system to version its verifiable behavior at each stage of t Each newer spec includes all previous behaviors: ``` -EQUIVALENCE → MINI_REX → REX → REX1 → REX2 → REX3 → REX4 +EQUIVALENCE → MINI_REX → REX → REX1 → REX2 → REX3 → REX4 → REX5 ``` {% hint style="info" %} @@ -69,6 +69,7 @@ Contracts deployed under a given spec will continue to behave identically, regar - **REX2** — SELFDESTRUCT re-enabled (EIP-6780), KeylessDeploy system contract. - **REX3** — Oracle gas cap raised to 20M, SLOAD-based oracle detention, keyless deploy compute gas tracking. - **REX4** — Per-call-frame resource budgets, relative gas detention, [storage gas stipend](glossary.md#storage-gas-stipend), MegaAccessControl and MegaLimitControl system contracts. +- **REX5** _(unstable)_ — SequencerRegistry system contract, Oracle v2.0.0 with dynamic system address, caller-account update deduplication, KeylessDeploy trailing-bytes rejection. See [Hardforks and Specs](hardfork-spec.md) for full details. diff --git a/docs/spec/system-contracts/keyless-deploy.md b/docs/spec/system-contracts/keyless-deploy.md index 6ca36795..db0bd8d8 100644 --- a/docs/spec/system-contracts/keyless-deploy.md +++ b/docs/spec/system-contracts/keyless-deploy.md @@ -70,13 +70,20 @@ The `keylessDeploymentTransaction` argument MUST decode as a signed pre-EIP-155 The following conditions MUST hold: - the transaction encoding is valid RLP for `TxLegacy`, -- (Rex5+) the encoding contains no trailing bytes after the signed RLP payload, - the transaction is a contract creation (`to = null`), - the transaction has no chain ID, - the transaction nonce is exactly `0`. If any of those conditions fail, the call MUST revert with the corresponding validation error. +
+Rex5 (unstable): Trailing-bytes rejection + +In addition to the conditions above, the encoding MUST contain no trailing bytes after the signed RLP payload. +If trailing bytes are present, the call MUST revert with `MalformedEncoding()`. + +
+ ### Validation Rules Before starting sandbox execution, the node MUST enforce the following checks: @@ -186,3 +193,4 @@ Allowing nonce `1` preserves deployability in that case while still preventing a - [Rex2](../upgrades/rex2.md) introduced KeylessDeploy and its stable top-level interception model. - [Rex3](../upgrades/rex3.md) makes the overhead gas count toward compute gas accounting. +- [Rex5](../upgrades/rex5.md) (**unstable**) rejects encodings with trailing bytes after the signed RLP payload by reverting with `MalformedEncoding()`. diff --git a/docs/spec/system-contracts/mega-access-control.md b/docs/spec/system-contracts/mega-access-control.md index 374c1132..2615c984 100644 --- a/docs/spec/system-contracts/mega-access-control.md +++ b/docs/spec/system-contracts/mega-access-control.md @@ -27,8 +27,6 @@ The MegaAccessControl system contract MUST exist at `MEGA_ACCESS_CONTROL_ADDRESS The contract takes no constructor arguments. A node MUST deploy the bytecode version corresponding to the active spec. -Source: [`MegaAccessControl.sol`](https://github.com/megaeth-labs/mega-evm/blob/main/crates/system-contracts/contracts/MegaAccessControl.sol) - #### Version 1.0.0 Since: [Rex4](../upgrades/rex4.md) diff --git a/docs/spec/system-contracts/mega-limit-control.md b/docs/spec/system-contracts/mega-limit-control.md index 9a4fd821..2703636c 100644 --- a/docs/spec/system-contracts/mega-limit-control.md +++ b/docs/spec/system-contracts/mega-limit-control.md @@ -28,8 +28,6 @@ The MegaLimitControl system contract MUST exist at `MEGA_LIMIT_CONTROL_ADDRESS`. The contract takes no constructor arguments. A node MUST deploy the bytecode version corresponding to the active spec. -Source: [`MegaLimitControl.sol`](https://github.com/megaeth-labs/mega-evm/blob/main/crates/system-contracts/contracts/MegaLimitControl.sol) - #### Version 1.0.0 Since: [Rex4](../upgrades/rex4.md) diff --git a/docs/spec/system-contracts/oracle.md b/docs/spec/system-contracts/oracle.md index 3b907351..00cba3b6 100644 --- a/docs/spec/system-contracts/oracle.md +++ b/docs/spec/system-contracts/oracle.md @@ -1,6 +1,6 @@ --- description: MegaETH Oracle system contract — address, storage layout, hint forwarding, and gas detention trigger. -spec: Rex5 +spec: Rex4 --- # Oracle @@ -23,7 +23,6 @@ The Oracle system contract MUST exist at `ORACLE_CONTRACT_ADDRESS`. 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 @@ -49,17 +48,20 @@ Deployed bytecode: 0x608060405234801561000f575f5ffd5b50600436106100b9575f3560e01c806366cdf82f116100725780638d4909dc116100585780638d4909dc146101c8578063a21e2d69146101db578063fbc0d035146101fb575f5ffd5b806366cdf82f146101955780637eba7ba6146101a8575f5ffd5b8063138f5ec5116100a2578063138f5ec514610123578063348a0cdc1461013657806354fd4d5014610156575f5ffd5b806301caec13146100bd5780630dc9b5da146100d2575b5f5ffd5b6100d06100cb3660046105db565b61020e565b005b6100f97f000000000000000000000000a887dcb9d5f39ef79272801d05abdf707cfbbd1d81565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100d0610131366004610647565b61028a565b61014961014436600461068f565b6102d4565b60405161011a919061071a565b604080518082018252600581527f312e312e300000000000000000000000000000000000000000000000000000006020820152905161011a919061079b565b6100d06101a33660046107b4565b505050565b6101ba6101b636600461082b565b5490565b60405190815260200161011a565b6100d06101d63660046107b4565b61044b565b6101ee6101e936600461068f565b61045e565b60405161011a9190610842565b6100d0610209366004610884565b6104d4565b828114610256576040517f5b7232fa00000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044015b60405180910390fd5b8382845f5b81811015610278576020810283810135908501355560010161025b565b505050506102846104e3565b50505050565b805f5b818110156102ca576102c2858585848181106102ab576102ab6108a4565b90506020028101906102bd91906108d1565b610554565b60010161028d565b50506101a36104e3565b60608167ffffffffffffffff8111156102ef576102ef610932565b60405190808252806020026020018201604052801561032257816020015b606081526020019060019003908161030d5790505b5090505f5b82811015610444575f8030868685818110610344576103446108a4565b905060200281019061035691906108d1565b60405161036492919061095f565b5f60405180830381855af49150503d805f811461039c576040519150601f19603f3d011682016040523d82523d5f602084013e6103a1565b606091505b50915091508161041c578051156103ba57805181602001fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d756c746963616c6c3a2063616c6c206661696c656400000000000000000000604482015260640161024d565b8084848151811061042f5761042f6108a4565b60209081029190910101525050600101610327565b5092915050565b610456838383610554565b6101a36104e3565b60608167ffffffffffffffff81111561047957610479610932565b6040519080825280602002602001820160405280156104a2578160200160208202803683370190505b5090506020810183835f5b818110156104ca57602081028381013554908501526001016104ad565b5050505092915050565b8082556104df6104e3565b5050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a887dcb9d5f39ef79272801d05abdf707cfbbd1d1614610552576040517f5e742c5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b827fda678492695e6a825d786c2375f7fdf3c1dc012451c61c1804227f499b0fc53e838360405161058692919061096e565b60405180910390a2505050565b5f5f83601f8401126105a3575f5ffd5b50813567ffffffffffffffff8111156105ba575f5ffd5b6020830191508360208260051b85010111156105d4575f5ffd5b9250929050565b5f5f5f5f604085870312156105ee575f5ffd5b843567ffffffffffffffff811115610604575f5ffd5b61061087828801610593565b909550935050602085013567ffffffffffffffff81111561062f575f5ffd5b61063b87828801610593565b95989497509550505050565b5f5f5f60408486031215610659575f5ffd5b83359250602084013567ffffffffffffffff811115610676575f5ffd5b61068286828701610593565b9497909650939450505050565b5f5f602083850312156106a0575f5ffd5b823567ffffffffffffffff8111156106b6575f5ffd5b6106c285828601610593565b90969095509350505050565b5f81518084528060208401602086015e5f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561078f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc087860301845261077a8583516106ce565b94506020938401939190910190600101610740565b50929695505050505050565b602081525f6107ad60208301846106ce565b9392505050565b5f5f5f604084860312156107c6575f5ffd5b83359250602084013567ffffffffffffffff8111156107e3575f5ffd5b8401601f810186136107f3575f5ffd5b803567ffffffffffffffff811115610809575f5ffd5b86602082840101111561081a575f5ffd5b939660209190910195509293505050565b5f6020828403121561083b575f5ffd5b5035919050565b602080825282518282018190525f918401906040840190835b8181101561087957835183526020938401939092019160010161085b565b509095945050505050565b5f5f60408385031215610895575f5ffd5b50508035926020909101359150565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f5f83357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610904575f5ffd5b83018035915067ffffffffffffffff82111561091e575f5ffd5b6020019150368190038213156105d4575f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b818382375f9101908152919050565b60208152816020820152818360408301375f818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010191905056fea164736f6c634300081e000a ``` -#### Version 2.0.0 +
+Rex5 (unstable): Oracle v2.0.0 — dynamic system-address authority -> **Unstable** — Rex5 semantics described here are under active development and may change before network activation. +#### Version 2.0.0 Since: [Rex5](../upgrades/rex5.md) -The `onlySystemAddress` modifier reads the authorized address from [`SequencerRegistry.currentSystemAddress()`](sequencer-registry.md) instead of a constructor `immutable`. +The `onlySystemAddress` modifier MUST read the authorized address from [`SequencerRegistry.currentSystemAddress()`](sequencer-registry.md) 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` +Code hash: `0x71a65239db8d0f1bb765fad36e34f57600420d103a4401ef7555bd50b229dc55` + +
### Public Read Interface @@ -160,13 +162,18 @@ From [Rex2](../upgrades/rex2.md) onward, the stable Oracle bytecode includes `se **Upgrade storage semantics.** When the Oracle account's bytecode is upgraded, the fate of existing Oracle storage is consensus-critical. -Pre-[Rex5](../upgrades/rex5.md), each bytecode upgrade MUST mark the Oracle account as newly created. +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](../upgrades/rex5.md) onward, a bytecode upgrade MUST NOT mark the Oracle account as newly created. +
+Rex5 (unstable): Bytecode upgrades preserve existing Oracle storage + +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 | diff --git a/docs/spec/system-contracts/sequencer-registry.md b/docs/spec/system-contracts/sequencer-registry.md index 1e6d2dc4..6f68b02b 100644 --- a/docs/spec/system-contracts/sequencer-registry.md +++ b/docs/spec/system-contracts/sequencer-registry.md @@ -34,6 +34,8 @@ Version 1.0.0 Since: [Rex5](../upgrades/rex5.md) +Code hash: `0x2dd91bc339d4dadc8cec5a7096213af7cacb02bbbd97308e168564ee5357fb65` + The contract is deployed via raw state patch with initial storage seeded at deploy time. No constructor is executed. @@ -77,6 +79,14 @@ interface ISequencerRegistry { function applyPendingChanges() external; function admin() external view returns (address); function transferAdmin(address newAdmin) external; + + // Errors + error FutureBlock(); + error BeforeInitialBlock(); + error NotAdmin(); + error ZeroAddress(); + error InvalidActivationBlock(); + error ActivationBlockTooLarge(); } ``` @@ -93,7 +103,8 @@ Both roles share the same `_initialFromBlock`. ### Change Scheduling Each role has independent `schedule*Change(newAddress, activationBlock)`. -`activationBlock` must be strictly greater than `block.number` and fit in `uint96`. +`activationBlock` MUST be strictly greater than `block.number`; otherwise the call MUST revert with `InvalidActivationBlock()`. +`activationBlock` MUST also fit in `uint96`; if it exceeds `type(uint96).max`, the call MUST revert with `ActivationBlockTooLarge()`. At most one pending change per role exists at a time; a new schedule overwrites the previous one. To cancel, pass `activationBlock = type(uint256).max` and `newAddress = address(0)`. diff --git a/docs/spec/system-contracts/system-tx.md b/docs/spec/system-contracts/system-tx.md index 6cf23899..e59221b5 100644 --- a/docs/spec/system-contracts/system-tx.md +++ b/docs/spec/system-contracts/system-tx.md @@ -1,6 +1,6 @@ --- description: Mega system transactions — sender/recipient identification rules, whitelisted contracts, and execution bypass semantics. -spec: Rex5 +spec: Rex4 --- # Mega System Transactions @@ -19,12 +19,16 @@ Mega System Transactions provide that mechanism. ### Resolution -> **Unstable** — The dynamic resolution described below is Rex5 behavior and may change before network activation. - `MEGA_SYSTEM_ADDRESS` is the authorized system-transaction sender for the current block. +It is the fixed constant `0xA887dCB9D5f39Ef79272801d05Abdf707CFBbD1d` (see [Constants](#constants)). + +
+Rex5 (unstable): Dynamic system address resolution + +`MEGA_SYSTEM_ADDRESS` MUST be resolved per block from [`SequencerRegistry.currentSystemAddress()`](sequencer-registry.md) after all pre-block changes are committed. +The fixed-constant resolution above no longer applies. -Pre-Rex5, `MEGA_SYSTEM_ADDRESS` is the fixed constant `0xA887dCB9D5f39Ef79272801d05Abdf707CFBbD1d`. -From [Rex5](../upgrades/rex5.md) onward, `MEGA_SYSTEM_ADDRESS` is resolved per block from [`SequencerRegistry.currentSystemAddress()`](sequencer-registry.md) after all pre-block changes are committed. +
### Identification diff --git a/docs/spec/upgrades/overview.md b/docs/spec/upgrades/overview.md index b8a0eb43..9b08b225 100644 --- a/docs/spec/upgrades/overview.md +++ b/docs/spec/upgrades/overview.md @@ -1,5 +1,5 @@ --- -description: MegaETH network upgrade history — hardfork timeline from MiniRex through Rex4 with activation dates and behavioral deltas. +description: MegaETH network upgrade history — hardfork timeline from MiniRex through Rex5 with activation dates and behavioral deltas. --- # Overview @@ -108,7 +108,7 @@ Per-[call-frame](../glossary.md#call-frame) resource budgets, relative gas deten ### [Rex5](rex5.md) _(unstable)_ -No behavioral changes defined yet. +[SequencerRegistry](../system-contracts/sequencer-registry.md) system contract, [Oracle](../system-contracts/oracle.md) v2.0.0 with dynamic system address, caller-account update deduplication for [data size](../evm/resource-accounting.md#data-size) and [KV updates](../evm/resource-accounting.md#kv-updates), [KeylessDeploy](../system-contracts/keyless-deploy.md) trailing-bytes rejection. ## How to Read These Pages diff --git a/docs/spec/upgrades/rex5.md b/docs/spec/upgrades/rex5.md index 0bdae7cd..bc29cec7 100644 --- a/docs/spec/upgrades/rex5.md +++ b/docs/spec/upgrades/rex5.md @@ -1,5 +1,5 @@ --- -description: Rex5 network upgrade — SequencerRegistry with dual roles, dynamic system address, Oracle v2.0.0, and caller-account update deduplication. +description: Rex5 network upgrade — SequencerRegistry with dual roles, dynamic system address, Oracle v2.0.0, KeylessDeploy trailing-bytes rejection, and caller-account update deduplication. --- # Rex5 Network Upgrade @@ -60,7 +60,17 @@ Pending role changes are applied during `pre_execution_changes` via a single pre This follows the same pattern as EIP-2935 and EIP-4788. The system call is only issued when a Rust-side pre-check confirms any role change is due. -### 5. Caller-Account Update Deduplication (Data Size and KV Updates) +### 5. KeylessDeploy Trailing-Bytes Rejection + +**Previous behavior (Rex4 and earlier):** +The `keylessDeploy` interceptor decoded the inner pre-EIP-155 transaction RLP without rejecting trailing bytes after the signed payload. +Encodings with trailing data were accepted as long as the leading bytes formed a valid `TxLegacy`. + +**New behavior (Rex5):** +The decoder MUST reject any encoding that contains bytes after the signed RLP payload by reverting with `MalformedEncoding()`. +This tightens validation so that two distinct byte strings cannot both pass as the "same" inner deployment transaction. + +### 6. Caller-Account Update Deduplication (Data Size and KV Updates) **Previous behavior (Rex4 and earlier):** When a call frame performed a value-transferring `CALL` / `CALLCODE` or a `CREATE` / `CREATE2`, the implementation charged the _caller_ account update to the child frame's discardable budget. @@ -94,6 +104,7 @@ The discardable-on-revert mechanic is unchanged: charges recorded inside a child - [mega-evm repository](https://github.com/megaeth-labs/mega-evm) - [Hardforks and Specs](../hardfork-spec.md) — spec progression and backward-compatibility model -- `crates/mega-evm/src/system/sequencer_registry.rs` — Rust implementation -- `crates/system-contracts/contracts/SequencerRegistry.sol` — Solidity contract -- `crates/system-contracts/contracts/Oracle.sol` — Oracle v2.0.0 +- [SequencerRegistry](../system-contracts/sequencer-registry.md) — system contract specification +- [Oracle](../system-contracts/oracle.md) — Oracle v2.0.0 specification +- [KeylessDeploy](../system-contracts/keyless-deploy.md) — KeylessDeploy specification +- [Resource Accounting](../evm/resource-accounting.md) — caller-account update deduplication From b375767b7067be7ba2709176aaad4546d9c95637 Mon Sep 17 00:00:00 2001 From: TroublorBot Date: Wed, 6 May 2026 03:28:12 +0000 Subject: [PATCH 2/3] docs: clarify cancel exception in sequencer-registry Change Scheduling The cancellation path (activationBlock == type(uint256).max) bypasses the ActivationBlockTooLarge check in the Solidity source. The previous prose stated the uint96 size constraint without noting the cancel exception, making it appear that passing type(uint256).max would revert. Document cancellation first to make the ordering clear. Generated-by: engineer-agent --- docs/spec/system-contracts/sequencer-registry.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/spec/system-contracts/sequencer-registry.md b/docs/spec/system-contracts/sequencer-registry.md index 6f68b02b..7c33fcac 100644 --- a/docs/spec/system-contracts/sequencer-registry.md +++ b/docs/spec/system-contracts/sequencer-registry.md @@ -103,10 +103,10 @@ Both roles share the same `_initialFromBlock`. ### Change Scheduling Each role has independent `schedule*Change(newAddress, activationBlock)`. -`activationBlock` MUST be strictly greater than `block.number`; otherwise the call MUST revert with `InvalidActivationBlock()`. +To cancel a pending change, pass `activationBlock = type(uint256).max` and `newAddress = address(0)`; the call is handled as a special cancellation case before any other validation. +For all other values, `activationBlock` MUST be strictly greater than `block.number`; otherwise the call MUST revert with `InvalidActivationBlock()`. `activationBlock` MUST also fit in `uint96`; if it exceeds `type(uint96).max`, the call MUST revert with `ActivationBlockTooLarge()`. At most one pending change per role exists at a time; a new schedule overwrites the previous one. -To cancel, pass `activationBlock = type(uint256).max` and `newAddress = address(0)`. ### Pre-Block Apply From 1942e407c5cb9480c19b4905a6001db651893e97 Mon Sep 17 00:00:00 2001 From: TroublorBot Date: Wed, 6 May 2026 03:32:02 +0000 Subject: [PATCH 3/3] address review feedback: fix details block wording and version heading MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - system-tx.md: make Rex5 details block self-contained — replace "above" reference with the explicit constant value so the block reads correctly when expanded in isolation. - sequencer-registry.md: promote "Version 1.0.0" to a #### heading and add the "A node MUST deploy..." preamble, matching the heading style used in oracle.md and other system contract pages. Generated-by: engineer-agent --- docs/spec/system-contracts/sequencer-registry.md | 4 +++- docs/spec/system-contracts/system-tx.md | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/spec/system-contracts/sequencer-registry.md b/docs/spec/system-contracts/sequencer-registry.md index 7c33fcac..18360b1e 100644 --- a/docs/spec/system-contracts/sequencer-registry.md +++ b/docs/spec/system-contracts/sequencer-registry.md @@ -30,7 +30,9 @@ The `SequencerRegistry` provides a canonical on-chain source of truth for both r ### Bytecode -Version 1.0.0 +A node MUST deploy the bytecode version corresponding to the active spec. + +#### Version 1.0.0 Since: [Rex5](../upgrades/rex5.md) diff --git a/docs/spec/system-contracts/system-tx.md b/docs/spec/system-contracts/system-tx.md index e59221b5..4af80098 100644 --- a/docs/spec/system-contracts/system-tx.md +++ b/docs/spec/system-contracts/system-tx.md @@ -26,7 +26,7 @@ It is the fixed constant `0xA887dCB9D5f39Ef79272801d05Abdf707CFBbD1d` (see [Cons Rex5 (unstable): Dynamic system address resolution `MEGA_SYSTEM_ADDRESS` MUST be resolved per block from [`SequencerRegistry.currentSystemAddress()`](sequencer-registry.md) after all pre-block changes are committed. -The fixed-constant resolution above no longer applies. +The fixed constant `0xA887dCB9D5f39Ef79272801d05Abdf707CFBbD1d` is replaced by this dynamic resolution; the fixed-constant rule does not apply in Rex5 and later.