Arena prize routing: 100% to podiums with 70/20/10 epoch tranches #300
Labels
No labels
agent:fix_bugfix
agent:fix_conflicts
agent:fix_security
agent:gap_analysis
agent:implement
agent:open_issues
agents
agent:security_audit
agent:verify
area
timecurve
arena
arena-v2
audit
block:feature_review
block:security
bug
contracts
design
devops
docs
documentation
enhancement
epic
feature
frontend
indexer
low priority
megaeth
operations
ops
performance
QA
qa checklist
referrals
removal
security
smart-contracts
tech-debt
testing
time-arena
timecurve
visual-qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
code/yieldomega#300
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Retarget 100% of DOUB buy proceeds to podium prize vaults (zero admin take on buys), with each of the four podiums receiving 25% of every buy, split across current / next / next+1 epoch pools at 70% / 20% / 10% per podium. Funding is global — all podiums receive DOUB even when a player has not unlocked that podium’s mechanics (see companion progression issue).
Parent epic: #238. Supersedes buy routing in #249. Related: #261 (manual top-up), #267 (vault-funding ingest).
Current codebase
Buy routing today
ArenaBuyRouting.solsplits each DOUB buy:AdminSellVaultTimeArena._routeDoubPrizeSplittransfers toPodiumVaultsactive/seed pools and admin vault; emitsPodiumFunded,SeedFunded,AdminVaultFunded.Epoch model
podiumEpoch[cat](#247).rollPodiumEpoch(cat), active pool pays winners 4:2:1 (ArenaPodiumSettlement.sol), seed rolls to active, epoch increments.Frontend / indexer
FeeTransparency.tsx/ArenaVaultAddressesPanel.tsxshow 40/30/30 split.GET /v1/arena/vault-funding/*(#267) indexesPodiumFunded/SeedFunded/AdminVaultFunded.Manual top-up
topUpPodiumPoolsroutes 100% prize-only at 10:7.5 active:seed per category (#261) — unchanged unless product wants epoch tranches for donations too (out of scope unless stated).Why this is needed
The 30% admin take on every buy dilutes player-facing prizes and complicates the “all-in on podiums” narrative. Players should see buys as directly feeding the four competitive tracks.
The 70/20/10 epoch tranche per podium smooths funding across the settling epoch and the next two, so early-epoch and late-epoch winners both receive liquidity without manual rebalancing. Because podiums roll independently, each category applies the split against its own
podiumEpoch[cat]:Example (buy amount
B; each podium gets0.25 × B):podiumEpochWithin each tranche, DOUB lands in the vault bucket that will settle that epoch (may require per-epoch pool mapping or seed/active sub-ledger — see solution direction).
Player unlock state does not affect routing — a level-1 wallet still funds all four podiums; only their timer/scoring side effects are gated (companion issue).
Constraints & guardrails
TimeArena; indexer decodes events only.buyWithCred— no DOUB routing today (#268); unchanged unless product explicitly extends CRED buys to fund vaults.AdminSellVault; admin revenue must not depend on this change without ops sign-off. Manual top-up and other admin flows stay separate.totalDoubRaised— clarify whether fullreceivedor prize-routed portion (recommend: still full payment for analytics).finalizeWarbowPodium(epoch)(#252).Relevant files
ArenaBuyRouting.sol,TimeArena.sol,PodiumVaults.sol,ArenaPodiumSettlement.solArenaPrizeRouting.t.sol,TimeArena.t.sol(test_buy_routes_doub_split)api_arena.rs, migrations underindexer/migrations/FeeTransparency.tsx,ArenaProtocolDonatePoolsSection.tsxarena-v2.md§ DOUB prize routing,invariants-and-business-logic.mdverify-vault-funding-anvil.sh,verify-time-arena-buy-router-anvil.shRecommended solution direction
Option A — Reuse active/seed as epoch+0 / epoch+1, add epoch+2 bucket
PodiumVaults).splitBuyPrizeByEpoch(amount, currentEpoch)pure library:podiumShare = amount / 4(remainder to cat 3 or Last Buy per documented rule).t70 = mulDiv(podiumShare, 7000, 10000)→ current epoch pool.t20→currentEpoch + 1pool.t10→currentEpoch + 2pool.rollPodiumEpoch, pay active tranche 4:2:1, promote +1/+2 tranches (exact promotion rules need a short design note in MR).Option B — Explicit
epochPool[cat][epoch]inPodiumVaultsEvents
PodiumFunded/SeedFundedwithPodiumEpochFunded(category, epoch, amount)for indexer clarity.AdminVaultFundedon buys (amount always zero).Indexer + API
GET /v1/arena/vault-funding/*exposes per-epoch balances or tranche breakdown.idx_arena_podium_liveif predictions depend on pool balances (#273).Frontend
Acceptance criteria
buy()routes 100% ofreceivedto podium vaults; 0 toAdminSellVaulton buy path.podiumEpoch[cat],+1,+2respectively.rollPodiumEpoch+ WarBowfinalizeWarbowPodiumstill pay correct epoch balances.topUpPodiumPoolsbehavior unchanged (#261).INV-ARENA-PRIZE-ROUTING-*invariants added.Test plan (functional paths)
forge test --match-contract ArenaPrizeRouting— fixed epochs + fuzzTimeArena.t.sol::test_buy_routes_doub_splitrewritten for 100% / 25% / 70-20-10test_finalize_warbow_podium_pays_after_rollwith pre-funded epoch poolbash scripts/verify-vault-funding-anvil.shbash scripts/verify-time-arena-buy-router-anvil.shnpm test—FeeTransparency.test.tsxbash scripts/verify-podium-live-anvil.shif balances feed predictionsTest plan (attack / abuse / edge vectors)
TimeArenatestFuzz_epoch_split_no_dustpodiumEpoch + 2neartype(uint256).max)PodiumFundedeventsTimeArenatotalDoubRaisedvs vault inflowsnotifyPodiumFundednonReentranton buyVerification criteria (merge gate)
cd contracts && forge testcd indexer && cargo clippy --all-targets -- -D warnings && cargo testbash scripts/verify-vault-funding-anvil.shbash scripts/verify-time-arena-buy-router-anvil.shcd frontend && npm run typecheck && npm run lint && npm testbash scripts/check-doc-anchors.shDependency
marked as related to #238
marked as related to #299
mentioned in commit
8c522eda7cmentioned in merge request !440
mentioned in commit
2398a6a1fcmentioned in commit
ab35170934mentioned in merge request !442
Verification complete — #300
Implementation was already merged (
2398a6a). All automated acceptance checks PASS.Acceptance criteria
test_buy_routes_doub_splitArenaPrizeRouting.t.sol(6/6)test_buy_routes_epoch_tranches_worked_exampletest_finalize_warbow_podium_pays_after_rolltestFuzz_splitBuy_no_dust,testFuzz_epoch_split_per_category_bpsbash scripts/verify-vault-funding-anvil.shFeeTransparency.test.tsx— 100% / 70/20/10 copytest_topUpPodiumPools_*(7 tests)Merge gate
cd contracts && forge testDoubAirdropMegaethForktests need gitignoreddoub.csv)cargo clippy+cargo testverify-vault-funding-anvil.shverify-time-arena-buy-router-anvil.shtypecheck+lint+npm testcheck-doc-anchors.shFollow-up MR
Opened !442 to align remaining 40/30/30 documentation (security model, QA checklists, agent guides) with the implemented 100% podium · 70/20/10 routing.
Issue left open pending MR merge.
mentioned in commit
79955b1013mentioned in merge request !444
mentioned in issue #293
mentioned in issue #302
mentioned in commit
feeadcfa6fmentioned in commit
b43f52647ementioned in commit
909d63d007mentioned in commit
6d823d5746mentioned in commit
ddfaa01f4fmentioned in commit
08d564baa0mentioned in commit
574c16ea46mentioned in commit
17c969fda6mentioned in commit
3d9291d507mentioned in commit
dffa6a02f9mentioned in commit
9fa5c1a852mentioned in commit
3ecd110cbdmentioned in commit
d5ee46397amentioned in issue #309
mentioned in issue #310
mentioned in issue #313
mentioned in issue #314
mentioned in issue #316
mentioned in merge request !458
mentioned in merge request !461
mentioned in merge request !464
mentioned in merge request !465
mentioned in merge request !473
mentioned in issue #332
mentioned in issue #366