Add sparse and empty podium roll contract tests (#355) #528

Merged
PlasticDigits merged 1 commit from issue-355-sparse-empty-podium-roll-tests into main 2026-06-28 04:49:03 +00:00
PlasticDigits commented 2026-06-28 02:44:47 +00:00 (Migrated from gitlab.com)

Summary

GitLab #355 — sparse and empty podium roll contract tests (parent #342 P2 #15 / M-C2).

Adds two Forge tests in TimeArena.t.sol matching existing roll test style:

  • test_roll_empty_pool_tranche_promotion — roll when activePoolBalance == 0 skips payout, still promotes seed/future tranches, disarms timer, and cannot extract DOUB from an empty active ledger.
  • test_roll_partial_winners — single Time Booster entrant: zero-address 2nd/3rd slots receive no transfer; sole winner gets 4/7; unclaimed shares remain on vault.

Documents invariants INV-TIME-ARENA-PODIUM-ROLL-EMPTY / INV-TIME-ARENA-PODIUM-ROLL-SPARSE (invariants §355) and cross-links skills/play-time-arena-doub.

Acceptance checklist

Criterion Command / step Result
Two new tests PASS cd contracts && forge test --match-test test_roll_empty PASS
Expected behavior documented in test names/comments Review TimeArena.t.sol tests + invariants §355 PASS
No regression in existing roll tests cd contracts && forge test --match-test test_roll_podium PASS
Full contract suite (excl. gitignored fork CSV) cd contracts && forge test PASS (229 pass; 4 DoubAirdropMegaethFork SKIP — missing airdrop/doub.csv)
Invariants doc updated docs/testing/invariants-and-business-logic.md §355 PASS

Verification checklist (third parties)

  1. cd contracts && forge test --match-test "test_roll_empty|test_roll_partial" -vv
  2. cd contracts && forge test --match-test test_roll_podium
  3. Grep invariants: rg "PODIUM-ROLL-EMPTY|PODIUM-ROLL-SPARSE" docs/testing/invariants-and-business-logic.md
  4. Optional full gate: cd contracts && forge test (expect 4 fork tests FAIL without airdrop/doub.csv — pre-existing)

Relates to #355 (issue stays open until merge).

## Summary GitLab [#355](https://gitlab.com/PlasticDigits/yieldomega/-/issues/355) — sparse and empty podium roll contract tests (parent [#342](https://gitlab.com/PlasticDigits/yieldomega/-/issues/342) P2 #15 / **M-C2**). Adds two Forge tests in `TimeArena.t.sol` matching existing roll test style: - **`test_roll_empty_pool_tranche_promotion`** — roll when `activePoolBalance == 0` skips payout, still promotes seed/future tranches, disarms timer, and cannot extract DOUB from an empty active ledger. - **`test_roll_partial_winners`** — single Time Booster entrant: zero-address 2nd/3rd slots receive no transfer; sole winner gets 4/7; unclaimed shares remain on vault. Documents invariants **`INV-TIME-ARENA-PODIUM-ROLL-EMPTY`** / **`INV-TIME-ARENA-PODIUM-ROLL-SPARSE`** ([invariants §355](docs/testing/invariants-and-business-logic.md#timearena-podium-roll-sparse-gitlab-355)) and cross-links [`skills/play-time-arena-doub`](skills/play-time-arena-doub/SKILL.md). ## Acceptance checklist | Criterion | Command / step | Result | |-----------|----------------|--------| | Two new tests PASS | `cd contracts && forge test --match-test test_roll_empty` | PASS | | Expected behavior documented in test names/comments | Review `TimeArena.t.sol` tests + invariants §355 | PASS | | No regression in existing roll tests | `cd contracts && forge test --match-test test_roll_podium` | PASS | | Full contract suite (excl. gitignored fork CSV) | `cd contracts && forge test` | PASS (229 pass; 4 `DoubAirdropMegaethFork` SKIP — missing `airdrop/doub.csv`) | | Invariants doc updated | `docs/testing/invariants-and-business-logic.md` §355 | PASS | ## Verification checklist (third parties) 1. `cd contracts && forge test --match-test "test_roll_empty|test_roll_partial" -vv` 2. `cd contracts && forge test --match-test test_roll_podium` 3. Grep invariants: `rg "PODIUM-ROLL-EMPTY|PODIUM-ROLL-SPARSE" docs/testing/invariants-and-business-logic.md` 4. Optional full gate: `cd contracts && forge test` (expect 4 fork tests FAIL without `airdrop/doub.csv` — pre-existing) ## Related issue Relates to #355 (issue stays open until merge).
PlasticDigits commented 2026-06-28 02:47:05 +00:00 (Migrated from gitlab.com)

Security review — MR !528

Commit reviewed: a824654811746579d1a7563deff71727df11a32c
Base: c91c2cfa59c2eec9931a54e33691ffc5356dddfa

Scope

  • contracts/test/TimeArena.t.sol — two new Forge tests (test_roll_empty_pool_tranche_promotion, test_roll_partial_winners), helper _ensureLevelCred, import of ArenaPodiumSettlement
  • docs/testing/invariants-and-business-logic.md — invariant rows §355
  • skills/play-time-arena-doub/SKILL.md — cross-links

No production contract, indexer, frontend, or dependency changes in this diff.

Method

Traced attacker-controlled inputs on the exercised onchain paths (rollPodiumEpoch → _rollPodiumEpoch, PodiumVaults.payPodiumWinners, PodiumVaults.rollEpochTranches, ArenaPodiumSettlement.payoutShares) at MR head SHA. Confirmed existing controls: nonReentrant on roll entrypoint, podiumTimerArmed + deadline gates, msg.sender == arena on vault mutators, zero-address skip on winner transfers, ledger underflow guard on commingled pools.

Test-only vm.prank(address(arena)) + creditTranche is Foundry setup mirroring arena-only auth — not reachable offchain.

Outcome

FINDINGS: 0 medium+

Security review: no medium+ findings on this diff.

No inline threads (nothing to block on).


Automated security review (Cursor Cloud agent).

## Security review — MR !528 **Commit reviewed:** `a824654811746579d1a7563deff71727df11a32c` **Base:** `c91c2cfa59c2eec9931a54e33691ffc5356dddfa` ### Scope - `contracts/test/TimeArena.t.sol` — two new Forge tests (`test_roll_empty_pool_tranche_promotion`, `test_roll_partial_winners`), helper `_ensureLevelCred`, import of `ArenaPodiumSettlement` - `docs/testing/invariants-and-business-logic.md` — invariant rows §355 - `skills/play-time-arena-doub/SKILL.md` — cross-links No production contract, indexer, frontend, or dependency changes in this diff. ### Method Traced attacker-controlled inputs on the exercised onchain paths (`rollPodiumEpoch` → `_rollPodiumEpoch`, `PodiumVaults.payPodiumWinners`, `PodiumVaults.rollEpochTranches`, `ArenaPodiumSettlement.payoutShares`) at MR head SHA. Confirmed existing controls: `nonReentrant` on roll entrypoint, `podiumTimerArmed` + deadline gates, `msg.sender == arena` on vault mutators, zero-address skip on winner transfers, ledger underflow guard on commingled pools. Test-only `vm.prank(address(arena))` + `creditTranche` is Foundry setup mirroring arena-only auth — not reachable offchain. ### Outcome **FINDINGS: 0** medium+ Security review: **no medium+ findings** on this diff. No inline threads (nothing to block on). --- Automated security review (Cursor Cloud agent).
PlasticDigits (Migrated from gitlab.com) merged commit d8fbb7ab2f into main 2026-06-28 04:49:04 +00:00
PlasticDigits commented 2026-06-28 04:49:09 +00:00 (Migrated from gitlab.com)

mentioned in commit d8fbb7ab2f

mentioned in commit d8fbb7ab2f9ec653c72676661dae2274e42b21c7
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!528
No description provided.