Polymarket Bot Tutorial · Chapitre 9 sur 32

Lisez directement les données on-chain de Polymarket : soldes USDC/pUSD, lectures du contrat CTF pour l'offre des outcomes, événements proposés/disputés de l'UMA Optimistic Oracle, et logs de transactions Polygon - avec du code.

Ce que couvre ce chapitre

Les APIs de Polymarket sont pratiques, mais eventualy consistent. La blockchain fait autorité. Ce chapitre passe en revue les lectures on-chain qu'un bot de production utilise pour vérifier sa propre comptabilité : soldes pUSD, inventaire des outcome tokens, événements de litige UMA et état du contrat CTF. Le schéma vers lequel convergent la plupart des bots de production est API-first pour la vitesse, plus une réconciliation on-chain périodique pour la fiabilité.

  • Ce qui vit on-chain (vs in CLOB)
  • Adresse du contrat pUSD et ABI
  • Conditional Tokens Framework (CTF)
  • UMA Optimistic Oracle : événements proposés et disputés
  • Lecture des logs d'événements Polygon (web3.py / ethers)
  • Quand lire on-chain vs faire confiance à l'API
  • Code : détecter un litige UMA via subscription d'événements

Ce qui vit on-chain (vs in CLOB)

Deux state machines, deux vérités.

On-chain (Polygon) : soldes pUSD, inventaire des outcome tokens (supply ERC-1155 par token), approvals d'allowance, propositions et litiges UMA Optimistic Oracle, événements de dépôt et de retrait. Correct à terme ; la latence correspond à un bloc Polygon (~2 secondes).

CLOB (Polymarket API) : order book, trades récents, ordres limite en attente, acknowledgments de matching. Temps réel mais eventualy consistent - un match est acknowledged avant que l'ERC-1155 ne soit settled, ce qui crée le problème de phantom-fill traité au chapitre 12.

Les deux doivent toujours converger. Lorsqu'ils divergent, la chaîne fait autorité. Un bot qui fait confiance uniquement au CLOB dérivera ; un bot qui fait confiance uniquement à la chaîne sera lent. Le code de production utilise les deux : le CLOB pour les décisions critiques en termes de vitesse, la chaîne pour la réconciliation périodique.

Adresse du contrat pUSD et ABI

pUSD est le stablecoin wrapper de Polymarket utilisé depuis la migration V2 de 2025. Le contrat sur Polygon mainnet à l'adresse 0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB est un standard ERC-20.

Trois lectures importantes pour un bot :

  • balanceOf(proxy) - votre pUSD dépensable. À comparer avec la vue du CLOB sur votre solde à chaque redémarrage.
  • allowance(proxy, exchange_contract) - si les contrats d'échange CTF/NegRisk peuvent dépenser votre pUSD. Requis pour le matching des ordres.
  • subscription à l'événement Transfer - détecte les dépôts et retraits sans polling.

L'USDC (0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174) reste le pair de sortie. La plupart des bots n'ont besoin que des lectures pUSD ; l'USDC n'est utile que pendant les cycles de dépôt/retrait.

Conditional Tokens Framework (CTF)

Les outcome shares sont des tokens ERC-1155 mintés par le Conditional Tokens Framework (CTF) de Gnosis. Le contrat CTF sur Polygon à 0x4D97DCd97eC945f40cF65F87097ACe5EA0476045 suit la supply par position-id.

Trois lectures :

  • balanceOf(proxy, position_id) - combien d'outcome tokens vous détenez réellement pour ce market+outcome.
  • getOutcomeSlotCount(condition_id) - nombre d'outcomes (2 pour binary, N pour multi-outcome).
  • payoutNumerators, payoutDenominator - définis lorsque UMA resolve le market. Les lire vous indique quel côté a gagné avant la mise à jour de l'UI du CLOB.

Le position_id est un hash de (condition_id, outcome_index). Calculez-le côté client via l'helper getPositionId du CTF ou reproduisez la keccak math dans votre stack.

UMA Optimistic Oracle : événements proposés et disputés

L'Optimistic Oracle (OO) d'UMA gère toute la résolution des litiges de Polymarket. Deux événements auxquels votre bot peut vouloir s'abonner.

  • ProposePrice(requester, identifier, timestamp, ancillaryData, proposer, proposedPrice) - déclenché lorsqu'un bot Polymarket propose un outcome.
  • DisputePrice(requester, identifier, timestamp, ancillaryData, disputer) - déclenché lorsque quelqu'un conteste l'outcome proposé.

