RUN DOVES SOL — slot —

The house has a liquidation price.

fills from YOLO, moves from Binance SOL/USDT 1 s closes · fired at the seconds they were filled, sixty times faster · each trace runs from its own fill on log time · brightness = bets passing through

one capture, then all of them
run · replay #2243 · YOLO SOL long · 1000× · $10.00 · 2026-10-15 14:03:19 UTC · YOLO fill, Binance 1 s moves
  1. t = 0Filled at 101.74
  2. t = 10 s0.21 of a division from ruin
  3. t = 80 sStop, and it splits by the odds
  4. t = 378 sThe house is liquidated
  5. × 200One capture of two hundred
  6. ↑ 2727 broke the house's line
  7. 1/(1+k)The house's odds of ruin

t = 0Filled at 101.74

A real 1000× long on SOL, $10, against a $100 house. Two prices are fixed the moment it fills: yours at 101.6339, one division below, and the house's at 102.7530, ten above. Between them is the window.

t = 10 s0.21 of a division from ruin

One division is 0.1%. At 1000× that is all the room you have. Here the price fell to 101.66, 0.21 of a division above your line, and turned.

t = 80 sStop, and it splits by the odds

At 101.90 the price is 1.57 divisions up. In a fair walk the house's line comes first from there (1 + 1.57)/11 = 23.4% of the time. Stop now and you take $24.07, the house $85.93.

t = 378 sThe house is liquidated

102.7530, after 378 seconds. The price crossed the house's line and the line broke. You take $103.00. The house keeps $7.00, its edge, and nothing more.

× 200One capture of two hundred

Pull back and #2243 is one frame in the instrument's memory: 200 real 1000× bets opened in the same fifteen minutes. 173 ended on the trader's line, half of them inside 23 seconds.

↑ 2727 broke the house's line

27 of the 200 reached the house's line, 13.5% in one quarter-hour of one market. Over 25,724 bets from six days, 9.33%.

1/(1+k)The house's odds of ruin

A walk between a floor one division away and a ceiling k away reaches the ceiling first one time in 1 + k: 9.09% at k = 10. It is the gambler's ruin, the problem the name comes from, and it is the split at every price.

Five houses are open

Each one is a stake waiting for a bet. The two lines move with the DOVES price until a bet fills; then they stay.

$RUIN

A house up to $100 needs no token. A bigger house locks $RUIN, 100 for every dollar of stake. The bets worth taking the other side of need it.

1ch1 probe · DOVES SOLFYq2…zXh · u64 @168 · ×1e−8
1raw—
Twindow—
Hhorizontal · roll6 s/div · 60 s · slot —

Houses

Pick the house you bet against. A house takes bets up to its stake divided by k.

where 200 real 1000× bets peaked before they ended—
chance the house's line comes first—
One table against your house
—
Your line, by leverage
$RUIN

Up to $100 of stake, no token. Above it, 100 RUIN per dollar of stake, returned when the house closes.

TAPE · 500–1000×YOLO public trades · live · DOVES · ruin's lines at k 10, e 7%
exits read—
liquidated on YOLO—
closed · YOLO paid—
ruin's split, same price—
ruin pays more—
time UTCbetheldon YOLOon ruin, same pricesΔ
Your bets
Your houses
Connect to see your bets and houses.

Probes

The three price accounts every window is measured against, read as they change.

ruin matches each 500–1000× bet on SOL, BTC and ETH with one house and puts both stakes in the same Solana contract. Two lines are fixed at the fill: yours one division away, the house's k divisions away. The first line the DOVES price reaches ends the bet, whichever side it is on. Stop before that and the table is split where the price stands, along a straight line you can read before you open.

On YOLO, the house is one pool for every market, filled only by traders' losses, and nobody can deposit into it [4]. A move of 0.002% or less in your favour pays nothing, and a bigger one is cut, most when it is small [5]. A win the pool cannot cover waits in a queue [4]. Here anyone can post a house, nothing is zeroed near the fill, the house's cut is one number printed on it, and everything a bet can win is in the house's vault before it fills.

This page is the manual and the record: how to bet and how to run a house, the formula and the code that settle a table, the values the program holds and every call it takes, what it was measured against, and what you are trusting.

1The window

A bet on ruin is a contract between two wallets. A, the trader, puts up margin m. B, the house, puts up k·m. Both amounts sit in the contract from the moment it fills. Their sum, (1+k)·m, is the table.

Two lines are fixed at the fill. A's line is 1/L from the fill price, against A. B's line is k/L from it, in A's favour. Measured in divisions of 1/L, A's line is one division away and B's line is k. At 1000× and k = 10, a long has its lines at −0.1% and +1%. Whoever's line the price reaches first gives up the table.

