Investigate columbus-5 CW20 code_id 3 for migrate-adopt and factory whitelist #627

Closed
opened 2026-08-24 13:31:33 +00:00 by PlasticDigits · 16 comments
PlasticDigits commented 2026-08-24 13:31:33 +00:00 (Migrated from gitlab.com)

Future investigation only — do not implement on the current migrate MR.

This ticket is not a license to append 3 to VITE_COMMUNITY_MIGRATE_CODE_IDS or call AddWhitelistedCodeId 3.


Why

Columbus-5 code_id 3 is the original everybody-instantiate CW20 store. It is the single most common historical token wasm on-chain (MIR, TWD, VKR, WHALE, KUJI, and many Station-minted tokens). It is not on the factory whitelist and not on the retail migrate allowlist.

Live LCD (2026-08-24):

Field Value
Code id 3
Creator terra15kc4dkquya20yx09avpdw8796unj709xuyxjyc
Instantiate Everybody
data_hash prefix F9B4AB2202A5110B…
cw2 crates.io:cw20-base 0.0.0–0.1.0 (instance-dependent)
Examples MIR terra15gwky…g40k6, TWD, VKRC, WHALEC, KUJI

Factory whitelist today: [6036, 8266, 10184, 11611, 11619]. Retail migrate default: 6036,10184,8266,8654.

Adopt keys off cw2 name, not code_id. adopt.rs already allowlists crates.io:cw20-base. A code-3 instance would pass the name check and then likely smash on TOKEN_INFO / BALANCES because columbus-5 code 3 still uses the cw20-legacy layout (CanonicalAddr balances; TokenInfo raw key \u{0}\ntoken_info). See columbus-5 dApp guide.

Listing 3 would admit every instantiate of that wasm (H-01 blast radius / catalogue B13).


Investigate (two tracks)

A. Migrate / adopt onto 11619

  1. Fetch + pin LCD wasm (cw20-codeid-audits/scripts/fetch-lcd-wasm.sh 3) and decomp. Confirm storage keys vs current cw20_base::state (BALANCES / TOKEN_INFO / allowances).
  2. Multitest: honest Transfer 1:1; adopt keep-balances / no mint-burn; leftover tax_map absent.
  3. Decide whether adopt needs a legacy-layout importer (CanonicalAddr → Addr) or whether code 3 is a hard no-go.
  4. If a layout adapter is even plausible: Layer A-lcd + B-lt on the pinned bytes (CODE_ID=3 LAYER_B_LT=1 make verify-issue-589). Fail closed on mismatch.
  5. Retail gate stays env (VITE_COMMUNITY_MIGRATE_CODE_IDS). Do not special-case MIR/KUJI addresses. Do not treat cw2 cw20-base alone as proof the layout matches 10184.

B. Factory whitelist (pair-asset)

  1. Same #589 REPORT GO gate as any other template. Checksum match / “looks like cw20-base” is not enough.
  2. Prove inbound Transfer / Send to a pair is 1:1 (P2). Code 3 is expected honest, but Everybody instantiate still admits hostile instances (minter / marketing) — record residual, do not treat as a veto by itself.
  3. If listed: F6 pin applies; Refresh after any later migrate. Unlisting 3 would freeze every pair still pinned to 3.
  4. Do not bundle this with 8654 / cw20-tax / +taxed00x forks.

Acceptance (when someone picks this up)

  • cw20-codeid-audits/codeids/3/REPORT.md with explicit go / no-go for (A) adopt and (B) factory list — they may differ.
  • Storage-layout note: legacy CanonicalAddr vs current cw20-base maps; adopt smash vs migrate-with-adapter.
  • Instance census (how many contracts, who has wasm admin) before any Everybody-list decision.
  • If either track is go: follow the #626 “add a future source” steps (cw2 allowlist and env code id). Factory list still requires governance AddWhitelistedCodeId after REPORT GO.
  • If no-go: document the revert reason in the migrate skill so agents do not append 3 from cw2 name alone.

Do not

  • Append 3 to Coolify VITE_COMMUNITY_MIGRATE_CODE_IDS or factory whitelist from this ticket alone.
  • Assume live cw2 crates.io:cw20-base means the same crate/layout as 10184 (10184 also reports cw20-base; 6036 reports terraswap-token).
  • Open exits / Refresh / RegisterListedPair as part of this investigation.

