feat: Phase 3 — treasury migrate + wrap-mapper (cLUNC/cUSTC, 1% fee) #5
Labels
No labels
bug
docs
documentation
duplicate
enhancement
frontend
good first issue
help wanted
invalid
missing-implementation
priority
medium
product
QA
question
testing
UX
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
code/ustr-cmm#5
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
Enable treasury-backed native wrapping for LUNC ↔ cLUNC and USTC ↔ cUSTC on Terra Classic mainnet using ustr-cmm treasury + wrap-mapper. Migrate the live CMM treasury to wrap-capable bytecode, deploy wrap-mapper and CW20 wrappers, and wire denom mappings — without reviving the USTC→USTR swap window and without using
ust1-window’scmm-native-wrap.Phase 0 decisions (approved):
cmm-native-wrap(ust1-window).fee_bps=100), governance-updatable (max 1000 bps / min 1 bps in contract).10673).Current codebase
contracts/contracts/treasury/WrapDeposit,InstantWithdraw,SetDenomWrapper,SetWrappingPaused; migrate entrypointcontracts/contracts/wrap-mapper/plans/NATIVE_TOKEN_WRAPPING.mddocs/DEPLOYMENT.md,docs/CONTRACTS.mdterra16j5u6…but do not document wrap-mapper mainnetLive mainnet (verified via LCD):
terra16j5u6ey7a84g40sr3gd94nzg5w5fm45046k9s2347qhfpwm5fr6sem3lr2, code_id 10673, adminterra1xsecn4snv94ezcez0z3vq8an9j4h4kxxcydp8l.{"denom_wrappers":{}}fails (unknown variant) → bytecode is pre-wrap; migrate required before wrap works.swap_contract: null(swap era ended — keep it that way).Downstream consumer:
cl8y-dex-terraclassicalready integrates treasury + wrap-mapper on LocalTerra (deploy-dex-local.shPhase 1b, routerSetWrapMapper, frontendwrapMapper.ts) but mainnet soft launch SL5 excluded wrap.Why this is needed
Native LUNC/USTC cannot be pair assets on CL8Y DEX (factory rejects native
AssetInfo). Users need 1:1 CW20 wrappers backed solely by treasury native balances so Phase 4 can enable wrap UX and secondary markets. The live treasury must be migrated; wrap-mapper is not yet on mainnet.Constraints / guardrails
uluna/uusd.cmm-native-wrapfrom ust1-window.SwapDepositproduct path; leaveswap_contractnull.fee_bps: 100(1%), not LocalTerra’s historical 50 bps default.terra16j5u6…).docs/DEPLOYMENT.md+docs/CONTRACTS.mdwith wrap-mapper addresses and migrate steps (docs currently stale).Relevant files
contracts/contracts/treasury/src/contract.rs(migrate, wrap handlers)contracts/contracts/treasury/src/msg.rs/state.rscontracts/contracts/wrap-mapper/src/contract.rs/msg.rs/state.rsplans/NATIVE_TOKEN_WRAPPING.mddocs/DEPLOYMENT.md,docs/CONTRACTS.md,docs/ARCHITECTURE.md(update for wrap)cl8y-dex-terraclassic/NATIVE_TOKEN_WRAPPING.md,scripts/deploy-dex-local.shPhase 1bRecommended direction
treasury.wasm+wrap_mapper.wasmfrom current workspace (0.2.0wrap API).terra16j5u6…from 10673 → new code_id (adminterra1xsecn…).config(includeswrapping_paused),denom_wrappers.{ governance, treasury: terra16j5u6…, fee_bps: 100 }.add_minter(wrap-mapper).SetDenomMappingforuluna→cLUNC anduusd→cUSTC.SetDenomWrapperfor both denoms → wrap-mapper.set_wrap_mapper, frontend env) and Phase 5 (ops).Optional: set initial per-denom rate limits via
SetRateLimitbefore public wrap.Acceptance criteria
denom_wrappers/ wrap queries succeed on mainnet address (same bech32).fee_bps == 100.ulunaanduusd.uluna→ cLUNC and unwrap cLUNC →ulunasucceed (small mainnet smoke).uusd→ cUSTC and unwrap cUSTC →uusdsucceed (small mainnet smoke).swap_contractnull / no new swap product).cmm-native-wrapdeployment.Test plan (happy / functional paths)
cargo testin contracts workspace).deploy-dex-local.shPhase 1b but withfee_bps: 100; full wrap/unwrap matrix for both denoms.test_migrate_from_old_version; confirm state preserved.SetFeeBps(e.g. temporary change on LocalTerra),SetRateLimit, pause/unpause.Test plan (attack / hack / abuse vectors)
InstantWithdrawSetDenomWrapper/SetDenomMapping/SetFeeBpsInstantWithdraw(insolvency guard)wrapping_pausedor wrap-mapperpausedMAX_FEE_BPS(1000) or <MIN_FEE_BPS(1)Verification criteria
NATIVE_WRAPPED_PAIRSwiring.DEPLOYMENT.md/CONTRACTS.mdmention wrap).Related
/ust1UI + pairsCross-repo tracking (Phase 0 approved)
/ust1UI + wraps + secondary AMMApproved params: window
fee_bps=100, per-tx 1000 UST1, 24h 10000 UST1; wrapfee_bps=100(1%). UI atdex.cl8y.com/ust1. Skipcmm-native-wrap. Phase 1 prerequisites confirmed.mentioned in issue PlasticDigits/cl8y-dex-terraclassic#502
mentioned in issue PlasticDigits/cl8y-dex-terraclassic#503
changed title from
feat: Phase 3 — treasury migrate + wrap-mapper (LUNC-C/USTC-C, 1% fee)tofeat: Phase 3 — treasury migrate + wrap-mapper (cLUNC/cUSTC, 1% fee)changed the description
Naming update
Wrapped token symbols are cLUNC and cUSTC (not
LUNC-C/USTC-C).LocalTerra / existing DEX code may still say
LUNC-C/USTC-C— Phase 3–4 implementation must mint and display cLUNC / cUSTC on mainnet and align frontend registry/env naming.mentioned in issue #6
Coordination: CW20 InstantWithdraw / spender registry for ust1-window is tracked in https://gitlab.com/PlasticDigits2/ustr-cmm/-/work_items/6 — prefer bundling into the same treasury migrate as this Phase 3 wrap work if schedules align (non-breaking parallel msgs; must not gate CW20 pulls on
wrapping_paused).mentioned in merge request !27
Bundled treasury upgrade (MR !27 + !28 + Phase 3 wrap)
Both CW20 InstantWithdraw pieces are already on
masterand should ride the same in-place treasury migrate as this Phase 3 wrap work:InstantWithdrawCw20+ spender registry +cw20_iw_paused(token, spender)10673Build from current workspace
0.2.1(not the issue’s older0.2.0note). One store + one migrate ofterra16j5u6…— do not migrate twice.A. One-shot treasury migrate
treasury.wasm+wrap_mapper.wasmfrommaster(0.2.1).terra16j5u6…(10673→ new code_id) as adminterra1xsecn….config→wrapping_paused,cw20_instant_withdraw_paused,swap_contract: nulldenom_wrappers,cw20_spenderscw20_spender_limit(pair query OK even if empty)B. Phase 3 wrap wiring (this issue)
{ governance, treasury: terra16j5u6…, fee_bps: 100 }.10184, decimals 6);add_minter(wrap-mapper).SetDenomMapping:uluna→cLUNC,uusd→cUSTC.SetDenomWrapperfor both denoms → wrap-mapper.SetRateLimitper denom before public wrap.swap_contractnull.C. CW20 InstantWithdraw / window (after ust1-window ready)
Fail-closed (#7): pulls deny until a limit is set. Do not register a spender without
limit_24h.SetCw20Spender { token: vFDUSD, spender: WINDOW, limit_24h: "<quota>" }(align quota with window 24h inventory, e.g. ~10_000 UST1-side policy).
cw20_spender_limit; then small redeem smoke.set_wrapping_paused≠ CW20 pulls; useset_cw20_instant_withdraw_pausedfor window IR. Neither stops govExecuteWithdraw.Do not
cmm-native-wrap/ re-enable USTC→USTR swap.wrapping_paused.Ops detail: docs/DEPLOYMENT.md § Treasury Migrate + CW20 Spender Wiring; agent playbook: skills/treasury-cw20-instant-withdraw.
mentioned in issue #8
marked as related to #8
Bundle: remove obsolete
SwapDeposit/swap_contractintegration in the same treasury migrate as this issue — see #8 (audit MB-1; full removal, not restore NotifyDeposit on ustc-swap).mentioned in commit
b2fe58e020mentioned in merge request !29
mentioned in merge request !30
Mainnet deploy complete (A + B + C) — 2026-08-08
One-shot via
contracts/scripts/treasury-migrate-wrap-wire.shascl8y2_admin(terra1xsecn4snv94ezcez0z3vq8an9j4h4kxxcydp8l). Docs updated:README.md,docs/DEPLOYMENT.md,docs/CONTRACTS.md.A — Treasury migrate
terra16j5u6ey7a84g40sr3gd94nzg5w5fm45046k9s2347qhfpwm5fr6sem3lr210673→11564380BA17B60B191ACFB786D086F72BDCB04243F97249A5F1F225F97E41DA656F965E36AF139E87FEE2271AD5C8FE58F9CE095B237D1549C8B2FEDB1CF0E14EE20Post-migrate
config:wrapping_paused=false,cw20_instant_withdraw_paused=false, noswap_contractfield (#8 strip). Queriesdenom_wrappers/cw20_spenders/cw20_spender_limitsucceed.B — Wrap wiring
terra1xuuuhpmyd5t29ry7mydg7ra2q2phrwhx7j28nx7x9sjw6zznkumsz0nmd2terra1437qslye72t7qmmahn4t5chz50r8a62g45phwkquwpyu2l62u6ksqssgdgterra1nap4dxh9tv35v0ynd9m4k6zt6c0dq6weszc4j5m564kjls56hu7qcr56chfee_bpsSetDenomMappinguluna→cLUNC, uusd→cUSTCSetDenomWrapperboth denoms → wrap-mapperB3C2597B25FC7C85D1147473B5011281013AAB80694F56BECB5EEE8F93D23164A5E4D3024FF6AD86702AAD29A3CD9ABCD5E933B9B8A82E58522B6BC87C826799C — CW20 InstantWithdraw spender (#6 / #7)
terra1mnl9azefrqpmu888ar2u6zrcwr80hxlt3avf4300r576cw5ar7esvxsvj3terra1zxwpzpzpleatqn39r00grau4yt29sld8pw78s7ktvjafnj5nsaxq0h3rh2limit_24h10000000000(10_000 @ 6 decimals), remaining full91BF752B8AFB08438D69C4827E94C506580DC0A211D9D2F19BA754F47366D630Gas note
DEPLOYMENT.mdfixed--fees 100000000ulunais insufficient for wasm store. Ops used--gas auto --gas-prices 28.325uluna(store adj 1.5).Remaining (not blocking migrate/wire)
set_wrap_mapper+ envSetRateLimitbefore public wrapArtifact:
contracts/scripts/treasury-migrate-wrap-20260808-090524.jsonDo not deploy
cmm-native-wrap; USTC→USTR swap remains disabled.config complete, closing
mentioned in issue PlasticDigits/cl8y-dex-terraclassic#507
mentioned in issue PlasticDigits/cl8y-dex-terraclassic#508