Skip to main content

Overview

Sudont supports two virtual machines: the Ethereum Virtual Machine (EVM) and the Solana Virtual Machine (SVM). Both are first-class citizens.
A single CanonicalIntent carries a vm_type field that routes it to the correct Cage implementation. The architecture is unified at the type level — the Judge and the rest of the pipeline are completely VM-agnostic.

The SimulationEngine Trait

Defined in sudont-types, SimulationEngine is the contract both Cage implementations fulfill:
SimulationEngine — VM-Agnostic Interface
/// Both EVM and SVM cages implement this trait.
pub trait SimulationEngine: Send + Sync {
    fn simulate(&self, intent: &CanonicalIntent) -> Result<SimOutcome, String>;
}
The CanonicalIntent input carries the vm_type discriminant:
VmType Enum
pub enum VmType {
    Evm,
    Svm,
}
The RPC layer reads vm_type and dispatches to the correct SimulationEngine implementation at runtime — no conditional logic needed in the Judge or policy layers.

VM Implementations

Rust crate: sudont-cage Dependency: revm = "14.0"The EVM Cage uses revm — a pure-Rust, production-grade Ethereum Virtual Machine implementation.

Exact Semantics

Byte-for-byte compatible with geth/reth execution

Full State Access

Storage slots, emitted logs, and state diffs

Gas Accounting

Precise gas computation and revert reason extraction

EIP Support

EIP-3607 and active EIPs via feature flags
State source: Local Base reth node with Flashblocks support. The simulation reflects the pending world, not a stale cache.Supported protocols: Uniswap V3 (exactInputSingle, exactInput), Aerodrome router swap flows.
SimOutcome
pub struct SimOutcome {
    pub success: bool,
    pub exit_reason: String,       // e.g. "Revert(0x...)" or "Stop"
    pub logs: Vec<SimLog>,         // Transfer events, Swap events
    pub asset_changes: Vec<AssetChange>, // token_in/token_out amounts
    pub state_diff: Vec<StateDiff>,      // storage slot changes
}
The Judge uses asset_changes to compute effective slippage and price impact against the CanonicalIntent’s amount_out_min and slippage_bps fields.

RPC Routing by vmType

The TypeScript SDK exposes vmType as a constructor parameter:
import { SudontClient } from '@sudont/sdk';

// Routes to sudont-cage (revm)
const evmClient = new SudontClient('http://localhost:8545', 'evm');
On the server side, the JSON-RPC layer reads vmType from the incoming request and selects the appropriate SimulationEngine implementation. The Judge, Constitution, and diagnostic machinery are shared — only the simulation backend differs.

Extending to New VMs

Define VmType Variant

Add a new variant to the VmType enum in sudont-types.

Implement SimulationEngine

Create a new Cage crate implementing the SimulationEngine trait for your VM.

Register in RPC Dispatch

Register the implementation in the sudont-rpc dispatch table.

Done — No Other Changes

No changes needed to sudont-judge, sudont-constitution, or sudont-cortex. The firewall logic stays stable as new chains are added.