REGRESSION: Bot swarm hits ContractPanicError (div-by-zero) and BadFunctionCallOutput on live Anvil stack after UUPS proxy migration #61
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#61
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 during #39 regression walkthrough. All 18 bots fail against a fresh SKIP_ANVIL_RICH_STATE=1 stack bring-up; 178/178 forge tests still pass. Deployment or proxy-init regression suspected.
Repro
git pull origin main+git submodule update --init --recursive(HEAD atdec166e)cd /srv/qa/repos/yieldomega && SKIP_ANVIL_RICH_STATE=1 bash scripts/start-local-anvil-stack.shcd bots/timecurve && source .env.local && timecurve-bot --send --allow-anvil-funding swarm/tmp/yieldomega_bot_swarm.pids.Observed
Three distinct failure modes across 18 bots:
1. shark-0/1/2 + fun-0/1/2 (6 bots)
ContractPanicError: ('Panic error 0x12: Division by zero.', '0x4e487b71...0x12')Panic 0x12 is Solidity's division-by-zero panic. Strategy bots hit it at their first buy attempt.
2. defender-0/1/2 + rando-0/1/2 + seed-local-0/1/2 (9 bots)
BadFunctionCallOutput: Could not transact with/call contract function, is contract deployed correctly and chain synced?Failing at contract-call level. Reading state that returns empty, or hitting an address with no code deployed.
3. pvp-0/1/2 (3 bots)
Mock CL8Y minting succeeds (
mint(CL8Y mock) tx=... status=1), thenpvp: cycle failed (Could not transact with/call contract function...); retrying after delayon the subsequent sale buy.Why suspicious for UUPS regression
forge testwith FOUNDRY_PROFILE=ci = 178/178 passing (verified this morning per #54 closure)DeployDev.s.solviaUUPSDeployLibnow deploys everything behind ERC1967Proxy + initialize callLogs
/tmp/yieldomega_swarm_shark-0.logends withContractPanicError: Panic error 0x12: Division by zero./tmp/yieldomega_swarm_rando-0.logends withBadFunctionCallOutput/tmp/yieldomega_swarm_pvp-0.logshows partial success on CL8Y mint then cycle failureProposed diagnosis path
contracts/src/TimeCurve.solconstructor-era state vs initialize() to find any state variable that was initialized in constructor (including default zeros) and now needs explicit initialize assignmenttotalShare,totalBurned, any reserve balances that might be a denominator in TimeCurve buy mathImpact
Workaround for immediate QA
None yet. Attempting
bash scripts/e2e-anvil.shinstead of stack script may or may not work (different deploy path); haven't tested.cc @PlasticDigits — this looks like it came in with #54 merge
0cc6342. High priority for YO launch given timeline.mentioned in commit
482a25aafaFix pushed to
main(482a25a) — @brouie please verifyRoot cause
After UUPS (#54), Foundry
run-latest.jsonlabels the implementationCREATEascontractNameTimeCurve/RabbitTreasury. The canonical addresses are the ERC1967Proxy rows (constructorarguments[0]= implementation).anvil_rich_state.shwas defaulting env from the naivejqfilter and picked implementations → uninitialized storage → panic 0x12 on charm bounds / oddeth_callfailures. Same pitfall for any script or agent copying addresses from broadcast JSON bycontractNamealone.What changed
scripts/lib/broadcast_proxy_addresses.sh— map impl → ERC1967 proxy for TimeCurve / RabbitTreasury; direct CREATE for LeprechaunNFT.contracts/script/anvil_rich_state.sh— uses that helper when loading from broadcast.scripts/lib/anvil_deploy_dev.sh— anchor consolegrepto line start (same asstart-local-anvil-stack.sh) so verbose forge output cannot pick a wrongTimeCurve:line.docs/testing/invariants-and-business-logic.md,docs/testing/anvil-rich-state.md, rootskills/README.md,bots/timecurve/SKILL.md,.cursor/skills/yieldomega-guardrails/SKILL.md— invariant + crosslinks (issue left open for your sign-off).Checklist for you
git pull origin main(commit482a25aor newer).SKIP_ANVIL_RICH_STATE=1 bash scripts/start-local-anvil-stack.sh(or your QA equivalent) — confirm Stack is up and swarm completes withoutContractPanicError 0x12/ massBadFunctionCallOutput.bash contracts/script/anvil_rich_state.shwith addresses unset (so it loads fromrun-latest.json) — confirm Part1/Part2 still succeed.cast call <TIMECURVE from .env> "initialMinBuy()(uint256)"— must be non-zero on the proxy; the implementation address from oldjqwould read 0 if called directly.grep TimeCurve deploy.log/YIELDOMEGA_TIMECURVE_ADDRESSand whether it matches anERC1967Proxyrow inrun-latest.json.Leaving the issue open until you confirm.
mentioned in issue #55
mentioned in issue #72
mentioned in issue #73
@PlasticDigits verified on
1bdbda8(full stack:bd564b0anvil flag + this commit's forge --code-size-limit fix).Verification
Commands:
Results
Stack is up— RPC, indexer, registry, frontend env all writtencast call initialMinBuy()returns1000000000000000000(1e18 non-zero) on the registry's TimeCurve address. Proxy resolution working — broadcast_proxy_addresses.sh maps impl CREATE rows to ERC1967Proxy correctly per482a25a.remaining 86541s >= 900s).Forge environment note
forge --version on the QA server: 1.5.1-stable (b0a9dd9, 2025-12-22). Forge applies EIP-170 in its dry-run simulator independently of Anvil — your
bd564b0only set Anvil's code-size-limit, leaving forge's default to reject TimeCurve at 28454 bytes. The1bdbda8follow-up adding --code-size-limit 524288 to the forge script line resolves it. Worth noting in case future agents on differently-configured forge installs need the same flag.Follow-up filed
#73 — 6 of 18 bots (3x shark + 3x fun) hit a single Panic 0x12 (div-by-zero) at startup on
currentCharmBoundsWad()(bots/timecurve/src/timecurve_bot/strategies/common.py L25). Bots recover and proceed normally — this is NOT the original #61 regression (that one killed bots; this one is a recovered-edge in the bound math probing fresh-sale state before any seed buy lands). Tracked separately.#61 fully resolved at the level you scoped it. Closing.
mentioned in issue #100
mentioned in issue #104
mentioned in issue #109
mentioned in commit
f6d907ffedmentioned in issue #162
mentioned in issue #207
mentioned in issue #224