Security Research DeFi Polymarket February 2026

Ghost Money: The Polymarket Exploit Draining Arb Bots in Real Time

A deep-dive into how a single public function - incrementNonce() - turns Polymarket's hybrid architecture against itself, letting attackers manufacture phantom liquidity, strand arbitrage bots naked on one leg of their hedge, and extract value that was never really there.

Nix | nixus.pro | Independent Security Research
TL;DR

Polymarket matches orders off-chain in milliseconds but settles them on-chain in seconds. Between those two moments, anyone can call incrementNonce() to invalidate their pending order signature for a gas fee measured in fractions of a cent. Arbitrage bots - which hedge across correlated markets - see their hedge leg evaporate. They are left with a naked position. The attacker knows exactly which side the bot is exposed on and closes against them. The result: synthetic price moves of thousands of percent with zero real volume, bot accounts drained, and no fast fix in sight.

01 - The Attack Vector

How One Function Call Kills a Trade After It's Already Been Matched

Polymarket runs on Polygon, a proof-of-stake Ethereum sidechain. Its exchange contract uses an order-book model where users sign typed data (EIP-712) off-chain and submit those signatures to a centralized matching engine. When two orders match, the matching engine sends both signatures to the on-chain settlement contract, which verifies them and transfers USDC between accounts. Fast off-chain matching, trustless on-chain settlement. In theory, the best of both worlds.

In practice, there is a gap. Off-chain matching happens in under 100 milliseconds. On-chain settlement can take anywhere from two seconds to several minutes depending on Polygon's block time and gas market conditions. That gap is the entire attack surface.

Every user account on Polymarket's exchange contract has a nonce - an integer that increments with each filled order, functioning as a replay-protection mechanism. Signatures are bound to a specific nonce value. If the nonce on-chain doesn't match the nonce embedded in the signature, the settlement transaction reverts.

The exchange contract exposes this function publicly:

// Polymarket CTF Exchange - simplified
function incrementNonce() external {
    uint256 newNonce = ++nonces[msg.sender];
    emit NonceIncremented(msg.sender, newNonce);
}
Solidity

No authorization required. Anyone can call it on their own account at any time. The intended purpose is legitimate: if your private key is compromised, you can invalidate all outstanding signed orders instantly by bumping your nonce. One call, all pending signatures dead.

The exploit repurposes this mechanism as a precision weapon. Here is the full sequence:

1
Attacker places a large resting limit order The attacker signs a limit order for 10,000 shares on a target market - say, YES shares at 0.50 USDC. This order is submitted to Polymarket's off-chain order book. The attacker's nonce at this point is N.
2
Arbitrage bot detects the order and hedges A market-making or arb bot scans the order book, identifies a pricing discrepancy, and places the complementary leg. Its matching logic fires. Both sides appear matched. The bot simultaneously opens a hedge position on a correlated market or exchange, believing the Polymarket leg is confirmed.
3
Matching engine queues the settlement transaction The off-chain matching engine bundles both signed orders into a settlement calldata payload and submits it to the Polygon mempool. The transaction is pending - not yet included in a block.
4
Attacker calls incrementNonce() immediately The attacker sends a second transaction calling incrementNonce() on their account. This costs roughly 0.001 MATIC - effectively nothing. If this transaction lands before the settlement transaction, the attacker's signature is now invalid.
5
Settlement transaction reverts on-chain When the settlement transaction executes, the contract checks nonces[attacker] == N. But nonces[attacker] is now N+1. Signature verification fails. The entire settlement reverts. No trade. No USDC transfers.
6
Bot is stranded. Attacker closes in. The bot's Polymarket position never existed on-chain. But its hedge leg on the correlated market is very real. The bot is now naked - full exposure, no offset. The attacker knows exactly which direction the bot is wrong-footed and trades aggressively into that vulnerability, extracting the bot's capital.

