Static analysis
fact forge lint runs with the exclusion list in foundry.toml. Each excluded lint is documented with a reason (for example block-timestamp is excluded because the protocol’s logic is defined in terms of timestamps by design, and calls-loop because the upkeep loops in NoteAutomation.checkUpkeep are bounded by maxSeriesPerCheck and the number of templates, and Treasury/Desk asset loops by governance-set lists).
fact Slither, Aderyn and forge lint outputs from the internal security review are committed under audit/static-analysis/ and audit/sale/ with dated file names, and triaged in audit/static-analysis.md (0 true positives at the reviewed commit; every accepted pattern is listed with its reason).
planned The following are part of the specified CI pipeline and will be enabled as the repository matures:
| Tool | Scope | Policy |
|---|---|---|
| Slither | All of src/ | High and medium findings fail CI unless triaged with an inline justification |
| Aderyn | All of src/ | Report attached to each release |
forge build --sizes | Contract sizes | Fail if any contract exceeds 24 KiB |
forge fmt --check | Formatting | Fail on diff |
forge coverage | Coverage | Fail below 95% on non-mock sources |
Known accepted patterns
Section titled “Known accepted patterns”| Pattern | Where | Reason |
|---|---|---|
| Reentrancy via ERC-1155 hook | NoteLegs → NoteCore.onLegTransfer | Required for coupon accounting on transfer; guarded and unit-tested |
| Timestamp comparisons | NoteCore, OracleAdapter, Treasury, sNOTE | Protocol semantics are calendar-based |
Unbounded loop over assetList | Treasury.reserveValueQuote | Asset list is governance-controlled and small; documented gas bound |
| Division before multiplication | FixedPointMath WAD helpers | Uses mulDiv with explicit rounding direction |
Reporting
Section titled “Reporting”Static analysis reports for tagged releases will be published in the repository under contracts/reports/. Nothing has been published yet.