feat(bot): cycle enumeration + per-block opportunity search, live-verified (7905) #14
No reviewers
Labels
No labels
auto-merge
auto-merge
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
fortiblox/arc-mev-bot!14
Loading…
Reference in a new issue
No description provided.
Delete branch "rev/cycles-search"
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?
Phase 2, WP 7905 (revenue-director lane
rev, PR 2 of 2; stacks on #12 quote+reserves). Full design, proofs and measurements indocs/search.md.cycles.py
2-4 hop closed cycles from configured base tokens (DFS, no pool/intermediate-token reuse, deterministic order,
max_cyclescap →truncated), cached perregistry_hash(§2.3 formula; pinned87f775b2877ab194forpools.testnet.json—registry.pymust match). Dedupe policy documented: reversals are distinct trades and kept; rotations cannot occur per base.search.py (incl. CEO scope additions from
docs/research/arc-arb-learnings.md§4.1)no_price/shallow/incoherent_price/stalereasons reported.blockHash; cycles touching touched pools are evaluated first; each Opportunity carrieschanged_pool_seeded,route_key(§2.3 format) andcontention = {touched_pools, swaps_head_block, distinct_senders}.[search.implausible_gross_bps], validated non-increasing in hop count.profit(x)=out(x)−xis concave withprofit(0)=0(proof in docs), soΠ(1−φ)R_out/R_in ≤ 1⇒ never profitable — one integer product, rejects 5/8 cycles per block before sizing; subsumes the 2-probe test.4εbound (ε = Σ_i Π_{j>i} ⌈R_out/R_in⌉), verified against an exhaustive scan for all 12 cycles at block 62413099 (profitable ones within 1 unit).ceil(gas × max_fee_per_gas / 1e12)for the USDC base (verified:0x3600…0000is a 6-dec view of native USDC — impl has nodeposit/withdraw,balanceOf == native // 1e12on 20/20 addresses, gas payers' native delta ==gasUsed × effectiveGasPrice); other bases priced conservatively viaquote_inon the price-source pool.net ≤ min_profitnever leaves.truncated,cycles_evaluated,rejected{reason}), nothing raised.Live dry-run (LXC 140 local node, 220 consecutive blocks 62413233-62413452, base fee 20 gwei, no tx sent)
0/220 over the 500 ms budget, 0 truncations, 0 stale. 2 distinct net-positive routes every block (testnet toy pools with a real 6× cross-factory price gap): best 2-hop net 0.468034 USDC (gross 0.473234, gas 0.0052), 3-hop 0.443775. Fixtures:
bot/tests/fixtures/search/liveblock_62413099.json(states + logs + ranking + brute-force + result, replayed bit-exact) andliverun3_220blocks_….json(timings + best per route).docs/architecture.md
Based on PR #10's text (so it rebases cleanly after #10): §2.3 optional Opportunity fields (
contentionetc.), §4.2 verification detail + other-base pricing rule, §7 rows for Multicall3 sub-call caps, the independent fee verification, and the measured block-pass timing.Tests:
python3 -m unittest discover -s bot/tests -t .→ 124 OK offline.🤖 Generated with Claude Code
automerger v2 auto-approved: all 7 gates pass. Approver: fortiblox-dev (opposite-identity rule). Gates: mergeable=true,label=auto-merge,author=buddysan,identity=ok,status_checks=not_required,signatures=upstream_BP_only,opt_in=repo_marker.
Auto-merged by forgejo-automerger at 2026-09-16 14:14:26 UTC. Approver:
fortiblox-dev(opposite-identity rule, Option C upgrade 2026-05-13). Merger:buddysanviafast-forward-only(NOT adminforce_merge). Criteria passed:mergeable=true,label=auto-merge,author=buddysan,identity=ok,status_checks=not_required,signatures=upstream_BP_only,opt_in=repo_marker. Branch43e8dbbf35merged ontomainand feature branch deleted. Seeproject_forgejo_automergermemory for rationale.