feat: /protocol UST1 window mint/redeem treasury fees #614
Labels
No labels
agent:fix_bugfix
agent:fix_conflicts
agent:fix_security
agent:gap_analysis
agent:implement
agent:implement
agent:implement
agent:open_issues
agent:ready
agent:research
agent:security_audit
agent:verify
architecture
backend
blocker:hybrid
blocker:launch
blocker:limit-orders
blocker:v2
block:log_only
block:security
bug
ci
contracts
correctness
deploy
dev
devops
docs
documentation
duplicate
e2e
enhancement
epic
feature
frontend
functional-completion
gas
good first issue
governance
help wanted
high-risk
hooks
hybrid
indexer
infra
infrastructure
integrators
invalid
launch-blocker
limit-orders
localnet
localterra
low priority
missing-implementation
needs-design
ops
performance
priority
high
priority
medium
product
qa
QA
question
ready
ready
research
scripts
security
security-hardening
smartcontracts
tech-debt
testing
ux
UX
v2
verification
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
code/cl8y-dex-terraclassic#614
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Add UST1 window mint/redeem treasury fees to the
/protocolfee census — the same panel that already shows AMM swap and Book take. #586 explicitly left this out of scope (different contract). Production indexer has noUST1_WINDOW_ADDRESSpin, noFeeSourcefor the window, and no ingest.Bundle deposit (vFDUSD→UST1 mint) and withdraw (UST1→vFDUSD redeem) into one issue. Do not split “pin env” vs “parser” vs “migration CHECK” vs “UI label” vs “mint vs redeem”.
Related: #586 (follow-up named in Constraints §14), #506 (
/ust1UI), #503 (ops / inventory), #550 (P550-11: CEX oracle ≠ UST1 window), #568 (stamp USD at ingest), #515 / #580 (never convert DEX fees with vFDUSD/FDUSD). Wrap/unwrap cUSTC/cLUNC ingest is a separate issue (mapper already in the enum; window is not).Current codebase
/ust1mints/redeems UST1 ↔ vFDUSD via CW20Sendto ust1-window — never the AMM router (ust1Window.ts,AGENTS_UST1_WINDOW_UI.md). Deposit hook{ deposit: {} }; withdraw{ withdraw: { min_vfdusd_out } }.effective_swap.fee_bps(approved target 100 = 1% on UST1 notional —ust1WindowMath.tsINV-SWAP-001/002). Goes to CMM treasury (cmm_treasuryon window config). Columbus-5 window:terra1zxwpzpzpleatqn39r00grau4yt29sld8pw78s7ktvjafnj5nsaxq0h3rh2(code 11566,REGISTRY.md).FeeSourceis onlyswap_amm/book_take/limit_place/wrap/unwrap. SQL CHECK onprotocol_fee_eventsandprotocol_fee_stats_by_sourcematches. Noust1_*key.config.rshasWRAP_MAPPER_ADDRESSonly. Grep ofindexer/has zeroUST1_WINDOW.indexer/.env.exampledoes not document a window pin.ProtocolFeeStats.tsxSOURCE_LABEL/SOURCE_ORDERhave no window row. Lead copy says “swaps, book takes, limit places, and wrap.”ProtocolFeeSourceKeyis the five #586 keys. CEX oracle card explicitly not the UST1 window rate (P550-11).Why this is needed
fee_amountand paircommission_amount./protocolis the USD census; omitting the window undercounts CMM.deposit/withdrawvia CW20 Send), different pin, different fee math. Folding it intowrap/unwrapwould lie to retail and break the mapper pin.swap_amm. Counting window mint as a swap would mix oracle mint volume with pool commission./ust1fee (1%) to Protocol totals will think the indexer is wrong.Constraints / guardrails
UST1_WINDOW_ADDRESS: trim, reject whitespace / wrong HRP /LIKE %, exactterra1equality on reserved_contract_addressonly (#285). Empty / garbage → omit window sources (not fake idle$0). Do not reuseWRAP_MAPPER_ADDRESS.ust1_notional × fee_bps. Missing identity → drop.deposit/withdraw/effective_swap. Hide idle$0(PFee-3).$1UST1 peg. Never2.5×USTR. Stampfee_usdat ingest (#568).min_vfdusd_outslippage haircut, paused/stale reject, rolling 24h unused capacity./protocol/feesrollup. Migration must widen CHECK constraints (ust1_mint/ust1_redeemor the chosen keys).FeeSource::parsestays allowlist — unknown /javascript:rejected.window=query param stays24h|7d|30d(400 else). Do not overload that word with “ust1-window”.other. No per-user window tape on/protocol.indexer/into root Docker for cargo.fee_bps. Soft-launch/mintfaucet. Wrap-mapper ingest (separate issue). Pair-creationuluna. Marketing the CEX vFDUSD tab as the window rate.Relevant files
indexer/src/indexer/protocol_fees.rsparse_*_window_feesindexer/src/indexer/parser.rssend+ window hookindexer/src/config.rs+indexer/.env.exampleUST1_WINDOW_ADDRESSindexer/migrations/protocol_fee_events_source_chk+protocol_fee_stats_by_source_source_chk; optionalust1_window_configuredonglobal_stats_24h(mirrorwrap_mapper_configured)indexer/src/db/queries/protocol_fees.rsindexer/src/api/protocol_fees.rsust1_window_configured(additive JSON)indexer/src/indexer/volume_aggregator.rsfrontend-dapp/src/types/index.tsProtocolFeeSourceKey+ response flagfrontend-dapp/src/components/protocol/ProtocolFeeStats.tsxfrontend-dapp/src/pages/ProtocolPage.test.tsxfrontend-dapp/src/services/terraclassic/ust1Window.tsskills/AGENTS_FRONTEND_PROTOCOL_STATS.mdskills/AGENTS_UST1_WINDOW_UI.md/mint)docs/indexer-invariants.md,docs/frontend.md§ Protocol,docs/runbooks/overview-global-stats-brin.mddeployments/mainnet-ust1-wrap/coolify.env.exampleeffective_swap/ wasm attrsRecommended direction
action, fee amount key, token key, and whether mint vs redeem are distinct. Do not invent attrs fromfee_bpsalone.parse_ust1_window_address/parse_ust1_window_fees. Flattened CW20send+ hook must still attribute the fee to the window_contract_address, not the UST1/vFDUSD token contract.ust1_mint+ust1_redeemwith labels UST1 mint / UST1 redeem. If not: oneust1_windowrow. Put them inSOURCE_ORDERafter unwrap, before AMM swap (or after wrap family — keep wrap/window grouped).ust1_window_configured(or a genericsources_configuredobject — prefer the wrap mirror for one flag). Additive GET JSON: old indexers without the flag → hide window rows, do not invent$0(PFee-10).UST1_WINDOW_ADDRESSon the indexer service (ViteVITE_UST1_WINDOW_ADDRESSdoes not feed the indexer).make verify-issue-<iid>: docs, CHECK + parse allowlist, omit-if-unconfigured, fixture ingest, UI labels, no GET scan, no vFDUSD conversion.Acceptance criteria
UST1_WINDOW_ADDRESSparsed like the wrap pin; invalid/empty omits window sources.protocol_fee_eventswith the new source(s), positiveamount_raw, and hub-stampedfee_usdwhen UST1 is priced.× fee_bps).then ≤ 0→null)./protocolSource shows retail UST1 mint / UST1 redeem (or the chosen single label) when events exist; idle$0hidden; unconfigured omitted./overviewand/protocol/feesstay O(1);window=allowlist unchanged.make verify-issue-586still passes. Newmake verify-issue-<iid>is the gate.Test plan (happy + edge)
send{ deposit }ust1_mint(or bundled source); fee token from attrs; USD via hub UST1 if that is the fee assetsend{ withdraw }ust1_redeem; slippagemin_vfdusd_outis not the fee$0; totals"0"fee_usdNULL; activity+all-unpriced →—ON CONFLICTno double-countsend+ window hook + cw20 mint)$0?ticker=vfdusdon/protocol--freshTest plan (attack / abuse)
action=deposit+ hugefee_amount_contract_addresscontract_address(no underscore)amount × 100when attr missing$1UST1 /2.5×USTRexchangeRateCurrentas treasuryjavascript:in symbolsource=javascript:in rollupFeeSource::parsedropswindow=30d); DROP TABLEFeeSource::ALL+ UI key updated togetherswap_amm(user later sells UST1 on AMM)swap_ammonlyprotocol_fee_eventsfor the new sourcesVerification criteria
Close only when Coolify indexer env documents the pin, a captured-or-LocalTerra tx increments the new source
event_count, USD uses hub/catalog (not vFDUSD/$1), unconfigured omit works, and #586 verify still passes. UI-only labels without ingest are not done.marked as related to #586
marked as related to #506
marked as related to #503
marked as related to #613
mentioned in issue #613
mentioned in merge request !1129
Follow-up for live ingest: ust1-window must emit
fee_amount+fee_asset(UST1) on deposit/withdraw. Opened ust1-window#33.DEX pin/parse/UI is in !1129 and stays fail-closed on columbus-5 11566 (bps attrs only). Do not infer
ust1_notional × fee_bpshere.mentioned in merge request ust1-window!732
mentioned in merge request ust1-window!733
mentioned in commit
c37265dc48mentioned in commit
992b980a3fmentioned in issue #616
marked as related to #616
Merge sanity (!1129 landed on
main; does not close this issue; CI not waited).Conflicts with !1128 wrap ingest resolved: keep #613
notify_deposit/feesegment scan andust1_mint/ust1_redeempin/parse. Follow-up992b980arestoredPFee-1–PFee-12indocs/frontend.mdsoverify-issue-586/614greps both pass.Automated:
make verify-issue-6146/6 (docs/CHECK/pin, lib parse fail-closed on crate bps-only attrs, integration omit-if-unconfigured, Protocol UST1 mint / UST1 redeem labels).Problems that keep this issue open
fee_*_bps/vfdusd_to_treasurywithoutfee_amount. Live mint/redeem stay dropped (fail closed). Upstream: ust1-window#33.UST1_WINDOW_ADDRESSis not set by this merge. Vite alone is not enough.ust1_notional × fee_bpshere.Ops checklist: #616.
Upstream window now emits
fee_amount(columbus-5)ust1-window#33 store+migrate is on the same address. Pin stays
terra1zxwpzpzpleatqn39r00grau4yt29sld8pw78s7ktvjafnj5nsaxq0h3rh2(do not instantiate a second window).F4D79240E8009740C63F3342A2AA655CE7015579FC376B765AC3821EF823C60A009BD391E27AE8A6A7FCBA94443E2A257875A19603C51FAB1CC6C6B91E8E747Dterra1xsecn…(cl8y2_admin) unchangedfee_bps=100preservedLive mint/redeem can now name
fee_amount+fee_asset(UST1). Indexer still fail-closes if CoolifyUST1_WINDOW_ADDRESSis unset. Vite pin is not enough.Still needed to close this issue: Coolify indexer pin + one captured deposit and one withdraw incrementing
protocol_fee_eventsust1_mint/ust1_redeem. See #616. Do not inferust1_notional × fee_bps.Live indexer still missing
UST1_WINDOW_ADDRESSAfter the 2026-08-24 Coolify redeploy:
VITE_UST1_WINDOW_ADDRESS=terra1zxwp…h3rh2GET /api/v1/protocol/fees→ust1_window_configured: false(mint/redeem rows omitted, not idle$0)fee_bps=100, paused=false) — wasmfee_amount/fee_assetare live on-chain (ust1-window#33 store+migrate)Set indexer Coolify:
Then one deposit + one withdraw to close the live-tx AC. Do not infer fees from
fee_*_bps. Issue stays open.mentioned in issue #631
mentioned in commit
e56a1fd323Verification (worktree
verify-issue-614)Ran
make verify-issue-614on a git worktree. First pass failed only because the worktree had nofrontend-dapp/node_modules(vitest: not found). Fixed the verify scripts to bootstrap a sibling symlink ornpm ci(same pattern as #516 / #634). Re-ran after that: 7/7 PASS, including the new live leftover probe.Pushed to
mainas89515ec1(docs + I614 playbook + verify bootstrap). Local primarymainstill had another agent's uncommitted files after 5×90s, so this wasgit push origin HEAD:mainfrom the worktree (did not touch that dirty checkout).What landed on main (this verify)
skills/AGENTS_INDEXER_UST1_WINDOW_FEES.md(I614-1–I614-8).fee_amount+fee_asset. 11566 bps-only attrs stay fail-closed. Neverust1_out × fee_total_bps.AGENTS.md,docs/indexer-invariants.md,docs/frontend.md,docs/testing.md, wrap skill, UST1 UI skill, #616 leftover copy (do not reopen #614).make verify-issue-614now greps I614 + 11618, bootstraps worktree frontend deps, and probes liveust1_window_configured+ mint/redeemevent_count.Live indexer (2026-08-25,
indexer.dex.cl8y.com)ust1_window_configuredtrueust1_mintevent_count=2,amount_usd≈1.58ust1_redeemevent_count=3,amount_usd≈3.70GET /hub-prices≈ 1.015 (not$1, not CEX vFDUSD)total_fees_24h_usdincludes the window rowsCoolify indexer pin is set. Vite-only bake is still not enough on rebuild — keep
UST1_WINDOW_ADDRESS=terra1zxwpzpzpleatqn39r00grau4yt29sld8pw78s7ktvjafnj5nsaxq0h3rh2.Checklist (issue body + comments)
UST1_WINDOW_ADDRESSparsed like wrap; invalid/empty omits window sourcesust1_mint/ust1_redeemwith positiveamount_raw; hub-stampedfee_usdwhen UST1 is pricedfee_amount/ token → no row (no× fee_bps); 11566 crate attrs fail closedcontract_addressignoredthen ≤ 0→null/protocolSource labels UST1 mint / UST1 redeem; idle$0hidden; unconfigured omitted/overviewand/protocol/feesstay O(1);window=allowlist unchangedmake verify-issue-586still passescoolify.env.example+ REGISTRY)event_count(comment leftover)$1UST1fee_amount+fee_asset(ust1-window#33) — do not infer from bpsAll verification criteria from the issue body and comments pass. Closing.
mentioned in commit
c89be8e43ementioned in issue #682
mentioned in issue #683
mentioned in issue #687
mentioned in issue #689
ops-worker referenced this issue2026-09-06 12:05:09 +00:00
ops-worker referenced this issue2026-09-06 12:05:13 +00:00