Polymarket Bot Tutorial · अध्याय 9 of 32
Polymarket का on-chain data सीधे पढ़ें: USDC/pUSD balances, outcome supply के लिए CTF contract reads, UMA Optimistic Oracle के proposed/disputed events, और Polygon transaction logs - code के साथ।
यह अध्याय क्या कवर करता है
Polymarket के APIs सुविधाजनक हैं, लेकिन अंततः consistent होते हैं। Chain authoritative है। यह अध्याय उन on-chain reads को समझाता है जिन्हें production bot अपनी bookkeeping verify करने के लिए उपयोग करता है: pUSD balances, outcome-token inventory, UMA dispute events, और CTF contract state। ज़्यादातर production bots जिस pattern पर converge करते हैं, वह है speed के लिए API-first और correctness के लिए periodic on-chain reconciliation।
- On-chain में क्या रहता है (CLOB में क्या)
- pUSD contract address और ABI
- Conditional Tokens Framework (CTF)
- UMA Optimistic Oracle: proposed और disputed events
- Polygon event logs पढ़ना (web3.py / ethers)
- On-chain कब पढ़ें बनाम API पर भरोसा करें
- Code: event subscription के जरिए UMA dispute detect करें
On-chain में क्या रहता है (CLOB में क्या)
दो state machines, दो truths।
On-chain (Polygon): pUSD balances, outcome-token inventory (प्रति token ERC-1155 supply), allowance approvals, UMA Optimistic Oracle proposals और disputes, deposit और withdrawal events। यह eventually correct होता है; latency एक Polygon block (~2 seconds) की होती है।
CLOB (Polymarket API): order book, recent trades, pending limit orders, match acknowledgments. Real-time लेकिन eventually consistent - ERC-1155 के settle होने से पहले match को acknowledge कर दिया जाता है, जिससे phantom-fill problem पैदा होती है, जिसका cover chapter 12 में है।
दोनों को हमेशा converge करना चाहिए। जब वे diverge करें, chain authoritative है। सिर्फ CLOB पर भरोसा करने वाला bot drift करेगा; सिर्फ chain पर भरोसा करने वाला bot धीरे trade करेगा। Production code दोनों का उपयोग करता है: speed-critical decisions के लिए CLOB, और periodic reconciliation के लिए chain।
pUSD contract address और ABI
pUSD Polymarket का stablecoin wrapper है, जो 2025 V2 migration के बाद से उपयोग में है। Polygon mainnet पर 0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB वाला contract एक standard ERC-20 है।
Bot के लिए तीन reads महत्वपूर्ण हैं:
balanceOf(proxy)- आपका spendable pUSD। हर restart पर इसे CLOB के balance view से compare करें।allowance(proxy, exchange_contract)- क्या CTF/NegRisk exchange contracts आपका pUSD spend कर सकते हैं। Order matching के लिए आवश्यक।Transferevent subscription - polling किए बिना deposits और withdrawals detect करता है।
USDC (0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174) अब भी off-ramp pair बना हुआ है। ज़्यादातर bots को सिर्फ pUSD reads की ज़रूरत होती है; USDC का महत्व केवल deposit/withdrawal cycles के दौरान होता है।
Conditional Tokens Framework (CTF)
Outcome shares Gnosis के Conditional Tokens Framework (CTF) द्वारा minted ERC-1155 tokens हैं। Polygon पर 0x4D97DCd97eC945f40cF65F87097ACe5EA0476045 वाला CTF contract प्रति position-id supply track करता है।
तीन reads:
balanceOf(proxy, position_id)- उस market+outcome के लिए आपके पास वास्तव में कितने outcome tokens हैं।getOutcomeSlotCount(condition_id)- outcomes की संख्या (binary के लिए 2, multi-outcome के लिए N)।payoutNumerators,payoutDenominator- जब UMA market resolve करता है तब सेट होते हैं। इन्हें पढ़कर आप CLOB UI update होने से पहले ही जान सकते हैं कि कौन-सा side जीता।
position_id, (condition_id, outcome_index) का hash होता है। इसे client-side CTF के getPositionId helper से compute करें या अपनी stack में keccak math को replicate करें।
UMA Optimistic Oracle: proposed और disputed events
UMA का Optimistic Oracle (OO) सभी Polymarket dispute resolution को handle करता है। दो events जिन पर आपका bot subscribe करना चाह सकता है।
ProposePrice(requester, identifier, timestamp, ancillaryData, proposer, proposedPrice)- जब Polymarket bot outcome propose करता है तब fired होता है।DisputePrice(requester, identifier, timestamp, ancillaryData, disputer)- जब कोई proposed outcome को challenge करता है तब fired होता है।
OO contract address: 0xeE3Afe347D5C74317041E2618C49534dAf887c24. Polymarket के requester address से filter करें।
Subscribe क्यों करें: dispute का मतलब है कि resolution अब contested है और 24-72h UMA vote की आवश्यकता होगी। उस window के दौरान market trading के लिए pause हो सकता है। जो bot disputed market पर positions hold कर रहा है, उसे तुरंत यह पता होना चाहिए।
Polygon event logs पढ़ना (web3.py / ethers)
दो reference implementations।
Python (web3.py):
from web3 import Web3
w3 = Web3(Web3.HTTPProvider(POLYGON_RPC))
ctf = w3.eth.contract(address=CTF_ADDR, abi=CTF_ABI)
filter = ctf.events.PayoutRedemption.create_filter(fromBlock="latest")
for event in filter.get_new_entries():
print(event["args"])
Node (ethers v6):
import { ethers } from "ethers";
const p = new ethers.JsonRpcProvider(POLYGON_RPC);
const ctf = new ethers.Contract(CTF_ADDR, CTF_ABI, p);
ctf.on("PayoutRedemption", (redeemer, collateral, parentId, conditionId) => {
console.log("redemption", { redeemer, conditionId });
});
Continuous monitoring के लिए HTTP polling की बजाय WebSocket transport (wss://...) का उपयोग करें - कम requests और तेज delivery। ज़्यादातर paid RPC providers entry tiers में WebSocket शामिल करते हैं।
On-chain कब पढ़ें बनाम API पर भरोसा करें
Production से practical rules।
- API पर भरोसा करें इनके लिए: real-time order book, recent trades, आपके अपने pending orders, market metadata (slug, question, end date), event/market discovery।
- Chain पर भरोसा करें इनके लिए: आपका अपना pUSD balance, आपका अपना outcome-token inventory, deposit और withdrawal verification, resolution outcomes, dispute state।
- दोनों cross-check करें इनके लिए: कोई भी financial चीज़ जिसे bot ने fill के रूप में record किया हो - API के "matched" event को chain के CTF transfer से match करके settlement confirm करें।
Buy के बाद 5-second-wait rule (chapter 12) API time में on-chain reality का intrusion है। Market buy के तुरंत बाद submit किया गया GTC sell chain check में balance: 0 दिखा सकता है, भले ही CLOB ने कुछ moments पहले match किया हो।
Code: event subscription के जरिए UMA dispute detect करें
Reference: Polymarket-related UMA disputes को real time में monitor करें।
from web3 import Web3
w3 = Web3(Web3.WebsocketProvider(POLYGON_WSS))
oo = w3.eth.contract(address=UMA_OO_ADDR, abi=UMA_ABI)
POLY_REQUESTER = "0x..." # Polymarket's UMA requester address
def on_dispute(event):
args = event["args"]
if args["requester"].lower() != POLY_REQUESTER.lower(): return
print(f"DISPUTE on Polymarket market: ancillary={args['ancillaryData'][:40]}...")
# decode ancillaryData to recover the market question
event_filter = oo.events.DisputePrice.create_filter(fromBlock="latest")
while True:
for ev in event_filter.get_new_entries():
on_dispute(ev)
time.sleep(2)
ancillaryData field hex-encoded JSON-ish text है जिसमें market question होता है। इसे decode करने पर आपको slug-equivalent identifier मिलता है, जिसे आप अपनी open positions के साथ cross-reference कर सकते हैं।