The cost to execute this attack is near-zero. A Polygon transaction costs fractions of a cent. The attacker's only constraint is timing - they need to get the nonce increment on-chain before the settlement tx confirms. On Polygon, blocks arrive roughly every two seconds. The window is real and repeatable.

Attack Cost vs. Potential Gain

Gas cost to call incrementNonce() on Polygon: ~0.0008 MATIC (approx. $0.0003 at current prices). Potential gain from stranding a bot hedging a 10,000-share position: hundreds to thousands of USDC per strike, depending on position size and market volatility at the moment of exposure.

02 - Real Example

The Dutch Prime Minister Market: +35,000% With Zero Actual Volume

The clearest documented instance of this exploit in action was the Dutch Prime Minister prediction market on Polymarket. The market was pricing the probability of a specific political outcome - a low-interest, low-volume contract sitting near 0.1% probability. Standard stuff.

Then, within a compressed time window, the implied probability moved from 0.1% to approximately 35%. That is a 35,000% price move. In a liquid market, a price move of that magnitude would require enormous buy-side pressure - thousands of transactions, millions of USDC in volume, a major information event.

0.1%
Starting implied probability
35%
Peak implied probability
~$0
Verified on-chain volume driving the move
35,000x
Price move with ghost liquidity

What actually happened: orders existed off-chain in the matching engine. They were matched. Prices updated in the Polymarket UI. Traders saw a 35% market. Arb bots responded, moving capital from correlated markets. Hedges were opened. Then the on-chain settlement failed - systematically, repeatedly. The orders that drove the price move were never real in the settlement sense. They were ghost liquidity: real enough to influence behavior, invisible on the chain.

This is the dangerous part. Polymarket's price feeds are consumed by downstream services - aggregators, analytics dashboards, other prediction markets calibrating their own odds. A manufactured price move on Polymarket doesn't stay on Polymarket. It propagates through the information layer of prediction markets broadly, distorting probability estimates in real markets that humans and institutions actually rely on.

The Dutch PM market recovered when the ghost orders expired or were otherwise invalidated. Traders who acted on the fake 35% price were left holding positions priced against a distorted market. Some recovered. Others did not.

Signal Contamination

Polymarket has been used as a reference source for political probability estimates by journalists, researchers, and campaign strategists. If those price signals can be artificially moved with pocket change, their value as information collapses entirely. The exploit doesn't just steal money - it corrupts data.

03 - Why Arb Bots

Targeting the Infrastructure That Makes Polymarket Work

Polymarket operates with thin retail participation relative to its headline volume numbers. The overwhelming majority of its liquidity - the resting limit orders that make trading possible - comes from automated market makers and arbitrage bots. Without them, spreads blow out, markets go illiquid, and the platform becomes unusable for casual traders.

These bots operate on a specific model: they maintain delta-neutral or near-neutral positions by hedging across correlated markets. A bot might hold YES shares on "Biden wins 2028" on Polymarket while simultaneously holding a short position on a correlated Kalshi contract or a crypto token whose price correlates with the outcome. Each leg is cheap in isolation. Together, they form a hedged book.

That hedged book is the attack target.

The Hedge Leg Architecture

When an arb bot detects that Polymarket's price diverges from a correlated instrument, it acts immediately. The sequence is:

  1. Bot detects price discrepancy across markets
  2. Bot submits take-liquidity order on Polymarket (the underpriced leg)
  3. Bot simultaneously opens hedge on correlated market (exchange, options, or another prediction platform)
  4. Both legs confirmed - bot is flat, earning the spread

Step 4 is the assumption that breaks. The bot treats the Polymarket match as confirmed the moment the off-chain matching engine acknowledges it. That acknowledgment triggers the hedge. But the Polymarket leg isn't confirmed - it's pending settlement. If that settlement gets killed by a nonce increment, the bot has a real hedge position on an external market with no offsetting position on Polymarket. It's carrying unintended directional risk.

The attacker knows which side the bot is naked on because they designed the original resting order to create a specific exposure. If the attacker posted a 10,000-share YES limit order and the bot bought it (taking YES), then the bot's hedge is SHORT on the correlated market. The attacker now sells aggressively into the correlated market, pushing price down, and the naked-short bot gets run over.

// Bot's internal state after nonce-kill attack

Position {
  polymarket_YES_shares: 10000,    // Does NOT exist on-chain
  polymarket_settled:    false,    // Settlement reverted
  hedge_position:        -10000,   // Very real. On external exchange.
  net_delta:             -10000,   // Naked short. Fully exposed.
  bot_awareness:         null      // Bot doesn't know yet.
}
Pseudocode

The bot's awareness lag is the final piece. Well-engineered bots will eventually detect that the on-chain settlement failed and attempt to unwind the hedge. But "eventually" is doing heavy lifting here. On-chain confirmation monitoring typically has a delay. By the time the bot reacts, the attacker has already closed their position against the bot's forced unwind, extracting maximum value from the moment of maximum exposure.

Sophisticated attackers can repeat this pattern across multiple bots simultaneously, targeting the same market from different angles, compounding the disruption.

04 - The Architectural Flaw

No Sequencer. No Risk Engine. No Pre-Trade Validation. Just Trust.

Polymarket's architecture is, at its core, optimistic. Off-chain matching happens with the assumption that settlement will succeed. There is no mechanism to validate that assumption before the matching engine acts on it. No check that the user's nonce is still valid. No confirmation that the signature hasn't been revoked. No pause-and-verify step between match and broadcast.

This design is not unusual for hybrid exchanges - it's common. The tradeoff is explicit: you either have fast off-chain matching with settlement risk, or you have slow on-chain matching with no settlement risk. Polymarket chose speed. The settlement risk was considered theoretical. It isn't.

The Timing Gap in Numbers

Polymarket's off-chain matching engine operates in sub-100ms latency. Polygon's average block time is approximately 2.0-2.2 seconds. That means there is a minimum of a 2-second window between a match being confirmed off-chain and it becoming immutable on-chain - and in practice the window is longer, because the settlement transaction must be included in a block after being submitted to the mempool.

During that 2+ second window, any of the following can invalidate the pending settlement:

The absence of a sequencer means there is no canonical ordering of events. The order of transactions landing on-chain is determined by gas price and validator discretion. A sophisticated attacker with MEV knowledge can use Polygon's mempool dynamics to increase the probability that their nonce increment lands before the settlement - not just by racing, but by strategically pricing their gas to win the ordering game.

The Core Structural Problem

Polymarket's matching engine treats an order match as a commitment. The blockchain does not. That semantic gap - between "matched" and "settled" - is the entire attack surface. Every system that confuses these two states is vulnerable.

What a Proper Architecture Looks Like

Exchanges that have solved this problem do so with one of two approaches. First: fully on-chain orderbooks (like Serum's original design on Solana) where matching itself is an on-chain operation and there is no off-chain state to exploit. Expensive, slow, and costly in fees, but settlement-safe by construction.

Second: commit-reveal schemes where a match produces a cryptographic commitment that must be acknowledged on-chain before either party can update their nonce. The nonce increment is blocked until the pending settlement resolves. This adds latency but closes the window entirely.

Polymarket implements neither. It relies on the practical difficulty of the attack - the speed required, the cost, the complexity of timing transactions on a live chain - as its primary defense. That's security through friction, not security through design.

05 - Why It Can't Be Quickly Fixed

Every Patch Breaks Something Else

The obvious question: why hasn't this been fixed? The honest answer is that every available fix involves a fundamental architectural trade-off that would change the nature of the platform. This isn't a bug that can be patched with a few lines of Solidity. It's a consequence of the design itself.

Option A: Add a Sequencer

A sequencer imposes a canonical ordering on transactions. It would allow the system to guarantee that a settlement transaction lands before any nonce-incrementing transaction from the same account. Problem: Polymarket currently has no sequencer. Building one means rebuilding the matching engine from scratch with a new ordering layer. That's months of engineering, a full security audit, and a complete re-architecture of how orders flow from users to the chain. It also introduces sequencer centralization risk - now a single infrastructure component can censor or reorder trades.

Option B: Block incrementNonce() While a Settlement is Pending

The contract could track pending settlement transactions and refuse nonce increments while any are in flight. Sounds simple. The implementation requires the off-chain matching engine to write pending settlement records to the chain (or to a trusted oracle), and the contract to read that state synchronously before allowing nonce increments. Every nonce increment becomes an on-chain read with a dependency on fresh settlement state. Gas costs increase. Latency increases. And critically, the "pending settlements" ledger itself becomes a new attack surface.

Option C: Pre-Validate Nonce Before Matching

The matching engine could query the current on-chain nonce of each order submitter before matching, ensuring the nonce embedded in the signature matches the live chain state. This adds a mandatory on-chain RPC call to every match operation. At Polymarket's throughput, this creates either massive latency or massive RPC costs. It also doesn't fully solve the problem - the nonce is valid at query time, but can still be incremented before settlement confirms.

Option D: Nonce Locking via Deposit Hold

Require users to lock their nonce increment capability by posting a small on-chain deposit when they place an order. The deposit is slashed if they call incrementNonce() while a matched settlement is pending. This changes the economics of the attack - suddenly there's a real cost. But it requires users to make on-chain calls to place and cancel orders, which defeats the purpose of off-chain matching entirely, and creates a new complexity layer for normal users.

The Uncomfortable Truth

None of these options are quick. None are clean. They all trade one problem for another. The architecture that makes Polymarket fast and cheap to use is the same architecture that makes it exploitable. You can't have both at the same time without a fundamentally different approach to on-chain/off-chain coordination.

06 - Broader Implications

The Industry-Wide Vulnerability Nobody Wants to Talk About

Polymarket is not an outlier. The hybrid off-chain matching / on-chain settlement architecture is nearly ubiquitous among DeFi exchanges that want real throughput without the cost of fully on-chain orderbooks. dYdX v3, early versions of Perpetual Protocol, several Polygon-native DEX designs, and dozens of smaller prediction markets use variations of this model.

Every single one of them is vulnerable to some version of the nonce-based invalidation attack, as long as three conditions are true:

  1. Order signatures are bound to a cancellable nonce
  2. Matching happens before on-chain settlement confirms
  3. The nonce can be incremented cheaply by the user

Most of these platforms have never experienced a documented exploit because the attack requires specific knowledge (knowing the architecture is vulnerable), timing skill (racing transactions on a live chain), and a target rich enough to justify the effort. As prediction markets grow in volume and bot infrastructure becomes more sophisticated, the targets get richer and the attacks become more attractive.

The DeFi "Move Fast" Tax

The culture of DeFi development pushes teams to ship fast, iterate publicly, and treat audits as post-hoc validation rather than pre-launch requirements. Polymarket's hybrid architecture was never a secret - it's the documented design. The nonce mechanism exists in the public contract. Security researchers could have (and some did) identify this pattern years ago.

The problem is incentive misalignment. Exploiting the attack requires capital, timing, and knowledge. Most security researchers aren't going to demonstrate it on a live mainnet contract with real USDC at stake. Most bug bounties don't cover "architectural design decisions" - only implementation bugs. So the vulnerability persists in the open, visible to anyone who reads the contract code carefully, documented nowhere officially, and silently exploited by those who figured it out.

This is the DeFi tax: the premium you pay in systemic risk for deploying unaudited architectural assumptions at scale. Polymarket processed over $1 billion in volume in 2024. The attack surface has existed for that entire period.

Prediction Market Integrity at Stake

The downstream consequence of manufactured price moves - corrupted probability signals propagating through aggregators, media, and institutional decision-makers - is arguably worse than the direct financial damage to bots. Markets are only useful as information mechanisms if their prices reflect real information. Ghost liquidity inserts fake information. When journalists cite "Polymarket's 35% probability" on a political event that was manufactured by a $0.0003 nonce increment, the entire premise of prediction markets as truth-aggregation machines collapses.

07 - Protect Yourself

What to Do If You're Running Bots, Trading Manually, or Both

For Bot Operators

Monitor on-chain settlement confirmation, not off-chain match status. The off-chain match acknowledgment is meaningless until the settlement transaction is confirmed in a block with sufficient depth. Do not open hedge positions until on-chain confirmation. This will cost you speed and some opportunities - that's the price of not being the target.

Watch for NonceIncremented events from counterparties. The exchange contract emits a NonceIncremented event every time someone bumps their nonce. Build event listeners that flag accounts repeatedly emitting this event - they are either compromised keys being rotated, or they are running the attack. Either way, avoid trading against them until the pattern clears.

// Event filter - watch for repeated NonceIncremented from same address
const filter = exchange.filters.NonceIncremented(
  suspiciousAddress,
  null
);

exchange.on(filter, (address, newNonce, event) => {
  flagHighRiskCounterparty(address, event.blockNumber);
  cancelPendingOrders(address);
});
JavaScript / ethers.js

Reduce hedge lag. If you must hedge before settlement confirms, use instruments with faster confirmation and lower manipulation risk for the hedge leg. Limit position sizes on Polymarket until settlement confirms. Treat every Polymarket position as unconfirmed for at least 3 Polygon block confirmations (~6 seconds) before considering it real.

Implement circuit breakers. If your settlement failure rate exceeds a threshold (more than 2-3% of matched orders failing to settle), pause trading on that market automatically. Repeated settlement failures on a specific market are a signal that you are being targeted.

For Manual Traders

Do not trade into abnormal price moves without on-chain volume confirmation. If you see a prediction market probability jump by more than 10-15 percentage points in a short window, check the on-chain transaction history before acting. If the on-chain volume doesn't match the price move, it's potentially ghost liquidity. The price will revert when the ghost orders expire.

Verify that the price you're trading at reflects settled trades. Polymarket's UI reflects off-chain order book state, not on-chain settlement state. There can be a meaningful divergence. For high-stakes trades, verify the last settled prices by querying the contract directly or using a block explorer to confirm recent settlement transactions.

Be skeptical of extreme probability estimates near major events. Adversarial actors have the most incentive to manufacture fake signals when the stakes are highest - election nights, major announcements, shock events. These are exactly the moments when price manipulation via nonce exploit will cause the most collateral damage.

For Everyone

The exploit exists. It's been documented. It will continue to be used until the architecture changes or the platform makes it expensive enough to deter casual attackers. The best defense is informed skepticism: understand what "price" means on Polymarket (off-chain order book state, not settled on-chain state) and adjust your trust in that number accordingly.

Polymarket is a useful tool. It's not a truth machine. Right now, it's closer to a real-time manipulation target with a useful truth-signal underneath the noise. Learn to separate the two.


Conclusion

The Bill That Always Comes Due

The incrementNonce() exploit is not a sophisticated zero-day. It doesn't require advanced cryptography, novel smart contract trickery, or insider access. It requires reading the contract documentation, understanding the timing gap between off-chain matching and on-chain settlement, and having the patience to execute a two-transaction attack that costs less than a cup of coffee.

That's what makes it damning. The attack has been executable since Polymarket deployed its current exchange contract. Every bot that got burned, every ghost liquidity event that corrupted a probability estimate, every manufactured price move that a journalist cited as real - all of it traces back to a design decision that prioritized speed over settlement finality.

The hybrid architecture will not disappear. It's too useful. But the industry needs to accept that "optimistic matching" is not a neutral design choice - it's a bet that attackers won't bother to exploit the gap. That bet gets worse as the markets get bigger. It's already being lost.

Ghost money is real money. It just costs almost nothing to make.