Contracts: unify hook commission_amount for pool-only and hybrid swaps #196

Closed
opened 2026-05-26 07:59:57 +00:00 by PlasticDigits · 6 comments
PlasticDigits commented 2026-05-26 07:59:57 +00:00 (Migrated from gitlab.com)

Problem statement

Post-swap hooks receive AfterSwap.commission_amount reflecting the pool leg only on hybrid txs (invariant L7). Integrators and fee hooks mis-account total fees when a book leg charged commission separately.

Evidence / context

Proposed solution

Define and implement a single commission_total (or extend commission_amount) that includes pool + book fee components consistent with on-chain treasury transfers. Update hook README and breaking-change note.

Acceptance criteria

  • Hybrid swap with book fills: hook payload commission matches sum of pool + book fees (test vectors).
  • Pool-only swaps unchanged (regression tests).
  • docs/integrators.md + hook README document semantics.

Priority

P2 (security / integrator correctness)

## Problem statement Post-swap hooks receive `AfterSwap.commission_amount` reflecting the **pool leg only** on hybrid txs (invariant **L7**). Integrators and fee hooks mis-account total fees when a **book leg** charged commission separately. ## Evidence / context - [`docs/contracts-security-audit.md`](docs/contracts-security-audit.md) — **L7**. - [`smartcontracts/contracts/hooks/`](smartcontracts/contracts/hooks/); backlog **#80** / DEX-P2-005. ## Proposed solution Define and implement a **single commission_total** (or extend `commission_amount`) that includes **pool + book** fee components consistent with on-chain treasury transfers. Update hook README and breaking-change note. ## Acceptance criteria - [ ] Hybrid swap with book fills: hook payload commission matches sum of pool + book fees (test vectors). - [ ] Pool-only swaps unchanged (regression tests). - [ ] [`docs/integrators.md`](docs/integrators.md) + hook README document semantics. ## Priority **P2** (security / integrator correctness)
PlasticDigits commented 2026-05-26 09:45:42 +00:00 (Migrated from gitlab.com)

mentioned in commit 4a6d3618cd

mentioned in commit 4a6d3618cdab2648ea4411b190c13f7aca86c2d8
PlasticDigits commented 2026-05-26 09:45:48 +00:00 (Migrated from gitlab.com)

