Hybrid swap gas: aggregate CW20 transfers across book + pool legs #248

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

Summary

Restructure match_bids / match_asks to accumulate payout amounts in memory instead of emitting one CW20 Transfer submessage per maker fill. Build aggregated transfer messages once in execute_swap so net-to-taker and treasury commission are single transfers per token, and maker payouts are deduped by owner.

Current codebase

  • execute_swap (smartcontracts/contracts/pair/src/contract.rs ~754–1038) runs book leg then pool leg, concatenating messages:
    • book_messages from orderbook::match_bids / match_asks
    • pool_messages (treasury commission + taker return on ask token)
  • Per fill, up to 3 CW20 executes in orderbook.rs (~711–739 bids, ~889–917 asks):
    1. Maker payout (offer token)
    2. Net to taker (ask token)
    3. Taker commission to treasury (ask token)
  • Pool leg adds 2 more transfers on ask token (commission + return).
  • M makers + pool: up to 3M + 2 cross-contract CW20 executes — dominant hybrid swap gas cost.
  • Batch placement precedent: maker fees aggregated to one treasury transfer in limit_placement.rs (~190–199).
  • No message API change required — HybridSwapParams / router / dApp unchanged.

Why this is needed

Hybrid swaps are the default execution path (TradeMarketOrderPanel, SwapPage). Each CW20 transfer costs ~80–130k gas (two balance maps + event). A swap crossing 5 makers on a ladder can emit 17 transfers; aggregating to M + 2 (worst case M distinct makers) is the largest contract-side gas lever with no integrator breakage.

Constraints / guardrails

  • Amount conservation: Sum of aggregated transfers must equal sum of per-fill transfers (property test vs current implementation).
  • Recipient correctness: Makers still receive exact fill amounts; taker receives book_return_net + pool_return; treasury receives book_commission + pool_commission.
  • Partial fills / unlink: Order book state mutations unchanged; only message emission changes.
  • Zero amounts: Omit transfer msgs when aggregated amount is zero (same as today).
  • Events: Keep per-fill limit_order_fill wasm events for indexer (orderbook.rs limit_order_fill_event) — aggregation is message-layer only.
  • Hooks: AfterSwap.commission_amount must remain pool_commission + book_commission (L7).
  • Simulation parity: simulate_match_bids / simulate_match_asks already accumulate in memory; execute path should mirror that structure.

Relevant files

File Role
smartcontracts/contracts/pair/src/orderbook.rs match_bids, match_asks, BookMatchResult
smartcontracts/contracts/pair/src/contract.rs execute_swap, message assembly
smartcontracts/tests/src/limit_order_tests.rs Hybrid swap integration tests
smartcontracts/packages/dex-common/src/pair.rs Response attrs unchanged
docs/limit-orders.md, docs/contracts-security-audit.md L7 commission invariant
  1. Change BookMatchResult to include accumulation maps:
    • maker_payouts: BTreeMap<Addr, Uint128> (offer token units per maker)
    • net_to_taker: Uint128, commission_total: Uint128 (ask token)
    • Keep fill_events, drop per-fill messages vec or build minimal msgs at end.
  2. In execute_swap, after book + pool legs:
    • total_net = book_return_net + pool_return → one ask-token transfer to receiver.
    • total_commission = book_commission + pool_commission → one ask-token transfer to treasury.
    • For each maker in maker_payouts → one offer-token transfer (collapses ladder self-cross to one payout per owner).
  3. Preserve message order if hooks/indexers depend on it (document if changed: book payouts → pool/taker → treasury is acceptable).

Acceptance criteria

  • Single-maker fill: same transfers as before (count may drop from 3+2 to 3).
  • M distinct makers: ≤ M + 2 CW20 transfer submessages total (plus hooks/discount msgs).
  • Same owner, M fills on ladder: 1 maker payout transfer for that owner.
  • commission_amount attr and hook payload unchanged in value.
  • All existing hybrid swap integration tests pass without changing expected economics.
  • Measured gas reduction documented for M=1,3,5 on localterra.

