Verification: #65 TimeCurveBuyRouter — live router-set state via DeployKumbayaAnvilFixtures #78

Closed
opened 2026-04-27 04:11:37 +00:00 by Brouie · 15 comments
Brouie commented 2026-04-27 04:11:37 +00:00 (Migrated from gitlab.com)

Follow-up tracker for the live-stack items deferred from #65 source closure on Monday 2026-04-27.

Background

#65 closed today on source + selective live verification:

  • forge test --match-contract TimeCurveBuyRouterTest: 3/3 passing (test_buyViaKumbaya_stable_creditsAlice, test_buyViaKumbaya_eth_creditsAlice, test_buyFor_revertsWhenRouterUnset)
  • forge: 191/191 full suite passing
  • Live cast confirmed AC2 default state and AC4 unauthorized-call revert on the default stack
  • AnvilKumbayaFixture.sol L109 documents walk-from-CL8Y-output direction for multi-hop exactOutput (AC3)
  • TimeCurve.sol L344 _buyForExternal gate: require(msg.sender == timeCurveBuyRouter && timeCurveBuyRouter != address(0), 'TimeCurve: not buy router')

Scope (deferred)

The default scripts/start-local-anvil-stack.sh and contracts/script/anvil_rich_state.sh do NOT call DeployKumbayaAnvilFixtures, so timeCurveBuyRouter remains 0 on a fresh stack. The router-set verification items need that fixtures script run separately.

  • Run DeployKumbayaAnvilFixtures: confirm console logs TimeCurveBuyRouter address (KUMBAYA_BUY_ROUTER per anvil_deploy_dev.sh L13/L59)
  • cast call timeCurveBuyRouter() on TimeCurve proxy returns the deployed router address (not zero)
  • Live USDM two-hop quoteExactOutput sanity: quote for CL8Y←WETH←USDM matches actual exactOutput execution within rounding
  • Live buyViaKumbaya tx via the deployed router: produces Buy event with correct buyer attribution (msg.sender=router, but Buy.buyer=participant)
  • Owner setTimeCurveBuyRouter(address(0)) live: subsequent buyFor reverts with 'TimeCurve: not buy router' even from previously-set router address (re-disable path)
  • Confirm Buy event flagPlanted field correctly mirrors plantWarBowFlag arg passed through buyFor → _buy

Pre-conditions

  • Live Anvil stack on 1bdbda8+
  • DeployKumbayaAnvilFixtures executed (manual until / unless folded into start-local-anvil-stack.sh)
  • Wallet for participant txs

Acceptance

All 6 rows produce evidence (cast output, tx hash, or event receipt screenshot) and either PASS or have a filed sub-issue. cc @PlasticDigits

Follow-up tracker for the live-stack items deferred from #65 source closure on Monday 2026-04-27. ## Background #65 closed today on source + selective live verification: - forge test --match-contract TimeCurveBuyRouterTest: 3/3 passing (test_buyViaKumbaya_stable_creditsAlice, test_buyViaKumbaya_eth_creditsAlice, test_buyFor_revertsWhenRouterUnset) - forge: 191/191 full suite passing - Live cast confirmed AC2 default state and AC4 unauthorized-call revert on the default stack - AnvilKumbayaFixture.sol L109 documents walk-from-CL8Y-output direction for multi-hop exactOutput (AC3) - TimeCurve.sol L344 _buyForExternal gate: require(msg.sender == timeCurveBuyRouter && timeCurveBuyRouter != address(0), 'TimeCurve: not buy router') ## Scope (deferred) The default scripts/start-local-anvil-stack.sh and contracts/script/anvil_rich_state.sh do NOT call DeployKumbayaAnvilFixtures, so timeCurveBuyRouter remains 0 on a fresh stack. The router-set verification items need that fixtures script run separately. - [ ] Run DeployKumbayaAnvilFixtures: confirm console logs TimeCurveBuyRouter address (KUMBAYA_BUY_ROUTER per anvil_deploy_dev.sh L13/L59) - [ ] cast call timeCurveBuyRouter() on TimeCurve proxy returns the deployed router address (not zero) - [ ] Live USDM two-hop quoteExactOutput sanity: quote for CL8Y←WETH←USDM matches actual exactOutput execution within rounding - [ ] Live buyViaKumbaya tx via the deployed router: produces Buy event with correct buyer attribution (msg.sender=router, but Buy.buyer=participant) - [ ] Owner setTimeCurveBuyRouter(address(0)) live: subsequent buyFor reverts with 'TimeCurve: not buy router' even from previously-set router address (re-disable path) - [ ] Confirm Buy event flagPlanted field correctly mirrors plantWarBowFlag arg passed through buyFor → _buy ## Pre-conditions - Live Anvil stack on 1bdbda8+ - DeployKumbayaAnvilFixtures executed (manual until / unless folded into start-local-anvil-stack.sh) - Wallet for participant txs ## Acceptance All 6 rows produce evidence (cast output, tx hash, or event receipt screenshot) and either PASS or have a filed sub-issue. cc @PlasticDigits
Brouie commented 2026-04-27 04:12:19 +00:00 (Migrated from gitlab.com)

