Polymarket Bot Tutorial · Chương 18 trên 32
UMA dispute prediction bots trên Polymarket: phát hiện Optimistic Oracle proposals, dự đoán khả năng dispute, khai thác chênh lệch giá trước và sau dispute, và tránh vòng xoáy tử thần của disputed markets.
Chương này bao gồm những gì
Optimistic Oracle (OO) của UMA là lớp giải quyết cho các market trên Polymarket, và disputes tạo ra các bất thường về giá trước và sau khi chúng xảy ra. Các pattern có thể trade tồn tại ở cả hai phía của dispute, nhưng chiến lược này cực kỳ phức tạp về vận hành và đã làm cháy nhiều bot hơn là nuôi sống chúng. Đây là playbook nói thật.
- UMA Optimistic Oracle hoạt động như thế nào
- Phát hiện một proposal on-chain
- Dispute predictors (volume, ambiguity, history)
- Chênh lệch giá trước dispute
- Thiết lập trade sau dispute
- Khi NÀO KHÔNG nên trade disputed markets
- Code: subscribe vào các sự kiện UMA proposed/disputed
UMA Optimistic Oracle hoạt động như thế nào
Optimistic Oracle (OO) của UMA là lớp giải quyết tranh chấp cho Polymarket. Mọi quá trình resolve market đều đi qua OO; phần lớn là không bị tranh chấp và tự động settle. Những trường hợp bị tranh chấp - disputes - sẽ kích hoạt một giai đoạn voting kéo dài 24-72 giờ, trong đó các token holder của UMA quyết định kết quả.
Vòng đời: resolver của Polymarket đề xuất một price (0 = NO thắng, 1 = YES thắng). Sau cửa sổ challenge 2 giờ, nếu không ai dispute thì price được finalize và hợp đồng CTF phân phối payout. Nếu có ai dispute, market bước vào voting window; UMA holders bỏ phiếu, đa số thắng.
Đối với bot, các event quan trọng là ProposePrice (proposal được đưa ra, challenge window mở) và DisputePrice (dispute được nộp, giai đoạn voting bắt đầu). Hãy subscribe vào các event này để theo dõi trạng thái resolve của market theo thời gian thực.
Phát hiện một proposal on-chain
Hợp đồng UMA OO trên Polygon phát ra event ProposePrice với các tham số (requester, identifier, timestamp, ancillaryData, proposer, proposedPrice). Lọc theo địa chỉ requester đã biết của Polymarket để giới hạn chỉ các proposal liên quan.
POLY_REQUESTER = "0x..." # Polymarket Adjudicator
filt = oo_contract.events.ProposePrice.create_filter(
fromBlock="latest",
argument_filters={"requester": POLY_REQUESTER}
)
for event in filt.get_new_entries():
market_id = decode_ancillary(event.args.ancillaryData)
proposed = "YES" if event.args.proposedPrice == 1e18 else "NO"
print(f"PROPOSE: market {market_id} → {proposed}")
Trường ancillaryData là JSON được mã hóa hex, mô tả câu hỏi của market. Giải mã nó sẽ cho bạn identifier của market để đối chiếu với các vị thế mở của mình.
Dispute predictors (volume, ambiguity, history)
Ba tín hiệu trước dispute có tương quan với các dispute thực sự sau đó.
- Tổng volume: các market có > $1M volume trọn đời bị dispute với tỷ lệ cao gấp 4 lần so với market nhỏ. Càng nhiều vốn được đặt cược = càng nhiều động lực để challenge.
- Cách diễn đạt mơ hồ: bất kỳ market nào có "or similar," "officially confirmed," hoặc điều kiện kép (ngày AND một kết quả cụ thể) đều có tỷ lệ dispute cao hơn.
- Dispute trước đó trên cùng sự kiện: nếu một proposal trước đã từng bị dispute và được đề xuất lại, proposal thứ hai có xác suất bị dispute cao gấp 2-3 lần mức bình thường.
Một bot có thể tính điểm "dispute probability" từ các đặc trưng này và tránh mở vị thế trong những market vượt ngưỡng khi gần đến thời điểm resolve.
Chênh lệch giá trước dispute
Trong vài giờ trước một dispute có khả năng cao, giá thị trường thường cho thấy chuyển động bất đối xứng: phía mà proposer gọi là YES trôi xuống (vì trader lo sợ dispute sẽ đảo kết quả), phía còn lại trôi lên.
Nếu bạn có quan điểm định hướng về việc dispute sẽ được giải quyết theo hướng nào, đây là một cửa sổ trade được. Rủi ro: nếu dispute không xảy ra, sự bất đối xứng sẽ đảo ngược khi challenge window đóng mà không có gì xảy ra và giá bật trở lại theo hướng đề xuất ban đầu.
Nói thật: đa số các trade chênh lệch trước dispute đều là lệnh lỗ, vì phần lớn challenge được giải quyết theo lợi cho proposal ban đầu. Chiến lược này chỉ hiệu quả khi bạn có thông tin cụ thể về lý do khiến dispute này nhiều khả năng sẽ được duy trì.
Thiết lập trade sau dispute
Sau khi dispute được nộp, market trade trong trạng thái "limbo" suốt 24-72 giờ - biết là có dispute, nhưng kết quả sẽ do bỏ phiếu quyết định. Có hai setup.
Hội tụ về UMA consensus: nếu tín hiệu giải quyết dispute xuất hiện sớm (ví dụ một UMA voter nổi bật công khai nghiêng về một phía), giá sẽ di chuyển về phía kết quả đó. Một bot theo dõi tín hiệu từ UMA Discord / Twitter + price action có thể bắt được điều này 30-60% thời gian.
Volatility farming: các giai đoạn limbo có spread rộng. Một market maker kiên nhẫn có thể kiếm spread tax qua nhiều trader luân phiên ra vào trong voting window. Rủi ro inventory rất cao; hãy sizing tương ứng.
Cả hai đều đòi hỏi bạn thoải mái với khả năng thực sự là kết quả sẽ đi ngược vị thế của mình. Hãy xem inventory trong giai đoạn dispute nhiều nhất chỉ bằng nửa size.
Khi NÀO KHÔNG nên trade disputed markets
Ba tình huống mà trade dispute mặc định là sai.
- Bạn không có góc nhìn cụ thể về UMA. Nếu edge duy nhất của bạn là "theo tôi proposal ban đầu có vẻ đúng," thì bạn không có edge nào so với chính proposer ban đầu - và người nộp dispute lại nghĩ ngược lại. Kết quả voting là một cú tung đồng xu mà bạn không thể dự đoán.
- Dispute nằm trên một cách diễn đạt mơ hồ. Các UMA voter thường nghiêng về cách đọc nghiêm ngặt của câu hỏi. Nếu market ghi "by January 31" và sự kiện xảy ra vào ngày 1 tháng 2, UMA sẽ resolve NO bất kể trực giác của cộng đồng trader ra sao.
- Bạn đang giữ inventory từ trước khi dispute xảy ra. Thêm vào một vị thế sẵn có để "average down" trong giai đoạn limbo là pattern kinh điển dẫn đến đốt vốn. Giữ hoặc thoát, đừng bao giờ thêm.
Code: subscribe vào các event UMA proposed/disputed
Tham khảo: WebSocket subscription tới các event của UMA OO, được lọc theo Polymarket requester.
from web3 import Web3
w3 = Web3(Web3.WebsocketProvider(POLYGON_WSS))
oo = w3.eth.contract(address=UMA_OO_ADDR, abi=UMA_OO_ABI)
POLY = "0x...".lower()
dispute_filter = oo.events.DisputePrice.create_filter(fromBlock="latest")
propose_filter = oo.events.ProposePrice.create_filter(fromBlock="latest")
while True:
for event in dispute_filter.get_new_entries():
if event.args.requester.lower() == POLY:
on_dispute(event)
for event in propose_filter.get_new_entries():
if event.args.requester.lower() == POLY:
on_propose(event)
time.sleep(2)
def on_dispute(event):
market_q = decode_ancillary_to_question(event.args.ancillaryData)
send_telegram(f"DISPUTE: {market_q}")
# If we hold a position in this market, alert + consider exit
if market_q in our_positions:
flag_position_for_review(market_q)
Pattern là: subscribe, decode, alert. Hành động trade dựa trên dispute bằng thuật toán là rất rủi ro; nhiệm vụ của bot thường là đưa event ra cho người review.





