Recent SNS Governance Security Fix: Restrict Proposals During Swaps


The DFINITY team found a bug in the SNS Governance canister that allows the initial neurons to execute undesired proposal types, such as minting SNS tokens, during the swap. This could allow a developer team with malicious intent to gain centralized control. This upgrade addresses the issue by disallowing several proposal types during the swap.

This issue has been fixed with proposal 130411 and no upcoming SNS swap will be vulnerable. In particular, the WaterNeuron swap that is about to start uses the fixed Governance canister version, see here.

Previous State

Before the proposal 130411, any SNS proposal type was allowed during the swap except for

  • Manage Nervous System Parameters
  • Transfer SNS Treasury Funds.

New state

DFINITY submitted and urgently voted on (see below) a proposal that also made the following proposal types unavailable during the swap:

  1. Mint SNS Tokens

  2. Upgrade SNS Controlled Canister

  3. Register Dapp Canisters

  4. Deregister Dapp Canisters


The benefit of making these proposal types unavailable during the swap is to prevent potential misuse by malicious initial neurons. Here are the specific risks associated with each proposal type:

  1. Mint SNS Tokens

    • Risk: This could be used by the initial neurons to give themselves a significant amount of SNS tokens before the swap is over, diluting the token supply and undermining the decentralization of the SNS. Furthermore, the SNS tokens could be staked, creating a neuron with voting majority that could pass arbitrary SNS proposals right after the swap completes, e.g., transferring the SNS treasury’s ICP funds to a personal account.
  2. Upgrade SNS-Controlled Canister

    • Risk: This could be used by the initial neurons to steal funds from an SNS-controlled dapp canister (if the canister controls funds) or to upgrade the dapp to something meaningless (e.g., removing all the content).

    • Disallowing upgrade proposals during the swap also comes with a risk: in case there is (for example) a security vulnerability in the dapp, the dapp could not be upgraded during the period of the swap to fix it. To mitigate this risk, DFINITY will propose (this Friday, 21 June 2024) that the NNS Root canister co-controls the dapp canisters during the swap. This will allow dapp canisters to be upgraded via an NNS proposal in an emergency situation. Until this proposal is adopted, dapp canisters will not be upgradable during the swap process. The NNS Root controllership will be revoked after the swap, making the dapp canisters solely controlled by the SNS as is the case now.

  3. Register Dapp Canisters

    • Risk: This could be used to associate the SNS with a dapp that it does not want to be associated with, potentially damaging the reputation and trust in the SNS.
  4. Deregister Dapp Canisters

    • Risk: This could be used to take control of the dapp canisters away from the SNS and give it to a centralized party just before the swap completes, undermining the control and purpose of the SNS launch process.

Why DFINITY voted early on this proposal

In accordance with the security policy, DFINITY voted on the proposal earlier than usual. The reason for this is that we considered the fact that initial neurons can mint new tokens during the swap as a high risk security issue that should be resolved as soon as possible.

WaterNeuron has upgraded to the latest version of SNS Governance which is fixed. This means that the initial neurons are unable to submit any of the above proposals. All future SNSes will also use the latest version of SNS Governance and likewise be unable to submit any of these proposals during the swap. There is no further action required by SNS projects.

Governance Proposal

## Proposal to Publish the SNS Governance Canister WASM to SNS-W
### Proposer: DFINITY Foundation
### Canister Type: governance
### Git Hash: a9a67996f7a5f0c4e95a697fafcad6b15a5aae62
### New Wasm Hash: d806d992ccd7f4f6ac0fe9faaed19f2a7b806f2b8136ba5a278fe1d093defc25
## Release Notes
$ git log --format="%C(auto) %h %s" d1504fc4265703c5c6a73098732a4256ea8ff6bf..a9a67996f7a5f0c4e95a697fafcad6b15a5aae62 -- ./rs/sns/governance
c064fd6c67 fix(nns): FOLLOW-943: Disallow dangerous proposals during PreinitializationSwap
5b7bfd703a feat(sns): When making a CreateServiceNervousSystem proposal through the SNS CLI, give additional information to users
ecc6808b80 refactor(sns): Refactor proposal_action_is_allowed_in_pre_initialization_swap_or_err
0c290f8ead refactor(sns): Make the canonical NervousSystemFunction accessible
695a0affa9 chore: Bump rust version to 1.78
f6951cf1a7 chore: upgrade external crates and use workspace version
2d7dfc0135 chore: upgrade tempfile version and use the workspace. version everywhere
f455700243 chore: use the rand version from the Cargo workspace
## Wasm Verification
Verify that the hash of the gzipped WASM matches the proposed hash.
git fetch
git checkout a9a67996f7a5f0c4e95a697fafcad6b15a5aae62
./gitlab-ci/container/ -c
sha256sum ./artifacts/canisters/sns-governance-canister.wasm.gz