Contracts: Independent podium timers (Streak, Time Booster, WarBow) + epoch settlement #247

Closed
opened 2026-05-27 07:07:14 +00:00 by PlasticDigits · 10 comments
PlasticDigits commented 2026-05-27 07:07:14 +00:00 (Migrated from gitlab.com)

Context

Independent podium timers and per-podium epoch settlement. Parent epic: #238.

Relevant files

  • contracts/src/TimeArena.sol
  • contracts/src/libraries/TimeMath.sol
  • Per-podium score tracking (adapt from TimeCurve.sol _updateTopThreeMonotonic, streak/booster logic)

Acceptance criteria

  • Four deadline storage slots + four epoch counters
  • Each buy extends all four podium timers with podium-specific extension/reset params (see spec issue)
  • On podium epoch end (deadline passed + qualifying buy or permissionless rollPodiumEpoch(category)):
    • Snapshot top-3 (or last-3 for Last Buy)
    • Pay winners from that podium's DOUB pool (4:2:1 within category)
    • Roll seed vault → active pool
    • Increment podium epoch; reset live scores for that podium only
  • Last Buy reset additionally triggers global Last Buy epoch (CHARM/CRED)

Verification checklist

  • Forge: Streak/TimeBooster/WarBow timers diverge from Last Buy after different buy patterns
  • Epoch counters independent (assert unequal after time skew)
## Context Independent podium timers and per-podium epoch settlement. Parent epic: #238. ## Relevant files - `contracts/src/TimeArena.sol` - `contracts/src/libraries/TimeMath.sol` - Per-podium score tracking (adapt from `TimeCurve.sol` `_updateTopThreeMonotonic`, streak/booster logic) ## Acceptance criteria - [ ] Four deadline storage slots + four epoch counters - [ ] Each buy extends **all four** podium timers with **podium-specific** extension/reset params (see spec issue) - [ ] On podium epoch end (deadline passed + qualifying buy or permissionless `rollPodiumEpoch(category)`): - Snapshot top-3 (or last-3 for Last Buy) - Pay winners from that podium's DOUB pool (4:2:1 within category) - Roll seed vault → active pool - Increment podium epoch; **reset live scores** for that podium only - [ ] Last Buy reset additionally triggers global Last Buy epoch (CHARM/CRED) ## Verification checklist - [ ] Forge: Streak/TimeBooster/WarBow timers diverge from Last Buy after different buy patterns - [ ] Epoch counters independent (assert unequal after time skew)
PlasticDigits commented 2026-05-27 07:07:15 +00:00 (Migrated from gitlab.com)

marked as related to #238

marked as related to #238
PlasticDigits commented 2026-05-27 07:07:59 +00:00 (Migrated from gitlab.com)

mentioned in issue #238

mentioned in issue #238
PlasticDigits commented 2026-05-28 13:58:40 +00:00 (Migrated from gitlab.com)

Implementation summary

  • podiumDeadline[4], podiumEpoch[4], rollPodiumEpoch, 4:2:1 payouts via PodiumVaults.payPodiumWinners, seed roll.
  • Spec in docs/product/arena-v2.md.

Acceptance criteria

  • Four deadline slots + epoch counters
  • Buys extend all four timers
  • rollPodiumEpoch settlement
  • Last Buy hard reset bumps lastBuyEpoch

Verification checklist

  • test_roll_podium_after_expiry in TimeArena.t.sol
## Implementation summary - `podiumDeadline[4]`, `podiumEpoch[4]`, `rollPodiumEpoch`, 4:2:1 payouts via `PodiumVaults.payPodiumWinners`, seed roll. - Spec in `docs/product/arena-v2.md`. ## Acceptance criteria - [x] Four deadline slots + epoch counters - [x] Buys extend all four timers - [x] `rollPodiumEpoch` settlement - [x] Last Buy hard reset bumps `lastBuyEpoch` ## Verification checklist - [x] `test_roll_podium_after_expiry` in TimeArena.t.sol
PlasticDigits commented 2026-05-30 14:04:56 +00:00 (Migrated from gitlab.com)

mentioned in commit 2a5e5d6c60

mentioned in commit 2a5e5d6c60e16a39d7ba959fcf0adc20fa5e75a3
PlasticDigits commented 2026-05-30 14:05:07 +00:00 (Migrated from gitlab.com)

Verification complete (agent)

Verified GitLab #247 on main (71837e1) via worktree issue/247-podium-timers-verify.

What was verified

Onchain (TimeArena.sol):

  • podiumDeadline[4] + podiumEpoch[4] storage
  • Each buy extends all four deadlines (_extendOtherPodiumTimers + Last Buy path)
  • Permissionless rollPodiumEpoch(category) after expiry: snapshot top-3, 4:2:1 payout via ArenaPodiumSettlement + PodiumVaults.payPodiumWinners, seed→active roll, per-category epoch bump, score clear
  • Last Buy hard reset on buy bumps lastBuyEpoch (CHARM/CRED); other podium rolls do not

