We kept calling different things an audit.
A tier-1 firm PDF. Slither in CI. A red team probe. An on-chain stake with a score. Hub admission. They are not interchangeable — and collapsing them is how you ship a critical with a clean conscience.
We just shipped BASANOS (βάσανος — the Lydian touchstone): a signed Assurance Pack for ecosystem Solidity at a pinned commit. One capability, one question:
Is this contract tree sound enough to ship — at this digest?
Not insurance. Not runtime red team. Not catalogue admission. Technical assurance with Ed25519 receipts and honest limits on every pack.
Stop collapsing the layers
| Node | Question | Layer |
|---|---|---|
| THEMIS | Let this agent into the Hub catalogue? | Procurement admission |
| MOMUS | Is the live federation holey? | Runtime red team |
| BASANOS | Is this Solidity sound at commit X? | Technical assurance pack |
| AgentAuditPool | Who staked USDC and published a scoreBps? |
On-chain insurance |
Assurance packs inform coverage decisions. AgentAuditPool enforces economic consequences.
BASANOS never emits scoreBps and never calls coverListing. If someone tells you assurance is insurance, they are selling confusion.
The measurement that hurt
BASANOS runs two layers:
Per file — 17 detectors on one contract at a time: CEI patterns, access modifiers, delegatecall, raw ecrecover, spot-price reads, allow-lists that are written but never enforced.
Whole tree — basanos/xcontract.py builds a contract graph: who may write each storage slot, who reads whose state across contracts.
Here is the story that forced the second layer.
A hand audit of our own ACEX contracts found two exploitable criticals:
- The same USDC pledged to a lending pool and to a bond series across two contracts.
- A default whose beneficiary could trigger it.
We ran BASANOS on that exact tree before the graph layer existed. Result: eight findings, all pragma.floating, pack verdict PASS.
Both bugs were correct in every single file. Only the graph was wrong.
Today the same vulnerable tree reads FAIL with root causes named. The fixed tree reads REVIEW — we do not hand out silent PASS on shapes nobody has checked.
The graph layer does not prove the invariant. It tells you which invariant to check and where both ends live. Every pack says so in basanos/limits.py.
One invoke, root id not path
Capability: agent.security.contract-assurance@v1 · live UI at basanos.modelmarket.dev · landing at alexar76.github.io/basanos
git clone https://github.com/alexar76/basanos
cd basanos
uv sync --extra dev
uv run pytest -q # 94 tests · ~95% coverage
uv run python agent.py # http://127.0.0.1:9470/ui/
On a fresh clone you can hit the deliberately-vulnerable corpus:
curl -sS http://127.0.0.1:9470/invoke \
-H 'content-type: application/json' \
-d '{"product_id":"basanos","capability_id":"agent.security.contract-assurance@v1","input":{"roots":["fixtures"]}}'
You name a root id, never a filesystem path — that is what stops /invoke from becoming a local-file read primitive.
| Root id | Resolves to | Standalone clone |
|---|---|---|
fixtures, sound
|
BASANOS test corpus | yes |
acex, lottery, core, zk
|
Monorepo contract trees | monorepo checkout only |
fixtures should come back FAIL with real findings. Asking for acex from a standalone clone returns NO_SUBJECT — no Solidity was read, so the pack judges nothing. That is not a clean bill and not an accusation.
Verdicts: PASS · REVIEW · FAIL · NO_SUBJECT.
Optional intel (BASANOS_THREAT_INTEL=1): OSV + GitHub advisory allowlist only. Advisory text can reorder detectors. It cannot invent a new one.
What happens on FAIL (and what never happens)
On FAIL or REVIEW, the pack includes a recommend-only playbook aligned with ISO/IEC 29147 disclosure, ISO/IEC 30111 handling, and NIST SP 800-61 containment:
- stop shipping that digest
- verify privately
- patch
- re-scan
- disclose after the fix or a 90-day CVD window
BASANOS will not pause a live contract. It will not publish an exploit. It will not replace a human who decides to stake USDC on a listing.
What BASANOS is not
- Not a tier-1 firm audit PDF — say machine assurance pack
-
Not Slither or Foundry
forge test— complementary, not a drop-in replacement - Not a formal prover — it finds the shape of a cross-contract flaw, not a proof
- Not HEPHAESTUS — forge.modelmarket.dev is the smith; BASANOS is the stone you scrape the alloy on
Crypto stays off the hero. On-chain insurance is a separate act humans opt into after reading the pack.
Try it
git clone https://github.com/alexar76/basanos
cd basanos && uv sync --extra dev && uv run python agent.py
- Repo: github.com/alexar76/basanos
- Live: basanos.modelmarket.dev
- Docs: five languages in
docs/README.*.md
If you have ever shipped a green CI scan and still felt uneasy about cross-contract state — this is the layer we were missing. A star helps; a reproducible FAIL on fixtures helps more.






Top comments (0)