Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

speed/v2 package

Overview

Package speed is the SPLASH HOURLY ticket draw: a draw every hour instead of every week.

WHY IT IS A SEPARATE REALM AND NOT A PARAMETER ON r/splash/arcade/raffle. The weekly raffle's cadence is woven into eight constants, four build guards and the refund grace window, and every one of them had to be re-derived from first principles here (see "the two clocks" below). A shared realm with a cadence dial would have had to satisfy BOTH sets of constraints simultaneously, which is how a margin gets shaved: the hourly window's pin offset is 2400 rounds and the weekly one's is 230400, and no single guard can assert both. Two realms, each with its own derivation and its own asserted margins, is the honest shape. The mechanics below are the raffle's, deliberately: the ticket index, the Commit/Capture/Resolve three-phase cycle, the FROZEN-TOTAL property, the one-way refund exit, and the pin-at-record-creation rule. Read r/splash/arcade/raffle/AUDIT-2026-09-28.md before changing any of them; this file's job was to re-scale the timing without re-introducing one of its fourteen findings.

========================================================================== V1 IS SELF-CONTAINED: THERE IS NO SPONSORSHIP AND THERE IS NO FundPot. ==========================================================================

The pot is ENTRY MONEY ONLY. Nothing outside this realm can put a coin into a window's pot, and this realm calls no other realm's code except r/gnoland/wugnot (to move money) and r/splash/beacon (to read a round). There is no cross-realm feed in either direction, on purpose, in both directions:

  • NOTHING FEEDS THIS POT. r/splash/arcade/duel's rake goes to the weekly raffle and stays there. Adding a second consumer of that rake would make the duel's settlement depend on two realms' bookkeeping instead of one, and the duel's Collect depending on the raffle's bookkeeping was AUDIT-2026-09-28.md finding 14 — the worst liveness defect of the day, in which any raffle panic trapped a resolved duel's whole pool in both realms. It was severed that evening (Collect books, FlushPot delivers) and this realm does not reinstate the shape.
  • THIS REALM FEEDS NOTHING. No rake, no share, no callback. Its only outbound transfers are wugnot to a winner's wallet, wugnot to a refunding buyer's wallet, and wugnot to opsVaultAddr.

AND THE PROPERTY THAT MAKES THE ABSENCE OF SPONSORSHIP A SECURITY FEATURE RATHER THAN A MISSING ONE — THE SOLE-ENTRANT PROPERTY:

Example
 1WITH NO HOUSE MONEY IN THE POT, A SOLE ENTRANT MERELY WINS BACK THEIR OWN STAKE
 2MINUS THE HOUSE CUT. The weekly raffle still has the sole-entrant attack, and it
 3is a real one there: the duel's rake is sponsored into the live week's pot, so
 4somebody who buys one ticket into a quiet week with a large sponsored balance
 5collects the sponsorship for the price of the fee on that ticket. Here Pot is
 6exactly sum(spendOf) by construction, so a sole entrant's pot IS their own
 7post-cut spend: they pay 100,000 ugnot, and if they are the only entrant they win
 895,000 back. THERE IS NO POSITIVE-EXPECTATION SOLO PLAY, so the attack cannot
 9exist — not mitigated, not made expensive, ABSENT, as an arithmetic consequence
10of the pot's definition.
11
12(A SOLE ENTRANT IS NO LONGER INDIFFERENT BETWEEN Resolve AND Refund, AND THIS
13PARAGRAPH SAID THEY WERE. It read: "The same arithmetic makes a sole entrant
14indifferent between Resolve and Refund: both return exactly their own 95,000."
15Since 2026-09-29 the fee is ESCROWED per window and earned only by a draw
16(AUDIT-2026-09-28.md finding 25), so a refund returns the whole 100,000 and a
17resolve returns 95,000: THE SOLE ENTRANT STRICTLY PREFERS THE DRAW TO FAIL, by
18exactly the fee. The conclusion this paragraph was supporting is unaffected —
19solo play is still never positive-expectation, which is what kills the
20sole-entrant attack — but the incentive it describes is now the general one the
21owner is weighing: with a refund at 100% of stake, every non-winner prefers a
22failed window to a drawn one. That is a product decision and is deliberately NOT
23fixed here; it is recorded in AUDIT-2026-09-28.md so that the next reader of this
24paragraph does not mistake it for a property of this realm's design. The refund
25grace window below is therefore not only a multi-entrant concern any more.)

SO DO NOT ADD FundPot, A SPONSORED FIELD, A ROLLOVER OR A JACKPOT WITHOUT RE-AUDITING THIS PARAGRAPH. Every one of them puts money in the pot that belongs to no entrant, which (a) resurrects the sole-entrant attack, (b) turns the invariant Pot == sum(spendOf) into Pot == sum(spendOf) + Sponsored with everything that follows from it (see the raffle's Draw.Sponsored, Refund's sponsorship transition and SweepDrawlessWeek — three separate mechanisms that exist only because house money belongs to nobody), and (c) makes this realm's liveness someone else's problem again.

========================================================================== THE ONE-HOUR CADENCE, AND THE TWO CLOCKS ==========================================================================

Every duration in the weekly raffle shrinks by roughly 168x here, and THE FAILURE MODE OF GETTING ONE WRONG IS SILENT — it is not a panic, it is a draw whose winning randomness was public on api.drand.sh before entries closed (finding 10). So each constant below is derived in place, and each is asserted by a build guard that obeys the doctrine that finding 11 cost three attempts to learn:

Example
1A GUARD THAT PROTECTS A REAL-WORLD DURATION MUST HAVE SECONDS ON BOTH SIDES,
2SOURCED FROM TWO DIFFERENT CLOCKS, OR IT CANNOT FAIL.

The two clocks available to a realm on this toolchain, neither of which it can measure at runtime (there is no block-timestamp getter):

  • DRAND'S PERIOD: beacon.PeriodSeconds = 3 s, EXACT. A round count multiplied by it is real seconds by definition of the beacon.
  • THE CHAIN'S BLOCK TIME: assumed 86400/blocksPerDay = 3.29998 s, written as the integer 33/10 in guards because 3.3 is not an integer constant. MEASURED ON LIVE gno.land MAINNET ON 2026-09-28: 3.306 s/block over 200,000 blocks and 3.311 s over 20,000. So reality is very slightly SLOWER than this file assumes, by about 0.2%. That is the benign direction for every margin here (a slower chain means the beacon's estimate LAGS drand rather than outrunning it, and lagging is correctable by any relay of drand's head — see speedMaxStaleBlocks), but the guards below are stated against a ±10% band rather than against the measurement, because the measurement is of the past.

Nothing in this realm is a timestamp. A window is a sequence number derived from chain height; no ticket, spend or draw is dated.

Function

WindowCount

func WindowCount() int64
Ask AI Claude ChatGPT

WindowCount is the number of windows that have a record: the windows that sold at least one ticket. O(1); avl keeps its size.

Command

gnokey query vm/qeval -remote "https://rpc.onyx.testnets.gno.land" -data "gno.land/r/g1r4aw43kagaaquhegxw6xr346h9f2qu2ezf0jar/arcade/speed/v2.WindowCount()"

Result