runreplay #2243 · YOLO fill, Binance SOL/USDT 1 s moves · 2026-10-15 14:03:19 UTC
SOL long, margin $10.00, ×1000, against k = 10, e = 7%. Filled at 101.74. A's line 101.6339, B's line 102.7530. The price fell to 101.66 at 10 s, turned, and reached B's line after 378 s. A takes $103.00. B keeps $7.00.

The fill is YOLO's own (4TB9…U7bk, slot 457,263,940). The moves after it are Binance 1 s closes, because the bet comes from the YOLO sample of 15 Oct. ruin itself settles only on DOVES (section 6).

2Using it

You need a Solana wallet in this browser, USDC for the margin or the stake, and a little SOL for network fees and account rent. The page builds each transaction; your wallet signs it and sends it.

Bet. On bet, pick a market, a side, a margin from $1.00 and a leverage of 500–1000×, then the house you bet against. Its window is drawn before you ask. Request bet moves the margin into that house's vault and asks for a fill, which comes 2–5 s later (section 5). From the fill the two lines stay where they are. Stop asks for the split at the price 2–5 s later (section 3). A line, a stop or 72 hours ends the table, and the transaction that ends it pays you. Your bets and their receipts are on you, and every ended table is on tape.

House. On house, pick a market, a stake, k, e and the sides you take, then Post house. The stake, and any $RUIN the house locks (section 8), moves into the house's vault. A house takes one bet at a time, up to its stake divided by k. Between bets you can top up, withdraw or close it on you, and pause stops new bets at any time.

figone table, from the ask to the payout · schematic, drawn on replay #2243
(1) Ask: the margin moves into the house's vault, beside the house's k·m. (2) Fill: 2–5 s later the DOVES price fixes the two lines. (3) Live: the split moves with the price, and you can stop at any point. (4) End: a line, a stop or 72 hours; the transaction that ends the table pays A, and the rest stays with the house.

Rent. A request pays the rent of its table account, and the trader gets it back when the table ends or is refunded. Posting a house pays the rent of the house and its vaults, and closing the house returns it.

3Stopping early

A can stop at any time. The table is split where the price stands between the two lines.

f = (1 + side·L·(p − p₀)/p₀) / (1 + k) clamped to [0, 1] A = f · (m + k·m·(1 − e)) B = (1 + k)·m − A

f is the price's place in the window: 0 on A's line, 1 on B's. At the fill f = 1/(1+k), so a $10 long against a $100 house that stops with nothing moved gets $103 / 11 = $9.36.

runreplay #2243, stopped at 80 s
Price 101.90, 1.57 divisions up. f = 0.2337. A gets $24.07, B gets $85.93. (The same bet on YOLO closed at 80 s for $22.18.)

ruin · mainnet · receipt H0·0000 · 2026-10-26 20:55:44 UTC · SOL long · $5.00 · 1000× · k 10 · e 7% · filled 100.2396 · stopped at 100.2537, f 0.1037 · A $5.34 · B $49.66 · tx 53iy…Tc6p

// programs/ruin/src/math.rs
pub fn split(side: Side, lev: u16, m: u64, k: u8, e: u16, p0: u64, p: u64) -> Result<Split> {
    require!(p0 > 0, RuinError::InvalidValue);
    let movement = i128::from(p)
        .checked_sub(i128::from(p0))
        .and_then(|v| v.checked_mul(i128::from(lev)))
        .ok_or(RuinError::Overflow)?;
    let num = match side {
        Side::Long => i128::from(p0).checked_add(movement),
        Side::Short => i128::from(p0).checked_sub(movement),
    }
    .ok_or(RuinError::Overflow)?;
    let den = i128::from(p0)
        .checked_mul(i128::from(k).checked_add(1).ok_or(RuinError::Overflow)?)
        .ok_or(RuinError::Overflow)?;
    let c = claim(m, k, e)?;
    let clamped = num.clamp(0, den) as u128;
    let a = if num >= den {
        narrow(c / 10_000)?
    } else {
        narrow(
            c.checked_mul(clamped).ok_or(RuinError::Overflow)?
                / (den as u128)
                    .checked_mul(10_000)
                    .ok_or(RuinError::Overflow)?,
        )?
    };
    Ok(Split {
        a,
        b: sub(mul(add(1, k.into())?, m)?, a)?,
        f_e9: narrow(
            clamped
                .checked_mul(1_000_000_000)
                .ok_or(RuinError::Overflow)?
                / den as u128,
        )?,
        line: if num <= 0 {
            Some(End::TraderLine)
        } else if num >= den {
            Some(End::HouseLine)
        } else {
            None
        },
    })
}

