An EVM transaction investigation skill for authorized defensive security research. It combines Tx2Poc's deterministic trace/state evidence collection with exploit-investigator's evidence ranking, non-exploit classification, and report review in one case directory.
Collect and validate one transaction directly from the repository root:
uv run python scripts/trace_tx.py \
--chain eth \
--tx 0x<transaction-hash> \
--output-dir cases/<case>
uv run python scripts/funds_flow.py \
--evidence-dir cases/<case>/evidence/<transaction-hash-without-0x> \
--chain ethereum
uv run python scripts/check_manifest.py cases/<case> \
--chain ethereum \
--tx-hash 0x<transaction-hash> \
--write-fixesThe Codex skill drives the Analyst/Validator stages described in SKILL.md; PoC generation remains an explicit follow-up request.
Investigation and validation run by default; a PoC is generated only when explicitly requested. All output is written under cases/<case>/:
manifest.json # Canonical index for transactions, contracts, roles, and classification
report.md # Template-checked public report
validation.json # Analyst/Validator results
evidence/<txhash>/raw/ # immutable transaction, receipt, block, and call-trace evidence
evidence/<txhash>/derived/ # summaries, selector candidates, context, and funds flow
contracts/<address>/ # Verified or confidence-labeled recovered source
poc/ # Foundry PoC, created after an explicit request
Requires Python 3.11+, uv, and Foundry. Set ALCHEMY_API_KEY in .env; ETHERSCAN_API_KEY is optional but improves source lookups.
cp .env.example .env
git submodule update --init --recursive
uv sync --frozen --group dev
uv run pytest
uv run ruff check .
uv run ruff format --check .
forge testEthereum, BSC, Arbitrum, Polygon, Optimism, Avalanche, Base, and Linea are supported by default. Chain aliases and native symbols come from one canonical table; --rpc-url is an explicit override. Metadata is queried at the evidence block, and lookup failure remains unknown rather than assuming 18 decimals.
Raw evidence is authoritative; derived summaries never satisfy a missing raw call trace. Geth callTracer, Parity/Erigon trace_replayTransaction, and flat trace_transaction responses are retained verbatim and normalized into canonical frames. Completed fetches write v2 artifact_meta.json with normalized block identity, backend, and SHA-256 digests; legacy caches are validated before migration. Selectors retain candidates, provenance, and confidence, while ambiguous signatures are not confidently decoded and verified ABI selectors use Ethereum Keccak. A transaction after index zero carries a same-block pre-state limitation. Funds flow is an observed event/call-value delta with neutral transaction-sender/root-target terminology, positive receiver candidates, gas, L2 fee, and non-standard-token limitations; value movement is counted only when receipt status proves success, and it is not an automatic final-wallet PnL claim. TAC bytecode submission is local by default; remote servers require explicit opt-in.
The setup script uses the repository-pinned forge-std commit. The shared Foundry profile defaults to Paris bytecode compatibility for historical forks; a case may override it when newer opcodes are part of the evidence. The operator remains responsible for authorization, RPC costs, and explorer limits; this project never submits on-chain transactions or publishes reports automatically.
- Deterministic scripts own the facts; AI handles semantic analysis and review.
- Evidence is fetched once and cached; the report and PoC share one manifest.
- Unverified source is inference-only and never overrides trace or verified source.
- No unauthenticated TAC HTTP service, oversized protocol interface library, protocol-specific math bundle, or social/PR automation is built in; add those as isolated, restricted modules only when needed.
MIT. See THIRD_PARTY_NOTICES.md for upstream sources and copyright information.