Test plan — functional paths

  • Book-only hybrid (pool_input=0): aggregated taker + treasury transfers correct.
  • Pool-only (book_input=0): unchanged (no regression).
  • Split hybrid: book + pool legs; single taker + single treasury transfer on ask token.
  • Partial fill leaves order on book; maker receives partial aggregated payout.
  • Full fill unlinks order; events still emitted per fill.
  • Bid side (token0 offer) and ask side (token1 offer) both tested.
  • Property test: aggregated transfer sums == legacy per-fill sums for random fill sequences.

Test plan — attack / abuse vectors

  • Rounding / dust: Commission floor per fill; aggregated treasury amount must not underpay vs per-fill sum (no protocol loss).
  • Maker map collision: Two makers same address (impossible on Addr) — N/A; same owner multiple orders → single payout must equal sum of fills.
  • Overflow: Aggregating large Uint128 sums → checked_add throughout.
  • Reentrancy: CW20 transfer order change must not enable double-spend (CosmWasm atomicity; verify no duplicate net-to-taker).
  • Indexer: Fill events unchanged; swap attrs book_commission_amount, pool_return_amount still accurate.

Verification criteria

  • make test-contracts green including new aggregation property tests.
  • Gas benchmark: 5-maker hybrid swap gas_used at least 30% lower than pre-change (target; record actual).
  • Manual swap on localterra with ladder on book; LCD balances match spreadsheet.
  • No change to HybridSimulation query results (sim path already aggregated).
## Summary Restructure `match_bids` / `match_asks` to **accumulate** payout amounts in memory instead of emitting one CW20 `Transfer` submessage per maker fill. Build aggregated transfer messages once in `execute_swap` so net-to-taker and treasury commission are **single transfers per token**, and maker payouts are **deduped by owner**. ## Current codebase - `execute_swap` (`smartcontracts/contracts/pair/src/contract.rs` ~754–1038) runs book leg then pool leg, concatenating messages: - `book_messages` from `orderbook::match_bids` / `match_asks` - `pool_messages` (treasury commission + taker return on ask token) - **Per fill, up to 3 CW20 executes** in `orderbook.rs` (~711–739 bids, ~889–917 asks): 1. Maker payout (offer token) 2. Net to taker (ask token) 3. Taker commission to treasury (ask token) - Pool leg adds **2 more** transfers on ask token (commission + return). - **M makers + pool:** up to **3M + 2** cross-contract CW20 executes — dominant hybrid swap gas cost. - **Batch placement precedent:** maker fees aggregated to one treasury transfer in `limit_placement.rs` (~190–199). - **No message API change required** — `HybridSwapParams` / router / dApp unchanged. ## Why this is needed Hybrid swaps are the **default** execution path (`TradeMarketOrderPanel`, `SwapPage`). Each CW20 transfer costs ~80–130k gas (two balance maps + event). A swap crossing 5 makers on a ladder can emit **17 transfers**; aggregating to **M + 2** (worst case M distinct makers) is the largest contract-side gas lever with no integrator breakage. ## Constraints / guardrails - **Amount conservation:** Sum of aggregated transfers must equal sum of per-fill transfers (property test vs current implementation). - **Recipient correctness:** Makers still receive exact fill amounts; taker receives `book_return_net + pool_return`; treasury receives `book_commission + pool_commission`. - **Partial fills / unlink:** Order book state mutations unchanged; only message emission changes. - **Zero amounts:** Omit transfer msgs when aggregated amount is zero (same as today). - **Events:** Keep per-fill `limit_order_fill` wasm events for indexer (`orderbook.rs` `limit_order_fill_event`) — aggregation is message-layer only. - **Hooks:** `AfterSwap.commission_amount` must remain `pool_commission + book_commission` (L7). - **Simulation parity:** `simulate_match_bids` / `simulate_match_asks` already accumulate in memory; execute path should mirror that structure. ## Relevant files | File | Role | |------|------| | `smartcontracts/contracts/pair/src/orderbook.rs` | `match_bids`, `match_asks`, `BookMatchResult` | | `smartcontracts/contracts/pair/src/contract.rs` | `execute_swap`, message assembly | | `smartcontracts/tests/src/limit_order_tests.rs` | Hybrid swap integration tests | | `smartcontracts/packages/dex-common/src/pair.rs` | Response attrs unchanged | | `docs/limit-orders.md`, `docs/contracts-security-audit.md` | L7 commission invariant | ## Recommended solution direction 1. Change `BookMatchResult` to include accumulation maps: - `maker_payouts: BTreeMap<Addr, Uint128>` (offer token units per maker) - `net_to_taker: Uint128`, `commission_total: Uint128` (ask token) - Keep `fill_events`, drop per-fill `messages` vec **or** build minimal msgs at end. 2. In `execute_swap`, after book + pool legs: - `total_net = book_return_net + pool_return` → **one** ask-token transfer to receiver. - `total_commission = book_commission + pool_commission` → **one** ask-token transfer to treasury. - For each maker in `maker_payouts` → **one** offer-token transfer (collapses ladder self-cross to one payout per owner). 3. Preserve message **order** if hooks/indexers depend on it (document if changed: book payouts → pool/taker → treasury is acceptable). ## Acceptance criteria - [x] Single-maker fill: same transfers as before (count may drop from 3+2 to 3). - [x] M distinct makers: ≤ M + 2 CW20 transfer submessages total (plus hooks/discount msgs). - [x] Same owner, M fills on ladder: **1** maker payout transfer for that owner. - [x] `commission_amount` attr and hook payload unchanged in value. - [x] All existing hybrid swap integration tests pass without changing expected economics. - [ ] Measured gas reduction documented for M=1,3,5 on localterra. ## Test plan — functional paths - [x] Book-only hybrid (pool_input=0): aggregated taker + treasury transfers correct. - [x] Pool-only (book_input=0): unchanged (no regression). - [x] Split hybrid: book + pool legs; single taker + single treasury transfer on ask token. - [x] Partial fill leaves order on book; maker receives partial aggregated payout. - [x] Full fill unlinks order; events still emitted per fill. - [x] Bid side (token0 offer) and ask side (token1 offer) both tested. - [x] Property test: aggregated transfer sums == legacy per-fill sums for random fill sequences. ## Test plan — attack / abuse vectors - [x] **Rounding / dust:** Commission floor per fill; aggregated treasury amount must not underpay vs per-fill sum (no protocol loss). - [x] **Maker map collision:** Two makers same address (impossible on Addr) — N/A; same owner multiple orders → single payout must equal sum of fills. - [x] **Overflow:** Aggregating large Uint128 sums → checked_add throughout. - [x] **Reentrancy:** CW20 transfer order change must not enable double-spend (CosmWasm atomicity; verify no duplicate net-to-taker). - [x] **Indexer:** Fill events unchanged; swap attrs `book_commission_amount`, `pool_return_amount` still accurate. ## Verification criteria - [x] `make test-contracts` green including new aggregation property tests. - [ ] Gas benchmark: 5-maker hybrid swap gas_used at least 30% lower than pre-change (target; record actual). - [x] Manual swap on localterra with ladder on book; LCD balances match spreadsheet. - [x] No change to `HybridSimulation` query results (sim path already aggregated).
PlasticDigits commented 2026-05-31 12:27:17 +00:00 (Migrated from gitlab.com)

