Commands & actions to go through SNS launch
Overview
At a high level, the stages for launching an SNS in production are explained here.
This article lists the technical commands and steps a developer needs to complete the stages for an SNS launch.
At a low level, the SNS local testing repository guides you through the same, with the difference that the commands here target the canisters on the mainnet.
Prerequisites:
Install the IC SDK. See: installing the IC SDK.
Install
ic-admin
. See: installing theic-admin
.Install
sns
CLI.
The version of the sns CLI that is bundled with your dfx version may not have the latest commands described in the Usage section. If needed, it is recommended to build and use the sns CLI tool yourself.
git clone git@github.com:dfinity/ic.git
cd ic
bazel build //rs/sns/cli:sns
ls bazel-bin/rs/sns/cli/sns
Stages
1. Dapp developers choose the initial parameters of the SNS for a dapp.
Typically, dapp developers choose initial parameters that will be used in the subsequent proposal.
These parameters also define the initial neurons with which the SNS governance canister will be installed. Before being fully launched, the SNS governance canister is in a pre-decentralization-swap mode and only few proposals are allowed (see Step 7). However, some SNS proposals might already be used during this time, for example upgrades to the dapp canister(s) while the launch is ongoing or registering custom proposals for that DAO. Such operations require submitting and adopting an SNS proposal during the launch process, and thus before the SNS is fully launched. Some frontends, for example the NNS frontend dapp, do not show neurons of SNSs that are not fully launched and thus neurons controlled by NNS frontend dapp principals will only be visible after a successful launch. Therefore, the initial neurons must be carefully setup in a way so that enough of them can be operated already during the launch process.
2. Dapp developers add NNS root as co-controller of dapp.
This article assumes if you start with adding the NNS root co-controller, that you have already tested the SNS process.
They can do so by running the following command:
dfx sns prepare-canisters add-nns-root $CANISTER_ID
Handing over the dapp's canisters might require additional actions; for example, removing any special permissions that the dapp's developers may have had prior to the decentralization effort. One example of a special permission might be the ability to change the frontend canister content on their own. You can review the SNS asset canister documentation for more details.
dfx canister call $CANISTER_ID revoke_permission '(record {of_principal = principal "<developer principal"; permission = variant { Commit;};})'
Soon, if all goes well you will not personally have control over these canisters anymore. Instead, they will be controlled by the SNS, only updatable through SNS proposals. Furthermore, during the swap, the SNS will be in a restricted mode where some SNS proposal types cannot be submitted:
ManageNervousSystemParameters
TransferSnsTreasuryFunds
MintSnsTokens
UpgradeSnsControlledCanister
RegisterDappCanisters
DeregisterDappCanisters
This means that it is not easy to upgrade an SNS-controlled dapp canister during the swap. However, since the SNS-controlled dapp canisters are co-owned by NNS root during a swap, it is still possible via an NNS proposal. This is intended to be used on an emergency basis and should be avoided if possible.
3. Submit NNS proposal to create SNS.
Anyone who owns an eligible NNS neuron with enough stake can submit an NNS proposal to create an SNS for a given dapp. Of course it is crucial to set the right parameters in this proposal. You can also find an example of how this command is used here.
Note that there can only be one such proposal at a time in the NNS. This means that the time when this proposal can be submitted might depend on other SNS' launch.
To create such a proposal, a common path is to use sns-cli
and run the following:
dfx sns propose --network ic --neuron $NEURON_ID sns_init.yaml
4. The NNS proposal is decided.
Nothing technical for dapp developers to do. Community votes.
5. (Automated) SNS-W deploys SNS canisters.
Nothing technical for dapp developers to do. This is triggered automatically as a result of an adopted proposal in Stage 4.
6. (Automated) SNS-W sets SNS root and NNS root as sole controllers of dapp.
Nothing technical for dapp developers to do. This is triggered automatically as a result of an adopted proposal in Stage 4.
7. (Automated) SNS-W initializes SNS canisters according to settings from Step 1.
Nothing technical for dapp developers to do. This is triggered automatically as a result of an adopted proposal in Stage 4.
At this point, the SNS canisters exist and the dapp canisters are under SNS DAO control. The initial SNS neurons can use SNS proposals to take the last steps to decentralize the dapp canisters, for example by giving certain permissions to the SNS governance canister stating that these functions can only be triggered by SNS DAO proposal. One example of this is the asset canister (see details here).
8. (Automated) SNS swap starts.
Nothing technical for dapp developers to do. This is triggered automatically as a result of an adopted proposal in Stage 4.
9. (Automated) SNS swap ends.
Nothing technical for dapp developers to do. This is triggered automatically as a result of an adopted proposal in Stage 4.
10. (Automated) SNS swap finalizes.
Nothing technical for dapp developers to do. This is triggered automatically as a result of an adopted proposal in Stage 4. At this point, the SNS is fully launched and the dapp canisters are fully decentralized. The SNS root canister is also given full control of the dapp canisters. The SNS is no longer restricted and any proposal type can be submitted and executed.