Skip to main content

Lottery personal boost v2

Lottery personal boost v2

Product lock (2026-09-03). This page is the normative personal-boost formula for when LotteryManager4626 sets boostManager after the boost-source timelock. It is not live.

v1 (live): boostManager and vaultGaugeVoting stay address(0). Personal multiplier is identity 1.0×. Gauge add is 0. Do not treat Share-coverage comments in current LM bytecode as the v2 product rule.

Reader path: LotteryManager4626 · ve4626. Curve kernel bounds: 2.5× proof (Lean proved [1.0, 2.5]; this page locks D, coverage, and the epoch budget).

Locked formula

BasePPM is unchanged: min(swapUSD / 250_000, baseCeilingPPM) (default ceiling 40,000 PPM / 4% at $10,000). Solana then scales odds by 400 / 690. Stake USD stays gross venue notional.

swapEff = min(swapUSD, 10_000)            # same ceiling as base PPM
boost = Curve(swapEff, D=100_000, ve/Ve)
cover = min(1, veUSD / swapUSD)
veUSD = locked■4626_amount × markPrice(■4626)
FinalPPM = BasePPM × (1 + (boost - 1) × cover)

ve / Ve are effective veLottery for the beneficiary and live total ve4626 power. boost is the Curve rate. cover is how much of this fill's USD that rate may touch. On the consume path, substitute remaining for veUSD (remaining starts at veUSD each epoch).

Classic Curve (α = 0.4)

l in Curve is swapEff, not coverage USD and not creator Share supply.

working = min(l, 0.4·l + 0.6·D·(ve/Ve))   # D = 100_000; l = swapEff
boost = min(2.5, working / (0.4·l)) # ∈ [1.0, 2.5]
SymbolMeaning
l / swapEffmin(swapUSD, 10_000)
DProtocol constant 100,000 (not creator ShareOFT supply USD)
ve / VeBeneficiary veLottery / live total ve power
veUSDLocked 4626 principal ×
covermin(1, remaining / swapUSD) on the epoch budget; see consume below

veUSD is not decaying ve-units × price. Decay changes ve/Ve (the rate). Lock size × mark changes cover (how much of the ticket that rate applies to).

Why swapEff matches the $10k base ceiling

Uncapped Curve(l = swap) after BasePPM is already capped makes personal EV+ non-monotonic for tickets above $10k: more USD can lower the Curve rate faster than base PPM grows. Cap Curve’s l at the same $10,000 as baseCeilingPPM.

2.5× threshold

Full 2.5× requires working = l, which is ve/Ve >= swapEff / D:

Ticket (swapEff)ve share for 2.5×
$1000.1% of Ve
$1,0001% of Ve
$10,000 (full base ceiling)10% of Ve

Small covered retail tickets reach 2.5× with a small ve share. A full $10k ticket needs a real slice of total ve. Whales do not mint 2.5× on large tickets by locking dust.

Cover vs rate

boost and cover are independent knobs:

PositionRate (boost)CoverEffective personal mult
Thin lock, fat veHigh (near 2.5×)SmallClose to 1.0×: almost none of the ticket is covered
Fat lock, tiny veLow (near 1.0×)FullClose to 1.0×: covered, but the Curve rate is weak
Fat lock, enough veHighFullUp to 2.5× on swapEff

Worked cover: $2,000 swap, $500 remaining veUSDcover = 0.25. If boost = 2.5, effective multiplier is 1 + 1.5 × 0.25 = 1.375×.

Epoch boost budget (wash control)

Each beneficiary (canonical CSW / wallet) holds a remaining coverage budget for the epoch. Base, Solana, and every other venue share one consume ledger. No per-chain double spend.

  1. Start / refresh: remaining starts at current veUSD each epoch. A live-mark refresh is allowed only through the same fail-closed oracle as veUSD (below).
  2. Each fill: cover = min(1, remaining / swapUSD), then used = min(swapUSD, remaining), then remaining -= used. Use remaining (not a second snapshot of veUSD) for that fill's cover.
  3. Unlock / lock decrease mid-epoch: remaining = min(remaining, live veUSD). Remaining never exceeds live lock USD.
  4. AMOE: attested points, not a venue swap. This budget is for venue fills only unless a later spec extends consume to attested USD.

Wash intent: one unit of lock USD cannot cover more than one unit of swap USD per epoch across all venues.

Oracle

uses the same fail-closed staleness and deviation posture as other lottery USD notionals (venue quote × feed). Missing, stale, or out-of-band price → no personal boost for that fill (identity 1.0×). Never silently default the mark to 1. Ticket USD stays venue spend, not this mark: LotteryManager4626, CreatorOracle.

Out of scope

These stay separate from personal Curve boost. Do not fold them into FinalPPM above.

Gauge lottery pot (additive)

Global pot 6.942% (69,420 PPM). Per-vault cap:

C(n) = 35_000 - 25_000 / n

n is the number of vaults sharing the pot. 1% at n = 1 (10,000 PPM), 3.5% asymptote (35,000 PPM). Added after personal boost; maxWinChance still caps the envelope.

Fees-on-vote / bribes

Solidly-style gauge loop (vote, bribe, stream). Not an input to boost, cover, or veUSD.

Rejected alternative (blend B)

Do not implement:

l       = min(swapUSD, veUSD)             # coverage inside Curve
boost = Curve(l, D=100_000, ve/Ve)
FinalPPM = BasePPM × (1 + (boost - 1) × (l / swapUSD))

Why it is wrong (unsaturated): when working < l,

boost  = 1 + 1.5 · D · (ve/Ve) / l
uplift = (boost - 1) · (l / swapUSD)
= 1.5 · D · (ve/Ve) / swapUSD

Coverage l cancels. Locking more past the saturation threshold does not raise EV in that regime; only ve/Ve and swapUSD remain. The locked formula keeps Curve’s l on swapEff and applies coverage outside Curve, so extra lock USD can still raise cover until 1.

Why uncapped l = swap is also wrong: past the $10k base ceiling, BasePPM is flat while Curve’s l keeps growing, so EV+ is non-monotonic. That is the swapEff cap above.

July 2026 LM comments (l = min(creatorShareUSD, swapUSD), L = creator Share supply USD) are the unarmed v1 door plus FriendKey-era coverage. They are not this lock. FriendKey stays out of lottery.

v1 vs v2 arming

Modev1 livev2 (this spec)
boostManageraddress(0)Set after propose → 24h → commit → timelock arm
Personal mult1.0×1 + (boost - 1) × cover[1.0, 2.5]
Gauge PPM0Additive pot above; still optional / separate window
Coveragen/aLock 4626 USD budget, unified per beneficiary per epoch

Keep LM pointers at zero until an implementation matches this page. Arming today’s Share-coverage _applyBoost is not v2.

See also