Route buy prize remainder to Last Buy category #473

Merged
PlasticDigits merged 3 commits from verify/issue-313-last-buy-remainder into main 2026-06-14 02:43:47 +00:00
PlasticDigits commented 2026-06-13 13:23:48 +00:00 (Migrated from gitlab.com)

Summary

  • ArenaBuyRouting.splitBuyAmount assigns cross-category remainder (amount % 4) to Last Buy (cat 0) instead of WarBow (cat 3).
  • Updated Forge routing tests including new testFuzz_split_remainder_on_cat0.
  • Aligned PARAMETERS.md, product docs, invariants, and onchain fee/security docs with approved #313 economics.

Verification checklist

Acceptance item Command / evidence Result
amount % 4 wei routes to Last Buy vault/tranche ArenaBuyRouting.sol L31: i == 0 ? catRem : 0; test_split_remainder_to_last_buy_and_t10_tranche (1003 → cat0=253) PASS
All Forge routing tests updated and pass cd contracts && forge test --match-contract ArenaPrizeRouting PASS (7/7)
buy_routes integration tests pass cd contracts && forge test --match-test buy_routes PASS (2/2)
Fuzz: four shares sum to amount exactly testFuzz_splitBuy_no_dust PASS (256 runs)
Fuzz: remainder lands on cat 0 testFuzz_split_remainder_on_cat0 PASS (256 runs)
PARAMETERS.md matches code Row: remainder → Last Buy (#313) PASS
Product docs reflect Last Buy remainder rule docs/product/time-arena.md, docs/product/arena-v2.md PASS
100% podium routing invariant (#300) unchanged testFuzz_splitBuy_no_dust, test_buy_routes_doub_split (0% admin, full sum) PASS

Follow-ups

None — remainder target is now consistent across code, fuzz tests, and product docs.


Note

Low Risk
Documentation and Forge test coverage only in this diff; prize routing behavior is a small, well-tested rounding rule with no auth or indexer changes.

Overview
Aligns GitLab #313 economics in docs and tests: when a DOUB buy amount does not divide evenly by four, the amount % 4 wei goes to Last Buy (category 0), not WarBow.

Adds testFuzz_split_remainder_on_cat0 in ArenaPrizeRouting.t.sol to assert cat 0 gets baseShare + catRem and categories 1–3 get baseShare only. Updates PARAMETERS.md, fee-routing, security threat-model, and INV-ARENA-PRIZE-ROUTING-300-25PCT evidence to cite #313 and the new fuzz test. No contract logic changes appear in this diff ( ArenaBuyRouting already uses i == 0 ? catRem : 0).

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

## Summary - `ArenaBuyRouting.splitBuyAmount` assigns cross-category remainder (`amount % 4`) to **Last Buy (cat 0)** instead of WarBow (cat 3). - Updated Forge routing tests including new `testFuzz_split_remainder_on_cat0`. - Aligned `PARAMETERS.md`, product docs, invariants, and onchain fee/security docs with approved #313 economics. ## Verification checklist | Acceptance item | Command / evidence | Result | |-----------------|-------------------|--------| | `amount % 4` wei routes to Last Buy vault/tranche | `ArenaBuyRouting.sol` L31: `i == 0 ? catRem : 0`; `test_split_remainder_to_last_buy_and_t10_tranche` (1003 → cat0=253) | **PASS** | | All Forge routing tests updated and pass | `cd contracts && forge test --match-contract ArenaPrizeRouting` | **PASS** (7/7) | | `buy_routes` integration tests pass | `cd contracts && forge test --match-test buy_routes` | **PASS** (2/2) | | Fuzz: four shares sum to `amount` exactly | `testFuzz_splitBuy_no_dust` | **PASS** (256 runs) | | Fuzz: remainder lands on cat 0 | `testFuzz_split_remainder_on_cat0` | **PASS** (256 runs) | | `PARAMETERS.md` matches code | Row: remainder → Last Buy ([#313](https://gitlab.com/PlasticDigits/yieldomega/-/issues/313)) | **PASS** | | Product docs reflect Last Buy remainder rule | `docs/product/time-arena.md`, `docs/product/arena-v2.md` | **PASS** | | 100% podium routing invariant (#300) unchanged | `testFuzz_splitBuy_no_dust`, `test_buy_routes_doub_split` (0% admin, full sum) | **PASS** | ## Follow-ups None — remainder target is now consistent across code, fuzz tests, and product docs. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Documentation and Forge test coverage only in this diff; prize routing behavior is a small, well-tested rounding rule with no auth or indexer changes. > > **Overview** > Aligns **GitLab #313** economics in docs and tests: when a DOUB **`buy`** amount does not divide evenly by four, the **`amount % 4`** wei goes to **Last Buy (category 0)**, not WarBow. > > Adds **`testFuzz_split_remainder_on_cat0`** in **`ArenaPrizeRouting.t.sol`** to assert cat 0 gets **`baseShare + catRem`** and categories 1–3 get **`baseShare`** only. Updates **`PARAMETERS.md`**, fee-routing, security threat-model, and **`INV-ARENA-PRIZE-ROUTING-300-25PCT`** evidence to cite #313 and the new fuzz test. No contract logic changes appear in this diff ( **`ArenaBuyRouting`** already uses **`i == 0 ? catRem : 0`**). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit fdcb5589917894976be9e637eec5a8ece7bdcb55. 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 13:23:55 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-13 13:24:05 +00:00 (Migrated from gitlab.com)

changed the description

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

Security review — MR !473

Commit reviewed: 6ac39067246979ae786013eb0cc1c7f081f7d30a

Scope: ArenaBuyRouting.splitBuyAmount remainder target (amount % 4 wei → category 0 instead of category 3), associated Forge fuzz/unit tests, and documentation alignment for #313.

Method: Traced attacker-controlled buy amount through TimeArena._buyDoub → _routeDoubPrizeSplit → ArenaBuyRouting.splitBuyAmount → PodiumVaults transfers/events. Checked conservation (no stranded DOUB), access control, reentrancy/CEI, fee-on-transfer parity, indexer ingest (event-sourced PodiumEpochFunded), and offchain recompute surfaces.

Outcome: FINDINGS: 0 medium+

Inline threads: None (no medium+ issues on this diff).

Summary

This MR is an intentional rounding-direction change only: cross-category remainder (0–3 wei per buy) moves from WarBow (cat 3) to Last Buy (cat 0). testFuzz_splitBuy_no_dust and testFuzz_split_remainder_on_cat0 preserve exact 100% routing; _pullDoubExact + safeTransfer semantics are unchanged. No new external call surfaces, auth gaps, injection paths, or exploitable economic leverage—the remainder is negligible and still fully paid by the buyer into podium vaults. Indexer vault-funding rows derive from on-chain events, not a hardcoded split mirror.

Prior MR security-review threads: none to re-report.

## Security review — MR !473 **Commit reviewed:** `6ac39067246979ae786013eb0cc1c7f081f7d30a` **Scope:** `ArenaBuyRouting.splitBuyAmount` remainder target (`amount % 4` wei → category 0 instead of category 3), associated Forge fuzz/unit tests, and documentation alignment for #313. **Method:** Traced attacker-controlled buy `amount` through `TimeArena._buyDoub` → `_routeDoubPrizeSplit` → `ArenaBuyRouting.splitBuyAmount` → `PodiumVaults` transfers/events. Checked conservation (no stranded DOUB), access control, reentrancy/CEI, fee-on-transfer parity, indexer ingest (event-sourced `PodiumEpochFunded`), and offchain recompute surfaces. **Outcome:** **FINDINGS: 0** medium+ **Inline threads:** None (no medium+ issues on this diff). ### Summary This MR is an intentional rounding-direction change only: cross-category remainder (0–3 wei per buy) moves from WarBow (cat 3) to Last Buy (cat 0). `testFuzz_splitBuy_no_dust` and `testFuzz_split_remainder_on_cat0` preserve exact 100% routing; `_pullDoubExact` + `safeTransfer` semantics are unchanged. No new external call surfaces, auth gaps, injection paths, or exploitable economic leverage—the remainder is negligible and still fully paid by the buyer into podium vaults. Indexer vault-funding rows derive from on-chain events, not a hardcoded split mirror. Prior MR security-review threads: none to re-report.
PlasticDigits commented 2026-06-13 14:13:32 +00:00 (Migrated from gitlab.com)

added 31 commits

  • 6ac39067...8dd57052 - 30 commits from branch main
  • 15e2998f - Merge main into verify/issue-313-last-buy-remainder

Compare with previous version

added 31 commits <ul><li>6ac39067...8dd57052 - 30 commits from branch <code>main</code></li><li>15e2998f - Merge main into verify/issue-313-last-buy-remainder</li></ul> [Compare with previous version](/PlasticDigits/yieldomega/-/merge_requests/103/diffs?diff_id=1850345562&start_sha=6ac39067246979ae786013eb0cc1c7f081f7d30a)
PlasticDigits commented 2026-06-13 14:13:34 +00:00 (Migrated from gitlab.com)

Resolved merge conflicts with main (6 doc files).

  • Kept Last Buy remainder (#313) wording and issue links from this branch.
  • Took main updates: #314 AdminSellVault-not-deployed invariant, combined time-arena buy table row, and testFuzz_epoch_split_per_category_bps / testFuzz_split_remainder_on_cat0 in invariant evidence.
  • forge test --match-contract ArenaPrizeRouting: 7/7 PASS
Resolved merge conflicts with `main` (6 doc files). - Kept **Last Buy remainder (#313)** wording and issue links from this branch. - Took **main** updates: `#314` AdminSellVault-not-deployed invariant, combined `time-arena` buy table row, and `testFuzz_epoch_split_per_category_bps` / `testFuzz_split_remainder_on_cat0` in invariant evidence. - `forge test --match-contract ArenaPrizeRouting`: **7/7 PASS**
PlasticDigits commented 2026-06-13 14:17:18 +00:00 (Migrated from gitlab.com)

Security review — MR !473

Commit reviewed: 15e2998f9bfa213471e487979c64e3cd99856499

Scope: Full MR intent (#313): ArenaBuyRouting.splitBuyAmount cross-category remainder (amount % 4, 0–3 wei) routed to Last Buy (cat 0) instead of WarBow (cat 3); Forge fuzz/unit coverage; documentation and invariant alignment. Post-merge diff vs main is docs + testFuzz_split_remainder_on_cat0; on-chain routing change is in branch commit 6ac39067 (already present on target).

Method: Traced attacker-controlled buy amount (charmWad → _pullDoubExact → _routeDoubPrizeSplit → ArenaBuyRouting.splitBuyAmount → PodiumVaults transfers/PodiumEpochFunded). Verified 100% conservation (testFuzz_splitBuy_no_dust, testFuzz_split_remainder_on_cat0), ERC-20 parity gate on pulls, unchanged access control/reentrancy surfaces, and indexer ingest (event-sourced vault funding, no offchain split mirror). Checked WarBow spend paths and integration tests (test_buy_routes_*).

Outcome: FINDINGS: 0 medium+

Inline threads: None (no medium+ issues on this diff).

Summary

Intentional rounding-direction change only: negligible remainder wei (max 3 per buy) shifts from WarBow to Last Buy while total routed DOUB still equals gross paid amount. Buyer cannot recover remainder; choosing amount % 4 offers no exploitable economic leverage at this scale. No new external-call/auth/injection paths; _pullDoubExact fee-on-transfer rejection unchanged. Indexer/UI derive funding from on-chain events, not a hardcoded WarBow-remainder assumption.

Prior MR security-review thread (6ac39067): no findings to re-report; merge-conflict resolution added docs/invariant evidence only.

## Security review — MR !473 **Commit reviewed:** `15e2998f9bfa213471e487979c64e3cd99856499` **Scope:** Full MR intent (#313): `ArenaBuyRouting.splitBuyAmount` cross-category remainder (`amount % 4`, 0–3 wei) routed to **Last Buy (cat 0)** instead of WarBow (cat 3); Forge fuzz/unit coverage; documentation and invariant alignment. Post-merge diff vs `main` is docs + `testFuzz_split_remainder_on_cat0`; on-chain routing change is in branch commit `6ac39067` (already present on target). **Method:** Traced attacker-controlled buy `amount` (`charmWad` → `_pullDoubExact` → `_routeDoubPrizeSplit` → `ArenaBuyRouting.splitBuyAmount` → `PodiumVaults` transfers/`PodiumEpochFunded`). Verified 100% conservation (`testFuzz_splitBuy_no_dust`, `testFuzz_split_remainder_on_cat0`), ERC-20 parity gate on pulls, unchanged access control/reentrancy surfaces, and indexer ingest (event-sourced vault funding, no offchain split mirror). Checked WarBow spend paths and integration tests (`test_buy_routes_*`). **Outcome:** **FINDINGS: 0** medium+ **Inline threads:** None (no medium+ issues on this diff). ### Summary Intentional rounding-direction change only: negligible remainder wei (max 3 per buy) shifts from WarBow to Last Buy while total routed DOUB still equals gross paid amount. Buyer cannot recover remainder; choosing `amount % 4` offers no exploitable economic leverage at this scale. No new external-call/auth/injection paths; `_pullDoubExact` fee-on-transfer rejection unchanged. Indexer/UI derive funding from on-chain events, not a hardcoded WarBow-remainder assumption. Prior MR security-review thread (`6ac39067`): no findings to re-report; merge-conflict resolution added docs/invariant evidence only.
PlasticDigits commented 2026-06-14 02:37:40 +00:00 (Migrated from gitlab.com)

added 23 commits

  • 15e2998f...2f53f814 - 22 commits from branch main
  • fdcb5589 - Merge main into verify/issue-313-last-buy-remainder

Compare with previous version

added 23 commits <ul><li>15e2998f...2f53f814 - 22 commits from branch <code>main</code></li><li>fdcb5589 - Merge main into verify/issue-313-last-buy-remainder</li></ul> [Compare with previous version](/PlasticDigits/yieldomega/-/merge_requests/103/diffs?diff_id=1850556940&start_sha=15e2998f9bfa213471e487979c64e3cd99856499)
PlasticDigits commented 2026-06-14 02:37:41 +00:00 (Migrated from gitlab.com)

Resolved merge conflicts with main.

Conflict: docs/product/arena-v2.md — both branches documented remainder → Last Buy (#313); kept that wording and retained main's ArenaBuyRouting.splitBuyAmount cross-reference.

Verification: forge test --match-contract ArenaPrizeRouting — 7/7 PASS.

Resolved merge conflicts with `main`. **Conflict:** `docs/product/arena-v2.md` — both branches documented remainder → Last Buy (#313); kept that wording and retained `main`'s `ArenaBuyRouting.splitBuyAmount` cross-reference. **Verification:** `forge test --match-contract ArenaPrizeRouting` — 7/7 PASS.
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-14 02:37:58 +00:00 (Migrated from gitlab.com)

changed the description

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

Security review — MR !473

Commit reviewed: fdcb5589917894976be9e637eec5a8ece7bdcb55

Scope: GitLab #313 buy prize routing — cross-category remainder (amount % 4, 0–3 wei) assigned to Last Buy (cat 0) instead of WarBow (cat 3). Current diff vs main: docs/invariant alignment + testFuzz_split_remainder_on_cat0; on-chain change in branch commit 6ac39067 (ArenaBuyRouting.splitBuyAmount L31: i == 0 ? catRem : 0).

Method: Traced attacker-controlled buy/spend amount through _pullDoubExact → _routeDoubPrizeSplit / _routeWarbowDoubSpend → ArenaBuyRouting.splitBuyAmount → PodiumVaults transfers and PodiumEpochFunded events. Verified 100% conservation (testFuzz_splitBuy_no_dust, testFuzz_split_remainder_on_cat0, testFuzz_epoch_split_per_category_bps), ERC-20 parity gate on pulls, unchanged nonReentrant/access-control surfaces, batch-vault fast path, and indexer ingest (event-sourced idx_arena_vault_funding, no offchain split mirror). Ran forge test --match-contract ArenaPrizeRouting and --match-test buy_routes — PASS.

Outcome: FINDINGS: 0 medium+

Inline threads: None (no medium+ issues on this diff).

Summary

Intentional rounding-direction change only: negligible remainder wei (max 3 per buy) shifts from WarBow to Last Buy while gross routed DOUB still equals paid amount. Buyer cannot recover remainder; choosing amount % 4 offers no exploitable economic leverage at this scale. No new external-call, auth, reentrancy, or injection paths introduced. Indexer/UI derive vault funding from on-chain events, not a hardcoded WarBow-remainder assumption.

Prior MR security-review threads (6ac39067, 15e2998f): no findings to re-report.

## Security review — MR !473 **Commit reviewed:** `fdcb5589917894976be9e637eec5a8ece7bdcb55` **Scope:** GitLab #313 buy prize routing — cross-category remainder (`amount % 4`, 0–3 wei) assigned to **Last Buy (cat 0)** instead of WarBow (cat 3). Current diff vs `main`: docs/invariant alignment + `testFuzz_split_remainder_on_cat0`; on-chain change in branch commit `6ac39067` (`ArenaBuyRouting.splitBuyAmount` L31: `i == 0 ? catRem : 0`). **Method:** Traced attacker-controlled buy/spend `amount` through `_pullDoubExact` → `_routeDoubPrizeSplit` / `_routeWarbowDoubSpend` → `ArenaBuyRouting.splitBuyAmount` → `PodiumVaults` transfers and `PodiumEpochFunded` events. Verified 100% conservation (`testFuzz_splitBuy_no_dust`, `testFuzz_split_remainder_on_cat0`, `testFuzz_epoch_split_per_category_bps`), ERC-20 parity gate on pulls, unchanged `nonReentrant`/access-control surfaces, batch-vault fast path, and indexer ingest (event-sourced `idx_arena_vault_funding`, no offchain split mirror). Ran `forge test --match-contract ArenaPrizeRouting` and `--match-test buy_routes` — PASS. **Outcome:** **FINDINGS: 0** medium+ **Inline threads:** None (no medium+ issues on this diff). ### Summary Intentional rounding-direction change only: negligible remainder wei (max 3 per buy) shifts from WarBow to Last Buy while gross routed DOUB still equals paid amount. Buyer cannot recover remainder; choosing `amount % 4` offers no exploitable economic leverage at this scale. No new external-call, auth, reentrancy, or injection paths introduced. Indexer/UI derive vault funding from on-chain events, not a hardcoded WarBow-remainder assumption. Prior MR security-review threads (`6ac39067`, `15e2998f`): no findings to re-report.
PlasticDigits commented 2026-06-14 02:43:47 +00:00 (Migrated from gitlab.com)

mentioned in commit 9d1e43cac9

mentioned in commit 9d1e43cac92ea049f717087999703034f58af7b1
PlasticDigits (Migrated from gitlab.com) merged commit 9d1e43cac9 into main 2026-06-14 02:43:47 +00:00
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!473
No description provided.