Fraud Detection & Manipulation Analysis for Prediction Markets
The wallet clustering system detects coordinated trading behavior on Polymarket by analyzing on-chain transaction patterns. It identifies suspicious clusters of wallets that may be engaging in market manipulation.
Bet data flows from Polymarket's CLOB API through our ingestion pipeline into the clustering analysis engine.
| Field | Type | Description |
|---|---|---|
id | string | Unique trade ID |
taker_address | string | Wallet placing the bet (primary for analysis) |
maker_address | string | Counterparty wallet |
market | string | Market/condition ID |
outcome | Yes/No | Bet outcome side |
size | string | Number of shares |
price | string | Price per share |
timestamp | number | Unix timestamp |
transaction_hash | string | On-chain tx hash |
The system detects 5 types of connections between wallets, each indicating different coordination patterns.
Same wallet funded both addresses. Tracks multi-hop funding chains up to N depth.
High Signal
Bets placed within 30 seconds of each other on the same market.
Strong Signal
Identical USD bet amounts (to the cent) across multiple bets.
Strong Signal
Jaccard index >= 0.3 on markets traded. Similar market selection patterns.
Moderate Signal
Correlation >= 0.7 on bet outcomes. Both win or lose together consistently.
Moderate Signal
Wallets are grouped into clusters using Union-Find (disjoint set) algorithm based on detected connections.
Each wallet and cluster is assigned a suspicion score (0-1) based on multiple indicators.
| Reason | Threshold | Weight |
|---|---|---|
abnormal_win_rate |
Cluster win rate > 70% | High |
high_coordination |
Many strong connections (> 5) | High |
funding_chain |
Multi-hop funding obscuration | High |
size_pattern |
Too-identical bet sizing (> 50% match) | Medium |
timing_coordination |
Avg timing delta < 30 seconds | Medium |
market_concentration |
Cluster dominates specific markets (> 30%) | Medium |
| Field | Description |
|---|---|
walletCount | Number of wallets in cluster |
suspicionScore | Aggregate score 0-1 |
suspicionReasons | Array of triggered reasons |
combinedWinRate | Cluster-wide win rate |
totalVolumeUsd | Total betting volume |
totalBets | Total number of bets |
topMarkets | Markets where cluster is most active |
avgBetTimingSeconds | Average timing between coordinated bets |
10 DSL primitives expose wallet clustering data to the Algorithm Builder.
| Primitive | Returns | Description |
|---|---|---|
polymarket_wallet_suspicion(address) |
number | Suspicion score for specific wallet (0-1) |
polymarket_cluster_size(address) |
number | Number of wallets in same cluster |
polymarket_wallet_win_rate(address) |
number | Historical win rate for wallet |
polymarket_is_flagged(address) |
boolean | True if wallet marked suspicious |
polymarket_connection_count(address) |
number | Number of connections to other wallets |
| Primitive | Returns | Description |
|---|---|---|
polymarket_smart_money_consensus(market) |
number | Consensus among high-win-rate wallets (-1 to +1) |
polymarket_manipulation_risk(market) |
number | Risk score based on cluster activity (0-1) |
polymarket_whale_flow(market) |
number | Net flow from high-volume wallets |
polymarket_has_suspicious_activity(market) |
boolean | True if suspicious clusters active in market |
polymarket_coordination_score(market) |
number | Degree of coordinated activity (0-1) |
// Avoid markets with high manipulation risk
entry: polymarket_manipulation_risk("btc-100k-2024") < 0.3 && polymarket_smart_money_consensus("btc-100k-2024") > 0.5
// Filter for clean signals
exit: polymarket_has_suspicious_activity("fed-rate-cut-june") == false
Three scheduler jobs maintain the wallet clustering system.
| Job | Interval | Description |
|---|---|---|
sync-polymarket-bets |
6 hours | Fetches recent trades from CLOB API, ingests into pm_wallet_bets |
wallet-clustering-incremental |
Daily | Analyzes recently active wallets, updates connections and clusters |
wallet-clustering-full-scan |
Weekly | Comprehensive analysis of all top wallets by volume |
| Endpoint | Method | Description |
|---|---|---|
/api/predict/v1/wallet-clustering/wallets |
GET | List suspicious wallets |
/api/predict/v1/wallet-clustering/wallets/:address |
GET | Get wallet details and connections |
/api/predict/v1/wallet-clustering/clusters |
GET | List suspicious clusters |
/api/predict/v1/wallet-clustering/clusters/:id |
GET | Get cluster details with member wallets |
/api/predict/v1/wallet-clustering/market/:marketId |
GET | Get cluster activity in a specific market |
/api/predict/v1/wallet-clustering/scans |
GET | List recent scan history |
/api/predict/v1/admin/wallet-clustering/scan |
POST | Trigger manual scan (admin only) |
Wallet clustering data feeds into the All-Seeing Eye aggregation layer.
Wallet clustering provides data points with these characteristics:
sourceType: 'wallet_clustering'normalizedValue — Suspicion score mapped to -1 to +1confidence — Based on bet volume and connection strengthmetadata — Cluster ID, wallet count, suspicion reasons| File | Purpose |
|---|---|
packages/be/src/wallet-clustering/types.ts | TypeScript interfaces |
packages/be/src/wallet-clustering/repository.ts | Database CRUD operations |
packages/be/src/wallet-clustering/service.ts | Business logic, scan orchestration |
packages/be/src/wallet-clustering/dsl-wrappers.ts | DSL primitive implementations |
packages/be/src/integrations/polymarket.ts | CLOB API integration |
packages/be/src/all-seeing-eye/aggregation/wallet-clustering.ts | ASE aggregation bridge |
db/migrations/255_wallet_clustering_schema.sql | Database schema |