InvariantChecker
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:
- Expose a
bool-returningviewon your protocol (e.g.isSolvent()returningbacking >= liabilities). - Governance (
DEFAULT_ADMIN_ROLE) calls registerInvariant with a key, the target contract, and that view's selector. - Gate sensitive operations on checkInvariant / checkInvariants; they
staticcallthe registered view and revert (InvariantViolatedError) if it returnsfalse, 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. Seetest/unit/InvariantCheckerUsageTest.t.solfor 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
| Name | Type | Description |
|---|---|---|
| key | bytes32 | The invariant key to query. |
Returns
| Name | Type | Description |
|---|---|---|
| target | address | The contract address to call. |
| selector | bytes4 | The 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
| Name | Type | Description |
|---|---|---|
| key | bytes32 | The invariant key. |
| target | address | The contract address to call (must not be address(0)). |
| selector | bytes4 | The 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
| Name | Type | Description |
|---|---|---|
| key | bytes32 | The 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
| Name | Type | Description |
|---|---|---|
| key | bytes32 | The invariant key to check. |
checkInvariants
Checks multiple invariants in order, reverting on the first failure.
function checkInvariants(bytes32[] calldata keys) public view virtual;Parameters
| Name | Type | Description |
|---|---|---|
| keys | bytes32[] | 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
| Name | Type | Description |
|---|---|---|
| selectors | bytes |