design: community CW20 migrate onto 11611 tax template (risks + strategies) #603

Closed
opened 2026-08-23 06:30:40 +00:00 by PlasticDigits · 30 comments
PlasticDigits commented 2026-08-23 06:30:40 +00:00 (Migrated from gitlab.com)

Community tax template #592 / store+list #601 / Create Token #593 / #602. F6 pin #582. ALPHA venues #558 (note: in-place 8654→11611 is not live).

This ticket is investigation + design (risks, options, guardrails). Do not ship a migrate importer until this issue records a go/no-go per source template. Implementation is a follow-up if a strategy is accepted.


Current codebase

cl8y-community-tax-token (columbus-5 11611, factory-listed) is a cw20-base fork plus tax config. Create is launcher-only for attested tokens:

  • Launcher 11614 terra126pr5… instantiates with admin: cmm_governance (T592-5). Manager cannot migrate or UpdateAdmin.
  • Free create is ExecuteMsg::CreateToken (0 SKU). Paid SKUs are UST1 Send + hook.
  • MigrateMsg {} only runs cw2::ensure_from_older_version(…, "crates.io:cl8y-community-tax-token", version). Same-crate bumps only. Foreign cw2 names revert.
  • Storage: cw20-base BALANCES / TOKEN_INFO plus CONFIG, FEATURES, LISTED_PAIRS, PROTOCOL_EXEMPT, MANAGER_EXEMPT, SINKS, LAUNCH_GUARDS, GetLauncherOrigin.
  • Tax model (T592): inbound to pair/router/escrow/AutoLP is 1:1. Sell is extra-debit on Send+Swap to a RegisterListedPair pair. Buy is outbound split from a listed pair. Not a tax_map / inbound FoT template.
  • Factory F6: pair pins ContractInfo.code_id at CreatePair and re-checks whitelist on writes. After a successful migrate to 11611, listed pairs on the old id fail closed until RefreshPairAssetCodeIds (11611 is already whitelisted).

