Rivellum

Rivellum Portal

Download Wallet (Chrome)
Checking...
mainnet

Mist Architecture & Internals

Deep dive into the Mist compilation pipeline, PVI graph model, UVL verification engine, MCE conservation analysis, and runtime execution model.

Compilation Pipeline

Mist source compiles through a 6-stage pipeline. Each stage produces verifiable intermediate artifacts:

                    ┌─────────────────────────────────────────────────────────┐
                    │                   mistc compile                        │
                    │                                                        │
   .mist source ─▶  Parse ─▶ Type Check ─▶ VIR Lowering ─▶ Normalize VIR   │
                    │                                                        │
                    │   ─▶ Static Analysis ─▶ MCE Conservation ─▶ Fee Calc  │
                    │                                                        │
                    │   ─▶ PVI Lowering ─▶ Bundle Generation               │
                    │                                                        │
                    └────────────────────────────────────────────── .bundle ─┘

Stage 1: Parsing

The parser converts .mist source into an AST (Abstract Syntax Tree). Mist uses an indentation-sensitive lexer (Python-style) and a recursive descent parser.

Key properties:

  • Tabs are forbidden — only spaces for indentation
  • No error recovery — first parse error halts compilation
  • Keywords are reserved (contract, state, function, hold, pay, etc.)

Output: Contract { name, state_decls, functions, events }

Stage 2: Type Checking

A three-pass type checker verifies type correctness:

  1. Pass 1 — Collect state declarations into the type environment
  2. Pass 2 — Collect function signatures (parameter types + return types)
  3. Pass 3 — Type-check function bodies, statement by statement

Gradual typing: The type system uses an Unknown type for dynamically-typed values (oracle reads, state reads, field accesses). Unknown is compatible with any concrete type, allowing oracle-dependent business logic without explicit casts.

Type lattice:

         Unknown
       /  |  |  \  \
    Int  Bool  String  Address  Value

Stage 3: VIR Lowering

Converts the AST into Value IR (VIR) — an SSA-based intermediate representation with basic blocks, value IDs, and typed value operations.

Key transformations:

  • Each expression becomes a fresh ValueId
  • require(cond)Branch { true: continue, false: Panic }
  • if/else → branch to then/else blocks, both merge to a join block
  • Value operations (hold, pay, etc.) become typed VIR instructions

Stage 4: VIR Normalization

Canonicalizes the VIR for deterministic hashing:

  • Blocks sorted by topological order
  • SSA value IDs renumbered sequentially
  • The normalized VIR is SHA-256 hashed to produce the code_hash

Stage 5: Static Analysis

Runs 10+ correctness checks on the normalized VIR:

CheckDescriptionError Code
No locked fundsEvery hold/mint vault is consumedMIST_E_LOCKED_FUNDS
ConservationValue inputs equal outputs + feesMIST_E_CONSERVATION
Split completenessSplit amounts sum to vault totalMIST_E_SPLIT_SUM
Mint authorityMint operations have valid authorityMIST_E_MINT_AUTHORITY
Burn validityBurns target valid vaultsMIST_E_BURN_INVALID
DeterminismNo non-deterministic operationsMIST_E_NON_DETERMINISTIC
No direct mutationBalances only change via value operationsMIST_E_DIRECT_BALANCE_MUTATION
No unbounded loopsLoops have provable boundsMIST_E_UNBOUNDED_LOOP
Deterministic feesFee computation is staticMIST_E_NON_DETERMINISTIC_FEE

Stage 5.5: MCE Conservation Analysis

The Mist Conservation Engine (MCE) performs deep value lineage analysis:

  1. Value Lineage Graph (VLG) — Traces every value from source to sink
  2. Symbolic Amount Analysis — Proves conservation symbolically when amounts aren't constant
  3. Linearity Check — Ensures each vault is consumed exactly once
  4. Runtime Assertion Injection — Adds conservation checks that trigger at execution time
  5. Fee Node Injection — Inserts fee deduction nodes into the VLG

Stage 6: PVI Lowering & Bundle Generation