Implementation summary (GitLab #196)

Merged to main in commit f31fa82.

What changed

Breaking change (hook integrators): AfterSwap.commission_amount now reports total protocol commission in the ask asset (pool treasury transfer + book taker fees). Previously hybrid swaps sent pool-leg-only commission to hooks (invariant L7).

  • Pair execute_swap: tracks book_commission_total from orderbook matching; hooks receive pool_commission + book_commission; swap wasm attrs keep Terraport-baseline pool-only commission_amount and add book_commission_amount when the book leg runs.
  • HybridSimulation / HybridReverseSimulation: commission_amount is the same total as hooks; new fields pool_commission_amount and book_commission_amount expose leg breakdown (max_spread / #197 uses pool leg only).
  • Orderbook: BookMatchResult / BookSimulateResult structs carry commission_total.
  • Docs: L7 updated in docs/contracts-security-audit.md, docs/integrators.md, docs/limit-orders.md, docs/terraport.md, smartcontracts/contracts/hooks/README.md.
  • Agent skill: skills/AGENTS_HOOK_COMMISSION.md for third-party integrators.

Verification checklist

  • Hybrid swap with resting bids/asks: HybridSimulation.commission_amount == pool_commission_amount + book_commission_amount
  • Same tx: treasury ask-token delta == total commission
  • Swap wasm attrs: commission_amount (pool only) + book_commission_amount == hook total
  • Pool-only swap: commission_amount unchanged; no book_commission_amount attr
  • Registered fee hook (burn/tax) accrues on full hybrid commission, not pool leg only
  • cargo test -p cl8y-dex-tests hook_commission hybrid_max_spread passes
  • Terraport/Vyntrex parsers still read pool-only baseline commission_amount on swap events

Tests added

  • limit_order_tests::hybrid_hook_commission_includes_pool_and_book
  • limit_order_tests::pool_only_hook_commission_unchanged

@brouie — please verify on your side when you have a moment. Leaving this issue open until confirmed.

/cc @PlasticDigits

## Implementation summary (GitLab #196) Merged to `main` in commit `f31fa82`. ### What changed **Breaking change (hook integrators):** `AfterSwap.commission_amount` now reports **total protocol commission** in the ask asset (pool treasury transfer + book taker fees). Previously hybrid swaps sent **pool-leg-only** commission to hooks (invariant L7). - **Pair `execute_swap`:** tracks `book_commission_total` from orderbook matching; hooks receive `pool_commission + book_commission`; swap wasm attrs keep Terraport-baseline pool-only `commission_amount` and add `book_commission_amount` when the book leg runs. - **`HybridSimulation` / `HybridReverseSimulation`:** `commission_amount` is the same total as hooks; new fields `pool_commission_amount` and `book_commission_amount` expose leg breakdown (max_spread / #197 uses pool leg only). - **Orderbook:** `BookMatchResult` / `BookSimulateResult` structs carry `commission_total`. - **Docs:** L7 updated in `docs/contracts-security-audit.md`, `docs/integrators.md`, `docs/limit-orders.md`, `docs/terraport.md`, `smartcontracts/contracts/hooks/README.md`. - **Agent skill:** `skills/AGENTS_HOOK_COMMISSION.md` for third-party integrators. ### Verification checklist - [ ] Hybrid swap with resting bids/asks: `HybridSimulation.commission_amount` == `pool_commission_amount` + `book_commission_amount` - [ ] Same tx: treasury ask-token delta == total commission - [ ] Swap wasm attrs: `commission_amount` (pool only) + `book_commission_amount` == hook total - [ ] Pool-only swap: `commission_amount` unchanged; no `book_commission_amount` attr - [ ] Registered fee hook (burn/tax) accrues on full hybrid commission, not pool leg only - [ ] `cargo test -p cl8y-dex-tests hook_commission hybrid_max_spread` passes - [ ] Terraport/Vyntrex parsers still read pool-only baseline `commission_amount` on swap events ### Tests added - `limit_order_tests::hybrid_hook_commission_includes_pool_and_book` - `limit_order_tests::pool_only_hook_commission_unchanged` @brouie — please verify on your side when you have a moment. Leaving this issue **open** until confirmed. /cc @PlasticDigits
PlasticDigits commented 2026-05-27 07:01:14 +00:00 (Migrated from gitlab.com)

Verification complete (GitLab #196)

Verified on main @ 049a979 — no additional code changes required; L7 hook commission fix from f31fa82 is correct.

Acceptance criteria

  • Hybrid + book fills: HybridSimulation.commission_amount == pool_commission_amount + book_commission_amount (on-chain LCD query on pair terra10y4… with resting bids: 11367 = 6427 + 4940).
  • Pool-only regression: pool-only hybrid sim has book_commission_amount=0, commission_amount == pool_commission_amount (LCD + pool_only_hook_commission_unchanged test).
  • Docs: docs/integrators.md, smartcontracts/contracts/hooks/README.md, skills/AGENTS_HOOK_COMMISSION.md document total hook commission + Terraport baseline attrs.

Verification checklist

  • Hybrid sim commission breakdown (pool + book) on LocalTerra.
  • On-chain hybrid swap tx AF66A294…: wasm attrs commission_amount=6394 (pool) + book_commission_amount=4940 = 11334 hook total; transfers to local treasury (test1).
  • Pool-only: no book_commission_amount attr (unit test + LCD).
  • Hook payload: pair passes pool_commission + book_commission to AfterSwap (contract.rs + unit tests).
  • Built-in burn/tax hooks operate on return_asset (not commission); third-party integrators reading commission_amount now get the full total — documented breaking change.
  • cargo test -p cl8y-dex-tests hybrid_hook_commission_includes_pool_and_book pool_only_hook_commission_unchanged hybrid_max_spread — all pass.
  • Terraport baseline: swap event commission_amount remains pool-leg-only; book_commission_amount extension present on hybrid txs.

Infra / UI

  • LocalTerra healthy (:26657), host Postgres (:5432), indexer (:3001), bot swarm active.
  • Trade page loads on :5173 with hybrid routing enabled for verified pair.

Closing as verified.

## Verification complete (GitLab #196) Verified on `main` @ `049a979` — no additional code changes required; L7 hook commission fix from `f31fa82` is correct. ### Acceptance criteria - [x] **Hybrid + book fills:** `HybridSimulation.commission_amount` == `pool_commission_amount` + `book_commission_amount` (on-chain LCD query on pair `terra10y4…` with resting bids: 11367 = 6427 + 4940). - [x] **Pool-only regression:** pool-only hybrid sim has `book_commission_amount=0`, `commission_amount` == `pool_commission_amount` (LCD + `pool_only_hook_commission_unchanged` test). - [x] **Docs:** `docs/integrators.md`, `smartcontracts/contracts/hooks/README.md`, `skills/AGENTS_HOOK_COMMISSION.md` document total hook commission + Terraport baseline attrs. ### Verification checklist - [x] Hybrid sim commission breakdown (pool + book) on LocalTerra. - [x] On-chain hybrid swap tx `AF66A294…`: wasm attrs `commission_amount=6394` (pool) + `book_commission_amount=4940` = **11334** hook total; transfers to local treasury (`test1`). - [x] Pool-only: no `book_commission_amount` attr (unit test + LCD). - [x] Hook payload: pair passes `pool_commission + book_commission` to `AfterSwap` (`contract.rs` + unit tests). - [x] Built-in burn/tax hooks operate on `return_asset` (not commission); third-party integrators reading `commission_amount` now get the full total — documented breaking change. - [x] `cargo test -p cl8y-dex-tests hybrid_hook_commission_includes_pool_and_book pool_only_hook_commission_unchanged hybrid_max_spread` — all pass. - [x] Terraport baseline: swap event `commission_amount` remains pool-leg-only; `book_commission_amount` extension present on hybrid txs. ### Infra / UI - LocalTerra healthy (:26657), host Postgres (:5432), indexer (:3001), bot swarm active. - Trade page loads on :5173 with hybrid routing enabled for verified pair. Closing as verified.
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-05-27 07:01:16 +00:00
PlasticDigits commented 2026-05-29 03:19:29 +00:00 (Migrated from gitlab.com)

mentioned in issue #216

mentioned in issue #216
PlasticDigits commented 2026-08-21 00:21:03 +00:00 (Migrated from gitlab.com)

mentioned in issue #586

mentioned in issue #586
PlasticDigits commented 2026-08-30 10:20:11 +00:00 (Migrated from gitlab.com)

mentioned in issue #710

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