4The edge

B's price is one number, e, printed on the house. Whatever happens, B keeps k·m·e of its stake: at its own line B loses k·m·(1 − e) and keeps the rest. Without e, A's split would be f·(1+k)·m, its place times the table. With e, A gets that less k·e/(1+k) of it, the same share at every price: 6.4% at k = 10 and e = 7%.

The split is one straight line from A's line to B's, set before you open. Nothing is zeroed near the fill, and the share taken does not change with the move. Every price in the window pays an amount you can read before you open.

figXY · what A gets at every price · margin $10
k
e
At the fill: A $9.36, B $100.64. YOLO's formula on the same move: $9.80.
Mint is ruin's split, one straight line from A's line to B's, set before you open. The dashed line is YOLO's published formula on the same move [5]. Past B's line the table has ended, and the rest of the move is given up. Pick k, e and the leverage and move across the window: it is the program's rule applied to the numbers you pick, not a forecast.

5Fills

You ask, and the fill comes later. A bet and a stop both fill at the DOVES value read in a window that opens at a random slot, 2.2 to 5.0 seconds after the request lands, and stays open 1.1 seconds. That value must be newer than the one on chain when you asked.

The delay is read from the hash of the slot your request lands in, so nobody, you included, knows it before the request lands. A fill at a price nobody can pick in advance means nobody opens or stops on a DOVES update they have already seen.

figone request, slot by slot · DOVES SOL writes of 20 Oct 2026, read from chain
A request lands in slot r. Its window opens d slots later, d between 10 and 23 and read from the hash of slot r, and stays open 5 slots. A fill reads the DOVES value of its own slot, which must be newer than the one at r, so a value written before the window opens counts. The ticks are every write to the DOVES SOL account in these slots, read from chain; the window drawn is one possible d. If no fill lands in the window, the margin can be refunded from slot r + 28 (section 7).

6The lines and the oracle

A line is crossed only by a DOVES value written on chain. The keeper reads the DOVES account of each market and calls settle for any table past a line. settle is permissionless: anyone can call it with the same account.

SOL FYq2BWQ1V5P1WFBqr3qB2Kb5yHVvSv7upzKodgQE5zXh
BTC hUqAT1KQ7eW1i6Csp9CXYtpPfSAvi835V7wKi5fRfmC
ETH AFZnHPzy4mvVCffrVwhewHbFc93uTHvDSFrVH7GtfXF1
price: u64 at offset 168, 8 decimals

// keeper/src/keeper/engine.ts
  if (
    price &&
    price.publishTs >= t.fillPublishTs &&
    r.split({
      side: t.side,
      lev: t.lev,
      m: t.m,
      k: t.k,
      eBps: t.eBps,
      p0: t.p0,
      p: price.price,
    }).line
  )
    return { kind: "settle-line" };
runDOVES what-if · recorded 2026-10-20 · slot 459,115,379
SOL long at 1000×, k = 10, filled 05:32:27 UTC at 104.6820. A's line 104.5773, B's line 105.7288. At 05:36:19 UTC the DOVES value 104.5673 (slot 459,116,446) crossed A's line, 3 min 52 s after the fill. The table goes to B.

ruin · mainnet · receipt H1·0000 · 2026-10-26 21:01:01 UTC · SOL short · $5.00 · 1000× · k 10 · e 7% · filled 100.1797 · the trader's line at 100.2877, slot 461,808,758 · A $0.00 · B $55.00 · tx 54jM…e6Hs

7When money waits

No fill. A request fills only inside its window, at a DOVES value newer than the one on chain when it landed. If none comes, the request can be refunded once the window has passed: the margin and the table's rent go back to the trader. The keeper does it, so can anyone, and your bets on you show a Refund key.

A missed stop. A stop fills only inside its own window, at a value newer than the one when it was asked. If it misses, the table stays open and you can ask again. A line reached meanwhile still ends it.

72 hours. A table still open 72 hours after its fill is split at the DOVES price then, by the same formula. When more than one applies, a line comes before a stop, and a stop before this.

No keeper. fill, refund and settle need no key of ours. If the operator's keeper stops, any wallet can send them with the same accounts, using the client in the source (section 12).

An old price. A DOVES value older than 30 s is refused. A request, a fill, a stop or a settle waits for a newer one.

8Houses and $RUIN

A house is a stake waiting for a bet: a market, the stake, k, e and the sides it takes. It takes one table at a time, and a bet of at most its stake divided by k. While a bet is asked for or open against it, a house cannot close, add stake or withdraw. It can stop taking new bets at any time.

A house with a stake up to $100 needs no token. $RUIN is not set yet; until it is, no house holds more than $100.

So the size of the bets a house can take is counted in $RUIN. At k = 10, a bet above $10 needs a house above $100, and until $RUIN is set no house is that big.

In the YOLO sample of 14–19 Oct (49,571 opens), the bets above $10, which a $100 house at k = 10 cannot take, were 52.0% of the count and 97.6% of the margin. Without the ten largest wallets they were 48.2% and 93.0%, and 1,236 of the 2,042 wallets placed at least one.

fig49,571 YOLO opens, 14–19 Oct, by margin · the house each one needs at k = 10
≤ $10a house up to $100 · no token
$10–100a house up to $1,000 · $RUIN once it is set
$100–1,000a house up to $10,000 · $RUIN once it is set
> $1,000a bigger house · $RUIN once it is set
Gold is what a $100 house at k = 10 cannot take: 52.0% of the bets and 97.6% of the margin.

9The ruin problem

ruin is named after it. Two players stake what they have on one walk, and whoever runs out first is ruined. On ruin, A stakes one division, B stakes k, and the walk is the DOVES price. The problem is older than the market. Huygens printed it in 1657 as the fifth problem of De Ratiociniis in Ludo Aleae [1]: two players with twelve pieces each play until one holds all twenty-four. Neither is the house. Pascal and Fermat had settled in 1654 how to split a game stopped early [2].

"A and B taking 12 Pieces of Money each, play with 3 Dice on this Condition, That if the Number 11 is thrown, A shall give B one Piece, but if 14 shall be thrown, then B shall give one to A; and he shall win the Game that first gets all the Pieces of Money."

Huygens, problem V, in the English of 1714 [1]

If the price is a martingale and touches lines exactly, the chance that B's line comes first is f [3]. At the fill that is 1/(1+k). A's share f·claim is then what A's position is worth at that moment, and by optional stopping its expected value is the same whenever A stops.

The contract leaves the model in three places: DOVES is read at discrete moments, the fill uses a later price, and the stop uses a later price.

10Measurements

reached B's line first9.33%the model: 9.09%
margin back, outside the top ten94.04%under YOLO's formula: 88.89%
ruin pays more, 1000× at k = 10+0.0049% to +1%of the price, your way

Held to a line. 25,724 real 1000× bets (YOLO, 14–19 Oct) held from their real open until a line at k = 10, on Binance 1 s highs and lows, ended within 24 h: 2,401 reached B's line first, 9.33%. The model says 1/11 = 9.09%. With the direction flipped, 10.47%.

Against the current formula. 48,496 real 500–1000× bets on the same paths and hold times, long and short averaged, beside YOLO's published fee formula as read on 25 Oct [5]. Wallets outside the top ten got back 94.04% of their margin under ruin's split and 88.89% under that formula. The top ten closed 61% of their margin inside a 10% move, after a median 28 s: 93.6% here, 95.5% there.

Where each pays more. A $10 long at 1000× against a house at k = 10 and e = 7%, beside the same formula on the same move: from +0.0049% up to B's line at +1%, ruin pays more ($14.05 against $12.50 at +0.05%, $103 against $95.48 at +1%). From −0.069% to +0.0049% it pays less ($9.36 against $9.80 with nothing moved). The table ends at B's line, so the house's k sets how far a bet can run: at k = 10 that is +1% and $103, and held on YOLO the same entry pays more from about +1.085%. Against a $1,000 house at k = 100 the line is at +10%. YOLO's payout stops at $499.80 from about +5.58%, at its cap of 50 times the collateral; this bet goes on to $940 at that line.

Conditions: Binance 1 s paths, original hold times, and YOLO's published values as read on 25 Oct 2026: nothing for a move of 0.002% or less, 0.9·P·d²/(d + c) above it, profit capped at 50 times the collateral, a 2% win fee and a 0.002% close fee [5]. The payout comparison leaves out fill prices and network fees. None of this is an expected return.

11Values and calls

These values are read from the program on Solana mainnet. A house keeps the $RUIN terms it was posted with and a table keeps the timing it was asked with, so a change applies only to new houses and new tables.

