feat(treasury): CW20 InstantWithdraw + spender registry (#6) #27

Merged
PlasticDigits merged 1 commit from feat/cw20-instant-withdraw-spender-registry into master 2026-07-31 02:34:18 +00:00
PlasticDigits commented 2026-07-31 02:33:24 +00:00 (Migrated from gitlab.com)

Summary

Implements #6: governance-registered CW20 InstantWithdraw path so ust1-window can redeem UST1→vFDUSD without CW20 allowances or wrap-mapper ABI changes.

  • Parallel msgs: SetCw20Spender / RemoveCw20Spender / SetCw20InstantWithdrawPaused / InstantWithdrawCw20 + query Cw20Spenders
  • Storage: cw20_spenders + cw20_iw_paused (distinct from denom_wrappers / cw20_whitelist)
  • Pause isolation: wrapping_paused does not block CW20 pulls
  • Docs + ./skills/treasury-cw20-instant-withdraw for agents; cross-links to ust1-window#20 / #19
  • Husky pre-commit fixed to cd frontend (active core.hooksPath)

Acceptance criteria (#6)

  • New msgs compile; schema-ready (#[cw_serde]); docs updated
  • Existing native wrap InstantWithdraw / SetDenomWrapper behavior unchanged (tests + wrap-mapper integration green)
  • Gov can register/remove CW20 spender; non-gov cannot
  • Registered spender InstantWithdrawCw20 → CW20 Transfer emitted; balance check enforced
  • Unregistered / wrong-token spender fails clearly
  • CW20 pull pause blocks InstantWithdrawCw20; does not require wrapping_paused=false
  • wrapping_paused=true does not block InstantWithdrawCw20
  • Insufficient CW20 balance fails without partial transfer
  • Zero amount rejected
  • ProposeWithdraw / ExecuteWithdraw CW20 path unaffected
  • Migrate smoke preserves gov / whitelist / pending withdraw / denom wrappers; new queries available
  • Docs: register → window redeem + pause semantics
  • Cross-link companion ust1-window issue; note mainnet SetCw20Spender post-deploy step

Not in this MR / follow-ups

  • On-chain per-spender/token pull cap (optional v1; documented as window-side only)
  • Mainnet store + migrate + SetCw20Spender (ops after window ready)
  • ust1-window consumer changes (#20)
  • LocalTerra / rebel live smoke
  • Formal security sign-off on A1–A12 (unit coverage added; human review still needed for A4/A12 process risk)

Test plan

  • cargo test --package treasury --lib (134 passed)
  • cargo test --package wrap-mapper --lib + integration InstantWithdraw regression
  • After merge: mainnet migrate; query cw20_spenders / config
  • After window deploy: SetCw20Spender { token: vFDUSD, spender: window }; small redeem smoke
## Summary Implements [#6](https://gitlab.com/PlasticDigits2/ustr-cmm/-/issues/6): governance-registered **CW20 InstantWithdraw** path so `ust1-window` can redeem UST1→vFDUSD without CW20 allowances or wrap-mapper ABI changes. - Parallel msgs: `SetCw20Spender` / `RemoveCw20Spender` / `SetCw20InstantWithdrawPaused` / `InstantWithdrawCw20` + query `Cw20Spenders` - Storage: `cw20_spenders` + `cw20_iw_paused` (distinct from `denom_wrappers` / `cw20_whitelist`) - Pause isolation: `wrapping_paused` does **not** block CW20 pulls - Docs + `./skills/treasury-cw20-instant-withdraw` for agents; cross-links to [ust1-window#20](https://gitlab.com/PlasticDigits/ust1-window/-/work_items/20) / [#19](https://gitlab.com/PlasticDigits/ust1-window/-/issues/19) - Husky pre-commit fixed to `cd frontend` (active `core.hooksPath`) ## Acceptance criteria (#6) - [x] New msgs compile; schema-ready (`#[cw_serde]`); docs updated - [x] Existing native wrap InstantWithdraw / SetDenomWrapper behavior unchanged (tests + wrap-mapper integration green) - [x] Gov can register/remove CW20 spender; non-gov cannot - [x] Registered spender InstantWithdrawCw20 → CW20 Transfer emitted; balance check enforced - [x] Unregistered / wrong-token spender fails clearly - [x] CW20 pull pause blocks InstantWithdrawCw20; does not require wrapping_paused=false - [x] wrapping_paused=true does **not** block InstantWithdrawCw20 - [x] Insufficient CW20 balance fails without partial transfer - [x] Zero amount rejected - [x] ProposeWithdraw / ExecuteWithdraw CW20 path unaffected - [x] Migrate smoke preserves gov / whitelist / pending withdraw / denom wrappers; new queries available - [x] Docs: register → window redeem + pause semantics - [x] Cross-link companion ust1-window issue; note mainnet SetCw20Spender post-deploy step ## Not in this MR / follow-ups - [ ] On-chain per-spender/token pull cap (optional v1; documented as window-side only) - [ ] Mainnet store + migrate + `SetCw20Spender` (ops after window ready) - [ ] ust1-window consumer changes ([#20](https://gitlab.com/PlasticDigits/ust1-window/-/work_items/20)) - [ ] LocalTerra / rebel live smoke - [ ] Formal security sign-off on A1–A12 (unit coverage added; human review still needed for A4/A12 process risk) ## Test plan - [x] `cargo test --package treasury --lib` (134 passed) - [x] `cargo test --package wrap-mapper --lib` + integration InstantWithdraw regression - [ ] After merge: mainnet migrate; query `cw20_spenders` / `config` - [ ] After window deploy: `SetCw20Spender { token: vFDUSD, spender: window }`; small redeem smoke ## Related - Closes #6 (treasury half) - Companion: PlasticDigits/ust1-window#20 - Coord migrate with #5 if timing aligns
PlasticDigits commented 2026-07-31 02:33:38 +00:00 (Migrated from gitlab.com)

restored source branch feat/cw20-instant-withdraw-spender-registry

restored source branch `feat/cw20-instant-withdraw-spender-registry`
PlasticDigits commented 2026-07-31 02:34:18 +00:00 (Migrated from gitlab.com)

mentioned in commit b0b07e4ca2

mentioned in commit b0b07e4ca20210de3b2f2f994446bd7637350d9b
PlasticDigits (Migrated from gitlab.com) merged commit b0b07e4ca2 into master 2026-07-31 02:34:18 +00:00
PlasticDigits commented 2026-07-31 02:43:59 +00:00 (Migrated from gitlab.com)

mentioned in commit 2738a8696f

mentioned in commit 2738a8696fa1cbabb9b9f9468949fae683cb5062
PlasticDigits commented 2026-07-31 02:44:32 +00:00 (Migrated from gitlab.com)

mentioned in issue #7

mentioned in issue #7
PlasticDigits commented 2026-07-31 03:21:16 +00:00 (Migrated from gitlab.com)

mentioned in issue #5

mentioned in issue #5
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/ustr-cmm!27
No description provided.