Fee verification: discount tiers, pool vs limit book, hybrid parity, treasury #100

Closed
opened 2026-04-13 12:15:57 +00:00 by PlasticDigits · 2 comments
PlasticDigits commented 2026-04-13 12:15:57 +00:00 (Migrated from gitlab.com)

Goal

Confirm that on-chain fee behavior matches product expectations across pool-only swaps, limit-book flows, hybrid swaps, the fee-discount registry, and treasury settlement. This issue tracks verification (docs, tests, targeted code review, and external audit alignment), not a single bugfix.

Intended fee semantics (reference)

The following is the documented / implemented model in this repo; reviewers should validate it end-to-end.

Fee discount tiers (CL8Y registry)

  • Effective swap fee: fee_bps * (10000 - discount_bps) / 10000 (integer division). See docs/reference/fee-discount-tiers.md and smartcontracts/packages/dex-common/src/fee_discount.rs wire types.
  • Self-registration only for tiers with governance_only: false; tier 0 / 255 are governance-assigned. Trusted router registration matters for router-originated trader forwarding (see docs/testing.md integration section).

Pool (AMM) swaps

  • Commission is effective_fee_bps of gross output on the constant-product leg; fee is sent to the pair’s configured treasury (see execute_swap path in smartcontracts/contracts/pair/src/contract.rs).

Limit orders (FIFO book)

  • Total limit-book fee rate matches the pair’s effective commission (after discount registry).
  • Maker half: charged once at PlaceLimitOrder from escrow; remaining is reduced; treasury receives the maker fee.
  • Taker half: charged on each fill against the book (taker_fee_bps = effective - floor(effective/2) so maker+taker equals effective). Basis: bids — token1 cost; asks — token0 fill. See orderbook::maker_fee_bps / taker_fee_bps in smartcontracts/contracts/pair/src/orderbook.rs.
  • Price update (UpdateLimitOrderPrice) does not re-charge the maker placement fee.