Adresse du contrat OO : 0xeE3Afe347D5C74317041E2618C49534dAf887c24. Filtrez par l'adresse requester de Polymarket.

Pourquoi s'abonner : un litige signifie que la résolution est désormais contestée et nécessitera un vote UMA de 24 à 72 h. Pendant cette fenêtre, le market peut être mis en pause pour le trading. Un bot qui détient des positions sur un market disputé doit le savoir immédiatement.

Lecture des logs d'événements Polygon (web3.py / ethers)

Deux implémentations de référence.

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

Pour une surveillance continue, utilisez un transport WebSocket (wss://...) plutôt que du polling HTTP - moins de requêtes et une livraison plus rapide. La plupart des fournisseurs RPC payants incluent WebSocket dès les offres d'entrée de gamme.

Quand lire on-chain vs faire confiance à l'API

Règles pratiques issues de la production.

  • Faites confiance à l'API pour : order book temps réel, trades récents, vos propres ordres en attente, metadata des markets (slug, question, date de fin), découverte des events/markets.
  • Faites confiance à la chaîne pour : votre propre solde pUSD, votre propre inventaire d'outcome tokens, vérification des dépôts et retraits, résultats de résolution, état des litiges.
  • Recoupez les deux pour : tout élément financier que le bot a enregistré comme fill - faites correspondre l'événement "matched" de l'API avec le transfert CTF de la chaîne pour confirmer le settlement.

La règle d'attente de 5 secondes après un buy (chapitre 12) correspond à la réalité on-chain qui s'impose au temps de l'API. Un sell GTC soumis immédiatement après un market buy verra balance: 0 lors du contrôle chaîne, même si le CLOB a matched quelques instants plus tôt.

Code : détecter un litige UMA via subscription d'événements

Référence : surveiller en temps réel les litiges UMA liés à 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)

Le champ ancillaryData est un texte hex-encodé de type JSON contenant la question du market. Le décoder vous donne l'identifiant équivalent au slug à recouper avec vos positions ouvertes.

Foire aux questions

Où puis-je trouver le contrat pUSD de Polymarket ?
pUSD se trouve à l'adresse 0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB sur Polygon. Il a remplacé USDC.e comme collateral canonique de Polymarkets le 28 avril 2026. Lien Polygonscan : https://polygonscan.com/token/0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB.
Qu'est-ce que le contrat CTF sur Polymarket ?
CTF signifie Conditional Tokens Framework - le contrat ERC-1155 dérivé de Gnosis qui émet les outcome tokens (les parts YES et NO que vous tradez). Chaque market Polymarket est une position CTF avec une logique de redemption liée à la resolution d'UMA. Les bots ont rarement besoin d'interagir directement avec CTF ; le SDK s'en charge.
Comment m'abonner aux événements de litige UMA sur Polygon ?
Abonnez-vous aux événements "ProposePrice" et "DisputePrice" du contrat UMA Optimistic Oracle V2 via le WebSocket de votre fournisseur RPC Polygon. Filtrez par le champ requesterAddress (l'adaptateur oracle de Polymarkets) pour n'obtenir que les litiges liés à Polymarket. Exemples de code dans le chapitre.
Ai-je besoin de lire les données on-chain si je fais confiance à l'API Polymarket ?
Pour la plupart des stratégies, non. L'API CLOB fait autorité pour l'order book et les données de trade, et l'API gamma fait autorité pour les metadata. Vous lisez on-chain quand vous avez besoin de (a) alertes de litige UMA plus rapides que ce que l'API affiche, (b) vérifier qu'un dépôt est bien arrivé, ou (c) faire de l'analytics personnalisée sur les outcomes/positions.
Quelle est la latence des données Polygon on-chain par rapport à l'API Polymarket ?
Le temps de bloc Polygon est d'environ 2 secondes. L'API Polymarket reflète généralement les changements de l'order book en quelques centaines de millisecondes après le matching on-chain. Pour la plupart des signaux, l'API est plus rapide que vos propres lectures on-chain. Les litiges UMA sont une exception : l'événement on-chain se déclenche avant que l'UI ne reflète le litige.
Puis-je lire les positions Polymarket sans l'API CLOB ?
Techniquement oui - lisez CTF balanceOf(walletAddress, positionId) pour chaque position. En pratique, l'endpoint CLOB API /trade/positions est plus rapide, inclut les prix et agrège toutes vos positions. Revenez aux lectures on-chain uniquement si vous avez besoin d'une vérification ou si l'API est indisponible.