LZLZL/Prediction markets/Engineering
FREEDO IT G · EngineeringTrap

The redeemable trap
and the phantom-empty position

2026-08-21 · two API misreadings that nearly cost me money

There is a redeemable field, and the name suggests it tells you whether a position can be redeemed. Measured, it cannot be used to determine win or loss: after a board closes, winners and losers are flagged identically. The sibling trap is worse — query positions, get "empty", assume you are clear, and the money is still there.

1Trap one: after close, both sides claim to be redeemable

The book empties once a board closes. Query positions then and you see something odd:

You holdThe API saysReference priceTruth
the winning sideredeemable: true≈ 0.5worth $1
the losing sideredeemable: true≈ 0.5worth $0

Where does 0.5 come from? With the book empty the best bid is 0 and the best ask is 1, so the midpoint is (0 + 1) / 2 = 0.5. It is not the market's valuation of the position — it is the numeric expression of "there is no market".

⚠ Both reasonable workarounds fail

Workaround one: only redeem positions valued ≥ $0.50. The result is that losing positions pass too — they also show 0.5. You send redemption transactions for a stream of certainly-worthless positions, burning fees.

Workaround two: raise the threshold to ≥ 0.9. Now winning positions are stuck — they show 0.5 as well and never clear the bar. Money sits there until something else rescues it.

Both were tried, both failed. The problem is not the threshold value; it is that judging outcomes from price is the wrong idea entirely — after close, that price carries no information about who won.

2The fix: do not ask the price, ask the settlement

settlement complete AND my side's payout share > 0 on-chain: the payout denominator is non-zero, and my outcome's numerator is positive
Why it is better
It is the settlementnot inferred from price, volume or any helper field
Immune to book stateempty book, no quotes, cold market — all irrelevant
Independently verifiablepublic on-chain; reproduce it on any settled board
No threshold to pickgreater than zero wins, equal to zero loses

After switching to those two values the misjudgements stopped. Re-checking history with it, agreement with market settlement was total (207:0 across the disputed windows, and 31:0 on a second batch).

3Trap two: the phantom-empty position — the dangerous one

This one nearly left money stranded on-chain.

The scenario: shut down a line, and before finishing, query positions to confirm everything is clear. The API returns empty. Looks perfect — so the redemption component gets switched off too.

⚠ That "empty" was ingestion lag

In fact the last two windows had just been bought and were not yet indexed. The positions were entirely real; the API simply did not know about them yet.

And the redemption component was already off — without a re-check, that money would have stayed stuck. Manual reconciliation afterwards showed one of those windows had won, for a non-trivial amount.

Ruleafter stopping a line, "the positions are clear" cannot rest on a single API snapshot. At minimum one of: wait several minutes past the last board's close, or reconcile against your own order ledger trade by trade.

4Why these two are the same trap

treating "what the API tells me now" as "the fact" whereas an API can only tell you what it currently knows
The API saidYou concludedTruth
Trap 1redeemable, worth 0.5an unresolved positionresolved; the book is simply empty
Trap 2no positionseverything is closedpositions exist, not yet indexed

Both are "cannot find it" read as "does not exist" — a class I have paid for repeatedly. The other two instances: reading "no record in the activity feed" as "no loss" (off by eight times), and reading an empty array as "this board has no rewards" (the API traps).

5A related lag

"Has this board settled?" has the same problem: the directory's closed flag lags by five to ten minutes. Waiting on it before redeeming costs you an extra cycle for nothing.

And settlement is already self-evident on-chain — since you are reading the payout result anyway, you do not need to ask a directory whether it closed. Removing that redundant precondition took the redemption cycle from ten-to-twenty minutes down to two to six, which is the mechanism's own floor.

⚠ And one that is genuinely hard to diagnose: raw calls need a User-Agent

Hand-assembling requests to read chain data rather than using a library? Send a User-Agent header — otherwise you are silently refused: no error, just no data.

Silently is the problem. The failure looks exactly like "there is no such record on-chain", so you go and doubt the data rather than the request. Library users never meet this.

6A checklist

Do not useUse instead
a "redeemable" field to judge outcomesthe on-chain payout result
the post-close price to judge outcomesas above — that price carries no outcome information
a single position snapshot to declare "clear"wait past close, then reconcile trade by trade
a directory closed flag to detect settlementread the chain; it is self-evident
"cannot find it" as "does not exist"first confirm you are querying correctly

7One line to keep

After close, price carries no information about who won — 0.5 means "no market", not "even odds". There is exactly one place to ask about outcomes: the settlement on-chain. And to ask whether you are clear, never trust a single snapshot.

EvidenceCheck it yourself

Both sides flagged measured: after a short-tenor board closes, both the winning and losing side report redeemable true at a reference price of ≈0.5, the empty-book midpoint (0+1)/2.
Neither threshold works ≥$0.50 lets losers through and burns fees; ≥0.9 strands winners.
The dependable test payout denominator non-zero and own numerator positive; used to re-check all disputed windows — 207:0, and 31:0 on a second batch.
Phantom empty measured: immediately after shutdown a position query returned empty, which was ingestion lag; the last two windows were unindexed and one of them had won.
Directory lag measured at five to ten minutes; removing that precondition took the redemption cycle from 10–20 minutes to 2–6.
User-Agent measured: raw requests without the header are silently refused, presenting as "no data".
Checked 2026-08. API behaviour changes; verify before relying on it.
Not included my own wallet addresses, hosts, or any strategy parameters.

NextWhere to go

A · MECHANICS
Why redemption never happens by itself
G · ENGINEERING
Eight API traps
G · ENGINEERING
Another "cannot find it" read as "does not exist"
A · MECHANICS
Who decides the outcome
This is an educational and research record. It is not investment advice, promises no returns, and offers no personalised trading recommendations. Rules and API behaviour are per the official documentation; this page states when it was checked and both can change without notice. Prediction markets are restricted or unavailable in some jurisdictions — confirm your own before taking part.