Hybrid swaps (pool + book in one tx)

  • Same effective rate as non-hybrid for the taker context: pool leg uses full effective_fee_bps; book fills use the taker half per fill (maker half was paid at placement). Integration test hybrid_book_fill_uses_taker_discounted_effective_fee_bps in smartcontracts/tests/src/limit_order_tests.rs asserts the book leg uses the taker’s discounted effective_fee_bps (GitLab #83).
  • Post-swap hooks: AfterSwap.commission_amount is pool leg only; book fees appear via limit_order_fill / treasury transfers — see docs/integrators.md and invariant L7 in docs/contracts-security-audit.md.

Treasury

  • Pool commission, limit maker fees, and limit taker commissions on fills are routed to treasury per pair FeeConfig (CW20 sends in the relevant token).

Verification checklist

Documentation

  • docs/reference/fee-discount-tiers.md — tier math and governance/registration rules.
  • docs/limit-orders.md — hybrid execution order, maker/taker split, events.
  • docs/integrators.md — hook semantics for hybrid (commission_amount = pool only).
  • docs/contracts-security-audit.md — invariants (e.g. L7, L8) still match code.

Tests — how to run

CosmWasm workspace (primary for fee logic):

cd smartcontracts
cargo test

Focus areas:

  • smartcontracts/tests/src/limit_order_tests.rs — hybrid fee parity, treasury balances, maker/taker splits, discount registry.
  • Fee-discount contract tests (see Fee Discount Contract Tests in docs/testing.md).
  • Pair swap + discount flows in the integration harness (docs/testing.md Integration Tests (Contracts)).

Coverage (optional):

cd smartcontracts
cargo llvm-cov test --workspace --lcov --output-path lcov.info

Or from repo root: make coverage-contracts.

Frontend (fee tier UX): frontend-dapp — npm run test:run, e2e under frontend-dapp/e2e/fee-*.spec.ts if UI parity is in scope.

Code review (targeted)

  • smartcontracts/contracts/pair/src/contract.rs — effective_fee_bps resolution, pool commission, PlaceLimitOrder maker fee, treasury sends.
  • smartcontracts/contracts/pair/src/orderbook.rs — maker_fee_bps / taker_fee_bps, bid/ask commission accounting.
  • Router / trader forwarding when discount registry is set (trusted router).

Audit

  • Map the above semantics to any external audit report scope; confirm total protocol fee on limit flows equals effective rate (maker + taker legs), and that no double charge occurs vs pool-only behavior for the same notional.

Deliverable

A short sign-off comment on this issue (or linked note) stating whether behavior matches expectations, listing any gaps between docs and code, and pointing to the test commands used.

## Goal Confirm that **on-chain fee behavior** matches product expectations across pool-only swaps, limit-book flows, hybrid swaps, the fee-discount registry, and **treasury** settlement. This issue tracks **verification** (docs, tests, targeted code review, and external audit alignment), not a single bugfix. ## Intended fee semantics (reference) The following is the **documented / implemented** model in this repo; reviewers should validate it end-to-end. ### Fee discount tiers (CL8Y registry) - **Effective swap fee:** `fee_bps * (10000 - discount_bps) / 10000` (integer division). See `docs/reference/fee-discount-tiers.md` and `smartcontracts/packages/dex-common/src/fee_discount.rs` wire types. - **Self-registration** only for tiers with `governance_only: false`; tier 0 / 255 are governance-assigned. Trusted router registration matters for router-originated `trader` forwarding (see `docs/testing.md` integration section). ### Pool (AMM) swaps - Commission is **`effective_fee_bps` of gross output** on the constant-product leg; fee is sent to the pair’s configured **`treasury`** (see `execute_swap` path in `smartcontracts/contracts/pair/src/contract.rs`). ### Limit orders (FIFO book) - **Total** limit-book fee rate matches the pair’s **effective** commission (after discount registry). - **Maker half:** charged once at **`PlaceLimitOrder`** from escrow; `remaining` is reduced; treasury receives the maker fee. - **Taker half:** charged on **each fill** against the book (`taker_fee_bps = effective - floor(effective/2)` so maker+taker equals effective). Basis: bids — token1 `cost`; asks — token0 fill. See `orderbook::maker_fee_bps` / `taker_fee_bps` in `smartcontracts/contracts/pair/src/orderbook.rs`. - **Price update** (`UpdateLimitOrderPrice`) does **not** re-charge the maker placement fee. ### Hybrid swaps (pool + book in one tx) - **Same effective rate as non-hybrid** for the taker context: pool leg uses full **`effective_fee_bps`**; book fills use the **taker half** per fill (maker half was paid at placement). Integration test `hybrid_book_fill_uses_taker_discounted_effective_fee_bps` in `smartcontracts/tests/src/limit_order_tests.rs` asserts the book leg uses the taker’s discounted `effective_fee_bps` (GitLab #83). - **Post-swap hooks:** `AfterSwap.commission_amount` is **pool leg only**; book fees appear via `limit_order_fill` / treasury transfers — see `docs/integrators.md` and invariant **L7** in `docs/contracts-security-audit.md`. ### Treasury - Pool commission, limit maker fees, and limit taker commissions on fills are routed to **`treasury`** per pair `FeeConfig` (CW20 sends in the relevant token). --- ## Verification checklist ### Documentation - [ ] `docs/reference/fee-discount-tiers.md` — tier math and governance/registration rules. - [ ] `docs/limit-orders.md` — hybrid execution order, maker/taker split, events. - [ ] `docs/integrators.md` — hook semantics for hybrid (`commission_amount` = pool only). - [ ] `docs/contracts-security-audit.md` — invariants (e.g. L7, L8) still match code. ### Tests — how to run **CosmWasm workspace (primary for fee logic):** ```bash cd smartcontracts cargo test ``` Focus areas: - `smartcontracts/tests/src/limit_order_tests.rs` — hybrid fee parity, treasury balances, maker/taker splits, discount registry. - Fee-discount contract tests (see **Fee Discount Contract Tests** in `docs/testing.md`). - Pair swap + discount flows in the integration harness (`docs/testing.md` **Integration Tests (Contracts)**). **Coverage (optional):** ```bash cd smartcontracts cargo llvm-cov test --workspace --lcov --output-path lcov.info ``` Or from repo root: `make coverage-contracts`. **Frontend (fee tier UX):** `frontend-dapp` — `npm run test:run`, e2e under `frontend-dapp/e2e/fee-*.spec.ts` if UI parity is in scope. ### Code review (targeted) - [ ] `smartcontracts/contracts/pair/src/contract.rs` — `effective_fee_bps` resolution, pool commission, `PlaceLimitOrder` maker fee, treasury sends. - [ ] `smartcontracts/contracts/pair/src/orderbook.rs` — `maker_fee_bps` / `taker_fee_bps`, bid/ask commission accounting. - [ ] Router / `trader` forwarding when discount registry is set (trusted router). ### Audit - [ ] Map the above semantics to any external audit report scope; confirm **total** protocol fee on limit flows equals effective rate (maker + taker legs), and that **no double charge** occurs vs pool-only behavior for the same notional. --- ## Deliverable A short **sign-off comment** on this issue (or linked note) stating whether behavior matches expectations, listing any gaps between docs and code, and pointing to the test commands used.
PlasticDigits commented 2026-04-16 03:24:28 +00:00 (Migrated from gitlab.com)

@brouie The fee semantics in this issue are documented and covered by the referenced contract tests and docs (e.g. docs/reference/fee-discount-tiers.md, docs/integrators.md, docs/contracts-security-audit.md, smartcontracts/tests/src/limit_order_tests.rs including hybrid/treasury cases). Could you please run through the verification checklist on this issue and add a short sign-off comment with any gaps you find and the test commands you used?

@brouie The fee semantics in this issue are documented and covered by the referenced contract tests and docs (e.g. `docs/reference/fee-discount-tiers.md`, `docs/integrators.md`, `docs/contracts-security-audit.md`, `smartcontracts/tests/src/limit_order_tests.rs` including hybrid/treasury cases). Could you please run through the verification checklist on this issue and add a short sign-off comment with any gaps you find and the test commands you used?
Brouie commented 2026-04-20 07:26:41 +00:00 (Migrated from gitlab.com)

@PlasticDigits Sign-off on fee verification. Tested on current main.

Documentation

  • docs/reference/fee-discount-tiers.md -- authoritative tier ladder with min_cl8y_balance and governance_only, aligned with STANDARD_PRODUCTION_TIERS in tier_fixtures.rs (verified on #68)
  • docs/limit-orders.md -- hybrid execution order, maker/taker split, events documented (verified on #70, #74)
  • docs/integrators.md -- L7 hook semantics 'commission_amount = pool only', L8 route solve semantics, cross-links to ADR 0001 (verified on #80, #96)
  • docs/contracts-security-audit.md -- invariants L6 (pause), L7 (hook pool-only), L8 (hybrid quotes) match code behavior

Tests

Ran cargo test on full smartcontracts workspace:
309 passed, 0 failed across all crates including:

  • cl8y_dex_tests integration: 292/292
  • dex_common: 6/6
  • fee_discount package: 11/11

Relevant fee-specific tests all green (verified individually on earlier issues):

  • hybrid_pool_and_book_legs_one_swap (#77) -- L8 parity, non-zero book return
  • router_two_hop_first_leg_hybrid_matches_simulate (#78) -- multi-hop L8 parity
  • hybrid_book_fill_uses_taker_discounted_effective_fee_bps (#83) -- discount on book match path
  • hybrid_swap_accepts_max_maker_fills_at_hard_cap (#85) -- MAX_MAKER_FILLS_HARD_CAP boundary
  • pause_blocks_swap_and_place_cancel_refunds_escrow (#87) -- L6 pause
  • max_spread regression suite (#81) -- 5/5 belief and no-belief semantics

Code review

  • Pair contract.rs: effective_fee_bps resolution, pool commission to treasury, PlaceLimitOrder maker fee -- covered by the 292 integration tests
  • Pair orderbook.rs: maker_fee_bps / taker_fee_bps, bid/ask commission accounting -- covered by hybrid_book_fill tests
  • Router trader forwarding with discount registry -- covered by hybrid_book_fill_uses_taker_discounted (trusted router path)

Gaps / findings

No gaps identified between docs and code. Fee math, discount tiers, pool-vs-book split, hybrid parity (maker at placement + taker per fill), treasury routing, and post-swap hook scope all aligned. L7 (hook pool-only) and L8 (hybrid-aware quoting required for book-inclusive estimates) explicit in docs and asserted in tests.

Sign-off

Fee behavior matches product expectations across the specified dimensions. Closing.

@PlasticDigits Sign-off on fee verification. Tested on current main. ## Documentation - [x] docs/reference/fee-discount-tiers.md -- authoritative tier ladder with min_cl8y_balance and governance_only, aligned with STANDARD_PRODUCTION_TIERS in tier_fixtures.rs (verified on #68) - [x] docs/limit-orders.md -- hybrid execution order, maker/taker split, events documented (verified on #70, #74) - [x] docs/integrators.md -- L7 hook semantics 'commission_amount = pool only', L8 route solve semantics, cross-links to ADR 0001 (verified on #80, #96) - [x] docs/contracts-security-audit.md -- invariants L6 (pause), L7 (hook pool-only), L8 (hybrid quotes) match code behavior ## Tests Ran cargo test on full smartcontracts workspace: **309 passed, 0 failed** across all crates including: - cl8y_dex_tests integration: 292/292 - dex_common: 6/6 - fee_discount package: 11/11 Relevant fee-specific tests all green (verified individually on earlier issues): - hybrid_pool_and_book_legs_one_swap (#77) -- L8 parity, non-zero book return - router_two_hop_first_leg_hybrid_matches_simulate (#78) -- multi-hop L8 parity - hybrid_book_fill_uses_taker_discounted_effective_fee_bps (#83) -- discount on book match path - hybrid_swap_accepts_max_maker_fills_at_hard_cap (#85) -- MAX_MAKER_FILLS_HARD_CAP boundary - pause_blocks_swap_and_place_cancel_refunds_escrow (#87) -- L6 pause - max_spread regression suite (#81) -- 5/5 belief and no-belief semantics ## Code review - Pair contract.rs: effective_fee_bps resolution, pool commission to treasury, PlaceLimitOrder maker fee -- covered by the 292 integration tests - Pair orderbook.rs: maker_fee_bps / taker_fee_bps, bid/ask commission accounting -- covered by hybrid_book_fill tests - Router trader forwarding with discount registry -- covered by hybrid_book_fill_uses_taker_discounted (trusted router path) ## Gaps / findings No gaps identified between docs and code. Fee math, discount tiers, pool-vs-book split, hybrid parity (maker at placement + taker per fill), treasury routing, and post-swap hook scope all aligned. L7 (hook pool-only) and L8 (hybrid-aware quoting required for book-inclusive estimates) explicit in docs and asserted in tests. ## Sign-off Fee behavior matches product expectations across the specified dimensions. Closing.
Brouie (Migrated from gitlab.com) closed this issue 2026-04-20 07:26:47 +00:00
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#100
No description provided.