Forge (36/36 TimeArenaTest pass):

  • test_multi_podium_deadline_extend — all four timers extend together
  • test_roll_podium_after_expiry — epoch bump on roll
  • test_podium_timers_diverge_after_single_roll — Booster/Streak/WarBow diverge from Last Buy after single-category roll
  • test_podium_epochs_independent_after_skewed_rolls — unequal epoch counters after skewed rolls
  • test_roll_podium_settlement_pays_and_clears_scores — winners paid, live scores cleared
  • test_last_buy_epoch_on_hard_reset_not_on_other_podium_roll — CRED/CHARM epoch semantics
  • test_roll_podium_reverts_while_timer_live — guard while timer live

Docs / crosslinks added:

  • Invariants: INV-TIME-ARENA-PODIUM-DIVERGE, INV-TIME-ARENA-PODIUM-EPOCH-INDEP, INV-TIME-ARENA-LAST-BUY-EPOCH
  • docs/product/arena-v2.md, docs/product/time-arena.md
  • skills/play-time-arena-doub/SKILL.md, guardrails skill §6d

Manual verification checklist

  • cd contracts && FOUNDRY_PROFILE=ci forge test --match-contract TimeArenaTest
  • Confirm four timer chips on /arena reflect independent deadlines (indexer GET /v1/arena/timers)
  • After local expiry, call rollPodiumEpoch(1) and confirm PodiumEpochRolled + pool payout on Anvil
  • Confirm Last Buy hard reset increments lastBuyEpoch but Streak/Booster/WarBow rolls do not

All automated acceptance criteria from the issue body pass. Closing.

## Verification complete (agent) Verified GitLab #247 on `main` (`71837e1`) via worktree `issue/247-podium-timers-verify`. ### What was verified **Onchain (`TimeArena.sol`):** - `podiumDeadline[4]` + `podiumEpoch[4]` storage - Each buy extends all four deadlines (`_extendOtherPodiumTimers` + Last Buy path) - Permissionless `rollPodiumEpoch(category)` after expiry: snapshot top-3, 4:2:1 payout via `ArenaPodiumSettlement` + `PodiumVaults.payPodiumWinners`, seed→active roll, per-category epoch bump, score clear - Last Buy **hard reset** on buy bumps `lastBuyEpoch` (CHARM/CRED); other podium rolls do not **Forge (36/36 `TimeArenaTest` pass):** - `test_multi_podium_deadline_extend` — all four timers extend together - `test_roll_podium_after_expiry` — epoch bump on roll - `test_podium_timers_diverge_after_single_roll` — Booster/Streak/WarBow diverge from Last Buy after single-category roll - `test_podium_epochs_independent_after_skewed_rolls` — unequal epoch counters after skewed rolls - `test_roll_podium_settlement_pays_and_clears_scores` — winners paid, live scores cleared - `test_last_buy_epoch_on_hard_reset_not_on_other_podium_roll` — CRED/CHARM epoch semantics - `test_roll_podium_reverts_while_timer_live` — guard while timer live **Docs / crosslinks added:** - Invariants: `INV-TIME-ARENA-PODIUM-DIVERGE`, `INV-TIME-ARENA-PODIUM-EPOCH-INDEP`, `INV-TIME-ARENA-LAST-BUY-EPOCH` - `docs/product/arena-v2.md`, `docs/product/time-arena.md` - `skills/play-time-arena-doub/SKILL.md`, guardrails skill §6d ### Manual verification checklist - [ ] `cd contracts && FOUNDRY_PROFILE=ci forge test --match-contract TimeArenaTest` - [ ] Confirm four timer chips on `/arena` reflect independent deadlines (indexer `GET /v1/arena/timers`) - [ ] After local expiry, call `rollPodiumEpoch(1)` and confirm `PodiumEpochRolled` + pool payout on Anvil - [ ] Confirm Last Buy hard reset increments `lastBuyEpoch` but Streak/Booster/WarBow rolls do not All automated acceptance criteria from the issue body pass. Closing.
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-05-30 14:05:08 +00:00
PlasticDigits commented 2026-05-30 14:06:51 +00:00 (Migrated from gitlab.com)

mentioned in issue #271

mentioned in issue #271
PlasticDigits commented 2026-05-30 14:06:52 +00:00 (Migrated from gitlab.com)

marked as related to #271

marked as related to #271
PlasticDigits commented 2026-06-01 03:31:04 +00:00 (Migrated from gitlab.com)

mentioned in issue #273

mentioned in issue #273
PlasticDigits commented 2026-06-07 07:50:09 +00:00 (Migrated from gitlab.com)

mentioned in issue #300

mentioned in issue #300
PlasticDigits commented 2026-06-16 05:49:43 +00:00 (Migrated from gitlab.com)

mentioned in issue #330

mentioned in issue #330
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
code/yieldomega#247
No description provided.