Power Slots
The Power Slots are the winning ticket positions for the Grand Prize. When a game ends, the contract marks a handful of slots at logarithmic positions counted back from the final ticket, and every Power Slot splits the Grand Prize Pool equally.
Selection is deterministic and entirely on-chain — no oracle, no randomness, no off-chain computation. Anyone can verify the slots from the entrant list alone.
In the contract, Power Slots are the tickets for which
isWinnerreturnstrue, and the slot count isgetNumWinners. "Power Slot" is the user-facing name for what the code calls a winner.
The rule
A ticket k lands a Power Slot when its position from the end is a power of
grandPrizeLogBase (including B^0 = 1):
position_from_end(k) = 1 + N - k where N = entrantCount[gameId]
ticket k is a Power Slot ⇔ position_from_end(k) = B_g^j for some integer j ≥ 0
Equivalently, the Power Slot ticket IDs are:
k_j = N + 1 - B_g^j for j = 0, 1, 2, …, W-1
where W = floor(log_{B_g}(N)) + 1 is the total number of Power Slots.
Number of Power Slots
W = floor(log_{B_g}(N)) + 1
| N | B_g=2 | B_g=3 | B_g=5 | B_g=7 | B_g=10 |
|---|---|---|---|---|---|
| 10 | 4 | 3 | 2 | 2 | 2 |
| 100 | 7 | 5 | 3 | 3 | 3 |
| 1,000 | 10 | 7 | 5 | 4 | 4 |
| 10,000 | 14 | 9 | 6 | 5 | 5 |
| 100,000 | 17 | 11 | 8 | 6 | 6 |
Prize per Power Slot
Equal split of the Grand Prize Pool:
P = floor(G / W)
G is the Grand Prize Pool accumulated for the game; the dust
G - W * P from integer division is locked in the contract.
Worked example: N = 50, B_g = 3
W = floor(log_3(50)) + 1 = 3 + 1 = 4 Power Slots
| j | Position from end (3^j) |
Power Slot ticket ID (51 − 3^j) |
|---|---|---|
| 0 | 1 | 50 (last ticket) |
| 1 | 3 | 48 |
| 2 | 9 | 42 |
| 3 | 27 | 24 |
Tuning the spacing
The host sets grandPrizeLogBase per game, which controls how many Power Slots
there are and how big each one pays:
| Configuration | Effect |
|---|---|
Lower grandPrizeLogBase (2-3) |
More Power Slots, smaller prizes — wide distribution |
Default grandPrizeLogBase (5-7) |
Balanced |
Higher grandPrizeLogBase (10) |
Few Power Slots, large prizes — V1-style |
Two effects compose as entries grow:
- The Grand Prize Pool grows linearly with N
- The number of Power Slots grows logarithmically with N
So each Power Slot's prize grows as O(N / log N) — sub-linear but nearly
linear for any practical N.
The last ticket is always a Power Slot
The final entrant (entrantId == entrantCount) always lands a Power Slot
because position_from_end = 1 = B^0. This is by design: it incentivizes
late-deadline sniping, and combined with the inactivity-countdown reset on
every entry, drives the "one-more-entry" dynamic the game is built around.
Reference implementation
function isWinner(uint256 _gameId, uint256 _entrantId) public view returns (bool) {
uint256 count = entrantCount[_gameId];
if (count == 0 || _entrantId == 0 || _entrantId > count) return false;
if (_entrantId == count) return true; // last entrant always lands a Power Slot
uint256 n = 1 + count - _entrantId;
uint256 base = gameConfigRecord[_gameId].grandPrizeLogBase;
return isPower(base, n);
}
The isPower(base, n) helper repeatedly divides n by base and returns
true if the remainder reaches 1, which is bounded by log_base(n) iterations.
See Prize Math Specification for the full formal treatment, including precision bounds and dust accounting.