feat: Phase 3 — treasury migrate + wrap-mapper (cLUNC/cUSTC, 1% fee) #5

Closed
opened 2026-07-29 02:07:43 +00:00 by PlasticDigits · 20 comments
PlasticDigits commented 2026-07-29 02:07:43 +00:00 (Migrated from gitlab.com)

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’s cmm-native-wrap.

Phase 0 decisions (approved):

  • Wrap path = this repo’s treasury + wrap-mapper only.
  • Skip cmm-native-wrap (ust1-window).
  • No active ust1/ustr/ustc swap window; treasury is used for wrap backing (+ later vFDUSD custody for UST1 window).
  • Wrap/unwrap fee: 1% (fee_bps=100), governance-updatable (max 1000 bps / min 1 bps in contract).
  • Phase 1 prerequisites confirmed (treasury admin can migrate code 10673).

Current codebase

Component Path Role
Treasury (wrap msgs) contracts/contracts/treasury/ WrapDeposit, InstantWithdraw, SetDenomWrapper, SetWrappingPaused; migrate entrypoint
wrap-mapper contracts/contracts/wrap-mapper/ Mint/burn CW20; fees; rate limits; never holds native
Design plans/NATIVE_TOKEN_WRAPPING.md Authoritative wrap architecture + test matrix
Mainnet docs (stale on wrap) docs/DEPLOYMENT.md, docs/CONTRACTS.md List treasury code 10673 / address terra16j5u6… but do not document wrap-mapper mainnet

Live mainnet (verified via LCD):

  • Treasury terra16j5u6ey7a84g40sr3gd94nzg5w5fm45046k9s2347qhfpwm5fr6sem3lr2, code_id 10673, admin terra1xsecn4snv94ezcez0z3vq8an9j4h4kxxcydp8l.
  • Query {"denom_wrappers":{}} fails (unknown variant) → bytecode is pre-wrap; migrate required before wrap works.
  • Config today: governance + timelock; swap_contract: null (swap era ended — keep it that way).

