Skip to content
Lattice

InvariantChecker

Git Source

Inherits: IInvariantChecker

Title: InvariantChecker

Thin Diamond facet that exposes a registry of named on-chain invariants.

All logic lives in InvariantCheckerLib. This contract is stateless and forwards every call to the library. Inherit this in your Diamond facet to add invariant checking.

Opt-in safety facet. Lattice ships no default invariants because it ships no protocol of its own — the checker is a generic primitive that consumers wire to their invariants. The pattern is:

  1. Expose a bool-returning view on your protocol (e.g. isSolvent() returning backing >= liabilities).
  2. Governance (DEFAULT_ADMIN_ROLE) calls registerInvariant with a key, the target contract, and that view's selector.
  3. Gate sensitive operations on checkInvariant / checkInvariants; they staticcall the registered view and revert (InvariantViolatedError) if it returns false, or (InvariantCheckFailed) if the call itself reverts. The check tracks live state — it is not a one-shot latch — so the gate re-opens once the invariant holds again. See test/unit/InvariantCheckerUsageTest.t.sol for the canonical worked example (a solvency invariant: registration, happy path, violation path, batch).

Notes:

  • lattice-version: 0.1.0
  • lattice-source: Lattice original

Functions

getInvariant

Returns the target address and function selector registered for key.

function getInvariant(bytes32 key) public view virtual returns (address target, bytes4 selector);

Parameters

NameTypeDescription
keybytes32The invariant key to query.

Returns

NameTypeDescription
targetaddressThe contract address to call.
selectorbytes4The function selector to invoke.

registerInvariant

Registers or updates an invariant.

Requires DEFAULT_ADMIN_ROLE. Reverts if target == address(0). Emits InvariantRegistered.

function registerInvariant(bytes32 key, address target, bytes4 selector) public virtual;

Parameters

NameTypeDescription
keybytes32The invariant key.
targetaddressThe contract address to call (must not be address(0)).
selectorbytes4The function selector to invoke (must return a bool).

unregisterInvariant

Removes a registered invariant.

Requires DEFAULT_ADMIN_ROLE. Reverts with InvariantNotRegistered if key is not registered. Emits InvariantUnregistered.

function unregisterInvariant(bytes32 key) public virtual;

Parameters

NameTypeDescription
keybytes32The invariant key to remove.

checkInvariant

Performs the staticcall check for key and reverts on violation or call failure.

Reverts with InvariantNotRegistered if the key is unregistered. Reverts with InvariantViolatedError if the call returns false. Reverts with InvariantCheckFailed if the staticcall reverts.

function checkInvariant(bytes32 key) public view virtual;

Parameters

NameTypeDescription
keybytes32The invariant key to check.

checkInvariants

Checks multiple invariants in order, reverting on the first failure.

function checkInvariants(bytes32[] calldata keys) public view virtual;

Parameters

NameTypeDescription
keysbytes32[]The array of invariant keys to check sequentially.

exportSelectors

ERC-8153 selector export: this facet's cuttable selectors, tightly packed (4 bytes each).

Excludes exportSelectors() itself (0x0ef22643) - it is never cut into a diamond. Order matches forge inspect InvariantChecker methodIdentifiers (alphabetical by signature); kept in exact parity by ExportSelectorsParityTest. Chunks: checkInvariant(bytes32) 0x165d31f6 checkInvariants(bytes32[]) 0x2e8019f1 getInvariant(bytes32) 0x0b0ab5fe registerInvariant(bytes32,address,bytes4) 0x848a35dd unregisterInvariant(bytes32) 0x93bee676

function exportSelectors() external pure virtual returns (bytes memory selectors);

Returns

NameTypeDescription
selectorsbytes