Skip to content
This repository was archived by the owner on May 25, 2026. It is now read-only.
This repository was archived by the owner on May 25, 2026. It is now read-only.

V2 settlement reverts ~35% of matched market BUYs with uniform 1.3M gas (logic revert), asymmetric on profitable orders #338

Description

@murphyxs8-ch1

Polymarket V2 Settlement Failure — Bug Report

Date: 2026-05-02
Reporter wallet (taker / proxy Safe): 0x0975c871e591c2a890095720b08386a221b62354
Affected contract: CTF Exchange V2 — 0xE111180000d2663C0091e4f400237545B87B996B
Selector: 0x3c2b4399 (matchOrders)


TL;DR

After the 28/04/2026 V2 cutover, ~35% of our successfully-matched market BUY orders are reverting at on-chain settlement. The failure pattern is non-random and asymmetric: orders that would have been profitable fail at roughly 3× the rate of orders that would have lost. All failures consume an unusually uniform ~1.3M gas before reverting with an empty reason (0x), and replay with 10M gas still reverts — confirming a logic revert, not OOG.

Out of 34 real on-chain trades, 12 settled as FAILED. Reconstructing the 12 against historical price data, 10 would have been winners, 2 losers (83% would-be WR). Among the 22 settled trades, WR is only 50%. Net: capital is being consumed by adverse selection on the small side while wins evaporate via settlement reverts.


Statistical pattern

Group Count Reconstructed result Notes
FAILED (settlement reverted) 12 10 WIN / 2 LOSS = 83% WR All would have profited but were reverted
CONFIRMED (settled) 22 11 WIN / 11 LOSS = 50% WR PnL net −$39.82
Combined "true signal" 34 21 WIN / 13 LOSS = 62% WR Close to backtest expectation

P(FAILED | would-be WIN) = 48%
P(FAILED | would-be LOSS) = 15%
3× asymmetry. Random/structural-only failures should affect both classes equally.


Four sample FAILED transactions (from session 2026-05-01 → 2026-05-02)

tx_hash block outcome price size maker
0x74fea333a05a8bfbfda6568d032dc78d30c5d94ab8d97fe4a7a57457d156b96a 86281482 Down 0.50 10.40 0x21fed8354bacefc952588e40fa4991edf8d834e9
0xc3a274b61db9d640f3a3861ab65819afc0da473e587700915cc9e038c9163639 86282239 Up 0.70 7.20 0xf2c061eaa8893ef48feb290d4e87bba7c464d97c
0x5ba73984ad7807e89d35f809f504a8156a803bcb152024aca17fee8cff9a9be0 86283437 Up 0.30 18.13 0x7a5237f9682d8ce14cd5cc70e2e3cdeef7c5f9c5
0x2125698b679b8012814c4c70fe8be93ef06991af21252801ab7d6dacf43a0fd1 86287483 Down 0.50 10.04 0x3bec844ee0c1334a3bb55b317a33edff4d83b8e7

All four were status=MATCHED via the off-chain CLOB and the matcher relayer submitted on-chain calls that reverted.


Technical signature of the failure

Attribute FAILED (n=4) CONFIRMED (n=10)
Selector 0x3c2b4399 0x3c2b4399
Target CTF Exchange V2 CTF Exchange V2
Gas used 1,296,940 – 1,300,946 (uniform) 415,324 – 515,068
Gas limit 1,350,000 1,350,000 / 1,800,000
% gas budget 96–96.4% 25–37%
Replay with 10M gas still reverts (logic revert) n/a
Revert reason 0x (empty) n/a
Maker count always 1 typically 2
Maker pUSD at block-1 $50k–$72k (drained to $0 after) mixed; some drain
Maker bytecode identical 124-byte Polymarket proxy identical
Maker creation recent (some <10 min before fill) mostly older

The uniformity of gasUsed across FAILED txs (within 0.3%) and the fact that gas exhaustion is not the cause strongly suggest a deterministic late-stage require() whose condition depends on some property of the maker's order or maker's Safe state — not on liquidity, slippage, or price movement.

Notably: the 4 FAILED makers held substantial pUSD at the trade block (50–72k USD each) and were drained to $0 immediately after — consistent with their orders being "valid enough" that the matcher accepted them, but failing some on-chain post-condition.


Questions for Polymarket engineering

  1. What is the specific require() / custom-error path consuming ~1.3M gas in matchOrders that produces an empty revert reason for these orders?
  2. Why does the failure cluster on single-maker fills against recently-funded Safes that hold substantial pUSD?
  3. Is there a known interaction issue between fresh proxy-wallet signature validation (signatureType) and the V2 cross-collateral path?
  4. Is the matcher relayer aware of which orders will fail before submission? If so, can these be filtered out?
  5. Why does the failure asymmetry favor adverse outcomes for the taker (i.e., the orders that would have been profitable fail more)?

We are not assuming malice — but the asymmetry is large enough that we need a public technical explanation before resuming live trading.


What we'd like

  • Acknowledgement of the issue and a public technical post-mortem.
  • Either: a CLOB-side filter that prevents matching against orders that will fail on-chain, OR a fix to the underlying require() logic.
  • Confirmation of whether other taker addresses are seeing the same FAILED rate (if it's universal vs. address-specific).

Reproducibility

All on-chain data and analysis scripts are saved locally:

  • _onchain_dump.json — full CLOB+RPC dump for 14 trades
  • _trace_failed.py, _verify_oog_hypothesis.py, _decode_makers.py, _balance_at_trade_time.py, _check_sigtype.py — reproducer scripts

Happy to share the full dataset or run additional diagnostics on request.

— Reporter contact: (reply to this thread / email)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions