LowfieldLabs

The $83 Mirage: Paper Said Profit, Live Was Dead in Eight Minutes

2026-05-12 — Saga A: Paper vs. Live — Part 1 of 5

Saga A: Paper vs. Live — Part 1 of 5 By LowfieldLabs — dated kill decisions from the hypothesis ledger

The paper simulation said the strategy made money. Two and a half hours of simulated trading reported +$83.20 — a figure our internal audit file rounds to “+$83/hr” and which, at the time, nobody thought to question. On 2026-04-14 we funded the live version of the same strategy with $633.37 USDC and turned it on. Eight minutes later we killed it. The wallet held $514.14.

This is the postmortem of the gap between those two states — not the strategy, which was mediocre, but the simulator that called it viable. The bot is dead, the wallets it replicated are dead, and nothing in this piece touches anything currently traded. What follows is safe to print in full, which is exactly why we’re printing it: the failure mode is generic, it will be in your simulator too, and it is cheap to check for before it costs you money.

One editorial note before the numbers: this entry records what we believed on 2026-05-12, the date of the code audit. A later ground-truth reconstruction — Part 3 of this saga — re-examined every figure below and found that some of them, including the blowup numbers themselves, were measurement artifacts. That is a separate story. The checklist at the end of this piece is what survives regardless.

The setup

The bot, which we call b27b after the pseudonymous on-chain wallet whose behavior it replicated, was a maker-buy bot on Polymarket’s BTC Up/Down five-minute markets. The design, as specified:

None of this is exotic. It is the kind of ladder a first market-making attempt produces, and the paper sim — a few hundred lines in paper_bot.py — was built to match. The sim reported steady profitability. The pre-deploy review read the paper output, found no contradiction, and approved a real-money run. That approval is the event this postmortem is about.

Anatomy of the divergence

The audit, run after the blowup, went straight to the fill model. Here is the relevant code, _simulate_fills() at paper_bot.py:391-440, verbatim:

# Fill requires: (a) observed book is below our level, AND
# (b) observed book has strictly moved down since we posted.
ref_bb = o.ref_best_bid_at_post
book_moved_down = (ref_bb <= 0) or (best_bid < ref_bb)
if best_bid < o.price and book_moved_down:
    o.filled = o.size

Read the two conditions. The sim credits a fill on a resting buy only when (a) the top-of-book bid is below our price, and (b) the top-of-book bid has strictly moved down since we posted. The book must be observed moving — being in a state below the level is not enough.

That is not how the venue works. On a real central limit order book, any taker-sell that crosses the resting level executes against it. The mechanism is execution-side, not observation-side. A seller’s market order does not wait for the best bid to tick down on your feed before it fills your ladder; it fills whatever it crosses, whether or not you ever saw the book move.

So the paper fill condition is a strict subset of the live fill condition. The sim only counted the fills that were hardest to get — the ones accompanied by a visible top-of-book move — and silently discarded the rest. The audit’s detection signature for this class of bug: live fill counts running 5-10x the paper fill count for the same quoting logic.

This matters because of which fills the sim was discarding. A taker-sell that crosses your level without warning is precisely the fill you least want — it is informed flow hitting your ladder. By construction, the paper sim filtered out the most toxic fills and kept the benign ones. Paper didn’t just get the count wrong; it got the composition wrong in the direction most flattering to the strategy.

The audit also established that this was not a new bug class, just a new instance. An earlier failure in a taker-side bot (catalogued as P08) had the mirror-image flaw: the paper model assumed entries at the next observable fill, while reality filled at the trigger price within milliseconds, so paper overcounted profitable entries — a realistic resimulation flipped 6 of 7 cells from PASS to FAIL. Same structure, opposite direction:

Dimension Taker (P08) Maker (b27b)
Domain Entry-side execution Resting-order execution
Paper claim “Entry at next observable fill” “Fill only on visible top-of-book crossing”
Reality Entry at trigger price within ms Fill on any taker-cross of level
Direction of error Paper overcounted Paper undercounted (as then believed)

Both are the same class of failure: the paper fill model is structurally different from the live execution mechanism, and nobody diffed the two before trusting the output.

Eight minutes live

The live run supplied the fills the sim had been hiding. The bot launched at 02:40 UTC on 2026-04-14 and was killed eight minutes later, the wallet down $119.23 from its $633.37 opening balance — a cash delta we reported at the time as the loss, and which (per the editorial note above) later reconstruction would revisit.

The postmortem catalogued six bugs, none of which the paper phase caught:

  1. No per-token position cap — the bot accumulated 260+ shares on a single bar.
  2. No per-wallet exposure cap — it spent the full $633 in eight minutes.
  3. The reprice anchor chased upward, so every fill compounded exposure in the direction of the informed flow that had just filled it.
  4. Discovering 4 bars ahead fanned out 40 concurrent tokens, each with a 5-rung ladder.
  5. Asymmetric fills with no UP/DOWN parity enforcement left unhedged directional exposure.
  6. The fill-model mismatch described above — paper’s visible-touch requirement versus live’s any-cross execution.

Bugs 1 through 5 are ordinary risk-control omissions; any competent review should have caught them on paper, because none of them depend on execution realism. Bug 6 is the one that made the paper number look trustworthy while bugs 1 through 5 waited underneath it. That layering is the real lesson: a wrong fill model doesn’t just misestimate PnL, it suppresses the evidence that would expose everything else.

The five-step fill-model audit

The generalized output of the audit is a checklist we now run before trusting any backtest. It costs about $0.20 of API time and zero compute on the b27b codebase, and it applies to any simulator, maker or taker, on any venue:

Fill-Model Audit — run before trusting any paper PnL

  1. State the paper fill condition explicitly. What event in the simulated orderbook triggers a fill? If you cannot write it in one sentence, you do not know what your backtest measured.
  2. State the live fill condition. What event in the real orderbook triggers a fill on the venue? Execution-side, not observation-side.
  3. Compare the two. Is the paper condition a strict subset of the live condition — or a superset?
  4. Direction determines the bias. Subset means paper undercounts fills (the b27b pattern, as then understood); superset means paper overcounts (the P08 pattern). Either direction invalidates the number until quantified. Audit before trust.
  5. Ratio-test empirically. Run the paper sim on a small slice of real orderbook-and-fill tape. Compare paper_fill_count to real_fill_count over the same window. A ratio outside [0.5, 2.0] fails the sim — do not backtest on it until the fill model is fixed.

Two operational rules fell out of this. First, every future maker-bot spec must state the fill condition in the specification, not just in code — the b27b flaw hid precisely in the gap between what the designer thought the sim did and what _simulate_fills() actually did. Second, no existing paper result gets re-trusted without re-validation against real fill data. The cheapest real-money probe you can legally run is worth more than any simulator you have not ratio-tested.

The kill ledger

LowfieldLabs keeps a kill ledger: one dated page per hypothesis, including — especially — the ones that died. The count currently stands at 1,232 hypothesis pages, 15 proven. b27b is one of the dead, and its page earns its keep twice: once as a blowup, and once as the origin of the fill-model audit above.

In Part 2: the second live blowup, launched the day after this one with the lessons of b27b applied — which produced six entirely new failure modes, because that is how this works.


This piece describes research methodology and historical experiments on dead systems. It is not financial advice.

Get the kill decisions by email