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
- What is the specific
require() / custom-error path consuming ~1.3M gas in matchOrders that produces an empty revert reason for these orders?
- Why does the failure cluster on single-maker fills against recently-funded Safes that hold substantial pUSD?
- Is there a known interaction issue between fresh proxy-wallet signature validation (signatureType) and the V2 cross-collateral path?
- Is the matcher relayer aware of which orders will fail before submission? If so, can these be filtered out?
- 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)
Polymarket V2 Settlement Failure — Bug Report
Date: 2026-05-02
Reporter wallet (taker / proxy Safe):
0x0975c871e591c2a890095720b08386a221b62354Affected contract: CTF Exchange V2 —
0xE111180000d2663C0091e4f400237545B87B996BSelector:
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
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)
0x74fea333a05a8bfbfda6568d032dc78d30c5d94ab8d97fe4a7a57457d156b96a0x21fed8354bacefc952588e40fa4991edf8d834e90xc3a274b61db9d640f3a3861ab65819afc0da473e587700915cc9e038c91636390xf2c061eaa8893ef48feb290d4e87bba7c464d97c0x5ba73984ad7807e89d35f809f504a8156a803bcb152024aca17fee8cff9a9be00x7a5237f9682d8ce14cd5cc70e2e3cdeef7c5f9c50x2125698b679b8012814c4c70fe8be93ef06991af21252801ab7d6dacf43a0fd10x3bec844ee0c1334a3bb55b317a33edff4d83b8e7All four were status=MATCHED via the off-chain CLOB and the matcher relayer submitted on-chain calls that reverted.
Technical signature of the failure
0x3c2b43990x3c2b43990x(empty)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
require()/ custom-error path consuming ~1.3M gas inmatchOrdersthat produces an empty revert reason for these orders?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
require()logic.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 scriptsHappy to share the full dataset or run additional diagnostics on request.
— Reporter contact: (reply to this thread / email)