Limitations
What is untested, what cannot be covered at all, and what the recorded run does not prove. None of this is softened for a documentation register.
On this page
- SOMI cannot be covered
- A void has never happened
- poke() is untested at scale
- A reservation has no user-side escape
- The engine has stopped before
- A buying callback runs close to its gas limit
- The default windows are the ones it never bought
- Two probes are pinned to expired markets
- The notification watcher is local
- The record is a sample
- Open questions
SOMI cannot be covered at all#
There is no binary market on SOMI, so there is no instrument to buy. This is not a feature we have not built — it is a market that does not exist. Ballast can only cover assets dreamDEX runs Event Contracts on.
A void has never happened on chain#
The settlement path has a void branch, which pays 0.5/0.5. It is covered by tests and it has never executed against a real market, because no market we touched has ever voided. So the branch is proven in a test harness and unproven in production, and those are different claims.
poke() is untested at mainnet-scale liquidity#
poke() nudges a stuck market and is permissionless by design. Every exercise of it has been against thin testnet books. Its behaviour against deep books with many competing participants is not known, and the gas figure we quote for it (an estimate of 1,936,405 on a live window) is a testnet measurement.
A reservation has no user-side escape#
reservedOf[user] is cleared by an approved engine spending or releasing it. If an engine reserved and then stopped, that collateral would be locked with no user-side way out. It is currently unreachable — the only caller pairs reserve with spend atomically in one transaction, and a revert rolls both back. It is not fixed because the fix is a reservation expiry in the vault, and the vault holds a live user deposit that redeploying would strand. Written down so it is a decision rather than an oversight.The engine has stopped before#
Between 2 and 10 September it bought no cover. Its subscription was first closed to preserve runway, then reopened at a gas limit too small for a purchase, then removed by Somnia when the balance ran dry. What it had already done stayed on chain and the vault stayed withdrawable throughout — a stop affects future purchases only.
The measurements are on Findings. Restarting took a new contract, not only a parameter change: the build it replaced gave every order a sixty-second expiry, which the pool refuses on a market that closes sooner, so it could never cover a one-minute window. topUp() is payable and permissionless, so anyone can fund a running engine; reopening a subscription is owner-only. The live state is on the Engine view.
A buying callback runs close to its gas limit#
Each callback is provisioned 10,000,000 gas. With one enrolled account, a callback that bought a single cover used 2,391,271 – 3,591,400 gas (median 2,445,376), and the heaviest so far used 9,218,505 — 92% of the limit.
The engine does guard its batches: it stops when less than gasReservePerEntry (400,000) remains and resumes from a cursor on the next callback. But one purchase costs about six times that reserve. So as more accounts share a batch, a purchase can start with too little gas to finish — it runs out inside its own call, the batch records PlacementFailed for that account, and that account goes uncovered for that window. If what is left is then too little for the batch’s own bookkeeping, the callback as a whole runs out of gas.
setBatchParams) would make a batch stop cleanly and resume, and the limit can rise to the precompile’s maximum of 200,000,000 — Somnia bills gas used, so the limit is not itself the cost. Neither has been done, because with one enrolled account the ceiling has not been reached.The default windows are the ones it never bought#
The product defaults to four-hour and twenty-four-hour windows, because those are the intervals where the spread is survivable. On testnet it has never bought one. Over the recorded history the engines saw 20 four-hour and 4 twenty-four-hour ETH windows and refused every one: the Down book was empty, or the affordable size fell below the venue’s minimum lot. Every cover in the record is on a window of an hour or less — 116 one-minute, 116 five-minute, 20 fifteen-minute and 6 one-hour.
So the economics argue for the windows the record cannot show, and the record shows the windows the economics argue against. That is a property of thin testnet books rather than of the engine, but it means cover at the intervals that matter is untested.
Two probes are pinned to expired markets#
The Phase 0 probe suite runs 21 of 23 green. test_ContractCanPlaceRestingBid and test_ContractCanMintCompleteSet are pinned to a specific BTC 24-hour market that expired on 2 September 2026, and now revert with OrderAlreadyExpired() and TradingNotActive() respectively.
That is a time-pinned probe decaying, not a product regression: the same assertions passed against that market while it was live, and the write path they exercise is the one the engine still uses. They would need repointing at a live market to run green again, and that has not been done.
The notification watcher is local#
The notification watcher runs as a local process. Notifications are only generated while that process is running. A judge or user who connects when the watcher is offline will not receive vault-low or engine alerts until it restarts.
The record is a sample, not a result#
128 settled positions with a positive net looks like a return. It is not one.
Open questions#
Three product decisions have not been made. They are written here as questions because that is what they are, and because improvising an answer when asked would be worse than saying the work has not been done.
Should it buy every available window?
Today it does: enrol, and the engine attempts cover on every window it is woken for. Whether that is the right production strategy is genuinely undecided. The alternative is episodic cover — buying around events, or when a position crosses a size threshold, or on a schedule the holder sets — which costs less in spread but leaves gaps that are uncovered by choice rather than by accident. We have not decided which is right, and the economics only tells us that buying every sixty-second window is not.
There is no expected-value or volatility filter
Every gate the engine applies is mechanical: is the book two-sided, is the cover price at or below 0.90, does the premium fit the ceiling and the notional cap, does the size clear the venue’s minimum lot. Those are all questions about whether a purchase is possible and within consent.
No view is taken on whether cover is worth buying today. The engine has no volatility estimate, no expected-value calculation, and no opinion about whether the market’s price for the Down side is generous or expensive relative to the risk. It buys because it is permitted to, not because it judged the trade good. Whether it should judge — and on whose model — is open.
Vault top-up is manual, and premium drains it
Premium is paid out of vault collateral every window cover is bought. On four-hour windows that runs at roughly 0.2% to 0.3% of exposure per day net of spread — see the frequency table. Collateral is therefore consumed steadily by a working policy.
The dashboard can notify a signed-in holder and prompt a manual top-up, but it never refills automatically. Those alerts depend on the local notification watcher described above; while it is offline, a holder can still find cover being skipped for want of collateral only in the activity log. An allowance the vault may pull on has not been designed, because it would change the custody model.