Indexer + Simple podium: expose active-pool prize preview (DOUB + USD) on GET /v1/arena/podiums #302

Closed
opened 2026-06-07 13:57:53 +00:00 by PlasticDigits · 14 comments
PlasticDigits commented 2026-06-07 13:57:53 +00:00 (Migrated from gitlab.com)

Summary

Extend GET /v1/arena/podiums to return per-category active-epoch prize preview (1st/2nd/3rd DOUB wad strings, 4∶2∶1 split) and wire ArenaSimplePage / ArenaSimplePodiumSection so podium cards show DOUB prizes and USD equivalent — without browser RPC reads.

Depends on / pairs with #301 (indexer-first display policy).


Current codebase

Indexer GET /v1/arena/podiums

indexer/src/api_arena.rs arena_podiums returns UX-ordered rows with:

  • category, category_index, epoch
  • winners[], values[] (scores)
  • podium_prediction / last_buy_prediction

No prize pool fields. When Postgres has no live row, the handler falls back to head podium() RPC snapshot at read_block_number (server-side only).

Frontend podium UI

ArenaSimplePodiumSection.tsx expects optional podiumPayoutPreview:

podiumPayoutPreview?: readonly { places: readonly [string, string, string] }[];

For each place, if prizeRaw is undefined → renders EmptyDataPlaceholder “Prizes loading” (#292 requires DOUB + USD prize rows).

ArenaSimplePage.tsx passes podiumPayoutPreview={undefined} — prizes always show loading placeholder even when indexer leaders load correctly.

Tests mock preview data in ArenaSimplePodiumSection.test.tsx; production never supplies it.

Onchain prize math (authoritative)

Historical context

Pre–Arena v2 [TimeCurveSimplePage](git history) computed preview from a single pool balanceOf in the browser via RPC. That path was not ported to v2 per-category vaults; hardcoded undefined replaced it.

USD display (existing, display-only)

ArenaSimplePodiumSection already formats USD via fallbackPayTokenWeiForCl8y + SIMPLE_PODIUM_USD_EQUIV_TITLE (static 0.98× shape, not live oracle — #192).


Why the new implementation is needed

  1. Product gap (#292): “Podium cards show 1st/2nd/3rd prize rows in DOUB with USD equivalent” — currently broken in production.
  2. User-visible bug: Winners load from indexer; prizes stuck on “PRIZES LOADING” indefinitely.
  3. RPC minimization (#301): Prize preview must be served by the indexer head poller (chain_timer), not useReadContracts in every browser tab.

Constraints & guardrails

  • Preview ≠ guarantee: Amounts reflect active pool balance at read_block_number; buys/donations/rolls before epoch settlement can change finals. UI copy/tooltip should say “preview” or reuse existing USD equiv disclaimer.
  • Onchain authority: Indexer computes from PodiumVaults.activePoolBalance(uint8) eth_call at head block — same trust model as existing podium() head mirror.
  • Schema version: Bump x-schema-version; document in indexer/README.md and docs/indexer/design.md.
  • WarBow: Same active-pool preview rules; settlement may require finalizeWarbowPodium after roll (#252) — preview still shows pool balance for current epoch.
  • Zero pool: Return "0" wad strings for all three places; UI shows 0 DOUB / ≈ $0 USD, not “loading”.
  • No new browser RPC for prizes.
  • AGPL indexer changes.

Relevant files

Indexer:

Contracts (reference / test vectors only):

Frontend:

Docs:


Indexer API (schema ≥ 2.8.0 proposed)

Extend each row in GET /v1/arena/podiums:

{
  "category_index": 0,
  "winners": ["0x…", "0x…", "0x…"],
  "values": ["…", "…", "…"],
  "prize_places_doub_wad": ["<1st>", "<2nd>", "<3rd>"],
  "active_pool_balance_doub_wad": "<pool before split>"
}

Computation (server-side at read_block_number):

  1. Resolve PodiumVaults from ADDRESS_REGISTRY.
  2. eth_call activePoolBalance(category_index) for each of 4 categories (batch in chain_timer poll alongside existing head reads).
  3. Apply 4∶2∶1 split (Rust port of ArenaPodiumSettlement / mirror podiumPlacementShares).
  4. Emit decimal strings (wad) consistent with other arena APIs.

Include read_block_number at response root (already present) so clients can show staleness.

Frontend

  1. Extend ArenaPodiumApiRow + fetchArenaPodiums parsing.
  2. In usePodiumReads (or thin helper), build podiumPayoutPreview[categoryIndex].places from prize_places_doub_wad.
  3. ArenaSimplePage: pass mapped preview; remove undefined.
  4. Keep USD formatting in ArenaSimplePodiumSection unchanged.
  5. When indexer row lacks prize fields (old schema), show muted “Prizes unavailable” instead of infinite “loading”.

Verification script

bash scripts/verify-podium-prize-preview-anvil.sh:

  • DeployDev + indexer ingest + fund pools via buy or topUpPodiumPools
  • curl GET /v1/arena/podiums → compare prize_places_doub_wad to cast call PodiumVaults activePoolBalance(cat) + 4∶2∶1 math at same block

Acceptance criteria

  • GET /v1/arena/podiums returns prize_places_doub_wad (3 strings) per row for all 4 categories at head block.
  • Values match onchain activePoolBalance(cat) × 4∶2∶1 at read_block_number (verify script PASS).
  • /arena Simple podium cards show DOUB amounts + ≈ $… USD for populated pools (#292).
  • No podiumPayoutPreview={undefined} in ArenaSimplePage.
  • Zero-balance pool shows 0 prizes, not “Prizes loading”.
  • Schema version bumped; docs + invariants updated (INV-INDEXER-PODIUM-PRIZE-PREVIEW proposed).
  • cd frontend && npm run typecheck && npm run lint && npm test PASS.
  • cd indexer && cargo clippy --all-targets -- -D warnings && cargo test PASS.
  • bash scripts/verify-podium-live-anvil.sh still PASS (no regression on leaders).

Test plan (functional paths)

Path Steps Expected
Fresh deploy, no buys GET /v1/arena/podiums prize_places_doub_wad all "0"; UI 0 DOUB
Single DOUB buy Buy CHARM, wait ingest Last Buy category preview > 0; 4∶2∶1 sum ≤ active pool
Donate top-up topUpPodiumPools Preview increases per category tranche rules
All four categories Multi-buy + WarBow activity Each row has independent preview
Indexer stale Pause poller briefly UI keeps last preview with block number / stale bar
Old indexer (no field) Omit field in test fixture Frontend “unavailable”, not infinite loading
USD row Funded pool ≈ $X USD visible with SIMPLE_PODIUM_USD_EQUIV_TITLE tooltip
Locked podium (L1 wallet) Connect low-level wallet Prizes still visible on locked cards

Test plan (attack, hack, abuse vectors)

Vector Test
Indexer lies about prizes (inflated wad) Verify script compares to block-tagged cast call; document display-only — settlement is on-chain at roll
Rounding drift vs Solidity mulDiv Property test: first+second+third == pool for random pool values in Rust unit test
Reorg after head poll Integration: rollback vault funding row → preview at new head decreases after reindex
Category index confusion (UX order vs onchain 0–3) Assert category_index matches prize_places mapping in API test
Overflow / huge wad strings Frontend formatCompactFromRaw must not throw; reject non-numeric in API layer
User trusts preview for financial decision Tooltip/disclaimer per #192; no “guaranteed payout” copy

Verification criteria

# New smoke
bash scripts/verify-podium-prize-preview-anvil.sh

# Regression
bash scripts/verify-podium-live-anvil.sh
bash scripts/verify-vault-funding-anvil.sh

# Indexer
cd indexer && cargo clippy --all-targets -- -D warnings && cargo test

# Frontend
cd frontend && npm run typecheck && npm run lint && npm test

# Manual QA checklist row for #292 prize rows

  • #301 — indexer-first; no browser RPC for display
  • #292 — production podium prize rows
  • #273 — live podium leaders
  • #300 — DOUB buy routing to vaults
## Summary Extend **`GET /v1/arena/podiums`** to return per-category **active-epoch prize preview** (1st/2nd/3rd DOUB wad strings, 4∶2∶1 split) and wire **`ArenaSimplePage`** / **`ArenaSimplePodiumSection`** so podium cards show DOUB prizes and USD equivalent — **without browser RPC reads**. Depends on / pairs with [#301](https://gitlab.com/PlasticDigits/yieldomega/-/issues/301) (indexer-first display policy). --- ## Current codebase ### Indexer `GET /v1/arena/podiums` [`indexer/src/api_arena.rs`](indexer/src/api_arena.rs) `arena_podiums` returns UX-ordered rows with: - `category`, `category_index`, `epoch` - `winners[]`, `values[]` (scores) - `podium_prediction` / `last_buy_prediction` **No prize pool fields.** When Postgres has no live row, the handler falls back to head `podium()` RPC snapshot at `read_block_number` (server-side only). ### Frontend podium UI [`ArenaSimplePodiumSection.tsx`](frontend/src/pages/arena/ArenaSimplePodiumSection.tsx) expects optional `podiumPayoutPreview`: ```ts podiumPayoutPreview?: readonly { places: readonly [string, string, string] }[]; ``` For each place, if `prizeRaw` is undefined → renders **`EmptyDataPlaceholder` “Prizes loading”** ([#292](https://gitlab.com/PlasticDigits/yieldomega/-/issues/292) requires DOUB + USD prize rows). [`ArenaSimplePage.tsx`](frontend/src/pages/arena/ArenaSimplePage.tsx) passes **`podiumPayoutPreview={undefined}`** — prizes always show loading placeholder even when indexer leaders load correctly. Tests mock preview data in [`ArenaSimplePodiumSection.test.tsx`](frontend/src/pages/arena/ArenaSimplePodiumSection.test.tsx); production never supplies it. ### Onchain prize math (authoritative) - Per category, **current epoch** prizes settle from **`PodiumVaults.activePoolBalance(category)`** ([`contracts/src/arena/PodiumVaults.sol`](contracts/src/arena/PodiumVaults.sol)). - Split **4∶2∶1** via [`ArenaPodiumSettlement.payoutShares`](contracts/src/arena/libraries/ArenaPodiumSettlement.sol) — mirrored in frontend [`podiumPlacementShares`](frontend/src/lib/timeArenaPodiumMath.ts). ### Historical context Pre–Arena v2 [`TimeCurveSimplePage`](git history) computed preview from a single pool `balanceOf` in the **browser** via RPC. That path was **not ported** to v2 per-category vaults; hardcoded `undefined` replaced it. ### USD display (existing, display-only) [`ArenaSimplePodiumSection`](frontend/src/pages/arena/ArenaSimplePodiumSection.tsx) already formats USD via [`fallbackPayTokenWeiForCl8y`](frontend/src/lib/kumbayaDisplayFallback.ts) + [`SIMPLE_PODIUM_USD_EQUIV_TITLE`](frontend/src/lib/cl8yUsdEquivalentDisplay.ts) (static 0.98× shape, **not** live oracle — [#192](https://gitlab.com/PlasticDigits/yieldomega/-/issues/192)). --- ## Why the new implementation is needed 1. **Product gap ([#292](https://gitlab.com/PlasticDigits/yieldomega/-/issues/292))**: “Podium cards show 1st/2nd/3rd prize rows in DOUB with USD equivalent” — currently broken in production. 2. **User-visible bug**: Winners load from indexer; prizes stuck on “PRIZES LOADING” indefinitely. 3. **RPC minimization ([#301](https://gitlab.com/PlasticDigits/yieldomega/-/issues/301))**: Prize preview must be served by the indexer head poller (`chain_timer`), not `useReadContracts` in every browser tab. --- ## Constraints & guardrails - **Preview ≠ guarantee**: Amounts reflect **active pool balance at `read_block_number`**; buys/donations/rolls before epoch settlement can change finals. UI copy/tooltip should say “preview” or reuse existing USD equiv disclaimer. - **Onchain authority**: Indexer computes from `PodiumVaults.activePoolBalance(uint8)` eth_call at head block — same trust model as existing `podium()` head mirror. - **Schema version**: Bump `x-schema-version`; document in [`indexer/README.md`](indexer/README.md) and [`docs/indexer/design.md`](docs/indexer/design.md). - **WarBow**: Same active-pool preview rules; settlement may require `finalizeWarbowPodium` after roll ([#252](https://gitlab.com/PlasticDigits/yieldomega/-/issues/252)) — preview still shows pool balance for current epoch. - **Zero pool**: Return `"0"` wad strings for all three places; UI shows `0 DOUB` / `≈ $0 USD`, not “loading”. - **No new browser RPC** for prizes. - **AGPL** indexer changes. --- ## Relevant files **Indexer:** - [`indexer/src/api_arena.rs`](indexer/src/api_arena.rs) — extend `arena_podiums` JSON - [`indexer/src/chain_timer.rs`](indexer/src/chain_timer.rs) — poll `PodiumVaults.activePoolBalance(0..3)` at head block (add selector + decode) - [`indexer/src/sale_state.rs`](indexer/src/sale_state.rs) — if registry address needed - [`indexer/tests/integration_stage2.rs`](indexer/tests/integration_stage2.rs) - New verify script e.g. `scripts/verify-podium-prize-preview-anvil.sh` **Contracts (reference / test vectors only):** - [`contracts/src/arena/PodiumVaults.sol`](contracts/src/arena/PodiumVaults.sol) - [`contracts/src/arena/libraries/ArenaPodiumSettlement.sol`](contracts/src/arena/libraries/ArenaPodiumSettlement.sol) - [`contracts/test/TimeArena.t.sol`](contracts/test/TimeArena.t.sol) — buy routing / pool funding **Frontend:** - [`frontend/src/lib/indexerApi.ts`](frontend/src/lib/indexerApi.ts) — `ArenaPodiumApiRow` types - [`frontend/src/pages/arena/usePodiumReads.ts`](frontend/src/pages/arena/usePodiumReads.ts) — map new fields → `podiumPayoutPreview` shape (or extend `PodiumReadRow`) - [`frontend/src/pages/arena/ArenaSimplePage.tsx`](frontend/src/pages/arena/ArenaSimplePage.tsx) — pass preview from hook - [`frontend/src/pages/arena/ArenaSimplePodiumSection.tsx`](frontend/src/pages/arena/ArenaSimplePodiumSection.tsx) — handle zero pool; optional “preview” aria - [`frontend/src/pages/arena/ArenaSimplePodiumSection.test.tsx`](frontend/src/pages/arena/ArenaSimplePodiumSection.test.tsx) - [`frontend/src/lib/indexerApi.test.ts`](frontend/src/lib/indexerApi.test.ts) **Docs:** - [`docs/frontend/arena-views.md`](docs/frontend/arena-views.md) § production components ([#292](https://gitlab.com/PlasticDigits/yieldomega/-/issues/292)) - [`docs/indexer/design.md`](docs/indexer/design.md) § arena podiums - [`docs/testing/invariants-and-business-logic.md`](docs/testing/invariants-and-business-logic.md) - [`skills/play-active-time-arena/SKILL.md`](skills/play-active-time-arena/SKILL.md) --- ## Recommended direction ### Indexer API (schema ≥ 2.8.0 proposed) Extend each row in `GET /v1/arena/podiums`: ```json { "category_index": 0, "winners": ["0x…", "0x…", "0x…"], "values": ["…", "…", "…"], "prize_places_doub_wad": ["<1st>", "<2nd>", "<3rd>"], "active_pool_balance_doub_wad": "<pool before split>" } ``` **Computation (server-side at `read_block_number`):** 1. Resolve `PodiumVaults` from `ADDRESS_REGISTRY`. 2. `eth_call` `activePoolBalance(category_index)` for each of 4 categories (batch in `chain_timer` poll alongside existing head reads). 3. Apply 4∶2∶1 split (Rust port of `ArenaPodiumSettlement` / mirror `podiumPlacementShares`). 4. Emit decimal strings (wad) consistent with other arena APIs. Include `read_block_number` at response root (already present) so clients can show staleness. ### Frontend 1. Extend `ArenaPodiumApiRow` + `fetchArenaPodiums` parsing. 2. In `usePodiumReads` (or thin helper), build `podiumPayoutPreview[categoryIndex].places` from `prize_places_doub_wad`. 3. `ArenaSimplePage`: pass mapped preview; remove `undefined`. 4. Keep USD formatting in `ArenaSimplePodiumSection` unchanged. 5. When indexer row lacks prize fields (old schema), show muted “Prizes unavailable” instead of infinite “loading”. ### Verification script `bash scripts/verify-podium-prize-preview-anvil.sh`: - DeployDev + indexer ingest + fund pools via buy or `topUpPodiumPools` - `curl GET /v1/arena/podiums` → compare `prize_places_doub_wad` to `cast call PodiumVaults activePoolBalance(cat)` + 4∶2∶1 math at same block --- ## Acceptance criteria - [ ] `GET /v1/arena/podiums` returns `prize_places_doub_wad` (3 strings) per row for all 4 categories at head block. - [ ] Values match onchain `activePoolBalance(cat)` × 4∶2∶1 at `read_block_number` (verify script PASS). - [ ] `/arena` Simple podium cards show DOUB amounts + `≈ $… USD` for populated pools ([#292](https://gitlab.com/PlasticDigits/yieldomega/-/issues/292)). - [ ] No `podiumPayoutPreview={undefined}` in `ArenaSimplePage`. - [ ] Zero-balance pool shows `0` prizes, not “Prizes loading”. - [ ] Schema version bumped; docs + invariants updated (`INV-INDEXER-PODIUM-PRIZE-PREVIEW` proposed). - [ ] `cd frontend && npm run typecheck && npm run lint && npm test` PASS. - [ ] `cd indexer && cargo clippy --all-targets -- -D warnings && cargo test` PASS. - [ ] `bash scripts/verify-podium-live-anvil.sh` still PASS (no regression on leaders). --- ## Test plan (functional paths) | Path | Steps | Expected | |------|-------|----------| | Fresh deploy, no buys | `GET /v1/arena/podiums` | `prize_places_doub_wad` all `"0"`; UI `0 DOUB` | | Single DOUB buy | Buy CHARM, wait ingest | Last Buy category preview > 0; 4∶2∶1 sum ≤ active pool | | Donate top-up | `topUpPodiumPools` | Preview increases per category tranche rules | | All four categories | Multi-buy + WarBow activity | Each row has independent preview | | Indexer stale | Pause poller briefly | UI keeps last preview with block number / stale bar | | Old indexer (no field) | Omit field in test fixture | Frontend “unavailable”, not infinite loading | | USD row | Funded pool | `≈ $X USD` visible with `SIMPLE_PODIUM_USD_EQUIV_TITLE` tooltip | | Locked podium (L1 wallet) | Connect low-level wallet | Prizes still visible on locked cards | --- ## Test plan (attack, hack, abuse vectors) | Vector | Test | |--------|------| | **Indexer lies about prizes** (inflated wad) | Verify script compares to block-tagged `cast call`; document display-only — settlement is on-chain at roll | | **Rounding drift** vs Solidity `mulDiv` | Property test: `first+second+third == pool` for random pool values in Rust unit test | | **Reorg** after head poll | Integration: rollback vault funding row → preview at new head decreases after reindex | | **Category index confusion** (UX order vs onchain 0–3) | Assert `category_index` matches `prize_places` mapping in API test | | **Overflow / huge wad strings** | Frontend `formatCompactFromRaw` must not throw; reject non-numeric in API layer | | **User trusts preview for financial decision** | Tooltip/disclaimer per [#192](https://gitlab.com/PlasticDigits/yieldomega/-/issues/192); no “guaranteed payout” copy | --- ## Verification criteria ```bash # New smoke bash scripts/verify-podium-prize-preview-anvil.sh # Regression bash scripts/verify-podium-live-anvil.sh bash scripts/verify-vault-funding-anvil.sh # Indexer cd indexer && cargo clippy --all-targets -- -D warnings && cargo test # Frontend cd frontend && npm run typecheck && npm run lint && npm test # Manual QA checklist row for #292 prize rows ``` --- ## Related issues - [#301](https://gitlab.com/PlasticDigits/yieldomega/-/issues/301) — indexer-first; no browser RPC for display - [#292](https://gitlab.com/PlasticDigits/yieldomega/-/issues/292) — production podium prize rows - [#273](https://gitlab.com/PlasticDigits/yieldomega/-/issues/273) — live podium leaders - [#300](https://gitlab.com/PlasticDigits/yieldomega/-/issues/300) — DOUB buy routing to vaults
ghost1 commented 2026-06-08 06:00:45 +00:00 (Migrated from gitlab.com)

mentioned in commit 3a663ac58c

mentioned in commit 3a663ac58ce3968a338698a3961482e1707abe92
ghost1 commented 2026-06-08 06:05:11 +00:00 (Migrated from gitlab.com)

mentioned in commit 8a9aa54a90cdc1b28dcc74e9d413075a0aba6146

mentioned in commit 8a9aa54a90cdc1b28dcc74e9d413075a0aba6146
ghost1 commented 2026-06-08 06:05:21 +00:00 (Migrated from gitlab.com)

mentioned in commit e24fb48af9

mentioned in commit e24fb48af9c73ab6f023a1e3c93ef8f1e44bf034
PlasticDigits commented 2026-06-08 06:05:41 +00:00 (Migrated from gitlab.com)

mentioned in merge request !445

mentioned in merge request !445
PlasticDigits commented 2026-06-08 06:05:44 +00:00 (Migrated from gitlab.com)

Implementation complete — MR !445: https://gitlab.com/PlasticDigits/yieldomega/-/merge_requests/75

Summary: GET /v1/arena/podiums (schema 2.8.0) now returns prize_places_doub_wad + active_pool_balance_doub_wad per row from head PodiumVaults.activePoolBalance × 4∶2∶1. /arena Simple podium cards consume indexer preview via usePodiumReads (no browser RPC).

Verification (all PASS):

  • bash scripts/verify-podium-prize-preview-anvil.sh
  • bash scripts/verify-podium-live-anvil.sh
  • cd indexer && cargo clippy --all-targets -- -D warnings && cargo test
  • cd frontend && npm run typecheck && npm run lint && npm test

Issue left open pending MR review/merge.

Implementation complete — MR !445: https://gitlab.com/PlasticDigits/yieldomega/-/merge_requests/75 **Summary:** `GET /v1/arena/podiums` (schema 2.8.0) now returns `prize_places_doub_wad` + `active_pool_balance_doub_wad` per row from head `PodiumVaults.activePoolBalance` × 4∶2∶1. `/arena` Simple podium cards consume indexer preview via `usePodiumReads` (no browser RPC). **Verification (all PASS):** - `bash scripts/verify-podium-prize-preview-anvil.sh` - `bash scripts/verify-podium-live-anvil.sh` - `cd indexer && cargo clippy --all-targets -- -D warnings && cargo test` - `cd frontend && npm run typecheck && npm run lint && npm test` Issue left open pending MR review/merge.
PlasticDigits commented 2026-06-08 06:10:56 +00:00 (Migrated from gitlab.com)

mentioned in commit 68af94b6ac

mentioned in commit 68af94b6acb5dbc5c5e0e4e3114c00d5ca70afdc
PlasticDigits commented 2026-06-08 06:22:57 +00:00 (Migrated from gitlab.com)

Verification complete — GitLab #302

Issue: Indexer + Simple podium: expose active-pool prize preview (DOUB + USD) on GET /v1/arena/podiums

Verified on branch main (commits 3a663ac, e24fb48). No repo changes required from this verification run.

Acceptance criteria

Criterion Result How verified
GET /v1/arena/podiums returns prize_places_doub_wad (3 strings) per row for all 4 categories PASS curl -sf http://127.0.0.1:3100/v1/arena/podiums — schema 2.8.0, 4 rows each with prize_places_doub_wad + active_pool_balance_doub_wad
Values match onchain activePoolBalance(cat) × 4∶2∶1 at read_block_number PASS bash scripts/verify-podium-prize-preview-anvil.sh → OK (read_block=17, last_buy_pool=1000000000000000000000, schema=2.8.0)
/arena Simple podium cards show DOUB + ≈ $… USD for populated pools (#292) PASS Verify script funds Last Buy pool via buy; unit tests cover populated preview; manual UI on fresh deploy confirms prize row format
No podiumPayoutPreview={undefined} in ArenaSimplePage PASS grep — none; passes podiumReads.podiumPayoutPreview from hook
Zero-balance pool shows 0 prizes, not “Prizes loading” PASS API returns "0" strings; ArenaSimplePodiumSection.test.tsx “zero DOUB prizes”; manual UI: all four cards show 0 DOUB ≈ $0 USD, no loading placeholder
Schema version bumped; docs + invariants updated (INV-INDEXER-PODIUM-PRIZE-PREVIEW) PASS indexer/src/api.rs SCHEMA_VERSION = "2.8.0"; docs/indexer/design.md, indexer/README.md, docs/frontend/arena-views.md, docs/testing/invariants-and-business-logic.md, skills/play-active-time-arena/SKILL.md
cd frontend && npm run typecheck && npm run lint && npm test PASS typecheck OK; lint 0 errors (9 pre-existing warnings); 109 files / 564 tests passed
cd indexer && cargo clippy --all-targets -- -D warnings && cargo test PASS clippy clean; 33 unit + 4 integration tests passed (includes arena_podiums_live_predictions_smoke)
bash scripts/verify-podium-live-anvil.sh regression PASS OK (read_block=25, live_rows=12)

Additional regression / manual checks

Check Result Command / notes
Vault funding regression PASS bash scripts/verify-vault-funding-anvil.sh
Legacy indexer (no prize field) → “Prizes unavailable” PASS ArenaSimplePodiumSection.test.tsx — podiumPayoutPreview: null
4∶2∶1 rounding property test PASS arena_podium_prize::tests::payout_shares_sum_equals_pool
Manual UI — no infinite loading on /arena PASS Browser QA on http://127.0.0.1:5173/arena — four podium cards, each place shows 0 DOUB ≈ $0 USD

Implementation notes (confirmed in tree)

  • Indexer: arena_podium_prize.rs, head poll in chain_timer.rs, API fields in api_arena.rs
  • Frontend: usePodiumReads.ts maps prize_places_doub_wad → podiumPayoutPreview; ArenaSimplePage wires hook output
  • Verify script: scripts/verify-podium-prize-preview-anvil.sh

All acceptance criteria met. Closing as verified.

## Verification complete — GitLab #302 **Issue:** [Indexer + Simple podium: expose active-pool prize preview (DOUB + USD) on GET /v1/arena/podiums](https://gitlab.com/PlasticDigits/yieldomega/-/work_items/302) Verified on branch `main` (commits `3a663ac`, `e24fb48`). No repo changes required from this verification run. ### Acceptance criteria | Criterion | Result | How verified | |-----------|--------|--------------| | `GET /v1/arena/podiums` returns `prize_places_doub_wad` (3 strings) per row for all 4 categories | **PASS** | `curl -sf http://127.0.0.1:3100/v1/arena/podiums` — schema `2.8.0`, 4 rows each with `prize_places_doub_wad` + `active_pool_balance_doub_wad` | | Values match onchain `activePoolBalance(cat)` × 4∶2∶1 at `read_block_number` | **PASS** | `bash scripts/verify-podium-prize-preview-anvil.sh` → `OK (read_block=17, last_buy_pool=1000000000000000000000, schema=2.8.0)` | | `/arena` Simple podium cards show DOUB + `≈ $… USD` for populated pools ([#292](https://gitlab.com/PlasticDigits/yieldomega/-/issues/292)) | **PASS** | Verify script funds Last Buy pool via buy; unit tests cover populated preview; manual UI on fresh deploy confirms prize row format | | No `podiumPayoutPreview={undefined}` in `ArenaSimplePage` | **PASS** | `grep` — none; passes `podiumReads.podiumPayoutPreview` from hook | | Zero-balance pool shows `0` prizes, not “Prizes loading” | **PASS** | API returns `"0"` strings; `ArenaSimplePodiumSection.test.tsx` “zero DOUB prizes”; manual UI: all four cards show `0 DOUB ≈ $0 USD`, no loading placeholder | | Schema version bumped; docs + invariants updated (`INV-INDEXER-PODIUM-PRIZE-PREVIEW`) | **PASS** | `indexer/src/api.rs` `SCHEMA_VERSION = "2.8.0"`; `docs/indexer/design.md`, `indexer/README.md`, `docs/frontend/arena-views.md`, `docs/testing/invariants-and-business-logic.md`, `skills/play-active-time-arena/SKILL.md` | | `cd frontend && npm run typecheck && npm run lint && npm test` | **PASS** | typecheck OK; lint 0 errors (9 pre-existing warnings); 109 files / 564 tests passed | | `cd indexer && cargo clippy --all-targets -- -D warnings && cargo test` | **PASS** | clippy clean; 33 unit + 4 integration tests passed (includes `arena_podiums_live_predictions_smoke`) | | `bash scripts/verify-podium-live-anvil.sh` regression | **PASS** | `OK (read_block=25, live_rows=12)` | ### Additional regression / manual checks | Check | Result | Command / notes | |-------|--------|-----------------| | Vault funding regression | **PASS** | `bash scripts/verify-vault-funding-anvil.sh` | | Legacy indexer (no prize field) → “Prizes unavailable” | **PASS** | `ArenaSimplePodiumSection.test.tsx` — `podiumPayoutPreview: null` | | 4∶2∶1 rounding property test | **PASS** | `arena_podium_prize::tests::payout_shares_sum_equals_pool` | | Manual UI — no infinite loading on `/arena` | **PASS** | Browser QA on `http://127.0.0.1:5173/arena` — four podium cards, each place shows `0 DOUB ≈ $0 USD` | ### Implementation notes (confirmed in tree) - Indexer: `arena_podium_prize.rs`, head poll in `chain_timer.rs`, API fields in `api_arena.rs` - Frontend: `usePodiumReads.ts` maps `prize_places_doub_wad` → `podiumPayoutPreview`; `ArenaSimplePage` wires hook output - Verify script: `scripts/verify-podium-prize-preview-anvil.sh` All acceptance criteria met. Closing as verified.
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-06-08 06:22:58 +00:00
PlasticDigits commented 2026-06-08 06:54:05 +00:00 (Migrated from gitlab.com)

mentioned in commit cbeb0db44e

mentioned in commit cbeb0db44e8750c4f589c51cf6e29ef95b190f11
PlasticDigits commented 2026-06-08 06:54:34 +00:00 (Migrated from gitlab.com)

mentioned in merge request !446

mentioned in merge request !446
PlasticDigits commented 2026-06-08 08:45:13 +00:00 (Migrated from gitlab.com)

mentioned in commit 60cf970f15

mentioned in commit 60cf970f1515afd5087ea1f65430d1beb2ed2e42
PlasticDigits commented 2026-06-08 08:45:13 +00:00 (Migrated from gitlab.com)

mentioned in commit 60aea8d8da

mentioned in commit 60aea8d8da802fd173bbdb09d242094b106aa0fc
PlasticDigits commented 2026-06-08 08:45:13 +00:00 (Migrated from gitlab.com)

mentioned in commit 818be0ba84

mentioned in commit 818be0ba8460b7274d5ef2d676cbd72f8f4229c2
PlasticDigits commented 2026-06-08 08:45:13 +00:00 (Migrated from gitlab.com)

mentioned in commit a34c7b99ea

mentioned in commit a34c7b99ea9bb1d946a05075bbaff743eeab1ed6
PlasticDigits commented 2026-06-13 06:34:51 +00:00 (Migrated from gitlab.com)

mentioned in issue #307

mentioned in issue #307
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#302
No description provided.