Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.solidscipt.zoracle.xyz/llms.txt

Use this file to discover all available pages before exploring further.

An invariant is a property that must stay true across all possible state transitions — no matter what sequence of calls a contract receives. SolidScript turns methods decorated with @invariant into Forge invariant tests and runs them as part of the verification pipeline. This guide shows you how to annotate a contract with invariant methods and run the invariant gate locally.

Add invariant methods to a contract

Decorate methods with @invariant to declare properties that must always hold. Each method should return a boolean:
YieldVault.ts
import { invariant, storage } from "solidscript";

export class YieldVault {
  @storage totalStaked: bigint = 0n;
  @storage totalRewardsPaid: bigint = 0n;

  @invariant
  invariantStakeBalances(): boolean {
    return this.totalStaked >= 0n;
  }

  @invariant
  invariantRewardsNonNegative(): boolean {
    return this.totalRewardsPaid >= 0n;
  }
}
Good invariant methods follow these principles:
  • Return boolean
  • Read contract state
  • Avoid changing state
  • Assert one property at a time
Use invariants for balances, supply constraints, quorum bounds, paused-state behavior, and other properties that should hold after arbitrary call sequences.

Run the invariant gate

Run all verification checks, including the invariant gate, with:
npx solidscript verify contracts
To skip the invariant gate during fast local iteration, pass --skip invariants:
npx solidscript verify contracts --skip invariants
The invariant gate is generated from your TypeScript annotations. You still need to choose properties that matter for the contract’s trust model.