Polymarket Bot Tutorial · Chapter 9 of 32

Baca data on-chain Polymarket secara langsung: saldo USDC/pUSD, pembacaan kontrak CTF untuk supply outcome, event UMA Optimistic Oracle yang proposed/disputed, dan Polygon transaction logs - lengkap dengan code.

Apa yang dibahas dalam chapter ini

API Polymarket itu praktis, tetapi pada akhirnya bersifat eventually consistent. Chain adalah sumber otoritatif. Chapter ini membahas pembacaan on-chain yang digunakan bot production untuk memverifikasi bookkeeping-nya sendiri: saldo pUSD, inventory outcome-token, event dispute UMA, dan state kontrak CTF. Pola yang paling umum dipakai bot production adalah API-first untuk kecepatan ditambah rekonsiliasi on-chain berkala untuk akurasi.

  • Apa yang ada di on-chain (vs di CLOB)
  • Alamat contract pUSD dan ABI
  • Conditional Tokens Framework (CTF)
  • UMA Optimistic Oracle: event proposed dan disputed
  • Membaca Polygon event logs (web3.py / ethers)
  • Kapan membaca on-chain vs mempercayai API
  • Code: mendeteksi dispute UMA via event subscription

Apa yang ada di on-chain (vs di CLOB)

Dua state machine, dua kebenaran.

On-chain (Polygon): saldo pUSD, inventory outcome-token (supply ERC-1155 per token), approval allowance, proposal dan dispute UMA Optimistic Oracle, event deposit dan withdrawal. Pada akhirnya benar; latensinya satu Polygon block (~2 detik).

CLOB (Polymarket API): order book, trade terbaru, pending limit orders, acknowledgement match. Real-time tetapi eventually consistent - sebuah match diakui sebelum ERC-1155 settle, yang menimbulkan masalah phantom-fill yang dibahas di chapter 12.

Keduanya seharusnya selalu konvergen. Saat keduanya berbeda, chain adalah otoritatif. Bot yang hanya mempercayai CLOB akan melenceng; bot yang hanya mempercayai chain akan trading lambat. Code production menggunakan keduanya: CLOB untuk keputusan yang kritis terhadap kecepatan, chain untuk rekonsiliasi berkala.

Alamat contract pUSD dan ABI

pUSD adalah stablecoin wrapper Polymarket yang digunakan sejak migrasi V2 pada 2025. Contract di 0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB pada Polygon mainnet adalah ERC-20 standar.

Tiga pembacaan yang penting untuk bot:

  • balanceOf(proxy) - pUSD yang bisa Anda belanjakan. Bandingkan dengan tampilan saldo CLOB pada setiap restart.
  • allowance(proxy, exchange_contract) - apakah contract exchange CTF/NegRisk dapat membelanjakan pUSD Anda. Diperlukan untuk order matching.
  • Subscription event Transfer - mendeteksi deposit dan withdrawal tanpa polling.

USDC (0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174) tetap menjadi pair off-ramp. Kebanyakan bot hanya perlu pembacaan pUSD; USDC hanya penting saat siklus deposit/withdrawal.

Conditional Tokens Framework (CTF)

Outcome shares adalah token ERC-1155 yang dicetak oleh Conditional Tokens Framework (CTF) milik Gnosis. Contract CTF di Polygon pada 0x4D97DCd97eC945f40cF65F87097ACe5EA0476045 melacak supply per position-id.

Tiga pembacaan:

  • balanceOf(proxy, position_id) - berapa banyak outcome token yang benar-benar Anda pegang untuk market+outcome tersebut.
  • getOutcomeSlotCount(condition_id) - jumlah outcome (2 untuk binary, N untuk multi-outcome).
  • payoutNumerators, payoutDenominator - di-set ketika UMA menyelesaikan market. Membacanya memberi tahu Anda sisi mana yang menang sebelum UI CLOB diperbarui.

position_id adalah hash dari (condition_id, outcome_index). Hitung di sisi client melalui helper getPositionId dari CTF atau tirukan math keccak di stack Anda.

UMA Optimistic Oracle: event proposed dan disputed

Optimistic Oracle (OO) milik UMA menangani semua penyelesaian sengketa Polymarket. Ada dua event yang mungkin ingin Anda subscribe.

  • ProposePrice(requester, identifier, timestamp, ancillaryData, proposer, proposedPrice) - dipicu saat bot Polymarket mengusulkan outcome.
  • DisputePrice(requester, identifier, timestamp, ancillaryData, disputer) - dipicu saat seseorang menantang outcome yang diusulkan.

