מדריך בוט Polymarket · פרק 9 מתוך 32

קראו נתוני on-chain של Polymarket ישירות: יתרות USDC/pUSD, קריאות מחוזה CTF עבור היצע התוצאות, אירועי proposed/disputed של UMA Optimistic Oracle, ולוגים של טרנזקציות ב-Polygon - עם קוד.

מה מכסה הפרק הזה

ה-API של Polymarket נוח, אבל הוא eventually consistent. ה-chain הוא הסמכות. הפרק הזה עובר על קריאות ה-on-chain שבוט פרודקשן משתמש בהן כדי לאמת את הנהלת החשבונות שלו עצמו: יתרות pUSD, מלאי טוקני תוצאות, אירועי מחלוקת של UMA, ומצב חוזה CTF. הדפוס שרוב בוטי הפרודקשן מתכנסים אליו הוא API-first למהירות, יחד עם reconciliation תקופתי על ה-chain לצורך דיוק.

  • מה חי על ה-chain (לעומת ב-CLOB)
  • כתובת חוזה pUSD ו-ABI
  • Conditional Tokens Framework (CTF)
  • UMA Optimistic Oracle: אירועי proposed ו-disputed
  • קריאת event logs ב-Polygon ‏(web3.py / ethers)
  • מתי לקרוא מה-chain ומתי לסמוך על ה-API
  • קוד: זיהוי מחלוקת של UMA באמצעות event subscription

מה חי על ה-chain (לעומת ב-CLOB)

שתי מכונות מצב, שתי אמיתות.

On-chain (Polygon): יתרות pUSD, מלאי טוקני תוצאות (היצע ERC-1155 לכל טוקן), approvals של allowance, אירועי proposals ו-disputes ב-UMA Optimistic Oracle, ואירועי הפקדה ומשיכה. נכון בסופו של דבר; ה-latency הוא בלוק אחד ב-Polygon, בערך 2 שניות.

CLOB (Polymarket API): order book, עסקאות אחרונות, orders מוגבלים ממתינים, ואישורי match. בזמן אמת אבל eventually consistent - ה-match מאושר לפני שה-ERC-1155 נסגר, וזה יוצר את בעיית phantom-fill שמכוסה בפרק 12.

השניים צריכים תמיד להתכנס. כשיש ביניהם סטייה, ה-chain הוא הסמכות. בוט שסומך רק על ה-CLOB יסטה; בוט שסומך רק על ה-chain יסחור לאט. קוד פרודקשן משתמש בשניהם: CLOB להחלטות קריטיות למהירות, chain ל-reconciliation תקופתי.

כתובת חוזה pUSD ו-ABI

pUSD הוא ה-stablecoin wrapper של Polymarket, בשימוש מאז ה-migration של V2 ב-2025. החוזה ב-Polygon mainnet בכתובת 0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB הוא ERC-20 סטנדרטי.

שלוש קריאות שחשובות לבוט:

  • balanceOf(proxy) - ה-pUSD הזמין שלכם להוצאה. השוו מול התצוגה של ה-CLOB על היתרה שלכם בכל restart.
  • allowance(proxy, exchange_contract) - האם חוזי ה-CTF/NegRisk exchange יכולים להשתמש ב-pUSD שלכם. נדרש לצורך התאמת orders.
  • Transfer event subscription - מזהה הפקדות ומשיכות בלי polling.

USDC (0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174) נשאר צמד ה-off-ramp. רוב הבוטים צריכים רק קריאות pUSD; USDC רלוונטי רק במהלך מחזורי הפקדה/משיכה.

Conditional Tokens Framework (CTF)

מניות התוצאה הן טוקני ERC-1155 שמוטבעים על ידי Conditional Tokens Framework ‏(CTF) של Gnosis. חוזה ה-CTF ב-Polygon בכתובת 0x4D97DCd97eC945f40cF65F87097ACe5EA0476045 עוקב אחרי ההיצע לכל position-id.

שלוש קריאות:

  • balanceOf(proxy, position_id) - כמה טוקני תוצאה באמת מחזיקים עבור אותו market+outcome.
  • getOutcomeSlotCount(condition_id) - מספר התוצאות (2 לבינארי, N ל-multi-outcome).
  • payoutNumerators, payoutDenominator - נקבעים כשה-UMA פותר את ה-market. קריאתם אומרת לכם איזה צד ניצח לפני שה-UI של ה-CLOB מתעדכן.

ה-position_id הוא hash של (condition_id, outcome_index). חשבו אותו בצד הלקוח באמצעות helper של getPositionId של ה-CTF, או שחזרו את חישוב ה-keccak ב-stack שלכם.

UMA Optimistic Oracle: אירועי proposed ו-disputed

ה-Optimistic Oracle ‏(OO) של UMA מטפל בכל הליך פתרון המחלוקות של Polymarket. שני אירועים שכדאי לבוט להירשם אליהם.

  • ProposePrice(requester, identifier, timestamp, ancillaryData, proposer, proposedPrice) - מופעל כאשר בוט של Polymarket מציע תוצאה.
  • DisputePrice(requester, identifier, timestamp, ancillaryData, disputer) - מופעל כאשר מישהו מערער על התוצאה המוצעת.