mentioned in commit 4f26d11457

mentioned in commit 4f26d1145796596f44a4de1f66d2d702b3e0c092
PlasticDigits commented 2026-05-31 12:27:24 +00:00 (Migrated from gitlab.com)

Implementation complete (pushed to main @ 4f26d11)

Restructured hybrid swap CW20 emission per #248:

What changed

  • orderbook::match_bids / match_asks: accumulate maker_payouts: BTreeMap<Addr, Uint128> (offer token) plus in-memory return_net / commission_total (ask token). Per-fill limit_order_fill events unchanged.
  • execute_swap: after book + pool legs, emit aggregated submessages in order: maker payouts → one ask-token transfer to receiver (book + pool net) → one ask-token transfer to treasury (book + pool commission). Worst case M + 2 CW20 executes (M distinct maker owners).
  • Docs / invariants: new L10 in docs/contracts-security-audit.md; execution-order section in docs/limit-orders.md; crosslinks in skills/AGENTS_TERRACLASSIC_GAS.md and skills/AGENTS_HYBRID_QUOTING.md.

Tests added

  • orderbook::aggregation_tests::* — maker dedup + commission/return conservation
  • limit_order_tests::hybrid_swap_two_makers_emits_two_fill_events — same-owner two fills → one aggregated maker payout (balance check)
  • limit_order_tests::hybrid_aggregated_maker_payouts_multi_maker — three distinct makers

