Formal Verification
Formal verification is a primary Ora feature: correctness properties are explicit, mechanically checked, and traceable through the compiler pipeline.
Research intent and current front-end integration. No guarantee of end-to-end proofs for all programs.
Model
Verification is expressed with specification clauses that live alongside code:
requires— preconditions the caller must satisfy (verified statically at call sites)guard— runtime-enforced preconditions the function checks itself (reverts if false, informs the verifier)ensures— postconditions the function must satisfy on all return pathsinvariant— contract-level or loop-level properties that must hold across all state transitionsassume— verification-only constraints (no runtime check)assert— runtime-visible checks also modeled as verification obligations
These clauses are parsed and type-checked in the front end, then lowered into verification-relevant IR for constraint extraction and SMT proof.
Example
pub fn transfer(to: address, amount: u256) -> bool
requires balances[std.msg.sender()] >= amount
guard amount > 0
guard to != std.constants.ZERO_ADDRESS
ensures balances[std.msg.sender()] == old(balances[std.msg.sender()]) - amount
ensures balances[to] == old(balances[to]) + amount
{
// implementation
}
Verification flow
Implemented today
- Specification clauses are recognized by the parser and type resolver.
- Constraints are carried into Ora MLIR using verification ops.
- Refinement constraints that cannot refine types become SMT-only assumptions rather than being dropped.
- SMT counterexamples are surfaced when proofs fail.
Next focus
- Default SMT discharge for refinement guards.
- Stronger propagation across control-flow joins.
- End-to-end proof reporting in the backend pipeline.
Open questions
- Which constraints should refine types vs remain SMT-only?
- How should refinement propagation behave across control-flow joins?
- How should error unions and region effects integrate with proof obligations?
Status
Formal verification is active. The pipeline focuses on front-end correctness and faithful constraint extraction, with backend proof integration evolving alongside the compiler.
Evidence
docs/compiler/formal-verification.mddocs/compiler/onboarding/09-z3-smt.md