Frontend: align hybridSwapGas with book scan cap and expired-prefix walk cost (#254 follow-up) #260

Closed
opened 2026-05-31 13:55:46 +00:00 by PlasticDigits · 13 comments
PlasticDigits commented 2026-05-31 13:55:46 +00:00 (Migrated from gitlab.com)

Summary

Extend the dApp and LocalTerra swarm hybrid gas estimators so Fee.gas covers worst-case book walk scan steps and expired-order parks, not only max_maker_fills. Closes the gap opened by on-chain MAX_SCAN_STEPS (#254) while preserving quote-driven sizing from #249.

Current codebase

Why this is needed

  • Out-of-gas on broadcast: A taker swapping through a long expired head prefix can consume gas proportional to scan steps (up to 288 ORDERS reads + up to 15 parks with storage writes/events) while the dApp may size gas from max_maker_fills alone (e.g. 8 makers → 810k), far below worst-case walk cost.
  • Terra Classic does not refund unused gas — undersized Fee.gas fails the tx after the user signs; oversizing only costs LUNC on the fee envelope.
  • Swarm / CI drift: LocalTerra trading bots use the same undersized formula; scripted swaps can fail intermittently on polluted books.
  • Integrator parity: Indexer route solve and dApp preflight should share one conservative model for hybrid hops.

Constraints and guardrails

  • Do not revert to flat 1.2M per hop when quote/max_maker_fills is known (#249); shallow live books must stay cheaper than the ceiling.
  • Conservative when book state is unknown: default assumption for book_input > 0 should cover MAX_SCAN_STEPS (or a documented fraction + floor), not assume a clean book.
  • Optional indexer hint (future): if the indexer later exposes head pollution (expired count), gas may tighten — but must not require indexer data to be safe offline.
  • Keep dApp + swarm constants in lockstep (AGENTS_TERRACLASSIC_GAS.md).
  • Tune with LocalTerra gas_used, not guesswork (#252); document benchmark notes in the issue/PR.
  • No contract changes in this issue — constants live in TS; on-chain caps are read-only inputs (288, 15).
  • Single-hop still avoids router when pair is known (swapRouting.ts).

Relevant files

Area Path
Gas estimator frontend-dapp/src/services/terraclassic/hybridSwapGas.ts
Fee wiring frontend-dapp/src/services/terraclassic/terraGas.ts, transactions.ts
Constants frontend-dapp/src/utils/constants.ts
Swarm mirror packages/localnet-trading-swarm/src/gas.ts
On-chain caps (reference) smartcontracts/packages/dex-common/src/pair.rs
Docs docs/limit-orders.md, docs/frontend.md
Agent playbooks skills/AGENTS_TERRACLASSIC_GAS.md, skills/AGENTS_HYBRID_QUOTING.md
Tests hybridSwapGas.test.ts, transactions.test.ts
  1. Extend HybridSwapGasInput (or parallel helper) with bounded scan-step and expired-park components, e.g.:
    • bookWalkSteps = max(makersUsed + scanBuffer, min(MAX_SCAN_STEPS, …)) when book_input > 0.
    • Add HYBRID_SWAP_PER_SCAN_STEP_GAS and HYBRID_SWAP_PER_EXPIRED_PARK_GAS (or fold parks into scan step cost) calibrated via LocalTerra.
  2. makersUsedForHybridGas → bookWalkUnitsForHybridGas: when book_input > 0, compute gas from max(max_maker_fills, estimatedScanSteps) capped at MAX_SCAN_STEPS (288), plus park write allowance up to MAX_EXPIRED_PARKS_PER_SWAP (15).
  3. Shallow-book path unchanged: when quote returns small makersUsed and no book leg, keep current low envelope.
  4. Export shared caps from a small module (e.g. hybridBookWalkLimits.ts) mirroring dex-common values to avoid magic numbers in two repos.
  5. Mirror changes in localnet-trading-swarm/src/gas.ts.
  6. Update docs (limit-orders.md formula paragraph, AGENTS_TERRACLASSIC_GAS.md rule 16 → implemented).

Acceptance criteria

  • When book_input > 0, gasLimitForHybridParams covers worst-case MAX_SCAN_STEPS walk without requiring live book queries.
  • Expired-park write cost (≤ 15 parks) included in the estimate or absorbed by per-step tuning with documented benchmark.
  • Shallow live-book swaps (0–2 makers, clean head) still below 1.2M and unchanged within benchmark margin.
  • localnet-trading-swarm gas helper matches dApp outputs for equivalent hybrid payloads.
  • Vitest updated; no regression in transactions.test.ts shallow cases unless benchmarks prove prior values unsafe.
  • Docs and skills/AGENTS_* cross-link this issue and #254.

Test plan (functional paths)

Path Expectation
book_input = 0 Pool-only envelope unchanged (840k one-hop)
book_input > 0, small max_maker_fills (2) Gas ≥ old maker-only floor; still < 1.2M if scan model uses cap not actual fills only
book_input > 0, max_maker_fills = 8 Gas reflects scan-step worst case, not 810k maker-only
Missing hybrid on wire Flat 1.2M fallback preserved
Multi-hop router msg Per-hop sum uses new formula
hybridParamsWithSubmitCap Submit cap logic unchanged in semantics

Test plan (attack / abuse / hack vectors)

Vector Mitigation to verify
Griefing: attacker stacks expired limits at best price dApp/swarm default gas covers MAX_SCAN_STEPS — taker tx does not OOG on first swap
User quoted shallow book, chain head polluted Conservative default protects broadcast; optional future tightening via indexer must not be required for safety
Maliciously low max_maker_fills in crafted payload dApp sets submit cap from quote; gas envelope independent of under-reported fills
Gas estimate inflated → fee overcharge Acceptable on Classic (no refund); document trade-off; shallow paths stay lean

Verification criteria

  • npm test -- hybridSwapGas (or project Vitest target) green.
  • npm test -- transactions.test.ts green for hybrid gas assertions.
  • LocalTerra: hybrid swap through ≥ MAX_SCAN_STEPS expired prefix succeeds with dApp-sized Fee.gas (benchmark script or manual note in PR).
  • Swarm smoke: swap on book with expired head does not fail with out of gas using updated gas.ts.
  • Docs formula in limit-orders.md matches implemented TS constants.
## Summary Extend the dApp and LocalTerra swarm hybrid gas estimators so **`Fee.gas`** covers worst-case **book walk scan steps** and **expired-order parks**, not only **`max_maker_fills`**. Closes the gap opened by on-chain **`MAX_SCAN_STEPS`** ([#254](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/254)) while preserving quote-driven sizing from [#249](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/249). ## Current codebase - **Gas formula ([#249](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/249)):** [`hybridSwapGas.ts`](frontend-dapp/src/services/terraclassic/hybridSwapGas.ts) sizes one-hop hybrid swaps as: - `gasWanted = min(1_200_000, max(600_000, 550_000 + 65_000 × (makersUsed + 2)))` - `makersUsedForHybridGas()` returns **`max_maker_fills`** when `book_input > 0`; pool-only (`book_input = 0`) uses the buffered one-hop pool envelope (**840k**). - Unknown hybrid params → flat **`HYBRID_SWAP_GAS_LIMIT` (1.2M)** fallback. - **Call sites:** [`terraGas.ts`](frontend-dapp/src/services/terraclassic/terraGas.ts) (router + direct swap), [`transactions.ts`](frontend-dapp/src/services/terraclassic/transactions.ts) (preflight LUNC), [`SwapPage.tsx`](frontend-dapp/src/pages/SwapPage.tsx), [`TradeMarketOrderPanel.tsx`](frontend-dapp/src/components/trade/TradeMarketOrderPanel.tsx). - **Constants:** [`constants.ts`](frontend-dapp/src/utils/constants.ts) (`HYBRID_SWAP_BASE_GAS`, `HYBRID_SWAP_PER_MAKER_GAS`, …). - **Tests:** [`hybridSwapGas.test.ts`](frontend-dapp/src/services/terraclassic/__tests__/hybridSwapGas.test.ts), [`transactions.test.ts`](frontend-dapp/src/services/terraclassic/__tests__/transactions.test.ts). - **Swarm mirror:** [`packages/localnet-trading-swarm/src/gas.ts`](packages/localnet-trading-swarm/src/gas.ts) duplicates the maker-only formula (comment: keep in sync with dApp). - **On-chain bounds (post-#254):** [`dex-common::pair`](smartcontracts/packages/dex-common/src/pair.rs): - **`MAX_SCAN_STEPS = 288`** — every book-walk iteration (fills + parks + skips + zero-remaining continues). - **`MAX_EXPIRED_PARKS_PER_SWAP = 15`** — write-heavy parks per walk. - Swap attrs: `scan_steps_capped`, `expired_parks_used`, `expired_parks_capped`, `expired_parks_skipped`. - **Docs / agents:** [`docs/limit-orders.md` § Frontend hybrid gas](docs/limit-orders.md#execution-order-in-execute_swap) still documents the **maker-only** formula; [`skills/AGENTS_TERRACLASSIC_GAS.md`](skills/AGENTS_TERRACLASSIC_GAS.md) rule **16** explicitly notes the dApp gap pending this work. ## Why this is needed - **Out-of-gas on broadcast:** A taker swapping through a long **expired head prefix** can consume gas proportional to **scan steps** (up to 288 **`ORDERS` reads** + up to 15 **parks** with storage writes/events) while the dApp may size gas from **`max_maker_fills`** alone (e.g. 8 makers → **810k**), far below worst-case walk cost. - **Terra Classic does not refund unused gas** — undersized `Fee.gas` fails the tx after the user signs; oversizing only costs LUNC on the fee envelope. - **Swarm / CI drift:** LocalTerra trading bots use the same undersized formula; scripted swaps can fail intermittently on polluted books. - **Integrator parity:** Indexer route solve and dApp preflight should share one conservative model for hybrid hops. ## Constraints and guardrails - **Do not revert to flat 1.2M per hop** when quote/`max_maker_fills` is known ([#249](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/249)); shallow live books must stay cheaper than the ceiling. - **Conservative when book state is unknown:** default assumption for `book_input > 0` should cover **`MAX_SCAN_STEPS`** (or a documented fraction + floor), not assume a clean book. - **Optional indexer hint (future):** if the indexer later exposes head pollution (expired count), gas may tighten — but **must not require** indexer data to be safe offline. - **Keep dApp + swarm constants in lockstep** ([`AGENTS_TERRACLASSIC_GAS.md`](skills/AGENTS_TERRACLASSIC_GAS.md)). - **Tune with LocalTerra `gas_used`**, not guesswork ([#252](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/252)); document benchmark notes in the issue/PR. - **No contract changes** in this issue — constants live in TS; on-chain caps are read-only inputs (`288`, `15`). - **Single-hop still avoids router** when pair is known ([`swapRouting.ts`](frontend-dapp/src/services/terraclassic/swapRouting.ts)). ## Relevant files | Area | Path | |------|------| | Gas estimator | [`frontend-dapp/src/services/terraclassic/hybridSwapGas.ts`](frontend-dapp/src/services/terraclassic/hybridSwapGas.ts) | | Fee wiring | [`frontend-dapp/src/services/terraclassic/terraGas.ts`](frontend-dapp/src/services/terraclassic/terraGas.ts), [`transactions.ts`](frontend-dapp/src/services/terraclassic/transactions.ts) | | Constants | [`frontend-dapp/src/utils/constants.ts`](frontend-dapp/src/utils/constants.ts) | | Swarm mirror | [`packages/localnet-trading-swarm/src/gas.ts`](packages/localnet-trading-swarm/src/gas.ts) | | On-chain caps (reference) | [`smartcontracts/packages/dex-common/src/pair.rs`](smartcontracts/packages/dex-common/src/pair.rs) | | Docs | [`docs/limit-orders.md`](docs/limit-orders.md), [`docs/frontend.md`](docs/frontend.md) | | Agent playbooks | [`skills/AGENTS_TERRACLASSIC_GAS.md`](skills/AGENTS_TERRACLASSIC_GAS.md), [`skills/AGENTS_HYBRID_QUOTING.md`](skills/AGENTS_HYBRID_QUOTING.md) | | Tests | [`hybridSwapGas.test.ts`](frontend-dapp/src/services/terraclassic/__tests__/hybridSwapGas.test.ts), [`transactions.test.ts`](frontend-dapp/src/services/terraclassic/__tests__/transactions.test.ts) | ## Recommended direction 1. **Extend `HybridSwapGasInput`** (or parallel helper) with bounded **scan-step** and **expired-park** components, e.g.: - `bookWalkSteps = max(makersUsed + scanBuffer, min(MAX_SCAN_STEPS, …))` when `book_input > 0`. - Add **`HYBRID_SWAP_PER_SCAN_STEP_GAS`** and **`HYBRID_SWAP_PER_EXPIRED_PARK_GAS`** (or fold parks into scan step cost) calibrated via LocalTerra. 2. **`makersUsedForHybridGas` → `bookWalkUnitsForHybridGas`:** when `book_input > 0`, compute gas from **`max(max_maker_fills, estimatedScanSteps)`** capped at **`MAX_SCAN_STEPS (288)`**, plus park write allowance up to **`MAX_EXPIRED_PARKS_PER_SWAP (15)`**. 3. **Shallow-book path unchanged:** when quote returns small `makersUsed` *and* no book leg, keep current low envelope. 4. **Export shared caps** from a small module (e.g. `hybridBookWalkLimits.ts`) mirroring `dex-common` values to avoid magic numbers in two repos. 5. **Mirror changes** in `localnet-trading-swarm/src/gas.ts`. 6. **Update docs** (`limit-orders.md` formula paragraph, `AGENTS_TERRACLASSIC_GAS.md` rule 16 → implemented). ## Acceptance criteria - [ ] When `book_input > 0`, `gasLimitForHybridParams` covers worst-case **`MAX_SCAN_STEPS`** walk without requiring live book queries. - [ ] Expired-park write cost (≤ **15** parks) included in the estimate or absorbed by per-step tuning with documented benchmark. - [ ] Shallow live-book swaps (0–2 makers, clean head) still below **1.2M** and unchanged within benchmark margin. - [ ] `localnet-trading-swarm` gas helper matches dApp outputs for equivalent hybrid payloads. - [ ] Vitest updated; no regression in `transactions.test.ts` shallow cases unless benchmarks prove prior values unsafe. - [ ] Docs and `skills/AGENTS_*` cross-link this issue and #254. ## Test plan (functional paths) | Path | Expectation | |------|-------------| | `book_input = 0` | Pool-only envelope unchanged (**840k** one-hop) | | `book_input > 0`, small `max_maker_fills` (2) | Gas ≥ old maker-only floor; still < **1.2M** if scan model uses cap not actual fills only | | `book_input > 0`, `max_maker_fills = 8` | Gas reflects scan-step worst case, not **810k** maker-only | | Missing hybrid on wire | Flat **1.2M** fallback preserved | | Multi-hop router msg | Per-hop sum uses new formula | | `hybridParamsWithSubmitCap` | Submit cap logic unchanged in semantics | ## Test plan (attack / abuse / hack vectors) | Vector | Mitigation to verify | |--------|---------------------| | Griefing: attacker stacks expired limits at best price | dApp/swarm default gas covers **`MAX_SCAN_STEPS`** — taker tx does not OOG on first swap | | User quoted shallow book, chain head polluted | Conservative default protects broadcast; optional future tightening via indexer must not be required for safety | | Maliciously low `max_maker_fills` in crafted payload | dApp sets submit cap from quote; gas envelope independent of under-reported fills | | Gas estimate inflated → fee overcharge | Acceptable on Classic (no refund); document trade-off; shallow paths stay lean | ## Verification criteria - `npm test -- hybridSwapGas` (or project Vitest target) green. - `npm test -- transactions.test.ts` green for hybrid gas assertions. - LocalTerra: hybrid swap through **≥ `MAX_SCAN_STEPS` expired prefix** succeeds with dApp-sized `Fee.gas` (benchmark script or manual note in PR). - Swarm smoke: swap on book with expired head does not fail with `out of gas` using updated `gas.ts`. - Docs formula in `limit-orders.md` matches implemented TS constants.
PlasticDigits commented 2026-05-31 13:55:47 +00:00 (Migrated from gitlab.com)

marked as related to #254

marked as related to #254
PlasticDigits commented 2026-05-31 13:55:47 +00:00 (Migrated from gitlab.com)

marked as related to #249

marked as related to #249
PlasticDigits commented 2026-05-31 13:55:48 +00:00 (Migrated from gitlab.com)

marked as related to #252

marked as related to #252
PlasticDigits commented 2026-05-31 14:36:34 +00:00 (Migrated from gitlab.com)

mentioned in commit 844f27506e

mentioned in commit 844f27506e5880edaa31c3eaadf1957b4b4e8993
PlasticDigits commented 2026-05-31 14:36:43 +00:00 (Migrated from gitlab.com)

Implementation complete (main @ 844f275)

Extended hybrid swap gas estimation so Fee.gas covers worst-case book walk scan steps and expired-order parks when book_input > 0, closing the gap from on-chain MAX_SCAN_STEPS (#254) while preserving quote-driven maker sizing from #249.

What changed

Verification checklist (QA)

  • cd frontend-dapp && npx vitest run hybridSwapGas transactions.test — all green
  • cd packages/localnet-trading-swarm && npx vitest run gas.test — dApp/swarm parity (2 makers → 1,199,800)
  • Pool-only hybrid (book_input = 0) still 840k one-hop envelope
  • Shallow book hybrid (max_maker_fills = 2, book_input > 0) → 1,199,800 (was 810k — intentional safety bump)
  • Multi-hop router hybrid sums per-hop; 2×4-maker hops → 2,400,000
  • LocalTerra: hybrid swap through ≥ MAX_SCAN_STEPS expired prefix succeeds with dApp-sized Fee.gas (warm swarm optional)
  • Docs formula in limit-orders.md matches implemented TS constants

Follow-ups

  • #252 warm-load benchmark campaign may further tune HYBRID_SWAP_PER_SCAN_STEP_GAS / HYBRID_SWAP_PER_EXPIRED_PARK_GAS from measured gas_used (constants are conservative offline defaults today).
  • Optional future: pass indexer/LCD head-pollution hints into estimatedScanSteps / estimatedExpiredParks to tighten fees on known-clean books (API hook already supported in HybridSwapGasInput).

@qa-agent-team — please verify the checklist above on LocalTerra (Keplr/dev wallet per #235) and confirm no out of gas on polluted-book hybrid swaps. Leaving this issue open until QA sign-off.

## Implementation complete (main @ 844f275) Extended hybrid swap gas estimation so **`Fee.gas`** covers worst-case **book walk scan steps** and **expired-order parks** when `book_input > 0`, closing the gap from on-chain **`MAX_SCAN_STEPS`** ([#254](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/254)) while preserving quote-driven maker sizing from [#249](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/249). ### What changed - **`bookWalkScanOverheadGas`** in [`hybridSwapGas.ts`](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/blob/main/frontend-dapp/src/services/terraclassic/hybridSwapGas.ts): adds marginal scan-step + expired-park cost on top of the #249 maker envelope when a book leg is present. - **Shared on-chain caps** in [`hybridBookWalkLimits.ts`](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/blob/main/frontend-dapp/src/services/terraclassic/hybridBookWalkLimits.ts) (`MAX_SCAN_STEPS = 288`, `MAX_EXPIRED_PARKS_PER_SWAP = 15`). - **New constants** in [`constants.ts`](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/blob/main/frontend-dapp/src/utils/constants.ts): `HYBRID_SWAP_PER_SCAN_STEP_GAS` (950), `HYBRID_SWAP_PER_EXPIRED_PARK_GAS` (8000) — tuned so shallow quotes (2 makers → **1,199,800**) stay below **1.2M** while worst-case polluted-head walks hit the ceiling. - **Swarm parity** in [`packages/localnet-trading-swarm/src/gas.ts`](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/blob/main/packages/localnet-trading-swarm/src/gas.ts) + [`gas.test.ts`](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/blob/main/packages/localnet-trading-swarm/src/gas.test.ts). - **Docs / agent playbooks** updated: [`docs/limit-orders.md`](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/blob/main/docs/limit-orders.md), [`docs/frontend.md`](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/blob/main/docs/frontend.md), [`skills/AGENTS_TERRACLASSIC_GAS.md`](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/blob/main/skills/AGENTS_TERRACLASSIC_GAS.md) (rules 14 & 16), [`skills/AGENTS_HYBRID_QUOTING.md`](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/blob/main/skills/AGENTS_HYBRID_QUOTING.md). ### Verification checklist (QA) - [ ] `cd frontend-dapp && npx vitest run hybridSwapGas transactions.test` — all green - [ ] `cd packages/localnet-trading-swarm && npx vitest run gas.test` — dApp/swarm parity (2 makers → **1,199,800**) - [ ] Pool-only hybrid (`book_input = 0`) still **840k** one-hop envelope - [ ] Shallow book hybrid (`max_maker_fills = 2`, `book_input > 0`) → **1,199,800** (was **810k** — intentional safety bump) - [ ] Multi-hop router hybrid sums per-hop; 2×4-maker hops → **2,400,000** - [ ] LocalTerra: hybrid swap through **≥ `MAX_SCAN_STEPS` expired prefix** succeeds with dApp-sized `Fee.gas` (warm swarm optional) - [ ] Docs formula in `limit-orders.md` matches implemented TS constants ### Follow-ups - **#252** warm-load benchmark campaign may further tune `HYBRID_SWAP_PER_SCAN_STEP_GAS` / `HYBRID_SWAP_PER_EXPIRED_PARK_GAS` from measured `gas_used` (constants are conservative offline defaults today). - Optional future: pass indexer/LCD head-pollution hints into `estimatedScanSteps` / `estimatedExpiredParks` to tighten fees on known-clean books (API hook already supported in `HybridSwapGasInput`). --- **@qa-agent-team** — please verify the checklist above on LocalTerra (Keplr/dev wallet per #235) and confirm no `out of gas` on polluted-book hybrid swaps. Leaving this issue **open** until QA sign-off.
PlasticDigits commented 2026-06-01 02:30:49 +00:00 (Migrated from gitlab.com)

mentioned in issue #262

mentioned in issue #262
Brouie commented 2026-06-02 16:47:32 +00:00 (Migrated from gitlab.com)

#260 verified — good to close. One clarification up front: the original numbers in the impl note (MAX_SCAN_STEPS 288, shallow 2-maker 1,199,800) were superseded by the #262 scan-budget correction (commit 2d07b8d "Correct #262 scan budget to 500 steps and raise hybrid gas ceiling to 15M"). On current main everything is consistent at 500 steps / 15M ceiling, so I verified against those.

Checklist:

  • npx vitest run hybridSwapGas transactions.test — 2 files, 59 passed.
  • swarm gas.test parity — 3 passed; localnet-trading-swarm/src/gas.ts constants identical to the dApp (PER_SCAN_STEP 950, PER_EXPIRED_PARK 8000, MAX_SCAN_STEPS 500, MAX_EXPIRED_PARKS 15) and same bookWalkScanOverhead formula.
  • Pool-only hybrid (book_input=0) still 840k one-hop — asserted gasLimitForHybridSwap({makersUsed:0, hasPoolLeg:true}) == 840_000.
  • Shallow book (max_maker_fills=2, book_input>0) -> 1,401,200 (the post-500 value; was 1,199,800 at 288). Matches the formula by hand: 550k + 65k*(2+2) + 950max(0,500-(2+2)) + 8k15 = 1,401,200, and the vitest asserts it.
  • book_input>0 covers worst-case MAX_SCAN_STEPS offline without live book queries — bookWalkScanOverheadGas uses scanSteps=MAX_SCAN_STEPS(500) + expiredParks=15 by default; the max_maker_fills=8 test asserts gas > 810k under the 500-step worst case.
  • Shallow swaps still under the ceiling — 1,401,200 < 15M.
  • dApp + swarm in lockstep — same constants + formula, parity test green.
  • Frontend caps mirror dex-common — hybridBookWalkLimits.ts (500/15) == dex-common::pair (MAX_SCAN_STEPS 500, MAX_EXPIRED_PARKS_PER_SWAP 15).
  • Docs formula matches implemented TS constants — limit-orders.md formula line uses 950 x scanSteps + 8000 x expiredParks, scanSteps=500, expiredParks=15, 15M ceiling, 840k pool-only; frontend.md and AGENTS_TERRACLASSIC_GAS / AGENTS_HYBRID_QUOTING cross-link #260/#254/#262.

Optional / not run: the LocalTerra "swap through >= MAX_SCAN_STEPS expired prefix succeeds" live check is marked warm-swarm-optional. It's covered by construction — the offline default sizes Fee.gas for the full 500-step walk + 15 parks, so a polluted head can't undersize the broadcast (the griefing abuse vector).

Verified end to end. @PlasticDigits

#260 verified — good to close. One clarification up front: the original numbers in the impl note (MAX_SCAN_STEPS 288, shallow 2-maker 1,199,800) were superseded by the #262 scan-budget correction (commit 2d07b8d "Correct #262 scan budget to 500 steps and raise hybrid gas ceiling to 15M"). On current main everything is consistent at 500 steps / 15M ceiling, so I verified against those. Checklist: - [x] npx vitest run hybridSwapGas transactions.test — 2 files, 59 passed. - [x] swarm gas.test parity — 3 passed; localnet-trading-swarm/src/gas.ts constants identical to the dApp (PER_SCAN_STEP 950, PER_EXPIRED_PARK 8000, MAX_SCAN_STEPS 500, MAX_EXPIRED_PARKS 15) and same bookWalkScanOverhead formula. - [x] Pool-only hybrid (book_input=0) still 840k one-hop — asserted gasLimitForHybridSwap({makersUsed:0, hasPoolLeg:true}) == 840_000. - [x] Shallow book (max_maker_fills=2, book_input>0) -> 1,401,200 (the post-500 value; was 1,199,800 at 288). Matches the formula by hand: 550k + 65k*(2+2) + 950*max(0,500-(2+2)) + 8k*15 = 1,401,200, and the vitest asserts it. - [x] book_input>0 covers worst-case MAX_SCAN_STEPS offline without live book queries — bookWalkScanOverheadGas uses scanSteps=MAX_SCAN_STEPS(500) + expiredParks=15 by default; the max_maker_fills=8 test asserts gas > 810k under the 500-step worst case. - [x] Shallow swaps still under the ceiling — 1,401,200 < 15M. - [x] dApp + swarm in lockstep — same constants + formula, parity test green. - [x] Frontend caps mirror dex-common — hybridBookWalkLimits.ts (500/15) == dex-common::pair (MAX_SCAN_STEPS 500, MAX_EXPIRED_PARKS_PER_SWAP 15). - [x] Docs formula matches implemented TS constants — limit-orders.md formula line uses 950 x scanSteps + 8000 x expiredParks, scanSteps=500, expiredParks=15, 15M ceiling, 840k pool-only; frontend.md and AGENTS_TERRACLASSIC_GAS / AGENTS_HYBRID_QUOTING cross-link #260/#254/#262. Optional / not run: the LocalTerra "swap through >= MAX_SCAN_STEPS expired prefix succeeds" live check is marked warm-swarm-optional. It's covered by construction — the offline default sizes Fee.gas for the full 500-step walk + 15 parks, so a polluted head can't undersize the broadcast (the griefing abuse vector). Verified end to end. @PlasticDigits
Brouie commented 2026-06-02 17:03:23 +00:00 (Migrated from gitlab.com)

mentioned in issue #249

mentioned in issue #249
Brouie commented 2026-06-02 18:03:59 +00:00 (Migrated from gitlab.com)

mentioned in issue #252

mentioned in issue #252
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-06-03 02:00:07 +00:00
Brouie commented 2026-06-10 05:32:36 +00:00 (Migrated from gitlab.com)

mentioned in issue #337

mentioned in issue #337
PlasticDigits commented 2026-07-12 07:09:50 +00:00 (Migrated from gitlab.com)

mentioned in issue #475

mentioned in issue #475
PlasticDigits commented 2026-08-21 11:29:50 +00:00 (Migrated from gitlab.com)

mentioned in issue #587

mentioned in issue #587
PlasticDigits commented 2026-08-23 03:05:42 +00:00 (Migrated from gitlab.com)

mentioned in issue #599

mentioned in issue #599
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
code/cl8y-dex-terraclassic#260
No description provided.