Downstream consumer: cl8y-dex-terraclassic already integrates treasury + wrap-mapper on LocalTerra (deploy-dex-local.sh Phase 1b, router SetWrapMapper, frontend wrapMapper.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

  1. Treasury-only custody for native backing — wrap-mapper never holds uluna/uusd.
  2. Do not deploy or recommend cmm-native-wrap from ust1-window.
  3. Do not re-enable USTC→USTR swap / SwapDeposit product path; leave swap_contract null.
  4. Instantiate wrap-mapper with fee_bps: 100 (1%), not LocalTerra’s historical 50 bps default.
  5. Migrate in-place to keep the same treasury address (UST1 window and bridge ops already point at terra16j5u6…).
  6. CW20 wrappers: mintable code 10184; wrap-mapper must be minter; decimals 6.
  7. Solvency invariant: treasury native balance ≥ outstanding wrapped supply (net of fees) at unwrap time (W1).
  8. Governance / pause / rate-limit controls must remain admin-gated (timelock where already designed).
  9. Update docs/DEPLOYMENT.md + docs/CONTRACTS.md with wrap-mapper addresses and migrate steps (docs currently stale).
  10. Coordinate with Phase 2: treasury continues to hold bridged vFDUSD for the UST1 window; wrap migrate must not break existing CW20 holdings/allowances.

Relevant files

  • contracts/contracts/treasury/src/contract.rs (migrate, wrap handlers)
  • contracts/contracts/treasury/src/msg.rs / state.rs
  • contracts/contracts/wrap-mapper/src/contract.rs / msg.rs / state.rs
  • plans/NATIVE_TOKEN_WRAPPING.md
  • docs/DEPLOYMENT.md, docs/CONTRACTS.md, docs/ARCHITECTURE.md (update for wrap)
  • Cross-repo reference (consumer): cl8y-dex-terraclassic/NATIVE_TOKEN_WRAPPING.md, scripts/deploy-dex-local.sh Phase 1b

  1. Build optimized treasury.wasm + wrap_mapper.wasm from current workspace (0.2.0 wrap API).
  2. Store new treasury code; migrate terra16j5u6… from 10673 → new code_id (admin terra1xsecn…).
  3. Verify post-migrate queries: config (includes wrapping_paused), denom_wrappers.
  4. Instantiate wrap-mapper { governance, treasury: terra16j5u6…, fee_bps: 100 }.
  5. Instantiate cLUNC and cUSTC (cw20-mintable); add_minter(wrap-mapper).
  6. wrap-mapper SetDenomMapping for uluna→cLUNC and uusd→cUSTC.
  7. Treasury SetDenomWrapper for both denoms → wrap-mapper.
  8. Confirm treasury native balances sufficient for planned unwrap liquidity; top up if needed.
  9. Document addresses; hand off to Phase 4 (router set_wrap_mapper, frontend env) and Phase 5 (ops).

Optional: set initial per-denom rate limits via SetRateLimit before public wrap.


Acceptance criteria

  • Treasury migrated; denom_wrappers / wrap queries succeed on mainnet address (same bech32).
  • wrap-mapper deployed; fee_bps == 100.
  • cLUNC and cUSTC live; wrap-mapper is minter; decimals 6.
  • Denom mappings + treasury wrappers configured for uluna and uusd.
  • Wrap uluna → cLUNC and unwrap cLUNC → uluna succeed (small mainnet smoke).
  • Wrap uusd → cUSTC and unwrap cUSTC → uusd succeed (small mainnet smoke).
  • Fee skim ≈ 1% on wrap and unwrap; residual native remains in treasury.
  • Pause (wrap-mapper and/or treasury wrapping) blocks wrap/unwrap; unauthorized callers rejected.
  • USTC→USTR swap remains disabled (swap_contract null / no new swap product).
  • Docs updated with code IDs, addresses, migrate + wire steps.
  • No cmm-native-wrap deployment.

Test plan (happy / functional paths)

  1. Contract tests: treasury wrap/migrate tests + wrap-mapper unit/integration (cargo test in contracts workspace).
  2. LocalTerra: clone/build as in cl8y-dex deploy-dex-local.sh Phase 1b but with fee_bps: 100; full wrap/unwrap matrix for both denoms.
  3. Migrate rehearsal: instantiate old-shape treasury if available, or multitest test_migrate_from_old_version; confirm state preserved.
  4. Mainnet post-migrate:
    • Query config + denom_wrappers.
    • Wrap small LUNC → cLUNC; unwrap back; check balances and fee.
    • Same for USTC / cUSTC.
  5. Governance: SetFeeBps (e.g. temporary change on LocalTerra), SetRateLimit, pause/unpause.
  6. Regression: existing treasury CW20 balances / whitelist queries still work; vFDUSD custody unaffected when Phase 2 deposits.

Test plan (attack / hack / abuse vectors)

Vector Expected
Unauthorized InstantWithdraw Rejected (wrapper-only)
Unauthorized SetDenomWrapper / SetDenomMapping / SetFeeBps Rejected
Unwrap more CW20 than treasury native Fail at InstantWithdraw (insolvency guard)
Wrap while wrapping_paused or wrap-mapper paused Rejected
Wrong denom / unmapped denom wrap Rejected
Fee > MAX_FEE_BPS (1000) or < MIN_FEE_BPS (1) Rejected
Rate-limit window exhaustion (Sybil many small wraps) Cap enforced per denom window
Direct Bank send to wrap-mapper (should not custody) No mint; native not accepted as wrap path
Migrate by non-admin Rejected
Re-point denom wrapper to attacker contract Governance-only; treat as critical ops control — dual-control / multisig
Drain via fee misconfiguration to 0 Min fee 1 bps prevents zero; still monitor tax erosion on unwrap sends

Verification criteria

  • LCD: treasury code_id ≠ 10673 (or documented new id); wrap queries succeed.
  • Mainnet smoke tx hashes for wrap+unwrap both denoms recorded.
  • Published address table: treasury (unchanged), wrap-mapper, cLUNC, cUSTC, fee_bps=100.
  • Phase 4 unblocked for router/NATIVE_WRAPPED_PAIRS wiring.
  • Docs drift fixed (DEPLOYMENT.md / CONTRACTS.md mention wrap).
  • Phase 2: ust1-window UST1 ↔ vFDUSD deploy
  • Phase 4: cl8y-dex wrap + /ust1 UI + pairs
  • Phase 5: ops (pause playbooks, inventory monitoring)
## 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`’s `cmm-native-wrap`. **Phase 0 decisions (approved):** - Wrap path = **this repo’s treasury + wrap-mapper** only. - Skip `cmm-native-wrap` (ust1-window). - No active ust1/ustr/ustc swap window; treasury is used for wrap backing (+ later vFDUSD custody for UST1 window). - Wrap/unwrap fee: **1% (`fee_bps=100`)**, governance-updatable (max 1000 bps / min 1 bps in contract). - **Phase 1 prerequisites confirmed** (treasury admin can migrate code `10673`). --- ## Current codebase | Component | Path | Role | |-----------|------|------| | Treasury (wrap msgs) | `contracts/contracts/treasury/` | `WrapDeposit`, `InstantWithdraw`, `SetDenomWrapper`, `SetWrappingPaused`; migrate entrypoint | | wrap-mapper | `contracts/contracts/wrap-mapper/` | Mint/burn CW20; fees; rate limits; never holds native | | Design | `plans/NATIVE_TOKEN_WRAPPING.md` | Authoritative wrap architecture + test matrix | | Mainnet docs (stale on wrap) | `docs/DEPLOYMENT.md`, `docs/CONTRACTS.md` | List treasury code **10673** / address `terra16j5u6…` but **do not** document wrap-mapper mainnet | **Live mainnet (verified via LCD):** - Treasury `terra16j5u6ey7a84g40sr3gd94nzg5w5fm45046k9s2347qhfpwm5fr6sem3lr2`, code_id **10673**, admin `terra1xsecn4snv94ezcez0z3vq8an9j4h4kxxcydp8l`. - Query `{"denom_wrappers":{}}` **fails** (`unknown variant`) → bytecode is **pre-wrap**; migrate required before wrap works. - Config today: governance + timelock; `swap_contract: null` (swap era ended — keep it that way). **Downstream consumer:** `cl8y-dex-terraclassic` already integrates treasury + wrap-mapper on LocalTerra (`deploy-dex-local.sh` Phase 1b, router `SetWrapMapper`, frontend `wrapMapper.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 1. **Treasury-only custody** for native backing — wrap-mapper never holds `uluna`/`uusd`. 2. **Do not** deploy or recommend `cmm-native-wrap` from ust1-window. 3. **Do not** re-enable USTC→USTR swap / `SwapDeposit` product path; leave `swap_contract` null. 4. Instantiate wrap-mapper with **`fee_bps: 100`** (1%), not LocalTerra’s historical 50 bps default. 5. Migrate in-place to keep the same treasury address (UST1 window and bridge ops already point at `terra16j5u6…`). 6. CW20 wrappers: mintable code **10184**; wrap-mapper must be minter; decimals **6**. 7. Solvency invariant: treasury native balance ≥ outstanding wrapped supply (net of fees) at unwrap time (W1). 8. Governance / pause / rate-limit controls must remain admin-gated (timelock where already designed). 9. Update `docs/DEPLOYMENT.md` + `docs/CONTRACTS.md` with wrap-mapper addresses and migrate steps (docs currently stale). 10. Coordinate with Phase 2: treasury continues to hold bridged **vFDUSD** for the UST1 window; wrap migrate must not break existing CW20 holdings/allowances. --- ## Relevant files - `contracts/contracts/treasury/src/contract.rs` (migrate, wrap handlers) - `contracts/contracts/treasury/src/msg.rs` / `state.rs` - `contracts/contracts/wrap-mapper/src/contract.rs` / `msg.rs` / `state.rs` - `plans/NATIVE_TOKEN_WRAPPING.md` - `docs/DEPLOYMENT.md`, `docs/CONTRACTS.md`, `docs/ARCHITECTURE.md` (update for wrap) - Cross-repo reference (consumer): `cl8y-dex-terraclassic/NATIVE_TOKEN_WRAPPING.md`, `scripts/deploy-dex-local.sh` Phase 1b --- ## Recommended direction 1. Build optimized `treasury.wasm` + `wrap_mapper.wasm` from current workspace (`0.2.0` wrap API). 2. Store new treasury code; **migrate** `terra16j5u6…` from 10673 → new code_id (admin `terra1xsecn…`). 3. Verify post-migrate queries: `config` (includes `wrapping_paused`), `denom_wrappers`. 4. Instantiate wrap-mapper `{ governance, treasury: terra16j5u6…, fee_bps: 100 }`. 5. Instantiate **cLUNC** and **cUSTC** (cw20-mintable); `add_minter(wrap-mapper)`. 6. wrap-mapper `SetDenomMapping` for `uluna`→cLUNC and `uusd`→cUSTC. 7. Treasury `SetDenomWrapper` for both denoms → wrap-mapper. 8. Confirm treasury native balances sufficient for planned unwrap liquidity; top up if needed. 9. Document addresses; hand off to Phase 4 (router `set_wrap_mapper`, frontend env) and Phase 5 (ops). Optional: set initial per-denom rate limits via `SetRateLimit` before public wrap. --- ## Acceptance criteria - [ ] Treasury migrated; `denom_wrappers` / wrap queries succeed on mainnet address (same bech32). - [ ] wrap-mapper deployed; `fee_bps == 100`. - [ ] cLUNC and cUSTC live; wrap-mapper is minter; decimals 6. - [ ] Denom mappings + treasury wrappers configured for `uluna` and `uusd`. - [ ] Wrap `uluna` → cLUNC and unwrap cLUNC → `uluna` succeed (small mainnet smoke). - [ ] Wrap `uusd` → cUSTC and unwrap cUSTC → `uusd` succeed (small mainnet smoke). - [ ] Fee skim ≈ 1% on wrap and unwrap; residual native remains in treasury. - [ ] Pause (wrap-mapper and/or treasury wrapping) blocks wrap/unwrap; unauthorized callers rejected. - [ ] USTC→USTR swap remains disabled (`swap_contract` null / no new swap product). - [ ] Docs updated with code IDs, addresses, migrate + wire steps. - [ ] No `cmm-native-wrap` deployment. --- ## Test plan (happy / functional paths) 1. **Contract tests:** treasury wrap/migrate tests + wrap-mapper unit/integration (`cargo test` in contracts workspace). 2. **LocalTerra:** clone/build as in cl8y-dex `deploy-dex-local.sh` Phase 1b but with `fee_bps: 100`; full wrap/unwrap matrix for both denoms. 3. **Migrate rehearsal:** instantiate old-shape treasury if available, or multitest `test_migrate_from_old_version`; confirm state preserved. 4. **Mainnet post-migrate:** - Query config + denom_wrappers. - Wrap small LUNC → cLUNC; unwrap back; check balances and fee. - Same for USTC / cUSTC. 5. **Governance:** `SetFeeBps` (e.g. temporary change on LocalTerra), `SetRateLimit`, pause/unpause. 6. **Regression:** existing treasury CW20 balances / whitelist queries still work; vFDUSD custody unaffected when Phase 2 deposits. --- ## Test plan (attack / hack / abuse vectors) | Vector | Expected | |--------|----------| | Unauthorized `InstantWithdraw` | Rejected (wrapper-only) | | Unauthorized `SetDenomWrapper` / `SetDenomMapping` / `SetFeeBps` | Rejected | | Unwrap more CW20 than treasury native | Fail at `InstantWithdraw` (insolvency guard) | | Wrap while `wrapping_paused` or wrap-mapper `paused` | Rejected | | Wrong denom / unmapped denom wrap | Rejected | | Fee > `MAX_FEE_BPS` (1000) or < `MIN_FEE_BPS` (1) | Rejected | | Rate-limit window exhaustion (Sybil many small wraps) | Cap enforced per denom window | | Direct Bank send to wrap-mapper (should not custody) | No mint; native not accepted as wrap path | | Migrate by non-admin | Rejected | | Re-point denom wrapper to attacker contract | Governance-only; treat as critical ops control — dual-control / multisig | | Drain via fee misconfiguration to 0 | Min fee 1 bps prevents zero; still monitor tax erosion on unwrap sends | --- ## Verification criteria - [ ] LCD: treasury code_id ≠ 10673 (or documented new id); wrap queries succeed. - [ ] Mainnet smoke tx hashes for wrap+unwrap both denoms recorded. - [ ] Published address table: treasury (unchanged), wrap-mapper, cLUNC, cUSTC, fee_bps=100. - [ ] Phase 4 unblocked for router/`NATIVE_WRAPPED_PAIRS` wiring. - [ ] Docs drift fixed (`DEPLOYMENT.md` / `CONTRACTS.md` mention wrap). ### Related - Phase 2: ust1-window UST1 ↔ vFDUSD deploy - Phase 4: cl8y-dex wrap + `/ust1` UI + pairs - Phase 5: ops (pause playbooks, inventory monitoring)
PlasticDigits commented 2026-07-29 02:08:00 +00:00 (Migrated from gitlab.com)

Cross-repo tracking (Phase 0 approved)

Phase Repo Issue
2 — UST1↔vFDUSD window deploy ust1-window https://gitlab.com/PlasticDigits/ust1-window/-/work_items/19
3 — Treasury migrate + wrap-mapper ustr-cmm https://gitlab.com/PlasticDigits2/ustr-cmm/-/work_items/5
4 — /ust1 UI + wraps + secondary AMM cl8y-dex-terraclassic https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/502
5 — Ops hardening cl8y-dex-terraclassic https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/503

Approved params: window fee_bps=100, per-tx 1000 UST1, 24h 10000 UST1; wrap fee_bps=100 (1%). UI at dex.cl8y.com/ust1. Skip cmm-native-wrap. Phase 1 prerequisites confirmed.

## Cross-repo tracking (Phase 0 approved) | Phase | Repo | Issue | |-------|------|-------| | 2 — UST1↔vFDUSD window deploy | ust1-window | https://gitlab.com/PlasticDigits/ust1-window/-/work_items/19 | | 3 — Treasury migrate + wrap-mapper | ustr-cmm | https://gitlab.com/PlasticDigits2/ustr-cmm/-/work_items/5 | | 4 — `/ust1` UI + wraps + secondary AMM | cl8y-dex-terraclassic | https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/502 | | 5 — Ops hardening | cl8y-dex-terraclassic | https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/503 | **Approved params:** window `fee_bps=100`, per-tx **1000** UST1, 24h **10000** UST1; wrap `fee_bps=100` (1%). UI at `dex.cl8y.com/ust1`. Skip `cmm-native-wrap`. Phase 1 prerequisites confirmed.
PlasticDigits commented 2026-07-29 02:08:03 +00:00 (Migrated from gitlab.com)
mentioned in issue PlasticDigits/cl8y-dex-terraclassic#502
PlasticDigits commented 2026-07-29 02:08:05 +00:00 (Migrated from gitlab.com)
mentioned in issue PlasticDigits/cl8y-dex-terraclassic#503
PlasticDigits commented 2026-07-29 05:20:59 +00:00 (Migrated from gitlab.com)

changed title from feat: Phase 3 — treasury migrate + wrap-mapper (LUNC-C/USTC-C, 1% fee) to feat: Phase 3 — treasury migrate + wrap-mapper (cLUNC/cUSTC, 1% fee)

<p>changed title from <code class="idiff">feat: Phase 3 — treasury migrate + wrap-mapper (LUNC<span class="idiff left deletion">-C</span>/USTC<span class="idiff right deletion">-C</span>, 1% fee)</code> to <code class="idiff">feat: Phase 3 — treasury migrate + wrap-mapper (<span class="idiff left addition">c</span>LUNC/<span class="idiff right addition">c</span>USTC, 1% fee)</code></p>
PlasticDigits commented 2026-07-29 05:21:02 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
PlasticDigits commented 2026-07-29 05:21:12 +00:00 (Migrated from gitlab.com)

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.

## 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.
PlasticDigits commented 2026-07-30 08:38:59 +00:00 (Migrated from gitlab.com)

mentioned in issue #6

mentioned in issue #6
PlasticDigits commented 2026-07-30 08:39:38 +00:00 (Migrated from gitlab.com)

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).

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`).
PlasticDigits commented 2026-07-31 02:34:08 +00:00 (Migrated from gitlab.com)

mentioned in merge request !27

mentioned in merge request !27
PlasticDigits commented 2026-07-31 03:21:15 +00:00 (Migrated from gitlab.com)

Bundled treasury upgrade (MR !27 + !28 + Phase 3 wrap)

Both CW20 InstantWithdraw pieces are already on master and should ride the same in-place treasury migrate as this Phase 3 wrap work:

MR Issue What lands in treasury migrate
!27 #6 InstantWithdrawCw20 + spender registry + cw20_iw_paused
!28 #7 fail-closed 24h pull limits per (token, spender)
this issue #5 wrap msgs already present; migrate enables them on live code 10673

Build from current workspace 0.2.1 (not the issue’s older 0.2.0 note). One store + one migrate of terra16j5u6… — do not migrate twice.

A. One-shot treasury migrate

  1. Build optimized treasury.wasm + wrap_mapper.wasm from master (0.2.1).
  2. Store treasury code → migrate terra16j5u6… (10673 → new code_id) as admin terra1xsecn….
  3. Verify queries (must all succeed):
    • config → wrapping_paused, cw20_instant_withdraw_paused, swap_contract: null
    • denom_wrappers, cw20_spenders
    • cw20_spender_limit (pair query OK even if empty)

B. Phase 3 wrap wiring (this issue)

  1. Instantiate wrap-mapper { governance, treasury: terra16j5u6…, fee_bps: 100 }.
  2. Instantiate cLUNC / cUSTC (cw20-mintable code 10184, decimals 6); add_minter(wrap-mapper).
  3. wrap-mapper SetDenomMapping: uluna→cLUNC, uusd→cUSTC.
  4. Treasury SetDenomWrapper for both denoms → wrap-mapper.
  5. Optional: wrap-mapper SetRateLimit per denom before public wrap.
  6. Small mainnet wrap/unwrap smoke both denoms; confirm ~1% fee; leave swap_contract null.

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.

  1. After ust1-window#20 is live:
    SetCw20Spender { token: vFDUSD, spender: WINDOW, limit_24h: "<quota>" }
    (align quota with window 24h inventory, e.g. ~10_000 UST1-side policy).
  2. Query cw20_spender_limit; then small redeem smoke.
  3. Pause playbooks: set_wrapping_paused ≠ CW20 pulls; use set_cw20_instant_withdraw_paused for window IR. Neither stops gov ExecuteWithdraw.

Do not

  • Deploy cmm-native-wrap / re-enable USTC→USTR swap.
  • Gate CW20 pulls on wrapping_paused.
  • Enable window redeem before step 10 (limit required).

Ops detail: docs/DEPLOYMENT.md § Treasury Migrate + CW20 Spender Wiring; agent playbook: skills/treasury-cw20-instant-withdraw.

## Bundled treasury upgrade (MR !27 + !28 + Phase 3 wrap) Both CW20 InstantWithdraw pieces are already on `master` and should ride the **same** in-place treasury migrate as this Phase 3 wrap work: | MR | Issue | What lands in treasury migrate | |----|-------|--------------------------------| | [!27](https://gitlab.com/PlasticDigits2/ustr-cmm/-/merge_requests/5) | #6 | `InstantWithdrawCw20` + spender registry + `cw20_iw_paused` | | [!28](https://gitlab.com/PlasticDigits2/ustr-cmm/-/merge_requests/6) | #7 | fail-closed 24h pull limits per `(token, spender)` | | this issue | #5 | wrap msgs already present; migrate enables them on live code `10673` | Build from current workspace **`0.2.1`** (not the issue’s older `0.2.0` note). One store + one migrate of `terra16j5u6…` — do **not** migrate twice. ### A. One-shot treasury migrate 1. Build optimized `treasury.wasm` + `wrap_mapper.wasm` from `master` (`0.2.1`). 2. Store treasury code → migrate `terra16j5u6…` (`10673` → new code_id) as admin `terra1xsecn…`. 3. Verify queries (must all succeed): - `config` → `wrapping_paused`, `cw20_instant_withdraw_paused`, `swap_contract: null` - `denom_wrappers`, `cw20_spenders` - `cw20_spender_limit` (pair query OK even if empty) ### B. Phase 3 wrap wiring (this issue) 4. Instantiate wrap-mapper `{ governance, treasury: terra16j5u6…, fee_bps: 100 }`. 5. Instantiate cLUNC / cUSTC (cw20-mintable code `10184`, decimals 6); `add_minter(wrap-mapper)`. 6. wrap-mapper `SetDenomMapping`: `uluna`→cLUNC, `uusd`→cUSTC. 7. Treasury `SetDenomWrapper` for both denoms → wrap-mapper. 8. Optional: wrap-mapper `SetRateLimit` per denom before public wrap. 9. Small mainnet wrap/unwrap smoke both denoms; confirm ~1% fee; leave `swap_contract` null. ### 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`. 10. After [ust1-window#20](https://gitlab.com/PlasticDigits/ust1-window/-/work_items/20) is live: `SetCw20Spender { token: vFDUSD, spender: WINDOW, limit_24h: "<quota>" }` (align quota with window 24h inventory, e.g. ~10_000 UST1-side policy). 11. Query `cw20_spender_limit`; then small redeem smoke. 12. Pause playbooks: `set_wrapping_paused` ≠ CW20 pulls; use `set_cw20_instant_withdraw_paused` for window IR. Neither stops gov `ExecuteWithdraw`. ### Do not - Deploy `cmm-native-wrap` / re-enable USTC→USTR swap. - Gate CW20 pulls on `wrapping_paused`. - Enable window redeem before step 10 (limit required). Ops detail: [docs/DEPLOYMENT.md](https://gitlab.com/PlasticDigits2/ustr-cmm/-/blob/master/docs/DEPLOYMENT.md) § Treasury Migrate + CW20 Spender Wiring; agent playbook: [skills/treasury-cw20-instant-withdraw](https://gitlab.com/PlasticDigits2/ustr-cmm/-/blob/master/skills/treasury-cw20-instant-withdraw/SKILL.md).
PlasticDigits commented 2026-08-05 00:10:06 +00:00 (Migrated from gitlab.com)

mentioned in issue #8

mentioned in issue #8
PlasticDigits commented 2026-08-05 00:10:07 +00:00 (Migrated from gitlab.com)

marked as related to #8

marked as related to #8
PlasticDigits commented 2026-08-05 00:10:11 +00:00 (Migrated from gitlab.com)

Bundle: remove obsolete SwapDeposit / swap_contract integration in the same treasury migrate as this issue — see #8 (audit MB-1; full removal, not restore NotifyDeposit on ustc-swap).

**Bundle:** remove obsolete `SwapDeposit` / `swap_contract` integration in the same treasury migrate as this issue — see [#8](https://gitlab.com/PlasticDigits2/ustr-cmm/-/issues/8) (audit MB-1; full removal, not restore NotifyDeposit on ustc-swap).
PlasticDigits commented 2026-08-05 01:44:44 +00:00 (Migrated from gitlab.com)

mentioned in commit b2fe58e020

mentioned in commit b2fe58e020cbcad6c8dc50025af7e28ec2ea8c4d
PlasticDigits commented 2026-08-05 01:45:01 +00:00 (Migrated from gitlab.com)

mentioned in merge request !29

mentioned in merge request !29
PlasticDigits commented 2026-08-05 01:45:28 +00:00 (Migrated from gitlab.com)

mentioned in merge request !30

mentioned in merge request !30
PlasticDigits commented 2026-08-08 00:07:56 +00:00 (Migrated from gitlab.com)

Mainnet deploy complete (A + B + C) — 2026-08-08

One-shot via contracts/scripts/treasury-migrate-wrap-wire.sh as cl8y2_admin (terra1xsecn4snv94ezcez0z3vq8an9j4h4kxxcydp8l). Docs updated: README.md, docs/DEPLOYMENT.md, docs/CONTRACTS.md.

A — Treasury migrate

Address (unchanged) terra16j5u6ey7a84g40sr3gd94nzg5w5fm45046k9s2347qhfpwm5fr6sem3lr2
Code 10673 → 11564
Store tx 380BA17B60B191ACFB786D086F72BDCB04243F97249A5F1F225F97E41DA656F9
Migrate tx 65E36AF139E87FEE2271AD5C8FE58F9CE095B237D1549C8B2FEDB1CF0E14EE20
Store gas (est) ~3,303,247 → ~140 LUNC @ 28.325 × 1.5
Migrate gas (est) ~182,411

Post-migrate config: wrapping_paused=false, cw20_instant_withdraw_paused=false, no swap_contract field (#8 strip). Queries denom_wrappers / cw20_spenders / cw20_spender_limit succeed.

B — Wrap wiring

Contract Code ID Address
wrap-mapper 11565 terra1xuuuhpmyd5t29ry7mydg7ra2q2phrwhx7j28nx7x9sjw6zznkumsz0nmd2
cLUNC 10184 terra1437qslye72t7qmmahn4t5chz50r8a62g45phwkquwpyu2l62u6ksqssgdg
cUSTC 10184 terra1nap4dxh9tv35v0ynd9m4k6zt6c0dq6weszc4j5m564kjls56hu7qcr56ch
Check Result
fee_bps 100
wrap-mapper minter on cLUNC/cUSTC yes
SetDenomMapping uluna→cLUNC, uusd→cUSTC yes
treasury SetDenomWrapper both denoms → wrap-mapper yes
Store wrap_mapper tx B3C2597B25FC7C85D1147473B5011281013AAB80694F56BECB5EEE8F93D23164
Instantiate wrap-mapper tx A5E4D3024FF6AD86702AAD29A3CD9ABCD5E933B9B8A82E58522B6BC87C826799

C — CW20 InstantWithdraw spender (#6 / #7)

token (vFDUSD) terra1mnl9azefrqpmu888ar2u6zrcwr80hxlt3avf4300r576cw5ar7esvxsvj3
spender (ust1-window) terra1zxwpzpzpleatqn39r00grau4yt29sld8pw78s7ktvjafnj5nsaxq0h3rh2
limit_24h 10000000000 (10_000 @ 6 decimals), remaining full
tx 91BF752B8AFB08438D69C4827E94C506580DC0A211D9D2F19BA754F47366D630

Gas note

DEPLOYMENT.md fixed --fees 100000000uluna is insufficient for wasm store. Ops used --gas auto --gas-prices 28.325uluna (store adj 1.5).

Remaining (not blocking migrate/wire)

  • Small mainnet wrap/unwrap smoke (both denoms, ~1% fee)
  • Window redeem smoke
  • Phase 4 frontend / router set_wrap_mapper + env
  • Optional per-denom SetRateLimit before public wrap

Artifact: contracts/scripts/treasury-migrate-wrap-20260808-090524.json

Do not deploy cmm-native-wrap; USTC→USTR swap remains disabled.

## Mainnet deploy complete (A + B + C) — 2026-08-08 One-shot via `contracts/scripts/treasury-migrate-wrap-wire.sh` as `cl8y2_admin` (`terra1xsecn4snv94ezcez0z3vq8an9j4h4kxxcydp8l`). Docs updated: `README.md`, `docs/DEPLOYMENT.md`, `docs/CONTRACTS.md`. ### A — Treasury migrate | | | |--|--| | Address (unchanged) | `terra16j5u6ey7a84g40sr3gd94nzg5w5fm45046k9s2347qhfpwm5fr6sem3lr2` | | Code | `10673` → **`11564`** | | Store tx | `380BA17B60B191ACFB786D086F72BDCB04243F97249A5F1F225F97E41DA656F9` | | Migrate tx | `65E36AF139E87FEE2271AD5C8FE58F9CE095B237D1549C8B2FEDB1CF0E14EE20` | | Store gas (est) | ~3,303,247 → ~140 LUNC @ 28.325 × 1.5 | | Migrate gas (est) | ~182,411 | Post-migrate `config`: `wrapping_paused=false`, `cw20_instant_withdraw_paused=false`, **no `swap_contract` field** (#8 strip). Queries `denom_wrappers` / `cw20_spenders` / `cw20_spender_limit` succeed. ### B — Wrap wiring | Contract | Code ID | Address | |--|--|--| | wrap-mapper | **11565** | `terra1xuuuhpmyd5t29ry7mydg7ra2q2phrwhx7j28nx7x9sjw6zznkumsz0nmd2` | | cLUNC | 10184 | `terra1437qslye72t7qmmahn4t5chz50r8a62g45phwkquwpyu2l62u6ksqssgdg` | | cUSTC | 10184 | `terra1nap4dxh9tv35v0ynd9m4k6zt6c0dq6weszc4j5m564kjls56hu7qcr56ch` | | Check | Result | |--|--| | `fee_bps` | **100** | | wrap-mapper minter on cLUNC/cUSTC | yes | | `SetDenomMapping` uluna→cLUNC, uusd→cUSTC | yes | | treasury `SetDenomWrapper` both denoms → wrap-mapper | yes | | Store wrap_mapper tx | `B3C2597B25FC7C85D1147473B5011281013AAB80694F56BECB5EEE8F93D23164` | | Instantiate wrap-mapper tx | `A5E4D3024FF6AD86702AAD29A3CD9ABCD5E933B9B8A82E58522B6BC87C826799` | ### C — CW20 InstantWithdraw spender (#6 / #7) | | | |--|--| | token (vFDUSD) | `terra1mnl9azefrqpmu888ar2u6zrcwr80hxlt3avf4300r576cw5ar7esvxsvj3` | | spender (ust1-window) | `terra1zxwpzpzpleatqn39r00grau4yt29sld8pw78s7ktvjafnj5nsaxq0h3rh2` | | `limit_24h` | **`10000000000`** (10_000 @ 6 decimals), remaining full | | tx | `91BF752B8AFB08438D69C4827E94C506580DC0A211D9D2F19BA754F47366D630` | ### Gas note `DEPLOYMENT.md` fixed `--fees 100000000uluna` is insufficient for wasm store. Ops used `--gas auto --gas-prices 28.325uluna` (store adj 1.5). ### Remaining (not blocking migrate/wire) - [ ] Small mainnet wrap/unwrap smoke (both denoms, ~1% fee) - [ ] Window redeem smoke - [ ] Phase 4 frontend / router `set_wrap_mapper` + env - [ ] Optional per-denom `SetRateLimit` before public wrap Artifact: `contracts/scripts/treasury-migrate-wrap-20260808-090524.json` **Do not** deploy `cmm-native-wrap`; USTC→USTR swap remains disabled.
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-08-08 00:28:56 +00:00
PlasticDigits commented 2026-08-08 00:28:57 +00:00 (Migrated from gitlab.com)

config complete, closing

config complete, closing
PlasticDigits commented 2026-08-08 11:26:46 +00:00 (Migrated from gitlab.com)
mentioned in issue PlasticDigits/cl8y-dex-terraclassic#507
PlasticDigits commented 2026-08-08 11:26:48 +00:00 (Migrated from gitlab.com)
mentioned in issue PlasticDigits/cl8y-dex-terraclassic#508
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/ustr-cmm#5
No description provided.