One reserved slot. ~220 possible functions.

Adding opcodes to an EVM chain risks collision with future Ethereum upgrades. MIP-7 claims one reserved slot as a safe extension namespace.

The information on this page should not be quoted. Please refer to MIP-7 for the authoritative spec.

EVM opcode space (0x00–0xFF)

149 defined106 free1 reserved

Click 0xAE to expand the extension namespace

The collision problem

Ethereum assigns new opcodes with every upgrade. Any slot Monad claims today might be claimed by Ethereum tomorrow, turning the same bytecode into two different programs on two different chains.

Monad

0xAB

FAST_HASH

assigned by Monad

// executes Monad FAST_HASH

Ethereum

0xAB

(unassigned)

not yet assigned

// 0xAB → INVALID

Monad adds opcode 0xAB as FAST_HASH, a Monad-specific optimized hash. Works great on Monad.

The extension namespace

MIP-7 reserves opcode 0xAE as a gateway. The byte that follows is a selector, giving Monad ~220 safe extension slots under a single top-level opcode.

Two-byte dispatch

Byte 1: opcode

0xAE

EXTENSION

reserved by EIP-8163 · INVALID on Ethereum L1

dispatch on selector

Byte 2: selector (0x00–0xFF)

0x00

unassigned → INVALID

0x01

unassigned → INVALID

...

unassigned → INVALID

0xFF

unassigned → INVALID

On Ethereum L1

0xAEINVALID · halt · all gas consumed
0xAE 0x01INVALID (same)

EIP-8163 permanently reserves 0xAE for non-L1 use. Ethereum will never assign it to anything else.

On Monad

0xAE 0x00INVALID (today)
0xAE 0x01future MIP assigns this
0xAE XXdispatch to selector XX

When a selector is undefined, behaves as INVALID. Future MIPs assign specific selectors to Monad features.

Extension selector table (first 32 of ~220 shown)

status: all unassigned

0x00

INVALID

0x01

INVALID

0x02

INVALID

0x03

INVALID

0x04

INVALID

0x05

INVALID

0x06

INVALID

0x07

INVALID

0x08

INVALID

0x09

INVALID

0x0A

INVALID

0x0B

INVALID

0x0C

INVALID

0x0D

INVALID

0x0E

INVALID

0x0F

INVALID

0x10

INVALID

0x11

INVALID

0x12

INVALID

0x13

INVALID

0x14

INVALID

0x15

INVALID

0x16

INVALID

0x17

INVALID

0x18

INVALID

0x19

INVALID

0x1A

INVALID

0x1B

INVALID

0x1C

INVALID

0x1D

INVALID

0x1E

INVALID

0x1F

INVALID

+ ~190 more selectors · all unassigned · future MIPs claim specific slots

JUMPDEST analysis

Before execution, the EVM scans bytecode to find valid jump destinations: bytes equal to 0x5B that are not consumed as PUSH immediates. MIP-7 is designed so that 0xAE never alters this analysis.

This preserves identical jump destination sets across all EVM chains, and it's why extension selectors have strict byte-range restrictions.

JUMPDEST analysis scanner

leftright
0x60
0x5B
0x5B

0 / 3 bytes

Legend

0xAE: extension gateway
valid selector
forbidden selector → halt
valid JUMPDEST ✓
PUSH opcode
PUSH-consumed (not JUMPDEST)
regular opcode/data

Immediate argument encoding

Extension opcodes have two ways to pass arguments. The choice depends on whether argument bytes need to include values in the restricted range (0x5B or 0x60–0x7F).

0xAE  selector  arg₁  arg₂  …

0xAE

EXTENSION

opcode

0x03

selector

0x03 (valid)

0xA0

arg 1

≠ 0x5B, ≠ PUSH

0xB2

arg 2

≠ 0x5B, ≠ PUSH

0xC4

arg 3

≠ 0x5B, ≠ PUSH

Simple. Argument bytes follow the selector inline. No overhead.

Constraint: Each argument byte must avoid 0x5B and 0x60–0x7F. Using a forbidden value causes an exceptional halt.

Why: JUMPDEST analysis scans arg bytes normally, since 0xAE doesn't eat them. Forbidden bytes would create analysis divergence between chains.

What this means for developers

Safe to innovate

Monad can add opcode-level features without claiming top-level slots that Ethereum might later assign. The 0xAE namespace is reserved specifically for non-L1 chains by EIP-8163.

EVM-portable bytecode

Contracts using 0xAE XX on Monad run on Ethereum as INVALID, not as some wrong function. Silent misbehavior is impossible. Bytecode that does work on Monad is predictably inert on Ethereum.

~220 slots for future MIPs

All ~220 selectors are unassigned today. Each future Monad feature claims its own selector via a new MIP. The encoding format never changes; only the dispatch table grows.

Continue the discussion on Monad Forum

Questions, feedback, or a better idea? Weigh in on the forum thread.

Open forum thread