Skip to content

turinglabsorg/wachi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Wachi

"Who sent it? Where did it come from? Why is there a Tornado Cash withdrawal 27 minutes before a $12K exploit? Wachi knows."

Wachi is a blockchain transaction OSINT tool that runs as an MCP server. Point it at a suspicious transaction, and it will rip it apart — tracing fund flows, identifying every contract, profiling every address, and following the money all the way back to its origin chain.

Built in Rust with alloy-rs (the library that powers Foundry). No Etherscan API keys. No subgraph dependencies. Just raw RPC calls and pattern matching.

Why?

Because reading Etherscan tabs manually is a war crime. Because copy-pasting addresses between explorer windows is not "investigation". Because the attacker used Tornado Cash and a cross-chain bridge and you shouldn't have to be a detective to figure that out.

Wachi turns a transaction hash into a full forensic report in under 30 seconds.

Install

cargo build --release

That's it. The binary is at ./target/release/wachi.

Config

Create ~/.wachi/config.toml with your Alchemy key (recommended for trace support and funding analysis):

[rpc_overrides]
arb = "https://arb-mainnet.g.alchemy.com/v2/YOUR_KEY"
eth = "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY"
base = "https://base-mainnet.g.alchemy.com/v2/YOUR_KEY"
opt = "https://opt-mainnet.g.alchemy.com/v2/YOUR_KEY"

Without Alchemy, basic analysis still works (public RPCs). You just won't get internal ETH traces or funding origin tracing.

Tools

Wachi exposes 6 MCP tools:

Tool What it does
wachi_analyze_tx Transaction basics — from, to, value, gas, status, timestamp
wachi_fund_flow All ERC20 transfers + optional internal ETH traces
wachi_contracts Contract vs EOA identification, EIP-1967 proxy detection
wachi_address_analysis Balances, nonces, roles for every address in the tx
wachi_trace_funding Recursive funding origin tracing with cross-chain support
wachi_list_tasks List all investigation folders

Supported Chains

Prefix Chain
arb Arbitrum One
eth Ethereum
base Base
opt Optimism

Transaction format: chain:0xhash (e.g. arb:0x2c83533c...)

How It Works

Each investigation gets its own folder under ~/.wachi/tasks/. Tools read and write JSON files there, building up intelligence incrementally. Run them in any order — each one enriches the next.

~/.wachi/tasks/arb_2c83533c.../
├── tx_info.json         ← wachi_analyze_tx
├── fund_flow.json       ← wachi_fund_flow
├── contracts.json       ← wachi_contracts
├── addresses.json       ← wachi_address_analysis
├── funding_tree.json    ← wachi_trace_funding
└── REPORT.md            ← final synthesized analysis

Example: Real Exploit Investigation

Here's what Wachi produces when pointed at an actual DeFi exploit — a Factor Protocol vault drain on Arbitrum (tx):

Transaction Info

{
  "chain": "Arbitrum One",
  "tx_hash": "0x2c83533c9b76010704b6a93032df03c2e6310349e08ebd53c42d02a1ba474b57",
  "block_number": 420639416,
  "timestamp": "2026-01-12 16:47:12 UTC",
  "from": "0x4e42188ef2221f55ef9f25d55d5a4502dd468de6",
  "to": "0x5362133b027a4dc7be6530c36d6658f18b24c537",
  "value_eth": "0.000000000000000000",
  "gas_used": 3720245,
  "method_id": "0x215c0c02",
  "status": "success",
  "log_count": 117
}

Fund Flow (46 ERC20 transfers, 2 internal ETH transfers)

{
  "summary": {
    "total_erc20_transfers": 46,
    "unique_tokens": 13,
    "unique_addresses": 15,
    "has_internal_transfers": true
  },
  "internal_transfers": [
    {
      "from": "0x82af49447d8a07e3bd95bd0d56f35241523fbab1",
      "to": "0x5362133b027a4dc7be6530c36d6658f18b24c537",
      "value_eth": "3.920211004002749376",
      "call_type": "CALL"
    },
    {
      "from": "0x5362133b027a4dc7be6530c36d6658f18b24c537",
      "to": "0x4e42188ef2221f55ef9f25d55d5a4502dd468de6",
      "value_eth": "3.920211004002749376",
      "call_type": "CALL"
    }
  ]
}

Contracts (22 addresses, 20 contracts, 2 EOAs)

{
  "summary": {
    "total_addresses": 22,
    "contracts": 20,
    "eoas": 2,
    "proxies": 0
  }
}

Funding Origin Tree

{
  "target_address": "0x4e42188ef2221f55ef9f25d55d5a4502dd468de6",
  "starting_chain": "Ethereum",
  "tree": {
    "address": "0x4e42188ef2221f55ef9f25d55d5a4502dd468de6",
    "chain": "Ethereum",
    "is_contract": false,
    "incoming_transfers": [
      {
        "from": "0x12d66f87a04a9e220743712ce6d9bb1b5616b8fc",
        "value": 0.09787125813515,
        "asset": "ETH",
        "category": "internal",
        "timestamp": "2026-01-12T16:20:47.000Z"
      }
    ],
    "outgoing_transfers": [
      {
        "to": "0x1231deb6f5749ef6ce6943a275a1d3e7486f4eae",
        "value": 0.09,
        "asset": "ETH",
        "category": "external",
        "timestamp": "2026-01-12T16:27:11.000Z"
      }
    ],
    "children": [
      {
        "address": "0x12d66f87a04a9e220743712ce6d9bb1b5616b8fc",
        "label": "Tornado Cash (0.1 ETH)",
        "is_contract": true,
        "children": []
      }
    ]
  },
  "summary": {
    "funding_sources": [
      {
        "address": "0x12d66f87a04a9e220743712ce6d9bb1b5616b8fc",
        "label": "Tornado Cash (0.1 ETH)",
        "total_eth_sent": 0.09787125813515,
        "transfer_count": 1
      }
    ]
  }
}

Final Report (synthesized by the LLM)

The tools above feed into a single REPORT.md — a complete forensic narrative:

Tornado Cash (0.1 ETH) ──→ Attacker EOA ──→ LiFi Bridge ──→ Arbitrum
                                                               │
                                            ┌──────────────────┘
                                            ▼
                                    Attack Contract
                                    (Morpho flash loan 5 WETH)
                                            │
                          ┌─────────┬───────┴───────┬──────────┐
                          ▼         ▼               ▼          ▼
                       FPS023    FPS020          FPS022      FPS033
                      (wstETH)  (USDC)          (USDT)      (WETH)
                      3.9 wst   $2,941          $2,803      1.4 WETH
                          │         │               │          │
                          └─────────┴───────┬───────┴──────────┘
                                            ▼
                                    Swap all → WETH
                                    Repay 5 WETH flash loan
                                    Unwrap 3.92 WETH → ETH
                                            │
                                            ▼
                                    Attacker: +3.92 ETH profit

Total damage: ~3.92 ETH (~$12,000). Total investment by the attacker: 0.09 ETH in gas money from a mixer.

Using with Claude Code / LLM Agents

See CLAUDE.md for agent instructions and SKILL.md for the investigation playbook.

The typical workflow: spawn parallel agents → each runs one wachi tool → main LLM reads all results → writes REPORT.md.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages