Testing Methodology
On this page
Testing covers individual functions, series lifecycles and accounting properties. The tables distinguish recorded suites from coverage targets; they do not certify the current deployment or replace an external contract review.
Toolchain
fact
| Item | Value |
|---|---|
| Framework | Foundry (forge 1.8.x) |
| Compiler | Solidity 0.8.28, optimiser on (200 runs), via_ir = false, EVM cancun |
| Dependencies | OpenZeppelin Contracts v5.1.0 |
| Formatting and lint | forge fmt (120 columns), forge lint with a documented exclusion list |
| Default profile | fuzz 2,048 runs; invariant 512 runs × depth 64, fail_on_revert = false |
| CI profile | fuzz 50,000 runs; invariant 5,000 runs × depth 64 |
| Lite profile | fuzz 64; invariant 16 × 16, for fast local iteration |
| Coverage target | ≥ 95% line and branch on src/ excluding mocks and interfaces |
Test Layers
| Layer | Location | Purpose | Status |
|---|---|---|---|
| Unit | test/unit/core, test/unit/token | Every external function, every revert path, every event, with exact expected values | present |
| Lifecycle | test/unit/core/NoteCore.Lifecycle.t.sol | End-to-end series scenarios: autocall, hold to maturity, breach with physical settlement, cancellation, deferral, refunds, transfers mid-life | present |
| Calendar | test/unit/core/MarketCalendar.t.sol | DST boundaries 2026 to 2030, holidays, early closes, isOfficialClose for every weekday close of a year | present |
| Oracle | test/unit/core/OracleAdapter.t.sol | Round walk-back, window bounds, backup deviation, deferral, force and cancel paths | present |
| Fuzz | test/fuzz/core (CalendarMath, Matching, Oracle, Settlement), test/fuzz/token (ExpMath, RevenueRouter) | Property tests over prices, notionals, decimals, timestamps and rounding; 40 testFuzz_* functions | present |
| Invariant | test/invariant/core, test/invariant/token, test/invariant/governance | Handler-based stateful fuzzing: 8 core (+1 reachability), 19 token and 13 governance invariant functions; the core handler includes a lazyCrank action | present |
| Automation | test/unit/automation, test/unit/core/NoteCore.LazyCrank.t.sol, test/fuzz/automation | RollPolicy (22), NoteAutomation (20), lazy crank / seriesCreator / dueWork (27) and roll-date fuzz (2) | present |
Status reflects the repository at the time these pages were written and is updated as suites land.
Unit Conventions
- Tests use the mocks in
src/mocks:MockUSDG(6 decimals),MockStockToken(18 decimals,uiMultiplierandbalanceOfUIexposed, raw balances unchanged),MockAggregatorV3(8 decimals, arbitrary round history, negative and stale answers),MockFeeSink. - Time is advanced with
vm.warpto exact official close timestamps; no test relies on “now”. - Every test that moves value asserts balances of all parties before and after, and asserts the escrow identity via
getSeriesandaccountingviews. - Events are asserted with
vm.expectEmitincluding indexed parameters.
Fuzz Properties
fact Present in test/fuzz: matching and requiredPrefund bounds, coupon index conservation across transfers, physical settlement within one wei and quoteToStock sum bound, civil-date round trips, day-of-week sequencing, DST rule, official-close and holiday/early-close logic, mulDivUp, bps bounds, WAD round trips, clamp, deviation symmetry, oracle walk-back, walk limit, answer validation, backup deviation and fallback, force timing, ExpMath decay bounds and monotonicity, router floor and current price bounds, previewSell rounding, sell accounting and sync split.
target Target property list:
- Coupon discovery:
floor ≤ couponBps ≤ capfor allrefBps,S,D. - Matching:
N ≤ min(D, S, notionalCap, prefundCapacity)andstockMatched × s0 / 1e8 ≥ N(rounded up). - Physical settlement:
redeem(units)deliversunits × 1e12 × 1e8 / s0wei within one wei, and the sum over all holders never exceedsstockMatched. - Coupon index: sum of
accruedover all holders never exceedscouponPool. - Oracle:
observenever returns a round withupdatedAt > closeTsor< closeTs − maxPreCloseLag, and returns the same round whenever it is called after the grace (reference model in the fuzz suite; 10,000 differential vectors against the Python model). - Calendar:
isOfficialClose(officialCloseOf(d)) == truefor every trading day; DST transitions match the pinned dates. - ExpMath:
halfLifeDecayWad(t, h)within 1e-9 relative error of a reference fort/h ∈ [0, 64]; equals0.5e18att = h. - Treasury:
previewRedeemmonotone innoteAmount; floor non-decreasing after any redemption. - sNOTE: share price non-decreasing across any sequence of deposit, notify, warp, request, redeem.
Coverage
forge coverage --report lcov in CI; threshold enforced at 95% for src/core, src/oracle, src/token, src/libraries. Mocks and interfaces are excluded.
Static Analysis
See Static analysis.
Formal Verification
Properties proved for all inputs by symbolic execution, the compiler’s model checker and integer proofs, with the open ones listed, are in Formal verification.
Reviews and Audits
Internal security review completed by the build team (reports under audit/ in the repository; full test run at the reviewed commit: 77 suites, 900 passed, 0 failed, 1 skipped). The external front-end review is complete and published; the structured-note contract review is in progress, not complete. See Audits.
Keep exploring, or revisit this topic from the navigation.