mentioned in issue #65

mentioned in issue #65
PlasticDigits commented 2026-04-27 04:41:42 +00:00 (Migrated from gitlab.com)

mentioned in commit 54e6ad92b4

mentioned in commit 54e6ad92b43e81d61e6f4b5ab2606396919a60b1
PlasticDigits commented 2026-04-27 04:41:57 +00:00 (Migrated from gitlab.com)

Fix pushed (issue #78)

Implemented the deferred #65 TimeCurveBuyRouter Anvil scope checklist as an automated path so it is no longer manual-only.

What shipped

  • scripts/verify-timecurve-buy-router-anvil.sh — optional YIELDOMEGA_DEPLOY_KUMBAYA=1 broadcasts DeployKumbayaAnvilFixtures when timeCurveBuyRouter() is zero; cast for router; guards on ended(); then sets YIELDOMEGA_FORK_VERIFY=1 and runs the fork test.
  • contracts/test/VerifyTimeCurveBuyRouterAnvil.t.sol — forked forge test: USDM two-hop quoteExactOutput vs exactOutput (≤1 wei delta), buyViaKumbaya stable (CHARM + WarBow opt-out), second buy with opt-in (warbowPendingFlagOwner mirrors Buy.flagPlanted intent), setTimeCurveBuyRouter(0) + buyFor revert. Without YIELDOMEGA_FORK_VERIFY, the test no-ops so default CI forge test is unchanged.
  • Docs + crosslinks: docs/testing/invariants-and-business-logic.md (#78 anchor), docs/integrations/kumbaya.md (corrected: start-local-anvil-stack = DeployDev only; e2e-anvil / anvil_deploy_dev = fixtures), e2e-anvil.md, local-swap-testing.md, .cursor/skills/yieldomega-guardrails, skills/verify-yo-timecurve-buy-router-anvil/SKILL.md, skills/README.md.

Verify checklist (for @brouie)

  • Live sale: stack with TimeCurve.ended() == false (e.g. SKIP_ANVIL_RICH_STATE=1 with start-local, or fresh anvil + DeployDev); script exits if sale ended.
  • Router path: bash scripts/verify-timecurve-buy-router-anvil.sh with RPC_URL pointing at anvil; if buy router is 0, use YIELDOMEGA_DEPLOY_KUMBAYA=1 once.
  • Green output: forge reports test_Forked_issue78_TimeCurveBuyRouter_checklist PASS.
  • Spot-check: cast call line in script output shows non-zero timeCurveBuyRouter after fixtures.
  • Unit regression: forge test --match-contract TimeCurveBuyRouterTest still 3/3 (unchanged contracts).

Commit: 54e6ad9 on main. Issue left open per request for your signoff.

## Fix pushed (issue #78) Implemented the deferred **#65 TimeCurveBuyRouter** Anvil scope checklist as an automated path so it is no longer manual-only. ### What shipped - **`scripts/verify-timecurve-buy-router-anvil.sh`** — optional `YIELDOMEGA_DEPLOY_KUMBAYA=1` broadcasts `DeployKumbayaAnvilFixtures` when `timeCurveBuyRouter()` is zero; `cast` for router; guards on `ended()`; then sets `YIELDOMEGA_FORK_VERIFY=1` and runs the fork test. - **`contracts/test/VerifyTimeCurveBuyRouterAnvil.t.sol`** — forked `forge test`: USDM two-hop `quoteExactOutput` vs `exactOutput` (≤1 wei delta), `buyViaKumbaya` stable (CHARM + WarBow opt-out), second buy with opt-in (`warbowPendingFlagOwner` mirrors `Buy.flagPlanted` intent), `setTimeCurveBuyRouter(0)` + `buyFor` revert. Without `YIELDOMEGA_FORK_VERIFY`, the test no-ops so default CI `forge test` is unchanged. - **Docs + crosslinks:** `docs/testing/invariants-and-business-logic.md` (#78 anchor), `docs/integrations/kumbaya.md` (corrected: **start-local-anvil-stack** = DeployDev only; **e2e-anvil** / **anvil_deploy_dev** = fixtures), `e2e-anvil.md`, `local-swap-testing.md`, `.cursor/skills/yieldomega-guardrails`, `skills/verify-yo-timecurve-buy-router-anvil/SKILL.md`, `skills/README.md`. ### Verify checklist (for @brouie) - [ ] **Live sale:** stack with `TimeCurve.ended() == false` (e.g. `SKIP_ANVIL_RICH_STATE=1` with start-local, or fresh anvil + DeployDev); script exits if sale ended. - [ ] **Router path:** `bash scripts/verify-timecurve-buy-router-anvil.sh` with `RPC_URL` pointing at anvil; if buy router is 0, use `YIELDOMEGA_DEPLOY_KUMBAYA=1` once. - [ ] **Green output:** forge reports `test_Forked_issue78_TimeCurveBuyRouter_checklist` PASS. - [ ] **Spot-check:** `cast call` line in script output shows non-zero `timeCurveBuyRouter` after fixtures. - [ ] **Unit regression:** `forge test --match-contract TimeCurveBuyRouterTest` still 3/3 (unchanged contracts). **Commit:** 54e6ad9 on `main`. Issue left **open** per request for your signoff.
Brouie commented 2026-04-27 05:07:21 +00:00 (Migrated from gitlab.com)

@PlasticDigits verified on 54e6ad9.

Verify-script execution (clean stack)

pkill -f timecurve_bot; pkill -9 -f anvil; sleep 2
SKIP_ANVIL_RICH_STATE=1 bash scripts/start-local-anvil-stack.sh
YIELDOMEGA_DEPLOY_KUMBAYA=1 bash scripts/verify-timecurve-buy-router-anvil.sh

Output:

  • DeployKumbayaAnvilFixtures broadcast successful (4543543 estimated gas)
  • Deployed TimeCurveBuyRouter: 0x998abeb3E57409262aE5b751f60747921B33613E
  • cast call timeCurveBuyRouter() returns the deployed router address (matches above)
  • forge test --fork PASS: test_Forked_issue78_TimeCurveBuyRouter_checklist (gas: 1219379)

That covers your 6 verify-checklist items in a single automated path.

Unit regression

cd contracts && FOUNDRY_PROFILE=ci forge test --match-contract TimeCurveBuyRouterTest:

  • 3/3 passing (unchanged contracts confirmed)

Stack-state collision caveat (worth noting for future runs)

First attempt failed because I had a swarm running from earlier #73 verification — anvil account #1 (Foundry default ALICE used by the test) had accumulated ~0.99e18 charmWeight from swarm buys, which collides with the test's '1e18 expected after buyViaKumbaya' assertion (got 1.99e18).

Restarted from clean stack (no swarm) and the verify ran green. Worth a one-line note in the script header or skill SKILL.md that the verify path expects an idle stack. Not blocking, just useful future-context.

Closing #78.

@PlasticDigits verified on 54e6ad9. ## Verify-script execution (clean stack) ``` pkill -f timecurve_bot; pkill -9 -f anvil; sleep 2 SKIP_ANVIL_RICH_STATE=1 bash scripts/start-local-anvil-stack.sh YIELDOMEGA_DEPLOY_KUMBAYA=1 bash scripts/verify-timecurve-buy-router-anvil.sh ``` Output: - DeployKumbayaAnvilFixtures broadcast successful (4543543 estimated gas) - Deployed TimeCurveBuyRouter: 0x998abeb3E57409262aE5b751f60747921B33613E - cast call timeCurveBuyRouter() returns the deployed router address (matches above) - forge test --fork PASS: test_Forked_issue78_TimeCurveBuyRouter_checklist (gas: 1219379) That covers your 6 verify-checklist items in a single automated path. ## Unit regression cd contracts && FOUNDRY_PROFILE=ci forge test --match-contract TimeCurveBuyRouterTest: - 3/3 passing (unchanged contracts confirmed) ## Stack-state collision caveat (worth noting for future runs) First attempt failed because I had a swarm running from earlier #73 verification — anvil account #1 (Foundry default ALICE used by the test) had accumulated ~0.99e18 charmWeight from swarm buys, which collides with the test's '1e18 expected after buyViaKumbaya' assertion (got 1.99e18). Restarted from clean stack (no swarm) and the verify ran green. Worth a one-line note in the script header or skill SKILL.md that the verify path expects an idle stack. Not blocking, just useful future-context. Closing #78.
Brouie (Migrated from gitlab.com) closed this issue 2026-04-27 05:07:22 +00:00
PlasticDigits commented 2026-04-27 06:49:48 +00:00 (Migrated from gitlab.com)

mentioned in commit 04d5054b5e

mentioned in commit 04d5054b5e7857b3f888bc3094b82f125275c1fd
PlasticDigits commented 2026-04-27 06:50:07 +00:00 (Migrated from gitlab.com)

mentioned in issue #82

mentioned in issue #82
PlasticDigits commented 2026-04-27 07:24:01 +00:00 (Migrated from gitlab.com)

mentioned in issue #83

mentioned in issue #83
PlasticDigits commented 2026-04-28 03:21:40 +00:00 (Migrated from gitlab.com)

mentioned in issue #84

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

mentioned in issue #100

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

mentioned in issue #104

mentioned in issue #104
PlasticDigits commented 2026-05-04 04:15:32 +00:00 (Migrated from gitlab.com)

mentioned in issue #117

mentioned in issue #117
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
PlasticDigits commented 2026-05-29 03:24:01 +00:00 (Migrated from gitlab.com)

mentioned in issue #263

mentioned in issue #263
PlasticDigits commented 2026-05-29 08:24:35 +00:00 (Migrated from gitlab.com)

mentioned in issue #270

mentioned in issue #270
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#78
No description provided.