TL;DR
- Recently the NNS approved a new flow to launch SNSs, in which it is unclear how asset canisters can be handed over to an SNS DAO.
- We propose slight modifications to the asset canister that allow a flow where the asset canister can be updated with the right information after the SNS is launched. This flow also works for other dapp canisters.
- This does not require any changes to the SNS code and does not affect existing SNSs.
Context & Problem statement
Each SNS community might have functions that should only be executed if the SNS DAO agrees on it but that might be very dapp-specific. Generic proposals allow a flexible way for SNS communities to define such functions. Usually, the dapp canisters that implement these functions enforce that the caller of the respective method must be the SNS governance’s canister ID.
One example canister that makes use of this is the asset canister where dapps can store and retrieve assets for their frontends. To ensure decentralized decisions making, only the SNS governance canister should be able to “commit” new assets and change the permissions who can “prepare” new assets (see more details about how the assets can be updated by SNS proposal here). As long as a dapp is still under the developers’ control, the developers can trigger these functions. However, once the dapp is handed over to an SNS DAO, it is essential that these functions can only be triggered by SNS DAO decisions.
As pointed out by this user, since a new SNS launch process was introduced, there is no good way of handing over the asset canister during an SNS launch without additional trust assumptions. The same holds for other dapp canisters that work in a similar way to the asset canister.
How it worked before August 2023
Let’s first understand how this worked for the first SNS launches. Until recently, SNSs were launched in the following steps:
-
An NNS proposal approved that an SNS launch could be started.
-
The SNS canisters were created and initialized. As a result, everyone could learn the canister ID of the SNS governance canister.
-
The developers handed over the dapp canisters to the SNS
- They updated the methods implementing generic proposals so that they can only be called by the SNS governance canister’s ID.
- They assigned the SNS root canister as the dapp canisters’ controller.
- An NNS proposal started the decentralization swap and, if successful, fully launched the SNS.
Why this does not work with the 1-proposal flow
With proposal 124279 the NNS released a new feature that allows SNSs to be created with a single NNS proposal.
In this new flow,
- The dapp’s control is handed over from the dapp developers to the NNS.
- A single NNS proposal creates the SNS canisters, initializes them, hands over the dapp canisters to the newly created SNS, and starts the decentralization swap.
Compared to the old flow, at the time of the dapp handover the SNS canisters do not yet exist. Therefore the ID of the SNS governance canister cannot be set at the time of the handover.
New proposed flow
Once an SNS is launched and the dapp canisters are handed over to it, the dapp canisters can be changed by SNS proposal. The idea is to make use of this fact and add one more step to the launch where a dapp canister upgrade changes the necessary privileges in the dapp canisters.
To better understand this, let us consider a concrete example, namely a canister game
with a method called change_color()
that changes the background color of the dapp and should only be triggered by SNS DAO decision.
The new flow would be as follows:
- The dapp’s control is handed over from the dapp developers to the NNS.
In the example, this means that the controller of the canistergame
is set to the NNS root canister. - A single NNS proposal creates the SNS canisters, initializes them, hands over the dapp canisters to the newly created SNS, and starts the decentralization swap.
By this, everyone can learn the canister ID of the newly created SNS governance canister. Let us call itSNS_governance_ID
. - The SNS community upgrades the dapp canister by an SNS proposal and sets the privileges in the dapp correctly.
The canistergame
is upgraded to a new version wherechange_color()
checks that the method’s caller equalsSNS_governance_ID
.
In more detail, Step 3 can be realized in one of the following ways.
- At Step 1, the canister
game
does not include the methodchange_color()
. The method is only added at Step 3 with the right check that the caller isSNS_governance_ID
. - At Step 1, the canister
game
already includes the methodchange_color()
which specifies that the caller must equal a constant. At this time the constant is not set. In Step 3, the canister is upgraded to a version where the constant is set toSNS_governance_ID
. - At Step 1, the canister
game
already includes the methodchange_color()
which specifies that the caller must equal a variable that is not set at this time. In Step 3, the canister is upgraded with upgrade argumentsSNS_governance_ID
and this variable is set to it.
Asset canister
We intend to adopt the asset canister so that the third version above would also work for this case. This means that projects that use an asset canister can hand over the asset canister to the NNS in Step 1 of the SNS launch and, after the SNS is created, upgrade it with upgrade arguments that specify the SNS governance’s canister ID.
We intend to do this by adding optional upgrade arguments that can be used to replace the existing permission settings with new permissions.
Next steps
We are looking forward to hearing your feedback on this proposed flow. This new proposed flow requires no changes to the SNS launch process and minimal changes to the asset canister.
If there are no big concerns raised here, we plan to make the appropriate adoptions in the publicly accessible implementation of the asset canister.