Deploy: TimeArenaBuyRouter on Anvil + setTimeArenaBuyRouter + default ETH E2E wiring #270

Closed
opened 2026-05-29 08:24:34 +00:00 by PlasticDigits · 9 comments
PlasticDigits commented 2026-05-29 08:24:34 +00:00 (Migrated from gitlab.com)

Summary

Automate local Anvil deployment of TimeArenaBuyRouter, wire TimeArena.setTimeArenaBuyRouter, and export VITE_KUMBAYA_TIME_ARENA_BUY_ROUTER so scripts/e2e-anvil.sh runs the ETH pay Playwright case without manual env. Closes the deploy gap left after onchain #251 and frontend #264.

Parent epic: #238. Related: #84 (registry + Vite merge), #78 (buy-router verification).


Current codebase

Onchain (done in #251)

  • TimeArenaBuyRouter.sol — buyViaKumbaya (ETH / stable / CL8Y → Kumbaya exactOutput → DOUB → TimeArena.buyFor). Paths end in DOUB (not CL8Y).
  • TimeArena.sol — timeArenaBuyRouter, setTimeArenaBuyRouter(address) (owner), buyFor restricted to router.

Deploy / scripts (gap)

  • DeployDev.s.sol deploys Arena v2 (TimeArena, vaults, Doubloon, etc.) and startArena() but does not deploy a buy router or call setTimeArenaBuyRouter.
  • DeployKumbayaAnvilFixtures.s.sol is referenced throughout docs and shell (scripts/lib/anvil_deploy_dev.sh, scripts/start-local-anvil-stack.sh, docs/integrations/kumbaya.md) but is not present under contracts/script/ (only DeployDev.s.sol and DeployProduction.s.sol exist today).
  • Legacy TimeCurveBuyRouter Solidity was retired; scripts still grep log lines for TimeCurveBuyRouter (single-tx and registry key TimeCurveBuyRouter (scripts/lib/kumbaya_local_anvil_env.sh).
  • scripts/e2e-anvil.sh runs DeployDev only; sets VITE_KUMBAYA_TIME_ARENA_BUY_ROUTER only when KUMBAYA_BUY_ROUTER is non-empty after optional YIELDOMEGA_DEPLOY_KUMBAYA=1 — which currently does not run in the default E2E path.
  • scripts/verify-time-arena-buy-router-anvil.sh is a stub (prints instructions, exits 0).

Frontend (done in #264)

  • ETH/USDM UI calls resolveTimeArenaBuyRouterForKumbayaSingleTx and submitArenaKumbayaSingleTxBuy when onchain timeArenaBuyRouter is set.
  • E2E anvil-arena-wallet-writes.spec.ts skips ETH pay unless VITE_KUMBAYA_TIME_ARENA_BUY_ROUTER (or legacy alias) is set at build time.

Fixtures

  • AnvilKumbayaFixture.sol — AnvilWETH9, AnvilMockUSDM, AnvilKumbayaRouter (swap + quoter) for local constant-product pools.

Why this is needed

  1. ETH E2E is not CI-realistic today — DOUB buy passes on Anvil; ETH pay is skipped unless operators manually deploy a router and export Vite env.
  2. Docs/scripts lie about DeployKumbayaAnvilFixtures — references assume a script that must be restored or replaced with an Arena v2 variant.
  3. Product parity — Arena v2 pay modes (docs/frontend/arena-views.md) require a non-zero timeArenaBuyRouter on devnet for integrators and agents running bash scripts/e2e-anvil.sh.

Constraints and guardrails

  • Dev-only: Buy-router deploy scripts must call DevOnlyChainGuard.assertDevScriptChain() (Anvil / MegaETH testnet only) — same as DeployDev (docs/contracts/foundry-and-megaeth.md).
  • Onchain authority unchanged: 40/30/30 DOUB routing, CHARM band, buyFor router gate — see docs/product/arena-v2.md and docs/testing/invariants-and-business-logic.md.
  • Do not reintroduce TimeCurve launchpad / TimeCurveBuyRouter as the Arena authority (#244).
  • Anvil pools: Router deploy must seed DOUB↔WETH and DOUB↔CL8Y (and USDM path) reserves on AnvilKumbayaRouter so exactOutput succeeds for ETH/USDM paths used by the frontend (#264).
  • doubSurplusRecipient: Use a documented dev sink (e.g. deployer or AdminSellVault) — constructor reverts on zero (#251).
  • Registry / indexer: Add TimeArenaBuyRouter to contracts/deployments/local-anvil-registry.json (and example JSON); optional BuyViaKumbaya decode follow-up — minimum: do not break existing Buy ingest.
  • AGPL-3.0; follow docs/testing/strategy.md.

Relevant files

Area Files
Contracts TimeArenaBuyRouter.sol, TimeArena.sol, AnvilKumbayaFixture.sol
Deploy script (new/restore) contracts/script/DeployKumbayaAnvilFixtures.s.sol (or DeployArenaKumbayaAnvilFixtures.s.sol)
Shell scripts/lib/anvil_deploy_dev.sh, scripts/e2e-anvil.sh, scripts/lib/kumbaya_local_anvil_env.sh, scripts/start-local-anvil-stack.sh, scripts/verify-time-arena-buy-router-anvil.sh
Registry contracts/deployments/local-anvil-registry.json, contracts/deployments/kumbaya-anvil-registry.example.json
ABI export contracts/script/export_abi_hashes.sh
Tests New contracts/test/TimeArenaBuyRouter*.t.sol (local + optional fork)
E2E frontend/e2e/anvil-arena-wallet-writes.spec.ts
Docs docs/integrations/kumbaya.md, docs/testing/e2e-anvil.md, docs/testing/local-swap-testing.md, skills/play-time-arena-doub/SKILL.md

  1. Add DeployKumbayaAnvilFixtures.s.sol (Arena v2)

    • Input: deployed TimeArena proxy address (from DeployDev).
    • Deploy: AnvilWETH9, AnvilMockUSDM, AnvilKumbayaRouter, TimeArenaBuyRouter (immutable args: arena, kumbaya router, doub, reserve/CL8Y token, WETH, USDM, surplus recipient, owner).
    • Seed pools with liquidity for DOUB exactOutput paths (ETH: DOUB←WETH; USDM: DOUB←WETH←USDM).
    • TimeArena.setTimeArenaBuyRouter(router) in same broadcast (deployer = owner).
    • Log parseable lines, e.g. TimeArenaBuyRouter (single-tx): 0x….
  2. Wire anvil_deploy_dev.sh

    • Default YIELDOMEGA_DEPLOY_KUMBAYA=1 for scripts/e2e-anvil.sh (or always run fixtures after DeployDev in that script only).
    • Parse TimeArenaBuyRouter log label; set KUMBAYA_BUY_ROUTER.
    • Assert: cast call $TA "timeArenaBuyRouter()(address)" equals deployed router.
  3. Registry + Vite helpers

    • Extend yieldomega_registry_merge_* for TimeArenaBuyRouter.
    • yieldomega_frontend_merge_kumbaya_vite_full: set VITE_KUMBAYA_TIME_ARENA_BUY_ROUTER (keep legacy VITE_KUMBAYA_TIMECURVE_BUY_ROUTER only if still needed for transitional tooling).
  4. Implement verify-time-arena-buy-router-anvil.sh

    • DeployDev + fixtures → onchain router match → optional forge test --match-contract TimeArenaBuyRouter → spot-check one buyViaKumbaya (ETH) on Anvil.
  5. Forge tests

    • Local: happy path ETH + USDM (mock router), StableIngressParity, bad path, paused arena, charm bounds, expired deadline.
    • Reuse patterns from retired TimeCurve buy-router tests if any exist in git history.
  6. E2E

    • Remove skip when e2e-anvil.sh always provides router env; document that YIELDOMEGA_DEPLOY_KUMBAYA=0 opts out.

Acceptance criteria

  • DeployKumbayaAnvilFixtures (or renamed equivalent) exists, passes DevOnlyChainGuard, and broadcasts on Anvil.
  • After default bash scripts/e2e-anvil.sh: TimeArena.timeArenaBuyRouter() is non-zero and equals deployed TimeArenaBuyRouter.
  • scripts/e2e-anvil.sh exports VITE_KUMBAYA_TIME_ARENA_BUY_ROUTER without manual steps.
  • Playwright ETH pay test in anvil-arena-wallet-writes.spec.ts runs (not skipped) on CI/local when using e2e-anvil.sh.
  • local-anvil-registry.json (or merge helper) includes TimeArenaBuyRouter when fixtures run.
  • verify-time-arena-buy-router-anvil.sh performs real checks (non-stub) and exits non-zero on failure.
  • Docs updated: kumbaya integration, e2e-anvil, local-swap-testing, play-time-arena-doub skill — no stale TimeCurveBuyRouter as Arena authority.

Test plan — functional paths

# Path Steps Expected
1 Default E2E deploy bash scripts/e2e-anvil.sh DeployDev + fixtures; router set; ETH E2E executes
2 Onchain wiring cast call timeArenaBuyRouter Matches logged router address
3 ETH buyViaKumbaya Anvil account, min CHARM, ETH pay Tx succeeds; Buy / BuyViaKumbaya event
4 USDM buyViaKumbaya Same with USDM path Succeeds when USDM pool seeded
5 DOUB direct (regression) CL8Y/DOUB pay mode, no router needed for pull Still works with router set
6 Opt-out YIELDOMEGA_DEPLOY_KUMBAYA=0 bash scripts/e2e-anvil.sh DOUB E2E passes; ETH test skipped with clear message
7 Stack script YIELDOMEGA_DEPLOY_KUMBAYA=1 bash scripts/start-local-anvil-stack.sh Registry + .env.local merged
8 Verify script bash scripts/verify-time-arena-buy-router-anvil.sh All checklist steps green

Automated: forge test --match-contract TimeArenaBuyRouter; frontend build unchanged; optional indexer cargo test if registry decode extended.


Test plan — attack / abuse vectors

Vector Test Expected mitigation
Wrong router wired Deploy script points setTimeArenaBuyRouter at non-router contract Script verifies buyViaKumbaya selector or post-deploy smoke call
Router not owner-gated Only deployer/owner can call setTimeArenaBuyRouter on prod paths Anvil uses deployer key only; document prod runbook separately
Malicious setTimeArenaBuyRouter on Anvil User cannot call setTimeArenaBuyRouter without owner cast send from random key reverts
Under-liquidity pool exactOutput with empty reserves Deploy script seeds min reserves; test reverts with slippage/insufficient
Stable fee-on-transfer Mock deflationary stable (if added) StableIngressParity revert on router
Env/router mismatch Frontend env ≠ onchain #264 fail-closed in UI; deploy sets both consistently
Mainnet mistaken deploy Run fixture script against 4326 DevOnlyChainGuard reverts

Verification criteria

  • forge test green for new TimeArenaBuyRouter suite.
  • bash scripts/e2e-anvil.sh green including ETH wallet-write spec.
  • cast call spot-check: router address, paused()==false, arena live.
  • Grep: DeployKumbayaAnvilFixtures references resolve to an existing .s.sol file.
  • Manual: docs/testing/manual-qa-checklists.md Arena ETH/USDM rows (if present) pass on Anvil.
  • Production deploy explicitly out of scope — separate mainnet registry issue.
## Summary Automate **local Anvil** deployment of **`TimeArenaBuyRouter`**, wire **`TimeArena.setTimeArenaBuyRouter`**, and export **`VITE_KUMBAYA_TIME_ARENA_BUY_ROUTER`** so **`scripts/e2e-anvil.sh`** runs the ETH pay Playwright case **without manual env**. Closes the deploy gap left after onchain [#251](https://gitlab.com/PlasticDigits/yieldomega/-/issues/251) and frontend [#264](https://gitlab.com/PlasticDigits/yieldomega/-/issues/264). Parent epic: [#238](https://gitlab.com/PlasticDigits/yieldomega/-/issues/238). Related: [#84](https://gitlab.com/PlasticDigits/yieldomega/-/issues/84) (registry + Vite merge), [#78](https://gitlab.com/PlasticDigits/yieldomega/-/issues/78) (buy-router verification). --- ## Current codebase ### Onchain (done in #251) - **[`TimeArenaBuyRouter.sol`](contracts/src/arena/TimeArenaBuyRouter.sol)** — `buyViaKumbaya` (ETH / stable / CL8Y → Kumbaya `exactOutput` → DOUB → `TimeArena.buyFor`). Paths end in **DOUB** (not CL8Y). - **[`TimeArena.sol`](contracts/src/arena/TimeArena.sol)** — `timeArenaBuyRouter`, `setTimeArenaBuyRouter(address)` (owner), `buyFor` restricted to router. ### Deploy / scripts (gap) - **[`DeployDev.s.sol`](contracts/script/DeployDev.s.sol)** deploys Arena v2 (`TimeArena`, vaults, `Doubloon`, etc.) and **`startArena()`** but does **not** deploy a buy router or call **`setTimeArenaBuyRouter`**. - **`DeployKumbayaAnvilFixtures.s.sol`** is referenced throughout docs and shell (`scripts/lib/anvil_deploy_dev.sh`, `scripts/start-local-anvil-stack.sh`, `docs/integrations/kumbaya.md`) but is **not present** under [`contracts/script/`](contracts/script/) (only `DeployDev.s.sol` and `DeployProduction.s.sol` exist today). - Legacy **`TimeCurveBuyRouter`** Solidity was retired; scripts still grep log lines for **`TimeCurveBuyRouter (single-tx`** and registry key **`TimeCurveBuyRouter`** ([`scripts/lib/kumbaya_local_anvil_env.sh`](scripts/lib/kumbaya_local_anvil_env.sh)). - **[`scripts/e2e-anvil.sh`](scripts/e2e-anvil.sh)** runs **`DeployDev`** only; sets **`VITE_KUMBAYA_TIME_ARENA_BUY_ROUTER`** only when **`KUMBAYA_BUY_ROUTER`** is non-empty after optional **`YIELDOMEGA_DEPLOY_KUMBAYA=1`** — which currently does not run in the default E2E path. - **[`scripts/verify-time-arena-buy-router-anvil.sh`](scripts/verify-time-arena-buy-router-anvil.sh)** is a stub (prints instructions, exits 0). ### Frontend (done in #264) - ETH/USDM UI calls **`resolveTimeArenaBuyRouterForKumbayaSingleTx`** and **`submitArenaKumbayaSingleTxBuy`** when onchain **`timeArenaBuyRouter`** is set. - E2E [`anvil-arena-wallet-writes.spec.ts`](frontend/e2e/anvil-arena-wallet-writes.spec.ts) **skips** ETH pay unless **`VITE_KUMBAYA_TIME_ARENA_BUY_ROUTER`** (or legacy alias) is set at build time. ### Fixtures - **[`AnvilKumbayaFixture.sol`](contracts/src/fixtures/AnvilKumbayaFixture.sol)** — `AnvilWETH9`, `AnvilMockUSDM`, `AnvilKumbayaRouter` (swap + quoter) for local constant-product pools. --- ## Why this is needed 1. **ETH E2E is not CI-realistic today** — DOUB buy passes on Anvil; ETH pay is skipped unless operators manually deploy a router and export Vite env. 2. **Docs/scripts lie about `DeployKumbayaAnvilFixtures`** — references assume a script that must be restored or replaced with an Arena v2 variant. 3. **Product parity** — Arena v2 pay modes ([`docs/frontend/arena-views.md`](docs/frontend/arena-views.md)) require a non-zero **`timeArenaBuyRouter`** on devnet for integrators and agents running **`bash scripts/e2e-anvil.sh`**. --- ## Constraints and guardrails - **Dev-only:** Buy-router deploy scripts must call **`DevOnlyChainGuard.assertDevScriptChain()`** (Anvil / MegaETH testnet only) — same as **`DeployDev`** ([`docs/contracts/foundry-and-megaeth.md`](docs/contracts/foundry-and-megaeth.md)). - **Onchain authority unchanged:** 40/30/30 DOUB routing, CHARM band, `buyFor` router gate — see [`docs/product/arena-v2.md`](docs/product/arena-v2.md) and [`docs/testing/invariants-and-business-logic.md`](docs/testing/invariants-and-business-logic.md). - **Do not reintroduce** TimeCurve launchpad / **`TimeCurveBuyRouter`** as the Arena authority ([#244](https://gitlab.com/PlasticDigits/yieldomega/-/issues/244)). - **Anvil pools:** Router deploy must seed **DOUB↔WETH** and **DOUB↔CL8Y** (and USDM path) reserves on **`AnvilKumbayaRouter`** so `exactOutput` succeeds for ETH/USDM paths used by the frontend ([#264](https://gitlab.com/PlasticDigits/yieldomega/-/issues/264)). - **`doubSurplusRecipient`:** Use a documented dev sink (e.g. deployer or **`AdminSellVault`**) — constructor reverts on zero ([#251](https://gitlab.com/PlasticDigits/yieldomega/-/issues/251)). - **Registry / indexer:** Add **`TimeArenaBuyRouter`** to [`contracts/deployments/local-anvil-registry.json`](contracts/deployments/local-anvil-registry.json) (and example JSON); optional **`BuyViaKumbaya`** decode follow-up — minimum: do not break existing **`Buy`** ingest. - **AGPL-3.0**; follow [`docs/testing/strategy.md`](docs/testing/strategy.md). --- ## Relevant files | Area | Files | |------|--------| | **Contracts** | [`TimeArenaBuyRouter.sol`](contracts/src/arena/TimeArenaBuyRouter.sol), [`TimeArena.sol`](contracts/src/arena/TimeArena.sol), [`AnvilKumbayaFixture.sol`](contracts/src/fixtures/AnvilKumbayaFixture.sol) | | **Deploy script (new/restore)** | `contracts/script/DeployKumbayaAnvilFixtures.s.sol` (or `DeployArenaKumbayaAnvilFixtures.s.sol`) | | **Shell** | [`scripts/lib/anvil_deploy_dev.sh`](scripts/lib/anvil_deploy_dev.sh), [`scripts/e2e-anvil.sh`](scripts/e2e-anvil.sh), [`scripts/lib/kumbaya_local_anvil_env.sh`](scripts/lib/kumbaya_local_anvil_env.sh), [`scripts/start-local-anvil-stack.sh`](scripts/start-local-anvil-stack.sh), [`scripts/verify-time-arena-buy-router-anvil.sh`](scripts/verify-time-arena-buy-router-anvil.sh) | | **Registry** | [`contracts/deployments/local-anvil-registry.json`](contracts/deployments/local-anvil-registry.json), [`contracts/deployments/kumbaya-anvil-registry.example.json`](contracts/deployments/kumbaya-anvil-registry.example.json) | | **ABI export** | [`contracts/script/export_abi_hashes.sh`](contracts/script/export_abi_hashes.sh) | | **Tests** | New `contracts/test/TimeArenaBuyRouter*.t.sol` (local + optional fork) | | **E2E** | [`frontend/e2e/anvil-arena-wallet-writes.spec.ts`](frontend/e2e/anvil-arena-wallet-writes.spec.ts) | | **Docs** | [`docs/integrations/kumbaya.md`](docs/integrations/kumbaya.md), [`docs/testing/e2e-anvil.md`](docs/testing/e2e-anvil.md), [`docs/testing/local-swap-testing.md`](docs/testing/local-swap-testing.md), [`skills/play-time-arena-doub/SKILL.md`](skills/play-time-arena-doub/SKILL.md) | --- ## Recommended direction 1. **Add `DeployKumbayaAnvilFixtures.s.sol` (Arena v2)** - Input: deployed **`TimeArena`** proxy address (from **`DeployDev`**). - Deploy: `AnvilWETH9`, `AnvilMockUSDM`, `AnvilKumbayaRouter`, **`TimeArenaBuyRouter`** (immutable args: arena, kumbaya router, `doub`, reserve/CL8Y token, WETH, USDM, surplus recipient, owner). - Seed pools with liquidity for **DOUB** `exactOutput` paths (ETH: DOUB←WETH; USDM: DOUB←WETH←USDM). - **`TimeArena.setTimeArenaBuyRouter(router)`** in same broadcast (deployer = owner). - Log parseable lines, e.g. `TimeArenaBuyRouter (single-tx): 0x…`. 2. **Wire `anvil_deploy_dev.sh`** - Default **`YIELDOMEGA_DEPLOY_KUMBAYA=1`** for **`scripts/e2e-anvil.sh`** (or always run fixtures after `DeployDev` in that script only). - Parse **`TimeArenaBuyRouter`** log label; set **`KUMBAYA_BUY_ROUTER`**. - Assert: `cast call $TA "timeArenaBuyRouter()(address)"` equals deployed router. 3. **Registry + Vite helpers** - Extend **`yieldomega_registry_merge_*`** for **`TimeArenaBuyRouter`**. - **`yieldomega_frontend_merge_kumbaya_vite_full`**: set **`VITE_KUMBAYA_TIME_ARENA_BUY_ROUTER`** (keep legacy **`VITE_KUMBAYA_TIMECURVE_BUY_ROUTER`** only if still needed for transitional tooling). 4. **Implement `verify-time-arena-buy-router-anvil.sh`** - DeployDev + fixtures → onchain router match → optional `forge test --match-contract TimeArenaBuyRouter` → spot-check one `buyViaKumbaya` (ETH) on Anvil. 5. **Forge tests** - Local: happy path ETH + USDM (mock router), `StableIngressParity`, bad path, paused arena, charm bounds, expired deadline. - Reuse patterns from retired TimeCurve buy-router tests if any exist in git history. 6. **E2E** - Remove skip when **`e2e-anvil.sh`** always provides router env; document that **`YIELDOMEGA_DEPLOY_KUMBAYA=0`** opts out. --- ## Acceptance criteria - [ ] **`DeployKumbayaAnvilFixtures`** (or renamed equivalent) exists, passes **`DevOnlyChainGuard`**, and broadcasts on Anvil. - [ ] After default **`bash scripts/e2e-anvil.sh`**: `TimeArena.timeArenaBuyRouter()` is non-zero and equals deployed **`TimeArenaBuyRouter`**. - [ ] **`scripts/e2e-anvil.sh`** exports **`VITE_KUMBAYA_TIME_ARENA_BUY_ROUTER`** without manual steps. - [ ] Playwright **ETH pay** test in [`anvil-arena-wallet-writes.spec.ts`](frontend/e2e/anvil-arena-wallet-writes.spec.ts) runs (not skipped) on CI/local when using `e2e-anvil.sh`. - [ ] **`local-anvil-registry.json`** (or merge helper) includes **`TimeArenaBuyRouter`** when fixtures run. - [ ] **`verify-time-arena-buy-router-anvil.sh`** performs real checks (non-stub) and exits non-zero on failure. - [ ] Docs updated: kumbaya integration, e2e-anvil, local-swap-testing, play-time-arena-doub skill — no stale **`TimeCurveBuyRouter`** as Arena authority. --- ## Test plan — functional paths | # | Path | Steps | Expected | |---|------|--------|----------| | 1 | Default E2E deploy | `bash scripts/e2e-anvil.sh` | DeployDev + fixtures; router set; ETH E2E executes | | 2 | Onchain wiring | `cast call` `timeArenaBuyRouter` | Matches logged router address | | 3 | ETH `buyViaKumbaya` | Anvil account, min CHARM, ETH pay | Tx succeeds; `Buy` / `BuyViaKumbaya` event | | 4 | USDM `buyViaKumbaya` | Same with USDM path | Succeeds when USDM pool seeded | | 5 | DOUB direct (regression) | CL8Y/DOUB pay mode, no router needed for pull | Still works with router set | | 6 | Opt-out | `YIELDOMEGA_DEPLOY_KUMBAYA=0 bash scripts/e2e-anvil.sh` | DOUB E2E passes; ETH test skipped with clear message | | 7 | Stack script | `YIELDOMEGA_DEPLOY_KUMBAYA=1 bash scripts/start-local-anvil-stack.sh` | Registry + `.env.local` merged | | 8 | Verify script | `bash scripts/verify-time-arena-buy-router-anvil.sh` | All checklist steps green | **Automated:** `forge test --match-contract TimeArenaBuyRouter`; frontend build unchanged; optional indexer `cargo test` if registry decode extended. --- ## Test plan — attack / abuse vectors | Vector | Test | Expected mitigation | |--------|------|---------------------| | **Wrong router wired** | Deploy script points `setTimeArenaBuyRouter` at non-router contract | Script verifies `buyViaKumbaya` selector or post-deploy smoke call | | **Router not owner-gated** | Only deployer/owner can call `setTimeArenaBuyRouter` on prod paths | Anvil uses deployer key only; document prod runbook separately | | **Malicious `setTimeArenaBuyRouter` on Anvil** | User cannot call `setTimeArenaBuyRouter` without owner | `cast send` from random key reverts | | **Under-liquidity pool** | `exactOutput` with empty reserves | Deploy script seeds min reserves; test reverts with slippage/insufficient | | **Stable fee-on-transfer** | Mock deflationary stable (if added) | `StableIngressParity` revert on router | | **Env/router mismatch** | Frontend env ≠ onchain | [#264](https://gitlab.com/PlasticDigits/yieldomega/-/issues/264) fail-closed in UI; deploy sets both consistently | | **Mainnet mistaken deploy** | Run fixture script against 4326 | `DevOnlyChainGuard` reverts | --- ## Verification criteria - [ ] `forge test` green for new **`TimeArenaBuyRouter`** suite. - [ ] `bash scripts/e2e-anvil.sh` green including ETH wallet-write spec. - [ ] `cast call` spot-check: router address, `paused()==false`, arena live. - [ ] Grep: `DeployKumbayaAnvilFixtures` references resolve to an existing `.s.sol` file. - [ ] Manual: [`docs/testing/manual-qa-checklists.md`](docs/testing/manual-qa-checklists.md) Arena ETH/USDM rows (if present) pass on Anvil. - [ ] Production deploy explicitly **out of scope** — separate mainnet registry issue.
PlasticDigits commented 2026-05-29 09:09:08 +00:00 (Migrated from gitlab.com)

mentioned in commit 46d347b491

mentioned in commit 46d347b4916dd3c9d477ca0da825190c6d86a783
PlasticDigits commented 2026-05-29 09:09:08 +00:00 (Migrated from gitlab.com)

mentioned in commit 6616779e30

mentioned in commit 6616779e306acb997e42bb3ee4521ba669cc4b89
PlasticDigits commented 2026-05-29 09:09:21 +00:00 (Migrated from gitlab.com)

Summary (#270)

Implemented Arena v2 Kumbaya Anvil fixtures and default ETH pay E2E wiring on main (6616779).

Delivered

  • contracts/script/DeployKumbayaAnvilFixtures.s.sol — AnvilWETH9, AnvilMockUSDM, AnvilKumbayaRouter, TimeArenaBuyRouter, DOUB pool seeding, setTimeArenaBuyRouter, DevOnlyChainGuard.
  • scripts/e2e-anvil.sh — defaults YIELDOMEGA_DEPLOY_KUMBAYA=1, exports VITE_KUMBAYA_TIME_ARENA_BUY_ROUTER, kills stale Anvil on port before start.
  • scripts/lib/anvil_deploy_dev.sh + kumbaya_local_anvil_env.sh — parse TimeArenaBuyRouter, registry merge, Vite merge (legacy TimeCurveBuyRouter log alias kept).
  • scripts/verify-time-arena-buy-router-anvil.sh — real deploy + cast checks + forge test --match-contract TimeArenaBuyRouter.
  • contracts/test/TimeArenaBuyRouter.t.sol — ETH/USDM happy paths, stable ingress parity, revert cases.
  • Contract fix: TimeArena._buyDoub pulls DOUB from timeArenaBuyRouter when buyFor is used (was incorrectly pulling from buyer wallet).
  • Docs / invariants: INV-DEV-KUMBAYA-270-*, INV-TIME-ARENA-BUYFOR-PULL, local-swap-testing.md, e2e-anvil.md, skills/play-time-arena-doub/SKILL.md.

Verification checklist for @brouie

  • cd contracts && forge test --match-contract TimeArenaBuyRouter
  • bash scripts/verify-time-arena-buy-router-anvil.sh (fresh Anvil; exits 0)
  • YIELDOMEGA_DEPLOY_NO_COOLDOWN=1 bash scripts/e2e-anvil.sh — confirm log line TimeArenaBuyRouter=… and cast call $TA timeArenaBuyRouter()(address) matches
  • Playwright ETH case in frontend/e2e/anvil-arena-wallet-writes.spec.ts runs (not skipped) when router env is set
  • Opt-out: YIELDOMEGA_DEPLOY_KUMBAYA=0 bash scripts/e2e-anvil.sh — DOUB path still deploys; ETH test skipped with message
  • YIELDOMEGA_DEPLOY_KUMBAYA=1 bash scripts/start-local-anvil-stack.sh — local-anvil-registry.json includes TimeArenaBuyRouter

Notes

  • Anvil E2E wallet-write specs may still need arena checkout UI alignment (Buy CHARM CTA visibility) — separate from deploy/router wiring; please flag if DOUB/ETH clicks fail locally after the above.

@brouie — please verify on a clean Anvil run when you have a moment. Leaving issue open until confirmed.

## Summary (#270) Implemented Arena v2 **Kumbaya Anvil fixtures** and default ETH pay E2E wiring on `main` (6616779). ### Delivered - **`contracts/script/DeployKumbayaAnvilFixtures.s.sol`** — `AnvilWETH9`, `AnvilMockUSDM`, `AnvilKumbayaRouter`, **`TimeArenaBuyRouter`**, DOUB pool seeding, `setTimeArenaBuyRouter`, `DevOnlyChainGuard`. - **`scripts/e2e-anvil.sh`** — defaults `YIELDOMEGA_DEPLOY_KUMBAYA=1`, exports `VITE_KUMBAYA_TIME_ARENA_BUY_ROUTER`, kills stale Anvil on port before start. - **`scripts/lib/anvil_deploy_dev.sh`** + **`kumbaya_local_anvil_env.sh`** — parse `TimeArenaBuyRouter`, registry merge, Vite merge (legacy `TimeCurveBuyRouter` log alias kept). - **`scripts/verify-time-arena-buy-router-anvil.sh`** — real deploy + cast checks + `forge test --match-contract TimeArenaBuyRouter`. - **`contracts/test/TimeArenaBuyRouter.t.sol`** — ETH/USDM happy paths, stable ingress parity, revert cases. - **Contract fix:** `TimeArena._buyDoub` pulls DOUB from `timeArenaBuyRouter` when `buyFor` is used (was incorrectly pulling from buyer wallet). - **Docs / invariants:** `INV-DEV-KUMBAYA-270-*`, `INV-TIME-ARENA-BUYFOR-PULL`, `local-swap-testing.md`, `e2e-anvil.md`, `skills/play-time-arena-doub/SKILL.md`. ### Verification checklist for @brouie - [ ] `cd contracts && forge test --match-contract TimeArenaBuyRouter` - [ ] `bash scripts/verify-time-arena-buy-router-anvil.sh` (fresh Anvil; exits 0) - [ ] `YIELDOMEGA_DEPLOY_NO_COOLDOWN=1 bash scripts/e2e-anvil.sh` — confirm log line `TimeArenaBuyRouter=…` and `cast call $TA timeArenaBuyRouter()(address)` matches - [ ] Playwright ETH case in `frontend/e2e/anvil-arena-wallet-writes.spec.ts` runs (not skipped) when router env is set - [ ] Opt-out: `YIELDOMEGA_DEPLOY_KUMBAYA=0 bash scripts/e2e-anvil.sh` — DOUB path still deploys; ETH test skipped with message - [ ] `YIELDOMEGA_DEPLOY_KUMBAYA=1 bash scripts/start-local-anvil-stack.sh` — `local-anvil-registry.json` includes `TimeArenaBuyRouter` ### Notes - Anvil E2E wallet-write specs may still need arena checkout UI alignment (Buy CHARM CTA visibility) — separate from deploy/router wiring; please flag if DOUB/ETH clicks fail locally after the above. @brouie — please verify on a clean Anvil run when you have a moment. Leaving issue **open** until confirmed.
PlasticDigits commented 2026-05-29 09:43:29 +00:00 (Migrated from gitlab.com)

mentioned in issue #259

mentioned in issue #259
PlasticDigits commented 2026-06-01 09:58:34 +00:00 (Migrated from gitlab.com)

mentioned in commit 5079fde4d5

mentioned in commit 5079fde4d55a601d64db63ec563beda4202a7476
PlasticDigits commented 2026-06-01 09:58:34 +00:00 (Migrated from gitlab.com)

mentioned in commit 2baf79563f

mentioned in commit 2baf79563f0f6f99ab09abfebb254991bce95957
PlasticDigits commented 2026-06-01 09:58:43 +00:00 (Migrated from gitlab.com)

mentioned in issue #260

mentioned in issue #260
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-06-01 11:38:38 +00:00
PlasticDigits commented 2026-06-01 11:38:39 +00:00 (Migrated from gitlab.com)

QA verification (#270) — passed

Verified on branch main @ 096c6f9 using worktree issue/270-verify (clean Anvil, no code changes required).

What was run

  1. cd contracts && forge test --match-contract TimeArenaBuyRouter — 11/11 passed (TimeArenaBuyRouter.t.sol) + fork VerifyTimeArenaBuyRouterAnvil.t.sol::test_Forked_issue251_eth_usdm_cl8y_paths passed.
  2. bash scripts/verify-time-arena-buy-router-anvil.sh — fresh Anvil → DeployDev + DeployKumbayaAnvilFixtures → timeArenaBuyRouter matches logged TimeArenaBuyRouter; registry merge + Vite env; exit 0.
  3. YIELDOMEGA_DEPLOY_NO_COOLDOWN=1 bash scripts/e2e-anvil.sh — DeployDev + Kumbaya fixtures; log TimeArenaBuyRouter=0x1613…78E8; 6/6 Playwright passed including ETH pay (anvil-arena-03-wallet-writes.spec.ts — not skipped).
  4. Opt-out: YIELDOMEGA_DEPLOY_KUMBAYA=0 bash scripts/e2e-anvil.sh — DOUB + CRED paths pass; ETH case skipped with router message (5 passed, 1 skipped).
  5. Grep: all DeployKumbayaAnvilFixtures doc/script references resolve to contracts/script/DeployKumbayaAnvilFixtures.s.sol.

Acceptance criteria (issue body)

  • DeployKumbayaAnvilFixtures exists, DevOnlyChainGuard, broadcasts on Anvil
  • Default e2e-anvil.sh: timeArenaBuyRouter() non-zero and equals deployed router
  • VITE_KUMBAYA_TIME_ARENA_BUY_ROUTER exported without manual steps
  • Playwright ETH pay runs (not skipped) on default E2E path
  • local-anvil-registry.json includes TimeArenaBuyRouter after fixtures
  • verify-time-arena-buy-router-anvil.sh real checks, exit 0 on success
  • Docs/skills cross-linked (INV-DEV-KUMBAYA-270-*, e2e-anvil.md, local-swap-testing.md, play-time-arena-doub/SKILL.md); no stale TimeCurve authority

Verification checklist for follow-up

  • cd contracts && forge test --match-contract TimeArenaBuyRouter
  • bash scripts/verify-time-arena-buy-router-anvil.sh (fresh Anvil)
  • YIELDOMEGA_DEPLOY_NO_COOLDOWN=1 bash scripts/e2e-anvil.sh — confirm ETH wallet-write spec green
  • YIELDOMEGA_DEPLOY_KUMBAYA=0 bash scripts/e2e-anvil.sh — ETH skipped, DOUB green
  • YIELDOMEGA_DEPLOY_KUMBAYA=1 bash scripts/start-local-anvil-stack.sh — registry + .env.local (requires Postgres/docker stack)
  • Manual: Arena ETH/USDM pay rows in docs/testing/manual-qa-checklists.md on Anvil (optional; onchain covered by Forge + verify script)

Notes

  • start-local-anvil-stack.sh deploy/registry merge for Kumbaya succeeded; script exited 1 only because local Postgres container was not running (unrelated to router wiring).
  • No commits from this QA pass — implementation on main already satisfies #270.

Closing as all issue-body acceptance criteria and verification criteria pass.

## QA verification (#270) — passed Verified on branch `main` @ `096c6f9` using worktree `issue/270-verify` (clean Anvil, no code changes required). ### What was run 1. **`cd contracts && forge test --match-contract TimeArenaBuyRouter`** — 11/11 passed (`TimeArenaBuyRouter.t.sol`) + fork `VerifyTimeArenaBuyRouterAnvil.t.sol::test_Forked_issue251_eth_usdm_cl8y_paths` passed. 2. **`bash scripts/verify-time-arena-buy-router-anvil.sh`** — fresh Anvil → DeployDev + DeployKumbayaAnvilFixtures → `timeArenaBuyRouter` matches logged `TimeArenaBuyRouter`; registry merge + Vite env; exit 0. 3. **`YIELDOMEGA_DEPLOY_NO_COOLDOWN=1 bash scripts/e2e-anvil.sh`** — DeployDev + Kumbaya fixtures; log `TimeArenaBuyRouter=0x1613…78E8`; **6/6 Playwright passed** including **ETH pay** (`anvil-arena-03-wallet-writes.spec.ts` — not skipped). 4. **Opt-out:** `YIELDOMEGA_DEPLOY_KUMBAYA=0 bash scripts/e2e-anvil.sh` — DOUB + CRED paths pass; ETH case **skipped** with router message (5 passed, 1 skipped). 5. **Grep:** all `DeployKumbayaAnvilFixtures` doc/script references resolve to `contracts/script/DeployKumbayaAnvilFixtures.s.sol`. ### Acceptance criteria (issue body) - [x] `DeployKumbayaAnvilFixtures` exists, `DevOnlyChainGuard`, broadcasts on Anvil - [x] Default `e2e-anvil.sh`: `timeArenaBuyRouter()` non-zero and equals deployed router - [x] `VITE_KUMBAYA_TIME_ARENA_BUY_ROUTER` exported without manual steps - [x] Playwright ETH pay runs (not skipped) on default E2E path - [x] `local-anvil-registry.json` includes `TimeArenaBuyRouter` after fixtures - [x] `verify-time-arena-buy-router-anvil.sh` real checks, exit 0 on success - [x] Docs/skills cross-linked (`INV-DEV-KUMBAYA-270-*`, `e2e-anvil.md`, `local-swap-testing.md`, `play-time-arena-doub/SKILL.md`); no stale TimeCurve authority ### Verification checklist for follow-up - [ ] `cd contracts && forge test --match-contract TimeArenaBuyRouter` - [ ] `bash scripts/verify-time-arena-buy-router-anvil.sh` (fresh Anvil) - [ ] `YIELDOMEGA_DEPLOY_NO_COOLDOWN=1 bash scripts/e2e-anvil.sh` — confirm ETH wallet-write spec green - [ ] `YIELDOMEGA_DEPLOY_KUMBAYA=0 bash scripts/e2e-anvil.sh` — ETH skipped, DOUB green - [ ] `YIELDOMEGA_DEPLOY_KUMBAYA=1 bash scripts/start-local-anvil-stack.sh` — registry + `.env.local` (requires Postgres/docker stack) - [ ] Manual: Arena ETH/USDM pay rows in `docs/testing/manual-qa-checklists.md` on Anvil (optional; onchain covered by Forge + verify script) ### Notes - `start-local-anvil-stack.sh` deploy/registry merge for Kumbaya succeeded; script exited 1 only because local Postgres container was not running (unrelated to router wiring). - No commits from this QA pass — implementation on `main` already satisfies #270. Closing as all issue-body acceptance criteria and verification criteria pass.
PlasticDigits commented 2026-06-28 13:20:48 +00:00 (Migrated from gitlab.com)

mentioned in commit 55e57688e7

mentioned in commit 55e57688e7d4339a5fec5d27ccb6a9a88bca6eb9
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#270
No description provided.