Hybrid reverse simulation: reduce redundant book walks in query #257
Labels
No labels
agent:fix_bugfix
agent:fix_conflicts
agent:fix_security
agent:gap_analysis
agent:implement
agent:implement
agent:implement
agent:open_issues
agent:ready
agent:research
agent:security_audit
agent:verify
architecture
backend
blocker:hybrid
blocker:launch
blocker:limit-orders
blocker:v2
block:log_only
block:security
bug
ci
contracts
correctness
deploy
dev
devops
docs
documentation
duplicate
e2e
enhancement
epic
feature
frontend
functional-completion
gas
good first issue
governance
help wanted
high-risk
hooks
hybrid
indexer
infra
infrastructure
integrators
invalid
launch-blocker
limit-orders
localnet
localterra
low priority
missing-implementation
needs-design
ops
performance
priority
high
priority
medium
product
qa
QA
question
ready
ready
research
scripts
security
security-hardening
smartcontracts
tech-debt
testing
ux
UX
v2
verification
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
code/cl8y-dex-terraclassic#257
Loading…
Add table
Add a link
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
Optimize
HybridReverseSimulationso it does not re-walk the limit book on every exponential/binary-search iteration; seed search bounds from closed-form pool math and minimize fullsimulate_hybrid_swap_with_feecalls.Current codebase
query_hybrid_reverse_simulationinsmartcontracts/contracts/pair/src/contract.rs.effective_fee_bps_for_sim) — good (#238 guardrail).hidoubles up to 128 iterations, each callingsimulate_hybrid_swap_with_feewithscale_hybrid_template(&hybrid, hi).lo..r_hi, each iteration another full simulation.r_hi.simulate_hybrid_swap_with_feecan invokesimulate_match_bids/simulate_match_asks(full book walk up tomax_maker_fills) plus pool AMM math.HybridReverseSimulationper hop (smartcontracts/contracts/router/src/contract.rs) — cost multiplies by hops (≤ 4).smartcontracts/tests/src/lib.rs,limit_order_tests.rs(reverse sim cases).Why this is needed
Constraints and guardrails
offer_amountmust remain minimal offer achievingask_targetreturn (same as today’s search invariant); rounding must not under-quote vs execute.pool_only_hybrid_templatepaths).scale_hybrid_templatepreservespool_input : book_inputratio — any optimizer must respect hybrid scaling semantics.MAX_SCAN_STEPS) lands first, simulation must use identical book walk bounds as execute.Relevant files
smartcontracts/contracts/pair/src/contract.rs(query_hybrid_reverse_simulation,simulate_hybrid_swap_with_fee)smartcontracts/contracts/pair/src/orderbook.rs(simulate_match_*)smartcontracts/packages/dex-common/src/pair.rs(HybridReverseSimulationResponse,HybridSwapParams)smartcontracts/contracts/router/src/contract.rsdocs/limit-orders.md,skills/AGENTS_HYBRID_QUOTING.mdsmartcontracts/tests/src/lib.rs,limit_order_tests.rsRecommended direction
pool_inputslice only (existing reserve math in swap/sim helpers) to seedhi/ shrink 128-iteration ramp.hybridratio, book return is non-decreasing in offer; binary search remains valid — reduce iterations by better initialhi(e.g. pool quote + book quote separately, sum).Acceptance criteria
HybridReverseSimulationreturns identicaloffer_amount(and fee breakdown fields) as baseline on existing test vectors.Test plan (functional paths)
ask_target= 0Test plan (attack / abuse / hack vectors)
ask_targethybridratioHybridSplitMismatch/ validation unchangedVerification criteria
cargo test).docs/contracts-terraclassic.mdor limit-orders quoting section.mentioned in commit
777ac45db4Implemented (main @
777ac45)Optimized
HybridReverseSimulationto reduce redundant full hybrid simulations on LCD/indexer reverse quotes.Code
smartcontracts/contracts/pair/src/hybrid_reverse.rs: pool CP reverse math seeds the upper offer bound;MAX_HYBRID_REVERSE_SIM_CALLS = 32caps fullsimulate_hybrid_swap_with_feecalls per query.query_hybrid_reverse_simulationuses seeded upper bound + binary search (replaces 128-step exponential ramp). Fee discount still resolved once per query (#238 guardrail).limit_order_tests::hybrid_reverse_sim_minimal_offer_invariant(pool-only, book-only, 40/60, 50/50 splits).Docs / agent playbooks
docs/contracts-security-audit.mddocs/limit-orders.md,docs/contracts-terraclassic.md,docs/adr/0001-hybrid-quoting-and-routing.mdskills/AGENTS_HYBRID_QUOTING.mdVerification checklist
cd smartcontracts && cargo test -p cl8y-dex-pair hybrid_reversecd smartcontracts && cargo test -p cl8y-dex-tests limit_order_tests::hybrid_reverse_sim_minimal_offer_invariantcd smartcontracts && cargo test -p cl8y-dex-tests test_reverse_simulation test_router_reverse_simulatecd smartcontracts && cargo test -p cl8y-dex-tests hybrid_pool_and_book hybrid_simulation_matches_executereverse_simulate_swap_operationson a book+pool hop matches pre-deploy quotes for same snapshotFollow-up (optional)
@qa-agent-team — please verify on
main(777ac45): minimal-offer invariant tests above, router reverse multi-hop, and that discountedtraderreverse quotes still match execute after deploy.Issue left open until QA sign-off.
Verified #257 on
main@6b22feb(777ac45, live on LocalTerra). Source + the reverse-sim test suite + live router equivalence and a discounted reverse↔execute round-trip. This is a read-only optimization, so the bar is correctness — minimal offer, no under-quote — and that holds.Headline — no under-quote + sim↔execute parity, proven live
On a deep book (300+ resting orders), reverse-quoted a discounted trader (test1, 95% tier) for target return 50,000,000 T1, hybrid 50/50 book+pool:
code=0,return_amount=50,000,000(≥ target),effective_fee_bps=9(base 180 × 5% after the 95% discount)Discount is applied in the reverse path too: discounted offer 44,579,693 < undiscounted 45,340,115 for the same target.
Acceptance criteria
offer_amount+ breakdown vs baseline: source —query_hybrid_reverse_simulationkeeps the same search invariant (minimal offer where the full sim's return ≥ target) and ends on a final validatingrun_sim(r_hi); the new pool-CP seed (seed_upper_offer_from_pool_math,ceil_divconservative) only changes how the upper bound is found, not the convergence target. Testshybrid_reverse_sim_minimal_offer_invariant(pool-only / book-only / 40-60 / 50-50),test_reverse_simulation(_b_to_a),hybrid_simulation_matches_execute_with_fee_discount. Live: minimal offer (return == target exactly). (layer note below)InsufficientLiquidityfrom the sim + an offer-overflow guard in the doubling loop. Teststest_reverse_simulation_with_100_pct_fee_rejected,test_reverse_simulation_with_wrong_asset_rejected.test_router_reverse_simulate. Live: routerreverse_simulate_swap_operations(book+pool hop) offer 45,340,115 == pairHybridReverseSimulation45,340,115 — identical (router delegates to the pair per hop).(AC2 is the one open item — see below.)
Functional + attack plans
ask_target=0, insufficient depth):ask_target==0→zero offer andbook_input==0→pool-only-parity seed (source) + the invariant test grid + live discounted 50/50.ask_target→ bounded byMAX_HYBRID_REVERSE_SIM_CALLS=32(source + live, queries completed); manipulated hybrid ratio →scale_hybrid_templatevalidation (source); quote-below-execute → min-offer invariant test + live no-under-quote (executed at the quote, realized ≥ target); DoS via repeated LCD query → per-query 32-call cap.Guardrails confirmed (source)
effective_fee_bps_for_simbefore the search, reused across iterations) — the #238 guardrail, not re-queried per iteration.simulate_match_*→ the sameMAX_SCAN_STEPS(288) book-walk bounds as execute (#254), so reverse quotes can't out-walk the execute path.Dev checklist
cargo test -p cl8y-dex-pair hybrid_reverse— 2/0hybrid_reverse_sim_minimal_offer_invariant— passtest_reverse_simulation+test_router_reverse_simulate— passhybrid_pool_and_book+hybrid_simulation_matches_execute*— passreverse_simulate_swap_operationson a book+pool hop — live, matches the pair reverse exactlyLayer honesty
MAX_HYBRID_REVERSE_SIM_CALLS=32cap + pool-seeded binary search complete and return a quote on a 300+-order deep book — exactly the case where the old 128-step exponential ramp (≈128 + log₂ + 2 full sims) could blow the query-gas / indexer-timeout budget.test_router_reverse_simulate); live I confirmed single-hop router↔pair equivalence (the router calls the pairHybridReverseSimulationper hop, so multi-hop is that, composed).@PlasticDigits — verified and signed off from my side, no issues found (minimal offer, no under-quote, discounted reverse↔execute parity exact, bounded query work); over to you to close.
mentioned in issue #258