Security¶
Security model¶
Wasichain does not rely on a custom VM for contract isolation. It runs standard wasm32-wasip2 components in Wasmtime, then constrains what those components are allowed to import and do.
The security boundary comes from three layers working together:
- deterministic admission checks before activation
- Wasmtime sandboxing plus a capability-free WASI context
- runtime limits on fuel, time, storage mutation, and call structure
Sandboxing¶
Contracts execute inside Wasmtime with a minimal WASI context that grants no ambient capabilities.
In practice, contracts do not get access to:
- filesystem APIs
- sockets or arbitrary network access
- clocks, timers, or wall-clock time
- randomness
- process spawning or environment access
The only useful host surface is the Wasichain WIT: storage, events, sender/origin identity, deferred dispatch, and read-only contract queries.
Determinism¶
Determinism is enforced at both admission time and execution time.
Before activation, the admission pipeline validates that uploaded code:
- is valid Wasm/component data
- stays within the maximum blob size
- exports the required contract ABI
- imports only the allowed namespaces
At runtime, determinism comes from the absence of nondeterministic host capabilities and from consensus over:
- the raw Wasm
code_hash - the VM version string
- the activation lifecycle recorded on-chain
Validators do not need identical native machine code. Consensus is over the raw Wasm blob and the activation fact, not over serialized native artifacts.
Code admission and compilation-bomb resistance¶
Untrusted contract compilation is kept off the consensus hot path.
The flow is:
- upload the raw Wasm blob
- validate and compile it in
admissiond - have validators attest readiness with
PreparedCodeVote - activate only after quorum
This avoids forcing validators to compile attacker-supplied code while executing transactions in consensus.
Current concrete defenses include:
- maximum blob-size enforcement
- deterministic structural validation before compilation
- isolated admission-sidecar compilation instead of in-transaction compilation
- compiled-artifact cache verification before execution
Fuel and denial-of-service resistance¶
Execution is metered with Wasmtime fuel.
ExecContractpre-charges against the declaredfuel_limit- execution stops on
OutOfFuel - the block proposer also enforces a block-wide fuel cap
Wasichain also enforces a wall-clock execution limit using Wasmtime epoch interruption. This protects against cases where fuel alone is not enough to bound execution cost.
See Fees & Fuel for pricing details.
Re-entrancy resistance¶
Mutable cross-contract calls use an actor-style dispatch/reply model rather than synchronous re-entrant execution.
That means:
- contract A finishes before contract B begins
- sub-message effects are isolated in nested overlays
- failures roll back the failing frame instead of partially mutating shared state
This removes classic synchronous re-entrancy from the mutable call path by construction.
Read-only contract queries are allowed synchronously because they cannot commit writes.
State isolation and atomicity¶
Each contract has its own key-value namespace.
- reads see committed state plus the current transactional overlay
- writes go to an overlay first
- failed execution discards the overlay
- successful execution commits atomically
Sub-messages get nested overlay frames, so partial failures can be rolled back cleanly.
Query safety¶
Queries run in read-only mode.
During a query:
kv-setkv-deleteemit-eventdispatch
are rejected. Query execution can inspect state, but it cannot persist mutations.
Additional structural limits¶
Wasichain also enforces:
- a maximum blob size for uploaded code
- a maximum fuel budget per transaction
- a maximum total fuel budget per block
- a maximum sub-message depth
Together, these keep both execution and host-side bookkeeping bounded.