feat(wrap): consume fee_wrap_bps / fee_unwrap_bps for ≈2% unwrap all-in (ustr-cmm#9) #516
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#516
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
Consume wrap-mapper
fee_wrap_bps/fee_unwrap_bpson the DEX (frontend + docs + ops probes) after ustr-cmm#9 migrates mainnet to200/51, so unwrap quotes show user all-in ≈ 2% (fee + Classic burn tax) without InstantWithdraw gross-up.Upstream (contracts): PlasticDigits2/ustr-cmm#9 — fee split migration + retune rule.
Supersedes gross-up follow-up called out in #512 /
skills/AGENTS_WRAP_UNWRAP_BURN_TAX.mdfor the “make unwrap 2%” product goal (disclosure from #512 stays until fees land).Current codebase
Live / product context
terra1xuuuhpmyd5t29ry7mydg7ra2q2phrwhx7j28nx7x9sjw6zznkumsz0nmd2— today singlefee_bps=200.InstantWithdrawBankMsg::Send.Relevant files (cl8y-dex-terraclassic)
frontend-dapp/src/services/terraclassic/wrapMapper.tsqueryWrapMapperConfig,wrapUnwrapFeeNote, config cachefrontend-dapp/src/services/terraclassic/router.tsnetCw20AfterNativeWrap,netNativeAfterUnwrap, simulate native swapfrontend-dapp/src/utils/nativeTransferTax.tsfrontend-dapp/src/pages/WrapPage.tsxfrontend-dapp/src/pages/SwapPage.tsxfrontend-dapp/src/utils/poolProvideCounterpart.tsfrontend-dapp/src/types/index.tsskills/AGENTS_WRAP_UNWRAP_BURN_TAX.mdskills/AGENTS_MAINNET_WRAP_ENABLEMENT.mdNATIVE_TOKEN_WRAPPING.mddocs/qa-templates/wrap-unwrap-test-pass.mddocs/runbooks/ust1-wrap-production-ops.mddeployments/mainnet-ust1-wrap/REGISTRY.mdscripts/check-ust1-wrap-ops-health.shIndexer: no change expected unless it indexes mapper config events/fields (verify; out of scope if unused).
Why this is needed
fee_bps.fee_unwrap_bpsfor unwrap /unwrap_outputandfee_wrap_bpsfor wrap / wrap-input — otherwise quotes stay wrong or fall back incorrectly.Constraints / guardrails
200/51(or dual-read compat window documented there).routerMinReceiveBasestays post-fee pre-tax for routerminimum_receive(R3).{ fee_bps }fallback (wrap=unwrap=fee_bps) if ustr-cmm MR provides it — match upstream choice exactly.fee_bps(different contract).Recommended direction
queryWrapMapperConfigforfee_wrap_bps/fee_unwrap_bps(compat per upstream).wrapUnwrapFeeNoteexamples/tests: e.g. unwrap 51 bps + 1.5% tax → all-in ≈ 2% copy still honest (“fee; You Receive after burn tax”).make verify-issue-512or addmake verify-issue-NNNfor dual-fee unit tests once this issue is numbered.Retune rule (mirror upstream)
Example:
0.015→ 51. Goal: user unwrap all-in ≈ 2% (receive/A = 0.98), prefer ≤2% when rounding. If tax ≥ ~2%, escalate — cannot hit 2% all-in without subsidy/gross-up.Acceptance criteria
fee_wrap_bps/fee_unwrap_bpscorrectly on all wrap/unwrap paths (Wrap page, Swap native in/out, pool provide wrap auto-fill).Test plan (all paths)
Unit
fee_bpsfallback if supported.netCw20AfterNativeWrapuses wrap fee only.netNativeAfterUnwrapuses unwrap fee then tax.wrapUnwrapFeeNotefor wrap vs unwrap with distinct bps + tax rate.Manual / QA (
docs/qa-templates/wrap-unwrap-test-pass.md)wrap_input/unwrap_output/ both.Ops
scripts/check-ust1-wrap-ops-health.sh(or successor checks) understands split fees.Test plan (attack / hack / abuse)
Verification criteria
fee_wrap_bps=200,fee_unwrap_bps=51Depends on: ustr-cmm#9.
marked as related to PlasticDigits2/ustr-cmm#9
mentioned in issue PlasticDigits2/ustr-cmm#9
Upstream contracts issue: https://gitlab.com/PlasticDigits2/ustr-cmm/-/work_items/9
Blocked on wrap-mapper migrate + gov set
fee_wrap_bps=200/fee_unwrap_bps=51before production UI verification.mentioned in merge request PlasticDigits2/ustr-cmm!727
mentioned in issue PlasticDigits2/ustr-cmm#13
ustr-cmm ops tracker for the bundled mainnet rollout: https://gitlab.com/PlasticDigits2/ustr-cmm/-/work_items/13
#9 code is merged; wrap-mapper is still live
11565/fee_bps=200. Implement this issue (#516) before or in the same window as migrate —Configdropsfee_bps(no dual-read).marked as related to #521
mentioned in issue #521
Factory #518 upgrade on columbus-5 is done (unrelated contract). Full tx/code-id record and remaining #516 ops order: https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/521#note_3690047839
Re-queried wrap-mapper just now: still code 11565,
{ fee_bps: 200 }. Admin remainscl8y2_admin(terra1xsecn4snv94ezcez0z3vq8an9j4h4kxxcydp8l). DEX 2-of-3 was not used and must not be used for mapper migrate /SetFees.#516 code in this repo is still outstanding. Ship it (or the Coolify artifact) before or in the same window as ustr-cmm#13 store + migrate +
set_fees200/51 —Configdropsfee_bps(no dual-read).mentioned in commit
75d9cf16d0mentioned in merge request !1054
Implementation shipped in !1054 (
feat/516-wrap-mapper-split-fees).Frontend consumes
fee_wrap_bps/fee_unwrap_bps(legacy{ fee_bps }mapped to both sides until migrate).make verify-issue-516green. Coolify rebuild still needed in the ustr-cmm#13 window.DEX router wasm still deserializes wrap-mapper
Config.fee_bpsfor unwrap_output R3 — upgrade that before or with mapper migrate (called out on the MR).Merge review (!1054) — 2026-08-15
Verified !1054 (
feat/516-wrap-mapper-split-fees@75d9cf1) against this issue’s acceptance criteria. No merge conflicts with currentmain. Merging viaglab mr merge(not auto-merge; not waiting on CI).Acceptance criteria
fee_wrap_bps/fee_unwrap_bpson Wrap, Swap native in/out, pool provide wrap auto-fillrouter.test.ts)make verify-issue-516W8–W15 / fail-closed /
{ fee_bps }fallback / no hardcoded quote math: pass. ust1-windowfee_bpsuntouched.Problems / remaining work (not blocking this MR)
ci_quota_exceeded(frontend, frontend-build, gitleaks) — not a code failure. Did not wait to re-run.Config.fee_bpsfor on-chainunwrap_outputR3. After ustr-cmm#9 migrate (Configdropsfee_bps), unwrap_output settlement will fail unless router is upgraded in the same window. Already called out on the MR.set_fees200/51 and Coolify frontend rebuild. Until then live LCD is still{ fee_bps: 200 }and UI will truthfully show ~9 653 unwrap, not 9 800.{ fee_bps: 0 }(transitional parser covers it; split-fee E2E not exercised).Not this MR
Local uncommitted
smartcontracts/artifacts/checksums.txtonmainis leftover wasm-build residue (factory/pair hashes + extra ignored wasm names). Unrelated to #516; will not be committed with this merge.mentioned in commit
248b144a67Upstream chain unblocked (ustr-cmm#13)
columbus-5 wrap-mapper is now the breaking
Configthis issue was waiting on:11574, cw20.3.0{ fee_wrap_bps: 200, fee_unwrap_bps: 51 }— nofee_bps9B305800…/ migrate8F05225E…/SetFees740CB152…!1054 frontend can quote 200/51 from LCD. Still open (not this issue’s code): Coolify rebuild +
/wrapsmoke, and router wasm #523 store+migrate (old routerunwrap_outputstill expectsfee_bps). Tracker: ustr-cmm#13.Leaving closed — consumer code shipped; prod checklist is ops.
mentioned in issue #512
mentioned in issue #523
Direct wrap/unwrap smoke (cl8ydeploy) — 2026-08-15
Live mapper 200 / 51 confirmed. This is direct treasury
wrap_deposit+ CW20sendunwrap — not routerunwrap_output.Wallet
terra1hu4zggf3f8yw6jw3rxrjxn2drwad675gq5k2lvhad 0 uusd; used 10 000 uluna (0.01 LUNC).C5DDA278…D493B7wrap_deposit10000 uluna → mappernotify_depositfee_wrap_bps=200 fee=200 mint=9800 cLUNC58FEE7CE…F08526floor(9751×0.015)=146)Terminal
balafter wrap still showed 0 cLUNC because it ran on the sync ack before inclusion. After both included: cLUNC 0, round-trip complete.Note: QA “unwrap 10 000 → 9 800 native” is for unwrapping 10 000 CW20. This smoke unwrapped the wrap output (9 800), so native back is 9 605, which matches 51 bps + tax on 9800.
Router
unwrap_outputon 1.1.0 (11576) still needs a CW20→native Swap to prove #523 settlement.mentioned in issue #525
marked as related to #525
marked as related to #526
mentioned in issue #533
mentioned in issue #539
mentioned in issue #549
mentioned in issue #586
mentioned in issue #587
mentioned in issue #613
marked as related to #613
mentioned in issue #614
mentioned in issue #661
mentioned in issue #690