Alamat contract OO: 0xeE3Afe347D5C74317041E2618C49534dAf887c24. Filter berdasarkan alamat requester milik Polymarket.

Mengapa subscribe: dispute berarti resolusi sekarang diperdebatkan dan akan memerlukan voting UMA selama 24-72 jam. Selama jendela itu, market mungkin dipause untuk trading. Bot yang memegang posisi di market yang disengketakan harus mengetahuinya segera.

Membaca Polygon event logs (web3.py / ethers)

Dua implementasi referensi.

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 });
});

Untuk monitoring berkelanjutan gunakan transport WebSocket (wss://...) вместо HTTP polling - request lebih sedikit dan pengiriman lebih cepat. Sebagian besar paid RPC provider menyertakan WebSocket pada tier entry.

Kapan membaca on-chain vs mempercayai API

Aturan praktis dari production.

  • Percayai API untuk: real-time order book, recent trades, pending orders Anda sendiri, metadata market (slug, question, end date), discovery event/market.
  • Percayai chain untuk: saldo pUSD Anda sendiri, inventory outcome-token Anda sendiri, verifikasi deposit dan withdrawal, outcome resolusi, state dispute.
  • Cross-check keduanya untuk: apa pun yang bersifat finansial dan dicatat bot sebagai fill - cocokkan event "matched" dari API dengan transfer CTF di chain untuk mengonfirmasi settlement.

Aturan tunggu 5 detik setelah buy (chapter 12) adalah kenyataan on-chain yang masuk ke waktu API. GTC sell yang dikirim segera setelah market buy akan melihat balance: 0 dari pengecekan chain meskipun CLOB sudah match beberapa saat sebelumnya.

Code: mendeteksi dispute UMA via event subscription

Referensi: memantau dispute UMA terkait Polymarket secara 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 ancillaryData adalah teks mirip JSON yang di-hex-encode dan berisi market question. Mendekodenya memberi Anda identifier setara slug untuk dicocokkan dengan open positions Anda.

Pertanyaan yang sering diajukan

Di mana saya bisa menemukan contract pUSD Polymarket?
pUSD berada di 0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB di Polygon. Ini menggantikan USDC.e sebagai collateral canonical Polymarket pada 28 April 2026. Link Polygonscan: https://polygonscan.com/token/0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB.
Apa itu contract CTF di Polymarket?
CTF adalah singkatan dari Conditional Tokens Framework - contract ERC-1155 turunan Gnosis yang menerbitkan outcome token (saham YES dan NO yang Anda trade). Setiap market Polymarket adalah posisi CTF dengan logika redemption yang terhubung ke resolusi UMA. Bot jarang perlu berinteraksi langsung dengan CTF; SDK yang menanganinya.
Bagaimana cara subscribe ke event dispute UMA di Polygon?
Subscribe ke event "ProposePrice" dan "DisputePrice" pada contract UMA Optimistic Oracle V2 melalui WebSocket dari provider RPC Polygon Anda. Filter berdasarkan field requesterAddress (oracle adapter Polymarket) untuk mendapatkan hanya dispute yang terkait Polymarket. Contoh code ada di chapter ini.
Apakah saya perlu membaca data on-chain jika saya mempercayai Polymarket API?
Untuk sebagian besar strategi, tidak. CLOB API adalah canonical untuk data order book dan trade, dan gamma API adalah canonical untuk metadata. Anda membaca on-chain ketika membutuhkan (a) peringatan dispute UMA lebih cepat daripada API menampilkannya, (b) verifikasi bahwa deposit benar-benar masuk, atau (c) analytics kustom pada outcome/position.
Berapa latensi data on-chain Polygon dibandingkan Polymarket API?
Waktu block Polygon sekitar ~2 detik. Polymarket API umumnya menampilkan perubahan order book dalam hitungan ratusan milidetik setelah match on-chain. Untuk kebanyakan sinyal, API lebih cepat daripada pembacaan on-chain Anda sendiri. Dispute UMA adalah pengecualian - event on-chain muncul sebelum UI mencerminkan dispute.
Bisakah saya membaca posisi Polymarket tanpa CLOB API?
Secara teknis ya - baca CTF balanceOf(walletAddress, positionId) untuk setiap posisi. Secara praktis endpoint CLOB API /trade/positions lebih cepat, menyertakan pricing, dan menggabungkan semua posisi Anda. Gunakan pembacaan on-chain hanya jika Anda perlu verifikasi atau API sedang down.