Skip to main content

Invariant Specifications

Invariant specifications enable a user to check properties that should always hold. Invariants are declared in a special section of the [V] specification, marked by the inv tag (short for "invariant"). The invariant section itself contains a single [V] expression, written as follows:

inv: constraint

Semantically, an invariant specification is violated whenever the constraint is violated after executing any transaction.

Specifying a Target​

In some cases, users may wish to specify an invariant over a single contract or single transaction. This can be done with the following syntax:

inv: constraint over target

Here, over is a keyword that separates the target from the invariant constraint. This restricted invariant specification is violated whenever the constraint is violated after executing any transaction that matches target.

For example, with a contract c, a target of c.* would specify that the invariant should hold after executing any transaction within c. A target of c.foo(x) would specify that the condition need only hold after any execution of the foo(x) transaction. Note that the transaction parameter x could then be referenced by the constraint.

Temporal Equivalents​

All invariant specifications can be expressed as equivalent (but possibly more verbose) temporal properties. Specifically, the invariant con over target could be equivalently written as []!finished(target, !con) (replacing target with * for invariants with no specified target).