Polymarket Bot Tutorial · Chapter 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 کے ساتھ۔
اس chapter میں کیا شامل ہے
Polymarket کے APIs آسان ہیں مگر آخرکار eventually consistent ہوتے ہیں۔ Chain authoritative ہے۔ یہ chapter ان 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 کیا ہوتا ہے (vs in CLOB)
- pUSD contract address اور ABI
- Conditional Tokens Framework (CTF)
- UMA Optimistic Oracle: proposed اور disputed events
- Polygon event logs پڑھنا (web3.py / ethers)
- On-chain کب پڑھنا ہے vs API پر کب trust کرنا ہے
- Code: event subscription کے ذریعے UMA dispute detect کرنا
On-chain کیا ہوتا ہے (vs in 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 - match کو ERC-1155 settle ہونے سے پہلے acknowledge کیا جاتا ہے، جس سے phantom-fill problem پیدا ہوتا ہے جس پر chapter 12 میں بات کی گئی ہے۔
دونوں کو ہمیشہ converge کرنا چاہیے۔ جب یہ diverge کریں تو chain authoritative ہے۔ جو bot صرف CLOB پر trust کرے گا وہ drift کرے گا؛ جو bot صرف chain پر trust کرے گا وہ آہستہ trade کرے گا۔ Production code دونوں استعمال کرتی ہے: speed-critical فیصلوں کے لیے 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 per-position-id supply track کرتا ہے۔
تین reads:
balanceOf(proxy, position_id)- اس market+outcome کے لیے آپ واقعی کتنے outcome tokens hold کرتے ہیں۔getOutcomeSlotCount(condition_id)- outcomes کی تعداد (binary کے لیے 2، multi-outcome کے لیے N)۔payoutNumerators,payoutDenominator- جب UMA market resolve کرتا ہے تو set ہوتے ہیں۔ انہیں پڑھ کر آپ 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 کرتا ہے تو یہ fire ہوتا ہے۔DisputePrice(requester, identifier, timestamp, ancillaryData, disputer)- جب کوئی proposed outcome کو challenge کرتا ہے تو یہ fire ہوتا ہے۔
OO contract address: 0xeE3Afe347D5C74317041E2618C49534dAf887c24۔ Polymarket کے requester address کے ذریعے filter کریں۔
Subscribe کیوں کریں: dispute کا مطلب ہے کہ resolution اب contested ہے اور 24-72h UMA vote درکار ہوگا۔ اس window کے دوران market trading کے لیے paused ہو سکتا ہے۔ Disputed market پر positions رکھنے والا bot اسے فوراً جان لے۔
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 کب پڑھنا ہے vs API پر کب trust کرنا ہے
Production سے practical rules۔
- API پر trust کریں ان چیزوں کے لیے: real-time order book، recent trades، آپ کے اپنے pending orders، market metadata (slug، question، end date)، event/market discovery۔
- Chain پر trust کریں ان چیزوں کے لیے: آپ کا اپنا 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 کا مداخلت کرنا ہے۔ Market buy کے فوراً بعد submit کیا گیا GTC sell chain check میں balance: 0 دکھائے گا، حالانکہ CLOB نے کچھ لمحے پہلے match کر دیا تھا۔
Code: event subscription کے ذریعے UMA dispute detect کرنا
Reference: Polymarket سے متعلق UMA disputes کو real time میں watch کریں۔
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 کیا جا سکتا ہے۔