Out of scope (sibling stores)

Same-era cw20-base stores that are not this ticket: 147 (aUST), 153 (ANC), 610 (ASTROC), 767 (Wormhole WETH), 1603 (stLuna), 1790 (bLuna), 4254 (STT), 5800 (LOOPC). Open a new ticket per id if those become product-relevant. GDEX 9788 / Terraswap current 7395 are also separate.

## Parent / related Future investigation only — **do not** implement on the current migrate MR. - Migrate-adopt impl [#626](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/626) / design [#603](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/603) - CW20 audit harness [#589](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/589) - F6 listing pin [#582](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/582) - Whitelist policy / H-01 [#377](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/377) - Playbook [`AGENTS_FRONTEND_TOKEN_MIGRATE.md`](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/blob/main/skills/AGENTS_FRONTEND_TOKEN_MIGRATE.md) (add a future source) This ticket is **not** a license to append `3` to `VITE_COMMUNITY_MIGRATE_CODE_IDS` or call `AddWhitelistedCodeId 3`. --- ## Why Columbus-5 **code_id 3** is the original everybody-instantiate CW20 store. It is the single most common historical token wasm on-chain (MIR, TWD, VKR, WHALE, KUJI, and many Station-minted tokens). It is **not** on the factory whitelist and **not** on the retail migrate allowlist. Live LCD (2026-08-24): | Field | Value | |-------|--------| | Code id | **3** | | Creator | `terra15kc4dkquya20yx09avpdw8796unj709xuyxjyc` | | Instantiate | **Everybody** | | `data_hash` prefix | `F9B4AB2202A5110B…` | | cw2 | `crates.io:cw20-base` `0.0.0`–`0.1.0` (instance-dependent) | | Examples | MIR `terra15gwky…g40k6`, TWD, VKRC, WHALEC, KUJI | Factory whitelist today: `[6036, 8266, 10184, 11611, 11619]`. Retail migrate default: `6036,10184,8266,8654`. Adopt keys off **cw2 name**, not `code_id`. `adopt.rs` already allowlists `crates.io:cw20-base`. A code-3 instance would **pass the name check** and then likely smash on `TOKEN_INFO` / `BALANCES` because columbus-5 code 3 still uses the **cw20-legacy** layout (CanonicalAddr balances; TokenInfo raw key `\u{0}\ntoken_info`). See [columbus-5 dApp guide](https://github.com/terra-money/classic-mainnet/wiki/Preparing-Terra-DApps-for-Columbus-5,-Full-Guide). Listing **3** would admit **every** instantiate of that wasm (H-01 blast radius / catalogue **B13**). --- ## Investigate (two tracks) ### A. Migrate / adopt onto 11619 1. Fetch + pin LCD wasm (`cw20-codeid-audits/scripts/fetch-lcd-wasm.sh 3`) and decomp. Confirm storage keys vs current `cw20_base::state` (`BALANCES` / `TOKEN_INFO` / allowances). 2. Multitest: honest Transfer 1:1; adopt keep-balances / no mint-burn; leftover `tax_map` absent. 3. Decide whether adopt needs a **legacy-layout importer** (CanonicalAddr → Addr) or whether code 3 is a hard no-go. 4. If a layout adapter is even plausible: Layer A-lcd + B-lt on the **pinned** bytes (`CODE_ID=3 LAYER_B_LT=1 make verify-issue-589`). Fail closed on mismatch. 5. Retail gate stays env (`VITE_COMMUNITY_MIGRATE_CODE_IDS`). Do not special-case MIR/KUJI addresses. Do not treat cw2 `cw20-base` alone as proof the layout matches 10184. ### B. Factory whitelist (pair-asset) 1. Same #589 REPORT **GO** gate as any other template. Checksum match / “looks like cw20-base” is **not** enough. 2. Prove inbound Transfer / Send to a pair is **1:1** (P2). Code 3 is expected honest, but Everybody instantiate still admits hostile *instances* (minter / marketing) — record residual, do not treat as a veto by itself. 3. If listed: F6 pin applies; Refresh after any later migrate. Unlisting 3 would freeze every pair still pinned to 3. 4. Do **not** bundle this with 8654 / `cw20-tax` / `+taxed00x` forks. --- ## Acceptance (when someone picks this up) - [ ] `cw20-codeid-audits/codeids/3/REPORT.md` with explicit **go / no-go** for (A) adopt and (B) factory list — they may differ. - [ ] Storage-layout note: legacy CanonicalAddr vs current `cw20-base` maps; adopt smash vs migrate-with-adapter. - [ ] Instance census (how many contracts, who has wasm admin) before any Everybody-list decision. - [ ] If either track is **go**: follow the #626 “add a future source” steps (cw2 allowlist **and** env code id). Factory list still requires governance `AddWhitelistedCodeId` after REPORT GO. - [ ] If **no-go**: document the revert reason in the migrate skill so agents do not append `3` from cw2 name alone. ## Do not - Append `3` to Coolify `VITE_COMMUNITY_MIGRATE_CODE_IDS` or factory whitelist from this ticket alone. - Assume live cw2 `crates.io:cw20-base` means the same crate/layout as 10184 (10184 also reports `cw20-base`; 6036 reports `terraswap-token`). - Open exits / Refresh / RegisterListedPair as part of this investigation. ## Out of scope (sibling stores) Same-era `cw20-base` stores that are **not** this ticket: **147** (aUST), **153** (ANC), **610** (ASTROC), **767** (Wormhole WETH), **1603** (stLuna), **1790** (bLuna), **4254** (STT), **5800** (LOOPC). Open a new ticket per id if those become product-relevant. GDEX **9788** / Terraswap current **7395** are also separate.
PlasticDigits commented 2026-08-24 13:31:34 +00:00 (Migrated from gitlab.com)

