Designing Assertions
Design high-signal invariants and map them to precise triggers before writing any Solidity.
Meta-Cognitive Protocol
Adopt the role of a Meta-Cognitive Reasoning Expert.
For every complex problem:
1.DECOMPOSE: Break into sub-problems
2.SOLVE: Address each with explicit confidence (0.0-1.0)
3.VERIFY: Check logic, facts, completeness, bias
4.SYNTHESIZE: Combine using weighted confidence
5.REFLECT: If confidence <0.8, identify weakness and retry
For simple questions, skip to direct answer.
Always output:
∙Clear answer
∙Confidence level
∙Key caveats
When to Use
- Starting a new assertion suite for a protocol or contract.
- Turning protocol rules into enforceable pre/post invariants.
- Choosing between call, storage, or balance triggers.
When NOT to Use
- You need to discover invariants from scratch. Use
mapping-invariants.
- You only need cheatcode syntax or implementation details. Use
implementing-assertions.
- You only need test harness patterns. Use
testing-assertions.
- You are doing a general security review without writing assertions.
Quick Start
- Identify assets, roles, and trust boundaries.
- List state transitions that can violate safety properties.
- Express invariants as pre/post comparisons or event-accounting rules.
- Select data sources (state, logs, call inputs, storage slots).
- Choose minimal triggers that cover all violating paths.
- Decide whether the invariant needs call-frame checks (
forkPreCall/forkPostCall) or only tx-level checks.
Workflow
- Build a protocol map: key contracts, roles, assets, mutable state.
- Draft invariants in plain language and math form.
- Identify legitimate exceptions in specs/audits and encode them explicitly (events/logs are often the signal).
- Decide if the invariant is transaction-scoped (pre/post) or call-scoped (per call id).
- Choose enforcement location (per-contract vs chokepoint) based on call routing.
- Flag upgradeability/proxy entrypoints and token integration assumptions.
- Pick observation strategy:
- State comparisons for monotonicity and conservation.
- Event-based accounting when internal state is opaque.
- Call input parsing for authorization or parameter bounds.
- Map to triggers with the smallest blast radius.
- For calldata-keyed invariants (timelock queues, executableAt[msg.data]), plan how to rebuild calldata from selector + args.
- Group invariants into multiple assertion contracts when needed to avoid
CreateContractSizeLimit.
- Enumerate edge cases (zero supply, empty vaults, proxy upgrades, nested batches).
Rationalizations to Reject
- "Trigger on any call; it is simpler." This risks gas-limit reverts and false drops.
- "Post-state is enough." Many invariants need pre/post deltas.
- "Ignore batch or nested calls." Real protocols use them heavily.
- "We can skip edge cases like zero supply." These are common sources of false positives.
Deliverable
- Invariant spec with: definition, data sources, trigger list, and edge cases.
- A candidate list of assertion functions with one invariant per function.
References
- Invariant Patterns
- Trigger Mapping Guide
1---2name: designing-assertions3description: Phylax Credible Layer assertions design. Designs invariants and trigger mapping for phylax/credible layer assertions.4---5
6# Designing Assertions
7
8Design high-signal invariants and map them to precise triggers before writing any Solidity.
9
10## Meta-Cognitive Protocol
11Adopt the role of a Meta-Cognitive Reasoning Expert.
12
13For every complex problem:
141.DECOMPOSE: Break into sub-problems
152.SOLVE: Address each with explicit confidence (0.0-1.0)
163.VERIFY: Check logic, facts, completeness, bias
174.SYNTHESIZE: Combine using weighted confidence
185.REFLECT: If confidence <0.8, identify weakness and retry
19For simple questions, skip to direct answer.
20
21Always output:
22∙Clear answer
23∙Confidence level
24∙Key caveats
25
26## When to Use
27- Starting a new assertion suite for a protocol or contract.
28- Turning protocol rules into enforceable pre/post invariants.
29- Choosing between call, storage, or balance triggers.
30
31## When NOT to Use
32- You need to discover invariants from scratch. Use `mapping-invariants`.
33- You only need cheatcode syntax or implementation details. Use `implementing-assertions`.
34- You only need test harness patterns. Use `testing-assertions`.
35- You are doing a general security review without writing assertions.
36
37## Quick Start
381. Identify assets, roles, and trust boundaries.
392. List state transitions that can violate safety properties.
403. Express invariants as pre/post comparisons or event-accounting rules.
414. Select data sources (state, logs, call inputs, storage slots).
425. Choose minimal triggers that cover all violating paths.
436. Decide whether the invariant needs call-frame checks (`forkPreCall`/`forkPostCall`) or only tx-level checks.
44
45## Workflow
46- Build a protocol map: key contracts, roles, assets, mutable state.
47- Draft invariants in plain language and math form.
48- Identify legitimate exceptions in specs/audits and encode them explicitly (events/logs are often the signal).
49- Decide if the invariant is transaction-scoped (pre/post) or call-scoped (per call id).
50- Choose enforcement location (per-contract vs chokepoint) based on call routing.
51- Flag upgradeability/proxy entrypoints and token integration assumptions.
52- Pick observation strategy:
53 - State comparisons for monotonicity and conservation.
54 - Event-based accounting when internal state is opaque.
55 - Call input parsing for authorization or parameter bounds.
56- Map to triggers with the smallest blast radius.
57- For calldata-keyed invariants (timelock queues, executableAt[msg.data]), plan how to rebuild calldata from selector + args.
58- Group invariants into multiple assertion contracts when needed to avoid `CreateContractSizeLimit`.
59- Enumerate edge cases (zero supply, empty vaults, proxy upgrades, nested batches).
60
61## Rationalizations to Reject
62- "Trigger on any call; it is simpler." This risks gas-limit reverts and false drops.
63- "Post-state is enough." Many invariants need pre/post deltas.
64- "Ignore batch or nested calls." Real protocols use them heavily.
65- "We can skip edge cases like zero supply." These are common sources of false positives.
66
67## Deliverable
68- Invariant spec with: definition, data sources, trigger list, and edge cases.
69- A candidate list of assertion functions with one invariant per function.
70
71## References
72- [Invariant Patterns](references/invariant-patterns.md)
73- [Trigger Mapping Guide](references/trigger-mapping.md)