fix(indexer): persist every multihop AMM hop in protocol_fee_events #1274

Merged
PlasticDigits merged 3 commits from issue/1269 into main 2026-09-16 22:57:02 +00:00

Summary

  • Persist every factory AMM hop in protocol_fee_events with pair-scoped uniqueness (tx_hash, source, pair_id, ordinal) so per-pair swap_index 0 hops no longer collide.
  • Wrap / unwrap / UST1 / book / place keep NULL pair_id and a partial unique on (tx_hash, source, ordinal). Replay stays ON CONFLICT DO NOTHING (never overwrite).
  • One-shot SQL + poller-startup backfill from swap_events.commission_amount; trade_exists still skips swap insert but retries fee ingest.

Fixes #1269

Test plan

  • VERIFY_ISSUE_1269_SKIP_RELATED=1 make verify-issue-1269 (docs/source greps, lib protocol_fees, parser swap_index, indexer_protocol_fees hop/replay/wrap/backfill)
  • make verify-issue-586 (and 613/614/683) after Coolify/indexer deploy
  • After deploy + backfill + aggregator tick, /protocol 7d AMM matches hop-complete priced SUM, not the collision-truncated census
  • Poller replay does not inflate fee_event_count
## Summary - Persist every factory AMM hop in `protocol_fee_events` with pair-scoped uniqueness `(tx_hash, source, pair_id, ordinal)` so per-pair `swap_index` 0 hops no longer collide. - Wrap / unwrap / UST1 / book / place keep NULL `pair_id` and a partial unique on `(tx_hash, source, ordinal)`. Replay stays `ON CONFLICT DO NOTHING` (never overwrite). - One-shot SQL + poller-startup backfill from `swap_events.commission_amount`; `trade_exists` still skips swap insert but retries fee ingest. Fixes #1269 ## Test plan - [x] `VERIFY_ISSUE_1269_SKIP_RELATED=1 make verify-issue-1269` (docs/source greps, lib `protocol_fees`, parser `swap_index`, `indexer_protocol_fees` hop/replay/wrap/backfill) - [ ] `make verify-issue-586` (and 613/614/683) after Coolify/indexer deploy - [ ] After deploy + backfill + aggregator tick, `/protocol` 7d AMM matches hop-complete priced `SUM`, not the collision-truncated census - [ ] Poller replay does not inflate `fee_event_count`
fix(indexer): persist every multihop AMM hop in protocol_fee_events
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
8ea9c302b9
Pair-scope swap_amm uniqueness so per-pair swap_index 0 hops coexist.
Backfill missing commissions from swap_events; replay stays idempotent.
Author
Owner

drain skip: no occupying job for rebase/fix-pr/CI-wait; remaining continue

drain skip: no occupying job for rebase/fix-pr/CI-wait; remaining continue
Author
Owner

/agent review

/agent review
Author
Owner

cl8y-agent-control: queued bug_review job 2ef6078c-0758-4dbe-a41d-a473acf8f7e1 (not executed; no Hetzner VM).

cl8y-agent-control: queued `bug_review` job `2ef6078c-0758-4dbe-a41d-a473acf8f7e1` (not executed; no Hetzner VM).
Merge branch 'main' into issue/1269
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
0ddffa5afd
Merge branch 'main' into issue/1269
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
3b080cfd3b
Author
Owner

Design for this slice is in-repo (docs only; no Coolify migrate/deploy from this comment).

Outcome: every factory AMM hop with commission_amount > 0 is one swap_amm row. Unique (tx_hash, source, pair_id, ordinal) WHERE pair_id IS NOT NULL; wrap/window/book/place stay NULL pair_id with the non-pair partial. Replay ON CONFLICT DO NOTHING. Backfill from swap_events. GET stays rollup-only.

Not #297 deploy/spend/custody. Not a founder card.

DESIGN: READY_FOR_REVIEW

Design for this slice is in-repo (docs only; no Coolify migrate/deploy from this comment). - ADR: https://git.cl8y.com/code/cl8y-dex-terraclassic/src/branch/design/1274-protocol-fee-hops/docs/adr/0005-protocol-fee-multihop-hops.md - Overview: https://git.cl8y.com/code/cl8y-dex-terraclassic/src/branch/design/1274-protocol-fee-hops/docs/architecture.md#indexer-protocol-fee-ledger - Design PR: https://git.cl8y.com/code/cl8y-dex-terraclassic/pulls/1275 Outcome: every factory AMM hop with `commission_amount > 0` is one `swap_amm` row. Unique `(tx_hash, source, pair_id, ordinal)` WHERE `pair_id IS NOT NULL`; wrap/window/book/place stay NULL `pair_id` with the non-pair partial. Replay `ON CONFLICT DO NOTHING`. Backfill from `swap_events`. GET stays rollup-only. Not #297 deploy/spend/custody. Not a founder card. DESIGN: READY_FOR_REVIEW
Sign in to join this conversation.
No reviewers
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!1274
No description provided.