marked as related to #626

marked as related to #626
PlasticDigits commented 2026-08-24 13:31:35 +00:00 (Migrated from gitlab.com)

marked as related to #603

marked as related to #603
PlasticDigits commented 2026-08-24 13:31:41 +00:00 (Migrated from gitlab.com)

marked as related to #589

marked as related to #589
PlasticDigits commented 2026-08-24 13:31:44 +00:00 (Migrated from gitlab.com)

marked as related to #582

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

mentioned in issue #626

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

mentioned in issue #628

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

marked as related to #628

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

mentioned in issue #603

mentioned in issue #603
PlasticDigits commented 2026-08-25 06:09:10 +00:00 (Migrated from gitlab.com)

mentioned in merge request !1145

mentioned in merge request !1145
PlasticDigits commented 2026-08-25 06:09:30 +00:00 (Migrated from gitlab.com)

Investigation recorded on !1145 (issue-627-cw20-codeid-3). make verify-issue-627 14/14.

Acceptance

  • cw20-codeid-audits/codeids/3/REPORT.md — NO-GO for (A) adopt and (B) factory list (they match; both no-go).
  • Storage-layout note: legacy \x00\x0atoken_info + CanonicalAddr balances vs modern unprefixed token_info + Addr maps. Adopt smash (AdoptMissingTokenInfo / AdoptLegacyLayout) vs migrate-with-adapter (not built).
  • Instance census: LCD walk lower bound ≥ 34,900 (349 pages, still paging). Sampled MIR/TWD/VKR/WHALE/KUJI + first-page Station instances all have wasm admin. Snapshot: codeids/3/census.json.
  • Neither track is go — did not append env or AddWhitelistedCodeId 3.
  • NO-GO revert reason in skills/AGENTS_FRONTEND_TOKEN_MIGRATE.md (S3-code3) and skills/AGENTS_CW20_CODE_ID_3.md so agents do not append 3 from cw2 name alone.

Do not (held)

  • Did not append 3 to VITE_COMMUNITY_MIGRATE_CODE_IDS.
  • Did not factory-list 3.
  • Did not Open exits / Refresh / RegisterListedPair.
  • Did not treat live cw2 crates.io:cw20-base as 10184 layout.

Extra (fail-closed, not an importer)

Crate now reverts AdoptLegacyLayout if CanonicalAddr balance keys are present or TOKEN_INFO serde fails. That is defense in depth, not a retail GO.

