Arena: TWAP-derived initial charmPriceWad (~$1 DOUB/CHARM) and DOUB spend band #303
Labels
No labels
agent:fix_bugfix
agent:fix_conflicts
agent:fix_security
agent:gap_analysis
agent:implement
agent:open_issues
agents
agent:security_audit
agent:verify
area
timecurve
arena
arena-v2
audit
block:feature_review
block:security
bug
contracts
design
devops
docs
documentation
enhancement
epic
feature
frontend
indexer
low priority
megaeth
operations
ops
performance
QA
qa checklist
referrals
removal
security
smart-contracts
tech-debt
testing
time-arena
timecurve
visual-qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
code/yieldomega#303
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Replace the hardcoded
charmPriceWad = 1000e18(1000 DOUB per 1 CHARM) production default with an initial price derived from Kumbaya V3 TWAP on the same DOUB↔WETH and WETH↔USDm pools Sir Trading uses, anchored so ~$1.00 USD of DOUB buys 1 CHARM at arena launch. The fixed onchain CHARM envelope (0.99–10 CHARM) stays unchanged; initial DOUB min/max spend for buys becomes a derived consequence of that TWAP-basedcharmPriceWad.Relates to existing
INV-TIME-ARENA-DOUB-PRICE(#246) and Kumbaya integration (#251, #264).Current codebase
Onchain CHARM price (flat admin rate, not a bonding curve)
TimeArena.charmPriceWad— DOUB wei owed per 1e18 CHARM:doubOwed = charmWad × charmPriceWad / 1e18(TimeArena.sol).1000e18everywhere production-like deploy runs:DeployProduction.s.sol—DEFAULT_CHARM_PRICE_WAD = 1000e18, overridable viaARENA_CHARM_PRICE_WAD.DeployDev.s.sol— hardcoded1000e18passed toUUPSDeployLib.deployTimeArenaProductionDefaults.PARAMETERS.md,docs/product/arena-v2.md,docs/product/time-arena.md.setCharmPriceWad(onlyOwner); no timelock today.CHARM_MIN_WAD = 99e16(0.99),CHARM_MAX_WAD = 10e18(10) —TimeArena.sol,ArenaXp.sol, frontendarenaConstants.ts.DOUB min/max spend (derived, not separate onchain params)
There is no
doubMin/doubMaxstorage slot. Spend band is computed:Used in:
timeArenaBuySubmitSizing.ts— submit-time sizing + headroom (#82).arenaV2SaleSessionBridge.ts— protocol accordion / envelope display.ArenaLiveBuysActivitySection.tsx— buy envelope fill ratio in activity feed.useArenaSaleSession.ts— buy CTA, Kumbaya quotes sized to gross DOUB.With
charmPriceWad = 1000e18, the band is ~990–10,000 DOUB per buy.Kumbaya pricing today (spot QuoterV2, not TWAP)
quoteExactOutputSinglehops —kumbayaRoutes.ts,kumbayaQuoter.ts,useKumbayaExactOutputQuote.ts.kumbayaRoutes.ts,docs/integrations/kumbaya.md./arena/protocoluses a two-hop spot quote (CL8Y←WETH←USDM) —cl8ySpotUsdPrice.ts,useProtocolCl8yUsdSpotPrice.ts. UI copy refers to “DOUB USD” but the hook still quotes the reserve CL8Y token path (technical debt; out of scope unless needed for parity).observeintegration exists in contracts or frontend today. Sir Trading deploys against the Kumbaya V3 factory (0x68b34591…on MegaETH); Sir’s live marks for DOUB/ETH and ETH/USD are expected to use V3 pool TWAP over those same pools — implementers must read Sir’s production TWAP window, observation cardinality, and pool addresses and match them (do not invent a new oracle recipe).Deploy / ops
ARENA_CHARM_PRICE_WAD—docs/operations/deployment-guide.md.1000e18for deterministic tests unless explicitly fork-testing TWAP init.Why this change is needed
Constraints and guardrails
charmPriceWadremainsTimeArenastorage set at deploy and viasetCharmPriceWad; indexer/frontend are derived only (yieldomega-guardrailsSKILL).CHARM_MIN_WAD/CHARM_MAX_WADor XP mapping without a separate spec issue (#246).charmPriceWadmust use V3 TWAP (poolobserve/OracleLibrarypattern), not QuoterV2 spot — spot is manipulable within a block (security-and-threat-model.md).observationCardinality, block time assumptions).ARENA_CHARM_PRICE_WADoverride — never silent default to1000e18on mainnet without logging.DeployDev/ E2E may keep1000e18or fixture TWAP; do not require live MegaETH RPC for defaultbash scripts/e2e-anvil.sh.TimeArenaBuyRoutergross DOUB stillcharmWad × charmPriceWad / 1e18—INV-TIME-ARENA-BUY-ROUTERunchanged (#251).Target formula (initial launch):
Let
doubUsdTwap= USD value of 1 DOUB from TWAP (USDM treated ≈ $1):Human must confirm rounding (floor vs nearest) and max deviation from spot at deploy block.
Relevant files
TimeArena.sol,DeployProduction.s.sol,DeployDev.s.sol,UUPSDeployLib.sol,PARAMETERS.mdcontracts/script/lib/ArenaCharmPriceTwap.solorscripts/compute-arena-charm-price-twap.sh), fork test against MegaETH poolsarenaConstants.ts,timeArenaBuySubmitSizing.ts,arenaV2SaleSessionBridge.ts,useArenaSaleSession.ts,kumbayaRoutes.tsdocs/product/arena-v2.md,docs/operations/deployment-guide.md,docs/integrations/kumbaya.md,docs/testing/invariants-and-business-logic.mdscripts/verify-time-arena-buy-router-anvil.sh,contracts/test/TimeArena.t.sol, optionalTimeArenaFork.t.solRecommended direction
observationCardinality, and whether cardinality was increased beyond default1.OracleLibrary+ poolobserve, or scriptedcast+eth_callfor deploy-only) that returnsdoubUsdTwapand derivedcharmPriceWad.DeployProduction(or pre-deploy script invoked by ops) to:charmPriceWadfrom TWAP + $1 anchordoubUsdTwap,charmPriceWad,minDoubSpend,maxDoubSpend, block number, pools usedARENA_CHARM_PRICE_WADoverride for rehearse / emergencyPARAMETERS.md, deployment guide, and addINV-TIME-ARENA-CHARM-TWAP-INITwith the formula and Sir parity note.charmPriceWadis set correctly onchain; verify buy slider min/max and KumbayaexactOutputquotes track the new price. Optional: show “launch TWAP” provenance on/arena/protocol(non-blocking).DeployDevat1000e18unless a fork test flag is set — preserves E2E determinism.Acceptance criteria
charmPriceWadso 1 CHARM ≈ $1.00 DOUB notional at deploy per TWAP (within documented rounding tolerance).0.99 × charmPriceWadto10 × charmPriceWad(wei), matching onchain math.ARENA_CHARM_PRICE_WADmanual override still works and is documented.1000e18on mainnet.DeployDev/ default Anvil unchanged for CI unless opt-in fork test.INV-TIME-ARENA-DOUB-PRICEtests updated: default constant may remain1000e18for dev; fork test asserts TWAP init when enabled.Test plan (functional paths)
forge test— helper returns expectedcharmPriceWadfor mockedobserveticksforge test --fork-url $MEGAETH_RPC(orTimeArenaFork.t.solextension) — live pools, logdoubUsdTwapcharmPriceWad, min/max DOUB; compare to manual spreadsheetARENA_CHARM_PRICE_WAD=…deploy uses override, skips TWAPcast callcharmPriceWad+ assertbuy(99e16)succeeds andbuy(10e18+1)revertsTimeArena.t.sol—doubOwedmatches new pricebash scripts/verify-time-arena-buy-router-anvil.sh— gross DOUB =charmWad × charmPriceWad / 1e18cd frontend && npm test—timeArenaBuySubmitSizing.test.ts,arenaV2SaleSessionBridge.test.tswith non-1000 price fixturecd frontend && npm run typecheck && npm run lintbash scripts/verify-podium-live-anvil.shafter deploy with new pricebash scripts/e2e-anvil.sh— still PASS with dev1000e18Test plan (attack, hack, and abuse vectors)
observationCardinality≥ minimum; documentincreaseObservationCardinalityNextops if neededcharmPriceWadsetCharmPriceWadafter fair TWAP initkumbayaRoutes.tsand integrator-kittestFuzz_buy_charmInBand_doubPullParitywith TWAP-derived priceexactOutputvs stalecharmPriceWadTimeArenaBuyRouter.t.sol+ submit-time headroom (#82)Verification criteria (merge gate)
cd contracts && forge testMEGAETH_RPCset (CI may SKIP)bash scripts/compute-arena-charm-price-twap.sh(or equivalent added by MR)charmPriceWad, min/max DOUB, exits 0 on mainnet forkbash scripts/verify-time-arena-buy-router-anvil.shcd frontend && npm run typecheck && npm run lint && npm testPARAMETERS.md+ deployment guide updatedINV-TIME-ARENA-CHARM-TWAP-INITrow ininvariants-and-business-logic.mdMR checklist row: TWAP charm init →
forge test+ fork script → PASS/FAIL.Out of scope
charmPriceWadeach block (governance refresh is separate)./sirlink only today).Open questions (resolve before implementation)
charmPriceWad(floor recommended for protocol-favorable).setCharmPriceWadmust also be TWAP-gated or remains free-form owner.mentioned in commit
69e05c9ac0mentioned in merge request !447
Implementation MR: https://gitlab.com/PlasticDigits/yieldomega/-/merge_requests/77
Summary: Production
charmPriceWadnow comes from Kumbaya V3 TWAP (Sir 15m) on DOUB/WETH + WETH/USDm unlessARENA_CHARM_PRICE_WADis set. DeployDev/Anvil unchanged at1000e18.Blocker for live TWAP: DOUB/WETH pool (fee 100) is not deployed on MegaETH mainnet yet —
bash scripts/compute-arena-charm-price-twap.shfails closed withmissing DOUB/WETH pool. Production deploy needs pool liquidity or explicit override until then.See MR checklist for PASS/FAIL/SKIP per acceptance item.
mentioned in commit
c67aef1866mentioned in commit
9390010deamentioned in merge request !450
Follow-up MR: !450
Core TWAP implementation landed in !447 (merged). This follow-up closes remaining acceptance gaps from the issue checklist.
What changed (!450)
invariants-and-business-logic.mdwith live-mainnet pool noteINV-TIME-ARENA-CHARM-TWAP-INITcross-linked inskills/play-time-arena-doub/SKILL.md,skills/README.md, and yieldomega-guardrailsINV-TIME-ARENA-DOUB-PRICE(#246) now references production TWAP initcharmPriceWad(2500 DOUB/CHARM TWAP-like fixture) intimeArenaBuySubmitSizing.test.tsandarenaV2SaleSessionBridge.test.tsVerification checklist
cd contracts && forge test --match-contract ArenaCharmPriceTwap— expect PASS (5/5)bash scripts/verify-time-arena-buy-router-anvil.sh— expect PASS (#251 router parity)cd frontend && npm run typecheck && npm test -- --run src/lib/timeArenaBuySubmitSizing.test.ts src/pages/arena/arenaV2SaleSessionBridge.test.ts— expect PASSbash scripts/compute-arena-charm-price-twap.sh— expect FAIL until DOUB/WETH pool (fee 100) is live on MegaETH; useARENA_CHARM_PRICE_WADfor rehearsal until thenFollow-ups (when pool exists)
bash scripts/compute-arena-charm-price-twap.shandFORK_URL=… forge test --match-contract ArenaCharmPriceTwapFork— should move from SKIP/FAIL to PASS/arena/protocolIssue stays open until DOUB/WETH pool is deployed and live TWAP dry-run passes, or ops explicitly accepts override-only production path.
mentioned in commit
eec8af160dmentioned in commit
e9072f0114TWAP pool path update (!450)
Per product direction: production charm TWAP now uses DOUB/CL8Y (100) → CL8Y/WETH (100) → WETH/USDm (3000) instead of direct DOUB/WETH. Matches the live Kumbaya DOUB/CL8Y spot pool and reserve-asset routing.
Verification checklist
cd contracts && forge test --match-contract ArenaCharmPriceTwap— PASS (5/5)FORK_URL=https://mainnet.megaeth.com/rpc forge test --match-test test_fork_megaeth_twap_charm_price— PASS (logsdoubUsdWad,charmPriceWad)bash scripts/compute-arena-charm-price-twap.sh— PASS on current MegaETH headINV-TIME-ARENA-CHARM-TWAP-INIT,kumbaya.md, deployment guide,PARAMETERS.md, play skill — pool recipe updatedLive head (example)
doubUsdWad≈ 2.45e13 (~$0.0000245/DOUB)charmPriceWad≈ 4.08e22 DOUB/CHARM (~$1/CHARM anchor)Issue remains open for merge review of !450.
mentioned in commit
5dffb56c2bmentioned in commit
d8775620e8mentioned in merge request !451
Verification complete — MR !451
Branch
local1/303-verify-charm-twap· MegaETH head block 18201912 (2026-06-09).What was verified
Implementation from !447 + !450 is correct: DOUB/CL8Y (100) → CL8Y/WETH (100) → WETH/USDm (3000) Sir 15m TWAP,
charmPriceWad = floor(1e36 / doubUsdWad), fail-closed on 4326 without override, DeployDev still1000e18.Fixes in verification MR
bash scripts/verify-arena-charm-twap.sh— orchestrates unit + fork + dry-run + fail-closed testsDeployProductionCharmPrice.t.sol— non-4326 revert withoutARENA_CHARM_PRICE_WADVITE_INDEXER_URL=(Anvil E2E) while keeping indexer-first when indexer is configured (#301)Checklist
forge test --match-contract ArenaCharmPriceTwap— PASS (5/5)FORK_URL=… forge test --match-test test_fork_megaeth_twap_charm_price— PASSbash scripts/compute-arena-charm-price-twap.sh— PASSbash scripts/verify-arena-charm-twap.sh— PASSARENA_CHARM_PRICE_WADoverride on MegaETH fork — PASSbash scripts/verify-time-arena-buy-router-anvil.sh— PASScd frontend && npm run typecheck && npm test— PASSbash scripts/e2e-anvil.sh— PASS (6/6)bash scripts/check-doc-anchors.sh— PASSINV-TIME-ARENA-CHARM-TWAP-INITcross-linked in invariants §303 + skillsMR: https://gitlab.com/PlasticDigits/yieldomega/-/merge_requests/81
Closing — all acceptance criteria and verification gates pass.
mentioned in issue #305
marked as related to #305
mentioned in commit
3db1539c92mentioned in issue #341
mentioned in issue #367