Converts normalized VIR to a PVI graph and produces the final bundle:

{
    "version": "0.1.0",
    "metadata": {
        "contract_name": "MyContract",
        "compiler_version": "0.1.0",
        "build_timestamp": "2026-04-14T12:00:00Z",
        "entry_function": "init",
        "fee_summary": { ... }
    },
    "vir": { ... },
    "pvi_graph": { ... },
    "code_hash": [32 bytes, SHA-256 of normalized VIR]
}

PVI Graph Model

A PVI (Proof-Verified Invocation) graph is a typed directed acyclic graph that represents all value flows in a contract execution. It is the artifact that the UVL engine verifies before settlement.

Node Types

Node TypeDescriptionExample
HOLDLock assets from an account into a vaulthold v = 100 asset "RIVL" from alice
PAYTransfer assets to an accountpay 100 asset "RIVL" to bob
RELEASEReturn vault contents to an accountrelease vault v to alice
REFUNDReturn vault contents (refund semantics)refund vault v to alice
SPLITDivide vault among multiple recipientssplit vault v into [80 to a, 20 to b]
MINTCreate new asset unitsmint v = 100 asset id authority owner
BURNDestroy asset unitsburn vault v
FEEProtocol fee deduction (injected by compiler)automatic

Edge Types

Edges connect nodes and represent value flow with amounts and asset types:

HOLD(alice, 1000 RIVL)
    ├──[800 RIVL]──▶ PAY(bob)
    └──[200 RIVL]──▶ PAY(charlie)

Graph Constraints

  1. Acyclicity — No cycles in the value flow graph
  2. Single source per vault — Each vault traces to exactly one HOLD or MINT
  3. Conservation per asset — For each asset type: Σ HOLD + Σ MINT = Σ PAY + Σ RELEASE + Σ REFUND + Σ BURN + Σ FEE
  4. No negative amounts — All edge weights are non-negative
  5. Complete consumption — Every HOLD/MINT node must have outgoing edges that sum to its total

Commitment Algorithm

The PVI graph is canonicalized and hashed to produce a 32-byte commitment:

PVI_commitment = Blake3(canonical_json(pvi_graph))

This commitment is embedded in the execution receipt and verified by UVL during settlement.

UVL Verification Engine

The Universal Value Ledger (UVL) is the settlement layer. It runs 14 verification checks at the commit boundary — if any check fails, the entire intent is rejected atomically.

Verification Checks

#CheckError
1PVI commitment matches embedded graphUVL_F001
2Conservation of value per assetUVL_F002
3No negative balancesUVL_F003
4No locked funds (all vaults consumed)UVL_F004
5Split sums correctUVL_F005
6Split rounding follows TruncateRemainderToLastUVL_F006
7Mint authority validUVL_F007
8Fee quote commitment matchesUVL_F008
9Oracle snapshot commitment matchesUVL_F009
10Oracle snapshot not stale (max 256 blocks)UVL_F010
11Protocol version supportedUVL_F011
12Compiler in allowlistUVL_F012
13Host ABI commitment matchUVL_F013
14VRF proof validUVL_F014

Settlement Process

Intent submitted
    → Mist execution produces PVI graph + state deltas
    → Execution receipt generated with commitments
    → UVL runs 14 verification checks
    → On success: SettlementPlan with BalanceDeltas applied atomically
    → On failure: Entire intent rejected, no state changes

The settlement plan is a list of BalanceDelta { account, asset_id, delta: i128 } applied in a single atomic operation.

Atomic Rejection

UVL guarantees all-or-nothing semantics. If check #7 (mint authority) fails, it doesn't matter that checks #1-6 passed — the entire intent is rejected. No partial state changes ever persist.

Runtime Execution Model

Architecture

MistDeploy/MistCall
    → dispatch (load bundle, validate)
    → execute (interpret VIR, produce PVI instances)
    → commitments (compute receipt extension)
    → UVL verify & settle (at commit boundary)

Host Environment

The runtime receives a deterministic host environment for each execution:

FieldTypeDescription
caller[u8; 32]Intent sender address
commit_time_msu64Block commit timestamp
oracle_pricesMap<String, u128>Oracle spot prices (1e18 fixed-point)
twap_rate_1e18u128Time-weighted average price
lane_idu32Execution lane
prestate_root[u8; 32]Pre-execution state root
fee_tieru8Fee tier for this execution

Host ABI (Syscalls)

Contracts interact with chain state through a fixed set of syscalls, each with a deterministic gas cost:

CategoryOperationsGas Range
StorageGET (100), SET (200), DELETE (150)100-200
TablesCREATE (300), GET (120), SET (220), DELETE (170), CONTAINS (80), LEN (50)50-300
ObjectsCREATE (500), READ (100), WRITE (250), TRANSFER (300), FREEZE (200), DELETE (200)100-500
AuthCALLER (10), HAS_CAPABILITY (50), VERIFY_SIGNATURE (1000), ISSUE_CAP (500), REVOKE_CAP (500)10-1000
EventsEMIT (150)150
OracleREAD_PRICE (200), READ_TWAP (300), SNAPSHOT_COMMITMENT (50)50-300
VRFSEED (50), RANDOM_U64 (100), RANDOM_RANGE (100)50-100
CryptoHASH_BLAKE3 (100), HASH_SHA3 (150), VERIFY_SIG (1000)100-1000

Size Limits

LimitValue
Max key size256 bytes
Max value size65,536 bytes
Max table entries10,000
Max events per transaction256
Max topic size64 bytes
Max event data size4,096 bytes

Contract ID Derivation

When a contract is deployed, its on-chain ID is computed deterministically:

contract_id = Blake3(
    "RIVELLUM_MIST_CONTRACT_ID_V1" ‖
    deployer_address ‖
    contract_name ‖
    code_hash ‖
    commit_time_ms
)

This means the same deployer deploying the same contract at different times gets different contract IDs.

Deterministic Replay

Every execution is fully reproducible. The execution receipt contains:

  • PVI commitment (Blake3 hash of canonical PVI graph)
  • Fee commitment
  • Oracle snapshot commitment
  • Host ABI commitment (Blake3 of read set ‖ write set ‖ object ops ‖ oracle ‖ vrf proof)

Given the receipt and the original host environment, anyone can replay the execution and verify they get identical commitments:

# Export replay bundle
mistc repro-export --contract my_contract.mist --receipt <receipt_id>

# Replay and verify
mistc replay replay_bundle.json

Insolvency Handling

When a SPLIT node distributes more than the vault contains (insolvency), UVL applies a waterfall policy:

PolicyBehavior
RejectAllReject the entire intent (default)
ProRataDistribute proportionally to weight
PriorityFirstFill recipients in order until exhausted

Split Rounding

When splitting amounts that don't divide evenly, Mist uses the TruncateRemainderToLast policy: integer division truncates each share, and any remainder goes to the last recipient in the split list.

Example: splitting 100 units three ways at equal weight:

  • Recipient 1: 33
  • Recipient 2: 33
  • Recipient 3: 34 (gets the remainder)

Oracle System

Price Format

Oracle prices use 1e18 fixed-point representation:

Actual price $60,000.50 → 60000500000000000000000 (60000.5 × 10^18)

Staleness Rules

Oracle snapshots have a maximum age of 256 blocks. If the snapshot is older, UVL rejects with UVL_F010. This ensures contract execution uses reasonably current market data.

Supported Pairs

Oracle pair format: "BASE_QUOTE" in Mist source, "BASE/QUOTE" in the runtime. The compiler translates automatically.

let btc = oracle.price("BTC_USD")
let eth = oracle.price("ETH_USD")
let rivl = oracle.price("RIVL_USD")

Compilation Output Artifacts

FileDescription
<name>.bundle.jsonComplete bundle (VIR + PVI + metadata + code hash)
<name>.pvi.jsonStandalone PVI graph
<name>.analysis.jsonStatic analysis report
<name>.fees.jsonFee breakdown by function