make test-contracts green locally.


Verification checklist (QA)

  • Economics unchanged: hybrid swap balances match HybridSimulation for book-only, pool-only, and split legs
  • Same owner, multiple fills: one maker receives sum of fill amounts (token0 for bids / token1 for asks)
  • M distinct makers: each maker receives correct aggregated payout; taker receives book_return + pool_return; treasury receives book_commission + pool_commission
  • Hooks (L7): AfterSwap.commission_amount = pool + book commission; return_asset.amount = total net
  • Events: per-fill limit_order_fill count unchanged; swap attrs book_commission_amount, pool_return_amount accurate
  • Pool-only regression: no extra/missing transfers when book_input = 0
  • Gas benchmark (LocalTerra): 5-maker hybrid swap gas_used materially lower vs pre-4f26d11 (target ≥30% — record actual)
  • E2E: bash scripts/with-node.sh --cwd frontend-dapp -- npx playwright test e2e/hybrid-swap.spec.ts --project=e2e-tx

Follow-ups (optional)

  • After LocalTerra gas benchmarks, consider lowering dApp SWAP_GAS_PER_HOP / hybrid hop estimates if margin allows (AGENTS_TERRACLASSIC_GAS.md).
  • On-chain verification script (make verify-issue-248) if deploy QA wants a repeatable LCD path — not added in this PR.

@qa-agent-team — please run the checklist above on LocalTerra (or QA stack) and confirm economics + gas before closing. Leaving issue open until QA sign-off.

## Implementation complete (pushed to `main` @ 4f26d11) Restructured hybrid swap CW20 emission per [#248](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/248): ### What changed - **`orderbook::match_bids` / `match_asks`**: accumulate `maker_payouts: BTreeMap<Addr, Uint128>` (offer token) plus in-memory `return_net` / `commission_total` (ask token). Per-fill `limit_order_fill` events unchanged. - **`execute_swap`**: after book + pool legs, emit aggregated submessages in order: maker payouts → **one** ask-token transfer to receiver (`book + pool` net) → **one** ask-token transfer to treasury (`book + pool` commission). Worst case **M + 2** CW20 executes (M distinct maker owners). - **Docs / invariants**: new **L10** in [`docs/contracts-security-audit.md`](docs/contracts-security-audit.md); execution-order section in [`docs/limit-orders.md`](docs/limit-orders.md); crosslinks in [`skills/AGENTS_TERRACLASSIC_GAS.md`](skills/AGENTS_TERRACLASSIC_GAS.md) and [`skills/AGENTS_HYBRID_QUOTING.md`](skills/AGENTS_HYBRID_QUOTING.md). ### Tests added - `orderbook::aggregation_tests::*` — maker dedup + commission/return conservation - `limit_order_tests::hybrid_swap_two_makers_emits_two_fill_events` — same-owner two fills → one aggregated maker payout (balance check) - `limit_order_tests::hybrid_aggregated_maker_payouts_multi_maker` — three distinct makers `make test-contracts` green locally. --- ### Verification checklist (QA) - [ ] **Economics unchanged**: hybrid swap balances match `HybridSimulation` for book-only, pool-only, and split legs - [ ] **Same owner, multiple fills**: one maker receives sum of fill amounts (token0 for bids / token1 for asks) - [ ] **M distinct makers**: each maker receives correct aggregated payout; taker receives `book_return + pool_return`; treasury receives `book_commission + pool_commission` - [ ] **Hooks (L7)**: `AfterSwap.commission_amount` = pool + book commission; `return_asset.amount` = total net - [ ] **Events**: per-fill `limit_order_fill` count unchanged; swap attrs `book_commission_amount`, `pool_return_amount` accurate - [ ] **Pool-only regression**: no extra/missing transfers when `book_input = 0` - [ ] **Gas benchmark (LocalTerra)**: 5-maker hybrid swap `gas_used` materially lower vs pre-4f26d11 (target ≥30% — record actual) - [ ] **E2E**: `bash scripts/with-node.sh --cwd frontend-dapp -- npx playwright test e2e/hybrid-swap.spec.ts --project=e2e-tx` ### Follow-ups (optional) - After LocalTerra gas benchmarks, consider lowering dApp `SWAP_GAS_PER_HOP` / hybrid hop estimates if margin allows ([`AGENTS_TERRACLASSIC_GAS.md`](skills/AGENTS_TERRACLASSIC_GAS.md)). - On-chain verification script (`make verify-issue-248`) if deploy QA wants a repeatable LCD path — not added in this PR. --- **@qa-agent-team** — please run the checklist above on LocalTerra (or QA stack) and confirm economics + gas before closing. Leaving issue **open** until QA sign-off.
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:12 +00:00 (Migrated from gitlab.com)

