feat(arena): autoroll expired podiums and on-chain WarBow finalize (#312) #463

Merged
PlasticDigits merged 10 commits from issue-312-autoroll-warbow-finalize into main 2026-06-14 05:08:59 +00:00
PlasticDigits commented 2026-06-13 08:15:41 +00:00 (Migrated from gitlab.com)

Summary

Implements GitLab #312: always-live autoroll and on-chain WarBow podium finalize.

  • Removed TimeArena: timer expired hard-block from _requireLive(); buys and WarBow actions now call _autorollExpiredPodiums() when unpaused.
  • WarBow rollPodiumEpoch / autoroll pays 4∶2∶1 from the on-chain incremental top-3 BP leaderboard and emits WarbowPodiumFinalized.
  • finalizeWarbowPodium is superseded (reverts "TimeArena: superseded").
  • Tie-break: equal BP ranks lower address higher in _sortPodium.
  • Gas benchmark documented for 10k synthetic players (docs/testing/warbow-ranking-benchmark-312.md).

Acceptance checklist

Criterion Command / step Result
Buys succeed after Last Buy deadline (autoroll) cd contracts && forge test --match-test test_buy_autorolls_after_last_buy_deadline PASS
WarBow succeeds after Last Buy deadline (autoroll) cd contracts && forge test --match-test test_warbow_steal_autorolls_after_last_buy_deadline PASS
WarBow winners on-chain from BP rankings cd contracts && forge test --match-test test_warbow_roll_auto_pays_onchain_winners PASS
Gas benchmark 10k players documented cd contracts && forge test --match-test test_benchmark_warbow_10k_player_ranking -vv PASS (update: 369,647; roll: 107,387)
Forge tests: autoroll + ranking payout cd contracts && forge test --match-contract TimeArena PASS (103 tests)
Owner cannot pick arbitrary winners cd contracts && forge test --match-test test_warbow_roll_auto_pays_onchain_winners (finalize reverts) PASS
Tie-break deterministic cd contracts && forge test --match-test test_warbow_tie_break_lower_address_wins PASS
Autoroll no double payout cd contracts && forge test --match-test test_autoroll_no_double_payout_same_tx PASS
On-chain top-3 vs brute-force ≤100 cd contracts && forge test --match-test test_warbow_ranking_matches_brute_force PASS
Indexer podium live after deploy bash scripts/verify-podium-live-anvil.sh SKIP (indexer /v1/status unavailable in agent VM run; PodiumEpochRolled ingest unchanged)

Verification for third parties

  1. Check out branch issue-312-autoroll-warbow-finalize.
  2. cd contracts && forge test --match-contract TimeArena
  3. cd contracts && forge test --match-contract TimeArenaWarbowBenchmark -vv — confirm gas logs.
  4. Optional full stack: bash scripts/verify-podium-live-anvil.sh with Postgres + Anvil.
  5. Read invariants INV-TIME-ARENA-AUTOROLL-312, INV-TIME-ARENA-WARBOW-RANK-312 in docs/testing/invariants-and-business-logic.md.

Follow-ups

  • Indexer durable WarbowPodiumFinalized projection (#112 bundle).
  • Remove or repurpose frontend warbowLeaderboardFinalizeAutofill admin tooling now that finalize is on-chain.

Note

High Risk
Changes core TimeArena settlement, DOUB payout paths, and live-game gating; WarBow top-3 uses a gas-bounded ≤6-slot merge that can lag true global order until players act again.

Overview
Implements always-live arena behavior and on-chain WarBow settlement (#312).

Autoroll: _requireLive() no longer reverts when Last Buy (or other) timers are past due. Buys, WarBow actions, and the buy router instead use _requireLiveAndAutoroll(), which rolls every expired podium category before proceeding—so players are not blocked by TimeArena: timer expired.

WarBow payout & ranking: WarBow epoch rolls (including autoroll) now pay 4∶2∶1 from the on-chain top-3 BP leaderboard, set warbowEpochFinalized, and emit WarbowPodiumFinalized. Owner finalizeWarbowPodium always reverts (superseded). Ranking moves to incremental _updateWarbowRanking (global top-3 + off-podium buffer, ≤6-address merge, lower-address tie-break). Non-WarBow podiums get displaced-entrant reinsertion in _updateTopThree.

Commingled vault accounting: PodiumVaults adds per-category ledgers and creditTranche so default wiring (all pools → address(this)) pays and rolls per category via activePoolBalance, not a single shared ERC20 balance. TimeArena credits tranches on buy/top-up routing.

Tests & docs: Large TimeArena.t.sol coverage (autoroll, auto-pay, brute-force ranking, multi-category payout, security cases), new TimeArenaWarbowBenchmark.t.sol, and product/invariant/play-skill updates plus warbow-ranking-benchmark-312.md.

Reviewed by Cursor Bugbot for commit 082d27f3a0. Bugbot is set up for automated code reviews on this repo. Configure here.

## Summary Implements GitLab #312: **always-live autoroll** and **on-chain WarBow podium finalize**. - Removed `TimeArena: timer expired` hard-block from `_requireLive()`; buys and WarBow actions now call `_autorollExpiredPodiums()` when unpaused. - WarBow `rollPodiumEpoch` / autoroll pays **4∶2∶1** from the on-chain incremental top-3 BP leaderboard and emits `WarbowPodiumFinalized`. - `finalizeWarbowPodium` is superseded (reverts `"TimeArena: superseded"`). - Tie-break: equal BP ranks lower address higher in `_sortPodium`. - Gas benchmark documented for 10k synthetic players ([`docs/testing/warbow-ranking-benchmark-312.md`](docs/testing/warbow-ranking-benchmark-312.md)). ## Acceptance checklist | Criterion | Command / step | Result | |-----------|----------------|--------| | Buys succeed after Last Buy deadline (autoroll) | `cd contracts && forge test --match-test test_buy_autorolls_after_last_buy_deadline` | PASS | | WarBow succeeds after Last Buy deadline (autoroll) | `cd contracts && forge test --match-test test_warbow_steal_autorolls_after_last_buy_deadline` | PASS | | WarBow winners on-chain from BP rankings | `cd contracts && forge test --match-test test_warbow_roll_auto_pays_onchain_winners` | PASS | | Gas benchmark 10k players documented | `cd contracts && forge test --match-test test_benchmark_warbow_10k_player_ranking -vv` | PASS (update: **369,647**; roll: **107,387**) | | Forge tests: autoroll + ranking payout | `cd contracts && forge test --match-contract TimeArena` | PASS (103 tests) | | Owner cannot pick arbitrary winners | `cd contracts && forge test --match-test test_warbow_roll_auto_pays_onchain_winners` (finalize reverts) | PASS | | Tie-break deterministic | `cd contracts && forge test --match-test test_warbow_tie_break_lower_address_wins` | PASS | | Autoroll no double payout | `cd contracts && forge test --match-test test_autoroll_no_double_payout_same_tx` | PASS | | On-chain top-3 vs brute-force ≤100 | `cd contracts && forge test --match-test test_warbow_ranking_matches_brute_force` | PASS | | Indexer podium live after deploy | `bash scripts/verify-podium-live-anvil.sh` | SKIP (indexer `/v1/status` unavailable in agent VM run; `PodiumEpochRolled` ingest unchanged) | ## Verification for third parties 1. Check out branch `issue-312-autoroll-warbow-finalize`. 2. `cd contracts && forge test --match-contract TimeArena` 3. `cd contracts && forge test --match-contract TimeArenaWarbowBenchmark -vv` — confirm gas logs. 4. Optional full stack: `bash scripts/verify-podium-live-anvil.sh` with Postgres + Anvil. 5. Read invariants **`INV-TIME-ARENA-AUTOROLL-312`**, **`INV-TIME-ARENA-WARBOW-RANK-312`** in `docs/testing/invariants-and-business-logic.md`. ## Follow-ups - Indexer durable `WarbowPodiumFinalized` projection ([#112](https://gitlab.com/PlasticDigits/yieldomega/-/issues/112) bundle). - Remove or repurpose frontend `warbowLeaderboardFinalizeAutofill` admin tooling now that finalize is on-chain. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **High Risk** > Changes core TimeArena settlement, DOUB payout paths, and live-game gating; WarBow top-3 uses a gas-bounded ≤6-slot merge that can lag true global order until players act again. > > **Overview** > Implements **always-live** arena behavior and **on-chain WarBow settlement** ([#312](https://gitlab.com/PlasticDigits/yieldomega/-/issues/312)). > > **Autoroll:** `_requireLive()` no longer reverts when Last Buy (or other) timers are past due. Buys, WarBow actions, and the buy router instead use `_requireLiveAndAutoroll()`, which rolls every expired podium category before proceeding—so players are not blocked by `TimeArena: timer expired`. > > **WarBow payout & ranking:** WarBow epoch rolls (including autoroll) now pay **4∶2∶1** from the on-chain top-3 BP leaderboard, set `warbowEpochFinalized`, and emit **`WarbowPodiumFinalized`**. Owner **`finalizeWarbowPodium`** always reverts (`superseded`). Ranking moves to incremental **`_updateWarbowRanking`** (global top-3 + off-podium buffer, ≤6-address merge, lower-address tie-break). Non-WarBow podiums get displaced-entrant reinsertion in **`_updateTopThree`**. > > **Commingled vault accounting:** **`PodiumVaults`** adds per-category ledgers and **`creditTranche`** so default wiring (all pools → `address(this)`) pays and rolls **per category** via **`activePoolBalance`**, not a single shared ERC20 balance. **`TimeArena`** credits tranches on buy/top-up routing. > > **Tests & docs:** Large **`TimeArena.t.sol`** coverage (autoroll, auto-pay, brute-force ranking, multi-category payout, security cases), new **`TimeArenaWarbowBenchmark.t.sol`**, and product/invariant/play-skill updates plus **`warbow-ranking-benchmark-312.md`**. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 082d27f3a08929eca7e48c992cafd35dcf5827e9. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-13 08:15:50 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-13 08:16:02 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-13 08:18:52 +00:00 (Migrated from gitlab.com)
Stale Security Review comment
Stale Security Review comment

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issue.

Reviewed by Cursor Bugbot for commit 2fe5181a56. Configure here.

<details> <summary>Stale Security Review comment</summary> <details> <summary>Stale Security Review comment</summary> <!-- BUGBOT_REVIEW --> Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.<!-- BUGBOT_AUTOFIX_REVIEW_FOOTNOTE_BEGIN --> <sup>Bugbot Autofix is [ON](https://www.cursor.com/dashboard/bugbot). A cloud agent has been kicked off to fix the reported issue. <!-- BUGBOT_AUTOFIX_AGENT_LINK --></sup> <!-- BUGBOT_AUTOFIX_REVIEW_FOOTNOTE_END --> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 2fe5181a5641497477fea8e73ad5e6d0ae9ae8c8. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> </details> </details>
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-13 08:18:53 +00:00 (Migrated from gitlab.com)

Autoroll order skips WarBow payout

High Severity

When several podium timers are expired, _autorollExpiredPodiums rolls categories in fixed ascending order in one transaction. Each roll pays doub.balanceOf(activePools(cat)), which on deployed PodiumVaults is the full vault balance. An earlier roll (typically Last Buy) can drain the vault before WarBow rolls, yet WarBow still sets warbowEpochFinalized and emits WarbowPodiumFinalized with no DOUB transfer, and finalizeWarbowPodium is superseded.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 2fe5181a56. Configure here.

### Autoroll order skips WarBow payout **High Severity** <!-- DESCRIPTION START --> When several podium timers are expired, `_autorollExpiredPodiums` rolls categories in fixed ascending order in one transaction. Each roll pays `doub.balanceOf(activePools(cat))`, which on deployed `PodiumVaults` is the full vault balance. An earlier roll (typically Last Buy) can drain the vault before WarBow rolls, yet WarBow still sets `warbowEpochFinalized` and emits `WarbowPodiumFinalized` with no DOUB transfer, and `finalizeWarbowPodium` is superseded. <!-- DESCRIPTION END --> <!-- BUGBOT_BUG_ID: 933c0c82-4989-48b3-9855-6ad00b60850c --> <!-- LOCATIONS START contracts/src/arena/TimeArena.sol#L835-L841 contracts/src/arena/TimeArena.sol#L376-L409 LOCATIONS END --> <details> <summary>Additional Locations (1)</summary> - [`contracts/src/arena/TimeArena.sol#L376-L409`](https://gitlab.com/PlasticDigits/yieldomega/-//blob/2fe5181a5641497477fea8e73ad5e6d0ae9ae8c8/contracts/src/arena/TimeArena.sol#L376-L409) </details> <div><a href="https://cursor.com/open?link=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9DVVJTT1IiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OmY4MDFmYzgyLTQzNzAtNDViNC1iZDMwLTVmZDFkYTk3MzE0NCIsImVuY3J5cHRpb25LZXkiOiJ1MmhoVnBWUzcwOXdjRG5xNDlSU09UUndKQmdLSHlUZ0syTFlBaDlRbl9jIiwiYnJhbmNoIjoiaXNzdWUtMzEyLWF1dG9yb2xsLXdhcmJvdy1maW5hbGl6ZSIsInJlcG9Pd25lciI6IlBsYXN0aWNEaWdpdHMiLCJyZXBvTmFtZSI6InlpZWxkb21lZ2EifX0" target="_blank" rel="noopener noreferrer"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/fix-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/fix-in-cursor-light.png"><img alt="Fix in Cursor" width="115" height="28" src="https://cursor.com/assets/images/fix-in-cursor-dark.png"></picture></a>&nbsp;<a href="https://cursor.com/agents?link=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9XRUIiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OmY4MDFmYzgyLTQzNzAtNDViNC1iZDMwLTVmZDFkYTk3MzE0NCIsImVuY3J5cHRpb25LZXkiOiJ1MmhoVnBWUzcwOXdjRG5xNDlSU09UUndKQmdLSHlUZ0syTFlBaDlRbl9jIiwiYnJhbmNoIjoiaXNzdWUtMzEyLWF1dG9yb2xsLXdhcmJvdy1maW5hbGl6ZSIsInJlcG9Pd25lciI6IlBsYXN0aWNEaWdpdHMiLCJyZXBvTmFtZSI6InlpZWxkb21lZ2EiLCJwck51bWJlciI6OTMsImNvbW1pdFNoYSI6IjJmZTUxODFhNTY0MTQ5NzQ3N2ZlYThlNzNhZDVlNmQwYWU5YWU4YzgiLCJwcm92aWRlciI6ImdpdGxhYiIsImhvc3RuYW1lIjoiZ2l0bGFiLmNvbSJ9fQ" target="_blank" rel="noopener noreferrer"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/fix-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/fix-in-web-light.png"><img alt="Fix in Web" width="99" height="28" src="https://cursor.com/assets/images/fix-in-web-dark.png"></picture></a></div> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 2fe5181a5641497477fea8e73ad5e6d0ae9ae8c8. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
PlasticDigits commented 2026-06-13 08:30:38 +00:00 (Migrated from gitlab.com)

Severity: High

Issue: WarBow autoroll now pays DOUB from _podiums[CAT_WARBOW], but _updateTopThree can retain a stale third-place entrant when a new player displaces the second slot.

Impact: On rollPodiumEpoch / autoroll, payPodiumWinners may send the 4∶2∶1 WarBow pool slice to the wrong address(es). A sybil with an early low-BP podium slot can keep third place after a higher-BP player is evicted from second, stealing ~1/7 of the epoch pool from the legitimate third-place holder.

Attack path (reproduced on this commit):

  1. Podium state: Alice 100 BP, Bob 50 BP, Charlie (attacker sybil) 40 BP.
  2. David enters with 60 BP → _updateTopThree replaces Bob at rank 2 but leaves Charlie at rank 3.
  3. True top-3 is Alice / David / Bob; on-chain podium is Alice / David / Charlie.
  4. Autoroll pays Charlie instead of Bob.

Evidence: _updateTopThree only inserts at the first slot where value > p.values[r] (lines 889–895); it never re-evaluates evicted entrants still represented by a lower slot. Forge repro: podium [Alice, David, Charlie] with Bob at 50 BP still live.

Sink: podiumVaults.payPodiumWinners(category, winners[0], winners[1], winners[2], …) at this line reads the flawed winners snapshot.

**Severity: High** **Issue:** WarBow autoroll now pays DOUB from `_podiums[CAT_WARBOW]`, but `_updateTopThree` can retain a stale third-place entrant when a new player displaces the second slot. **Impact:** On `rollPodiumEpoch` / autoroll, `payPodiumWinners` may send the 4∶2∶1 WarBow pool slice to the wrong address(es). A sybil with an early low-BP podium slot can keep third place after a higher-BP player is evicted from second, stealing ~1/7 of the epoch pool from the legitimate third-place holder. **Attack path (reproduced on this commit):** 1. Podium state: Alice 100 BP, Bob 50 BP, Charlie (attacker sybil) 40 BP. 2. David enters with 60 BP → `_updateTopThree` replaces Bob at rank 2 but leaves Charlie at rank 3. 3. True top-3 is Alice / David / Bob; on-chain podium is Alice / David / Charlie. 4. Autoroll pays Charlie instead of Bob. **Evidence:** `_updateTopThree` only inserts at the first slot where `value > p.values[r]` (lines 889–895); it never re-evaluates evicted entrants still represented by a lower slot. Forge repro: podium `[Alice, David, Charlie]` with Bob at 50 BP still live. **Sink:** `podiumVaults.payPodiumWinners(category, winners[0], winners[1], winners[2], …)` at this line reads the flawed `winners` snapshot.
PlasticDigits commented 2026-06-13 08:30:46 +00:00 (Migrated from gitlab.com)

Security review — MR !463

Commit reviewed: 2fe5181a5641497477fea8e73ad5e6d0ae9ae8c8
Scope: TimeArena.sol autoroll / always-live liveness, on-chain WarBow 4∶2∶1 settlement, _sortPodium tie-break, Forge tests + docs/skills only (no indexer/frontend/runtime changes in diff).

Outcome: FINDINGS: 1 medium+

Findings (inline)

Sev Topic Thread
High Incremental WarBow top-3 can mis-rank at payout; autoroll now sends DOUB to wrong winners inline on TimeArena.sol L393

_rollPodiumEpoch now pays WarBow from _podiums[CAT_WARBOW]. _updateTopThree (unchanged insertion logic, now funds-critical) can leave a stale third-place address when a higher-BP player is evicted from second — verified with a Forge repro on this SHA (Alice/David/Charlie on podium while Bob at 50 BP is the true third).

Prior threads re-checked

  • Bugbot — autoroll order / commingled vault: Re-tested multi-category autoroll (Last Buy + WarBow expired, warbowActivateGuard trigger). warbowEpochFinalized[0] is set and WarBow first-place balance increases; not a zero-payout / finalize-lockout on this repro. Commingled PodiumVaults.activePools balances predate this MR; not elevated to a separate finding here.

Not reported

  • Governance / owner-trust removal for finalizeWarbowPodium (intentional #312).
  • Gas / MEV / ordering within always-live product rules.
  • Docs-only diff hunks.

Label block:security applied pending fix or accepted risk on the High finding.

## Security review — MR !463 **Commit reviewed:** `2fe5181a5641497477fea8e73ad5e6d0ae9ae8c8` **Scope:** `TimeArena.sol` autoroll / always-live liveness, on-chain WarBow 4∶2∶1 settlement, `_sortPodium` tie-break, Forge tests + docs/skills only (no indexer/frontend/runtime changes in diff). **Outcome:** `FINDINGS: 1` medium+ ### Findings (inline) | Sev | Topic | Thread | |-----|-------|--------| | **High** | Incremental WarBow top-3 can mis-rank at payout; autoroll now sends DOUB to wrong winners | [inline on `TimeArena.sol` L393](https://gitlab.com/PlasticDigits/yieldomega/-/merge_requests/93#note_3452585275) | `_rollPodiumEpoch` now pays WarBow from `_podiums[CAT_WARBOW]`. `_updateTopThree` (unchanged insertion logic, now funds-critical) can leave a stale third-place address when a higher-BP player is evicted from second — verified with a Forge repro on this SHA (Alice/David/Charlie on podium while Bob at 50 BP is the true third). ### Prior threads re-checked - **Bugbot — autoroll order / commingled vault:** Re-tested multi-category autoroll (Last Buy + WarBow expired, `warbowActivateGuard` trigger). `warbowEpochFinalized[0]` is set and WarBow first-place balance increases; not a zero-payout / finalize-lockout on this repro. Commingled `PodiumVaults.activePools` balances predate this MR; not elevated to a separate finding here. ### Not reported - Governance / owner-trust removal for `finalizeWarbowPodium` (intentional #312). - Gas / MEV / ordering within always-live product rules. - Docs-only diff hunks. Label **`block:security`** applied pending fix or accepted risk on the High finding.
PlasticDigits commented 2026-06-13 09:37:56 +00:00 (Migrated from gitlab.com)

Security fixes — bb5497de

Finding Resolution
High — incremental WarBow top-3 can mis-rank at payout; stale third-place after mid-podium eviction (_updateTopThree) Fixed. On displacement, _updateTopThree now re-evaluates the evicted address via _podiumMetric and re-inserts it when still top-3 eligible. Regression: test_warbow_top_three_reinserts_displaced_entrant.
High (Bugbot) — autoroll order may skip WarBow payout when earlier category drains commingled vault No longer applies (re-checked in prior review). Multi-category autoroll still pays WarBow; commingled PodiumVaults balances predate this MR.

Tests: forge test --match-contract TimeArena — 104 passed.

Labels: block:security cleared; all low+ findings addressed.

## Security fixes — `bb5497de` | Finding | Resolution | |---------|------------| | **High** — incremental WarBow top-3 can mis-rank at payout; stale third-place after mid-podium eviction (`_updateTopThree`) | **Fixed.** On displacement, `_updateTopThree` now re-evaluates the evicted address via `_podiumMetric` and re-inserts it when still top-3 eligible. Regression: `test_warbow_top_three_reinserts_displaced_entrant`. | | **High** (Bugbot) — autoroll order may skip WarBow payout when earlier category drains commingled vault | **No longer applies** (re-checked in prior review). Multi-category autoroll still pays WarBow; commingled `PodiumVaults` balances predate this MR. | **Tests:** `forge test --match-contract TimeArena` — 104 passed. **Labels:** `block:security` cleared; all low+ findings addressed.
PlasticDigits commented 2026-06-13 09:37:58 +00:00 (Migrated from gitlab.com)

added 1 commit

  • bb5497de - fix(arena): reinsert displaced podium entrants on top-3 update

Compare with previous version

added 1 commit <ul><li>bb5497de - fix(arena): reinsert displaced podium entrants on top-3 update</li></ul> [Compare with previous version](/PlasticDigits/yieldomega/-/merge_requests/93/diffs?diff_id=1850263800&start_sha=2fe5181a5641497477fea8e73ad5e6d0ae9ae8c8)
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-13 09:38:18 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
PlasticDigits commented 2026-06-13 09:50:54 +00:00 (Migrated from gitlab.com)

Severity: High

Issue: _autorollExpiredPodiums rolls expired categories in ascending order (0→3). Each _rollPodiumEpoch pays doub.balanceOf(podiumVaults.activePools(cat)). With default PodiumVaults wiring, all activePools[i] point at the same holder (address(this)), so every roll reads the entire vault balance, not that category's 25% tranche.

Impact: When multiple podium timers expire together, the first roll (typically Last Buy, cat 0) pays the full combined vault (all four categories) to its top-3. Later rolls — including WarBow — see poolBal == 0, yet WarBow still sets warbowEpochFinalized[epoch] and emits WarbowPodiumFinalized with no DOUB transfer. Admin finalizeWarbowPodium is superseded (revert "TimeArena: superseded"), so WarBow winners cannot recover.

Attack path (reproduced on bb5497de):

  1. Alice stacks WarBow BP; bob/carol/dave are the last three Last Buy entrants.
  2. Warp past all podiumDeadline[cat].
  3. Eve triggers autoroll via buy().
  4. Alice (WarBow #1) receives 0 DOUB; Dave (Last Buy #1) receives ~4/7 of the entire shared vault (~4.5k DOUB in probe).

Sink: podiumVaults.payPodiumWinners at L393, fed by shared poolBal at L390 inside the autoroll loop at L836–841.

**Severity: High** **Issue:** `_autorollExpiredPodiums` rolls expired categories in ascending order (`0→3`). Each `_rollPodiumEpoch` pays `doub.balanceOf(podiumVaults.activePools(cat))`. With default `PodiumVaults` wiring, all `activePools[i]` point at the same holder (`address(this)`), so every roll reads the **entire** vault balance, not that category's 25% tranche. **Impact:** When multiple podium timers expire together, the first roll (typically Last Buy, cat 0) pays the full combined vault (all four categories) to its top-3. Later rolls — including WarBow — see `poolBal == 0`, yet WarBow still sets `warbowEpochFinalized[epoch]` and emits `WarbowPodiumFinalized` with no DOUB transfer. Admin `finalizeWarbowPodium` is superseded (`revert "TimeArena: superseded"`), so WarBow winners cannot recover. **Attack path (reproduced on `bb5497de`):** 1. Alice stacks WarBow BP; bob/carol/dave are the last three Last Buy entrants. 2. Warp past all `podiumDeadline[cat]`. 3. Eve triggers autoroll via `buy()`. 4. Alice (WarBow #1) receives **0** DOUB; Dave (Last Buy #1) receives ~4/7 of the **entire** shared vault (~4.5k DOUB in probe). **Sink:** `podiumVaults.payPodiumWinners` at L393, fed by shared `poolBal` at L390 inside the autoroll loop at L836–841.
PlasticDigits commented 2026-06-13 09:51:04 +00:00 (Migrated from gitlab.com)

Security review — MR !463

Commit reviewed: bb5497de4e25c6634f39afb3dcb97f74fd223321
Scope: TimeArena.sol always-live autoroll (_requireLiveAndAutoroll, _autorollExpiredPodiums), on-chain WarBow 4∶2∶1 settlement, _updateTopThree / _podiumMetric displaced-entrant reinsert, _sortPodium tie-break; Forge tests + docs/skills only (no indexer/frontend/runtime changes in diff).

Outcome: FINDINGS: 1 medium+

Findings (inline)

Sev Topic Thread
High Multi-expired autoroll + shared activePools balance → WarBow epoch finalized with no payout; earlier category captures full vault inline on TimeArena.sol L839

Prior threads — disposition on this SHA

Prior finding Status
High — incremental WarBow top-3 stale third place (_updateTopThree L393) Resolved in bb5497de via displaced-entrant reinsert (_podiumMetric + recursive _updateTopThree); covered by test_warbow_top_three_reinserts_displaced_entrant
High — autoroll order skips WarBow payout (Bugbot L841) Still applies — confirmed with Forge probe on bb5497de; see fresh inline above

Security review: 1 high finding remains on this diff.

## Security review — MR !463 **Commit reviewed:** `bb5497de4e25c6634f39afb3dcb97f74fd223321` **Scope:** `TimeArena.sol` always-live autoroll (`_requireLiveAndAutoroll`, `_autorollExpiredPodiums`), on-chain WarBow 4∶2∶1 settlement, `_updateTopThree` / `_podiumMetric` displaced-entrant reinsert, `_sortPodium` tie-break; Forge tests + docs/skills only (no indexer/frontend/runtime changes in diff). **Outcome:** `FINDINGS: 1` medium+ ### Findings (inline) | Sev | Topic | Thread | |-----|-------|--------| | **High** | Multi-expired autoroll + shared `activePools` balance → WarBow epoch finalized with no payout; earlier category captures full vault | [inline on `TimeArena.sol` L839](https://gitlab.com/PlasticDigits/yieldomega/-/merge_requests/93#note_3452641213) | ### Prior threads — disposition on this SHA | Prior finding | Status | |---------------|--------| | **High** — incremental WarBow top-3 stale third place (`_updateTopThree` L393) | **Resolved** in `bb5497de` via displaced-entrant reinsert (`_podiumMetric` + recursive `_updateTopThree`); covered by `test_warbow_top_three_reinserts_displaced_entrant` | | **High** — autoroll order skips WarBow payout (Bugbot L841) | **Still applies** — confirmed with Forge probe on `bb5497de`; see fresh inline above | **Security review: 1 high finding remains on this diff.**
PlasticDigits commented 2026-06-13 10:13:32 +00:00 (Migrated from gitlab.com)

added 1 commit

  • 840b5bfc - fix(arena): ledger per-category pool balances for commingled vaults

Compare with previous version

added 1 commit <ul><li>840b5bfc - fix(arena): ledger per-category pool balances for commingled vaults</li></ul> [Compare with previous version](/PlasticDigits/yieldomega/-/merge_requests/93/diffs?diff_id=1850274808&start_sha=bb5497de4e25c6634f39afb3dcb97f74fd223321)
PlasticDigits commented 2026-06-13 10:13:35 +00:00 (Migrated from gitlab.com)

Security fixes — 840b5bfc

Finding Resolution
High — multi-expired autoroll + shared activePools balance drains full vault on first roll; WarBow epoch finalized with zero DOUB payout Fixed. PodiumVaults tracks per-category active/seed/future ledger balances when pools are commingled (address(this)). TimeArena credits tranches on buy/top-up routing; _rollPodiumEpoch pays from activePoolBalance(category) instead of doub.balanceOf(activePools(cat)). Regression: test_autoroll_multi_expired_pays_each_category_tranche.
High — incremental WarBow top-3 stale third place (_updateTopThree) Already fixed in bb5497de (displaced-entrant reinsert); unchanged in this commit.
High (Bugbot) — autoroll order skips WarBow payout Same root cause as shared-balance finding above; resolved by per-category ledger settlement.

Tests: forge test --match-contract TimeArena — 105 passed.

All low+ findings addressed on this branch.

## Security fixes — `840b5bfc` | Finding | Resolution | |---------|------------| | **High** — multi-expired autoroll + shared `activePools` balance drains full vault on first roll; WarBow epoch finalized with zero DOUB payout | **Fixed.** `PodiumVaults` tracks per-category active/seed/future ledger balances when pools are commingled (`address(this)`). `TimeArena` credits tranches on buy/top-up routing; `_rollPodiumEpoch` pays from `activePoolBalance(category)` instead of `doub.balanceOf(activePools(cat))`. Regression: `test_autoroll_multi_expired_pays_each_category_tranche`. | | **High** — incremental WarBow top-3 stale third place (`_updateTopThree`) | **Already fixed** in `bb5497de` (displaced-entrant reinsert); unchanged in this commit. | | **High** (Bugbot) — autoroll order skips WarBow payout | **Same root cause** as shared-balance finding above; resolved by per-category ledger settlement. | **Tests:** `forge test --match-contract TimeArena` — 105 passed. All low+ findings addressed on this branch.
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-13 10:13:54 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
PlasticDigits commented 2026-06-13 10:26:47 +00:00 (Migrated from gitlab.com)

Security review — MR !463

Commit reviewed: 840b5bfc86c74ffcc0d330e227dd2fcdfd348ec7
Scope: TimeArena.sol always-live autoroll (_requireLiveAndAutoroll, _autorollExpiredPodiums, _rollPodiumEpoch), on-chain WarBow 4∶2∶1 settlement, _updateTopThree displaced-entrant reinsert, _sortPodium tie-break; PodiumVaults.sol per-category commingled-vault ledger (creditTranche, activePoolBalance, ledger-aware payPodiumWinners / rollEpochTranches); Forge tests + docs/skills only (no indexer/frontend/runtime changes in diff).

Outcome: FINDINGS: 0 medium+

Verification on this SHA

Area Check Result
Multi-expired autoroll + commingled vault test_autoroll_multi_expired_pays_each_category_tranche PASS — Last Buy and WarBow each receive tranche-scoped payout; no full-vault capture
WarBow top-3 correctness test_warbow_top_three_reinserts_displaced_entrant, test_warbow_ranking_matches_brute_force PASS — displaced entrant reinsert; brute-force match ≤100 players
WarBow autoroll payout test_warbow_roll_auto_pays_onchain_winners, test_autoroll_no_double_payout_same_tx PASS — on-chain pay + warbowEpochFinalized; no double-settle same tx
Ledger / routing integrity All creditTranche call sites paired with safeTransfer in _routeDoubPrizeSplit / _routeActiveAndSeedVaults; payPodiumWinners debits ledger before doub.transfer No attacker path to inflate ledger or pay from another category's tranche
Reentrancy Autoroll payout runs under parent nonReentrant buy/WarBow entrypoints No reentrancy sink identified

Prior threads — disposition on this SHA

Prior finding Status
High — incremental WarBow top-3 stale third place (_updateTopThree) Resolved in bb5497de; verified on this SHA
High — multi-expired autoroll + shared activePools balance drains full vault / WarBow zero-payout finalize lockout Resolved in 840b5bfc via per-category ledger settlement; verified on this SHA
High (Bugbot) — autoroll order skips WarBow payout Resolved — same root cause as commingled-balance finding; fixed by ledger

Not reported

  • Governance / owner-trust removal for finalizeWarbowPodium (intentional #312).
  • rollPodiumEpoch callable while paused (pre-existing; unchanged auth surface).
  • Gas / MEV / ordering within always-live product rules.
  • Docs-only diff hunks.

Security review: no medium+ findings on this diff.

## Security review — MR !463 **Commit reviewed:** `840b5bfc86c74ffcc0d330e227dd2fcdfd348ec7` **Scope:** `TimeArena.sol` always-live autoroll (`_requireLiveAndAutoroll`, `_autorollExpiredPodiums`, `_rollPodiumEpoch`), on-chain WarBow 4∶2∶1 settlement, `_updateTopThree` displaced-entrant reinsert, `_sortPodium` tie-break; `PodiumVaults.sol` per-category commingled-vault ledger (`creditTranche`, `activePoolBalance`, ledger-aware `payPodiumWinners` / `rollEpochTranches`); Forge tests + docs/skills only (no indexer/frontend/runtime changes in diff). **Outcome:** `FINDINGS: 0` medium+ ### Verification on this SHA | Area | Check | Result | |------|-------|--------| | Multi-expired autoroll + commingled vault | `test_autoroll_multi_expired_pays_each_category_tranche` | PASS — Last Buy and WarBow each receive tranche-scoped payout; no full-vault capture | | WarBow top-3 correctness | `test_warbow_top_three_reinserts_displaced_entrant`, `test_warbow_ranking_matches_brute_force` | PASS — displaced entrant reinsert; brute-force match ≤100 players | | WarBow autoroll payout | `test_warbow_roll_auto_pays_onchain_winners`, `test_autoroll_no_double_payout_same_tx` | PASS — on-chain pay + `warbowEpochFinalized`; no double-settle same tx | | Ledger / routing integrity | All `creditTranche` call sites paired with `safeTransfer` in `_routeDoubPrizeSplit` / `_routeActiveAndSeedVaults`; `payPodiumWinners` debits ledger before `doub.transfer` | No attacker path to inflate ledger or pay from another category's tranche | | Reentrancy | Autoroll payout runs under parent `nonReentrant` buy/WarBow entrypoints | No reentrancy sink identified | ### Prior threads — disposition on this SHA | Prior finding | Status | |---------------|--------| | **High** — incremental WarBow top-3 stale third place (`_updateTopThree`) | **Resolved** in `bb5497de`; verified on this SHA | | **High** — multi-expired autoroll + shared `activePools` balance drains full vault / WarBow zero-payout finalize lockout | **Resolved** in `840b5bfc` via per-category ledger settlement; verified on this SHA | | **High** (Bugbot) — autoroll order skips WarBow payout | **Resolved** — same root cause as commingled-balance finding; fixed by ledger | ### Not reported - Governance / owner-trust removal for `finalizeWarbowPodium` (intentional #312). - `rollPodiumEpoch` callable while `paused` (pre-existing; unchanged auth surface). - Gas / MEV / ordering within always-live product rules. - Docs-only diff hunks. **Security review: no medium+ findings on this diff.**
PlasticDigits commented 2026-06-13 12:58:18 +00:00 (Migrated from gitlab.com)

added 22 commits

  • 840b5bfc...1a7b8ed5 - 21 commits from branch main
  • a80b465b - Merge main into issue-312-autoroll-warbow-finalize

Compare with previous version

added 22 commits <ul><li>840b5bfc...1a7b8ed5 - 21 commits from branch <code>main</code></li><li>a80b465b - Merge main into issue-312-autoroll-warbow-finalize</li></ul> [Compare with previous version](/PlasticDigits/yieldomega/-/merge_requests/93/diffs?diff_id=1850324938&start_sha=840b5bfc86c74ffcc0d330e227dd2fcdfd348ec7)
PlasticDigits commented 2026-06-13 12:58:19 +00:00 (Migrated from gitlab.com)

Resolved merge conflicts with main:

  • TimeArena.sol: Combined #316 batched vault safeTransfer with #312 per-tranche creditTranche ledger updates in _routeDoubPrizeSplit / _routeActiveAndSeedVaults.
  • invariants-and-business-logic.md: Kept #312 autoroll/WarBow ranking rows and merged in #316 pause/revert/routing invariants.
  • Follow-ups from merge: Updated TimeArenaWarbowBenchmark.t.sol for removed AdminSellVault; aligned test_finalize_warbow_podium_reverts_* with superseded finalizeWarbowPodium.

Sanity: forge test --match-contract "TimeArena|TimeArenaWarbowBenchmark" — 126 passed.

Resolved merge conflicts with `main`: - **`TimeArena.sol`**: Combined #316 batched vault `safeTransfer` with #312 per-tranche `creditTranche` ledger updates in `_routeDoubPrizeSplit` / `_routeActiveAndSeedVaults`. - **`invariants-and-business-logic.md`**: Kept #312 autoroll/WarBow ranking rows and merged in #316 pause/revert/routing invariants. - **Follow-ups from merge**: Updated `TimeArenaWarbowBenchmark.t.sol` for removed `AdminSellVault`; aligned `test_finalize_warbow_podium_reverts_*` with superseded `finalizeWarbowPodium`. Sanity: `forge test --match-contract "TimeArena|TimeArenaWarbowBenchmark"` — 126 passed.
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-13 12:58:39 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-13 12:59:57 +00:00 (Migrated from gitlab.com)
Stale Security Review comment

Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issues.

Reviewed by Cursor Bugbot for commit a80b465b34. Configure here.

<details> <summary>Stale Security Review comment</summary> <!-- BUGBOT_REVIEW --> Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.<!-- BUGBOT_AUTOFIX_REVIEW_FOOTNOTE_BEGIN --> <sup>Bugbot Autofix is [ON](https://www.cursor.com/dashboard/bugbot). A cloud agent has been kicked off to fix the reported issues. <!-- BUGBOT_AUTOFIX_AGENT_LINK --></sup> <!-- BUGBOT_AUTOFIX_REVIEW_FOOTNOTE_END --> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit a80b465b34f0ba82622d1853026b6f5dcacf3be3. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> </details>
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-13 12:59:58 +00:00 (Migrated from gitlab.com)

WarBow podium stale after drain

High Severity

WarBow steals and revenges reduce a victim’s live battle points but only refresh the attacker in _updateTopThree. Existing podium slots keep peak stored scores because _updateTopThree never lowers an entrant’s cached value. _rollPodiumEpoch / autoroll pays 4∶2∶1 from that stale top-3, so DOUB can go to the wrong wallets after PvP drains.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit a80b465b34. Configure here.

### WarBow podium stale after drain **High Severity** <!-- DESCRIPTION START --> WarBow steals and revenges reduce a victim’s live battle points but only refresh the attacker in `_updateTopThree`. Existing podium slots keep peak stored scores because `_updateTopThree` never lowers an entrant’s cached value. `_rollPodiumEpoch` / autoroll pays 4∶2∶1 from that stale top-3, so DOUB can go to the wrong wallets after PvP drains. <!-- DESCRIPTION END --> <!-- BUGBOT_BUG_ID: 7f4ac79f-d236-4c7b-aff7-e0707a12e54c --> <!-- LOCATIONS START contracts/src/arena/TimeArena.sol#L432-L438 contracts/src/arena/TimeArena.sol#L915-L922 contracts/src/arena/TimeArena.sol#L377-L393 LOCATIONS END --> <details> <summary>Additional Locations (2)</summary> - [`contracts/src/arena/TimeArena.sol#L915-L922`](https://gitlab.com/PlasticDigits/yieldomega/-//blob/a80b465b34f0ba82622d1853026b6f5dcacf3be3/contracts/src/arena/TimeArena.sol#L915-L922) - [`contracts/src/arena/TimeArena.sol#L377-L393`](https://gitlab.com/PlasticDigits/yieldomega/-//blob/a80b465b34f0ba82622d1853026b6f5dcacf3be3/contracts/src/arena/TimeArena.sol#L377-L393) </details> <div><a href="https://cursor.com/open?link=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9DVVJTT1IiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OmE4Nzk0YzQ2LTVlMGUtNDFiOS04YWI1LTQ4MWI4MDBkZDM4ZCIsImVuY3J5cHRpb25LZXkiOiJTa0huYWZkeDZPSEpsVkZUU25rMlNUQV8tWGpYdEh3TllnT09PakJfR2VJIiwiYnJhbmNoIjoiaXNzdWUtMzEyLWF1dG9yb2xsLXdhcmJvdy1maW5hbGl6ZSIsInJlcG9Pd25lciI6IlBsYXN0aWNEaWdpdHMiLCJyZXBvTmFtZSI6InlpZWxkb21lZ2EifX0" target="_blank" rel="noopener noreferrer"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/fix-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/fix-in-cursor-light.png"><img alt="Fix in Cursor" width="115" height="28" src="https://cursor.com/assets/images/fix-in-cursor-dark.png"></picture></a>&nbsp;<a href="https://cursor.com/agents?link=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9XRUIiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OmE4Nzk0YzQ2LTVlMGUtNDFiOS04YWI1LTQ4MWI4MDBkZDM4ZCIsImVuY3J5cHRpb25LZXkiOiJTa0huYWZkeDZPSEpsVkZUU25rMlNUQV8tWGpYdEh3TllnT09PakJfR2VJIiwiYnJhbmNoIjoiaXNzdWUtMzEyLWF1dG9yb2xsLXdhcmJvdy1maW5hbGl6ZSIsInJlcG9Pd25lciI6IlBsYXN0aWNEaWdpdHMiLCJyZXBvTmFtZSI6InlpZWxkb21lZ2EiLCJwck51bWJlciI6OTMsImNvbW1pdFNoYSI6ImE4MGI0NjViMzRmMGJhODI2MjJkMTg1MzAyNmI2ZjVkY2FjZjNiZTMiLCJwcm92aWRlciI6ImdpdGxhYiIsImhvc3RuYW1lIjoiZ2l0bGFiLmNvbSJ9fQ" target="_blank" rel="noopener noreferrer"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/fix-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/fix-in-web-light.png"><img alt="Fix in Web" width="99" height="28" src="https://cursor.com/assets/images/fix-in-web-dark.png"></picture></a></div> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit a80b465b34f0ba82622d1853026b6f5dcacf3be3. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-13 12:59:58 +00:00 (Migrated from gitlab.com)

Router blocks post-deadline buys

Medium Severity

TimeArena now allows buys after the Last Buy deadline via _requireLiveAndAutoroll, but TimeArenaBuyRouter.buyViaKumbaya still reverts when block.timestamp > ta.deadline(). ETH/USDM/CL8Y single-tx entry stays dead after timer expiry while direct DOUB buy still works.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit a80b465b34. Configure here.

### Router blocks post-deadline buys **Medium Severity** <!-- DESCRIPTION START --> `TimeArena` now allows buys after the Last Buy deadline via `_requireLiveAndAutoroll`, but `TimeArenaBuyRouter.buyViaKumbaya` still reverts when `block.timestamp > ta.deadline()`. ETH/USDM/CL8Y single-tx entry stays dead after timer expiry while direct DOUB `buy` still works. <!-- DESCRIPTION END --> <!-- BUGBOT_BUG_ID: 0f2c43a8-33b2-4b8c-b618-597ffec5f80d --> <!-- LOCATIONS START contracts/src/arena/TimeArena.sol#L860-L870 LOCATIONS END --> <div><a href="https://cursor.com/open?link=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9DVVJTT1IiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OjcwMThjZTA1LWQ1NTMtNGFlNi1hZDg3LWM2ZmE1NGJjMjA1MCIsImVuY3J5cHRpb25LZXkiOiJ3em1qbFRqOG9CM2ZGaFRydXRTR2huZ0RUMUJsOFdoUWRUYWRmdDhwOVJFIiwiYnJhbmNoIjoiaXNzdWUtMzEyLWF1dG9yb2xsLXdhcmJvdy1maW5hbGl6ZSIsInJlcG9Pd25lciI6IlBsYXN0aWNEaWdpdHMiLCJyZXBvTmFtZSI6InlpZWxkb21lZ2EifX0" target="_blank" rel="noopener noreferrer"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/fix-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/fix-in-cursor-light.png"><img alt="Fix in Cursor" width="115" height="28" src="https://cursor.com/assets/images/fix-in-cursor-dark.png"></picture></a>&nbsp;<a href="https://cursor.com/agents?link=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9XRUIiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OjcwMThjZTA1LWQ1NTMtNGFlNi1hZDg3LWM2ZmE1NGJjMjA1MCIsImVuY3J5cHRpb25LZXkiOiJ3em1qbFRqOG9CM2ZGaFRydXRTR2huZ0RUMUJsOFdoUWRUYWRmdDhwOVJFIiwiYnJhbmNoIjoiaXNzdWUtMzEyLWF1dG9yb2xsLXdhcmJvdy1maW5hbGl6ZSIsInJlcG9Pd25lciI6IlBsYXN0aWNEaWdpdHMiLCJyZXBvTmFtZSI6InlpZWxkb21lZ2EiLCJwck51bWJlciI6OTMsImNvbW1pdFNoYSI6ImE4MGI0NjViMzRmMGJhODI2MjJkMTg1MzAyNmI2ZjVkY2FjZjNiZTMiLCJwcm92aWRlciI6ImdpdGxhYiIsImhvc3RuYW1lIjoiZ2l0bGFiLmNvbSJ9fQ" target="_blank" rel="noopener noreferrer"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/fix-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/fix-in-web-light.png"><img alt="Fix in Web" width="99" height="28" src="https://cursor.com/assets/images/fix-in-web-dark.png"></picture></a></div> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit a80b465b34f0ba82622d1853026b6f5dcacf3be3. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-13 13:03:57 +00:00 (Migrated from gitlab.com)

added 1 commit

  • b01baa52 - fix(arena): sync WarBow podium on drain and allow router post-deadline buys

Compare with previous version

added 1 commit <ul><li>b01baa52 - fix(arena): sync WarBow podium on drain and allow router post-deadline buys</li></ul> [Compare with previous version](/PlasticDigits/yieldomega/-/merge_requests/93/diffs?diff_id=1850326511&start_sha=a80b465b34f0ba82622d1853026b6f5dcacf3be3)
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-13 13:04:15 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
PlasticDigits commented 2026-06-13 13:16:58 +00:00 (Migrated from gitlab.com)

Security review — MR !463

Commit reviewed: b01baa52c6e7af7945906746ef5f2804dbd50159
Scope: TimeArena.sol always-live autoroll (_requireLiveAndAutoroll, _autorollExpiredPodiums, _rollPodiumEpoch), on-chain WarBow 4∶2∶1 settlement, _updateTopThree / _podiumMetric displaced-entrant reinsert + BP-drain podium sync, _sortPodium tie-break; PodiumVaults.sol per-category commingled-vault ledger (creditTranche, ledger-aware payPodiumWinners / rollEpochTranches); TimeArenaBuyRouter.sol post-deadline gate removal; Forge tests + docs/skills only (no indexer/frontend/runtime changes in diff).

Outcome: FINDINGS: 0 medium+

Verification on this SHA

Area Check Result
Multi-expired autoroll + commingled vault test_autoroll_multi_expired_pays_each_category_tranche PASS — per-category ledger tranche payout; no full-vault capture
WarBow top-3 correctness (insertion) test_warbow_top_three_reinserts_displaced_entrant, test_warbow_ranking_matches_brute_force PASS
WarBow podium sync after BP drain b01baa52 victim/stealer _updateTopThree + allow score decrease on existing entrant PASS — Forge probe confirms podium value tracks live BP after steal
WarBow autoroll payout test_warbow_roll_auto_pays_onchain_winners, test_autoroll_no_double_payout_same_tx PASS
Ledger / routing integrity creditTranche paired with batched safeTransfer; payPodiumWinners debits ledger before doub.transfer No attacker path to inflate ledger or pay from another category's tranche
Reentrancy Autoroll payout under parent nonReentrant buy/WarBow entrypoints No reentrancy sink identified

Prior threads — disposition on this SHA

Prior finding Status
High — incremental WarBow top-3 stale third place after mid-podium eviction (_updateTopThree) Resolved in bb5497de
High — multi-expired autoroll + shared activePools balance drains full vault / WarBow zero-payout finalize lockout Resolved in 840b5bfc
High (Bugbot) — WarBow podium stale peak scores after steal/revenge drain Resolved in b01baa52 (victim/stealer podium refresh + score decrease)
High (Bugbot) — autoroll order skips WarBow payout Resolved — same root cause as commingled-balance finding

Not reported

  • Governance / owner-trust removal for finalizeWarbowPodium (intentional #312).
  • TimeArenaBuyRouter post-deadline alignment (product consistency; not an authz bypass).
  • rollPodiumEpoch callable while paused (pre-existing; unchanged auth surface).
  • Gas / MEV / ordering within always-live product rules.
  • Docs-only diff hunks.

Security review: no medium+ findings on this diff.

## Security review — MR !463 **Commit reviewed:** `b01baa52c6e7af7945906746ef5f2804dbd50159` **Scope:** `TimeArena.sol` always-live autoroll (`_requireLiveAndAutoroll`, `_autorollExpiredPodiums`, `_rollPodiumEpoch`), on-chain WarBow 4∶2∶1 settlement, `_updateTopThree` / `_podiumMetric` displaced-entrant reinsert + BP-drain podium sync, `_sortPodium` tie-break; `PodiumVaults.sol` per-category commingled-vault ledger (`creditTranche`, ledger-aware `payPodiumWinners` / `rollEpochTranches`); `TimeArenaBuyRouter.sol` post-deadline gate removal; Forge tests + docs/skills only (no indexer/frontend/runtime changes in diff). **Outcome:** `FINDINGS: 0` medium+ ### Verification on this SHA | Area | Check | Result | |------|-------|--------| | Multi-expired autoroll + commingled vault | `test_autoroll_multi_expired_pays_each_category_tranche` | PASS — per-category ledger tranche payout; no full-vault capture | | WarBow top-3 correctness (insertion) | `test_warbow_top_three_reinserts_displaced_entrant`, `test_warbow_ranking_matches_brute_force` | PASS | | WarBow podium sync after BP drain | `b01baa52` victim/stealer `_updateTopThree` + allow score decrease on existing entrant | PASS — Forge probe confirms podium value tracks live BP after steal | | WarBow autoroll payout | `test_warbow_roll_auto_pays_onchain_winners`, `test_autoroll_no_double_payout_same_tx` | PASS | | Ledger / routing integrity | `creditTranche` paired with batched `safeTransfer`; `payPodiumWinners` debits ledger before `doub.transfer` | No attacker path to inflate ledger or pay from another category's tranche | | Reentrancy | Autoroll payout under parent `nonReentrant` buy/WarBow entrypoints | No reentrancy sink identified | ### Prior threads — disposition on this SHA | Prior finding | Status | |---------------|--------| | **High** — incremental WarBow top-3 stale third place after mid-podium eviction (`_updateTopThree`) | **Resolved** in `bb5497de` | | **High** — multi-expired autoroll + shared `activePools` balance drains full vault / WarBow zero-payout finalize lockout | **Resolved** in `840b5bfc` | | **High** (Bugbot) — WarBow podium stale peak scores after steal/revenge drain | **Resolved** in `b01baa52` (victim/stealer podium refresh + score decrease) | | **High** (Bugbot) — autoroll order skips WarBow payout | **Resolved** — same root cause as commingled-balance finding | ### Not reported - Governance / owner-trust removal for `finalizeWarbowPodium` (intentional #312). - `TimeArenaBuyRouter` post-deadline alignment (product consistency; not an authz bypass). - `rollPodiumEpoch` callable while `paused` (pre-existing; unchanged auth surface). - Gas / MEV / ordering within always-live product rules. - Docs-only diff hunks. **Security review: no medium+ findings on this diff.**
PlasticDigits commented 2026-06-13 13:33:07 +00:00 (Migrated from gitlab.com)

mentioned in commit a1e35f6915

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

added 1 commit

  • a1e35f69 - docs(arena): align WarBow autoroll cross-links for issue #312 verify

Compare with previous version

added 1 commit <ul><li>a1e35f69 - docs(arena): align WarBow autoroll cross-links for issue #312 verify</li></ul> [Compare with previous version](/PlasticDigits/yieldomega/-/merge_requests/93/diffs?diff_id=1850334542&start_sha=b01baa52c6e7af7945906746ef5f2804dbd50159)
PlasticDigits commented 2026-06-13 13:33:17 +00:00 (Migrated from gitlab.com)

mentioned in issue #312

mentioned in issue #312
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-13 13:33:28 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
PlasticDigits commented 2026-06-13 13:56:20 +00:00 (Migrated from gitlab.com)

Severity: High

Issue: When an existing podium entrant's score decreases (e.g. WarBow steal/revenge), _updateTopThree only writes the lower value into their current slot and returns — it never promotes a higher-BP player who was previously below the top-3 cutoff.

Impact: Autoroll / rollPodiumEpoch now pays 4∶2∶1 from the on-chain podium snapshot. A sybil holding rank #3 can stay on the podium after being stolen down while a legitimate off-podium player with higher live BP is excluded, receiving ~1/7 of the category active pool.

Attack path (reproduced on a1e35f69):

  1. Podium: Alice / Bob / Charlie (Charlie sybil, 500 BP); Eve has 500 BP but is off-podium (tie-break kept Charlie).
  2. Stealer (250 BP) steals 10% from Charlie → Charlie drops to 450 BP on-chain.
  3. Eve (500 BP) now outranks Charlie, but podium third slot remains Charlie.
  4. Autoroll pays Charlie instead of Eve.

Sink: podiumVaults.payPodiumWinners(category, winners[0], winners[1], winners[2], …) in _rollPodiumEpoch reads the stale winners array.

Note: The prior displacement-on-insert thread is fixed by displaced-entrant reinsert at L933–936; this is a separate in-place decrease path.

**Severity: High** **Issue:** When an existing podium entrant's score *decreases* (e.g. WarBow steal/revenge), `_updateTopThree` only writes the lower value into their current slot and returns — it never promotes a higher-BP player who was previously below the top-3 cutoff. **Impact:** Autoroll / `rollPodiumEpoch` now pays 4∶2∶1 from the on-chain podium snapshot. A sybil holding rank #3 can stay on the podium after being stolen down while a legitimate off-podium player with higher live BP is excluded, receiving ~1/7 of the category active pool. **Attack path (reproduced on `a1e35f69`):** 1. Podium: Alice / Bob / Charlie (Charlie sybil, 500 BP); Eve has 500 BP but is off-podium (tie-break kept Charlie). 2. Stealer (250 BP) steals 10% from Charlie → Charlie drops to 450 BP on-chain. 3. Eve (500 BP) now outranks Charlie, but podium third slot remains Charlie. 4. Autoroll pays Charlie instead of Eve. **Sink:** `podiumVaults.payPodiumWinners(category, winners[0], winners[1], winners[2], …)` in `_rollPodiumEpoch` reads the stale `winners` array. **Note:** The prior displacement-on-insert thread is fixed by displaced-entrant reinsert at L933–936; this is a separate in-place decrease path.
PlasticDigits commented 2026-06-13 13:56:27 +00:00 (Migrated from gitlab.com)

Security review — MR !463

Commit reviewed: a1e35f6915c8f2d1ace655232272ea740f6d9181
Scope: TimeArena.sol always-live autoroll, on-chain WarBow 4∶2∶1 settlement, PodiumVaults commingled ledgers, _updateTopThree ranking/tie-break, TimeArenaBuyRouter phase gate, Forge tests + docs/skills.

Outcome: FINDINGS: 1 medium+

Findings (inline)

Sev Topic Thread
High Incremental top-3 stale slot after in-place BP decrease; autoroll pays wrong WarBow (and other category) winner inline on TimeArena.sol L922

_updateTopThree reinserts displaced entrants on insert (L933–936), but when an existing slot holder's score drops (steal/revenge), it only updates that slot and returns (L921–924). Off-podium players with higher live metrics are never promoted. With on-chain autoroll payout, a sybil can retain a podium slot after being stolen below a legitimate challenger and collect ~1/7 of the active pool. Reproduced on this SHA (Charlie 450 BP remains #3 while Eve 500 BP is off-podium).

Prior threads re-checked

Prior finding Status on a1e35f69
Bugbot — autoroll order drains commingled vault before WarBow Fixed — per-category PodiumVaults ledgers + test_autoroll_multi_expired_pays_each_category_tranche
Security review — stale third after displacement on insert Fixed — displaced-entrant reinsert + test_warbow_top_three_reinserts_displaced_entrant
## Security review — MR !463 **Commit reviewed:** `a1e35f6915c8f2d1ace655232272ea740f6d9181` **Scope:** `TimeArena.sol` always-live autoroll, on-chain WarBow 4∶2∶1 settlement, `PodiumVaults` commingled ledgers, `_updateTopThree` ranking/tie-break, `TimeArenaBuyRouter` phase gate, Forge tests + docs/skills. **Outcome:** `FINDINGS: 1` medium+ ### Findings (inline) | Sev | Topic | Thread | |-----|-------|--------| | **High** | Incremental top-3 stale slot after in-place BP decrease; autoroll pays wrong WarBow (and other category) winner | [inline on `TimeArena.sol` L922](https://gitlab.com/PlasticDigits/yieldomega/-/merge_requests/93#note_3452790583) | `_updateTopThree` reinserts displaced entrants on *insert* (L933–936), but when an existing slot holder's score drops (steal/revenge), it only updates that slot and returns (L921–924). Off-podium players with higher live metrics are never promoted. With on-chain autoroll payout, a sybil can retain a podium slot after being stolen below a legitimate challenger and collect ~1/7 of the active pool. Reproduced on this SHA (Charlie 450 BP remains #3 while Eve 500 BP is off-podium). ### Prior threads re-checked | Prior finding | Status on `a1e35f69` | |---------------|----------------------| | Bugbot — autoroll order drains commingled vault before WarBow | **Fixed** — per-category `PodiumVaults` ledgers + `test_autoroll_multi_expired_pays_each_category_tranche` | | Security review — stale third after *displacement on insert* | **Fixed** — displaced-entrant reinsert + `test_warbow_top_three_reinserts_displaced_entrant` |
PlasticDigits commented 2026-06-13 14:27:00 +00:00 (Migrated from gitlab.com)

added 1 commit

  • 297e79aa - fix(arena): recompute WarBow podium after BP drain promotes challengers

Compare with previous version

added 1 commit <ul><li>297e79aa - fix(arena): recompute WarBow podium after BP drain promotes challengers</li></ul> [Compare with previous version](/PlasticDigits/yieldomega/-/merge_requests/93/diffs?diff_id=1850349889&start_sha=a1e35f6915c8f2d1ace655232272ea740f6d9181)
PlasticDigits commented 2026-06-13 14:27:12 +00:00 (Migrated from gitlab.com)

Security fixes — 297e79aa

Finding Severity Fix
Incremental top-3 stale slot after in-place BP decrease (steal/revenge); autoroll pays wrong WarBow winner High On WarBow BP drain (value < oldVal in _updateTopThree), call _recomputeWarbowPodium() over _warbowBpHolders (populated in _addBattlePoints, cleared on epoch roll). Forge: test_warbow_podium_promotes_challenger_after_bp_decrease.
Autoroll order skips WarBow payout (commingled vault) High Already fixed in 840b5bfc — per-category PodiumVaults ledgers.
Stale third after displacement on insert High Already fixed in bb5497de — displaced-entrant reinsert.
WarBow podium stale peak scores after steal/revenge drain High Already fixed in b01baa52 — victim/stealer podium refresh; this commit closes the remaining off-podium promotion gap.
Router blocks post-deadline buys Medium Already fixed in b01baa52 — TimeArenaBuyRouter deadline gate removed.

Verification: cd contracts && forge test --match-contract TimeArena — 127 tests PASS on this SHA.

## Security fixes — `297e79aa` | Finding | Severity | Fix | |---------|----------|-----| | Incremental top-3 stale slot after in-place BP decrease (steal/revenge); autoroll pays wrong WarBow winner | **High** | On WarBow BP drain (`value < oldVal` in `_updateTopThree`), call `_recomputeWarbowPodium()` over `_warbowBpHolders` (populated in `_addBattlePoints`, cleared on epoch roll). Forge: `test_warbow_podium_promotes_challenger_after_bp_decrease`. | | Autoroll order skips WarBow payout (commingled vault) | **High** | **Already fixed** in `840b5bfc` — per-category `PodiumVaults` ledgers. | | Stale third after displacement on insert | **High** | **Already fixed** in `bb5497de` — displaced-entrant reinsert. | | WarBow podium stale peak scores after steal/revenge drain | **High** | **Already fixed** in `b01baa52` — victim/stealer podium refresh; this commit closes the remaining off-podium promotion gap. | | Router blocks post-deadline buys | **Medium** | **Already fixed** in `b01baa52` — `TimeArenaBuyRouter` deadline gate removed. | **Verification:** `cd contracts && forge test --match-contract TimeArena` — 127 tests PASS on this SHA.
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-13 14:27:19 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
PlasticDigits commented 2026-06-13 14:31:46 +00:00 (Migrated from gitlab.com)

Security review — MR !463

Commit reviewed: 297e79aa12f6a16be7f968db4907638465e6513e
Scope: TimeArena.sol always-live autoroll (_requireLiveAndAutoroll, _autorollExpiredPodiums, on-chain WarBow 4∶2∶1 payout), WarBow incremental ranking (_updateTopThree, _recomputeWarbowPodium, _warbowBpHolders), PodiumVaults.sol per-category commingled ledgers (creditTranche, activePoolBalance), TimeArenaBuyRouter.sol post-deadline phase gate removal, Forge tests + docs/skills.

Outcome: FINDINGS: 0 medium+ — Security review: no medium+ findings on this diff.

Prior threads re-checked (not re-reported)

Prior finding Current status
High — incremental WarBow top-3 stale third-place after mid-podium eviction (_updateTopThree) Fixed in bb5497de / 297e79aa: displaced-entrant re-insert + _recomputeWarbowPodium() on in-place BP drain. Regression tests pass: test_warbow_top_three_reinserts_displaced_entrant, test_warbow_podium_promotes_challenger_after_bp_decrease.
High (Bugbot) — multi-expired autoroll drains commingled vault before WarBow payout Fixed by per-category _activeLedger / creditTranche accounting (840b5bfc). Regression: test_autoroll_multi_expired_pays_each_category_tranche.
High (Bugbot) — WarBow podium stale after steal/revenge BP drain Fixed in 297e79aa: victim/stealer _updateTopThree refresh + full recompute when cached value drops. Covered by test_warbow_podium_promotes_challenger_after_bp_decrease.

Areas reviewed (no medium+ issues)

  • Fund routing / settlement: _rollPodiumEpoch pays from activePoolBalance(category); ledger underflow guard in payPodiumWinners; autoroll cannot double-pay same epoch (test_autoroll_no_double_payout_same_tx).
  • Access control: creditTranche / payPodiumWinners / tranche rolls remain arena-only; finalizeWarbowPodium hard-reverts (superseded by design).
  • Reentrancy: Mutating entrypoints retain nonReentrant; autoroll payout transfers cannot re-enter guarded paths.
  • Authn/authz / offchain: No indexer, frontend, SQL, shell, or SSRF surface in this diff.

Verification run

forge test --match-contract TimeArena — 104 passed; targeted security regressions above — all PASS.

No inline threads opened (zero current medium+ findings). block:security not applied.

## Security review — MR !463 **Commit reviewed:** `297e79aa12f6a16be7f968db4907638465e6513e` **Scope:** `TimeArena.sol` always-live autoroll (`_requireLiveAndAutoroll`, `_autorollExpiredPodiums`, on-chain WarBow 4∶2∶1 payout), WarBow incremental ranking (`_updateTopThree`, `_recomputeWarbowPodium`, `_warbowBpHolders`), `PodiumVaults.sol` per-category commingled ledgers (`creditTranche`, `activePoolBalance`), `TimeArenaBuyRouter.sol` post-deadline phase gate removal, Forge tests + docs/skills. **Outcome:** `FINDINGS: 0` medium+ — **Security review: no medium+ findings on this diff.** ### Prior threads re-checked (not re-reported) | Prior finding | Current status | |---------------|----------------| | **High** — incremental WarBow top-3 stale third-place after mid-podium eviction (`_updateTopThree`) | **Fixed** in `bb5497de` / `297e79aa`: displaced-entrant re-insert + `_recomputeWarbowPodium()` on in-place BP drain. Regression tests pass: `test_warbow_top_three_reinserts_displaced_entrant`, `test_warbow_podium_promotes_challenger_after_bp_decrease`. | | **High** (Bugbot) — multi-expired autoroll drains commingled vault before WarBow payout | **Fixed** by per-category `_activeLedger` / `creditTranche` accounting (`840b5bfc`). Regression: `test_autoroll_multi_expired_pays_each_category_tranche`. | | **High** (Bugbot) — WarBow podium stale after steal/revenge BP drain | **Fixed** in `297e79aa`: victim/stealer `_updateTopThree` refresh + full recompute when cached value drops. Covered by `test_warbow_podium_promotes_challenger_after_bp_decrease`. | ### Areas reviewed (no medium+ issues) - **Fund routing / settlement:** `_rollPodiumEpoch` pays from `activePoolBalance(category)`; ledger underflow guard in `payPodiumWinners`; autoroll cannot double-pay same epoch (`test_autoroll_no_double_payout_same_tx`). - **Access control:** `creditTranche` / `payPodiumWinners` / tranche rolls remain arena-only; `finalizeWarbowPodium` hard-reverts (superseded by design). - **Reentrancy:** Mutating entrypoints retain `nonReentrant`; autoroll payout transfers cannot re-enter guarded paths. - **Authn/authz / offchain:** No indexer, frontend, SQL, shell, or SSRF surface in this diff. ### Verification run `forge test --match-contract TimeArena` — 104 passed; targeted security regressions above — all PASS. No inline threads opened (zero current medium+ findings). `block:security` not applied.
PlasticDigits commented 2026-06-14 02:21:07 +00:00 (Migrated from gitlab.com)

Requires gas optimization. WarBow is expected to have 100s to thousands of participants. Make sure to test gas on large boards & use a more optimized solution.

Requires gas optimization. WarBow is expected to have 100s to thousands of participants. Make sure to test gas on large boards & use a more optimized solution.
PlasticDigits commented 2026-06-14 02:41:22 +00:00 (Migrated from gitlab.com)

added 1 commit

  • f59e284d - fix(arena): O(1) WarBow ranking merge replaces full-holder recompute

Compare with previous version

added 1 commit <ul><li>f59e284d - fix(arena): O(1) WarBow ranking merge replaces full-holder recompute</li></ul> [Compare with previous version](/PlasticDigits/yieldomega/-/merge_requests/93/diffs?diff_id=1850557640&start_sha=297e79aa12f6a16be7f968db4907638465e6513e)
PlasticDigits commented 2026-06-14 02:41:30 +00:00 (Migrated from gitlab.com)

resolved all threads

resolved all threads
PlasticDigits commented 2026-06-14 02:41:36 +00:00 (Migrated from gitlab.com)

Fix bugfix — f59e284d

Thread / item Fix
High — stale third after mid-podium eviction (_updateTopThree) Already fixed in bb5497de; preserved via O(1) off-podium merge in f59e284d. Regression: test_warbow_top_three_reinserts_displaced_entrant PASS
High — multi-expired autoroll drains commingled vault before WarBow Already fixed in 840b5bfc (per-category PodiumVaults ledgers). Regression: test_autoroll_multi_expired_pays_each_category_tranche PASS
High (Bugbot) — WarBow podium stale peak scores after steal/revenge drain Fixed in b01baa52 + off-podium merge in f59e284d
High — in-place BP decrease leaves stale podium slot (Eve vs Charlie) Fixed in f59e284d: track off-podium top-3 + merge ≤6 candidates instead of _recomputeWarbowPodium() O(n) scan. Regression: test_warbow_podium_promotes_challenger_after_bp_decrease PASS
Medium (Bugbot) — router blocks post-deadline buys Already fixed in b01baa52 (TimeArenaBuyRouter deadline gate removed)
Gas — WarBow ranking must stay cheap at 100s–1000s of players f59e284d removes _warbowBpHolders linear recompute; steal at 10k seeded state 245,841 gas (test_benchmark_warbow_steal_10k_player_ranking)

Verification: cd contracts && forge test --match-contract TimeArena — 128 tests PASS (incl. new steal benchmark).

All listed threads resolved.

## Fix bugfix — `f59e284d` | Thread / item | Fix | |---------------|-----| | **High** — stale third after mid-podium eviction (`_updateTopThree`) | Already fixed in `bb5497de`; preserved via O(1) off-podium merge in `f59e284d`. Regression: `test_warbow_top_three_reinserts_displaced_entrant` PASS | | **High** — multi-expired autoroll drains commingled vault before WarBow | Already fixed in `840b5bfc` (per-category `PodiumVaults` ledgers). Regression: `test_autoroll_multi_expired_pays_each_category_tranche` PASS | | **High** (Bugbot) — WarBow podium stale peak scores after steal/revenge drain | Fixed in `b01baa52` + off-podium merge in `f59e284d` | | **High** — in-place BP decrease leaves stale podium slot (Eve vs Charlie) | Fixed in `f59e284d`: track off-podium top-3 + merge ≤6 candidates instead of `_recomputeWarbowPodium()` O(n) scan. Regression: `test_warbow_podium_promotes_challenger_after_bp_decrease` PASS | | **Medium** (Bugbot) — router blocks post-deadline buys | Already fixed in `b01baa52` (`TimeArenaBuyRouter` deadline gate removed) | | **Gas** — WarBow ranking must stay cheap at 100s–1000s of players | `f59e284d` removes `_warbowBpHolders` linear recompute; steal at 10k seeded state **245,841** gas (`test_benchmark_warbow_steal_10k_player_ranking`) | **Verification:** `cd contracts && forge test --match-contract TimeArena` — 128 tests PASS (incl. new steal benchmark). All listed threads resolved.
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-14 02:41:40 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-14 02:43:14 +00:00 (Migrated from gitlab.com)

Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit f59e284db0. Configure here.

<!-- BUGBOT_REVIEW --> Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues. <!-- BUGBOT_FIX_ALL --> <a href="https://cursor.com/open?link=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9BTExfSU5fQ1VSU09SIiwiZGF0YSI6eyJyZWRpc0tleSI6ImJ1Z2JvdC1tdWx0aTo4Zjg1OTgzYy05YjE0LTRkZTYtODI2Ny0xMjcxMDI3YzVkZWQiLCJlbmNyeXB0aW9uS2V5IjoiVDJmTHJYY3lheXoxVmZtdEd2bFZtNHdYVGthUng5aE0xek5LdlZpMHJtZyIsImJyYW5jaCI6Imlzc3VlLTMxMi1hdXRvcm9sbC13YXJib3ctZmluYWxpemUiLCJyZXBvT3duZXIiOiJQbGFzdGljRGlnaXRzIiwicmVwb05hbWUiOiJ5aWVsZG9tZWdhIn19" target="_blank" rel="noopener noreferrer"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/fix-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/fix-in-cursor-light.png"><img alt="Fix All in Cursor" width="115" height="28" src="https://cursor.com/assets/images/fix-in-cursor-dark.png"></picture></a> <!-- /BUGBOT_FIX_ALL --> <!-- BUGBOT_AUTOFIX_REVIEW_FOOTNOTE_BEGIN --> <sup>❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the [Cursor dashboard](https://www.cursor.com/dashboard/bugbot).</sup> <!-- BUGBOT_AUTOFIX_REVIEW_FOOTNOTE_END --> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit f59e284db0c9905096ff1eb5d896369341df179a. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-14 02:43:15 +00:00 (Migrated from gitlab.com)

Off-podium evicts without reinsert

High Severity

In _updateOffWarbowPodium, a new entrant overwrites an off-podium slot without re-evaluating the displaced address, unlike _updateTopThree for other categories. _mergeWarbowGlobalPodium only merges up to six tracked addresses, so a displaced player with live BP can disappear from the snapshot and autoroll may pay the wrong WarBow top-3.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit f59e284db0. Configure here.

### Off-podium evicts without reinsert **High Severity** <!-- DESCRIPTION START --> In `_updateOffWarbowPodium`, a new entrant overwrites an off-podium slot without re-evaluating the displaced address, unlike `_updateTopThree` for other categories. `_mergeWarbowGlobalPodium` only merges up to six tracked addresses, so a displaced player with live BP can disappear from the snapshot and autoroll may pay the wrong WarBow top-3. <!-- DESCRIPTION END --> <!-- BUGBOT_BUG_ID: cefb959a-c6d7-4979-8a86-68fb7871a605 --> <!-- LOCATIONS START contracts/src/arena/TimeArena.sol#L971-L977 contracts/src/arena/TimeArena.sol#L985-L1053 LOCATIONS END --> <details> <summary>Additional Locations (1)</summary> - [`contracts/src/arena/TimeArena.sol#L985-L1053`](https://gitlab.com/PlasticDigits/yieldomega/-//blob/f59e284db0c9905096ff1eb5d896369341df179a/contracts/src/arena/TimeArena.sol#L985-L1053) </details> <div><a href="https://cursor.com/open?link=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9DVVJTT1IiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90Ojg3MDc4ZGViLWVhYzYtNGQyYi1iNDZhLWI1OGI1MzE2MDIyMSIsImVuY3J5cHRpb25LZXkiOiJCVHEtZk1xSnBOVnpPM1Q2TFFRUjZ3QUxGTnZLcXNCZVFoX1EwUVBYekpJIiwiYnJhbmNoIjoiaXNzdWUtMzEyLWF1dG9yb2xsLXdhcmJvdy1maW5hbGl6ZSIsInJlcG9Pd25lciI6IlBsYXN0aWNEaWdpdHMiLCJyZXBvTmFtZSI6InlpZWxkb21lZ2EifX0" target="_blank" rel="noopener noreferrer"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/fix-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/fix-in-cursor-light.png"><img alt="Fix in Cursor" width="115" height="28" src="https://cursor.com/assets/images/fix-in-cursor-dark.png"></picture></a>&nbsp;<a href="https://cursor.com/agents?link=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9XRUIiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90Ojg3MDc4ZGViLWVhYzYtNGQyYi1iNDZhLWI1OGI1MzE2MDIyMSIsImVuY3J5cHRpb25LZXkiOiJCVHEtZk1xSnBOVnpPM1Q2TFFRUjZ3QUxGTnZLcXNCZVFoX1EwUVBYekpJIiwiYnJhbmNoIjoiaXNzdWUtMzEyLWF1dG9yb2xsLXdhcmJvdy1maW5hbGl6ZSIsInJlcG9Pd25lciI6IlBsYXN0aWNEaWdpdHMiLCJyZXBvTmFtZSI6InlpZWxkb21lZ2EiLCJwck51bWJlciI6OTMsImNvbW1pdFNoYSI6ImY1OWUyODRkYjBjOTkwNTA5NmZmMWViNWQ4OTYzNjkzNDFkZjE3OWEiLCJwcm92aWRlciI6ImdpdGxhYiIsImhvc3RuYW1lIjoiZ2l0bGFiLmNvbSJ9fQ" target="_blank" rel="noopener noreferrer"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/fix-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/fix-in-web-light.png"><img alt="Fix in Web" width="99" height="28" src="https://cursor.com/assets/images/fix-in-web-dark.png"></picture></a></div> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit f59e284db0c9905096ff1eb5d896369341df179a. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-14 02:43:15 +00:00 (Migrated from gitlab.com)

Equal BP skips off-podium slot

High Severity

_updateOffWarbowPodium only inserts when value is strictly greater than an off-podium value, so equal BP does not compete using the lower-address tie-break used elsewhere. A tied challenger with better tie-break can fail to enter _warbowOffPodium, never reach the merge set, and lose a podium slot autoroll should award.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit f59e284db0. Configure here.

### Equal BP skips off-podium slot **High Severity** <!-- DESCRIPTION START --> `_updateOffWarbowPodium` only inserts when `value` is strictly greater than an off-podium value, so equal BP does not compete using the lower-address tie-break used elsewhere. A tied challenger with better tie-break can fail to enter `_warbowOffPodium`, never reach the merge set, and lose a podium slot autoroll should award. <!-- DESCRIPTION END --> <!-- BUGBOT_BUG_ID: 6eb2152c-7f8c-44ea-9ee3-f44943682cd7 --> <!-- LOCATIONS START contracts/src/arena/TimeArena.sol#L971-L978 LOCATIONS END --> <div><a href="https://cursor.com/open?link=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9DVVJTT1IiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OmI2YjcwMzBhLTMxZDQtNGFiMS05MDM2LWFiMjUwNjY1NzBiMyIsImVuY3J5cHRpb25LZXkiOiJuc3ZHLWRjb1hmYVpfbkVIQ3pldVkwY2d1YkpRTjBCODZLdWpuQ1cyY0NNIiwiYnJhbmNoIjoiaXNzdWUtMzEyLWF1dG9yb2xsLXdhcmJvdy1maW5hbGl6ZSIsInJlcG9Pd25lciI6IlBsYXN0aWNEaWdpdHMiLCJyZXBvTmFtZSI6InlpZWxkb21lZ2EifX0" target="_blank" rel="noopener noreferrer"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/fix-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/fix-in-cursor-light.png"><img alt="Fix in Cursor" width="115" height="28" src="https://cursor.com/assets/images/fix-in-cursor-dark.png"></picture></a>&nbsp;<a href="https://cursor.com/agents?link=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9XRUIiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OmI2YjcwMzBhLTMxZDQtNGFiMS05MDM2LWFiMjUwNjY1NzBiMyIsImVuY3J5cHRpb25LZXkiOiJuc3ZHLWRjb1hmYVpfbkVIQ3pldVkwY2d1YkpRTjBCODZLdWpuQ1cyY0NNIiwiYnJhbmNoIjoiaXNzdWUtMzEyLWF1dG9yb2xsLXdhcmJvdy1maW5hbGl6ZSIsInJlcG9Pd25lciI6IlBsYXN0aWNEaWdpdHMiLCJyZXBvTmFtZSI6InlpZWxkb21lZ2EiLCJwck51bWJlciI6OTMsImNvbW1pdFNoYSI6ImY1OWUyODRkYjBjOTkwNTA5NmZmMWViNWQ4OTYzNjkzNDFkZjE3OWEiLCJwcm92aWRlciI6ImdpdGxhYiIsImhvc3RuYW1lIjoiZ2l0bGFiLmNvbSJ9fQ" target="_blank" rel="noopener noreferrer"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/fix-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/fix-in-web-light.png"><img alt="Fix in Web" width="99" height="28" src="https://cursor.com/assets/images/fix-in-web-dark.png"></picture></a></div> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit f59e284db0c9905096ff1eb5d896369341df179a. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
PlasticDigits commented 2026-06-14 02:47:48 +00:00 (Migrated from gitlab.com)

Severity: High

Issue: _updateOffWarbowPodium only inserts when value > o.values[r] (strict). When the off-podium top-3 is full and a challenger ties an existing off-podium BP, the challenger is never added to the ≤6-address merge set. _mergeWarbowGlobalPodium cannot promote them, even when the tie-break rule (lower address wins — same as _sortPodium) would rank them above an incumbent global third-place holder.

Impact: Autoroll / rollPodiumEpoch(CAT_WARBOW) pays 4∶2∶1 from a stale _podiums[CAT_WARBOW] snapshot. A sybil can occupy global #3 plus three equal-BP off-podium slots; a legitimate challenger with the same BP and a better tie-break is dropped from tracking and loses ~1/7 of the WarBow active pool.

Attack path (reproduced on f59e284d):

  1. Alice/Bob stack high BP; Carol (0x300), D/E/F each make one level-4 buy (shared 500 BP).
  2. Podium: Alice / Bob / Carol; off-podium holds D/E/F at 500 BP.
  3. Greg (0x100) buys once → 500 BP, better tie-break than Carol, but 50 > 50 fails for every off slot → Greg is untracked.
  4. On-chain third remains Carol; true third should be Greg.

Sink: _rollPodiumEpoch → podiumVaults.payPodiumWinners(category, winners[0], winners[1], winners[2], …) reads the flawed winners snapshot.

Fix hint: Mirror _sortPodium tie-break on insert (value > o.values[r] || (value == o.values[r] && uint160(entrant) < uint160(o.winners[r]))), and/or reinsert displaced off-podium entrants the way _updateTopThree does for other categories.

**Severity: High** **Issue:** `_updateOffWarbowPodium` only inserts when `value > o.values[r]` (strict). When the off-podium top-3 is full and a challenger ties an existing off-podium BP, the challenger is never added to the ≤6-address merge set. `_mergeWarbowGlobalPodium` cannot promote them, even when the tie-break rule (lower address wins — same as `_sortPodium`) would rank them above an incumbent global third-place holder. **Impact:** Autoroll / `rollPodiumEpoch(CAT_WARBOW)` pays 4∶2∶1 from a stale `_podiums[CAT_WARBOW]` snapshot. A sybil can occupy global #3 plus three equal-BP off-podium slots; a legitimate challenger with the same BP and a better tie-break is dropped from tracking and loses ~1/7 of the WarBow active pool. **Attack path (reproduced on `f59e284d`):** 1. Alice/Bob stack high BP; Carol (`0x300`), D/E/F each make one level-4 buy (shared 500 BP). 2. Podium: Alice / Bob / Carol; off-podium holds D/E/F at 500 BP. 3. Greg (`0x100`) buys once → 500 BP, better tie-break than Carol, but `50 > 50` fails for every off slot → Greg is untracked. 4. On-chain third remains Carol; true third should be Greg. **Sink:** `_rollPodiumEpoch` → `podiumVaults.payPodiumWinners(category, winners[0], winners[1], winners[2], …)` reads the flawed `winners` snapshot. **Fix hint:** Mirror `_sortPodium` tie-break on insert (`value > o.values[r] || (value == o.values[r] && uint160(entrant) < uint160(o.winners[r]))`), and/or reinsert displaced off-podium entrants the way `_updateTopThree` does for other categories.
PlasticDigits commented 2026-06-14 02:47:56 +00:00 (Migrated from gitlab.com)

Security review — MR !463

Commit reviewed: f59e284db0c9905096ff1eb5d896369341df179a
Scope: TimeArena.sol always-live autoroll (_requireLiveAndAutoroll, _autorollExpiredPodiums, _rollPodiumEpoch), O(1) WarBow ranking (_updateWarbowRanking, _warbowOffPodium, _mergeWarbowGlobalPodium), on-chain WarBow 4∶2∶1 settlement; PodiumVaults.sol per-category commingled-vault ledgers (creditTranche, activePoolBalance); TimeArenaBuyRouter.sol post-deadline buy path; Forge tests + docs/skills.

Outcome: FINDINGS: 1 medium+

Findings (inline)

Sev Topic Thread
High Equal-BP off-podium insert skips tie-break challenger → wrong WarBow autoroll payout inline on TimeArena.sol L973

_updateOffWarbowPodium uses strict value > o.values[r]. When off-podium is full at the same BP, a challenger with a better tie-break (lower address, per _sortPodium) never enters the ≤6-address merge set; global #3 can stay a worse-address sybil. Reproduced locally on this SHA (Carol 0x300 keeps third at 500 BP while Greg 0x100 at 500 BP is untracked).

Prior threads — disposition on this SHA

Prior finding Status
High — stale WarBow third after mid-podium eviction (_updateTopThree / displacement) Resolved in bb5497de + _updateWarbowRanking merge (f59e284d); test_warbow_top_three_reinserts_displaced_entrant PASS
High — multi-expired autoroll drains commingled vault before WarBow Resolved in 840b5bfc (per-category ledgers); test_autoroll_multi_expired_pays_each_category_tranche PASS
High — BP drain leaves stale podium slot (steal/revenge) Resolved in f59e284d off-podium merge; test_warbow_podium_promotes_challenger_after_bp_decrease PASS
High (Bugbot) — off-podium displacement without displaced reinsert Not elevated — displacement evicts rank-4..6 tracked slots; could not construct top-3 payout mismatch beyond the equal-BP insert gap above
High (Bugbot, prior 2fe5181) — autoroll order / shared balanceOf Resolved by ledger accounting (840b5bfc)
## Security review — MR !463 **Commit reviewed:** `f59e284db0c9905096ff1eb5d896369341df179a` **Scope:** `TimeArena.sol` always-live autoroll (`_requireLiveAndAutoroll`, `_autorollExpiredPodiums`, `_rollPodiumEpoch`), O(1) WarBow ranking (`_updateWarbowRanking`, `_warbowOffPodium`, `_mergeWarbowGlobalPodium`), on-chain WarBow 4∶2∶1 settlement; `PodiumVaults.sol` per-category commingled-vault ledgers (`creditTranche`, `activePoolBalance`); `TimeArenaBuyRouter.sol` post-deadline buy path; Forge tests + docs/skills. **Outcome:** `FINDINGS: 1` medium+ ### Findings (inline) | Sev | Topic | Thread | |-----|-------|--------| | **High** | Equal-BP off-podium insert skips tie-break challenger → wrong WarBow autoroll payout | [inline on `TimeArena.sol` L973](https://gitlab.com/PlasticDigits/yieldomega/-/merge_requests/93#note_3453361008) | `_updateOffWarbowPodium` uses strict `value > o.values[r]`. When off-podium is full at the same BP, a challenger with a better tie-break (lower address, per `_sortPodium`) never enters the ≤6-address merge set; global #3 can stay a worse-address sybil. Reproduced locally on this SHA (Carol `0x300` keeps third at 500 BP while Greg `0x100` at 500 BP is untracked). ### Prior threads — disposition on this SHA | Prior finding | Status | |---------------|--------| | **High** — stale WarBow third after mid-podium eviction (`_updateTopThree` / displacement) | **Resolved** in `bb5497de` + `_updateWarbowRanking` merge (`f59e284d`); `test_warbow_top_three_reinserts_displaced_entrant` PASS | | **High** — multi-expired autoroll drains commingled vault before WarBow | **Resolved** in `840b5bfc` (per-category ledgers); `test_autoroll_multi_expired_pays_each_category_tranche` PASS | | **High** — BP drain leaves stale podium slot (steal/revenge) | **Resolved** in `f59e284d` off-podium merge; `test_warbow_podium_promotes_challenger_after_bp_decrease` PASS | | **High** (Bugbot) — off-podium displacement without displaced reinsert | **Not elevated** — displacement evicts rank-4..6 tracked slots; could not construct top-3 payout mismatch beyond the equal-BP insert gap above | | **High** (Bugbot, prior `2fe5181`) — autoroll order / shared `balanceOf` | **Resolved** by ledger accounting (`840b5bfc`) |
PlasticDigits commented 2026-06-14 02:48:56 +00:00 (Migrated from gitlab.com)

Acceptable tradeoff for gas efficiency.

Acceptable tradeoff for gas efficiency.
PlasticDigits commented 2026-06-14 02:49:14 +00:00 (Migrated from gitlab.com)

Acceptable tradeoff for gas efficiency

Acceptable tradeoff for gas efficiency
PlasticDigits commented 2026-06-14 02:49:58 +00:00 (Migrated from gitlab.com)

Must document 6 tracking tradeoff, gas efficiency for slightly less accurate podium standings. Verify that if a user is NOT on the podium and has higger BP than podium, it will at least put them in podium when they buy.

Must document 6 tracking tradeoff, gas efficiency for slightly less accurate podium standings. Verify that if a user is NOT on the podium and has higger BP than podium, it will at least put them in podium when they buy.
PlasticDigits commented 2026-06-14 03:07:22 +00:00 (Migrated from gitlab.com)

added 1 commit

  • 0e789579 - fix(arena): WarBow off-podium equal-BP tie-break on insert

Compare with previous version

added 1 commit <ul><li>0e789579 - fix(arena): WarBow off-podium equal-BP tie-break on insert</li></ul> [Compare with previous version](/PlasticDigits/yieldomega/-/merge_requests/93/diffs?diff_id=1850563113&start_sha=f59e284db0c9905096ff1eb5d896369341df179a)
PlasticDigits commented 2026-06-14 03:07:26 +00:00 (Migrated from gitlab.com)

resolved all threads

resolved all threads
PlasticDigits commented 2026-06-14 03:07:38 +00:00 (Migrated from gitlab.com)

Fix bugfix — 0e789579

Thread / item Fix
High — _updateOffWarbowPodium strict value > skips equal-BP tie-break challenger (Greg vs Carol) Fixed. Insert now mirrors _sortPodium: value > slot || (value == slot && lower address). Regression: test_warbow_off_podium_tie_break_promotes_to_global PASS
Review — document ≤6-address tracking tradeoff; verify higher-BP buy enters podium Done. Benchmark doc § tradeoff + INV-TIME-ARENA-WARBOW-RANK-312 updated; arena-v2.md cross-link. Regression: test_warbow_higher_bp_buy_enters_podium PASS
High (Bugbot) — off-podium displacement without reinsert No change — accepted gas tradeoff per review; documented in benchmark § tradeoff
Prior highs (commingled vault, stale third, BP drain, router deadline) Already fixed on branch; unchanged in this commit

Verification: cd contracts && forge test --match-contract TimeArena — 130 tests PASS.

## Fix bugfix — `0e789579` | Thread / item | Fix | |---------------|-----| | **High** — `_updateOffWarbowPodium` strict `value >` skips equal-BP tie-break challenger (Greg vs Carol) | **Fixed.** Insert now mirrors `_sortPodium`: `value > slot \|\| (value == slot && lower address)`. Regression: `test_warbow_off_podium_tie_break_promotes_to_global` PASS | | **Review** — document ≤6-address tracking tradeoff; verify higher-BP buy enters podium | **Done.** Benchmark doc § tradeoff + `INV-TIME-ARENA-WARBOW-RANK-312` updated; `arena-v2.md` cross-link. Regression: `test_warbow_higher_bp_buy_enters_podium` PASS | | **High** (Bugbot) — off-podium displacement without reinsert | **No change** — accepted gas tradeoff per review; documented in benchmark § tradeoff | | Prior highs (commingled vault, stale third, BP drain, router deadline) | **Already fixed** on branch; unchanged in this commit | **Verification:** `cd contracts && forge test --match-contract TimeArena` — 130 tests PASS.
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-14 03:07:44 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
PlasticDigits commented 2026-06-14 03:12:41 +00:00 (Migrated from gitlab.com)

Security review — MR !463

Commit reviewed: 0e7895790ca39b32cb844ad0f1a52d71ab476c22
Scope: TimeArena.sol always-live autoroll (_requireLiveAndAutoroll, _autorollExpiredPodiums, _rollPodiumEpoch), on-chain WarBow 4∶2∶1 settlement (_updateWarbowRanking, _warbowOffPodium, _mergeWarbowGlobalPodium, finalizeWarbowPodium superseded); PodiumVaults.sol per-category commingled-vault ledgers (creditTranche, ledger-aware payPodiumWinners / activePoolBalance); TimeArenaBuyRouter.sol post-deadline buy path; Forge tests + docs/skills.

Outcome: FINDINGS: 0 medium+

Security review: no medium+ findings on this diff at 0e789579.

Inline threads

None on this pass (no new medium+ issues).

Prior threads — disposition on 0e789579

Prior finding Status
High — stale WarBow third after mid-podium eviction (_updateTopThree) Resolved (bb5497de + _updateWarbowRanking merge); test_warbow_top_three_reinserts_displaced_entrant PASS
High — multi-expired autoroll drains commingled vault before WarBow Resolved (840b5bfc per-category ledgers); test_autoroll_multi_expired_pays_each_category_tranche PASS
High — BP drain leaves stale podium slot (steal/revenge) Resolved (f59e284d off-podium merge); test_warbow_podium_promotes_challenger_after_bp_decrease PASS
High — equal-BP off-podium insert skips tie-break challenger Resolved (0e789579); test_warbow_off_podium_tie_break_promotes_to_global PASS
High (Bugbot) — off-podium displacement without reinsert Not elevated — documented ≤6-address gas/accuracy tradeoff (benchmark § tradeoff); author accepted; no new payout-mismatch path beyond documented buffer limits

Verification (this pass)

  • cd contracts && forge test --match-contract TimeArena — 130 PASS
  • Security regressions: test_autoroll_multi_expired_pays_each_category_tranche, test_warbow_top_three_reinserts_displaced_entrant, test_warbow_podium_promotes_challenger_after_bp_decrease, test_warbow_off_podium_tie_break_promotes_to_global, test_warbow_higher_bp_buy_enters_podium, test_autoroll_no_double_payout_same_tx — PASS

Notes (informational, below threshold)

  • rollPodiumEpoch remains callable while paused (pre-existing; autoroll on buys/WarBow is correctly gated via _requireLive).
  • Commingled creditTranche accounting assumes default address(this) pool wiring; external pool addresses would revert on buy routing (owner config).
## Security review — MR !463 **Commit reviewed:** `0e7895790ca39b32cb844ad0f1a52d71ab476c22` **Scope:** `TimeArena.sol` always-live autoroll (`_requireLiveAndAutoroll`, `_autorollExpiredPodiums`, `_rollPodiumEpoch`), on-chain WarBow 4∶2∶1 settlement (`_updateWarbowRanking`, `_warbowOffPodium`, `_mergeWarbowGlobalPodium`, `finalizeWarbowPodium` superseded); `PodiumVaults.sol` per-category commingled-vault ledgers (`creditTranche`, ledger-aware `payPodiumWinners` / `activePoolBalance`); `TimeArenaBuyRouter.sol` post-deadline buy path; Forge tests + docs/skills. **Outcome:** `FINDINGS: 0` medium+ Security review: **no medium+ findings** on this diff at `0e789579`. ### Inline threads None on this pass (no new medium+ issues). ### Prior threads — disposition on `0e789579` | Prior finding | Status | |---------------|--------| | **High** — stale WarBow third after mid-podium eviction (`_updateTopThree`) | **Resolved** (`bb5497de` + `_updateWarbowRanking` merge); `test_warbow_top_three_reinserts_displaced_entrant` PASS | | **High** — multi-expired autoroll drains commingled vault before WarBow | **Resolved** (`840b5bfc` per-category ledgers); `test_autoroll_multi_expired_pays_each_category_tranche` PASS | | **High** — BP drain leaves stale podium slot (steal/revenge) | **Resolved** (`f59e284d` off-podium merge); `test_warbow_podium_promotes_challenger_after_bp_decrease` PASS | | **High** — equal-BP off-podium insert skips tie-break challenger | **Resolved** (`0e789579`); `test_warbow_off_podium_tie_break_promotes_to_global` PASS | | **High** (Bugbot) — off-podium displacement without reinsert | **Not elevated** — documented ≤6-address gas/accuracy tradeoff ([benchmark § tradeoff](docs/testing/warbow-ranking-benchmark-312.md)); author accepted; no new payout-mismatch path beyond documented buffer limits | ### Verification (this pass) - `cd contracts && forge test --match-contract TimeArena` — **130 PASS** - Security regressions: `test_autoroll_multi_expired_pays_each_category_tranche`, `test_warbow_top_three_reinserts_displaced_entrant`, `test_warbow_podium_promotes_challenger_after_bp_decrease`, `test_warbow_off_podium_tie_break_promotes_to_global`, `test_warbow_higher_bp_buy_enters_podium`, `test_autoroll_no_double_payout_same_tx` — **PASS** ### Notes (informational, below threshold) - `rollPodiumEpoch` remains callable while `paused` (pre-existing; autoroll on buys/WarBow is correctly gated via `_requireLive`). - Commingled `creditTranche` accounting assumes default `address(this)` pool wiring; external pool addresses would revert on buy routing (owner config).
PlasticDigits commented 2026-06-14 05:02:49 +00:00 (Migrated from gitlab.com)

added 40 commits

  • 0e789579...03a43d4a - 39 commits from branch main
  • 082d27f3 - Merge branch 'main' into issue-312-autoroll-warbow-finalize

Compare with previous version

added 40 commits <ul><li>0e789579...03a43d4a - 39 commits from branch <code>main</code></li><li>082d27f3 - Merge branch &#39;main&#39; into issue-312-autoroll-warbow-finalize</li></ul> [Compare with previous version](/PlasticDigits/yieldomega/-/merge_requests/93/diffs?diff_id=1850587838&start_sha=0e7895790ca39b32cb844ad0f1a52d71ab476c22)
PlasticDigits commented 2026-06-14 05:02:52 +00:00 (Migrated from gitlab.com)

Resolved merge conflicts with main (merge commit 082d27f3).

Conflicts resolved in:

  • contracts/PARAMETERS.md — combined #310 WarBow DOUB routing / streak-ambush BP with #312 autoroll on-chain top-3 payout docs
  • docs/testing/invariants-and-business-logic.md — kept #312 autoroll/ranking invariants alongside #310 DOUB routing and BP streak-ambush rows
  • skills/README.md — effectiveCharmPriceWad() from main + #312 WarBow autoroll skill blurb
  • skills/play-active-time-arena/SKILL.md — #312 always-live autoroll step + / play surface from #320

Sanity: forge test --match-contract TimeArena PASS after merge.

Resolved merge conflicts with `main` (merge commit `082d27f3`). **Conflicts resolved in:** - `contracts/PARAMETERS.md` — combined #310 WarBow DOUB routing / streak-ambush BP with #312 autoroll on-chain top-3 payout docs - `docs/testing/invariants-and-business-logic.md` — kept #312 autoroll/ranking invariants alongside #310 DOUB routing and BP streak-ambush rows - `skills/README.md` — `effectiveCharmPriceWad()` from main + #312 WarBow autoroll skill blurb - `skills/play-active-time-arena/SKILL.md` — #312 always-live autoroll step + `/` play surface from #320 **Sanity:** `forge test --match-contract TimeArena` PASS after merge.
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-14 05:03:21 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
PlasticDigits commented 2026-06-14 05:08:56 +00:00 (Migrated from gitlab.com)

Security review — MR !463

Commit reviewed: 082d27f3a08929eca7e48c992cafd35dcf5827e9
Scope: Merge commit re-validates #312 (TimeArena.sol always-live autoroll, on-chain WarBow 4∶2∶1 settlement, _updateWarbowRanking / _warbowOffPodium merge, finalizeWarbowPodium superseded; PodiumVaults.sol per-category commingled ledgers + creditTranche) plus main merge-ins (TimeArenaBuyRouter.sol post-deadline buys, #310 WarBow DOUB routing / streak-break BP). Forge security regressions + TimeArena suite.

Outcome: FINDINGS: 0 medium+

Security review: no medium+ findings on this diff at 082d27f3.

Inline threads

None on this pass (no new medium+ issues).

Prior threads — disposition on 082d27f3

Prior finding Status
High — stale WarBow third after mid-podium eviction Resolved (bb5497de displaced reinsert + _updateWarbowRanking); test_warbow_top_three_reinserts_displaced_entrant PASS
High — multi-expired autoroll drains commingled vault before WarBow Resolved (840b5bfc per-category ledgers); test_autoroll_multi_expired_pays_each_category_tranche PASS
High — BP drain leaves stale podium slot (steal/revenge) Resolved (f59e284d off-podium merge); test_warbow_podium_promotes_challenger_after_bp_decrease PASS
High — equal-BP off-podium insert skips tie-break challenger Resolved (0e789579); test_warbow_off_podium_tie_break_promotes_to_global PASS
High (Bugbot) — autoroll order / shared balanceOf Resolved by ledger accounting
High (Bugbot) — off-podium displacement without reinsert Not elevated — documented ≤6-address gas/accuracy tradeoff; no top-3 payout mismatch reproduced beyond buffer limits

Verification (this pass)

  • forge test --match-contract TimeArena — PASS
  • Security regressions: test_autoroll_multi_expired_pays_each_category_tranche, test_warbow_top_three_reinserts_displaced_entrant, test_warbow_podium_promotes_challenger_after_bp_decrease, test_warbow_off_podium_tie_break_promotes_to_global, test_warbow_higher_bp_buy_enters_podium, test_autoroll_no_double_payout_same_tx, test_warbow_ranking_matches_brute_force — PASS

Notes (informational, below threshold)

  • TimeArenaBuyRouter correctly drops the Last Buy deadline gate; buyFor → _requireLiveAndAutoroll() rolls before settlement.
  • #310 _routeWarbowDoubSpend uses the same _routeDoubPrizeSplit + creditTranche path as buys; no stranded-DOUB or cross-category ledger skew observed in tests.
  • rollPodiumEpoch remains callable while paused (pre-existing); user buys/WarBow paths stay gated via _requireLive.
  • Commingled ledger accounting assumes default address(this) pool wiring.
## Security review — MR !463 **Commit reviewed:** `082d27f3a08929eca7e48c992cafd35dcf5827e9` **Scope:** Merge commit re-validates #312 (`TimeArena.sol` always-live autoroll, on-chain WarBow 4∶2∶1 settlement, `_updateWarbowRanking` / `_warbowOffPodium` merge, `finalizeWarbowPodium` superseded; `PodiumVaults.sol` per-category commingled ledgers + `creditTranche`) plus `main` merge-ins (`TimeArenaBuyRouter.sol` post-deadline buys, #310 WarBow DOUB routing / streak-break BP). Forge security regressions + `TimeArena` suite. **Outcome:** `FINDINGS: 0` medium+ Security review: **no medium+ findings** on this diff at `082d27f3`. ### Inline threads None on this pass (no new medium+ issues). ### Prior threads — disposition on `082d27f3` | Prior finding | Status | |---------------|--------| | **High** — stale WarBow third after mid-podium eviction | **Resolved** (`bb5497de` displaced reinsert + `_updateWarbowRanking`); `test_warbow_top_three_reinserts_displaced_entrant` PASS | | **High** — multi-expired autoroll drains commingled vault before WarBow | **Resolved** (`840b5bfc` per-category ledgers); `test_autoroll_multi_expired_pays_each_category_tranche` PASS | | **High** — BP drain leaves stale podium slot (steal/revenge) | **Resolved** (`f59e284d` off-podium merge); `test_warbow_podium_promotes_challenger_after_bp_decrease` PASS | | **High** — equal-BP off-podium insert skips tie-break challenger | **Resolved** (`0e789579`); `test_warbow_off_podium_tie_break_promotes_to_global` PASS | | **High** (Bugbot) — autoroll order / shared `balanceOf` | **Resolved** by ledger accounting | | **High** (Bugbot) — off-podium displacement without reinsert | **Not elevated** — documented ≤6-address gas/accuracy tradeoff; no top-3 payout mismatch reproduced beyond buffer limits | ### Verification (this pass) - `forge test --match-contract TimeArena` — **PASS** - Security regressions: `test_autoroll_multi_expired_pays_each_category_tranche`, `test_warbow_top_three_reinserts_displaced_entrant`, `test_warbow_podium_promotes_challenger_after_bp_decrease`, `test_warbow_off_podium_tie_break_promotes_to_global`, `test_warbow_higher_bp_buy_enters_podium`, `test_autoroll_no_double_payout_same_tx`, `test_warbow_ranking_matches_brute_force` — **PASS** ### Notes (informational, below threshold) - `TimeArenaBuyRouter` correctly drops the Last Buy deadline gate; `buyFor` → `_requireLiveAndAutoroll()` rolls before settlement. - #310 `_routeWarbowDoubSpend` uses the same `_routeDoubPrizeSplit` + `creditTranche` path as buys; no stranded-DOUB or cross-category ledger skew observed in tests. - `rollPodiumEpoch` remains callable while `paused` (pre-existing); user buys/WarBow paths stay gated via `_requireLive`. - Commingled ledger accounting assumes default `address(this)` pool wiring.
PlasticDigits commented 2026-06-14 05:08:59 +00:00 (Migrated from gitlab.com)

mentioned in commit e84483343f

mentioned in commit e84483343f723b70071161455ef0d23813b62ef9
PlasticDigits (Migrated from gitlab.com) merged commit e84483343f into main 2026-06-14 05:08:59 +00:00
PlasticDigits commented 2026-06-14 05:34:02 +00:00 (Migrated from gitlab.com)

mentioned in merge request !484

mentioned in merge request !484
Sign in to join this conversation.
No reviewers
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!463
No description provided.