Fix buyWithCred to contribute 35 CRED to epoch pool per buy #475

Merged
PlasticDigits merged 3 commits from fix/311-cred-buy-epoch-pool into main 2026-06-14 02:44:09 +00:00
PlasticDigits commented 2026-06-13 13:35:50 +00:00 (Migrated from gitlab.com)

Summary

  • Route buyWithCred through _accrueCharmAndCred so each CRED buy adds 35 CRED (CRED_PER_BUY) to epochCredPool[lastBuyEpoch], mirroring DOUB buys.
  • Remove unused _accrueCharmOnly; add Forge tests for pool accrual, mixed DOUB/CRED pro-rata, epoch boundary, and fair CRED-only claims.
  • Replace INV-TIME-ARENA-CRED-NO-POOL with INV-TIME-ARENA-CRED-POOL-ACCRUE; update product docs and guardrails.
  • Extend verify-cred-buy-anvil.sh with on-chain epochCredPool assertion; fix stale starter-buy level expectation (#304 max-band XP → level 2).

Verification checklist

Acceptance item Command / evidence Result
Each buyWithCred adds 35 CRED to epochCredPool[epoch] forge test --match-test test_buy_with_cred · test_buyWithCred_accrues_epoch_cred_pool PASS
CHARM weight accrual unchanged in intent forge test --match-test test_xp_buy_with_cred_same_as_doub PASS
claimCred pro-rata fair for mixed DOUB/CRED buyers forge test --match-test test_cred_pro_rata_mixed_doub_and_cred PASS
Invariant doc updated; CRED-NO-POOL revised docs/testing/invariants-and-business-logic.md → INV-TIME-ARENA-CRED-POOL-ACCRUE PASS
Forge cred / buy_with_cred tests cd contracts && forge test --match-contract TimeArena PASS
verify-cred-buy-anvil.sh bash scripts/verify-cred-buy-anvil.sh PASS
No regression in DOUB pool accrual forge test --match-test test_cred_accrue_on_doub_buy PASS
CRED-only buyer cannot extract more than fair share forge test --match-test test_buyWithCred_only_fair_pro_rata_claim PASS
Epoch boundary pool credit forge test --match-test test_buyWithCred_epoch_boundary_credits_correct_pool PASS
Double-claim still one-shot forge test --match-test test_claimCred_cannot_double_claim PASS
Indexer pool-related fields No epochCredPool indexer decode in scope SKIP
Rabby manual CRED buy UI Not required for onchain economics change SKIP

Note

Medium Risk
Changes on-chain epoch CRED funding for every buyWithCred, which affects pro-rata claimCred payouts; scope is narrow and heavily tested but is core TimeArena economics.

Overview
buyWithCred now participates in Last Buy epoch CRED economics the same way DOUB buys do: each CRED purchase adds 35 CRED (CRED_PER_BUY) to epochCredPool[lastBuyEpoch] while still burning Play CRED and accruing CHARM weight (implementation routes through _accrueCharmAndCred; supersedes the old “no pool” invariant).

The PR adds Forge coverage for pool accrual, mixed DOUB/CRED pro-rata claims, soft vs hard epoch boundaries, and CRED-only fair-share claims, and tightens test_buy_with_cred to assert the pool bump. Product docs, guardrails, and INV-TIME-ARENA-CRED-POOL-PARITY / §311 invariant tables now document epochCredPool behavior and point at the new tests plus verify-cred-buy-anvil.sh.

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

## Summary - Route `buyWithCred` through `_accrueCharmAndCred` so each CRED buy adds **35 CRED** (`CRED_PER_BUY`) to `epochCredPool[lastBuyEpoch]`, mirroring DOUB buys. - Remove unused `_accrueCharmOnly`; add Forge tests for pool accrual, mixed DOUB/CRED pro-rata, epoch boundary, and fair CRED-only claims. - Replace `INV-TIME-ARENA-CRED-NO-POOL` with `INV-TIME-ARENA-CRED-POOL-ACCRUE`; update product docs and guardrails. - Extend `verify-cred-buy-anvil.sh` with on-chain `epochCredPool` assertion; fix stale starter-buy level expectation (#304 max-band XP → level 2). ## Verification checklist | Acceptance item | Command / evidence | Result | |-----------------|-------------------|--------| | Each `buyWithCred` adds 35 CRED to `epochCredPool[epoch]` | `forge test --match-test test_buy_with_cred` · `test_buyWithCred_accrues_epoch_cred_pool` | **PASS** | | CHARM weight accrual unchanged in intent | `forge test --match-test test_xp_buy_with_cred_same_as_doub` | **PASS** | | `claimCred` pro-rata fair for mixed DOUB/CRED buyers | `forge test --match-test test_cred_pro_rata_mixed_doub_and_cred` | **PASS** | | Invariant doc updated; `CRED-NO-POOL` revised | `docs/testing/invariants-and-business-logic.md` → `INV-TIME-ARENA-CRED-POOL-ACCRUE` | **PASS** | | Forge cred / buy_with_cred tests | `cd contracts && forge test --match-contract TimeArena` | **PASS** | | `verify-cred-buy-anvil.sh` | `bash scripts/verify-cred-buy-anvil.sh` | **PASS** | | No regression in DOUB pool accrual | `forge test --match-test test_cred_accrue_on_doub_buy` | **PASS** | | CRED-only buyer cannot extract more than fair share | `forge test --match-test test_buyWithCred_only_fair_pro_rata_claim` | **PASS** | | Epoch boundary pool credit | `forge test --match-test test_buyWithCred_epoch_boundary_credits_correct_pool` | **PASS** | | Double-claim still one-shot | `forge test --match-test test_claimCred_cannot_double_claim` | **PASS** | | Indexer pool-related fields | No `epochCredPool` indexer decode in scope | **SKIP** | | Rabby manual CRED buy UI | Not required for onchain economics change | **SKIP** | <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes on-chain epoch CRED funding for every `buyWithCred`, which affects pro-rata `claimCred` payouts; scope is narrow and heavily tested but is core TimeArena economics. > > **Overview** > **`buyWithCred`** now participates in Last Buy epoch CRED economics the same way DOUB buys do: each CRED purchase adds **35 CRED** (`CRED_PER_BUY`) to **`epochCredPool[lastBuyEpoch]`** while still burning Play CRED and accruing CHARM weight (implementation routes through **`_accrueCharmAndCred`**; supersedes the old “no pool” invariant). > > The PR adds **Forge coverage** for pool accrual, mixed DOUB/CRED pro-rata claims, soft vs hard epoch boundaries, and CRED-only fair-share claims, and tightens **`test_buy_with_cred`** to assert the pool bump. **Product docs**, **guardrails**, and **`INV-TIME-ARENA-CRED-POOL-PARITY`** / §311 invariant tables now document **`epochCredPool`** behavior and point at the new tests plus **`verify-cred-buy-anvil.sh`**. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 9d384bf7f1cfdf16a14b695e65f36fa6d1115a6f. 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:35:59 +00:00 (Migrated from gitlab.com)

changed the description

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

changed the description

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

Security review — MR !475

Commit reviewed: 68ddfb0c9a839fd47e4dee8a7b11b2810bd854c8

Scope: TimeArena.sol change routing buyWithCred through _accrueCharmAndCred (epoch pool +35 CRED per buy); removed _accrueCharmOnly; Forge tests, docs/invariants, verify-cred-buy-anvil.sh.

Prior review threads: None on this MR (re-checked discussions).

Outcome: FINDINGS: 0 medium+ — NONE

Analysis summary

Traced attacker-controlled inputs (charmWad, msg.sender) through _buyCred → playCred.burn → _accrueCharmAndCred(buyer, charmWad, bytes32(0)) → _finishBuy → claimCred.

Area Result
Reentrancy nonReentrant on buyWithCred / claimCred; PlayCred has no transfer hooks; burn still precedes accrual/finish (unchanged order).
Access control / authz No new external surfaces; buyWithCred remains self-serve with existing cooldown + CHARM bounds.
Referral / mint side-effects codeHash = bytes32(0) skips referral mint branch in _accrueCharmAndCred (same as DOUB path without code).
CRED inflation / extraction Pool accrual is flat CRED_PER_BUY (35e18) per buy; claims use existing pro-rata mulDiv with epoch weight zeroing. Sole/mixed-buyer tests show claim ≤ pool and burn (≥99 CRED at min CHARM) exceeds pro-rata return — no CRED mint arbitrage.
Dilution / griefing Large-charmWad CRED buys dilute others' CHARM weight; MR adds matching pool contribution (same model as DOUB buys) — does not open a new drain path.
Epoch boundary Accrual uses lastBuyEpoch before _finishBuy hard-reset; covered by test_buyWithCred_epoch_boundary_credits_correct_pool.
Off-chain (indexer/scripts) Diff is assertion/docs only; no new injection or SSRF surfaces.

Inline threads: None (no medium+ findings).

Label: block:security not applied.

## Security review — MR !475 **Commit reviewed:** `68ddfb0c9a839fd47e4dee8a7b11b2810bd854c8` **Scope:** `TimeArena.sol` change routing `buyWithCred` through `_accrueCharmAndCred` (epoch pool +35 CRED per buy); removed `_accrueCharmOnly`; Forge tests, docs/invariants, `verify-cred-buy-anvil.sh`. **Prior review threads:** None on this MR (re-checked discussions). **Outcome:** `FINDINGS: 0` medium+ — **NONE** ### Analysis summary Traced attacker-controlled inputs (`charmWad`, `msg.sender`) through `_buyCred` → `playCred.burn` → `_accrueCharmAndCred(buyer, charmWad, bytes32(0))` → `_finishBuy` → `claimCred`. | Area | Result | |------|--------| | Reentrancy | `nonReentrant` on `buyWithCred` / `claimCred`; `PlayCred` has no transfer hooks; burn still precedes accrual/finish (unchanged order). | | Access control / authz | No new external surfaces; `buyWithCred` remains self-serve with existing cooldown + CHARM bounds. | | Referral / mint side-effects | `codeHash = bytes32(0)` skips referral mint branch in `_accrueCharmAndCred` (same as DOUB path without code). | | CRED inflation / extraction | Pool accrual is flat `CRED_PER_BUY` (35e18) per buy; claims use existing pro-rata `mulDiv` with epoch weight zeroing. Sole/mixed-buyer tests show claim ≤ pool and burn (≥99 CRED at min CHARM) exceeds pro-rata return — no CRED mint arbitrage. | | Dilution / griefing | Large-`charmWad` CRED buys dilute others' CHARM weight; MR adds matching pool contribution (same model as DOUB buys) — does not open a new drain path. | | Epoch boundary | Accrual uses `lastBuyEpoch` before `_finishBuy` hard-reset; covered by `test_buyWithCred_epoch_boundary_credits_correct_pool`. | | Off-chain (indexer/scripts) | Diff is assertion/docs only; no new injection or SSRF surfaces. | **Inline threads:** None (no medium+ findings). **Label:** `block:security` not applied.
PlasticDigits commented 2026-06-13 14:15:39 +00:00 (Migrated from gitlab.com)

added 31 commits

  • 68ddfb0c...8dd57052 - 30 commits from branch main
  • f68da432 - Merge origin/main into fix/311-cred-buy-epoch-pool

Compare with previous version

added 31 commits <ul><li>68ddfb0c...8dd57052 - 30 commits from branch <code>main</code></li><li>f68da432 - Merge origin/main into fix/311-cred-buy-epoch-pool</li></ul> [Compare with previous version](/PlasticDigits/yieldomega/-/merge_requests/105/diffs?diff_id=1850346098&start_sha=68ddfb0c9a839fd47e4dee8a7b11b2810bd854c8)
PlasticDigits commented 2026-06-13 14:15:42 +00:00 (Migrated from gitlab.com)

Resolved merge conflicts with origin/main:

  • TimeArena.sol — kept main's _applyBuyWarBowBp streak-break signature (5-arg); CRED pool accrual unchanged.
  • TimeArena.t.sol — merged both sides' Forge tests: MR pool-accrual/pro-rata/epoch-boundary cases plus main's renamed test_cred_pro_rata_mixed_doub_and_cred_buyers and hard-reset boundary test.
  • Docs — unified on INV-TIME-ARENA-CRED-POOL-PARITY with combined test evidence from both branches.
  • verify-cred-buy-anvil.sh — kept single epochCredPool +35 delta assertion (removed duplicate block from MR).

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

Resolved merge conflicts with `origin/main`: - **TimeArena.sol** — kept main's `_applyBuyWarBowBp` streak-break signature (5-arg); CRED pool accrual unchanged. - **TimeArena.t.sol** — merged both sides' Forge tests: MR pool-accrual/pro-rata/epoch-boundary cases plus main's renamed `test_cred_pro_rata_mixed_doub_and_cred_buyers` and hard-reset boundary test. - **Docs** — unified on `INV-TIME-ARENA-CRED-POOL-PARITY` with combined test evidence from both branches. - **verify-cred-buy-anvil.sh** — kept single `epochCredPool +35` delta assertion (removed duplicate block from MR). Sanity: `forge test --match-contract TimeArena` PASS.
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-13 14:16:03 +00:00 (Migrated from gitlab.com)

changed the description

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

Security review — MR !475

Commit reviewed: f68da432b949c07905d0162dd87020c4e991b9fa

Scope: Current MR diff vs main (8dd57052): additional Forge tests (TimeArena.t.sol), product/invariant docs, guardrails. Contract routing (buyWithCred → _accrueCharmAndCred) and verify-cred-buy-anvil.sh pool assertion are already on main at merge-base; re-traced full on-chain path for regression after main merge.

Prior review threads: Reviewed prior note on 68ddfb0c — no medium+ findings there; re-validated against post-merge head.

Outcome: FINDINGS: 0 medium+ — NONE

Analysis summary

Traced attacker-controlled inputs (charmWad, msg.sender) through _buyCred → playCred.burn → _accrueCharmAndCred(buyer, charmWad, bytes32(0)) → _finishBuy → claimCred.

Area Result
Reentrancy nonReentrant on buyWithCred / claimCred; PlayCred only allows mint/burn (no transfer hooks); burn precedes accrual/finish.
Access control / authz No new external surfaces; buyWithCred remains self-serve with existing cooldown + CHARM bounds.
Referral / mint side-effects codeHash = bytes32(0) skips referral mint branch in _accrueCharmAndCred.
CRED inflation / extraction Flat CRED_PER_BUY (35e18) accrual; claimCred uses mulDiv pro-rata with per-user weight zeroing. CRED burn (≥99e18 at min CHARM) exceeds solo or equal-split pro-rata return — no mint arbitrage.
Dilution / griefing Large-charmWad CRED buys dilute others' CHARM weight with matching pool contribution (parity with DOUB buys) — no new drain path.
Epoch boundary _prepareBuyBeforeTimer re-anchors lastBuyEpoch before accrual on hard reset; soft roll credits current epoch — covered by test_buyWithCred_epoch_boundary_credits_correct_pool and test_cred_accrue_buyWithCred_at_epoch_boundary.
Off-chain (this diff) Tests/docs/guardrails only; no injection, SSRF, or auth surfaces.

Inline threads: None (no medium+ findings).

Label: block:security not applied.

## Security review — MR !475 **Commit reviewed:** `f68da432b949c07905d0162dd87020c4e991b9fa` **Scope:** Current MR diff vs `main` (`8dd57052`): additional Forge tests (`TimeArena.t.sol`), product/invariant docs, guardrails. Contract routing (`buyWithCred` → `_accrueCharmAndCred`) and `verify-cred-buy-anvil.sh` pool assertion are already on `main` at merge-base; re-traced full on-chain path for regression after main merge. **Prior review threads:** Reviewed prior note on `68ddfb0c` — no medium+ findings there; re-validated against post-merge head. **Outcome:** `FINDINGS: 0` medium+ — **NONE** ### Analysis summary Traced attacker-controlled inputs (`charmWad`, `msg.sender`) through `_buyCred` → `playCred.burn` → `_accrueCharmAndCred(buyer, charmWad, bytes32(0))` → `_finishBuy` → `claimCred`. | Area | Result | |------|--------| | Reentrancy | `nonReentrant` on `buyWithCred` / `claimCred`; `PlayCred` only allows mint/burn (no transfer hooks); burn precedes accrual/finish. | | Access control / authz | No new external surfaces; `buyWithCred` remains self-serve with existing cooldown + CHARM bounds. | | Referral / mint side-effects | `codeHash = bytes32(0)` skips referral mint branch in `_accrueCharmAndCred`. | | CRED inflation / extraction | Flat `CRED_PER_BUY` (35e18) accrual; `claimCred` uses `mulDiv` pro-rata with per-user weight zeroing. CRED burn (≥99e18 at min CHARM) exceeds solo or equal-split pro-rata return — no mint arbitrage. | | Dilution / griefing | Large-`charmWad` CRED buys dilute others' CHARM weight with matching pool contribution (parity with DOUB buys) — no new drain path. | | Epoch boundary | `_prepareBuyBeforeTimer` re-anchors `lastBuyEpoch` before accrual on hard reset; soft roll credits current epoch — covered by `test_buyWithCred_epoch_boundary_credits_correct_pool` and `test_cred_accrue_buyWithCred_at_epoch_boundary`. | | Off-chain (this diff) | Tests/docs/guardrails only; no injection, SSRF, or auth surfaces. | **Inline threads:** None (no medium+ findings). **Label:** `block:security` not applied.
PlasticDigits commented 2026-06-14 02:41:05 +00:00 (Migrated from gitlab.com)

added 23 commits

  • f68da432...2f53f814 - 22 commits from branch main
  • 9d384bf7 - Merge origin/main into fix/311-cred-buy-epoch-pool

Compare with previous version

added 23 commits <ul><li>f68da432...2f53f814 - 22 commits from branch <code>main</code></li><li>9d384bf7 - Merge origin/main into fix/311-cred-buy-epoch-pool</li></ul> [Compare with previous version](/PlasticDigits/yieldomega/-/merge_requests/105/diffs?diff_id=1850557586&start_sha=f68da432b949c07905d0162dd87020c4e991b9fa)
PlasticDigits commented 2026-06-14 02:41:06 +00:00 (Migrated from gitlab.com)

Resolved merge conflicts with origin/main (2 files):

  • .cursor/skills/yieldomega-guardrails/SKILL.md — kept #311 epoch pool accrual on buyWithCred and updated first-buy bonus to FIRST_BUY_CRED_BONUS = 1100e18 from main (#299).
  • docs/product/arena-v2.md — same: 35 CRED pool accrual per CRED buy + 1100e18 first-buy bonus wording from main.

Sanity: forge test --match-contract TimeArena --match-test cred|buy_with_cred|buyWithCred — 24 passed.

Resolved merge conflicts with `origin/main` (2 files): - **`.cursor/skills/yieldomega-guardrails/SKILL.md`** — kept #311 epoch pool accrual on `buyWithCred` and updated first-buy bonus to `FIRST_BUY_CRED_BONUS = 1100e18` from main (#299). - **`docs/product/arena-v2.md`** — same: 35 CRED pool accrual per CRED buy + `1100e18` first-buy bonus wording from main. Sanity: `forge test --match-contract TimeArena --match-test cred|buy_with_cred|buyWithCred` — **24 passed**.
project_80561744_bot_5118c68a88bff95eacb6ab1c47c19cae commented 2026-06-14 02:41:24 +00:00 (Migrated from gitlab.com)

changed the description

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

mentioned in commit 03a43d4a6e

mentioned in commit 03a43d4a6eccfa39fe5556e2f9e732c5333f4a92
PlasticDigits (Migrated from gitlab.com) merged commit 03a43d4a6e into main 2026-06-14 02:44:09 +00:00
PlasticDigits commented 2026-06-14 02:45:39 +00:00 (Migrated from gitlab.com)

Security review — MR !475

Commit reviewed: 9d384bf7f1cfdf16a14b695e65f36fa6d1115a6f

Scope: MR diff vs main (2f53f814): additional Forge tests (TimeArena.t.sol), product/invariant docs, guardrails. On-chain routing (buyWithCred → _accrueCharmAndCred, epochCredPool += CRED_PER_BUY) is already present on main at merge-base; re-traced full attacker path for regression after latest merge.

Prior review threads: Two prior top-level reviews (68ddfb0c, f68da432) reported FINDINGS: 0; no inline security threads. Re-validated against current head — conclusions unchanged.

Outcome: FINDINGS: 0 medium+ — NONE

Analysis summary

Traced attacker-controlled inputs (charmWad, msg.sender) through _buyCred → playCred.burn → _accrueCharmAndCred(buyer, charmWad, bytes32(0)) → _finishBuy → claimCred.

Area Result
Reentrancy nonReentrant on buyWithCred / claimCred; PlayCred is non-transferable with no external hooks; burn precedes accrual/finish.
Access control / authz No new external surfaces; buyWithCred remains self-serve with existing cooldown + CHARM bounds.
Referral / mint side-effects codeHash = bytes32(0) skips referral mint branch in _accrueCharmAndCred.
CRED inflation / extraction Flat CRED_PER_BUY (35e18) accrual; claimCred uses mulDiv pro-rata with per-user weight zeroing. CRED burn (≥99e18 at min CHARM) exceeds solo or equal-split pro-rata return — no mint arbitrage.
Dilution / griefing Large-charmWad CRED buys dilute others' CHARM weight with matching pool contribution (parity with DOUB buys) — no new drain path.
Epoch boundary _prepareBuyBeforeTimer re-anchors lastBuyEpoch before accrual on hard reset; soft roll credits current epoch — covered by test_buyWithCred_epoch_boundary_credits_correct_pool and test_cred_accrue_buyWithCred_at_epoch_boundary.
Off-chain (this diff) Tests/docs/guardrails only; no injection, SSRF, or auth surfaces.

Inline threads: None (no medium+ findings).

Label: block:security not applied.

## Security review — MR !475 **Commit reviewed:** `9d384bf7f1cfdf16a14b695e65f36fa6d1115a6f` **Scope:** MR diff vs `main` (`2f53f814`): additional Forge tests (`TimeArena.t.sol`), product/invariant docs, guardrails. On-chain routing (`buyWithCred` → `_accrueCharmAndCred`, `epochCredPool += CRED_PER_BUY`) is already present on `main` at merge-base; re-traced full attacker path for regression after latest merge. **Prior review threads:** Two prior top-level reviews (`68ddfb0c`, `f68da432`) reported `FINDINGS: 0`; no inline security threads. Re-validated against current head — conclusions unchanged. **Outcome:** `FINDINGS: 0` medium+ — **NONE** ### Analysis summary Traced attacker-controlled inputs (`charmWad`, `msg.sender`) through `_buyCred` → `playCred.burn` → `_accrueCharmAndCred(buyer, charmWad, bytes32(0))` → `_finishBuy` → `claimCred`. | Area | Result | |------|--------| | Reentrancy | `nonReentrant` on `buyWithCred` / `claimCred`; `PlayCred` is non-transferable with no external hooks; burn precedes accrual/finish. | | Access control / authz | No new external surfaces; `buyWithCred` remains self-serve with existing cooldown + CHARM bounds. | | Referral / mint side-effects | `codeHash = bytes32(0)` skips referral mint branch in `_accrueCharmAndCred`. | | CRED inflation / extraction | Flat `CRED_PER_BUY` (35e18) accrual; `claimCred` uses `mulDiv` pro-rata with per-user weight zeroing. CRED burn (≥99e18 at min CHARM) exceeds solo or equal-split pro-rata return — no mint arbitrage. | | Dilution / griefing | Large-`charmWad` CRED buys dilute others' CHARM weight with matching pool contribution (parity with DOUB buys) — no new drain path. | | Epoch boundary | `_prepareBuyBeforeTimer` re-anchors `lastBuyEpoch` before accrual on hard reset; soft roll credits current epoch — covered by `test_buyWithCred_epoch_boundary_credits_correct_pool` and `test_cred_accrue_buyWithCred_at_epoch_boundary`. | | Off-chain (this diff) | Tests/docs/guardrails only; no injection, SSRF, or auth surfaces. | **Inline threads:** None (no medium+ findings). **Label:** `block:security` not applied.
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!475
No description provided.