A professional, production‑grade tool for auditing blockchains for wash trading and fake volume generated by bots. Supports 20+ blockchains and major DEXes (Uniswap V2/V3, PancakeSwap, Sushiswap, Curve, Balancer, TraderJoe, QuickSwap, Velodrome, Aerodrome, SyncSwap, and more).
- Multi‑chain & Multi‑DEX – instant support for Ethereum, BSC, Polygon, Arbitrum, Optimism, Base, Avalanche, Fantom, Celo, Gnosis, Moonbeam, Aurora, Harmony, Cronos, Metis, Boba, zkSync Era, Polygon zkEVM, Linea, Scroll, Mantle, Kava, Klaytn.
- Heuristic Detection with near‑zero false positives:
- Self‑trading (same sender/recipient)
- Circular trading (strongly connected components)
- Position‑neutral SCC analysis (Victor & Weintraud, WWW '21) – multi‑window zero‑net‑position detection
- Closed‑cluster detection – volume‑balanced collusive trading rings (network‑based, 2025 research)
- Repeated‑amount fingerprinting – senders recycling identical trade sizes
- High‑frequency bot patterns (allow‑listable via
BOT_ALLOWLIST, thresholds configurable) - Volume anomaly detection (MAD/IQR/z‑score, method and threshold configurable)
- Entity clustering via on‑chain funding traces (uses
trace_filteror block scanning)
- Machine Learning – Isolation Forest on 21 features incl. Benford's‑law deviation, amount roundness and hour‑of‑day entropy, with per‑pool contamination control and feature explainability.
- Quantified Reporting – wash volume in USD, per‑method breakdown, severity grading (
MINIMAL→CRITICAL). - Web Panel – built‑in dashboard at
/panel: global statistics, per‑method wash‑volume charts, pool inspector, live monitor feed and audit controls; session‑cookie login backed by the API‑key system, dark/light theme, zero external assets. - REST API + WebSocket streaming –
wash-apiserves on‑demand audits, risk reports and live streaming detection over websockets; hardened with hashed API‑key auth, per‑IP rate limiting and security headers (see docs/api.md). - Real‑time Monitoring – HTTP‑based listeners with circuit breaker protection.
- Full Audit Reports – JSON/CSV export.
- Production‑Ready – Retry logic, rate limiting, circuit breaker, graceful shutdown, input validation, SSL/TLS enforcement.
git clone https://github.com/Yog-Sotho/Wash-Trade-Scanner.git
cd Wash-Trade-Scanner
python -m venv venv
source venv/bin/activate # or venv\Scripts\activate on Windows
pip install -e ".[dev]"
Copy .env.example to .env and fill in your RPC endpoints (at least one per chain you want to scan). Database configuration is required via separate secure parameters:
DATABASE_HOST,DATABASE_NAME,DATABASE_USER,DATABASE_PASSWORDDATABASE_SSL_MODEdefaults torequire
See .env.example for full reference.
docker run -d --name wash_detector_db \
-e POSTGRES_USER=wash_user \
-e POSTGRES_PASSWORD=wash_pass \
-e POSTGRES_DB=wash_detector \
-p 5432:5432 postgres:15-alpine
Then initialise the tables:
python -c "from core.storage import Storage; import asyncio; asyncio.run(Storage().initialize())"
python scripts/run_audit.py \
--chain-id 1 \
--pool 0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc \
--start-block 18000000 \
--end-block 19000000 \
--export json
Addresses are checksum‑validated. Block ranges are limited to 10M spans maximum.
For more options:
python scripts/run_audit.py --help
python scripts/train_model.py --chain-id 1 --pools 0x... 0x...
All settings are in .env (see .env.example). Important variables:
DATABASE_HOST,DATABASE_PORT,DATABASE_NAME,DATABASE_USER,DATABASE_PASSWORD– PostgreSQL connection parameters (async, SSL enforced)DATABASE_SSL_MODE–require(default),verify-ca,verify-fullBOT_ALLOWLIST– comma‑separated addresses to skip in high‑frequency bot detectionETH_RPC_URL,BSC_RPC_URL, … – RPC endpoints per chain (placeholders rejected at startup)VOLUME_ANOMALY_METHOD–mad(default),iqr, orzscoreVOLUME_ANOMALY_THRESHOLD– default 3.5 for MAD/IQRRPC_MAX_FAILURES/RPC_RECOVERY_TIMEOUT– circuit breaker configuration
Full reference: see docs/configuration.md.
The detection stack layers fast pairwise heuristics, research‑grade graph analysis, statistical fingerprinting, and ML anomaly detection. Every detector assigns a per‑trade confidence score; when several detectors hit the same trade, the highest‑confidence label wins.
- Self‑Trading:
sender == recipient⇒ instant wash trade (score 1.0). - Circular Trading: Strongly Connected Components in the trade graph with reverse trades within a configurable time window (score 0.9).
- High‑Frequency Bot: Configurable thresholds (default: >10 trades, average inter‑trade time < 60s, CV < 0.5). Bots in
BOT_ALLOWLISTare ignored. All thresholds tunable via environment (score 0.8). - Volume Anomaly: MAD (default) or IQR on log‑transformed trade volumes within configurable buckets. Z‑score available for backward compatibility. Threshold configurable in settings (score ≥ 0.7).
- Wash Clusters: Trades between addresses funded by the same source (requires
trace_filteror block scanning). Optional due to privacy implications (score 0.95).
- Position‑Neutral SCC (score 0.95): implements the method of Victor & Weintraud, Detecting and Quantifying Wash Trading on Decentralized Cryptocurrency Exchanges (WWW '21). Within each strongly connected component of the trade graph, multi‑pass time windows (default 1h / 24h / 7d,
POSITION_NEUTRAL_WINDOWS_HOURS) are scanned for trade sets in which every participant's net token position change is ≈ zero (withinPOSITION_NEUTRAL_MARGIN, default 1%) while gross volume is large — the legal definition of wash trading. - Closed Clusters (score 0.85): network‑based detection following 2025 research on collusive trading rings — wash traders form approximately closed clusters that seldom transact outside the ring. Volume‑weighted communities (greedy modularity) are flagged when their volume is ≥
CLOSED_CLUSTER_INTERNAL_RATIO(default 90%) internal and each member's internal in/out flow is balanced (CLOSED_CLUSTER_BALANCE_TOLERANCE), which separates recycling rings from organic directional flow. - Repeated Amounts (score 0.75): senders recycling the same trade size (rounded to
REPEATED_AMOUNT_SIG_FIGSsignificant digits) ≥REPEATED_AMOUNT_MIN_COUNTtimes — a volume‑bot fingerprint; organic flow almost never repeats exact sizes at scale.
- ML Isolation Forest: anomaly detection on 21 trade‑ and pool‑level features, including statistical fingerprints used by forensic platforms: Benford's‑law first‑digit deviation of pool amounts, amount roundness (significant‑digit count), and hour‑of‑day entropy (humans trade diurnally; wash bots trade uniformly around the clock). Per‑pool contamination control; feature explainability via
ML_EXPLAINABILITY=true.
Audit reports quantify wash activity, not just count it: wash volume in USD, wash‑volume ratio, a per‑method volume breakdown, and a severity grade (MINIMAL → CRITICAL) derived from the wash‑volume ratio.
config/ – chain and DEX configurations with validated RPC URLs
core/ – detection logic (ingestor, heuristics, ML, entity clustering, validators, circuit breaker)
models/ – database schemas
scripts/ – entry points (run_audit.py, train_model.py)
tests/ – pytest tests
docs/ – detailed documentation
- Installation
- Configuration Reference
- API & Real-Time Monitoring
- Architecture Overview
- Security Guide
pytest tests/ -v --cov=core --cov-report=html --cov-fail-under=80
- Input validation via Pydantic (checksum addresses, block ranges, chain IDs)
- Circuit breaker for RPC resilience
- Database SSL/TLS enforcement
- Secret scanning and dependency audit in CI
- See
docs/security.mdfor full details
Start the API (binds 127.0.0.1:8000 by default):
wash-api
Open the dashboard at http://127.0.0.1:8000/panel — statistics, charts,
pool inspection, live monitoring and audit management in the browser.
Stream live detections for a pool over websocket:
/api/v1/ws/monitor/{chain_id}/{pool_address}
To expose the API beyond localhost you must enable authentication — generate
a key with wash-genkey, set API_AUTH_ENABLED=true and API_KEY_HASHES;
the server refuses to bind a public interface otherwise. Full reference:
docs/api.md.
Use --export json or --export csv to save audit results. A JSON summary file and a CSV metrics file will be created.
MIT
If you like my work, buy me a coffee ❤️ Yog-Sotho
