Gap Analysis Report #361

Closed
opened 2026-06-12 04:34:59 +00:00 by PlasticDigits · 18 comments
PlasticDigits commented 2026-06-12 04:34:59 +00:00 (Migrated from gitlab.com)
No description provided.
PlasticDigits commented 2026-06-12 04:46:02 +00:00 (Migrated from gitlab.com)

CL8Y DEX Terra Classic — Gap Analysis

Field Value
Generated (UTC) 2026-06-12
Epoch 1781239451
Branch baseline main @ 8408689
Prior analysis gaps/GAP_1780200149.md (2026-05-31)
Issue GitLab #361
Live backlog GitLab issues

Methodology

Fresh code-grounded pass over the monorepo (contracts, indexer, frontend, bots, CI/docs). Prior gap register items were re-verified against current source. Automated checks run in this session:

Suite Result
make test-contracts PASS (375 integration tests in cl8y-dex-tests)
make test-frontend PASS (160 files, 946 tests)
make test-frontend-charts PASS (21 tests, 1 skipped CI-only soak)
make test-indexer-integration PASS (serialized; 22 integration binaries)
make lint PASS (5 ESLint warnings, 0 errors)
E2E Playwright (make test-e2e-tx) NOT RUN — LocalTerra not provisioned on this VM
make test-charts-integration NOT RUN — requires live indexer on :3001

Measured snapshot:

Area LOC (approx.) Tests
Smart contracts (Rust) ~40k 375 integration + proptest + in-crate units
Indexer (Rust) ~18k 135 lib + 22 integration binaries
Frontend (TS/TSX) ~42k 160 Vitest files, 30 Playwright specs
Bot swarm (scripts/bots/, packages/localnet-trading-swarm/) ~3k Python unittest + Vitest gas/profile tests

Out of scope (by design): bridge / cross-chain.


Executive summary

CL8Y DEX remains a mature Terra Classic CosmWasm stack with strong engineering discipline: checked math, pool-favorable rounding, shared dex-common slippage logic, bounded on-chain work, documented invariant→test matrices, hardened indexer API (allowlists, rate limits, sanitized errors), and a feature-rich React dApp (swap, trade, limits, pool, portfolio, charts, fee tiers).

