Score on-chain wallets on historical edge over a long window — emitted as a feature, never as a copy-trade signal.
3. Why This Bot Matters
Wallet behaviour treated as a copy-trade signal
Naively echoing 'smart money' wallets is the textbook way to lose money — the apparent edge is survivor bias, the real wallets front-run, and the implementation amounts to copy-trading. Emitting a feature with explicit non-trigger guidance prevents that misuse.
Strategies build their own wallet scorers, inconsistently
Without a shared classifier, every strategy author writes a slightly different version. The library ends up with three inconsistent scores, none of them auditable.
No long-window context for short-term flows
A wallet's 24-hour activity is meaningless without its multi-month history. Centralising the long-window score gives all consumers the same baseline and prevents recency-driven misclassifications.
Compliance unable to flag suspicious counterparties
Sanctions and abuse reviews need a structured score per wallet. The classifier provides one consistent input that ComplianceGate and Governance can both read.
4. Required Polymarket Inputs
Input
Source
Required?
Use
CTFExchangeV2 OrderFilled events from Polygon on-chain
onchain
Yes
Primary source of wallet fill data for flow classification.
Historical wallet fill patterns
data
No
Supplement recent fills with historical context for better classification accuracy.
5. Required Internal Inputs
Input
Source
Required?
Use
KillSwitch active flag
KillSwitch
Yes
Suppress all emissions when KillSwitch is active.
6. Parameter Guide
Parameter
Default
Warning
Hard
What it controls
institutional_threshold_pusd
10000
5000
1000
Minimum pUSD fill volume per block for a wallet to be classified as institutional.
poll_interval_s
12
30
60
Seconds between Polygon RPC polls for new OrderFilled events. Aligns with Polygon block time.
7. Detailed Parameter Instructions
institutional_threshold_pusd
What it means
Minimum pUSD fill volume per block for a wallet to be classified as institutional.
Default
{ "institutional_threshold_pusd": 10000 }
Why this default matters
10000 pUSD per block distinguishes institutional flow from retail with high confidence.
Strategy adjusted weighting after institutional flow detected
A large wallet made significant fills on this market. The system treats high-volume wallet flows as a market signal when sizing positions.
Wallet flow classified as arbitrage
Fill patterns consistent with arbitrage trading were detected. Arbitrage flow is treated as less directionally informative.
18. Failure-Mode Block
main_failure_mode
Polygon RPC outage causes WalletFlowClassifier to miss fills for one or more blocks, resulting in gaps in wallet flow classification during high-activity periods.
false_positive_risk
A single wallet conducting coordinated multi-leg arbitrage is classified as institutional by volume alone, overstating the directional signal from that wallet.
false_negative_risk
An institutional actor using many small wallets below the institutional_threshold evades classification and is labelled retail, understating the informed flow.
safe_fallback
If RPC is unavailable for > 2x poll_interval_s, emit STALE_DATA WARN and halt new classifications. Retain last classification labels for each wallet in Redis until fresh data is available.
required_dependencies
Polygon RPC (CTFExchangeV2 OrderFilled events), KillSwitch active flag, Redis for wallet state storage
19. Failure-Injection Recipes
Scenario
How to inject
Expected behaviour
Recovery
RPC_OUTAGE
Block TCP to Polygon RPC for 30 s
Automatic on RPC recovery; classification resumes from next available block
INSTITUTIONAL_FLOW
Inject mock fills of 50000 pUSD for a single wallet in one block
Automatic; no action required
KILL_SWITCH_ON
Set killswitch.active=true during active classification
Automatic on KillSwitch reset
20. State & Persistence
Cold-start recovery
On cold start, re-classify from next block; historical backfill not required.
21. Concurrency & Idempotency
Aspect
Specification
Execution model
single-threaded per-block processing
Max in-flight
1
Idempotency key
wallet_address + block_number
Per-call timeout (ms)
10000
Backpressure strategy
drop-after-buffer — skip block if previous block still processing at next poll
Locking / mutual exclusion
Redis SETNX on wallet + block_number to prevent duplicate classification
Adversary uses multiple wallets to fragment institutional flow and evade institutional classification
Wash-trades between related wallets to generate artificial arbitrage pattern signals
Mitigations
Classification is probabilistic and informational only; strategies apply independent signal weighting
Arbitrage detection requires multi-market simultaneous fills to reduce single-market spoofing
24. Polymarket V2 Compatibility
Aspect
Value
CLOB version
v2
Collateral asset
pUSD
EIP-712 Exchange domain version
2
Aware of builderCode field
no
Aware of negative-risk markets
no
Multi-chain ready
no
SDK used
py-clob-client-v2
Settlement contract
CTFExchangeV2
Notes
Classifies wallet pUSD flow types (retail, institutional, arbitrage) from CTFExchangeV2 on-chain data. Read-only. No order signing.
API surfaces declared
onchaindatainternal
Networks supported
polygon
25. Versioning & Migration
Field
Value
spec
2.0.0
implementation
0.1.0
schema
2
released
None
planned_release
Q3-2026
Migration history
Date
From
To
Reason
Action taken
2026-04-28
n/a
v2-spec
Spec drafted post-CLOB-V2 cutover; bot not yet implemented
Designed against V2 schema (pUSD, builder codes, V2 EIP-712 domain)
26. Acceptance Tests
Unit Tests
Test
Setup
Expected result
Large fill classified as institutional and ObservationReport emitted
Single wallet, total_pusd=50000 in one block
ObservationReport emitted with flow_label=institutional
Small fill classified as retail
Single wallet, total_pusd=200 in one block
ObservationReport emitted with flow_label=retail
KillSwitch suppresses emission
killswitch.active=true; institutional fill present
No ObservationReport; KILL_SWITCH_ACTIVE logged
Integration Tests
Test
Expected result
Full lifecycle: institutional fill detected on-chain → ObservationReport → strategy adjusts signal weight
Strategy receives flow_label=institutional with total_pusd
RPC outage: STALE_DATA emitted; classification halted; last labels retained
STALE_DATA WARN; WalletFlowClassifierRPCDown alert fires; last labels in Redis
Property Tests
Property
Required behaviour
WalletFlowClassifier never submits or signs orders
Always true
No ObservationReport emitted when KillSwitch is active
Always true
27. Operational Runbook
WalletFlowClassifier incidents are most commonly RPC outages. High arbitrage rate alerts indicate unusual market conditions worth investigating but do not block trading.
On-call actions
Alert
First step
Diagnosis
Mitigation
Escalate to
WalletFlowClassifierRPCDown
Check rpc_block_lag_s. Verify Polygon RPC endpoint health. Trigger failover if primary is down.
Infra on-call immediately; Intelligence pod lead within 5 min
WalletFlowClassifierHighArbitrageRate
Review arbitrage-labelled wallets. Check for known arbitrage bots or unusual market conditions.
Intelligence pod lead if > 20 arbitrage classifications in 10 min
Manual overrides
reset_wallet_state — DEL redis key wallet:<address> to reset classification state for a specific wallet — After known wallet rotation or operator-confirmed wallet re-use
Healthcheck
Endpoint: /internal/health/wallet-flow-classifier | Green: rpc_block_lag_s < 24 AND Redis reachable AND last classification < 30 s ago | Red: rpc_block_lag_s > 60 OR Redis unreachable
28. Promotion Gates
A bot does not advance to the next readiness state until every gate below is green. Gates are observable from production data — no subjective sign-off.
Promote to Shadow
Gate
How measured
Threshold
Unit tests pass for retail/institutional/arbitrage classification and KillSwitch suppression
CI test run
100% pass
Promote to Limited live
Gate
How measured
Threshold
Classification completes within one Polygon block interval (12 s) for p99 of blocks