Hybrid swap gas (frontend): quote-driven gas limits + single-hop direct-to-pair audit #249

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

Summary

Reduce LUNC fees on hybrid swaps by (1) sizing gas limits from the route quote (makers used per hop) instead of a flat 1.2M/hop, and (2) auditing and standardizing single-hop direct-to-pair execution (skip router SubMsg/reply overhead).

Current codebase

Gas model (flat, padded)

  • HYBRID_SWAP_GAS_LIMIT = 1_200_000 per hop (frontend-dapp/src/services/terraclassic/terraGas.ts).
  • Multi-hop: gasLimitForExecuteSwapOperations scales hops but hybrid floor is still 1.2M × hops when any hop has hybrid params.
  • Terra Classic: fee = gas_limit × gas_price; unused gas is not refunded — over-estimation directly costs users LUNC.

Route quote already knows book depth

  • Indexer POST /api/v1/route/solve returns hybrid routing with per-hop simulation (makers touched).
  • TradeMarketOrderPanel / SwapPage use indexer ops when present; simulation includes book leg sizing.
  • max_maker_fills in HybridSwapParams is set from UI/route but gas budget ignores it.

Direct-to-pair vs router

  • Trade market tab (TradeMarketOrderPanel.tsx ~341–357): if idxOps.length === 0 → swap() direct to pair with hybrid; if multi-hop → executeMultiHopSwap via router.
  • SwapPage (SwapPage.tsx ~564): single-hop uses direct swap() with hybrid when directPair exists.
  • Router path (router.ts, contract.rs): each hop = CW20 Send + SubMsg::reply_on_success + balance delta queries (~2 CW20 balance reads per hop).

Gap: Gas preflight still uses flat hybrid constants; any remaining single-hop paths through router should be eliminated; max_maker_fills not tied to quote.

Why this is needed

Most retail trades are single-hop, shallow book (0–2 maker fills). Paying for 1.2M gas when ~600–800k suffices wastes LUNC on every swap. Router overhead on unnecessary single-hop adds latency and gas beyond the pair execute itself.

