Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Stylus WASM Runtime

Stylus allows smart contracts written in Rust, C, and C++ to run on Arbitrum as compiled WASM programs alongside standard EVM contracts. ArbReth implements the full Stylus execution pipeline.

How Stylus Works

Stylus programs are identified by a 3-byte prefix in their deployed bytecode: [0xEF, 0xF0, 0x00]. When the EVM encounters a call to an address with this prefix, execution is dispatched to the WASM runtime instead of the EVM interpreter.

Execution Flow

  1. Detection - during an EVM CALL, the target's bytecode is checked for the Stylus discriminant
  2. Cache lookup - the compiled WASM module is loaded from cache (or compiled on-the-fly)
  3. Ink conversion - EVM gas is converted to "ink" (Stylus's internal gas unit) at the configured ink_price rate
  4. Execution - the WASM program runs in a wasmer sandbox with host I/O functions for EVM state access
  5. Gas settlement - remaining ink is converted back to EVM gas and returned to the caller

Ink Metering

Stylus uses ink as its internal gas unit, separate from EVM gas. The conversion rate is configurable:

Gas * ink_price = Ink

Ink is deducted for:

  • WASM opcode execution (via compiler-injected metering middleware)
  • Host I/O calls (storage reads/writes, calls, memory operations)
  • Memory page allocation

Upfront Gas Costs

Before a Stylus program starts executing, gas is deducted for:

  • Memory initialization - based on the program's memory footprint
  • Program startup - init_gas (first activation) or cached_gas (subsequent calls)

Program Lifecycle

Activation

Programs must be activated before they can be called. Activation:

  1. Validates the WASM module structure
  2. Instruments it with ink metering middleware
  3. Compiles to native code via Cranelift
  4. Stores metadata (version, init cost, cached cost, footprint) in a packed 32-byte storage word
  5. Charges a data pricing fee based on an exponential demand curve

Caching

Compiled WASM modules are cached in a two-tier system:

  • Long-term cache - pinned programs that are always available
  • LRU cache - recently-used programs evicted under memory pressure

Cache management is exposed through the ArbWasmCache precompile (0x72).

Host I/O

Stylus programs interact with EVM state through host functions:

Host FunctionPurposeInk Cost
storage_load_bytes32Read a storage slotCold SLOAD + access cost
storage_cache_bytes32Write to storage cacheSSTORE sentry + access cost
storage_flush_cacheFlush cached writesPer-slot SSTORE cost
call_contractCALL to another contractEVM call cost + gas forwarding
delegate_call_contractDELEGATECALLSame as call
static_call_contractSTATICCALLSame as call
create1 / create2Deploy a contractCREATE/CREATE2 gas
emit_logEmit an eventLOG base + topic + data costs
account_balanceRead account balanceAccount access cost
account_codehashRead code hashAccount access cost
tx_origin / msg_senderTransaction contextBase hostio cost
block_timestamp / block_numberBlock contextBase hostio cost
read_return_dataRead return data from last callBase hostio cost
msg_valueCallvalueBase hostio cost

Sub-Calls

Stylus programs can call other contracts (both EVM and Stylus):

  • EVM contracts - ink is converted back to gas, a standard EVM frame is created
  • Stylus contracts - gas is converted to ink in the callee's context
  • Precompiles - dispatched through the standard precompile routing

The 63/64ths gas forwarding rule applies, matching EVM semantics. Call depth is tracked and reentrancy into the same Stylus program is detected per-address.

Precompiles

AddressNamePurpose
0x71ArbWasmActivate programs, query version/gas/footprint/expiry
0x72ArbWasmCachePin/unpin programs in cache, query cache status

Both precompiles are available from ArbOS v30 onward.