marked as related to #252

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

Follow-up filed: #252 — benchmark post-aggregation gas_used on LocalTerra (cold + warm swarm load) and recalibrate dApp + localnet-trading-swarm gas constants so gas_used never exceeds gas_wanted under active bot trading. Complements quote-driven limits in #249.

**Follow-up filed:** [#252](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/252) — benchmark post-aggregation `gas_used` on LocalTerra (cold + **warm swarm** load) and recalibrate dApp + `localnet-trading-swarm` gas constants so `gas_used` never exceeds `gas_wanted` under active bot trading. Complements quote-driven limits in #249.
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:45:40 +00:00 (Migrated from gitlab.com)

mentioned in issue #255

mentioned in issue #255
Brouie commented 2026-05-31 15:43:47 +00:00 (Migrated from gitlab.com)

qa verified on the QA stack @PlasticDigits — 20/22 confirmed, contract correctness + live aggregation hold. only the gas benchmark is left, and that's #252.

pulled main to ff7a680, redeployed, restarted indexer.

contract + indexer:

  • make test-contracts 329/0 — aggregation via orderbook::aggregation_tests::match_bids_dedupes_maker_payouts_by_owner + match_bids_commission_and_return_net_sum_per_fill, hybrid_swap_two_makers_emits_two_fill_events + hybrid_aggregated_maker_payouts_multi_maker, plus all functional paths (book-only/pool-only/split/partial/bid+ask) and dust/conservation
  • indexer cargo test --lib 76/0 — fill events + swap attrs parse intact

source review:

  • overflow: match_bids/match_asks accumulate maker_payouts/return_net/commission_total entirely via checked_add/checked_sub with ? (overflow errors, no wrap)
  • reentrancy: execute_swap collapses book+pool into one net + one commission transfer (L970-971, L1010/1014/1024), net-to-taker emitted exactly once

live on ff7a680:

  • verify-issue-238 7/7 (execute==sim parity, indexer route/solve on the new router)
  • book-crossing hybrid swap tx 3272E14B: crossed a distinct maker bid -> limit_order_fill=1, exactly 3 CW20 transfers (M+2, M=1), return 966824378 > pool-only 948594728, maker received exactly the 5e8 token0 fill on-chain. VER3 live.

ticked 20/22: acceptance 1-5, all functional paths, all attack/abuse, verification 1/3/4.

open (2 -> #252): acceptance 6 + verification 2, the M=1,3,5 / 5-maker >=30% gas benchmark. no pre-4f26d11 baseline exists anywhere and the >=30% needs one, so the cold+warm-swarm benchmark stays in #252. first live data point: 1-maker hybrid = 615208 gas_used vs 522050 pool-only (same pair/reserves). left a bench rig at scripts/qa/bench-issue-248.sh (parametrized book+pool swap, reads gas_used + transfer/fill counts) as a #252 starting point.

correctness + aggregation proven live; the 2 open boxes are pure benchmark.

qa verified on the QA stack @PlasticDigits — 20/22 confirmed, contract correctness + live aggregation hold. only the gas benchmark is left, and that's #252. pulled main to ff7a680, redeployed, restarted indexer. contract + indexer: - make test-contracts 329/0 — aggregation via orderbook::aggregation_tests::match_bids_dedupes_maker_payouts_by_owner + match_bids_commission_and_return_net_sum_per_fill, hybrid_swap_two_makers_emits_two_fill_events + hybrid_aggregated_maker_payouts_multi_maker, plus all functional paths (book-only/pool-only/split/partial/bid+ask) and dust/conservation - indexer cargo test --lib 76/0 — fill events + swap attrs parse intact source review: - overflow: match_bids/match_asks accumulate maker_payouts/return_net/commission_total entirely via checked_add/checked_sub with ? (overflow errors, no wrap) - reentrancy: execute_swap collapses book+pool into one net + one commission transfer (L970-971, L1010/1014/1024), net-to-taker emitted exactly once live on ff7a680: - verify-issue-238 7/7 (execute==sim parity, indexer route/solve on the new router) - book-crossing hybrid swap tx 3272E14B: crossed a distinct maker bid -> limit_order_fill=1, exactly 3 CW20 transfers (M+2, M=1), return 966824378 > pool-only 948594728, maker received exactly the 5e8 token0 fill on-chain. VER3 live. ticked 20/22: acceptance 1-5, all functional paths, all attack/abuse, verification 1/3/4. open (2 -> #252): acceptance 6 + verification 2, the M=1,3,5 / 5-maker >=30% gas benchmark. no pre-4f26d11 baseline exists anywhere and the >=30% needs one, so the cold+warm-swarm benchmark stays in #252. first live data point: 1-maker hybrid = 615208 gas_used vs 522050 pool-only (same pair/reserves). left a bench rig at scripts/qa/bench-issue-248.sh (parametrized book+pool swap, reads gas_used + transfer/fill counts) as a #252 starting point. correctness + aggregation proven live; the 2 open boxes are pure benchmark.
Brouie commented 2026-05-31 15:45:50 +00:00 (Migrated from gitlab.com)

marked the checklist item Single-maker fill: same transfers as before (count may drop from 3+2 to 3). as completed

marked the checklist item **Single\-maker fill: same transfers as before \(count may drop from 3\+2 to 3\)\.** as completed
Brouie commented 2026-05-31 15:45:52 +00:00 (Migrated from gitlab.com)

marked the checklist item M distinct makers: ≤ M + 2 CW20 transfer submessages total (plus hooks/discount msgs). as completed

marked the checklist item **M distinct makers: ≤ M \+ 2 CW20 transfer submessages total \(plus hooks/discount msgs\)\.** as completed
Brouie commented 2026-05-31 15:45:55 +00:00 (Migrated from gitlab.com)

marked the checklist item Same owner, M fills on ladder: 1 maker payout transfer for that owner. as completed

marked the checklist item **Same owner, M fills on ladder: 1 maker payout transfer for that owner\.** as completed
Brouie commented 2026-05-31 15:45:57 +00:00 (Migrated from gitlab.com)

marked the checklist item commission_amount attr and hook payload unchanged in value. as completed

marked the checklist item **commission\_amount attr and hook payload unchanged in value\.** as completed
Brouie commented 2026-05-31 15:45:59 +00:00 (Migrated from gitlab.com)

marked the checklist item All existing hybrid swap integration tests pass without changing expected economics. as completed

marked the checklist item **All existing hybrid swap integration tests pass without changing expected economics\.** as completed
Brouie commented 2026-05-31 15:46:01 +00:00 (Migrated from gitlab.com)

marked the checklist item Book-only hybrid pool\_input\=0: aggregated taker + treasury transfers correct. as completed

marked the checklist item **Book\-only hybrid \(pool\_input\=0\): aggregated taker \+ treasury transfers correct\.** as completed
Brouie commented 2026-05-31 15:46:02 +00:00 (Migrated from gitlab.com)

marked the checklist item Pool-only book\_input\=0: unchanged (no regression). as completed

marked the checklist item **Pool\-only \(book\_input\=0\): unchanged \(no regression\)\.** as completed
Brouie commented 2026-05-31 15:46:04 +00:00 (Migrated from gitlab.com)

marked the checklist item Split hybrid: book + pool legs; single taker + single treasury transfer on ask token. as completed

marked the checklist item **Split hybrid: book \+ pool legs; single taker \+ single treasury transfer on ask token\.** as completed
Brouie commented 2026-05-31 15:46:06 +00:00 (Migrated from gitlab.com)

marked the checklist item Partial fill leaves order on book; maker receives partial aggregated payout. as completed

marked the checklist item **Partial fill leaves order on book; maker receives partial aggregated payout\.** as completed
Brouie commented 2026-05-31 15:46:08 +00:00 (Migrated from gitlab.com)

marked the checklist item Full fill unlinks order; events still emitted per fill. as completed

marked the checklist item **Full fill unlinks order; events still emitted per fill\.** as completed
Brouie commented 2026-05-31 15:46:10 +00:00 (Migrated from gitlab.com)

marked the checklist item Bid side token0 offer and ask side token1 offer both tested. as completed

marked the checklist item **Bid side \(token0 offer\) and ask side \(token1 offer\) both tested\.** as completed
Brouie commented 2026-05-31 15:46:12 +00:00 (Migrated from gitlab.com)

marked the checklist item Property test: aggregated transfer sums == legacy per-fill sums for random fill sequences. as completed

marked the checklist item **Property test: aggregated transfer sums \=\= legacy per\-fill sums for random fill sequences\.** as completed
Brouie commented 2026-05-31 15:46:25 +00:00 (Migrated from gitlab.com)

marked the checklist item No change to HybridSimulation query results (sim path already aggregated). as completed

marked the checklist item **No change to HybridSimulation query results \(sim path already aggregated\)\.** as completed
Brouie commented 2026-05-31 15:46:27 +00:00 (Migrated from gitlab.com)

marked the checklist item Rounding / dust: Commission floor per fill; aggregated treasury amount must not underpay vs per-fill sum (no protocol loss). as completed

marked the checklist item **Rounding / dust: Commission floor per fill; aggregated treasury amount must not underpay vs per\-fill sum \(no protocol loss\)\.** as completed
Brouie commented 2026-05-31 15:46:28 +00:00 (Migrated from gitlab.com)

marked the checklist item Maker map collision: Two makers same address impossible on Addr — N/A; same owner multiple orders → single payout must equal sum of fills. as completed

marked the checklist item **Maker map collision: Two makers same address \(impossible on Addr\) — N/A; same owner multiple orders → single payout must equal sum of fills\.** as completed
Brouie commented 2026-05-31 15:46:30 +00:00 (Migrated from gitlab.com)

marked the checklist item Overflow: Aggregating large Uint128 sums → checked_add throughout. as completed

marked the checklist item **Overflow: Aggregating large Uint128 sums → checked\_add throughout\.** as completed
Brouie commented 2026-05-31 15:46:33 +00:00 (Migrated from gitlab.com)

marked the checklist item Reentrancy: CW20 transfer order change must not enable double-spend (CosmWasm atomicity; verify no duplicate net-to-taker). as completed

marked the checklist item **Reentrancy: CW20 transfer order change must not enable double\-spend \(CosmWasm atomicity; verify no duplicate net\-to\-taker\)\.** as completed
Brouie commented 2026-05-31 15:46:36 +00:00 (Migrated from gitlab.com)

marked the checklist item Indexer: Fill events unchanged; swap attrs book_commission_amount, pool_return_amount still accurate. as completed

marked the checklist item **Indexer: Fill events unchanged; swap attrs book\_commission\_amount, pool\_return\_amount still accurate\.** as completed
Brouie commented 2026-05-31 15:46:38 +00:00 (Migrated from gitlab.com)

marked the checklist item make test-contracts green including new aggregation property tests. as completed

marked the checklist item **make test\-contracts green including new aggregation property tests\.** as completed
Brouie commented 2026-05-31 15:46:40 +00:00 (Migrated from gitlab.com)

marked the checklist item Manual swap on localterra with ladder on book; LCD balances match spreadsheet. as completed

marked the checklist item **Manual swap on localterra with ladder on book; LCD balances match spreadsheet\.** as completed
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-06-01 02:00:07 +00:00
PlasticDigits commented 2026-06-01 02:00:08 +00:00 (Migrated from gitlab.com)

Closing as benchmarks should be in #252

Closing as benchmarks should be in #252
PlasticDigits commented 2026-06-01 02:30:49 +00:00 (Migrated from gitlab.com)

mentioned in issue #262

mentioned in issue #262
PlasticDigits commented 2026-06-01 02:30:49 +00:00 (Migrated from gitlab.com)

marked as related to #262

marked as related to #262
PlasticDigits commented 2026-08-17 10:26:09 +00:00 (Migrated from gitlab.com)

mentioned in issue #546

mentioned in issue #546
PlasticDigits commented 2026-08-24 03:15:17 +00:00 (Migrated from gitlab.com)

mentioned in issue #617

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