valuenowwhat it means
marketsSOL · BTC · ETHeach read from its DOVES price account (section 6)
marginUSDC, from $1.00moved into the house's vault by the request
leverage500–1000×one division is 1/L of the fill price
k1–100the house's line in divisions; the house puts up k·m
e0–10%the house's edge, printed on the house (section 4)
fill2.2–5.0 s after the request, open 1.1 sat a DOVES value newer than the request's
stop2.2–5.0 s after the stop, open 1.1 sa stop that misses can be asked again
price ageat most 30 san older DOVES value is refused
table endsa line, a stop, or 72 hours after the fillin that order when more than one applies
no-token stakeup to $100a bigger house locks $RUIN
$RUINnot set yetuntil it is, no house is above $100

The program counts slots, not seconds: a delay of 10–23 slots, a fill window of 5 and a stop window of 5. Seconds on this page are at the recent slot length, 218 ms.

callwhowhat it does
post_houseanyoneMoves the stake, and any $RUIN lock, into a new house's vault.
top_up · withdrawthe house's owner, between tablesAdds or takes stake and $RUIN. The lock must still cover the stake.
set_acceptingthe owner, any timeStops or resumes new bets. An open table plays out.
close_housethe owner, between tablesReturns the stake, the lock and the rent, and closes the house.
request_opena traderMoves the margin into the house's vault and asks for a fill. The house takes no other bet until this one ends.
fill_openanyoneFills the request inside its window at a newer DOVES value.
refund_openanyone, after the windowSends an unfilled margin and the table's rent back to the trader.
request_closethe traderAsks for a stop. A stop that missed its window can be asked again.
settleanyoneEnds a table at a line, at a filled stop, or after 72 hours, and pays the trader in the same transaction.
set_paramsthe adminChanges, for new houses and tables, the minimum margin, the no-token stake, the $RUIN per dollar, the delays and windows, and the oldest DOVES value accepted.
set_feedthe adminPoints a market at another DOVES account for the same asset.
set_ruinthe admin, onceSets the $RUIN mint.
initthe upgrade authority, onceFixes the settlement mint, the admin, the leverage, k and e ranges, and how long a table may stay open.

12Trust assumptions

  • ruin is one program on Solana.
  • The admin key can change, for new houses and new tables only, the minimum margin, the stake a house may hold without $RUIN, the $RUIN per dollar, the fill delay and windows, and how old a DOVES value may be. It cannot move any vault or lock. The admin is set when the program is initialized, and no call changes it.
  • DOVES is a price account. Its terms are not published.
  • The keeper is run by the operator. Anyone can run another, because fill, settle and refund are permissionless.
  • This build links no source. The program's source is published with its mainnet deployment.

13Problems

Problem 1. A $10 long at 1000× against a $100 house. Nothing moves and A stops. What does A get?

f = 1/11. A = 103/11 = $9.36. B = $100.64.

run · DOVES what-if · 2026-10-20 05:32:27 UTC: at the fill (104.6820) the table read A $9.36, B $100.64.

Problem 2. The price reaches B's line. What does B keep?

k·m·e = $7.00. A takes $103.00.

run · replay #2243 · held 378 s after 14:03:19 UTC, 15 Oct: A $103.00, B $7.00.

Problem 3. Can B lose more than its stake?

No. The most B can lose on a table is k·m·(1 − e), $93 here, and it is on the table before A bets.

Problem 4. Why not fill at the price on the screen?

Because then whoever sees a DOVES update first could trade on it. A random 2–5 s delay takes that away (section 5).

Problem 5. What if nobody calls settle?

The keeper calls it, and so can anyone. A table that is never settled at a line is split at 72 hours (section 7).

Problem 6. You ask, and no fill comes in the window. Where is your margin?

In the house's vault until the window has passed. Then a refund, by you, the keeper or anyone, sends it back with the table's rent (section 7).

Problem 7. A $100 bet at 1000× comes in against houses at k = 10. Which can take it?

One with at least $1,000 of stake. Until $RUIN is set no house holds more than $100, so none can yet (section 8).

References

  1. [1] C. Huygens, De Ratiociniis in Ludo Aleae, 1657, problem V. In English as The Value of All Chances in Games of Fortune, 1714.
  2. [2] B. Pascal and P. de Fermat, correspondence of 1654.
  3. [3] W. Feller, An Introduction to Probability Theory and Its Applications, vol. 1, 3rd ed., Wiley, 1968, ch. XIV, "Random Walk and Ruin Problems".
  4. [4] Jupiter, YOLO payouts and the House, read 25 Oct 2026.
  5. [5] Jupiter, YOLO profit adjustment and fees, read 25 Oct 2026.
  6. [6] DOVES price program, DoVEsk76QybCEHQGzkvYPWLQu9gzNoZZZt3TPiL597e. Its terms are not published.