Mantle-specific and agent-context Slither detectors for TryAnneal
Project description
@tryanneal/detectors
Custom Slither detectors for Mantle and ERC-8004 agent-context exploits, plus a curated exploit-corpus matcher.
Install
pip install -e packages/detectors
Slither discovers the pack automatically via the slither_analyzer.plugin entry point. Once installed, slither contract.sol runs builtin detectors and TryAnneal detectors together.
Detectors (15 + 1 meta)
Agent-context (novel IP)
| Argument | Impact | Confidence | What it catches |
|---|---|---|---|
agent-reentrancy |
HIGH | HIGH | ERC-8004 agent A calls into agent B before completing state writes; B can re-enter A |
agent-callback-loop |
HIGH | MEDIUM | Agent callback handler mutates state without idempotency guard; repeated delivery re-credits |
Mantle-specific (Arsia)
| Argument | Impact | Confidence | What it catches |
|---|---|---|---|
calldata-bloat |
MEDIUM | HIGH | Functions whose FastLZ-estimated calldata makes L1 data fee dominate total cost |
operator-fee-outlier |
LOW | HIGH | Loops + heavy SSTOREs where Arsia operator fee component > 25% of total |
l1block-unchecked-read |
MEDIUM | MEDIUM | Reads L1Block predeploy without validating returned value |
arsia-anti-patterns |
MEDIUM | MEDIUM | Hardcoded pre-Arsia basefee floor, EigenDA refs, retired predeploys |
Exploit patterns (encode real historical + 2026 hacks)
| Argument | Impact | Confidence | Encoded incident |
|---|---|---|---|
single-dvn-verifier |
HIGH | HIGH | KelpDAO/LayerZero DVN drain (Apr 2026, ~$292M) — N≤2 verifier threshold |
donation-attack |
HIGH | MEDIUM | Euler-class ERC4626 share-price inflation (~$197M) |
init-unprotected |
HIGH | HIGH | Nomad-class initializer replay (~$190M) |
oracle-no-staleness |
MEDIUM | HIGH | Oracle reads without freshness check (Mango Markets ~$117M and many more) |
proxy-storage-collision |
HIGH | HIGH | EIP-1967 proxy with state vars colliding with implementation slots |
approval-abuse-arbitrary-call |
HIGH | HIGH | SwapNet/Li.Fi/SocketGateway class — user-supplied target+calldata in a contract that holds approvals (5+ corpus entries) |
signature-replay-bypass |
HIGH | HIGH | ecrecover/EIP-712 consumed without nonce or replay tracking (5+ corpus entries, $1.19B cumulative) |
amm-spot-oracle-dependency |
HIGH | MEDIUM | Prices derived from AMM getReserves/balanceOf with no TWAP (6+ corpus entries, $128.8M) |
vault-share-rounding |
HIGH | MEDIUM | Debt/vault share math without explicit rounding direction (Sonne/Onyx/zkLend class, 6+ entries, $92.9M) |
Meta
| Argument | Impact | Confidence | What it catches |
|---|---|---|---|
corpus-match |
MEDIUM | MEDIUM | TF-IDF cosine similarity ≥ 65% to any of 98 curated incidents — surfaces losses, threat actor, linked incident, chain. Falls back to Jaccard when scikit-learn is unavailable. |
Exploit corpus
tryanneal_detectors/corpus/patterns.json ships 98 vetted entries spanning $7.1B in real historical losses across 13 chains and 2020-2026 (one entry per unique incident — no double-counting). The file is generated by build_corpus.py from raw research dumps in tryanneal_detectors/corpus/research/ (see the research README for the discovery overview).
Each entry carries:
- Year, month, USD losses, category, vulnerability class
- A
code_signaturedescription for human review fingerprint_features— the feature set the Jaccard matcher compares against- A
recommended_fixand areference_urlto the canonical post-mortem
The CorpusMatch detector and the standalone tryanneal_detectors.corpus.matcher extract a fingerprint from any Solidity source and report matches above a configurable threshold (default 60%).
from tryanneal_detectors.corpus.matcher import find_matches
matches = find_matches(open("Vault.sol").read())
for m in matches:
print(f"{m.similarity*100:.0f}% — {m.name} — ${m.losses_usd:,} lost")
Tests
Two suites:
tests/test_corpus.py+tests/test_helpers.py— pure-Python, no Slither required. Exercises the matcher against fixtures and asserts canonical incidents come back at the expected similarity (11 tests).tests/test_detectors_smoke.py— end-to-end Slither integration. Each fixture is run through the actual detector and we assert the right argument fires. Auto-skips whenslither-analyzeris not installed.
cd packages/detectors
pip install -e .[dev]
pytest
CLI integration
The anneal audit CLI accepts:
anneal audit Vault.sol # default: builtin + tryanneal
anneal audit Vault.sol --detectors=tryanneal # only the custom pack
anneal audit Vault.sol --detectors=builtin # only stock Slither
Findings tagged with source: "tryanneal" get distinct rendering in the report. Corpus matches get the highlighted call-out:
⚠️ CORPUS MATCH (78% similar to known exploit)
KelpDAO LayerZero DVN Drain — 2026 — $292.0M lost
Lines 12-34 | Sources: tryanneal
Fix: Require N≥3 distinct DVN operators with independent infrastructure
Reference: https://blockaid.io/blog/...
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tryanneal_detectors-0.1.0.tar.gz.
File metadata
- Download URL: tryanneal_detectors-0.1.0.tar.gz
- Upload date:
- Size: 64.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8a43f4b9e05cc4e490fa8f7497882c1eafc25b48d71f3872de5f6c768d01f209
|
|
| MD5 |
a9615557bc10ab51d74c2be0aa1fae8e
|
|
| BLAKE2b-256 |
6e91fdba65b537905e27cacc226b5f9657a962c412ab01eab8d23fcf4b9c1cb0
|
File details
Details for the file tryanneal_detectors-0.1.0-py3-none-any.whl.
File metadata
- Download URL: tryanneal_detectors-0.1.0-py3-none-any.whl
- Upload date:
- Size: 70.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
383c9d1985e4f4e0e4b08e52000657b43663e4184af3097211b657818d9aff9b
|
|
| MD5 |
d0718abf4be173f165d6061396076da1
|
|
| BLAKE2b-256 |
c282848d65e921a27e74fdf911b1b23fc996f4688a86c2ac70e79aefa1af9d3b
|