Fix: /limits book Edit drops orderId — no update path (GitLab #294) #312

Closed
opened 2026-06-05 04:08:28 +00:00 by PlasticDigits · 6 comments
PlasticDigits commented 2026-06-05 04:08:28 +00:00 (Migrated from gitlab.com)

Current codebase

Trade page (correct): TradePage.tsx passes book-row Edit drafts via pushLimitBookDraft → TradeOrderTicket.tsx. On consume, it sets editContext via buildLimitBookEditContext(limitBookDraft) including orderId, enabling price-only UpdateLimitOrderPrice through useLimitOrderUpdatePriceMutation.

Limits page (broken): LimitOrdersPage.tsx lines 202–206:

const onPrefillLimitTicketFromBook = (draft: LimitBookTicketDraft) => {
  setSide(draft.side)
  setPrice(draft.price)
  setLimitEscrowAmountFromDraft(draft.amountHuman)
}

LimitBookTicketDraft (types/limitBookTicketDraft.ts) includes orderId, expiresAt, hintAfterOrderId for edit/amend flows (#162, #178, #247). The Limits page drops orderId and has no editContext, no useLimitOrderUpdatePriceMutation, and submit only calls placeMutation → placeLimitOrderWithAllowance (always a new order).

Follow-up: GitLab #294.

Why this is needed

Users editing a resting order from the book on /limits unknowingly place a duplicate order instead of amending price. This is a functional regression vs /trade and wastes escrow/gas; cancel cleanup is manual.

Constraints / guardrails

  • Reuse Trade ticket patterns — do not invent a parallel edit state machine.
  • Price-only edit must use updateLimitOrderPrice when only price changed (same gates as TradeOrderTicket.tsx).
  • Material field changes (side, amount, expiry) should cancel+replace or block with clear copy — match Trade behavior.
  • hintAfterOrderId advisory hint must flow to update mutation when amending.
  • Paused pair: disable edit actions consistently with cancel.

Relevant files

Area Path
Bug site frontend-dapp/src/pages/LimitOrdersPage.tsx
Reference impl frontend-dapp/src/components/trade/TradeOrderTicket.tsx
Draft type frontend-dapp/src/types/limitBookTicketDraft.ts
Utils frontend-dapp/src/utils/limitOrderPriceEdit.ts
Mutation frontend-dapp/src/hooks/useLimitOrderUpdatePriceMutation.ts
Service frontend-dapp/src/services/terraclassic/pair.ts (updateLimitOrderPrice)
Book UI frontend-dapp/src/components/trade/OrderBookPanel.tsx
E2E frontend-dapp/e2e/trade-book-edit-178.spec.ts (Trade only today)
  1. Mirror Trade ticket edit state on Limits page: editContext, editHintAfterOrderId, isPriceOnlyLimitEdit, updatePriceMutation.
  2. Fix onPrefillLimitTicketFromBook to call buildLimitBookEditContext(draft) and set hint.
  3. Submit handler: branch — price-only → updatePriceMutation; else existing place flow or explicit “cancel and replace” UX.
  4. Button copy: Update price vs Place limit when editing.
  5. Add E2E or component test on Limits page paralleling Trade book edit.

Acceptance criteria

  • Edit from book on /limits prefill shows “Editing order #N”.
  • Price-only change submits UpdateLimitOrderPrice, not place_limit_order.
  • orderId preserved through prefill; no duplicate order on price amend.
  • Changing amount/side/expiry behavior matches Trade ticket policy.
  • Tests cover Limits prefill includes orderId.

Test plan (all paths)

Path Steps Expected
Price-only edit Edit bid, change price, submit Update tx; same order id on book
No-op price Edit, same price Gate or no-op per Trade rules
Side change Edit, flip bid→ask Block or replace per Trade
Amount change Edit, change size Replace flow, not silent duplicate
New order Place without edit placeMutation unchanged
Paused pair Edit while paused Disabled with message

Attack / abuse / hack vectors

Vector Test
Edit another user's order Contract rejects; UI only enables own rows
Stale orderId after fill Update fails gracefully; indexer refresh
Race: order cancelled while editing On-chain error humanized; clear retry

Verification criteria

  • make test-frontend green.
  • Manual: /limits book Edit → price amend → single order id on LCD.
  • Optional E2E spec limit-orders-edit analogous to trade-book-edit-178.spec.ts.
## Current codebase **Trade page (correct):** `TradePage.tsx` passes book-row Edit drafts via `pushLimitBookDraft` → `TradeOrderTicket.tsx`. On consume, it sets `editContext` via `buildLimitBookEditContext(limitBookDraft)` including `orderId`, enabling price-only `UpdateLimitOrderPrice` through `useLimitOrderUpdatePriceMutation`. **Limits page (broken):** `LimitOrdersPage.tsx` lines 202–206: ```ts const onPrefillLimitTicketFromBook = (draft: LimitBookTicketDraft) => { setSide(draft.side) setPrice(draft.price) setLimitEscrowAmountFromDraft(draft.amountHuman) } ``` `LimitBookTicketDraft` (`types/limitBookTicketDraft.ts`) includes `orderId`, `expiresAt`, `hintAfterOrderId` for edit/amend flows (#162, #178, #247). The Limits page **drops** `orderId` and has **no** `editContext`, **no** `useLimitOrderUpdatePriceMutation`, and submit **only** calls `placeMutation` → `placeLimitOrderWithAllowance` (always a new order). Follow-up: GitLab **#294**. ## Why this is needed Users editing a resting order from the book on `/limits` unknowingly place a **duplicate** order instead of amending price. This is a functional regression vs `/trade` and wastes escrow/gas; cancel cleanup is manual. ## Constraints / guardrails - Reuse Trade ticket patterns — do not invent a parallel edit state machine. - Price-only edit must use `updateLimitOrderPrice` when only price changed (same gates as `TradeOrderTicket.tsx`). - Material field changes (side, amount, expiry) should cancel+replace or block with clear copy — match Trade behavior. - `hintAfterOrderId` advisory hint must flow to update mutation when amending. - Paused pair: disable edit actions consistently with cancel. ## Relevant files | Area | Path | |------|------| | Bug site | `frontend-dapp/src/pages/LimitOrdersPage.tsx` | | Reference impl | `frontend-dapp/src/components/trade/TradeOrderTicket.tsx` | | Draft type | `frontend-dapp/src/types/limitBookTicketDraft.ts` | | Utils | `frontend-dapp/src/utils/limitOrderPriceEdit.ts` | | Mutation | `frontend-dapp/src/hooks/useLimitOrderUpdatePriceMutation.ts` | | Service | `frontend-dapp/src/services/terraclassic/pair.ts` (`updateLimitOrderPrice`) | | Book UI | `frontend-dapp/src/components/trade/OrderBookPanel.tsx` | | E2E | `frontend-dapp/e2e/trade-book-edit-178.spec.ts` (Trade only today) | ## Recommended direction 1. Mirror Trade ticket edit state on Limits page: `editContext`, `editHintAfterOrderId`, `isPriceOnlyLimitEdit`, `updatePriceMutation`. 2. Fix `onPrefillLimitTicketFromBook` to call `buildLimitBookEditContext(draft)` and set hint. 3. Submit handler: branch — price-only → `updatePriceMutation`; else existing place flow or explicit “cancel and replace” UX. 4. Button copy: **Update price** vs **Place limit** when editing. 5. Add E2E or component test on Limits page paralleling Trade book edit. ## Acceptance criteria - [ ] Edit from book on `/limits` prefill shows “Editing order #N”. - [ ] Price-only change submits `UpdateLimitOrderPrice`, not `place_limit_order`. - [ ] `orderId` preserved through prefill; no duplicate order on price amend. - [ ] Changing amount/side/expiry behavior matches Trade ticket policy. - [ ] Tests cover Limits prefill includes `orderId`. ## Test plan (all paths) | Path | Steps | Expected | |------|-------|----------| | Price-only edit | Edit bid, change price, submit | Update tx; same order id on book | | No-op price | Edit, same price | Gate or no-op per Trade rules | | Side change | Edit, flip bid→ask | Block or replace per Trade | | Amount change | Edit, change size | Replace flow, not silent duplicate | | New order | Place without edit | `placeMutation` unchanged | | Paused pair | Edit while paused | Disabled with message | ## Attack / abuse / hack vectors | Vector | Test | |--------|------| | Edit another user's order | Contract rejects; UI only enables own rows | | Stale orderId after fill | Update fails gracefully; indexer refresh | | Race: order cancelled while editing | On-chain error humanized; clear retry | ## Verification criteria - `make test-frontend` green. - Manual: `/limits` book Edit → price amend → single order id on LCD. - Optional E2E spec `limit-orders-edit` analogous to `trade-book-edit-178.spec.ts`.
PlasticDigits commented 2026-06-05 04:08:28 +00:00 (Migrated from gitlab.com)

marked as related to #294

marked as related to #294
ghost1 commented 2026-06-05 10:09:20 +00:00 (Migrated from gitlab.com)

mentioned in commit 0a1810e959

mentioned in commit 0a1810e9591052d74565187abe5ebcb415e3e542
PlasticDigits commented 2026-06-05 10:09:25 +00:00 (Migrated from gitlab.com)

mentioned in merge request !791

mentioned in merge request !791
PlasticDigits commented 2026-06-05 10:09:31 +00:00 (Migrated from gitlab.com)

Implemented fix in !791 — https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/merge_requests/73

What changed

/limits now mirrors TradeOrderTicket book-edit flow: buildLimitBookEditContext on prefill, price-only submit via UpdateLimitOrderPrice, and block/replace messaging when side/amount/expiry change.

Verification

  • make test-frontend — PASS (832 tests)
  • npm run test -- src/pages/LimitOrdersPage.test.tsx — PASS (9 tests, 4 new for #312)
  • Manual LCD price amend on /limits — SKIP (needs LocalTerra wallet QA)

Issue left open pending MR merge and optional manual QA.

Implemented fix in !791 — https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/merge_requests/73 ## What changed `/limits` now mirrors `TradeOrderTicket` book-edit flow: `buildLimitBookEditContext` on prefill, price-only submit via `UpdateLimitOrderPrice`, and block/replace messaging when side/amount/expiry change. ## Verification - `make test-frontend` — PASS (832 tests) - `npm run test -- src/pages/LimitOrdersPage.test.tsx` — PASS (9 tests, 4 new for #312) - Manual LCD price amend on `/limits` — SKIP (needs LocalTerra wallet QA) Issue left **open** pending MR merge and optional manual QA.
PlasticDigits commented 2026-06-05 10:38:25 +00:00 (Migrated from gitlab.com)

mentioned in commit 13422e60c4

mentioned in commit 13422e60c4d6a63063f0c1c92b9fc6c947d0c01d
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-06-05 10:38:25 +00:00
PlasticDigits commented 2026-06-05 12:03:19 +00:00 (Migrated from gitlab.com)

mentioned in issue #294

mentioned in issue #294
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#312
No description provided.