כתובת חוזה ה-OO: 0xeE3Afe347D5C74317041E2618C49534dAf887c24. סננו לפי כתובת ה-requester של Polymarket.

למה להירשם: מחלוקת אומרת שה-resolution עכשיו שנוי במחלוקת ויידרש עליו vote של UMA במשך 24-72 שעות. במהלך החלון הזה, ייתכן שה-market ייעצר למסחר. בוט שמחזיק פוזיציות ב-market שנוי במחלוקת צריך לדעת זאת מיד.

קריאת event logs ב-Polygon ‏(web3.py / ethers)

שתי הטמעות עזר.

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

לניטור רציף השתמשו ב-WebSocket transport (wss://...) במקום HTTP polling - פחות requests ואספקה מהירה יותר. רוב ספקי ה-RPC בתשלום כוללים WebSocket ב-tierים הראשונים.

מתי לקרוא מה-chain ומתי לסמוך על ה-API

כללים מעשיים מהפרודקשן.

  • סמכו על ה-API עבור: order book בזמן אמת, עסקאות אחרונות, ה-orders הממתינים שלכם, metadata של ה-market ‏(slug, question, end date), discovery של events/markets.
  • סמכו על ה-chain עבור: יתרת pUSD שלכם, מלאי טוקני התוצאה שלכם, אימות של הפקדות ומשיכות, תוצאות resolution, מצב מחלוקת.
  • בצעו cross-check לשניהם עבור: כל דבר פיננסי שה-bot רשם כ-fill - התאימו את אירוע ה-"matched" של ה-API ל-transfer של ה-CTF ב-chain כדי לאמת settlement.

כלל ההמתנה של 5 שניות אחרי קנייה (פרק 12) הוא מציאות ה-on-chain שחודרת אל זמן ה-API. sell מסוג GTC שנשלח מיד אחרי קנייה ב-market יראה balance: 0 בבדיקת ה-chain, למרות שה-CLOB התאים לפני רגע.

קוד: זיהוי מחלוקת של UMA באמצעות event subscription

הפניה: מעקב בזמן אמת אחרי מחלוקות UMA הקשורות ל-Polymarket.

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 הוא טקסט בסגנון JSON שמקודד בהקס, ומכיל את שאלת ה-market. פענוח שלו נותן לכם את המזהה המקביל ל-slug כדי לבצע cross-reference מול הפוזיציות הפתוחות שלכם.

שאלות נפוצות

איפה אפשר למצוא את חוזה ה-pUSD של Polymarket?
pUSD נמצא בכתובת 0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB ב-Polygon. הוא החליף את USDC.e כ-collateral הקנוני של Polymarket ב-28 באפריל 2026. קישור ל-Polygonscan: https://polygonscan.com/token/0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB.
מהו חוזה ה-CTF ב-Polymarket?
CTF הוא ראשי תיבות של Conditional Tokens Framework - חוזה ERC-1155 שמקורו ב-Gnosis ומנפיק טוקני תוצאה (מניות ה-YES וה-NO שאתם סוחרים בהן). כל market ב-Polymarket הוא position של CTF עם לוגיקת redemption שמקושרת לפתרון של UMA. לבוטים לעיתים נדירות יש צורך ליצור אינטראקציה ישירה עם CTF; ה-SDK מטפל בזה.
איך נרשמים לאירועי מחלוקת של UMA ב-Polygon?
הירשמו לאירועי "ProposePrice" ו-"DisputePrice" של חוזה UMA Optimistic Oracle V2 דרך ה-WebSocket של ספק ה-RPC שלכם ב-Polygon. סננו לפי השדה requesterAddress ‏(מתאם ה-oracle של Polymarket) כדי לקבל רק מחלוקות הקשורות ל-Polymarket. דוגמאות קוד מופיעות בפרק.
האם צריך לקרוא נתונים on-chain אם אני סומך על ה-API של Polymarket?
עבור רוב האסטרטגיות, לא. ה-CLOB API הוא המקור הקנוני לנתוני order book ו-trade, ו-gamma API הוא המקור הקנוני ל-metadata. קוראים מה-chain כשצריך (a) התראות על מחלוקות UMA מהר יותר ממה שה-API מציג אותן, (b) אימות שהפקדה אכן הגיעה, או (c) analytics מותאמים אישית על תוצאות/פוזיציות.
מה ה-latency של נתוני Polygon on-chain לעומת ה-API של Polymarket?
זמן הבלוק ב-Polygon הוא בערך 2 שניות. ה-API של Polymarket בדרך כלל מציג שינויי order book בתוך מאות מילישניות מה-match on-chain. עבור רוב הסיגנלים, ה-API מהיר יותר מהקריאות on-chain שלכם. מחלוקות UMA הן חריג - האירוע on-chain מופעל לפני שה-UI משקף את המחלוקת.
האם אפשר לקרוא פוזיציות של Polymarket בלי ה-CLOB API?
טכנית כן - קראו balanceOf(walletAddress, positionId) של CTF עבור כל position. בפועל, ה-CLOB API ‏/trade/positions מהיר יותר, כולל תמחור, ומאגד את כל הפוזיציות שלכם. חזרו לקריאות on-chain רק אם אתם צריכים אימות או אם ה-API לא זמין.