TL;DR
Terra Classic currently lets any account upload arbitrary CosmWasm bytecode (code_upload_access = Everybody). As a precautionary security-hardening measure, and in line with current CosmWasm ecosystem best practice, this proposal changes that parameter to Nobody, so that only governance can add new contract code.
- Existing contracts and all contract execution/instantiation are unaffected.
- CosmWasm is not removed — new code can still be added via a governance proposal.
- The change is fully reversible and privileges no individual address.
Feedback is requested before this goes to an on-chain vote.
Background & rationale
By default, wasmd (the CosmWasm module) ships with code_upload_access = Everybody. Terra Classic has never changed this, so today any account can store arbitrary contract bytecode on-chain via MsgStoreCode.
Uploading bytecode is the most powerful and lowest-trust action a chain can expose: the uploaded code is processed by the on-chain VM on every validator. As the CosmWasm stack continues to evolve, a growing number of chains are moving upload behind governance as a standard, precautionary reduction of attack surface. This proposal brings Terra Classic in line with that practice.
The goal is deliberately conservative: privilege no one, keep the door fully open for the community to authorize specific deployers later, and change nothing about how existing contracts run.
What changes
x/wasm module parameters:
| Parameter | Before | After |
|---|---|---|
code_upload_access.permission |
Everybody |
Nobody |
code_upload_access.addresses |
[] |
[] |
instantiate_default_permission |
Everybody |
Everybody (unchanged) |
What this does not change
- Existing contracts keep working. Instantiation and execution of already-stored code are untouched (
instantiate_default_permissionstaysEverybody). - CosmWasm stays enabled. New code can still be uploaded — through a governance proposal.
- No lock-in. Every parameter here can be changed again by a future governance vote.
- No address is favored. The allow-list is empty; nobody gets a special upload privilege.
Future allow-listing
Starting at Nobody forecloses nothing. Should the community later wish to permit specific, vetted deployers (teams, a deployer multisig, etc.), a subsequent governance proposal can simply set code_upload_access to AnyOfAddresses with the chosen addresses. The mechanism to add uploaders via proposal is always available — this proposal just declines to privilege anyone today.
(Note: AnyOfAddresses requires at least one address to be valid; an “empty allow-list” is expressed as Nobody. The two are equivalent in effect, and either can be changed into the other by governance at any time.)
Impact on builders
- Teams that need to deploy new contracts will, while this is in effect, do so via a governance proposal (or via an allow-list added by a later proposal, if the community approves one).
- Already-deployed contracts, their users, and all existing dApp activity are unaffected.
- If you are a builder who expects to deploy soon, please comment below so the community can weigh an
AnyOfAddressesallow-list alongside or after this change.
Technical detail — the on-chain message
The vote will execute a single MsgUpdateParams against the x/wasm module:
{
"messages": [
{
"@type": "/cosmwasm.wasm.v1.MsgUpdateParams",
"authority": "<gov module account address>",
"params": {
"code_upload_access": { "permission": "Nobody", "addresses": [] },
"instantiate_default_permission": "Everybody"
}
}
],
"metadata": "",
"deposit": "<min deposit>uluna",
"title": "Restrict CosmWasm code upload to governance",
"summary": "Change code_upload_access from Everybody to Nobody as a precautionary security hardening. Existing contracts and instantiation are unaffected; reversible by future governance."
}
The authority is the governance module account (terrad q auth module-account gov). Current params can be verified by anyone with terrad q wasm params (or the public LCD endpoint /cosmwasm/wasm/v1/codes/params).
Discussion questions
- Do you support moving contract upload behind governance as a precautionary measure?
- Should we pair this with (or quickly follow it by) an
AnyOfAddressesallow-list for known, trusted deployers — and if so, which addresses? - Any objections from active builders who have near-term deployment plans?
Please share feedback here before this is submitted on-chain.