bots: shark/fun strategies hit Panic 0x12 (div-by-zero) on currentCharmBoundsWad() at startup; recover but log noise #73
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#73
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?
Found Monday 2026-04-27 during #61 live-stack verification on bd564b0+524288 fix.
Summary
After #61 fix landed (proxy address resolution working — initialMinBuy returns 1e18 from registry address, dev's verification step #4 PASS), bot swarm runs successfully overall:
But 6 of 18 bot logs (3x shark + 3x fun) show a single
ContractPanicError: Panic error 0x12: Division by zeroat startup. Bots recover after the error and proceed normally — this is NOT the Friday #61 regression where bots died with no recovery.Repro
Call site
bots/timecurve/src/timecurve_bot/strategies/common.pyL25:The shark/fun strategies call this very early at startup (
charm_for_buywrapper). Defender / rando / pvp / seed-local don't hit it — different code paths or different probe order at startup, or seed-local bots seed state before the others probe.Hypothesis
currentCharmBoundsWad()divides by something that is zero on a fresh sale before any seed buy has landed. The function is callable on the proxy (so #61 root-cause-resolution proxy plumbing is correct), but the underlying math has an edge case for "sale started, but zero charm sold yet, fun/shark probe before seed-local lands".The seed-local bots that prime CL8Y mock balances mint and approve, but those don't issue buys — so total_charm_weight or another denominator stays zero until the first real buy.
Severity
LOW. Bots recover; swarm produces 180+ successful buys. But:
Suggested fixes
Either / or:
currentCharmBoundsWad()should return a sane fallback (e.g., (initialMinBuy, initialMaxBuy)) when the underlying denominator is zero (pre-first-buy state). Catch in the math.Out of scope
Friday #61 regression itself — separate root cause (proxy address resolution, fixed in
482a25a, verified working today).cc @PlasticDigits
mentioned in issue #61
mentioned in commit
a4052d7b10Fix landed on
main(ee09f16) — please verifySummary:
TimeCurve._charmBoundsno longer divides byinitialMinBuywhen it is zero (uninitialized implementation / degenerate storage).currentCharmBoundsWad()returns the base CHARM band(0.99e18, 10e18)instead of panic 0x12, so shark/fun startup probes and similar reads do not spew tracebacks. Authorized sale state and buys still require the ERC1967 proxy — this is a view-only resilience fix.Also: One-line header note on
scripts/start-local-anvil-stack.shthat DeployDev uses--code-size-limit 524288(the stack deploy line itself was already fixed onmainin prior commits).Docs / cross-links:
docs/testing/invariants-and-business-logic.md(business table + TimeCurve test map),bots/timecurve/README.md,skills/README.md,.cursor/skills/yieldomega-guardrails/SKILL.md(#73). Forge:test_currentCharmBoundsWad_zero_initialMinBuy_returns_base_envelope.Checklist for @brouie
cd contracts && FOUNDRY_PROFILE=ci forge test --match-test test_currentCharmBoundsWad_zero_initialMinBuy -vv— passSKIP_ANVIL_RICH_STATE=1stack +timecurve-bot … swarm);grep -l 'Panic error 0x12' /tmp/yieldomega_swarm_*.log— no matches (or only from unrelated / wrong-address calls)cast call … currentCharmBoundsWad()matches previous behavior (same min/max as before this change for initialized sale)cast callagainst the implementation address fromrun-latest.json: should return(99000000000000000, 10000000000000000000)without revert (not for production use)Leaving the issue open as requested.
@PlasticDigits verified on
a4052d7(withee09f16docs companion).Tests
cd contracts && FOUNDRY_PROFILE=ci forge test --match-test test_currentCharmBoundsWad_zero_initialMinBuy -vv:
Live swarm repro
Same commands as the original repro:
Results:
Closing #73.
mentioned in issue #78
mentioned in issue #109
mentioned in commit
f6d907ffed