Polymarket Bot Tutorial · Kabanata 9 ng 32
Basahin nang direkta ang Polymarket on-chain data: USDC/pUSD balances, CTF contract reads para sa outcome supply, UMA Optimistic Oracle proposed/disputed events, at Polygon transaction logs - na may code.
Ano ang sinasaklaw ng kabanatang ito
Ang APIs ng Polymarket ay convenient pero eventually consistent. Ang chain ay authoritative. Ang kabanatang ito ay naglalakad sa on-chain reads na ginagamit ng production bot para i-verify ang sariling bookkeeping: pUSD balances, outcome-token inventory, UMA dispute events, at CTF contract state. Ang pattern na karamihan ng production bots ay umaabot ay API-first para sa bilis kasama ang periodic on-chain reconciliation para sa correctness.
- Ano ang nakatira on-chain (vs sa CLOB)
- pUSD contract address at ABI
- Conditional Tokens Framework (CTF)
- UMA Optimistic Oracle: proposed at disputed events
- Pagbabasa ng Polygon event logs (web3.py / ethers)
- Kailan magbasa on-chain vs magtiwala sa API
- Code: i-detect ang UMA dispute sa pamamagitan ng event subscription
Ano ang nakatira on-chain (vs sa CLOB)
Dalawang state machines, dalawang katotohanan.
On-chain (Polygon): pUSD balances, outcome-token inventory (ERC-1155 supply per token), allowance approvals, UMA Optimistic Oracle proposals at disputes, deposit at withdrawal events. Eventually correct; latency ay isang Polygon block (~2 segundo).
CLOB (Polymarket API): order book, recent trades, pending limit orders, match acknowledgments. Real-time pero eventually consistent - ang match ay kinikilala bago mag-settle ang ERC-1155, na gumagawa ng phantom-fill problem na sinasaklaw sa kabanata 12.
Ang dalawa ay dapat laging mag-converge. Kapag sila ay diverge, ang chain ay authoritative. Ang bot na nagtitiwala lamang sa CLOB ay magde-drift; ang bot na nagtitiwala lamang sa chain ay mag-trade nang mabagal. Ang production code ay gumagamit ng pareho: CLOB para sa speed-critical decisions, chain para sa periodic reconciliation.
pUSD contract address at ABI
Ang pUSD ay stablecoin wrapper ng Polymarket na ginamit mula sa 2025 V2 migration. Ang contract sa 0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB sa Polygon mainnet ay standard ERC-20.
Tatlong reads na mahalaga para sa bot:
balanceOf(proxy)- ang iyong spendable pUSD. Ihambing sa view ng CLOB ng iyong balance sa bawat restart.allowance(proxy, exchange_contract)- kung ang CTF/NegRisk exchange contracts ay maaaring gumastos ng iyong pUSD. Kinakailangan para sa order matching.Transferevent subscription - nag-detect ng deposits at withdrawals nang walang polling.
Ang USDC (0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174) ay nananatiling off-ramp pair. Ang karamihan ng bots ay kailangan lang ng pUSD reads; ang USDC ay mahalaga lamang sa deposit/withdrawal cycles.
Conditional Tokens Framework (CTF)
Ang outcome shares ay ERC-1155 tokens na minted ng Gnosis Conditional Tokens Framework (CTF). Ang CTF contract sa Polygon sa 0x4D97DCd97eC945f40cF65F87097ACe5EA0476045 ay nag-track ng per-position-id supply.
Tatlong reads:
balanceOf(proxy, position_id)- kung ilang outcome tokens ang aktwal mong hawak para sa market+outcome na iyon.getOutcomeSlotCount(condition_id)- bilang ng outcomes (2 para sa binary, N para sa multi-outcome).payoutNumerators,payoutDenominator- itinakda kapag nag-resolve ang UMA ng market. Ang pagbasa nito ay nagsasabi sa iyo kung aling panig ang nanalo bago mag-update ang CLOB UI.
Ang position_id ay hash ng (condition_id, outcome_index). I-compute ito client-side sa pamamagitan ng getPositionId helper ng CTF o i-replicate ang keccak math sa iyong stack.
UMA Optimistic Oracle: proposed at disputed events
Ang Optimistic Oracle (OO) ng UMA ay humahawak ng lahat ng Polymarket dispute resolution. Dalawang events na maaaring gustong i-subscribe ng iyong bot.
ProposePrice(requester, identifier, timestamp, ancillaryData, proposer, proposedPrice)- fired kapag nag-propose ng outcome ang Polymarket bot.DisputePrice(requester, identifier, timestamp, ancillaryData, disputer)- fired kapag may humamon ng proposed outcome.
OO contract address: 0xeE3Afe347D5C74317041E2618C49534dAf887c24. Mag-filter ayon sa Polymarket requester address.
Bakit mag-subscribe: ang dispute ay nangangahulugan na ang resolution ngayon ay contested at mangangailangan ng 24-72h UMA vote. Sa loob ng window na iyon, maaaring ma-pause ang market para sa trading. Ang bot na may hawak ng positions sa disputed market ay dapat malaman kaagad.
Pagbabasa ng Polygon event logs (web3.py / ethers)
Dalawang 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 });
});
Para sa continuous monitoring gamitin ang WebSocket transport (wss://...) sa halip na HTTP polling - mas kaunting requests at mas mabilis na delivery. Ang karamihan ng paid RPC providers ay kasama ang WebSocket sa entry tiers.
Kailan magbasa on-chain vs magtiwala sa API
Practical rules mula sa production.
- Magtiwala sa API para sa: real-time order book, recent trades, sariling pending orders, market metadata (slug, question, end date), event/market discovery.
- Magtiwala sa chain para sa: sariling pUSD balance, sariling outcome-token inventory, deposit at withdrawal verification, resolution outcomes, dispute state.
- I-cross-check ang pareho para sa: anumang financial na naitala ng bot bilang fill - i-match ang "matched" event ng API laban sa CTF transfer ng chain para kumpirmahin ang settlement.
Ang 5-second-wait rule pagkatapos ng buy (kabanata 12) ay ang on-chain reality na pumapasok sa API time. Ang GTC sell na isinubmit kaagad pagkatapos ng market buy ay makakita ng balance: 0 mula sa chain check kahit na nag-match ang CLOB ilang sandali ang nakalipas.
Code: i-detect ang UMA dispute sa pamamagitan ng event subscription
Reference: panoorin ang Polymarket-related UMA disputes sa real time.
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)
Ang ancillaryData field ay hex-encoded JSON-ish text na naglalaman ng market question. Ang pag-decode nito ay nagbibigay sa iyo ng slug-equivalent identifier na maaaring i-cross-reference laban sa iyong open positions.












