Local Anvil: env-gated no-cooldown deploy mode for QA verification throughput #88

Closed
opened 2026-04-29 01:30:17 +00:00 by Brouie · 11 comments
Brouie commented 2026-04-29 01:30:17 +00:00 (Migrated from gitlab.com)

Summary

5-minute per-wallet nextBuyAllowedAt cooldown is significantly slowing manual checklist verification on local Anvil stacks. Most QA checklist scenarios (#38 F-flows, #39 A/B/C, #82 multi-buy spread tests) need to exercise multiple consecutive buys on the same wallet, and the 5-min wait between each one is making sessions unsustainable.

Per dev's direct request in TG: "Open an issue for this so we can deploy a no cd version".

Proposal

Either:

  1. A new dedicated TimeCurveAnvilNoCooldown.sol test fixture that exposes a setBuyCooldownSec(uint256) admin path which can be set to 0 (or 1 second), gated behind an env var like YIELDOMEGA_DEPLOY_NO_COOLDOWN=1 similar to the YIELDOMEGA_DEPLOY_KUMBAYA=1 pattern from #84.

  2. OR a post-deploy admin call wired into start-local-anvil-stack.sh that calls setBuyCooldownSec(1) (or similar 1-second floor) on the deployed proxy when an env flag is set. Cooldown is already initialized via _buyCooldownSec in the constructor (TimeCurve.sol L259), so an owner setter would unlock this path.

  3. OR a separate Anvil-only TimeCurve subclass that overrides _requireCooldown() to a no-op when block.chainid == 31337.

Option 2 feels lightest if there's already a setBuyCooldownSec owner function or one can be added.

Why this blocks QA

  • #38 DOUB Launch UX — F-05 buy charms test needs multiple buys to exercise different slider positions. Currently 5 min wait per buy = ~50 min for 10 test cases.
  • #39 TimeCurve QA checklist A/B/C — same pattern, multi-buy spread.
  • #82 lower/upper edge regression checklist — needs at least 4 distinct buys (CL8Y near-min, CL8Y near-max, Kumbaya near-min, Kumbaya near-max), can't multiplex across wallets without funding overhead.
  • Browser walkthrough sessions — multi-flow verification stalls behind cooldowns.

Workaround today is funding multiple wallets with CL8Y/ETH via cast send + switching MetaMask between them, but each wallet switch causes its own MM nonce-tracking issues (see #84-followup observations) so it's a wash on time saved.

Acceptance criteria

  • An env-flag-gated path that lets the local Anvil stack come up with effective cooldown ≤ 1 second.
  • Default behavior unchanged (5 min cooldown stays in place when flag not set).
  • Forge tests covering both cooldown-on and cooldown-off configurations to prevent accidental config drift.
  • Doc note in docs/testing/e2e-anvil.md (or wherever the Kumbaya flag is documented) explaining when to enable it.

Severity

P2-medium. Not a launch-blocker for mainnet (production cooldown is correct), purely a QA throughput fix. But TGE in 2 days = high time-pressure on checklist completion, so prioritizing this would compound across multiple open verification issues.

Filed at dev request.

cc @PlasticDigits

## Summary 5-minute per-wallet `nextBuyAllowedAt` cooldown is significantly slowing manual checklist verification on local Anvil stacks. Most QA checklist scenarios (#38 F-flows, #39 A/B/C, #82 multi-buy spread tests) need to exercise multiple consecutive buys on the same wallet, and the 5-min wait between each one is making sessions unsustainable. Per dev's direct request in TG: "Open an issue for this so we can deploy a no cd version". ## Proposal Either: 1. A new dedicated **`TimeCurveAnvilNoCooldown.sol` test fixture** that exposes a `setBuyCooldownSec(uint256)` admin path which can be set to 0 (or 1 second), gated behind an env var like `YIELDOMEGA_DEPLOY_NO_COOLDOWN=1` similar to the `YIELDOMEGA_DEPLOY_KUMBAYA=1` pattern from #84. 2. OR a **post-deploy admin call wired into start-local-anvil-stack.sh** that calls `setBuyCooldownSec(1)` (or similar 1-second floor) on the deployed proxy when an env flag is set. Cooldown is already initialized via `_buyCooldownSec` in the constructor (TimeCurve.sol L259), so an owner setter would unlock this path. 3. OR a separate Anvil-only TimeCurve subclass that overrides `_requireCooldown()` to a no-op when `block.chainid == 31337`. Option 2 feels lightest if there's already a `setBuyCooldownSec` owner function or one can be added. ## Why this blocks QA - #38 DOUB Launch UX — F-05 buy charms test needs multiple buys to exercise different slider positions. Currently 5 min wait per buy = ~50 min for 10 test cases. - #39 TimeCurve QA checklist A/B/C — same pattern, multi-buy spread. - #82 lower/upper edge regression checklist — needs at least 4 distinct buys (CL8Y near-min, CL8Y near-max, Kumbaya near-min, Kumbaya near-max), can't multiplex across wallets without funding overhead. - Browser walkthrough sessions — multi-flow verification stalls behind cooldowns. Workaround today is funding multiple wallets with CL8Y/ETH via `cast send` + switching MetaMask between them, but each wallet switch causes its own MM nonce-tracking issues (see #84-followup observations) so it's a wash on time saved. ## Acceptance criteria - An env-flag-gated path that lets the local Anvil stack come up with effective cooldown ≤ 1 second. - Default behavior unchanged (5 min cooldown stays in place when flag not set). - Forge tests covering both cooldown-on and cooldown-off configurations to prevent accidental config drift. - Doc note in `docs/testing/e2e-anvil.md` (or wherever the Kumbaya flag is documented) explaining when to enable it. ## Severity P2-medium. Not a launch-blocker for mainnet (production cooldown is correct), purely a QA throughput fix. But TGE in 2 days = high time-pressure on checklist completion, so prioritizing this would compound across multiple open verification issues. Filed at dev request. cc @PlasticDigits
PlasticDigits commented 2026-04-29 03:12:47 +00:00 (Migrated from gitlab.com)

Should allow a flag on the infra set for testing that passes 1s to constructor for wallet cd, so if not already the constructor (init for proxy) shoudl consume a cd time in seconds

Should allow a flag on the infra set for testing that passes 1s to constructor for wallet cd, so if not already the constructor (init for proxy) shoudl consume a cd time in seconds
PlasticDigits commented 2026-04-29 03:35:03 +00:00 (Migrated from gitlab.com)

mentioned in commit 799cf6f1d4

mentioned in commit 799cf6f1d429626a38edf547205c78878e7e7abd
PlasticDigits commented 2026-04-29 03:35:15 +00:00 (Migrated from gitlab.com)

Shipped on main (799cf6f)

Implemented env-gated DeployDev TimeCurve buyCooldownSec for local Anvil QA throughput (DeployDevBuyCooldown.sol, consumed from DeployDev.s.sol).

Flags

  • YIELDOMEGA_DEPLOY_NO_COOLDOWN=1 → initializer uses YIELDOMEGA_ANVIL_BUY_COOLDOWN_SEC default 1 when unset (still > 0 for TimeCurve.initialize).
  • YIELDOMEGA_ANVIL_BUY_COOLDOWN_SEC=<n> → explicit seconds in either branch (must be > 0).

Docs / skills

Leaving issue open for sign-off.


@brouie — could you verify on a fresh Anvil stack?

Verification checklist

  1. Default unchanged: bash scripts/start-local-anvil-stack.sh (no flags) → cast call <TimeCurveProxy> "buyCooldownSec()(uint256)" --rpc-url http://127.0.0.1:8545 returns 300.
  2. Short cooldown: YIELDOMEGA_DEPLOY_NO_COOLDOWN=1 bash scripts/start-local-anvil-stack.sh (or export before forge script … DeployDev) → same cast call returns 1 (or your explicit YIELDOMEGA_ANVIL_BUY_COOLDOWN_SEC).
  3. Two buys, one wallet: with flag on, two buy txs from the same funded account succeed after ~1s wall time (or your chosen ANVIL seconds) without TimeCurve: buy cooldown revert.
  4. Reject zero: YIELDOMEGA_ANVIL_BUY_COOLDOWN_SEC=0 → forge script … DeployDev fails before broadcast with DeployDev: buy cooldown sec must be > 0.
  5. Regression: FOUNDRY_PROFILE=ci forge test (or CI) stays green.

Thanks!

## Shipped on `main` (799cf6f) Implemented **env-gated `DeployDev` TimeCurve `buyCooldownSec`** for local Anvil QA throughput ([`DeployDevBuyCooldown.sol`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/contracts/script/DeployDevBuyCooldown.sol), consumed from [`DeployDev.s.sol`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/contracts/script/DeployDev.s.sol)). **Flags** - `YIELDOMEGA_DEPLOY_NO_COOLDOWN=1` → initializer uses `YIELDOMEGA_ANVIL_BUY_COOLDOWN_SEC` default **1** when unset (still **> 0** for `TimeCurve.initialize`). - `YIELDOMEGA_ANVIL_BUY_COOLDOWN_SEC=<n>` → explicit seconds in either branch (**must be > 0**). **Docs / skills** - Runbook: [`docs/testing/e2e-anvil.md` — Anvil DeployDev buy cooldown](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/docs/testing/e2e-anvil.md#anvil-deploydev-buy-cooldown-gitlab-88) - Invariants: [`docs/testing/invariants-and-business-logic.md` — DeployDev buy cooldown env](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/docs/testing/invariants-and-business-logic.md#deploydev-buy-cooldown-env-issue-88) - Play checklist: [`skills/verify-yo-anvil-buy-cooldown/SKILL.md`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/skills/verify-yo-anvil-buy-cooldown/SKILL.md) - Forge: `test_readBuyCooldownSec_env_resolution_matrix` in [`DeployDevBuyCooldown.t.sol`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/contracts/test/DeployDevBuyCooldown.t.sol) (full suite: `FOUNDRY_PROFILE=ci forge test`). Leaving issue **open** for sign-off. --- @brouie — could you verify on a fresh Anvil stack? ### Verification checklist 1. **Default unchanged:** `bash scripts/start-local-anvil-stack.sh` (no flags) → `cast call <TimeCurveProxy> "buyCooldownSec()(uint256)" --rpc-url http://127.0.0.1:8545` returns **300**. 2. **Short cooldown:** `YIELDOMEGA_DEPLOY_NO_COOLDOWN=1 bash scripts/start-local-anvil-stack.sh` (or export before `forge script … DeployDev`) → same `cast call` returns **1** (or your explicit `YIELDOMEGA_ANVIL_BUY_COOLDOWN_SEC`). 3. **Two buys, one wallet:** with flag on, two `buy` txs from the same funded account succeed after ~1s wall time (or your chosen `ANVIL` seconds) without `TimeCurve: buy cooldown` revert. 4. **Reject zero:** `YIELDOMEGA_ANVIL_BUY_COOLDOWN_SEC=0` → `forge script … DeployDev` fails before broadcast with `DeployDev: buy cooldown sec must be > 0`. 5. **Regression:** `FOUNDRY_PROFILE=ci forge test` (or CI) stays green. Thanks!
Brouie commented 2026-04-29 04:50:29 +00:00 (Migrated from gitlab.com)

Verified 799cf6f against all 5 acceptance items. Closing.

Item 1 - Default unchanged

bash scripts/start-local-anvil-stack.sh (no flags, fresh stack from earlier today before #88 pull):

cast call 0x59b670e9fA9D0A427751Af201D676719a970857b "buyCooldownSec()(uint256)" --rpc-url http://127.0.0.1:8545

  • 300

PASS, default behavior preserved.

Item 2 - Short cooldown via flag

Killed previous stack, full rebuild on 799cf6f with YIELDOMEGA_DEPLOY_NO_COOLDOWN=1:

YIELDOMEGA_DEPLOY_NO_COOLDOWN=1 SKIP_ANVIL_RICH_STATE=1 YIELDOMEGA_DEPLOY_KUMBAYA=1 bash scripts/start-local-anvil-stack.sh

Stack output confirmed the override path was engaged:
"TimeCurve buyCooldownSec override (GitLab #88): YIELDOMEGA_DEPLOY_NO_COOLDOWN=1 YIELDOMEGA_ANVIL_BUY_COOLDOWN_SEC="

cast call 0x59b670e9fA9D0A427751Af201D676719a970857b "buyCooldownSec()(uint256)" --rpc-url http://127.0.0.1:8545

  • 1

PASS, default 1s when YIELDOMEGA_ANVIL_BUY_COOLDOWN_SEC unset.

Item 3 - Two buys, one wallet, no cooldown revert

Same stack, deployer wallet 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266:

approve CL8Y on TimeCurve proxy (status 1 success), then:

buy 1: cast send TimeCurve "buy(uint256)" 1500000000000000000 ... -> status 1 (success), Buy event emitted, fee router routes captured in logs (DOUB/CL8Y LP, dEaD burn, podium pool, team, treasury all present)

buy 2 immediately back-to-back: REVERTED with "TimeCurve: buy cooldown" - this was actually correct, cast send pairs run sub-second so the 1s cooldown was still active.

After sleep 2, retry buy 2:
cast send TimeCurve "buy(uint256)" 1500000000000000000 ... -> status 1 (success)

PASS. The 1s cooldown is real and enforced; my back-to-back broke it because cast send is faster than 1s. After the 2s wait both buys land cleanly. This is exactly the throughput improvement vs 5min default the issue was filed for.

Item 4 - Reject zero pre-broadcast

YIELDOMEGA_ANVIL_BUY_COOLDOWN_SEC=0 forge script script/DeployDev.s.sol --tc DeployDev --rpc-url http://127.0.0.1:8545

Result:
"Error: script failed: DeployDev: buy cooldown sec must be > 0"

The script ran the early-stage DeployDev simulation (Doubloon, PodiumPool, FeeRouter etc dry-run echoed in logs) but aborted at the validation step with the exact spec error message before any --broadcast would have hit chain. PASS.

Item 5 - Forge regression suite green

Dedicated test:
FOUNDRY_PROFILE=ci forge test --match-path "test/DeployDevBuyCooldown.t.sol"

  • test_constants_match_documented_defaults() PASS
  • test_readBuyCooldownSec_env_resolution_matrix() PASS
  • 2 passed, 0 failed

Full ci suite:
FOUNDRY_PROFILE=ci forge test

  • 22 test suites, 205 tests passed, 0 failed, 0 skipped, 2.32s

PASS, no regressions.

Close

All 5 items verified clean. The env-gated DeployDev cooldown override does what was asked and unblocks the multi-buy QA flows that were behind the 5-min wait. Big quality-of-life win for the remaining checklist items today (38, 39).

cc @PlasticDigits

Verified 799cf6f against all 5 acceptance items. Closing. ## Item 1 - Default unchanged bash scripts/start-local-anvil-stack.sh (no flags, fresh stack from earlier today before #88 pull): cast call 0x59b670e9fA9D0A427751Af201D676719a970857b "buyCooldownSec()(uint256)" --rpc-url http://127.0.0.1:8545 - 300 PASS, default behavior preserved. ## Item 2 - Short cooldown via flag Killed previous stack, full rebuild on 799cf6f with YIELDOMEGA_DEPLOY_NO_COOLDOWN=1: YIELDOMEGA_DEPLOY_NO_COOLDOWN=1 SKIP_ANVIL_RICH_STATE=1 YIELDOMEGA_DEPLOY_KUMBAYA=1 bash scripts/start-local-anvil-stack.sh Stack output confirmed the override path was engaged: "TimeCurve buyCooldownSec override (GitLab #88): YIELDOMEGA_DEPLOY_NO_COOLDOWN=1 YIELDOMEGA_ANVIL_BUY_COOLDOWN_SEC=<unset>" cast call 0x59b670e9fA9D0A427751Af201D676719a970857b "buyCooldownSec()(uint256)" --rpc-url http://127.0.0.1:8545 - 1 PASS, default 1s when YIELDOMEGA_ANVIL_BUY_COOLDOWN_SEC unset. ## Item 3 - Two buys, one wallet, no cooldown revert Same stack, deployer wallet 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266: approve CL8Y on TimeCurve proxy (status 1 success), then: buy 1: cast send TimeCurve "buy(uint256)" 1500000000000000000 ... -> status 1 (success), Buy event emitted, fee router routes captured in logs (DOUB/CL8Y LP, dEaD burn, podium pool, team, treasury all present) buy 2 immediately back-to-back: REVERTED with "TimeCurve: buy cooldown" - this was actually correct, cast send pairs run sub-second so the 1s cooldown was still active. After sleep 2, retry buy 2: cast send TimeCurve "buy(uint256)" 1500000000000000000 ... -> status 1 (success) PASS. The 1s cooldown is real and enforced; my back-to-back broke it because cast send is faster than 1s. After the 2s wait both buys land cleanly. This is exactly the throughput improvement vs 5min default the issue was filed for. ## Item 4 - Reject zero pre-broadcast YIELDOMEGA_ANVIL_BUY_COOLDOWN_SEC=0 forge script script/DeployDev.s.sol --tc DeployDev --rpc-url http://127.0.0.1:8545 Result: "Error: script failed: DeployDev: buy cooldown sec must be > 0" The script ran the early-stage DeployDev simulation (Doubloon, PodiumPool, FeeRouter etc dry-run echoed in logs) but aborted at the validation step with the exact spec error message before any --broadcast would have hit chain. PASS. ## Item 5 - Forge regression suite green Dedicated test: FOUNDRY_PROFILE=ci forge test --match-path "test/DeployDevBuyCooldown.t.sol" - test_constants_match_documented_defaults() PASS - test_readBuyCooldownSec_env_resolution_matrix() PASS - 2 passed, 0 failed Full ci suite: FOUNDRY_PROFILE=ci forge test - 22 test suites, 205 tests passed, 0 failed, 0 skipped, 2.32s PASS, no regressions. ## Close All 5 items verified clean. The env-gated DeployDev cooldown override does what was asked and unblocks the multi-buy QA flows that were behind the 5-min wait. Big quality-of-life win for the remaining checklist items today (38, 39). cc @PlasticDigits
Brouie (Migrated from gitlab.com) closed this issue 2026-04-29 04:50:31 +00:00
Brouie commented 2026-04-29 04:58:45 +00:00 (Migrated from gitlab.com)

mentioned in issue #58

mentioned in issue #58
Brouie commented 2026-04-29 06:08:51 +00:00 (Migrated from gitlab.com)

mentioned in issue #39

mentioned in issue #39
PlasticDigits commented 2026-04-30 05:05:48 +00:00 (Migrated from gitlab.com)

mentioned in issue #99

mentioned in issue #99
PlasticDigits commented 2026-04-30 05:25:09 +00:00 (Migrated from gitlab.com)

mentioned in issue #100

mentioned in issue #100
PlasticDigits commented 2026-05-01 06:11:32 +00:00 (Migrated from gitlab.com)

mentioned in issue #104

mentioned in issue #104
PlasticDigits commented 2026-05-05 13:57:31 +00:00 (Migrated from gitlab.com)

mentioned in issue #162

mentioned in issue #162
PlasticDigits commented 2026-05-13 16:07:17 +00:00 (Migrated from gitlab.com)

mentioned in issue #207

mentioned in issue #207
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
code/yieldomega#88
No description provided.