Polymarket Bot Tutorial · Sura ya 9 kati ya 32
Soma Polymarket on-chain data moja kwa moja: USDC/pUSD balances, CTF contract reads kwa outcome supply, UMA Optimistic Oracle proposed/disputed events, na Polygon transaction logs - na code.
Sura hii inafunika nini
APIs za Polymarket ni rahisi lakini eventually consistent. Chain ni authoritative. Sura hii inapitia on-chain reads ambazo production bot inatumia kuhakiki bookkeeping yake mwenyewe: pUSD balances, outcome-token inventory, UMA dispute events, na CTF contract state. Pattern ambayo production bots wengi huingia ni API-first kwa speed pamoja na periodic on-chain reconciliation kwa correctness.
- Kinachoishi on-chain (vs katika CLOB)
- pUSD contract address na ABI
- Conditional Tokens Framework (CTF)
- UMA Optimistic Oracle: proposed na disputed events
- Kusoma Polygon event logs (web3.py / ethers)
- Wakati wa kusoma on-chain vs kutrust API
- Code: detect UMA dispute kupitia event subscription
Kinachoishi on-chain (vs katika CLOB)
State machines mbili, kweli mbili.
On-chain (Polygon): pUSD balances, outcome-token inventory (ERC-1155 supply per token), allowance approvals, UMA Optimistic Oracle proposals na disputes, deposit na withdrawal events. Eventually correct; latency ni Polygon block moja (~sekunde 2).
CLOB (Polymarket API): order book, recent trades, pending limit orders, match acknowledgments. Real-time lakini eventually consistent - match inakubaliwa kabla ERC-1155 isettle, ambayo inazalisha phantom-fill problem iliyofunikwa katika sura ya 12.
Zote mbili zinapaswa kuconverge daima. Wakati zinadiverge, chain ni authoritative. Bot inayotrust CLOB tu itadrift; bot inayotrust chain tu itatrade polepole. Production code inatumia zote: CLOB kwa speed-critical decisions, chain kwa periodic reconciliation.
pUSD contract address na ABI
pUSD ni stablecoin wrapper ya Polymarket iliyotumika tangu 2025 V2 migration. Contract kwenye 0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB kwenye Polygon mainnet ni standard ERC-20.
Reads tatu zinazojali kwa bot:
balanceOf(proxy)- pUSD yako inayoweza kutumika. Linganisha dhidi ya view ya CLOB ya balance yako kwenye kila restart.allowance(proxy, exchange_contract)- kama CTF/NegRisk exchange contracts zinaweza kutumia pUSD yako. Inahitajika kwa order matching.Transferevent subscription - inadetect deposits na withdrawals bila polling.
USDC (0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174) inabaki off-ramp pair. Bots wengi wanahitaji pUSD reads tu; USDC inajali tu wakati wa deposit/withdrawal cycles.
Conditional Tokens Framework (CTF)
Outcome shares ni ERC-1155 tokens minted na Gnosis Conditional Tokens Framework (CTF). CTF contract kwenye Polygon kwenye 0x4D97DCd97eC945f40cF65F87097ACe5EA0476045 inafuatilia per-position-id supply.
Reads tatu:
balanceOf(proxy, position_id)- outcome tokens ngapi unashikilia kweli kwa market+outcome hiyo.getOutcomeSlotCount(condition_id)- idadi ya outcomes (2 kwa binary, N kwa multi-outcome).payoutNumerators,payoutDenominator- zinawekwa wakati UMA inaresolve market. Kusoma hizi kunakuambia ni side gani ilishinda kabla CLOB UI haijaupdate.
position_id ni hash ya (condition_id, outcome_index). Hesabu client-side kupitia CTF getPositionId helper au replicate keccak math katika stack yako.
UMA Optimistic Oracle: proposed na disputed events
UMA Optimistic Oracle (OO) inashughulikia Polymarket dispute resolution zote. Events mbili bot yako inaweza kutaka kujisajili.
ProposePrice(requester, identifier, timestamp, ancillaryData, proposer, proposedPrice)- inafired wakati Polymarket bot inapropose outcome.DisputePrice(requester, identifier, timestamp, ancillaryData, disputer)- inafired wakati mtu anachallenge proposed outcome.
OO contract address: 0xeE3Afe347D5C74317041E2618C49534dAf887c24. Chuja na Polymarket requester address.
Kwa nini ujisajili: dispute inamaanisha resolution sasa imecontested na itahitaji 24-72h UMA vote. Wakati wa window hiyo, market inaweza kupauziwa kwa trading. Bot inayoshikilia positions kwenye disputed market inapaswa kujua mara moja.
Kusoma Polygon event logs (web3.py / ethers)
Implementations mbili za reference.
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 });
});
Kwa continuous monitoring tumia WebSocket transport (wss://...) badala ya HTTP polling - requests chache na faster delivery. Paid RPC providers wengi wanajumuisha WebSocket kwenye entry tiers.
Wakati wa kusoma on-chain vs kutrust API
Practical rules kutoka production.
- Trust API kwa: real-time order book, recent trades, pending orders zako mwenyewe, market metadata (slug, question, end date), event/market discovery.
- Trust chain kwa: pUSD balance yako mwenyewe, outcome-token inventory yako mwenyewe, deposit na withdrawal verification, resolution outcomes, dispute state.
- Cross-check zote kwa: kitu chochote cha kifedha ambacho bot ilikiandika kama fill - match "matched" event ya API dhidi ya CTF transfer ya chain kuthibitisha settlement.
5-second-wait rule baada ya buy (sura ya 12) ni on-chain reality inayoingia katika API time. GTC sell iliyosubmit mara moja baada ya market buy itaona balance: 0 kutoka chain check hata kama CLOB ilimatch dakika iliyopita.
Code: detect UMA dispute kupitia event subscription
Reference: angalia Polymarket-related UMA disputes katika 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)
Field ya ancillaryData ni hex-encoded JSON-ish text inayoshikilia market question. Kuidecodi kunakupa slug-equivalent identifier ya kucross-reference dhidi ya open positions zako.