Layer A-lcd / B-lt on pinned bytes was fail-closed (interface_version_7). A CanonicalAddr → Addr importer is a new ticket if product wants one later.

Investigation recorded on !1145 (`issue-627-cw20-codeid-3`). `make verify-issue-627` **14/14**. ## Acceptance - [x] `cw20-codeid-audits/codeids/3/REPORT.md` — **NO-GO** for (A) adopt and (B) factory list (they match; both no-go). - [x] Storage-layout note: legacy `\x00\x0atoken_info` + CanonicalAddr balances vs modern unprefixed `token_info` + `Addr` maps. Adopt smash (`AdoptMissingTokenInfo` / `AdoptLegacyLayout`) vs migrate-with-adapter (not built). - [x] Instance census: LCD walk lower bound **≥ 34,900** (349 pages, still paging). Sampled MIR/TWD/VKR/WHALE/KUJI + first-page Station instances all have wasm admin. Snapshot: `codeids/3/census.json`. - [x] Neither track is **go** — did **not** append env or `AddWhitelistedCodeId 3`. - [x] **NO-GO** revert reason in `skills/AGENTS_FRONTEND_TOKEN_MIGRATE.md` (**S3-code3**) and `skills/AGENTS_CW20_CODE_ID_3.md` so agents do not append `3` from cw2 name alone. ## Do not (held) - Did not append `3` to `VITE_COMMUNITY_MIGRATE_CODE_IDS`. - Did not factory-list 3. - Did not Open exits / Refresh / RegisterListedPair. - Did not treat live cw2 `crates.io:cw20-base` as 10184 layout. ## Extra (fail-closed, not an importer) Crate now reverts `AdoptLegacyLayout` if CanonicalAddr `balance` keys are present or `TOKEN_INFO` serde fails. That is defense in depth, not a retail GO. Layer A-lcd / B-lt on pinned bytes was **fail-closed** (`interface_version_7`). A CanonicalAddr → Addr importer is a new ticket if product wants one later.
PlasticDigits commented 2026-08-25 06:28:19 +00:00 (Migrated from gitlab.com)

mentioned in commit 1576710716

mentioned in commit 157671071664695e78e90b097e3681207a2a86e5
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-08-25 06:28:20 +00:00
PlasticDigits commented 2026-08-25 06:29:23 +00:00 (Migrated from gitlab.com)

!1145 merged to main (15767107) without waiting for CI. Conflicts were docs/Makefile/AGENTS; live tax pin 11630 (from #628/#635) kept, plus do not append 3. make verify-issue-627 14/14 (first pass + retest). Crate adopt 16 + Vitest migrate 10.

Verdict unchanged: dual-track NO-GO (A adopt + B factory list). Coolify VITE_COMMUNITY_MIGRATE_CODE_IDS must not gain 3. No AddWhitelistedCodeId 3 / Refresh / RegisterListedPair from this ticket.

Sibling stores (147, 153, …) stay out of scope — open a new ticket per id if needed.

!1145 merged to `main` (`15767107`) without waiting for CI. Conflicts were docs/Makefile/AGENTS; live tax pin **11630** (from #628/#635) kept, plus **do not append 3**. `make verify-issue-627` **14/14** (first pass + retest). Crate adopt **16** + Vitest migrate **10**. **Verdict unchanged:** dual-track **NO-GO** (A adopt + B factory list). Coolify `VITE_COMMUNITY_MIGRATE_CODE_IDS` must **not** gain `3`. No `AddWhitelistedCodeId 3` / Refresh / RegisterListedPair from this ticket. Sibling stores (147, 153, …) stay out of scope — open a new ticket per id if needed.
PlasticDigits commented 2026-08-25 06:29:43 +00:00 (Migrated from gitlab.com)

mentioned in issue #638

mentioned in issue #638
PlasticDigits commented 2026-08-25 06:29:46 +00:00 (Migrated from gitlab.com)

marked as related to #638

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

Post-merge leftovers for the !1140/!1142/!1143/!1144/!1145 pass: #638.

Post-merge leftovers for the !1140/!1142/!1143/!1144/!1145 pass: #638.
PlasticDigits commented 2026-08-27 11:52:20 +00:00 (Migrated from gitlab.com)

mentioned in issue #690

mentioned in issue #690
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#627
No description provided.