WarBow: widen steal BP band from 2x-10x to 1x-50x (contract + frontend + docs/bots/sims) #366
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#366
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
Widen the WarBow steal victim BP eligibility band from 2×–10× attacker BP to 1×–50× attacker BP, across the contract (source of truth), frontend mirrors/UX copy, docs, bots, and simulations — one bundled change so every layer stays consistent.
Current codebase
The band is enforced onchain in
TimeArena.warbowStealas hardcoded literals with a single revert string:TimeArenais UUPS upgradeable (Ownable2StepUpgradeable+_authorizeUpgradegatedonlyOwner); there is no owner setter for the band — allWARBOW_*economics arepublic constantand documented as Fixed incontracts/PARAMETERS.md(§ "WarBow steal BP bracket", originally #211).require(victim != address(0) && victim != msg.sender, "TimeArena: bad victim")), and daily caps (WARBOW_MAX_STEALS_PER_DAY = 3per attacker and per victim, UTC day) plus theWARBOW_STEAL_LIMIT_BYPASS_DOUB = 50_000e18bypass are independent of the band.frontend/src/lib/warbowStealBpBand.ts(WARBOW_STEAL_VICTIM_MIN_MULT = 2n,WARBOW_STEAL_VICTIM_MAX_MULT = 10n,isWarbowStealVictimBpInBand), butArenaWarbowHeroPanel.tsx(isEligibleTarget) duplicates the literals (viewer * 2n/viewer * 10n) instead of using the shared helper, andtimeArenaUx.tsdescribeStealPreflightuses* 2ndirectly for the lower bound while importing onlyWARBOW_STEAL_VICTIM_MAX_MULTfor the upper bound.timeArenaUx.ts,revertMessage.ts,warbowHeroSubcardHelpCopy.ts,ArenaSections.tsx, docs (contracts/PARAMETERS.md,docs/product/arena-v2.md,docs/product/time-arena.md), skills (skills/play-time-arena-warbow/SKILL.md), bots (bots/timearena/src/timearena_bot/strategies/warbow_setup.py,pvp.py), and simulations (simulations/ecostrategy/warbow_pvp.py,constants.py).INV-TIME-ARENA-WARBOW-REVERT-MATRIX(#316) withtest_warbow_steal_reverts_steal_bandand helpers_seedWarbowStealBand/_boostWarbowVictimincontracts/test/TimeArena.t.sol.Why the new implementation is needed
The 2× floor forbids attacking peers at or near your own BP, and the 10× cap keeps large leaders out of reach of most of the field. Widening to 1×–50×:
_routeWarbowDoubSpend.Whale-griefing protection is preserved by construction: the victim must still hold at least 1× the attacker's BP, so high-BP attackers can never drain lower-BP wallets.
Constraints / guardrails
TimeArena.sol; a frontend-only change would just produceTimeArena: steal bandreverts. Deployed instances need a UUPS implementation upgrade (no admin setter exists).constants (no new storage). Do not add owner setters in this issue unless separately decided — keep the "Fixed" convention fromPARAMETERS.md."TimeArena: steal band"unchanged sorevertMessage.tsmatching and the #316 revert matrix stay valid.*semantics:vbp >= 1 * abp && vbp <= 50 * abp;abp > 0requirement unchanged. At exactly 1×, equal-BP victims are eligible.warbowStealBpBand.ts) — remove the duplicated literals inArenaWarbowHeroPanel.tsxand the hardcoded* 2nintimeArenaUx.tsso a future band change is single-sourced.WarBowStealevent shape unchanged) — confirm, do not touch.Relevant files
contracts/src/arena/TimeArena.sol(warbowSteal band require,WARBOW_*constants block)contracts/test/TimeArena.t.sol(test_warbow_steal_reverts_steal_band,_seedWarbowStealBand,_boostWarbowVictim, band assertions at ~1810)frontend/src/lib/warbowStealBpBand.ts(+.test.ts),frontend/src/pages/arena/ArenaWarbowHeroPanel.tsx(isEligibleTarget),frontend/src/lib/timeArenaUx.ts(describeStealPreflight)frontend/src/lib/revertMessage.ts,frontend/src/pages/arena/warbowHeroSubcardHelpCopy.ts,frontend/src/pages/arena/ArenaSections.tsxwarbowStealBpBand.test.ts,timeArenaUx.test.ts,revertMessage.test.ts,warbowHeroSubcardHelpCopy.test.ts,ArenaWarbowHeroPanel.test.tsxcontracts/PARAMETERS.md(§ WarBow steal BP bracket),docs/product/arena-v2.md,docs/product/time-arena.md,docs/testing/invariants-and-business-logic.md,docs/frontend/design.md(2× BP rule copy)skills/play-time-arena-warbow/SKILL.mdbots/timearena/src/timearena_bot/strategies/warbow_setup.py(band predicate),pvp.py(log copy)simulations/ecostrategy/warbow_pvp.py,simulations/ecostrategy/constants.py,simulations/tests/test_ecostrategy.pyRecommended direction
WARBOW_*values and use them in the check: Expose them in the read ABI (frontend/src/lib/abis.ts) if the UI should read them onchain when the indexer is off, mirroring theWARBOW_STEAL_DOUBpattern.WARBOW_STEAL_VICTIM_MIN_MULT = 1n/WARBOW_STEAL_VICTIM_MAX_MULT = 50ninwarbowStealBpBand.ts; routeArenaWarbowHeroPanel.isEligibleTargetanddescribeStealPreflightlower bound through the shared constants/helper; update all "2×–10×" strings to "1×–50×" (preflight titles like "2× minimum not met" → band-driven copy).warbow_setup.pypredicatevbp >= 1 * abp and vbp <= 50 * abp; simswarbow_pvp.pythresholds +constants.pylabel.INV-TIME-ARENA-WARBOW-REVERT-MATRIXwording and add/refresh a band invariant row mapping to the new tests.TimeArenaimplementation (ownerupgradeToAndCall); Anvil dev stack picks the new implementation up automatically viaDeployDev.Acceptance criteria
warbowStealaccepts victims withabp <= vbp <= 50 * abp(inclusive both ends) and revertsTimeArena: steal bandoutside it;abp == 0still reverts.vbp == abp - 1andvbp == 50 * abp + 1revert.TimeArena: bad victim(regression).warbowStealBpBand.tsconstants (no duplicated literals inArenaWarbowHeroPanel.tsx/timeArenaUx.ts).PARAMETERS.md,arena-v2.md,time-arena.md, invariants), skill, bots, and sims updated; no stale "2×–10×" references (rg -n '2×–10×|2x–10x|2 \* abp|10 \* abp'clean outside changelog/audit history).WarBowStealevent unchanged; indexer untouched.Test plan — all paths
Contracts (
cd contracts && forge test):vbp == abp,vbp == 2*abp(old floor still in band),vbp == 50*abp; revert atvbp == abp - 1,vbp == 50*abp + 1, andabp == 0._seedWarbowStealBand/_boostWarbowVictimand theassertGe/assertLeband assertions (~line 1810) to the new multiples.steal zerowhen take rounds to 0; daily cap + bypass (steal limit); revenge window opens for victim; ranking updates for both parties; DOUB routing andtotalDoubRaisedincrement.abp > 0, in-bandvbpsucceeds and out-of-band reverts; include largeabpvalues to exercise50 * abpuint256 multiplication (no overflow within realistic BP magnitudes; document thetype(uint256).max / 50bound).Frontend (
cd frontend && npm run typecheck && npm run lint && npm test):warbowStealBpBand.test.ts: constants1n/50n; inclusive boundaries (equal BP eligible,50x+1not,abp = 0not).timeArenaUx.test.ts: preflight grading at new boundaries; self-target, zero-BP, below-min, above-max, cap/bypass, guarded-success wording.ArenaWarbowHeroPanel.test.tsx: target rows flag eligible/too-low/too-high per new band.revertMessage.test.ts,warbowHeroSubcardHelpCopy.test.ts: updated copy.Bots/sims:
simulations/tests/test_ecostrategy.pyband cases updated; botwarbow_setup.pypredicate covered by its existing checks.E2E (stack):
bash scripts/verify-podium-live-anvil.shsmoke plus a manual steal at exactly 1× on the Anvil stack (bash scripts/start-qa-local-full-stack.sh).Test plan — attack / hack / abuse vectors
WARBOW_STEAL_DOUBrouted to podiums, per-attacker and per-victim UTC-day caps (3) bind, and bypass costs 50k DOUB — so the loop is strictly value-negative for the pair. Add a Forge test simulating N round-trips and asserting total BP conservation and cumulative DOUB spend.steal band(replaces the old 2× griefing test's intent; keep a dedicated test).simulations/ecostrategy/warbow_pvp.pyscenario to quantify ladder speed under the new band and confirm guard (1% drain) neutralizes it economically.bad victimstill fires (1× would otherwise make self in-band).abpneartype(uint256).max / 50to confirm the multiplication reverts safely (Solidity 0.8 checked math) rather than wrapping into a false in-band pass.steal zerostill guards dust-BP victims.Verification criteria
cd contracts && forge testdoub.csvfork tests may skip)cd frontend && npm run typecheck && npm run lint && npm testcd simulations && python3 -m pytest tests/test_ecostrategy.pyWarBowStealindexedINV-TIME-ARENA-WARBOW-REVERT-MATRIX+ band rows updatedRelated: #211 (band origin), #316 (revert matrix), #310 (spend routing), #361 (steal quota UX).
mentioned in commit
23aa74d1fementioned in commit
e20072c565mentioned in commit
0aa5658521mentioned in commit
a55964fa25mentioned in merge request !542
mentioned in commit
8cc66b98d3