Ethereum Address Poisoning Attack Detection
Poison-Hunter detects address poisoning attacks on Ethereum, a phishing technique where attackers send dust/zero-value transactions from lookalike addresses to contaminate victims' transaction history.
- Attacker monitors the blockchain for high-value transfers
- Generates an address similar to the victim's frequent contact (matching first/last characters)
- Sends a dust (0 < value < 1) or zero-value transfer to the victim
- Victim copies the fake address from their transaction history
- Victim sends funds to the attacker's address
flowchart TD
A[Collect Transfer Logs] --> B[Classify Transfers]
B --> C{Value Check}
C -->|value >= threshold| D[Legitimate]
C -->|0 < value < threshold| E[Suspicious: DUST]
C -->|value == 0 && sender != from| F[Suspicious: ZERO]
D --> G[Match Phishing Pairs]
E --> G
F --> G
G --> H{Similar Address?}
H -->|score >= 4| I[Phishing Pair Detected]
H -->|score < 4| J[Not Phishing]
I --> K[Extract Entities]
K --> L[Phishing Addresses]
K --> M[Funding Addresses]
K --> N[Batching Contracts]
Bidirectional comparison matching characters from both ends:
- Matching both ends: +2 points
- Matching left only: +1 point
- Matching right only: +1 point
- No match: stop
Similar character pairs (visually confusing):
0↔O,1↔l/I,6↔b,8↔B,5↔S
# Clone the repository
git clone https://github.com/your-org/poison-hunter.git
cd poison-hunter
# Install in development mode
pip install -e .
# Or with development dependencies
pip install -e ".[dev]"- Python 3.10+
- Ethereum RPC endpoint (Alchemy, Infura, or local node)
# Set your RPC endpoint
export ETH_RPC_URL="https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY"
# 1. Collect Transfer logs
poison-hunter collect --from-block 18000000 --to-block 18010000 --tokens usdc,usdt
# 2. Analyze and classify transfers
poison-hunter analyze --input data/transfers.parquet
# 3. Filter and match phishing pairs
poison-hunter filter --legit data/analyzed/legitimate.parquet --susp data/analyzed/suspicious.parquet
# 4. Extract phishing entities
poison-hunter extract --pairs data/phishing/phishing_pairs.parquet --susp data/analyzed/suspicious.parquetCollect ERC-20 Transfer logs from Ethereum.
poison-hunter collect [OPTIONS]| Option | Type | Default | Description |
|---|---|---|---|
--from-block |
INT | 14880000 | Start block number |
--to-block |
INT | 19350000 | End block number |
--tokens |
TEXT | usdc,usdt | Comma-separated token names |
--out |
PATH | data | Output directory |
--chunk-size |
INT | 5000 | Blocks per RPC request |
--verbose / -v |
FLAG | - | Enable debug logging |
--dry-run |
FLAG | - | Show what would be done |
Classify transfers as legitimate or suspicious.
poison-hunter analyze [OPTIONS]| Option | Type | Default | Description |
|---|---|---|---|
--input |
PATH | required | Input transfers Parquet file |
--out |
PATH | data/analyzed | Output directory |
--dust-threshold |
FLOAT | 1.0 | Dust threshold in token units |
--verbose / -v |
FLAG | - | Enable debug logging |
Find phishing pairs by matching suspicious transfers to legitimate ones.
poison-hunter filter [OPTIONS]| Option | Type | Default | Description |
|---|---|---|---|
--legit |
PATH | required | Legitimate transfers Parquet file |
--susp |
PATH | required | Suspicious transfers Parquet file |
--out |
PATH | data/phishing | Output directory |
--similarity-threshold |
INT | 4 | Minimum similarity score |
--verbose / -v |
FLAG | - | Enable debug logging |
Extract phishing, funding, and batching entities.
poison-hunter extract [OPTIONS]| Option | Type | Default | Description |
|---|---|---|---|
--pairs |
PATH | required | Phishing pairs Parquet file |
--susp |
PATH | - | Suspicious transfers (for funding/batching) |
--out |
PATH | data/output | Output directory |
--verbose / -v |
FLAG | - | Enable debug logging |
Compute similarity score between two addresses.
poison-hunter similarity --addr1 0x... --addr2 0x...| Variable | Description | Default |
|---|---|---|
ETH_RPC_URL |
Ethereum RPC endpoint | Alchemy demo |
RPC_REQUESTS_PER_SECOND |
Rate limit | 10 |
RPC_MAX_RETRIES |
Max retry attempts | 5 |
RPC_TIMEOUT |
Request timeout (seconds) | 30 |
DATA_DIR |
Data directory | ./data |
data/
├── transfers.parquet # Raw Transfer logs
├── analyzed/
│ ├── legitimate.parquet # Normal transfers
│ └── suspicious.parquet # DUST/ZERO transfers
├── phishing/
│ └── phishing_pairs.parquet # Matched phishing pairs
└── output/
├── phishing_addresses.parquet
├── funding_addresses.parquet
└── batching_contracts.parquet
MIT License