ALPHA (motivating case, #558):

Field Live
Address terra1x6e64es6yhauhvs3prvpdg2gkqdtfru840wgnhs935x8axr7zxkqzysuxz
code_id 8654 cw20_taxed
Wasm + tax admin terra1ljqgc0cdkl7gcc7s64eczv3hrgga32vfh8xvfj (not CMM / not DEX 2-of-3)
Tax on_send Always 1%; Terraport dest 8260/8214 0%; transfer-out of those codes 4.5%; transfer_from never; proceeds terra1w37akazc…
Supply ~1.328B @ 6 dp; minter null

8654 is a known-bad harness control. Do not whitelist it. In-place migrate to 11611 reverts today.

Communities on 10184 / 6036 / 8266 (honest cw20-base / Terraport token) have the same gap: they can only new-instantiate 11611 (new address, empty balances) or stay on the old template.


Why this is needed

Communities want to keep the same CW20 address and holder set while moving onto the listed tax template (DEX-safe extra-debit / outbound split, Create Token / catalog, factory pairs). Today the only safe product path is a new 11611 token + liquidity move (or a 10184 wrap). That splits holders, tickers, and Terraport vs CL8Y venues.

ALPHA is the first ask (#558 note). Others on 10184/8266 will ask the same. We need a written strategy: refuse in-place, allowlisted importer, or wrap-only — before anyone signs MsgMigrateContract at the live ALPHA address.


Constraints / guardrails

  1. H-01 — do not add pair/router FoT balance-delta math. Migrated tokens must keep inbound 1:1 (T592-1).
  2. Do not whitelist 8654 (or any tax_map / inbound FoT template). Listing 11611 is enough for new or migrated-to-11611 addresses.
  3. T592-5 — after adopt, wasm admin must be CMM (terra16j5u6…). Source admin becomes manager only. UpdateAdmin in the same migrate tx (or immediately after) is required if we allow in-place.
  4. O601-4 — catalog / dApp must not promote a migrate that lacks GetLauncherOrigin + CMM admin unless this issue explicitly defines an attested-migrate origin.
  5. F6 — post-migrate, every factory pair that had the old code_id pin must Refresh or stay frozen. Document the ops order.
  6. cw2 — do not skip ensure_from_older_version for same-crate upgrades. A foreign importer is a new migrate branch with an explicit allowlist, not a silent cw2 bypass.
  7. No supply mint / burn on adopt — total_supply and every BALANCES entry must match pre-migrate (or a documented dust rule).
  8. No leftover tax_map — after adopt, {"tax_map":{}} must fail (unknown query). Execute paths must not read 8654 tax keys.
  9. Launcher is still the create path for new tokens. Migrate-adopt is opt-in and admin-signed on the source contract.
  10. Combined max_buy+max_sell+max_transfer ≤ 2500. MintControl stays instantiate-only unless the source already has a minter (then map or revoke — decide here).

Relevant files

Path Role
smartcontracts/contracts/community-tax-token/src/contract.rs instantiate, migrate (cw2 same-crate only)
smartcontracts/contracts/community-tax-token/src/msg.rs MigrateMsg {}, SKUs, caps
smartcontracts/contracts/community-tax-token/src/state.rs CONFIG / FEATURES / exemptions
smartcontracts/contracts/community-tax-token/src/tax.rs Extra-debit / outbound / protocol exempt
smartcontracts/contracts/community-token-launcher/src/contract.rs admin: cmm_governance, GetLauncherOrigin stamp
docs/contracts-terraclassic.md § Community tax CW20 Message shapes
docs/runbooks/cw20-code-id-ops.md F6 refresh after migrate
skills/AGENTS_COMMUNITY_TAX_CW20.md T592 / O601
skills/AGENTS_CW20_CODE_ID_PIN.md F6
cw20-codeid-audits/codeids/11611/REPORT.md Listed template
cw20-codeid-audits/codeids/8654/README.md Known-bad ALPHA control
#558 note Live ALPHA tax_map + why 8654 migrate fails today

Strategies to evaluate (pick one or a sequenced mix)

ID Strategy Keeps address? Fits ALPHA 8654? Fits 10184/8266?
S1 Document only — new 11611 via launcher; copy settings; holders swap No Yes (new ticker) Yes
S2 POL wrap (10184 cALPHA) — already on #558 No (wrap addr) Yes (holders stay on 8654) N/A
S3 Allowlisted importer in 11611 migrate — only if source cw2 ∈ {cw20-base, terraport_token, cw20-mintable} and LCD probe shows no tax_map; copy/keep BALANCES/TOKEN_INFO; write CONFIG/FEATURES; set cw2; UpdateAdmin → CMM Yes No (8654 has tax_map) Candidate
S4 Dedicated 8654 importer — parse tax_map, wipe it, map 1%/4.5% → sell/buy bps, prove every balance 1:1 Yes Research only N/A
S5 Off-chain snapshot + new instantiate + airdrop New addr Dangerous (fake mint) Dangerous

Recommended direction (pending this investigation):

  • Default product remains S1 (and S2 for ALPHA if they need the existing holder set in CL8Y pools without changing 8654).
  • Investigate S3 as the only in-place path for honest listed templates (10184/6036/8266). Require: storage-layout proof, no extra tax keys, supply invariant, CMM admin in the same ops bundle, launcher-origin or a new GetMigrateOrigin attestation, F6 Refresh runbook.
  • S4 is no-go unless the investigation produces a storage map, a wipe of tax_map, and Layer A/B that 8654-after-migrate is indistinguishable from a launcher 11611 token (inbound 1:1, extra-debit sell). Treat S4 as high-risk; do not schedule it as the first impl.
  • S5 is out (airdrop mint is a rug).

Do not implement S3/S4 in this ticket — only the decision record + threat model + follow-up issue if go.


Acceptance criteria

  • Written comparison of S1–S5 with go/no-go per source template: 8654, 10184, 6036, 8266, unknown.
  • Storage-layout note: which cw20-base keys collide; what 8654 extra keys exist; what 11611 must write on adopt.
  • If any in-place path is go: MigrateMsg shape (caps, manager, treasury, factory, SKUs), CMM UpdateAdmin order, origin/attestation rule (O601-4), F6 Refresh steps.
  • If all in-place paths are no-go: product copy + Create Token docs that communities must new-instantiate; #558 ALPHA stays S1 or S2.
  • Explicit do not list: no 8654 whitelist, no H-01 FoT math, no silent cw2 bypass, no supply mint.
  • Skills + docs/contracts-terraclassic.md + #592/#558 crosslinks updated with the decision (even if the decision is “never in-place”).
  • Follow-up implementation issue opened only if S3 or S4 is go (link it here).

Test plan (all paths)

Investigation / design proofs (LocalTerra + multitest). No columbus-5 ALPHA migrate.

Path Prove
P1 Today MsgMigrateContract 8654→11611 reverts (ensure_from_older_version). Same for a random 10184 if pointed at current 11611 (cw2 name mismatch).
P2 Same-crate 11611→11611 (or 1.0.0→next) still works; MigrateMsg {} unchanged for honest upgrades.
P3 S1 Launcher CreateToken 6 dp / sell 100 / buy 450 / no MintControl / treasury+manager from ALPHA live map; RegisterListedPair; extra-debit + outbound match TaxPreview.
P4 S3 prototype (if go) Fixture cw20-base with known balances → migrate → token_info.total_supply + sample balance unchanged; get_config present; tax_map query errors; inbound Transfer to pair 1:1.
P5 S3 reject Fixture with tax_map / unknown cw2 / mint cap mismatch / decimals > 18 → migrate revert, balances untouched.
P6 Admin After a successful adopt, ContractInfo.admin == CMM; manager ≠ admin; manager cannot migrate.
P7 F6 Pair pinned to 10184 (or 8266), asset migrates to 11611, swap fails closed until Refresh; after Refresh, extra-debit sell works.
P8 Catalog Migrated token is attested only under the rule this issue chooses (GetLauncherOrigin vs new origin). Rogue migrate without CMM admin stays unlisted.
P9 Docs Decision table in the community-tax skill + contracts-terraclassic § migrate-adopt (or “not supported”).

Attack / abuse test plan

Vector Expect
A1 Migrate 8654 without wiping tax_map Pair inbound FoT / P2 desync. Must revert or wipe; harness 8654 1:1 stays red on pre-migrate wasm.
A2 Importer mints or burns total_supply or any balance changes → fail.
A3 Skip UpdateAdmin Source admin keeps migrate and can jump off 11611 (F6 freeze is not enough if they migrate to a listed malicious rebuild). Adopt must set CMM admin.
A4 Fake origin Event-only “migrated” without CMM admin + origin query → catalog must not attest (O601-4).
A5 Storage smash Overlapping keys: 8654 tax_map vs 11611 CONFIG. Deserialize garbage / default-zero tax → fail closed, do not run.
A6 Re-enable mint Source had minter: null; adopt must not set MintControl / minter.
A7 Caps Mapped 1%+4.5% is fine (550). A source that implies >2500 combined → revert.
A8 Refresh grief Governance Refresh on a pair whose other asset is unlisted → batch fail-closed (existing F6). Adopt runbook must Refresh only pairs whose both pins are listed.
A9 Phishing /create? / payee Unchanged: payee from env/token, no query prefill.
A10 Second migrate back to 8654 CMM-only; policy is refuse. Test that manager cannot migrate.

Verification criteria

# After the decision is written (this ticket):
rg -n "migrate-adopt|S3|8654" skills/AGENTS_COMMUNITY_TAX_CW20.md docs/contracts-terraclassic.md
make verify-issue-592
make verify-issue-601   # 11611 still GO; no 8654 whitelist
  • Issue comment or body records go/no-go for S3 (10184/8266) and S4 (8654).
  • P1 reproduced (current 11611 rejects foreign cw2) — LocalTerra or documented LCD/simulate.
  • No factory AddWhitelistedCodeId 8654.
  • #558 left open for LP custody; this ticket does not replace wrap vs drop.
  • If implementation is approved, a new issue is opened with crate tests + LocalTerra smoke; this issue closes on the design record.

Verify (when a child impl exists)

Do not add make verify-issue-* until an impl lands. Gate remains make verify-issue-592 / make verify-issue-601.

## Parent / related Community tax template [#592](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/592) / store+list [#601](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/601) / Create Token [#593](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/593) / [#602](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/602). F6 pin [#582](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/582). ALPHA venues [#558](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/558) (note: in-place 8654→11611 is **not** live). This ticket is **investigation + design** (risks, options, guardrails). Do **not** ship a migrate importer until this issue records a go/no-go per source template. Implementation is a follow-up if a strategy is accepted. --- ## Current codebase `cl8y-community-tax-token` (columbus-5 **11611**, factory-listed) is a cw20-base fork plus tax config. Create is **launcher-only** for attested tokens: - Launcher **11614** `terra126pr5…` instantiates with `admin: cmm_governance` (**T592-5**). Manager cannot migrate or `UpdateAdmin`. - Free create is `ExecuteMsg::CreateToken` (0 SKU). Paid SKUs are UST1 `Send` + hook. - `MigrateMsg {}` only runs `cw2::ensure_from_older_version(…, "crates.io:cl8y-community-tax-token", version)`. Same-crate bumps only. Foreign cw2 names **revert**. - Storage: cw20-base `BALANCES` / `TOKEN_INFO` plus `CONFIG`, `FEATURES`, `LISTED_PAIRS`, `PROTOCOL_EXEMPT`, `MANAGER_EXEMPT`, `SINKS`, `LAUNCH_GUARDS`, `GetLauncherOrigin`. - Tax model (**T592**): inbound to pair/router/escrow/AutoLP is **1:1**. Sell is extra-debit on `Send`+`Swap` to a `RegisterListedPair` pair. Buy is outbound split from a listed pair. Not a `tax_map` / inbound FoT template. - Factory F6: pair pins `ContractInfo.code_id` at `CreatePair` and re-checks whitelist on writes. After a successful migrate to **11611**, listed pairs on the old id **fail closed** until `RefreshPairAssetCodeIds` (11611 is already whitelisted). ALPHA (motivating case, [#558](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/558)): | Field | Live | |-------|------| | Address | `terra1x6e64es6yhauhvs3prvpdg2gkqdtfru840wgnhs935x8axr7zxkqzysuxz` | | `code_id` | **8654** `cw20_taxed` | | Wasm + tax admin | `terra1ljqgc0cdkl7gcc7s64eczv3hrgga32vfh8xvfj` (not CMM / not DEX 2-of-3) | | Tax | `on_send` Always **1%**; Terraport dest **8260/8214** 0%; transfer-out of those codes **4.5%**; `transfer_from` never; proceeds `terra1w37akazc…` | | Supply | ~1.328B @ 6 dp; `minter` null | 8654 is a **known-bad** harness control. Do **not** whitelist it. In-place migrate to 11611 **reverts** today. Communities on **10184 / 6036 / 8266** (honest cw20-base / Terraport token) have the same gap: they can only **new-instantiate** 11611 (new address, empty balances) or stay on the old template. --- ## Why this is needed Communities want to **keep the same CW20 address and holder set** while moving onto the listed tax template (DEX-safe extra-debit / outbound split, Create Token / catalog, factory pairs). Today the only safe product path is a **new** 11611 token + liquidity move (or a 10184 wrap). That splits holders, tickers, and Terraport vs CL8Y venues. ALPHA is the first ask ([#558](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/558) note). Others on 10184/8266 will ask the same. We need a written strategy: refuse in-place, allowlisted importer, or wrap-only — **before** anyone signs `MsgMigrateContract` at the live ALPHA address. --- ## Constraints / guardrails 1. **H-01** — do not add pair/router FoT balance-delta math. Migrated tokens must keep inbound 1:1 (**T592-1**). 2. **Do not whitelist 8654** (or any `tax_map` / inbound FoT template). Listing 11611 is enough for new or migrated-to-11611 addresses. 3. **T592-5** — after adopt, wasm admin **must** be CMM (`terra16j5u6…`). Source admin becomes **manager** only. `UpdateAdmin` in the same migrate tx (or immediately after) is required if we allow in-place. 4. **O601-4** — catalog / dApp must not promote a migrate that lacks `GetLauncherOrigin` + CMM admin unless this issue explicitly defines an attested-migrate origin. 5. **F6** — post-migrate, every factory pair that had the old `code_id` pin must Refresh or stay frozen. Document the ops order. 6. **cw2** — do not skip `ensure_from_older_version` for *same-crate* upgrades. A foreign importer is a **new** migrate branch with an explicit allowlist, not a silent cw2 bypass. 7. **No supply mint / burn on adopt** — `total_supply` and every `BALANCES` entry must match pre-migrate (or a documented dust rule). 8. **No leftover `tax_map`** — after adopt, `{"tax_map":{}}` must fail (unknown query). Execute paths must not read 8654 tax keys. 9. **Launcher is still the create path** for *new* tokens. Migrate-adopt is opt-in and admin-signed on the **source** contract. 10. Combined `max_buy+max_sell+max_transfer ≤ 2500`. MintControl stays instantiate-only unless the source already has a minter (then map or revoke — decide here). --- ## Relevant files | Path | Role | |------|------| | [`smartcontracts/contracts/community-tax-token/src/contract.rs`](../smartcontracts/contracts/community-tax-token/src/contract.rs) | `instantiate`, `migrate` (cw2 same-crate only) | | [`smartcontracts/contracts/community-tax-token/src/msg.rs`](../smartcontracts/contracts/community-tax-token/src/msg.rs) | `MigrateMsg {}`, SKUs, caps | | [`smartcontracts/contracts/community-tax-token/src/state.rs`](../smartcontracts/contracts/community-tax-token/src/state.rs) | `CONFIG` / `FEATURES` / exemptions | | [`smartcontracts/contracts/community-tax-token/src/tax.rs`](../smartcontracts/contracts/community-tax-token/src/tax.rs) | Extra-debit / outbound / protocol exempt | | [`smartcontracts/contracts/community-token-launcher/src/contract.rs`](../smartcontracts/contracts/community-token-launcher/src/contract.rs) | `admin: cmm_governance`, `GetLauncherOrigin` stamp | | [`docs/contracts-terraclassic.md`](../docs/contracts-terraclassic.md) § Community tax CW20 | Message shapes | | [`docs/runbooks/cw20-code-id-ops.md`](../docs/runbooks/cw20-code-id-ops.md) | F6 refresh after migrate | | [`skills/AGENTS_COMMUNITY_TAX_CW20.md`](../skills/AGENTS_COMMUNITY_TAX_CW20.md) | **T592** / **O601** | | [`skills/AGENTS_CW20_CODE_ID_PIN.md`](../skills/AGENTS_CW20_CODE_ID_PIN.md) | F6 | | [`cw20-codeid-audits/codeids/11611/REPORT.md`](../cw20-codeid-audits/codeids/11611/REPORT.md) | Listed template | | [`cw20-codeid-audits/codeids/8654/README.md`](../cw20-codeid-audits/codeids/8654/README.md) | Known-bad ALPHA control | | [#558 note](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/558#note_3720918030) | Live ALPHA tax_map + why 8654 migrate fails today | --- ## Strategies to evaluate (pick one or a sequenced mix) | ID | Strategy | Keeps address? | Fits ALPHA 8654? | Fits 10184/8266? | |----|----------|----------------|------------------|------------------| | **S1** | **Document only** — new 11611 via launcher; copy settings; holders swap | No | Yes (new ticker) | Yes | | **S2** | **POL wrap** (10184 `cALPHA`) — already on #558 | No (wrap addr) | Yes (holders stay on 8654) | N/A | | **S3** | **Allowlisted importer** in 11611 `migrate` — only if source cw2 ∈ {cw20-base, terraport_token, cw20-mintable} **and** LCD probe shows no `tax_map`; copy/keep `BALANCES`/`TOKEN_INFO`; write `CONFIG`/`FEATURES`; set cw2; `UpdateAdmin` → CMM | Yes | **No** (8654 has `tax_map`) | Candidate | | **S4** | **Dedicated 8654 importer** — parse `tax_map`, wipe it, map 1%/4.5% → sell/buy bps, prove every balance 1:1 | Yes | Research only | N/A | | **S5** | Off-chain snapshot + new instantiate + airdrop | New addr | Dangerous (fake mint) | Dangerous | **Recommended direction (pending this investigation):** - **Default product** remains **S1** (and **S2** for ALPHA if they need the existing holder set in CL8Y pools without changing 8654). - Investigate **S3** as the only in-place path for *honest* listed templates (10184/6036/8266). Require: storage-layout proof, no extra tax keys, supply invariant, CMM admin in the same ops bundle, launcher-origin or a new `GetMigrateOrigin` attestation, F6 Refresh runbook. - **S4 is no-go unless** the investigation produces a storage map, a wipe of `tax_map`, and Layer A/B that 8654-after-migrate is indistinguishable from a launcher 11611 token (inbound 1:1, extra-debit sell). Treat S4 as high-risk; do not schedule it as the first impl. - **S5 is out** (airdrop mint is a rug). Do **not** implement S3/S4 in this ticket — only the decision record + threat model + follow-up issue if go. --- ## Acceptance criteria - [ ] Written comparison of **S1–S5** with go/no-go per source template: **8654**, **10184**, **6036**, **8266**, unknown. - [ ] Storage-layout note: which cw20-base keys collide; what 8654 extra keys exist; what 11611 must write on adopt. - [ ] If any in-place path is **go**: `MigrateMsg` shape (caps, manager, treasury, factory, SKUs), CMM `UpdateAdmin` order, origin/attestation rule (**O601-4**), F6 Refresh steps. - [ ] If all in-place paths are **no-go**: product copy + Create Token docs that communities **must** new-instantiate; #558 ALPHA stays S1 or S2. - [ ] Explicit **do not** list: no 8654 whitelist, no H-01 FoT math, no silent cw2 bypass, no supply mint. - [ ] Skills + `docs/contracts-terraclassic.md` + #592/#558 crosslinks updated with the decision (even if the decision is “never in-place”). - [ ] Follow-up implementation issue opened **only** if S3 or S4 is go (link it here). --- ## Test plan (all paths) Investigation / design proofs (LocalTerra + multitest). No columbus-5 ALPHA migrate. | Path | Prove | |------|--------| | **P1** Today | `MsgMigrateContract` 8654→11611 reverts (`ensure_from_older_version`). Same for a random 10184 if pointed at current 11611 (cw2 name mismatch). | | **P2** Same-crate | 11611→11611 (or 1.0.0→next) still works; `MigrateMsg {}` unchanged for honest upgrades. | | **P3** S1 | Launcher `CreateToken` 6 dp / sell 100 / buy 450 / no MintControl / treasury+manager from ALPHA live map; `RegisterListedPair`; extra-debit + outbound match `TaxPreview`. | | **P4** S3 prototype (if go) | Fixture cw20-base with known balances → migrate → `token_info.total_supply` + sample `balance` unchanged; `get_config` present; `tax_map` query errors; inbound Transfer to pair 1:1. | | **P5** S3 reject | Fixture with `tax_map` / unknown cw2 / mint cap mismatch / decimals > 18 → migrate **revert**, balances untouched. | | **P6** Admin | After a successful adopt, `ContractInfo.admin == CMM`; manager ≠ admin; manager cannot migrate. | | **P7** F6 | Pair pinned to 10184 (or 8266), asset migrates to 11611, swap fails closed until Refresh; after Refresh, extra-debit sell works. | | **P8** Catalog | Migrated token is attested only under the rule this issue chooses (`GetLauncherOrigin` vs new origin). Rogue migrate without CMM admin stays unlisted. | | **P9** Docs | Decision table in the community-tax skill + contracts-terraclassic § migrate-adopt (or “not supported”). | --- ## Attack / abuse test plan | Vector | Expect | |--------|--------| | **A1** Migrate 8654 without wiping `tax_map` | Pair inbound FoT / **P2** desync. Must revert or wipe; harness 8654 1:1 stays red on *pre*-migrate wasm. | | **A2** Importer mints or burns | `total_supply` or any balance changes → fail. | | **A3** Skip `UpdateAdmin` | Source admin keeps migrate and can jump off 11611 (F6 freeze is not enough if they migrate to a *listed* malicious rebuild). Adopt must set CMM admin. | | **A4** Fake origin | Event-only “migrated” without CMM admin + origin query → catalog must not attest (**O601-4**). | | **A5** Storage smash | Overlapping keys: 8654 `tax_map` vs 11611 `CONFIG`. Deserialize garbage / default-zero tax → fail closed, do not run. | | **A6** Re-enable mint | Source had `minter: null`; adopt must not set MintControl / minter. | | **A7** Caps | Mapped 1%+4.5% is fine (550). A source that implies >2500 combined → revert. | | **A8** Refresh grief | Governance Refresh on a pair whose *other* asset is unlisted → batch fail-closed (existing F6). Adopt runbook must Refresh only pairs whose both pins are listed. | | **A9** Phishing `/create?` / payee | Unchanged: payee from env/token, no query prefill. | | **A10** Second migrate back to 8654 | CMM-only; policy is refuse. Test that manager cannot migrate. | --- ## Verification criteria ```bash # After the decision is written (this ticket): rg -n "migrate-adopt|S3|8654" skills/AGENTS_COMMUNITY_TAX_CW20.md docs/contracts-terraclassic.md make verify-issue-592 make verify-issue-601 # 11611 still GO; no 8654 whitelist ``` - [ ] Issue comment or body records **go/no-go** for S3 (10184/8266) and S4 (8654). - [ ] P1 reproduced (current 11611 rejects foreign cw2) — LocalTerra or documented LCD/simulate. - [ ] No factory `AddWhitelistedCodeId 8654`. - [ ] #558 left open for LP custody; this ticket does not replace wrap vs drop. - [ ] If implementation is approved, a **new** issue is opened with crate tests + LocalTerra smoke; this issue closes on the design record. ## Verify (when a child impl exists) Do not add `make verify-issue-*` until an impl lands. Gate remains `make verify-issue-592` / `make verify-issue-601`.
PlasticDigits commented 2026-08-23 06:30:41 +00:00 (Migrated from gitlab.com)

marked as related to #558

marked as related to #558
PlasticDigits commented 2026-08-23 06:30:42 +00:00 (Migrated from gitlab.com)

marked as related to #592

marked as related to #592
PlasticDigits commented 2026-08-23 06:30:42 +00:00 (Migrated from gitlab.com)

marked as related to #593

marked as related to #593
PlasticDigits commented 2026-08-23 06:30:43 +00:00 (Migrated from gitlab.com)

marked as related to #601

marked as related to #601
PlasticDigits commented 2026-08-23 06:30:44 +00:00 (Migrated from gitlab.com)

marked as related to #602

marked as related to #602
PlasticDigits commented 2026-08-23 06:30:44 +00:00 (Migrated from gitlab.com)

marked as related to #582

marked as related to #582
PlasticDigits commented 2026-08-23 06:37:07 +00:00 (Migrated from gitlab.com)

Goal should be for codeids that have been whitelisted to migrate, to be able to migrate for free, through extremely simplified click on a "migrate" page (they can load in their token and click one button to migrate it). Possible need for custom migration paths for different codeids such as 8266 and 8654

Goal should be for codeids that have been whitelisted to migrate, to be able to migrate for free, through extremely simplified click on a "migrate" page (they can load in their token and click one button to migrate it). Possible need for custom migration paths for different codeids such as 8266 and 8654
PlasticDigits commented 2026-08-23 06:48:17 +00:00 (Migrated from gitlab.com)

mentioned in issue #604

mentioned in issue #604
PlasticDigits commented 2026-08-23 06:48:20 +00:00 (Migrated from gitlab.com)

marked as related to #604

marked as related to #604
PlasticDigits commented 2026-08-23 06:48:28 +00:00 (Migrated from gitlab.com)

mentioned in issue #605

mentioned in issue #605
PlasticDigits commented 2026-08-23 11:49:49 +00:00 (Migrated from gitlab.com)

mentioned in issue #607

mentioned in issue #607
PlasticDigits commented 2026-08-23 11:52:16 +00:00 (Migrated from gitlab.com)

mentioned in merge request !1122

mentioned in merge request !1122
PlasticDigits commented 2026-08-23 12:55:29 +00:00 (Migrated from gitlab.com)

C-2 is written: #607 chose option 1 (router hops Honest / pair-direct still taxes). This importer ticket is no longer blocked on an unwritten tax/router policy.

If any in-place path is later go, migrated 11611 tokens must keep T592-13. Do not ship copy that promises advertised buy/sell bps on official multi-hop or execute_swap_operations.

MR for the design close: !1126

C-2 is written: [#607](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/607) chose **option 1** (router hops Honest / pair-direct still taxes). This importer ticket is no longer blocked on an unwritten tax/router policy. If any in-place path is later **go**, migrated 11611 tokens must keep **T592-13**. Do not ship copy that promises advertised buy/sell bps on official multi-hop or `execute_swap_operations`. MR for the design close: !1126
PlasticDigits commented 2026-08-24 00:18:18 +00:00 (Migrated from gitlab.com)

#607 reopened due to option 1 beign poor choice & damaging communitys that list their tokens expecting fees they dont receive

#607 reopened due to option 1 beign poor choice & damaging communitys that list their tokens expecting fees they dont receive
PlasticDigits commented 2026-08-24 00:29:00 +00:00 (Migrated from gitlab.com)

mentioned in merge request !1127

mentioned in merge request !1127
PlasticDigits commented 2026-08-24 06:03:26 +00:00 (Migrated from gitlab.com)
  • we have new code id, no longer 11611 for our latest community tax template cw20
  • must check that migrating a token such as 8654 will not impact terraprot or gdex lp for the token migrating
- we have new code id, no longer 11611 for our latest community tax template cw20 - must check that migrating a token such as 8654 will not impact terraprot or gdex lp for the token migrating
PlasticDigits commented 2026-08-24 11:45:20 +00:00 (Migrated from gitlab.com)

Status check (2026-08-24)

State: open, design-only. No assignee. No importer impl. Acceptance (S1–S5 go/no-go, storage-layout, follow-up impl issue) is still unchecked.

community-tax-token::migrate is still MigrateMsg {} + cw2::ensure_from_older_version(…, "crates.io:cl8y-community-tax-token", …). Same-crate bumps only. Foreign cw2 (8654 / 10184 / 6036 / 8266) still reverts. No /migrate page. No GetMigrateOrigin.

Live pins (issue body is stale)

Body still says “onto 11611” / launcher 11614. After #611 / #616 (2026-08-24):

Role Live
Latest tax CW20 11619 (cl8y-community-tax-token 1.0.0, option-2 hop_trader, #604–#609). REPORT GO.
Still listed 11611 (pre-option-2). Keep until Refresh. Zero instances — no CMM same-crate migrate to run.
Factory whitelist [6036, 8266, 10184, 11611, 11619]
Launcher terra126pr5… code 11622; GetConfig token_code_id 11619 / autolp_code_id **11621`
Do not whitelist ALPHA 8654, launcher 11612 / 11614 / 11620 / 11622, AutoLP 11613 / 11621

Same-crate 11611 → 11619 is already allowed by current migrate. That is not this ticket. Any S3/S4 importer must target 11619 (T592-13), not 11611-era Honest hops.

C-2 (earlier notes on this issue)

#607 closed on improved option 2 (!1127). The 2026-08-23 note that C-2 is option 1 / Honest hops is stale. Unmigrated live 11611 still Honest hops until a CMM same-crate bump; new 11619 taxes official-router trader. Related: !1122 (#604/#605), !1126 (superseded option-1 docs), #558 still open (ALPHA wrap vs drop / POL).

Product notes already here (still open)

  • One-click free migrate page for already-whitelisted templates; possible custom paths for 8266 and 8654.
  • Must check Terraport / GDEX LP impact for an in-place migrate (e.g. ALPHA 8654).

Terraport / GDEX LP (investigation fact, not a go)

In-place migrate keeps the CW20 address. Terraport / GDEX pairs are not CL8Y factory pairs and are not F6-pinned. They keep holding the same token; only wasm + tax keys change.

Source After adopt to 11619 Terraport / GDEX LP
6036 / 10184 / 8266 (honest 1:1) Extra-debit / outbound only on CL8Y RegisterListedPair. Other DEX transfers stay 1:1. Address unchanged. Reserves / LP accounting stay 1:1. CL8Y factory pairs freeze until RefreshPairAssetCodeIds.
8654 (ALPHA tax_map) Must wipe tax_map. Inbound 1:1 everywhere (T592-1). Sell/buy tax only if the pair is CL8Y-listed. Address unchanged, so existing TP/GDEX pools still see the token. Live ALPHA map (Terraport dest 8260/8214 = 0% inbound; transfer-out of those codes = 4.5%) goes away. Forward TP/GDEX flow becomes honest 1:1 (safer for those AMMs). Historical buy/withdraw that already skimmed 4.5% from pair→user is not unwound. Do not RegisterListedPair a Terraport/GDEX pair. S4 remains no-go until storage wipe + Layer A/B prove 8654-after-migrate ≡ launcher 11619.

Do not whitelist 8654 so Terraport/GDEX can “keep working.” Listing 8654 is still forbidden (H-01 / P2).

Still not this ticket

  • No one-click page, no S3/S4 branch, no supply mint.
  • #558 stays open. This ticket does not replace wrap vs drop.
  • Follow-up impl issue only after a written go.

Gate remains make verify-issue-592 / make verify-issue-601. No verify-issue-603.

## Status check (2026-08-24) **State:** open, design-only. No assignee. No importer impl. Acceptance (S1–S5 go/no-go, storage-layout, follow-up impl issue) is still unchecked. `community-tax-token::migrate` is still `MigrateMsg {}` + `cw2::ensure_from_older_version(…, "crates.io:cl8y-community-tax-token", …)`. Same-crate bumps only. Foreign cw2 (**8654** / **10184** / **6036** / **8266**) still reverts. No `/migrate` page. No `GetMigrateOrigin`. ### Live pins (issue body is stale) Body still says “onto **11611**” / launcher **11614**. After #611 / #616 (2026-08-24): | Role | Live | |------|------| | Latest tax CW20 | **11619** (`cl8y-community-tax-token` 1.0.0, option-2 `hop_trader`, #604–#609). REPORT **GO**. | | Still listed | **11611** (pre-option-2). Keep until Refresh. Zero instances — no CMM same-crate migrate to run. | | Factory whitelist | `[6036, 8266, 10184, 11611, 11619]` | | Launcher | `terra126pr5…` code **11622**; `GetConfig` `token_code_id` **11619** / `autolp_code_id` **11621` | | Do not whitelist | ALPHA **8654**, launcher **11612 / 11614 / 11620 / 11622**, AutoLP **11613 / 11621** | Same-crate **11611 → 11619** is already allowed by current `migrate`. That is **not** this ticket. Any S3/S4 importer must target **11619** (T592-13), not 11611-era Honest hops. ### C-2 (earlier notes on this issue) #607 closed on **improved option 2** ([!1127](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/merge_requests/409)). The 2026-08-23 note that C-2 is option 1 / Honest hops is **stale**. Unmigrated live **11611** still Honest hops until a CMM same-crate bump; new **11619** taxes official-router `trader`. Related: !1122 (#604/#605), !1126 (superseded option-1 docs), #558 still open (ALPHA wrap vs drop / POL). ### Product notes already here (still open) - One-click **free** migrate page for **already-whitelisted** templates; possible custom paths for **8266** and **8654**. - Must check Terraport / GDEX LP impact for an in-place migrate (e.g. ALPHA 8654). ### Terraport / GDEX LP (investigation fact, not a go) In-place migrate **keeps the CW20 address**. Terraport / GDEX pairs are not CL8Y factory pairs and are **not** F6-pinned. They keep holding the same token; only wasm + tax keys change. | Source | After adopt to 11619 | Terraport / GDEX LP | |--------|----------------------|---------------------| | **6036 / 10184 / 8266** (honest 1:1) | Extra-debit / outbound only on CL8Y `RegisterListedPair`. Other DEX transfers stay 1:1. | Address unchanged. Reserves / LP accounting stay 1:1. CL8Y factory pairs freeze until `RefreshPairAssetCodeIds`. | | **8654** (ALPHA `tax_map`) | Must wipe `tax_map`. Inbound 1:1 everywhere (T592-1). Sell/buy tax only if the pair is CL8Y-listed. | Address unchanged, so existing TP/GDEX pools still see the token. Live ALPHA map (**Terraport dest 8260/8214 = 0% inbound; transfer-out of those codes = 4.5%**) goes away. Forward TP/GDEX flow becomes honest 1:1 (safer for those AMMs). Historical buy/withdraw that already skimmed 4.5% from pair→user is **not** unwound. Do **not** `RegisterListedPair` a Terraport/GDEX pair. **S4 remains no-go** until storage wipe + Layer A/B prove 8654-after-migrate ≡ launcher 11619. | Do **not** whitelist 8654 so Terraport/GDEX can “keep working.” Listing 8654 is still forbidden (H-01 / P2). ### Still not this ticket - No one-click page, no S3/S4 branch, no supply mint. - #558 stays open. This ticket does not replace wrap vs drop. - Follow-up impl issue only after a written go. Gate remains `make verify-issue-592` / `make verify-issue-601`. No `verify-issue-603`.
PlasticDigits commented 2026-08-24 11:49:43 +00:00 (Migrated from gitlab.com)

mentioned in issue #626

mentioned in issue #626
PlasticDigits commented 2026-08-24 11:49:44 +00:00 (Migrated from gitlab.com)

marked as related to #626

marked as related to #626
PlasticDigits commented 2026-08-24 11:49:54 +00:00 (Migrated from gitlab.com)

Implementation follow-up opened: #626 (feat(community-tax): one-click free migrate onto 11619 for listed templates + Terraport/GDEX LP gate).

Bundles the two product notes on this ticket (one-click free page + Terraport/GDEX LP impact). S3 first (6036/10184); 8266 custom path gated on storage + LP table; 8654 stays refuse until S4 go. This design ticket stays open until S1–S5 is filled or points at #626 as the decision+impl record.

Implementation follow-up opened: [#626](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/626) (`feat(community-tax): one-click free migrate onto 11619 for listed templates + Terraport/GDEX LP gate`). Bundles the two product notes on this ticket (one-click free page + Terraport/GDEX LP impact). S3 first (6036/10184); 8266 custom path gated on storage + LP table; 8654 stays refuse until S4 go. This design ticket stays open until S1–S5 is filled or points at #626 as the decision+impl record.
PlasticDigits commented 2026-08-24 12:12:27 +00:00 (Migrated from gitlab.com)

mentioned in merge request !1136

mentioned in merge request !1136
PlasticDigits commented 2026-08-24 12:12:35 +00:00 (Migrated from gitlab.com)

Implementation follow-up shipped in #626 / !1136.

Go / no-go recorded on #626: S3 go, S3-8266 go, S4 8654 no-go. This issue stays open as the design record (do not close until the S1–S5 table is filled or explicitly points at #626 as the decision+impl record).

Implementation follow-up shipped in #626 / !1136. Go / no-go recorded on #626: **S3 go**, **S3-8266 go**, **S4 8654 no-go**. This issue stays open as the design record (do not close until the S1–S5 table is filled or explicitly points at #626 as the decision+impl record).
PlasticDigits commented 2026-08-24 13:31:34 +00:00 (Migrated from gitlab.com)

mentioned in issue #627

mentioned in issue #627
PlasticDigits commented 2026-08-24 13:31:35 +00:00 (Migrated from gitlab.com)

marked as related to #627

marked as related to #627
PlasticDigits commented 2026-08-24 13:33:32 +00:00 (Migrated from gitlab.com)

mentioned in issue #628

mentioned in issue #628
PlasticDigits commented 2026-08-24 13:33:33 +00:00 (Migrated from gitlab.com)

marked as related to #628

marked as related to #628
PlasticDigits commented 2026-08-25 03:06:23 +00:00 (Migrated from gitlab.com)

mentioned in issue #636

mentioned in issue #636
PlasticDigits commented 2026-08-25 05:50:59 +00:00 (Migrated from gitlab.com)

Design close — S1–S5 recorded; impl is #626

This ticket is the decision record. Implementation shipped on #626 / !1136. Venue inventory shipped on #634. Canonical write-up: docs/contracts-terraclassic.md § migrate-adopt + skills/AGENTS_FRONTEND_TOKEN_MIGRATE.md.

S1–S5 (go / no-go)

ID Strategy Status
S1 New instantiate via Create Token (new address) Fallback — still the path for unknown / refused sources
S2 POL wrap #558 — wrap vs drop stays open; this ticket does not replace it
S3 Allowlisted importer for 6036 / 10184 go — cw2 crates.io:cw20-base / crates.io:cw20-mintable; keep balances; write CONFIG/FEATURES; CMM UpdateAdmin
S3-8266 8266 Terraport token go — cw2 crates.io:terraport-token; leftover marketing_info / balance_at unread; Terraport Open/LUNC stays 1:1
S4 8654 ALPHA wipe go — wipe tax_info / tax_map / whale_info; map 4.5%/1% → buy 450 / sell 100. Retail allowlist includes 8654. Never factory-list 8654 (listing 11619 / later adopt pin covers the address)
S5 Snapshot + airdrop mint out — fake mint / rug
Unknown Other cw2 / smash / code 3 no-go — revert. Columbus-5 code 3 stays on #627

Target wasm is option-2 hop_trader (T592-13), not 11611-era Honest hops. Same-crate bump remains MigrateMsg {} (CMM-only; not the retail page). Foreign adopt is MigrateMsg { adopt }. Origin is GetMigrateOrigin (do not fake launcher_tx). Retail /token/migrate is free.

Do not

  • AddWhitelistedCodeId 8654 (or any inbound FoT / tax_map wasm)
  • Pair/router FoT math (H-01)
  • Silent cw2 bypass for same-crate upgrades
  • Supply mint / burn on adopt
  • RegisterListedPair Terraport / GDEX

Verified this pass (2026-08-25)

  • make verify-issue-592 — 4/4
  • make verify-issue-626 — 8/8 (crates include P1 p1_foreign_cw2_without_adopt_reverts, S3, S3-8266, S4 wipe)
  • VERIFY634_SKIP_CHAIN=1 make verify-issue-634 — 4/4
  • Columbus-5 GetWhitelistedCodeIds = [6036, 8266, 10184, 11630] — 8654 absent

Did not re-run full make verify-issue-601 (live pin is 11630, not the 11626 check in that script). Store / Coolify leftover stays on #628.

Closing this design ticket per its own gate: S1–S5 filled here and pointed at #626 as the decision+impl record. #558 / #627 / #628 remain open.

## Design close — S1–S5 recorded; impl is #626 This ticket is the decision record. Implementation shipped on [#626](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/626) / [!1136](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/merge_requests/418). Venue inventory shipped on [#634](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/634). Canonical write-up: [`docs/contracts-terraclassic.md` § migrate-adopt](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/blob/main/docs/contracts-terraclassic.md#migrate-adopt-gitlab-626) + [`skills/AGENTS_FRONTEND_TOKEN_MIGRATE.md`](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/blob/main/skills/AGENTS_FRONTEND_TOKEN_MIGRATE.md). ### S1–S5 (go / no-go) | ID | Strategy | Status | |----|----------|--------| | **S1** | New instantiate via Create Token (new address) | **Fallback** — still the path for unknown / refused sources | | **S2** | POL wrap | **#558** — wrap vs drop stays open; this ticket does not replace it | | **S3** | Allowlisted importer for **6036** / **10184** | **go** — cw2 `crates.io:cw20-base` / `crates.io:cw20-mintable`; keep balances; write CONFIG/FEATURES; CMM `UpdateAdmin` | | **S3-8266** | **8266** Terraport token | **go** — cw2 `crates.io:terraport-token`; leftover `marketing_info` / `balance_at` unread; Terraport Open/LUNC stays 1:1 | | **S4** | **8654** ALPHA wipe | **go** — wipe `tax_info` / `tax_map` / `whale_info`; map 4.5%/1% → buy 450 / sell 100. Retail allowlist includes 8654. **Never** factory-list 8654 (listing **11619** / later adopt pin covers the address) | | **S5** | Snapshot + airdrop mint | **out** — fake mint / rug | | **Unknown** | Other cw2 / smash / code 3 | **no-go** — revert. Columbus-5 code **3** stays on [#627](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/627) | Target wasm is option-2 `hop_trader` (**T592-13**), not 11611-era Honest hops. Same-crate bump remains `MigrateMsg {}` (CMM-only; not the retail page). Foreign adopt is `MigrateMsg { adopt }`. Origin is `GetMigrateOrigin` (do not fake `launcher_tx`). Retail `/token/migrate` is free. ### Do not - `AddWhitelistedCodeId 8654` (or any inbound FoT / `tax_map` wasm) - Pair/router FoT math (**H-01**) - Silent cw2 bypass for same-crate upgrades - Supply mint / burn on adopt - `RegisterListedPair` Terraport / GDEX ### Verified this pass (2026-08-25) - `make verify-issue-592` — 4/4 - `make verify-issue-626` — 8/8 (crates include **P1** `p1_foreign_cw2_without_adopt_reverts`, S3, S3-8266, S4 wipe) - `VERIFY634_SKIP_CHAIN=1 make verify-issue-634` — 4/4 - Columbus-5 `GetWhitelistedCodeIds` = `[6036, 8266, 10184, 11630]` — **8654 absent** Did not re-run full `make verify-issue-601` (live pin is **11630**, not the 11626 check in that script). Store / Coolify leftover stays on [#628](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/628). Closing this design ticket per its own gate: S1–S5 filled here and pointed at #626 as the decision+impl record. #558 / #627 / #628 remain open.
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-08-25 05:51:01 +00:00
PlasticDigits commented 2026-08-25 05:57:12 +00:00 (Migrated from gitlab.com)

mentioned in commit 315d5c910c

mentioned in commit 315d5c910cb03ad10ea0013547c767ccc7209153
PlasticDigits commented 2026-08-25 06:11:42 +00:00 (Migrated from gitlab.com)

mentioned in commit dd712705bd

mentioned in commit dd712705bdc50f17ce181c94db9de69d1a64bd47
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/cl8y-dex-terraclassic#603
No description provided.