Investigate frontend WarBow "flag planted" showing for many consecutive accounts on localnet #51
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#51
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
Observed on localnet: multiple accounts in a row appear to show flags planted in the frontend (buy feed / buy highlights / rivalry narrative). This issue tracks whether that is a real bug (wrong wallet perspective, stale reads, indexer drift) or expected given how the
Buyevent encodesflagPlantedand how the UI interprets it.How WarBow flags work (authoritative — onchain)
There is a single global pending-flag slot on
TimeCurve:warbowPendingFlagOwner— who may eventuallyclaimWarBowFlagwarbowPendingFlagPlantAt— when their qualifying buy last (re)planted the flagFlow
_buysetswarbowPendingFlagOwner = msg.senderandwarbowPendingFlagPlantAt = block.timestamp(the previous holder is cleared or penalized first if another buyer interrupts — see contract).claimWarBowFlag(while sale active): requiresmsg.sender == warbowPendingFlagOwner,now >= plantAt + WARBOW_FLAG_SILENCE_SEC(300s), then awardsWARBOW_FLAG_CLAIM_BP(1000) BP and clears the slot.plantAt + 300s, the former holder may take a2 × WARBOW_FLAG_CLAIM_BPBP penalty (WarBowFlagPenalized); if before silence ends, no 2× penalty (they simply lose the claim window).Game theory (why this exists)
How it is coded today
Contract (
contracts/src/TimeCurve.sol)warbowPendingFlagOwner,warbowPendingFlagPlantAt, constantsWARBOW_FLAG_SILENCE_SEC,WARBOW_FLAG_CLAIM_BP._buy: Clears prior pending (with optional 2× penalty branch), then always assigns pending tomsg.senderand updatesplantAt.Buyevent: The Solidity emit passesflagPlantedas the literaltrueon every successful buy (not conditional on “new plant after clear” in the payload). Seeemit Buy(..., flagPenalty, true, ...).Indexer (
indexer/src/decoder.rs)Buy.flagPlantedfrom logs intoflag_plantedon indexed buy rows — faithful to the event, so every modernBuyrow carriesflag_planted: truewhen the contract always emitstrue.Frontend
Chain truth for “do I hold the pending flag?” (
frontend/src/pages/TimeCurvePage.tsx)warbowPendingFlagOwner/warbowPendingFlagPlantAtvia wagmi.iHoldPlantFlag= connected wallet matcheswarbowPendingFlagOwner(case-insensitive).canClaimWarBowFlagadditionally requires sale phase active and ledger time past silence end.Indexer-driven copy (per buy row) (
frontend/src/lib/timeCurveUx.ts)pickBuyHighlightStat,listBuyImpactTicks,buildBuyFeedNarrativetreatbuy.flag_plantedas a signal and surface “Flag planted” / “flag planted” tags when no higher-priority WarBow/timer signals dominate.true, many consecutive buyers will each have rows that can show flag-related highlights — even though only one address is the currentwarbowPendingFlagOwner.Arena panel (
frontend/src/pages/timecurve/TimeCurveSections.tsx)iHoldPlantFlag(not by indexerflag_planted), which is the correct wallet-specific behavior.Tests / fixtures
frontend/src/lib/timeCurveUx.test.ts— expectations aroundflag_plantedin UX helpers.frontend/e2e/timecurve-live-buys-modals.spec.ts— mock buy usesflag_planted: false(may not reflect live contract encoding).How it is documented
docs/product/primitives.md— Plant flag / claim flagBuyincludesflagPlantedwhen a new plant occurs after clears — this does not match the currentTimeCurve.solemit, which istrueon every buy.skills/play-timecurve-warbow/SKILL.mddocs/frontend/design.mddocs/frontend/timecurve-views.mddocs/qa/YO-TimeCurve-QA-Checklist.mdcontracts/PARAMETERS.mdWARBOW_FLAG_CLAIM_BP/ silence 300s.bots/timecurve/README.mdCross-reference index (repo paths)
contracts/src/TimeCurve.sol(_buy,claimWarBowFlag,WarBowFlagPenalized,WarBowFlagClaimed)frontend/src/lib/abis.ts(Buyevent includesflagPlanted)indexer/src/decoder.rs(TimeCurveEvents::Buy→flag_planted)frontend/src/lib/indexerApi.ts(flag_planted?: boolean)frontend/src/lib/timeCurveUx.ts,frontend/src/pages/TimeCurvePage.tsx,frontend/src/pages/timecurve/TimeCurveSections.tsxfrontend/src/pages/TimeCurveProtocolPage.tsx(exposeswarbowPendingFlag*views)docs/product/primitives.md,docs/frontend/design.md,skills/play-timecurve-warbow/SKILL.mdIs the reported behavior expected?
Likely yes for indexer-driven buy rows, if “flag planted” is driven from
Buy.flagPlanted: the field is alwaystruein current bytecode, so rotating localnet accounts that each buy will each get rows that advertise flag planting — that is semantically “every buy replants the global pending flag to this buyer”, not “every buyer simultaneously holds a flag.”Still worth validating in this issue
iHoldPlantFlag/canClaimWarBowFlagalways trackuseAccount()and do not cache the wrong address on localnet.docs/product/primitives.mdto match the always-trueevent encoding, or change the contract (future) to emit a meaningful boolean and reindex — only if product wantsflagPlantedto mean something narrower.Suggested acceptance criteria
timeCurveUxmessaging or priority so “flag planted” is not repeated for every ordinary buy unless intended.primitives.mdvsTimeCurve.solmismatch onflagPlantedmeaning.assigned to @PlasticDigits
changed the description
Frontend also needs to display when flags are won or destroyed, and indicate if a flag is currently active and if so who is the placer and how many seconds left on it
mentioned in commit
8f303ef56aImplemented on main (commit `
8f303ef`).Summary
Verification checklist for @brouie
Issue left open for your sign-off.
mentioned in issue #55
mentioned in issue #44
@PlasticDigits verified on
8f303efduring browser walkthrough on live local-anvil stack (chain 31337, frontend at http://127.0.0.1:5173).Visual verification — Arena page (/timecurve/arena)
PENDING WARBOW FLAG (CHAIN) panel:
cf6fe19)Buy feed / Live Buys sidebar (4 historical buys from rich-state Part1):
Top Rivals + Chasing Pack:
Rivalry feed:
Frontend tests
cd frontend && npx vitest run:
Spec items confirmed
Screenshot evidence captured
10 screenshots taken across Simple, Arena, Protocol views during this walkthrough. Closing #51 with a follow-up filed at #81 for an unrelated finding (frontend leaks mainnet RPC fetches to eth.merkle.io even when connected to local Anvil chain 31337 — CORS-blocked, hygiene issue, not blocking).
Closing #51.
mentioned in issue #218