Constraints / guardrails

  • Safety margin: gas_limit = base + perMaker × (makersUsed + buffer) with buffer ≥ 1–2; never below observed gas_used from QA/localterra (#115, #114 regression floors in transactions.test.ts).
  • Fallback: When quote unavailable, use current conservative flat limit (do not under-gas).
  • Multi-hop: Per-hop makers from indexer ops; sum gas across hops for preflight native-LUNC gate.
  • Router retained: Only for ≥ 2 hop routes; do not break Terraport-style multi-hop.
  • Trusted router / trader field: Direct pair path must still pass trader when using router elsewhere; direct pair uses CW20 sender as trader unless discount router pattern applies.
  • Do not change on-chain semantics — frontend-only (+ possibly pass tighter max_maker_fills from quote).

Relevant files

File Role
frontend-dapp/src/services/terraclassic/terraGas.ts Gas constants, getGasLimitForTx
frontend-dapp/src/services/terraclassic/transactions.ts Preflight fee totals
frontend-dapp/src/components/trade/TradeMarketOrderPanel.tsx Market swap submit + sim
frontend-dapp/src/pages/SwapPage.tsx Swap page routing
frontend-dapp/src/services/terraclassic/router.ts Multi-hop only
frontend-dapp/src/services/terraclassic/pair.ts Direct swap()
frontend-dapp/src/utils/constants.ts Gas floors
frontend-dapp/src/services/terraclassic/__tests__/transactions.test.ts Gas regression tests
docs/limit-orders.md Hybrid gas documentation
  1. Dynamic gas function: gasLimitForHybridSwap({ makersUsed, hasPoolLeg, hopCount }) ≈ HYBRID_BASE + HYBRID_PER_MAKER × (makersUsed + buffer); calibrate from localterra measurements post-#248 (transfer aggregation).
  2. Wire quote → gas: Pass makersUsed from indexer sim / pair HybridSimulation into fee builder at submit time; set max_maker_fills = makersUsed + buffer in hybrid params (cap at MAX_MAKER_FILLS_HARD_CAP).
  3. Audit: Grep all execute_swap_operations / executeMultiHopSwap call sites; ensure single-hop never uses router; document matrix in PR.
  4. UI: Optional fee hint showing estimated vs flat savings on shallow book.
  5. Update regression tests: shallow-book case uses lower limit; deep-book / no-quote uses floor.

Acceptance criteria

  • Single-hop hybrid with 0–2 makers: gas limit ≤ flat 1.2M (measurable lower bound in tests).
  • Single-hop never routes through router when pair address known.
  • Multi-hop still uses router; gas = sum of per-hop dynamic estimates.
  • No-quote fallback: conservative limit (current behavior).
  • max_maker_fills aligned with quote + buffer (does not truncate valid fills under normal conditions).
  • Native LUNC preflight gate uses new estimate (evaluateMarketSwapNativeGasPlaceGate).
  • Existing #115/#114 gas floor tests updated with new formula floors, not removed.

Test plan — functional paths

  • Unit: gasLimitForHybridSwap(0), (2), (10) monotonic, bounded.
  • Unit: getGasLimitForTx on direct pair send + inner hybrid swap msg.
  • Integration: Trade market swap single-hop broadcasts with reduced fee; tx succeeds on localterra.
  • Multi-hop 2-hop: gas = hop1 + hop2 estimates.
  • SwapPage direct pair path unchanged functionally.
  • Preflight rejects when native balance < new (lower) estimate still passes when sufficient.

Test plan — attack / abuse

  • Under-gas griefing (self): Quote under-estimates makers → tx fails out-of-gas; user funds safe; UI shows retry with higher gas (fallback path).
  • max_maker_fills too tight: Adversarial book adds orders at quote time → fill truncated not OOG (prefer buffer).
  • Manipulated indexer quote: Client-side quote ignored for gas when stale; on-chain sim fallback or max cap.

Verification criteria

  • npm test in frontend-dapp green.
  • Document measured gas_used vs gas_limit for 0/2/5 makers on localterra in PR or docs/limit-orders.md.
  • Manual trade on /trade market tab: successful hybrid swap with lower fee than pre-change screenshot/log.
## Summary Reduce LUNC fees on hybrid swaps by (1) **sizing gas limits from the route quote** (makers used per hop) instead of a flat **1.2M/hop**, and (2) **auditing and standardizing single-hop direct-to-pair** execution (skip router SubMsg/reply overhead). ## Current codebase ### Gas model (flat, padded) - `HYBRID_SWAP_GAS_LIMIT = 1_200_000` per hop (`frontend-dapp/src/services/terraclassic/terraGas.ts`). - Multi-hop: `gasLimitForExecuteSwapOperations` scales hops but hybrid floor is still **1.2M × hops** when any hop has hybrid params. - **Terra Classic:** fee = `gas_limit × gas_price`; **unused gas is not refunded** — over-estimation directly costs users LUNC. ### Route quote already knows book depth - Indexer **`POST /api/v1/route/solve`** returns hybrid routing with per-hop simulation (makers touched). - `TradeMarketOrderPanel` / `SwapPage` use indexer ops when present; simulation includes book leg sizing. - **`max_maker_fills`** in `HybridSwapParams` is set from UI/route but gas budget ignores it. ### Direct-to-pair vs router - **Trade market tab** (`TradeMarketOrderPanel.tsx` ~341–357): if `idxOps.length === 0` → **`swap()` direct to pair** with hybrid; if multi-hop → `executeMultiHopSwap` via router. - **SwapPage** (`SwapPage.tsx` ~564): single-hop uses direct `swap()` with hybrid when `directPair` exists. - **Router path** (`router.ts`, `contract.rs`): each hop = CW20 `Send` + **`SubMsg::reply_on_success`** + balance delta queries (~2 CW20 balance reads per hop). **Gap:** Gas preflight still uses flat hybrid constants; any remaining single-hop paths through router should be eliminated; `max_maker_fills` not tied to quote. ## Why this is needed Most retail trades are **single-hop, shallow book** (0–2 maker fills). Paying for 1.2M gas when ~600–800k suffices wastes LUNC on every swap. Router overhead on unnecessary single-hop adds latency and gas beyond the pair execute itself. ## Constraints / guardrails - **Safety margin:** `gas_limit = base + perMaker × (makersUsed + buffer)` with buffer ≥ 1–2; never below observed `gas_used` from QA/localterra (#115, #114 regression floors in `transactions.test.ts`). - **Fallback:** When quote unavailable, use current conservative flat limit (do not under-gas). - **Multi-hop:** Per-hop makers from indexer ops; sum gas across hops for preflight native-LUNC gate. - **Router retained:** Only for **≥ 2 hop** routes; do not break Terraport-style multi-hop. - **Trusted router / trader field:** Direct pair path must still pass `trader` when using router elsewhere; direct pair uses CW20 sender as trader unless discount router pattern applies. - **Do not change on-chain semantics** — frontend-only (+ possibly pass tighter `max_maker_fills` from quote). ## Relevant files | File | Role | |------|------| | `frontend-dapp/src/services/terraclassic/terraGas.ts` | Gas constants, `getGasLimitForTx` | | `frontend-dapp/src/services/terraclassic/transactions.ts` | Preflight fee totals | | `frontend-dapp/src/components/trade/TradeMarketOrderPanel.tsx` | Market swap submit + sim | | `frontend-dapp/src/pages/SwapPage.tsx` | Swap page routing | | `frontend-dapp/src/services/terraclassic/router.ts` | Multi-hop only | | `frontend-dapp/src/services/terraclassic/pair.ts` | Direct `swap()` | | `frontend-dapp/src/utils/constants.ts` | Gas floors | | `frontend-dapp/src/services/terraclassic/__tests__/transactions.test.ts` | Gas regression tests | | `docs/limit-orders.md` | Hybrid gas documentation | ## Recommended solution direction 1. **Dynamic gas function:** `gasLimitForHybridSwap({ makersUsed, hasPoolLeg, hopCount })` ≈ `HYBRID_BASE + HYBRID_PER_MAKER × (makersUsed + buffer)`; calibrate from localterra measurements post-#248 (transfer aggregation). 2. **Wire quote → gas:** Pass `makersUsed` from indexer sim / pair `HybridSimulation` into fee builder at submit time; set `max_maker_fills = makersUsed + buffer` in hybrid params (cap at `MAX_MAKER_FILLS_HARD_CAP`). 3. **Audit:** Grep all `execute_swap_operations` / `executeMultiHopSwap` call sites; ensure single-hop never uses router; document matrix in PR. 4. **UI:** Optional fee hint showing estimated vs flat savings on shallow book. 5. Update regression tests: shallow-book case uses lower limit; deep-book / no-quote uses floor. ## Acceptance criteria - [ ] Single-hop hybrid with 0–2 makers: gas limit ≤ flat 1.2M (measurable lower bound in tests). - [ ] Single-hop never routes through router when pair address known. - [ ] Multi-hop still uses router; gas = sum of per-hop dynamic estimates. - [ ] No-quote fallback: conservative limit (current behavior). - [ ] `max_maker_fills` aligned with quote + buffer (does not truncate valid fills under normal conditions). - [ ] Native LUNC preflight gate uses new estimate (`evaluateMarketSwapNativeGasPlaceGate`). - [ ] Existing #115/#114 gas floor tests updated with new formula floors, not removed. ## Test plan — functional paths - [ ] Unit: `gasLimitForHybridSwap(0)`, `(2)`, `(10)` monotonic, bounded. - [ ] Unit: `getGasLimitForTx` on direct pair `send` + inner hybrid swap msg. - [ ] Integration: Trade market swap single-hop broadcasts with reduced fee; tx succeeds on localterra. - [ ] Multi-hop 2-hop: gas = hop1 + hop2 estimates. - [ ] SwapPage direct pair path unchanged functionally. - [ ] Preflight rejects when native balance < new (lower) estimate still passes when sufficient. ## Test plan — attack / abuse - [ ] **Under-gas griefing (self):** Quote under-estimates makers → tx fails out-of-gas; user funds safe; UI shows retry with higher gas (fallback path). - [ ] **max_maker_fills too tight:** Adversarial book adds orders at quote time → fill truncated not OOG (prefer buffer). - [ ] **Manipulated indexer quote:** Client-side quote ignored for gas when stale; on-chain sim fallback or max cap. ## Verification criteria - [ ] `npm test` in frontend-dapp green. - [ ] Document measured `gas_used` vs `gas_limit` for 0/2/5 makers on localterra in PR or `docs/limit-orders.md`. - [ ] Manual trade on `/trade` market tab: successful hybrid swap with lower fee than pre-change screenshot/log.
PlasticDigits commented 2026-05-31 12:29:12 +00:00 (Migrated from gitlab.com)

mentioned in issue #252

mentioned in issue #252
PlasticDigits commented 2026-05-31 12:29:13 +00:00 (Migrated from gitlab.com)

marked as related to #252

marked as related to #252
PlasticDigits commented 2026-05-31 12:29:18 +00:00 (Migrated from gitlab.com)

mentioned in issue #248

mentioned in issue #248
PlasticDigits commented 2026-05-31 13:10:23 +00:00 (Migrated from gitlab.com)

mentioned in commit 0be09de77c

mentioned in commit 0be09de77c28c09b9e5d5a52089a05226532085e
PlasticDigits commented 2026-05-31 13:15:39 +00:00 (Migrated from gitlab.com)

mentioned in commit d58704820c

mentioned in commit d58704820c80fbf0184051b72e5a097537da876d
PlasticDigits commented 2026-05-31 13:15:59 +00:00 (Migrated from gitlab.com)

Implementation summary (pushed to main @ d587048)

Implemented GitLab #249 — quote-driven hybrid swap gas limits and single-hop direct-to-pair execution.

What changed

  1. Dynamic hybrid gas (frontend-dapp/src/services/terraclassic/hybridSwapGas.ts)

    • gasWanted ≈ min(1.2M, max(600k, 550k + 65k × (max_maker_fills + 2))) per hop with book leg
    • Pool-only hybrid (book_input = 0) → buffered one-hop pool envelope (840k)
    • Missing/invalid hybrid params → conservative 1.2M fallback
    • Multi-hop router paths sum per-hop estimates
  2. Single-hop routing (swapRouting.ts)

    • Router only when indexerOperations.length ≥ 2
    • Trade market and Swap use direct swap() for single-hop (avoids router SubMsg/reply overhead)
    • max_maker_fills capped at submit via hybridParamsWithSubmitCap (quote cap + buffer)
  3. Preflight — estimateMarketPairSwapSequenceUlunaFeesTotal accepts live hybrid params for native LUNC gate alignment

  4. Docs / agent playbooks — docs/limit-orders.md, docs/frontend.md, skills/AGENTS_TERRACLASSIC_GAS.md (rule 14), AGENTS_HYBRID_QUOTING.md, AGENTS_E2E_HYBRID_SWAP.md

  5. Localnet swarm — packages/localnet-trading-swarm/src/gas.ts kept in lockstep

Verification checklist

  • cd frontend-dapp && npm test — green (includes new hybridSwapGas.test.ts, swapRouting.test.ts, updated transactions.test.ts)
  • LocalTerra: /trade market tab — single-hop hybrid swap succeeds with lower gas_wanted than flat 1.2M when max_maker_fills ≤ 2 (compare tx log / Keplr fee)
  • LocalTerra: shallow book — gas_used < gas_wanted and tx succeeds (no OOG)
  • Multi-hop (2+ hops) still routes via router; fee estimate ≈ sum of per-hop dynamic limits
  • Swap page direct pair + indexer 1-hop — broadcasts to pair contract, not router
  • Native LUNC preflight on market tab still blocks when balance < estimateMarketPairSwapSequenceUlunaFeesTotal(hybrid)

Follow-ups

  • Record measured gas_used vs gas_wanted for 0/2/5 makers on LocalTerra in #252 / docs/limit-orders.md once QA benchmarks land.

@qa-agent-team — please verify the checklist above on LocalTerra (Keplr or dev wallet per #235; not Station). Issue remains open until sign-off.

## Implementation summary (pushed to `main` @ `d587048`) Implemented **GitLab #249** — quote-driven hybrid swap gas limits and single-hop direct-to-pair execution. ### What changed 1. **Dynamic hybrid gas** (`frontend-dapp/src/services/terraclassic/hybridSwapGas.ts`) - `gasWanted ≈ min(1.2M, max(600k, 550k + 65k × (max_maker_fills + 2)))` per hop with book leg - Pool-only hybrid (`book_input = 0`) → buffered one-hop pool envelope (**840k**) - Missing/invalid hybrid params → conservative **1.2M** fallback - Multi-hop router paths **sum** per-hop estimates 2. **Single-hop routing** (`swapRouting.ts`) - Router only when `indexerOperations.length ≥ 2` - **Trade market** and **Swap** use direct `swap()` for single-hop (avoids router SubMsg/reply overhead) - `max_maker_fills` capped at submit via `hybridParamsWithSubmitCap` (quote cap + buffer) 3. **Preflight** — `estimateMarketPairSwapSequenceUlunaFeesTotal` accepts live hybrid params for native LUNC gate alignment 4. **Docs / agent playbooks** — `docs/limit-orders.md`, `docs/frontend.md`, `skills/AGENTS_TERRACLASSIC_GAS.md` (rule 14), `AGENTS_HYBRID_QUOTING.md`, `AGENTS_E2E_HYBRID_SWAP.md` 5. **Localnet swarm** — `packages/localnet-trading-swarm/src/gas.ts` kept in lockstep ### Verification checklist - [ ] `cd frontend-dapp && npm test` — green (includes new `hybridSwapGas.test.ts`, `swapRouting.test.ts`, updated `transactions.test.ts`) - [ ] LocalTerra: `/trade` market tab — single-hop hybrid swap succeeds with **lower** `gas_wanted` than flat 1.2M when `max_maker_fills ≤ 2` (compare tx log / Keplr fee) - [ ] LocalTerra: shallow book — `gas_used < gas_wanted` and tx succeeds (no OOG) - [ ] Multi-hop (2+ hops) still routes via router; fee estimate ≈ sum of per-hop dynamic limits - [ ] Swap page direct pair + indexer 1-hop — broadcasts to **pair** contract, not router - [ ] Native LUNC preflight on market tab still blocks when balance < `estimateMarketPairSwapSequenceUlunaFeesTotal(hybrid)` ### Follow-ups - Record measured `gas_used` vs `gas_wanted` for 0/2/5 makers on LocalTerra in #252 / `docs/limit-orders.md` once QA benchmarks land. --- **@qa-agent-team** — please verify the checklist above on LocalTerra (Keplr or dev wallet per #235; not Station). Issue remains **open** until sign-off.
PlasticDigits commented 2026-05-31 13:55:46 +00:00 (Migrated from gitlab.com)

mentioned in issue #260

mentioned in issue #260
PlasticDigits commented 2026-05-31 13:55:47 +00:00 (Migrated from gitlab.com)

marked as related to #260

marked as related to #260
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-06-01 02:30:49 +00:00 (Migrated from gitlab.com)

mentioned in issue #262

mentioned in issue #262
Brouie commented 2026-06-02 17:03:23 +00:00 (Migrated from gitlab.com)

#249 verified — good to close. Quote-driven hybrid gas + single-hop direct-to-pair are both in place. (#249 is the base formula that #260/#262 later extended — verified at current main values.)

Checklist:

  • frontend npm test (hybridSwapGas + swapRouting + transactions) — 3 files, 61 passed.
  • Single-hop never routes through router when pair known — swapOpsRequireRouter(ops) returns ops.length >= 2; single-hop pulls hybrid via hybridFromSingleHopIndexerOps and executes direct swap() to the pair. swapRouting.test.ts asserts "requires router only for 2+ hops" (undefined/1-hop -> false, 2-hop -> true).
  • Multi-hop still uses router; gas = sum of per-hop dynamic estimates — same swapOpsRequireRouter gate; hybridSwapGas sums per hop.
  • No-quote fallback stays conservative — missing/invalid hybrid -> flat fallback.
  • max_maker_fills aligned with quote + buffer — hybridParamsWithSubmitCap / maxMakerFillsForSubmit caps from the quote.
  • Native LUNC preflight uses the new estimate — estimateMarketPairSwapSequenceUlunaFeesTotal accepts live hybrid params (transactions.test.ts).
  • #115/#114 gas floors updated, not removed — transactions.test.ts still asserts the regression floors.
  • dApp + swarm lockstep — verified under #260 (identical constants + formula).

Note on the "single-hop 0-2 makers <= 1.2M" target: pool-only (book_input=0) is 840k, so the fee saving vs the old flat 1.2M holds there. The shallow book-leg case is now 1,401,200 because #260/#262 raised book-leg sizing to cover the worst-case 500-step scan (MAX_SCAN_STEPS) + 15 parks — a deliberate OOG-safety bump that supersedes the original <=1.2M for book-leg swaps. The quote-driven sizing mechanism and single-hop routing from #249 are unchanged underneath.

Live /trade single-hop hybrid (lower gas_wanted than flat when shallow; gas_used < gas_wanted, no OOG) is the browser layer; the routing + gas logic is fully unit-covered here.

Verified end to end. @PlasticDigits

#249 verified — good to close. Quote-driven hybrid gas + single-hop direct-to-pair are both in place. (#249 is the base formula that #260/#262 later extended — verified at current main values.) Checklist: - [x] frontend npm test (hybridSwapGas + swapRouting + transactions) — 3 files, 61 passed. - [x] Single-hop never routes through router when pair known — swapOpsRequireRouter(ops) returns ops.length >= 2; single-hop pulls hybrid via hybridFromSingleHopIndexerOps and executes direct swap() to the pair. swapRouting.test.ts asserts "requires router only for 2+ hops" (undefined/1-hop -> false, 2-hop -> true). - [x] Multi-hop still uses router; gas = sum of per-hop dynamic estimates — same swapOpsRequireRouter gate; hybridSwapGas sums per hop. - [x] No-quote fallback stays conservative — missing/invalid hybrid -> flat fallback. - [x] max_maker_fills aligned with quote + buffer — hybridParamsWithSubmitCap / maxMakerFillsForSubmit caps from the quote. - [x] Native LUNC preflight uses the new estimate — estimateMarketPairSwapSequenceUlunaFeesTotal accepts live hybrid params (transactions.test.ts). - [x] #115/#114 gas floors updated, not removed — transactions.test.ts still asserts the regression floors. - [x] dApp + swarm lockstep — verified under #260 (identical constants + formula). Note on the "single-hop 0-2 makers <= 1.2M" target: pool-only (book_input=0) is 840k, so the fee saving vs the old flat 1.2M holds there. The shallow book-leg case is now 1,401,200 because #260/#262 raised book-leg sizing to cover the worst-case 500-step scan (MAX_SCAN_STEPS) + 15 parks — a deliberate OOG-safety bump that supersedes the original <=1.2M for book-leg swaps. The quote-driven sizing mechanism and single-hop routing from #249 are unchanged underneath. Live /trade single-hop hybrid (lower gas_wanted than flat when shallow; gas_used < gas_wanted, no OOG) is the browser layer; the routing + gas logic is fully unit-covered here. Verified end to end. @PlasticDigits
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-06-03 02:00:32 +00:00
Brouie commented 2026-06-10 01:51:41 +00:00 (Migrated from gitlab.com)

mentioned in issue #353

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

mentioned in issue #475

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

mentioned in issue #501

mentioned in issue #501
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
PlasticDigits commented 2026-08-27 00:20:45 +00:00 (Migrated from gitlab.com)

mentioned in issue #679

mentioned in issue #679
PlasticDigits commented 2026-08-27 00:20:46 +00:00 (Migrated from gitlab.com)

marked as related to #679

marked as related to #679
PlasticDigits commented 2026-08-27 00:20:55 +00:00 (Migrated from gitlab.com)

mentioned in issue #681

mentioned in issue #681
PlasticDigits commented 2026-08-27 00:20:56 +00:00 (Migrated from gitlab.com)

marked as related to #681

marked as related to #681
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#249
No description provided.