Since the May 2026 analysis, several critical indexer and frontend gaps were closed: block tx pagination, cursor discipline on indexing failures, reorg halt, LCD 502 sanitization, swap/trade min_received via BigInt slippage floor (#356), hybrid book submit snapshot alignment (#360), post-sign broadcast recovery (#359), and swap-page indexer outage UX.

The most material remaining gaps cluster into five themes:

  1. Trust & governance — no evidenced third-party contract audit; single-key factory governance (fees, hooks, pause, blacklist); pause blocks limit cancel/claim; atomic post-swap hooks are a liveness risk.
  2. Automation enforcement — make test still covers only contracts + frontend unit; no hosted test CI gate on MRs; no coverage thresholds; dependency/SCA scanning absent; E2E not run in this pass.
  3. Operational observability — no Prometheus /metrics; /health is a static {"status":"ok"} with no DB/LCD probe; trader tier sync is O(unique traders) every 10 min.
  4. Retail UX completeness — no impermanent-loss disclosure on /pool; a11y axe gate covers trade/charts/wallet chrome only (not swap, limits, pool, portfolio); E2E remains Chromium-only.
  5. Residual precision / quoting edges — parseFloat still used for input gating and price-impact display on swap (not submit path); fee-discount registry Err silently charges full fee; route solver tier depends on indexer sync lag.

Pool-only (v2) launch remains feasible with documented ops checklists. Hybrid-as-default retail is materially improved but still depends on indexer/LCD availability and honest outage disclosure. Indexer ingestion is significantly hardened; hosted test automation is now the top process gap.


1. Severity register (top findings)

# Sev Area Finding Status / location
C1 Critical Indexer Poller advanced cursor on block-processing errors Fixed: cursor advances only on Ok; MaxRetriesExceeded halts with cursor unchanged
C2 Critical Indexer ≤100 txs/block with no pagination Fixed: get_block_txs paginates until pagination.total satisfied
C3 High Indexer Reorg handling is detect-and-halt, not auto-replay Halts on hash mismatch; recovery is manual runbook
C4 Critical Ops/Test No unified hosted test CI — .gitlab-ci.yml publishes QA wasm/indexer artifacts only; make test = contracts + frontend unit; indexer/charts/E2E/swarm excluded Makefile:336; .gitlab-ci.yml
H1 High Contracts Hybrid simulation fee discounts Fixed (#238, #245)
H2 High Frontend min_received via parseFloat on raw integers Fixed for swap/trade submit via useSubmitAlignedSimQuote + applySlippagePercentFloor (BigInt)
H3 High Contracts Pause blocks cancel + expired claim — makers cannot withdraw resting escrow while paused Documented L6
H4 High Contracts Reverting post-swap hook fails entire swap (atomic add_messages) Liveness risk for misbehaving hooks
H5 High Contracts/Ops Governance centralization — single addr controls fees, hooks, pause, whitelist, batch discount; no in-contract timelock factory/src/contract.rs
H6 High Indexer LCD error text leaked to API clients Fixed (#239) — security.rs::lcd_failure_returns_sanitized_502_body
H7 High Indexer LCD amplification on route/solve/best, deep limit-book, CG/CMC orderbook — rate limit optional in config Throttled when rate_limit_lcd_heavy_rps set
H8 High Contracts Router sweeps full CW20 balance per hop Fixed (#240)
H9 High Ops/Sec No third-party audit; no cargo-audit/cargo-deny/npm audit/Dependabot docs/security-model.md:130-132
H10 High Frontend/Test No enforced coverage gate (vitest.config.ts has no thresholds); axe a11y E2E on trade/charts/wallet only vitest.config.ts:19-22; e2e/a11y-critical-routes.spec.ts
H11 High Indexer/Obs No Prometheus /metrics; shallow /health (no DB/LCD probe) api/mod.rs:359-361; GitLab #200
H12 High Frontend Post-sign broadcast timeout / duplicate-submit risk — materially improved (#359) but wallet-specific edge cases and Keplr vs Simulated Wallet parity need ongoing E2E terraBroadcast.ts, terraTxRecoveryPoll.ts
M1 Medium Frontend Swap page lacked outage banner / simQuery.isError handling Fixed — detectSwapIndexerOutage, outage banners
M2 Medium Contracts Fee-discount registry Err(_) → full fee charged silently pair/src/contract.rs
M3 Medium Contracts SetDiscountRegistryAll unbounded Fixed (#242) — batch API
M4 Medium Indexer Pair-list volume_24h per-request aggregation Fixed (#243) — rollup table
M5 Medium Frontend Custom listboxes lacked keyboard nav Fixed (#244)
M6 Medium Frontend No impermanent-loss / LP risk disclosure on /pool No IL copy in frontend
M7 Medium Ops E2E Chromium-only — no Firefox/WebKit/mobile Playwright projects playwright.config.ts:59-76
M8 Medium Indexer Block timestamp fallback / uncapped offsets Fixed (#243)
M9 Medium Ops Forked @goblinhunt/cosmes + patch-package — supply-chain drift if postinstall skipped frontend-dapp/package.json; cosmesPatch127.test.ts
M10 Low Frontend parseFloat still used for input validation and price-impact % on swap (display-only; submit path is BigInt-safe) SwapPage.tsx:172,762-766
M11 Medium Indexer Trader tier sync O(unique traders) every 10 min — LCD load scales with trader count indexer/src/indexer/trader_tracker.rs:20-70
M12 Medium Ops Post-deploy smoke is manual — scripts/smoke-pool-swap.sh not in any CI gate GitLab #86
M13 Medium Ops GCH golden-image runner (gch-cloud-init-runner.sh) provisions agent VMs but does not yet enforce the full make test ladder on every merge gch-cloud-init-runner.sh; recent chore: wire GCH job secrets commits

2. Smart contracts (smartcontracts/)

Toolchain: cosmwasm-std 1.5.11; release overflow-checks = true. All main contracts implement cw2 versioning + migrate.

Strengths

  • Constant-product AMM with pool-favorable rounding, shared dex-common max-spread/slippage helpers.
  • Hybrid swap (pool + on-chain FIFO limit book) with simulation parity for fee discounts when trader is set.
  • Limit orders: placement, cancel, update, batch/ladder, parked-expired claim, non-crossing guards.
  • Factory governance: fee hooks, pause, trading blacklist (wallet/token/pair), trusted routers.
  • 375 integration tests in cl8y-dex-tests covering adversarial tokens, pause, blacklist, hybrid, router hops.

Gaps

Theme Gap Recommendation
Security No third-party audit before mainnet TVL Commission audit; track in release checklist
Governance Single-key control; no timelock Multisig + documented key ceremony; consider timelock ADR
Liveness Pause blocks cancel/claim (L6) Document ops playbook; consider separate "withdraw-only" pause mode ADR
Liveness Atomic hook failure bricks swap Hook allowlist + monitoring; circuit-breaker governance
UX/fairness Silent full fee on discount registry errors Surface query health; optional revert on registry outage ADR
Gas Hybrid + multi-hop quotes near LCD 3M gas cap Continue bounded sim patterns; document worst-case gas in integrators doc

3. Indexer (indexer/)

Strengths

  • Paginated block tx ingestion with retry + reorg detection (major improvement since prior report).
  • Sanitized API errors, OpenAPI/Swagger, optional rate limits on LCD-heavy routes.
  • pair_volume_24h rollup; paginated pair/token/CG endpoints.
  • Route solver with cache tiers (#324).
  • 135 lib tests + 22 integration binaries (security, hybrid columns, limit lifecycle, volume rollup).

Gaps

Theme Gap Recommendation
Correctness Reorg = halt, not auto-replay Automate replay per runbook or add checkpoint rollback job
Scale Tier sync scans all traders periodically Event-driven tier updates on discount registry txs
Observability No /metrics; shallow /health Add Prometheus metrics (#200); readiness probe with DB + LCD
Abuse Route solver / orderbook sim can fan out LCD queries Keep rate limits on in production; document integrator quotas
Testing Integration tests require serialized Postgres Acceptable locally; need CI job with Postgres service

4. Frontend (frontend-dapp/)

Strengths

  • Swap, trade, limits (incl. ladder), pool, portfolio, charts, fee tiers, compliance blacklist check.
  • Submit-aligned quote debouncing (#356, #360).
  • BigInt-safe min_received / LP withdraw mins via rawAmountMath.ts.
  • Post-sign broadcast recovery poll (#359).
  • Humanized errors, indexer outage banners on swap/trade/limits/charts.
  • 946 unit tests; real lightweight-charts Vitest layer; 30 Playwright specs.

Gaps

Theme Gap Recommendation
UX/risk No IL disclosure on pool page Add concise IL warning + link to docs
a11y Axe gate on 3 route groups only Extend to /swap, /limits, /pool, /portfolio
Precision parseFloat on price-impact display Use string/BigInt math for impact % when amounts > 2⁵³
Wallet Forked cosmes + patches Pin + CI verify patch hash; track upstream merge
Testing Default Vitest stubs chain I/O Keep charts integration + E2E as release gates
Mobile No WebKit/mobile E2E Add at least one mobile viewport smoke project

5. Bots & tooling (scripts/bots/, packages/localnet-trading-swarm/)

Strengths

  • Python swarm for load testing (swap types, limits, LP).
  • TypeScript localnet-trading-swarm with gas alignment tests shared with frontend SWAP_GAS_BUFFER.
  • QA scripts: start-qa, redeploy decision guide (#325), issue verify scripts.

Gaps

Theme Gap Recommendation
CI Swarm tests not in make test Optional nightly job on QA host
Observability Swarm failures lack structured metrics Log aggregation + alert on swap failure rate
GCH runner Agent VM automation in progress Wire post-job make test + test-e2e-tx ladder when LocalTerra available

6. CI, testing & process

Current state

Check Enforced in CI? In make test?
Contract integration No Yes
Frontend unit No Yes
Indexer lib No No
Indexer integration No No (make test-indexer-integration separate)
Frontend charts (real library) No No (make test-frontend-charts)
Charts HTTP integration No No (make test-charts-integration)
Playwright E2E No No (make test-e2e-tx)
Lint / doc drift No Yes (make lint)
QA wasm/indexer artifacts Yes (main branch, path filters) N/A

Reference GitHub workflows (.github/workflows/test.yml) document the intended ladder but are not executed.

Gaps

  1. No MR merge gate — regressions depend on voluntary local/QA runs.
  2. No coverage thresholds — Vitest coverage config exists but no minimums.
  3. No dependency scanning — Rust/npm advisories not automated.
  4. E2E not validated this session — requires make setup-cloud-localterra (~10–15 min).
  5. Post-deploy smoke manual — smoke-pool-swap.sh should run after every deploy in QA.

P0 — Before mainnet with meaningful TVL

  1. Commission third-party contract audit; remediate findings.
  2. Establish hosted test CI on MRs: at minimum make lint, make test, make test-indexer-integration, make test-frontend-charts.
  3. Multisig + key ceremony for factory governance; document pause/claim policy (L6).
  4. Add indexer readiness (/health probes DB + LCD) and Prometheus metrics (#200).

P1 — Retail readiness

  1. Extend a11y axe coverage to swap, limits, pool, portfolio.
  2. Add IL / LP risk disclosure on pool page.
  3. Run and gate strict E2E (make test-e2e-tx) on QA after contract changes.
  4. Automate post-deploy smoke (#86).

P2 — Hardening & scale

  1. Reorg auto-replay or operator alert + one-click replay job.
  2. Event-driven fee-tier sync instead of full trader scan.
  3. Add cargo-deny / npm audit to CI.
  4. Coverage thresholds on critical paths (rawAmountMath, terraBroadcast, route solver).
  5. Evaluate Firefox/WebKit smoke or document Chromium-only rationale for launch.

8. Test run log (this session)

make test-contracts          → PASS (375 tests)
make test-frontend           → PASS (160 files, 946 tests)
make test-frontend-charts    → PASS (21 passed, 1 skipped)
make test-indexer-integration → PASS (serialized, all binaries green)
make lint                    → PASS (5 ESLint warnings)
make has-localterra          → NOT RUNNING (E2E skipped)

Point-in-time analysis. Prefer the live GitLab backlog for authoritative issue status. Items marked Fixed were verified in source during this pass.

# CL8Y DEX Terra Classic — Gap Analysis | Field | Value | |-------|-------| | **Generated (UTC)** | 2026-06-12 | | **Epoch** | `1781239451` | | **Branch baseline** | `main` @ `8408689` | | **Prior analysis** | [`gaps/GAP_1780200149.md`](./GAP_1780200149.md) (2026-05-31) | | **Issue** | [GitLab #361](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/361) | | **Live backlog** | [GitLab issues](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues) | ## Methodology Fresh code-grounded pass over the monorepo (contracts, indexer, frontend, bots, CI/docs). Prior gap register items were re-verified against current source. Automated checks run in this session: | Suite | Result | |-------|--------| | `make test-contracts` | **PASS** (375 integration tests in `cl8y-dex-tests`) | | `make test-frontend` | **PASS** (160 files, 946 tests) | | `make test-frontend-charts` | **PASS** (21 tests, 1 skipped CI-only soak) | | `make test-indexer-integration` | **PASS** (serialized; 22 integration binaries) | | `make lint` | **PASS** (5 ESLint warnings, 0 errors) | | E2E Playwright (`make test-e2e-tx`) | **NOT RUN** — LocalTerra not provisioned on this VM | | `make test-charts-integration` | **NOT RUN** — requires live indexer on `:3001` | Measured snapshot: | Area | LOC (approx.) | Tests | |------|---------------|-------| | Smart contracts (Rust) | ~40k | 375 integration + proptest + in-crate units | | Indexer (Rust) | ~18k | 135 lib + 22 integration binaries | | Frontend (TS/TSX) | ~42k | 160 Vitest files, 30 Playwright specs | | Bot swarm (`scripts/bots/`, `packages/localnet-trading-swarm/`) | ~3k | Python unittest + Vitest gas/profile tests | Out of scope (by design): bridge / cross-chain. --- ## Executive summary CL8Y DEX remains a **mature Terra Classic CosmWasm stack** with strong engineering discipline: checked math, pool-favorable rounding, shared `dex-common` slippage logic, bounded on-chain work, documented invariant→test matrices, hardened indexer API (allowlists, rate limits, sanitized errors), and a feature-rich React dApp (swap, trade, limits, pool, portfolio, charts, fee tiers). **Since the May 2026 analysis**, several critical indexer and frontend gaps were closed: block tx pagination, cursor discipline on indexing failures, reorg halt, LCD 502 sanitization, swap/trade `min_received` via BigInt slippage floor ([#356](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/356)), hybrid book submit snapshot alignment ([#360](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/360)), post-sign broadcast recovery ([#359](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/359)), and swap-page indexer outage UX. The most material **remaining** gaps cluster into five themes: 1. **Trust & governance** — no evidenced third-party contract audit; single-key factory governance (fees, hooks, pause, blacklist); pause blocks limit cancel/claim; atomic post-swap hooks are a liveness risk. 2. **Automation enforcement** — `make test` still covers only contracts + frontend unit; no hosted test CI gate on MRs; no coverage thresholds; dependency/SCA scanning absent; E2E not run in this pass. 3. **Operational observability** — no Prometheus `/metrics`; `/health` is a static `{"status":"ok"}` with no DB/LCD probe; trader tier sync is O(unique traders) every 10 min. 4. **Retail UX completeness** — no impermanent-loss disclosure on `/pool`; a11y axe gate covers trade/charts/wallet chrome only (not swap, limits, pool, portfolio); E2E remains Chromium-only. 5. **Residual precision / quoting edges** — `parseFloat` still used for input gating and price-impact display on swap (not submit path); fee-discount registry `Err` silently charges full fee; route solver tier depends on indexer sync lag. **Pool-only (v2) launch** remains feasible with documented ops checklists. **Hybrid-as-default retail** is materially improved but still depends on indexer/LCD availability and honest outage disclosure. **Indexer ingestion** is significantly hardened; **hosted test automation** is now the top process gap. --- ## 1. Severity register (top findings) | # | Sev | Area | Finding | Status / location | |---|-----|------|---------|-------------------| | C1 | ~~Critical~~ | Indexer | Poller advanced cursor on block-processing errors | **Fixed:** cursor advances only on `Ok`; `MaxRetriesExceeded` halts with cursor unchanged | `indexer/src/indexer/poller.rs:131-167` | | C2 | ~~Critical~~ | Indexer | ≤100 txs/block with no pagination | **Fixed:** `get_block_txs` paginates until `pagination.total` satisfied | `indexer/src/lcd/mod.rs:211-229`; tests `get_block_txs_multi_page` | | C3 | **High** | Indexer | Reorg handling is detect-and-halt, not auto-replay | Halts on hash mismatch; recovery is manual runbook | `poller.rs:111-154`; `docs/runbooks/indexer-reorg-replay-dedup.md` | | C4 | **Critical** | Ops/Test | **No unified hosted test CI** — `.gitlab-ci.yml` publishes QA wasm/indexer artifacts only; `make test` = contracts + frontend unit; indexer/charts/E2E/swarm excluded | `Makefile:336`; `.gitlab-ci.yml` | | H1 | ~~High~~ | Contracts | Hybrid simulation fee discounts | **Fixed** ([#238](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/238), [#245](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/245)) | `pair/src/contract.rs`; `make verify-issue-238` | | H2 | ~~High~~ | Frontend | `min_received` via `parseFloat` on raw integers | **Fixed** for swap/trade submit via `useSubmitAlignedSimQuote` + `applySlippagePercentFloor` (BigInt) | `hooks/useSubmitAlignedSimQuote.ts`; `utils/rawAmountMath.ts` | | H3 | **High** | Contracts | **Pause blocks cancel + expired claim** — makers cannot withdraw resting escrow while paused | Documented L6 | `pair/src/lib.rs:33`; `contracts-security-audit.md` | | H4 | **High** | Contracts | **Reverting post-swap hook fails entire swap** (atomic `add_messages`) | Liveness risk for misbehaving hooks | `pair/src/contract.rs` | | H5 | **High** | Contracts/Ops | **Governance centralization** — single addr controls fees, hooks, pause, whitelist, batch discount; no in-contract timelock | `factory/src/contract.rs` | | H6 | ~~High~~ | Indexer | LCD error text leaked to API clients | **Fixed** ([#239](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/239)) — `security.rs::lcd_failure_returns_sanitized_502_body` | `indexer/tests/security.rs` | | H7 | **High** | Indexer | **LCD amplification** on `route/solve/best`, deep limit-book, CG/CMC orderbook — rate limit optional in config | Throttled when `rate_limit_lcd_heavy_rps` set | `api/mod.rs:406-411` | | H8 | ~~High~~ | Contracts | Router sweeps full CW20 balance per hop | **Fixed** ([#240](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/240)) | `router/src/contract.rs` | | H9 | **High** | Ops/Sec | **No third-party audit**; no `cargo-audit`/`cargo-deny`/`npm audit`/Dependabot | `docs/security-model.md:130-132` | | H10 | **High** | Frontend/Test | **No enforced coverage gate** (`vitest.config.ts` has no thresholds); axe a11y E2E on trade/charts/wallet only | `vitest.config.ts:19-22`; `e2e/a11y-critical-routes.spec.ts` | | H11 | **High** | Indexer/Obs | **No Prometheus `/metrics`**; shallow `/health` (no DB/LCD probe) | `api/mod.rs:359-361`; GitLab [#200](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/200) | | H12 | **High** | Frontend | **Post-sign broadcast timeout / duplicate-submit risk** — materially improved ([#359](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/359)) but wallet-specific edge cases and Keplr vs Simulated Wallet parity need ongoing E2E | `terraBroadcast.ts`, `terraTxRecoveryPoll.ts` | | M1 | ~~Medium~~ | Frontend | Swap page lacked outage banner / `simQuery.isError` handling | **Fixed** — `detectSwapIndexerOutage`, outage banners | `SwapPage.tsx:740-976` | | M2 | **Medium** | Contracts | Fee-discount registry `Err(_)` → full fee charged silently | `pair/src/contract.rs` | | M3 | ~~Medium~~ | Contracts | `SetDiscountRegistryAll` unbounded | **Fixed** ([#242](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/242)) — batch API | | M4 | ~~Medium~~ | Indexer | Pair-list `volume_24h` per-request aggregation | **Fixed** ([#243](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/243)) — rollup table | | M5 | ~~Medium~~ | Frontend | Custom listboxes lacked keyboard nav | **Fixed** ([#244](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/244)) | | M6 | **Medium** | Frontend | **No impermanent-loss / LP risk disclosure** on `/pool` | No IL copy in frontend | | M7 | **Medium** | Ops | **E2E Chromium-only** — no Firefox/WebKit/mobile Playwright projects | `playwright.config.ts:59-76` | | M8 | ~~Medium~~ | Indexer | Block timestamp fallback / uncapped offsets | **Fixed** ([#243](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/243)) | | M9 | **Medium** | Ops | **Forked `@goblinhunt/cosmes` + patch-package** — supply-chain drift if postinstall skipped | `frontend-dapp/package.json`; `cosmesPatch127.test.ts` | | M10 | **Low** | Frontend | `parseFloat` still used for **input validation** and **price-impact %** on swap (display-only; submit path is BigInt-safe) | `SwapPage.tsx:172,762-766` | | M11 | **Medium** | Indexer | **Trader tier sync O(unique traders)** every 10 min — LCD load scales with trader count | `indexer/src/indexer/trader_tracker.rs:20-70` | | M12 | **Medium** | Ops | **Post-deploy smoke is manual** — `scripts/smoke-pool-swap.sh` not in any CI gate | GitLab [#86](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/86) | | M13 | **Medium** | Ops | **GCH golden-image runner** (`gch-cloud-init-runner.sh`) provisions agent VMs but does not yet enforce the full `make` test ladder on every merge | `gch-cloud-init-runner.sh`; recent `chore: wire GCH job secrets` commits | --- ## 2. Smart contracts (`smartcontracts/`) **Toolchain:** `cosmwasm-std` 1.5.11; release `overflow-checks = true`. All main contracts implement `cw2` versioning + `migrate`. ### Strengths - Constant-product AMM with pool-favorable rounding, shared `dex-common` max-spread/slippage helpers. - Hybrid swap (pool + on-chain FIFO limit book) with simulation parity for fee discounts when `trader` is set. - Limit orders: placement, cancel, update, batch/ladder, parked-expired claim, non-crossing guards. - Factory governance: fee hooks, pause, trading blacklist (wallet/token/pair), trusted routers. - **375** integration tests in `cl8y-dex-tests` covering adversarial tokens, pause, blacklist, hybrid, router hops. ### Gaps | Theme | Gap | Recommendation | |-------|-----|----------------| | Security | No third-party audit before mainnet TVL | Commission audit; track in release checklist | | Governance | Single-key control; no timelock | Multisig + documented key ceremony; consider timelock ADR | | Liveness | Pause blocks cancel/claim (L6) | Document ops playbook; consider separate "withdraw-only" pause mode ADR | | Liveness | Atomic hook failure bricks swap | Hook allowlist + monitoring; circuit-breaker governance | | UX/fairness | Silent full fee on discount registry errors | Surface query health; optional revert on registry outage ADR | | Gas | Hybrid + multi-hop quotes near LCD 3M gas cap | Continue bounded sim patterns; document worst-case gas in integrators doc | --- ## 3. Indexer (`indexer/`) ### Strengths - Paginated block tx ingestion with retry + reorg detection (major improvement since prior report). - Sanitized API errors, OpenAPI/Swagger, optional rate limits on LCD-heavy routes. - `pair_volume_24h` rollup; paginated pair/token/CG endpoints. - Route solver with cache tiers ([#324](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/324)). - **135** lib tests + **22** integration binaries (security, hybrid columns, limit lifecycle, volume rollup). ### Gaps | Theme | Gap | Recommendation | |-------|-----|----------------| | Correctness | Reorg = halt, not auto-replay | Automate replay per runbook or add checkpoint rollback job | | Scale | Tier sync scans all traders periodically | Event-driven tier updates on discount registry txs | | Observability | No `/metrics`; shallow `/health` | Add Prometheus metrics ([#200](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/200)); readiness probe with DB + LCD | | Abuse | Route solver / orderbook sim can fan out LCD queries | Keep rate limits on in production; document integrator quotas | | Testing | Integration tests require serialized Postgres | Acceptable locally; need CI job with Postgres service | --- ## 4. Frontend (`frontend-dapp/`) ### Strengths - Swap, trade, limits (incl. ladder), pool, portfolio, charts, fee tiers, compliance blacklist check. - Submit-aligned quote debouncing ([#356](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/356), [#360](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/360)). - BigInt-safe `min_received` / LP withdraw mins via `rawAmountMath.ts`. - Post-sign broadcast recovery poll ([#359](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/359)). - Humanized errors, indexer outage banners on swap/trade/limits/charts. - **946** unit tests; real `lightweight-charts` Vitest layer; **30** Playwright specs. ### Gaps | Theme | Gap | Recommendation | |-------|-----|----------------| | UX/risk | No IL disclosure on pool page | Add concise IL warning + link to docs | | a11y | Axe gate on 3 route groups only | Extend to `/swap`, `/limits`, `/pool`, `/portfolio` | | Precision | `parseFloat` on price-impact display | Use string/BigInt math for impact % when amounts > 2⁵³ | | Wallet | Forked cosmes + patches | Pin + CI verify patch hash; track upstream merge | | Testing | Default Vitest stubs chain I/O | Keep charts integration + E2E as release gates | | Mobile | No WebKit/mobile E2E | Add at least one mobile viewport smoke project | --- ## 5. Bots & tooling (`scripts/bots/`, `packages/localnet-trading-swarm/`) ### Strengths - Python swarm for load testing (swap types, limits, LP). - TypeScript `localnet-trading-swarm` with gas alignment tests shared with frontend `SWAP_GAS_BUFFER`. - QA scripts: `start-qa`, redeploy decision guide ([#325](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/325)), issue verify scripts. ### Gaps | Theme | Gap | Recommendation | |-------|-----|----------------| | CI | Swarm tests not in `make test` | Optional nightly job on QA host | | Observability | Swarm failures lack structured metrics | Log aggregation + alert on swap failure rate | | GCH runner | Agent VM automation in progress | Wire post-job `make test` + `test-e2e-tx` ladder when LocalTerra available | --- ## 6. CI, testing & process ### Current state | Check | Enforced in CI? | In `make test`? | |-------|-----------------|-----------------| | Contract integration | No | Yes | | Frontend unit | No | Yes | | Indexer lib | No | No | | Indexer integration | No | No (`make test-indexer-integration` separate) | | Frontend charts (real library) | No | No (`make test-frontend-charts`) | | Charts HTTP integration | No | No (`make test-charts-integration`) | | Playwright E2E | No | No (`make test-e2e-tx`) | | Lint / doc drift | No | Yes (`make lint`) | | QA wasm/indexer artifacts | **Yes** (main branch, path filters) | N/A | Reference GitHub workflows (`.github/workflows/test.yml`) document the intended ladder but are **not executed**. ### Gaps 1. **No MR merge gate** — regressions depend on voluntary local/QA runs. 2. **No coverage thresholds** — Vitest coverage config exists but no minimums. 3. **No dependency scanning** — Rust/npm advisories not automated. 4. **E2E not validated this session** — requires `make setup-cloud-localterra` (~10–15 min). 5. **Post-deploy smoke manual** — `smoke-pool-swap.sh` should run after every deploy in QA. --- ## 7. Recommended next steps (prioritized) ### P0 — Before mainnet with meaningful TVL 1. Commission **third-party contract audit**; remediate findings. 2. Establish **hosted test CI** on MRs: at minimum `make lint`, `make test`, `make test-indexer-integration`, `make test-frontend-charts`. 3. **Multisig + key ceremony** for factory governance; document pause/claim policy (L6). 4. Add **indexer readiness** (`/health` probes DB + LCD) and **Prometheus metrics** ([#200](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/200)). ### P1 — Retail readiness 5. Extend **a11y axe** coverage to swap, limits, pool, portfolio. 6. Add **IL / LP risk disclosure** on pool page. 7. Run and gate **strict E2E** (`make test-e2e-tx`) on QA after contract changes. 8. Automate **post-deploy smoke** ([#86](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/86)). ### P2 — Hardening & scale 9. **Reorg auto-replay** or operator alert + one-click replay job. 10. **Event-driven fee-tier sync** instead of full trader scan. 11. Add **cargo-deny / npm audit** to CI. 12. **Coverage thresholds** on critical paths (`rawAmountMath`, `terraBroadcast`, route solver). 13. Evaluate **Firefox/WebKit** smoke or document Chromium-only rationale for launch. --- ## 8. Test run log (this session) ``` make test-contracts → PASS (375 tests) make test-frontend → PASS (160 files, 946 tests) make test-frontend-charts → PASS (21 passed, 1 skipped) make test-indexer-integration → PASS (serialized, all binaries green) make lint → PASS (5 ESLint warnings) make has-localterra → NOT RUNNING (E2E skipped) ``` --- *Point-in-time analysis. Prefer the [live GitLab backlog](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues) for authoritative issue status. Items marked **Fixed** were verified in source during this pass.*
PlasticDigits commented 2026-06-12 05:01:03 +00:00 (Migrated from gitlab.com)

Operational observability & Automation enforcement is rejeced as excessive overhead at this scale (>$1m tvl) but will be needed at higher tvl. Same reason for firefix/webkit.
Must investigate the tier sync issue O(unique traders)
Approved: C3, H7, H12, M2, M6 (keep succinct), M9, M10, M11, M12, H10 (a11y should be on all pages, no enforced coverage gate)
Rejected due to overhead: C4, H10 (enforced coverage gate only), H11, M13
Rejected due to security model:
H3 (intendend behavior to prevent withdawl of assets during an ongoing exploit)
H5 (Must switch to multisig after $1m+ tvl
H9 (Requires $50k+ in projected annual revenues to fund audit)
Rejected due to intended behavior:
H4 (hooks should be allowed to revert swaps if attached to a pair. Hooks must be approved by governance)

Recommendations approved:
Extend a11y axe coverage to swap, limits, pool, portfolio.
Add IL / LP risk disclosure on pool page.
Reorg auto-replay or operator alert + one-click replay job.
Event-driven fee-tier sync instead of full trader scan.

**Operational observability** & **Automation enforcement** is rejeced as excessive overhead at this scale (>$1m tvl) but will be needed at higher tvl. Same reason for firefix/webkit. Must investigate the tier sync issue O(unique traders) Approved: C3, H7, H12, M2, M6 (keep succinct), M9, M10, M11, M12, H10 (a11y should be on all pages, no enforced coverage gate) Rejected due to overhead: C4, H10 (enforced coverage gate only), H11, M13 Rejected due to security model: H3 (intendend behavior to prevent withdawl of assets during an ongoing exploit) H5 (Must switch to multisig after $1m+ tvl H9 (Requires $50k+ in projected annual revenues to fund audit) Rejected due to intended behavior: H4 (hooks should be allowed to revert swaps if attached to a pair. Hooks must be approved by governance) Recommendations approved: Extend a11y axe coverage to swap, limits, pool, portfolio. Add IL / LP risk disclosure on pool page. Reorg auto-replay or operator alert + one-click replay job. Event-driven fee-tier sync instead of full trader scan.
PlasticDigits commented 2026-06-12 05:05:43 +00:00 (Migrated from gitlab.com)

mentioned in issue #362

mentioned in issue #362
PlasticDigits commented 2026-06-12 05:05:45 +00:00 (Migrated from gitlab.com)

mentioned in issue #363

mentioned in issue #363
PlasticDigits commented 2026-06-12 05:05:45 +00:00 (Migrated from gitlab.com)

mentioned in issue #364

mentioned in issue #364
PlasticDigits commented 2026-06-12 05:05:47 +00:00 (Migrated from gitlab.com)

mentioned in issue #365

mentioned in issue #365
PlasticDigits commented 2026-06-12 05:05:52 +00:00 (Migrated from gitlab.com)

mentioned in issue #366

mentioned in issue #366
PlasticDigits commented 2026-06-12 05:05:54 +00:00 (Migrated from gitlab.com)

mentioned in issue #367

mentioned in issue #367
PlasticDigits commented 2026-06-12 05:05:54 +00:00 (Migrated from gitlab.com)

mentioned in issue #368

mentioned in issue #368
PlasticDigits commented 2026-06-12 05:06:03 +00:00 (Migrated from gitlab.com)

Child issues opened from gap analysis triage

Reviewed parent body + triage comment (2026-06-12). Opened 7 issues for approved items; skipped rejected / deferred items. No prior child links existed on #361.

Opened

Issue Bundle Register items
#362 Indexer reorg recovery C3
#363 LCD-heavy rate limits H7
#364 Event-driven tier sync M11
#365 Fee-discount registry transparency M2
#366 Retail UX (IL + swap precision + a11y) M6, M10, H10 (a11y only)
#367 Cosmes fork / patch-package M9
#368 QA validation (smoke + broadcast E2E) H12, M12

Bundling notes

  • #366 — Frontend retail completeness: impermanent-loss disclosure, BigInt-safe swap display/gating, axe on /swap /limits /pool /portfolio.
  • #368 — Post-deploy smoke-pool-swap.sh hook in start-qa plus Playwright post-sign broadcast recovery (Simulated Wallet; Keplr parity documented).
  • Indexer ops split across #362 (reorg), #363 (LCD abuse), #364 (tier sync scale).

Skipped — rejected (excessive overhead at current TVL)

Item Finding Reason
C4 No unified hosted test CI on MRs Rejected — overhead
H10 Enforced Vitest coverage thresholds Rejected — overhead (a11y portion approved → #366)
H11 Prometheus /metrics; deep /health Rejected — overhead
M13 GCH runner full make test ladder Rejected — overhead
— Firefox / WebKit Playwright Rejected — same overhead rationale

Skipped — rejected (security model / deferred)

Item Finding Reason
H3 Pause blocks cancel + expired claim Intended exploit-response behavior
H5 Single-key factory governance Multisig deferred until $1m+ TVL
H9 Third-party contract audit Deferred until $50k+ projected annual revenue

Skipped — rejected (intended behavior)

Item Finding Reason
H4 Reverting post-swap hook fails swap Intended — governance-approved hooks

Skipped — already fixed (verified in #361 body)

C1, C2, H1, H2, H6, H8, M1, M3, M4, M5, M7 (Firefox portion rejected anyway), M8 — no new issues.

Already closed / superseded references

  • #86 — smoke script delivered; #368 tracks wiring into QA deploy.
  • #214 — trade/charts/wallet a11y; #366 extends coverage.
  • #278 — cg/cmc limiter fix; #363 covers production enforcement.
## Child issues opened from gap analysis triage Reviewed parent body + triage comment (2026-06-12). Opened **7 issues** for **approved** items; skipped rejected / deferred items. No prior child links existed on #361. ### Opened | Issue | Bundle | Register items | |-------|--------|----------------| | [#362](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/362) | Indexer reorg recovery | **C3** | | [#363](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/363) | LCD-heavy rate limits | **H7** | | [#364](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/364) | Event-driven tier sync | **M11** | | [#365](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/365) | Fee-discount registry transparency | **M2** | | [#366](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/366) | Retail UX (IL + swap precision + a11y) | **M6**, **M10**, **H10** (a11y only) | | [#367](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/367) | Cosmes fork / patch-package | **M9** | | [#368](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/368) | QA validation (smoke + broadcast E2E) | **H12**, **M12** | ### Bundling notes - **#366** — Frontend retail completeness: impermanent-loss disclosure, BigInt-safe swap display/gating, axe on `/swap` `/limits` `/pool` `/portfolio`. - **#368** — Post-deploy `smoke-pool-swap.sh` hook in `start-qa` plus Playwright post-sign broadcast recovery (Simulated Wallet; Keplr parity documented). - Indexer ops split across **#362** (reorg), **#363** (LCD abuse), **#364** (tier sync scale). ### Skipped — rejected (excessive overhead at current TVL) | Item | Finding | Reason | |------|---------|--------| | **C4** | No unified hosted test CI on MRs | Rejected — overhead | | **H10** | Enforced Vitest coverage thresholds | Rejected — overhead (a11y portion approved → #366) | | **H11** | Prometheus `/metrics`; deep `/health` | Rejected — overhead | | **M13** | GCH runner full `make` test ladder | Rejected — overhead | | — | Firefox / WebKit Playwright | Rejected — same overhead rationale | ### Skipped — rejected (security model / deferred) | Item | Finding | Reason | |------|---------|--------| | **H3** | Pause blocks cancel + expired claim | Intended exploit-response behavior | | **H5** | Single-key factory governance | Multisig deferred until $1m+ TVL | | **H9** | Third-party contract audit | Deferred until $50k+ projected annual revenue | ### Skipped — rejected (intended behavior) | Item | Finding | Reason | |------|---------|--------| | **H4** | Reverting post-swap hook fails swap | Intended — governance-approved hooks | ### Skipped — already fixed (verified in #361 body) C1, C2, H1, H2, H6, H8, M1, M3, M4, M5, M7 (Firefox portion rejected anyway), M8 — no new issues. ### Already closed / superseded references - [#86](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/86) — smoke script delivered; **#368** tracks wiring into QA deploy. - [#214](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/214) — trade/charts/wallet a11y; **#366** extends coverage. - [#278](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/278) — cg/cmc limiter fix; **#363** covers production enforcement.
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-06-12 05:07:44 +00:00
PlasticDigits commented 2026-06-12 05:13:56 +00:00 (Migrated from gitlab.com)

mentioned in merge request !871

mentioned in merge request !871
PlasticDigits commented 2026-06-12 05:14:08 +00:00 (Migrated from gitlab.com)

mentioned in merge request !872

mentioned in merge request !872
PlasticDigits commented 2026-06-12 05:18:35 +00:00 (Migrated from gitlab.com)

mentioned in merge request !873

mentioned in merge request !873
PlasticDigits commented 2026-06-12 05:21:50 +00:00 (Migrated from gitlab.com)

mentioned in merge request !875

mentioned in merge request !875
PlasticDigits commented 2026-06-13 02:49:42 +00:00 (Migrated from gitlab.com)

mentioned in issue #373

mentioned in issue #373
PlasticDigits commented 2026-06-13 02:49:45 +00:00 (Migrated from gitlab.com)

mentioned in issue #374

mentioned in issue #374
PlasticDigits commented 2026-06-13 02:49:46 +00:00 (Migrated from gitlab.com)

mentioned in issue #375

mentioned in issue #375
PlasticDigits commented 2026-06-13 03:02:56 +00:00 (Migrated from gitlab.com)

mentioned in merge request !893

mentioned in merge request !893
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#361
No description provided.