Polymarket Bot Tutorial · অধ্যায় ৯ / ৩২
Polymarket on-chain data সরাসরি পড়ুন: USDC/pUSD balances, outcome supply-এর জন্য CTF contract reads, UMA Optimistic Oracle-এর proposed/disputed events, এবং Polygon transaction logs - code সহ।
এই অধ্যায়ে কী আলোচনা করা হয়েছে
Polymarket-এর APIs সুবিধাজনক, কিন্তু শেষ পর্যন্ত eventually consistent। Chain-ই authoritative। এই অধ্যায়ে সেই on-chain reads দেখানো হয়েছে, যেগুলো একটি production bot নিজের bookkeeping যাচাই করতে ব্যবহার করে: pUSD balances, outcome-token inventory, UMA dispute events, এবং CTF contract state। বেশিরভাগ production bots speed-এর জন্য API-first ব্যবহার করে, আর correctness-এর জন্য নির্দিষ্ট সময় পরপর on-chain reconciliation করে।
এটি Polymarket trading bot তৈরি নিয়ে আমাদের ৩২-অংশের সিরিজের ৯ম অধ্যায়। নিচের sections-এ আমরা বিষয়টি বিস্তারিতভাবে কভার করেছি। প্রতিটি section-এর body content chapter-by-chapter লেখা হচ্ছে এবং rollout করা হচ্ছে; FAQ answers এবং references ইতিমধ্যে সম্পূর্ণ এবং আমাদের own trader চালানোর production experience প্রতিফলিত করে।
- 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 machine, দুটি truth.
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 (~২ সেকেন্ড)।
CLOB (Polymarket API): order book, recent trades, pending limit orders, match acknowledgments। Real-time কিন্তু eventually consistent - একটি match, ERC-1155 settle হওয়ার আগে acknowledge হয়, যার ফলে chapter 12-এ আলোচিত phantom-fill problem তৈরি হয়।
দুটির ফল সবসময় converge করা উচিত। যখন তারা diverge করে, chain-ই authoritative। শুধু CLOB-এর ওপর নির্ভর করা bot drift করবে; শুধু chain-এর ওপর নির্ভর করা bot ধীরে trade করবে। Production code উভয়ই ব্যবহার করে: speed-critical সিদ্ধান্তের জন্য CLOB, আর periodic reconciliation-এর জন্য chain।
pUSD contract address এবং ABI
pUSD হলো Polymarket-এর stablecoin wrapper, যা ২০২৫ V2 migration-এর পর থেকে ব্যবহৃত হচ্ছে। Polygon mainnet-এ 0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB ঠিকানার contract একটি standard ERC-20।
একটি bot-এর জন্য গুরুত্বপূর্ণ তিনটি read:
balanceOf(proxy)- আপনার spendable pUSD। প্রতিটি restart-এ CLOB-এর balance view-এর সঙ্গে তুলনা করুন।allowance(proxy, exchange_contract)- CTF/NegRisk exchange contracts আপনার pUSD spend করতে পারবে কি না। Order matching-এর জন্য প্রয়োজন।Transferevent subscription - polling ছাড়াই deposit এবং withdrawal detect করে।
USDC (0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174) এখনও off-ramp pair হিসেবে থাকে। বেশিরভাগ bot-এর শুধু pUSD reads-ই দরকার; USDC কেবল deposit/withdrawal cycle-এর সময় প্রাসঙ্গিক।
Conditional Tokens Framework (CTF)
Outcome shares হলো Gnosis-এর Conditional Tokens Framework (CTF) দ্বারা minted ERC-1155 tokens। Polygon-এ 0x4D97DCd97eC945f40cF65F87097ACe5EA0476045 ঠিকানার CTF contract প্রতি position-id-এর supply track করে।
তিনটি read:
balanceOf(proxy, position_id)- ওই market+outcome-এর জন্য আপনি প্রকৃতপক্ষে কত outcome tokens hold করছেন।getOutcomeSlotCount(condition_id)- outcome-এর সংখ্যা (binary হলে ২, multi-outcome হলে N)।payoutNumerators,payoutDenominator- UMA market resolve করার সময় সেট হয়। এগুলো পড়ে আপনি জানতে পারবেন CLOB UI আপডেট হওয়ার আগেই কোন side জিতেছে।
position_id হলো (condition_id, outcome_index)-এর একটি hash। CTF-এর getPositionId helper ব্যবহার করে client-side-এ এটি compute করুন, অথবা আপনার stack-এ keccak math replicate করুন।
UMA Optimistic Oracle: proposed এবং disputed events
UMA-এর Optimistic Oracle (OO) সব Polymarket dispute resolution handle করে। দুটি event আপনার 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, এবং এর জন্য ২৪-৭২ ঘণ্টার UMA vote লাগবে। সেই window-তে market trading-এর জন্য paused হতে পারে। disputed market-এ position hold করা bot-এর তা সঙ্গে সঙ্গেই জানা উচিত।
Polygon event logs পড়া (web3.py / ethers)
দুটি reference implementation।
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://...) ব্যবহার করুন - request কম লাগে এবং delivery দ্রুত হয়। বেশিরভাগ paid RPC provider-এর entry tier-এ 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 করুন এইগুলোর জন্য: bot যেসব financial item-কে fill হিসেবে record করেছে - API-এর "matched" event-কে chain-এর CTF transfer-এর সঙ্গে মিলিয়ে settlement confirm করুন।
Buy-এর পর ৫-সেকেন্ড-wait rule (chapter 12) হলো API time-এ on-chain reality-এর প্রবেশ। কোনো market buy-এর ঠিক পরেই submitted GTC sell chain check-এ balance: 0 দেখাতে পারে, যদিও CLOB moments ago 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 করতে পারবেন।












