diff --git a/AGENTS.md b/AGENTS.md
index e31bd87..fc39840 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 73ded56..3ab887a 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 e28bef0..a1adfba 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 54eeeae..c7a62d0 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 a8523fc..50a0620 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 3b0d026..cabac3a 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 1913048..35eadda 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 6ca3679..db0bd8d 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 374c113..2615c98 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 9a4fd82..2703636 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 0015949..0ea5498 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
@@ -174,13 +176,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 1e6d2dc..18360b1 100644
--- a/docs/spec/system-contracts/sequencer-registry.md
+++ b/docs/spec/system-contracts/sequencer-registry.md
@@ -30,10 +30,14 @@ 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)
+Code hash: `0x2dd91bc339d4dadc8cec5a7096213af7cacb02bbbd97308e168564ee5357fb65`
+
The contract is deployed via raw state patch with initial storage seeded at deploy time.
No constructor is executed.
@@ -77,6 +81,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,9 +105,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` and fit in `uint96`.
+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
diff --git a/docs/spec/system-contracts/system-tx.md b/docs/spec/system-contracts/system-tx.md
index 6cf2389..4af8009 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 `0xA887dCB9D5f39Ef79272801d05Abdf707CFBbD1d` is replaced by this dynamic resolution; the fixed-constant rule does not apply in Rex5 and later.
-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 b8a0eb4..9b08b22 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 0bdae7c..bc29cec 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