Open Governance canister for SNS | Design proposal

Hi all,

I propose to use this new thread to discuss a new proposed design for the open governance canister that can be used for implementation of the service nervous systems (SNSs).

Objective

Similarly to how the Network Nervous System (NNS) is the open tokenized governance system that controls the Internet Computer blockchain (IC), service nervous systems (SNSs) are algorithmic DAOs that will allow developers to create decentralized, token-based governance systems for their dapps.

Decentralized control and tokenization enables the introduction of new incentive systems and use cases that have the potential to set dapps apart from traditional applications. We refer to this article for more background on how SNSs will empower Dapps to leverage the full potential of the IC.

The goal of this project is to provide a first implementation of an open governance canister that will then be used to realise the service nervous systems (SNSs).

More concretely, this release’s goal is to provide an “out of the box” governance canister implementation that

  1. Can be used to realize the SNS (see next section)
  2. Can be used by anyone looking to implement another kind of DAO for their dapp, either by using the governance canister and integrating it with other canisters or by just taking the governance canister code as a basis and evolving it to another kind of governance

Background & Context with other projects

Relation to the original SNS design & overall approach

We presented a first proposed SNS design in October 2021. The community’s feedback was that that SNS design was rather complex and does not leave a lot of freedom to developers to configure a DAO to their needs. Moreover, some developers mentioned that they have a particular DAO or use case in mind and are only interested in an implementation of a ledger or governance canister, which they plan to integrate with existing canisters.

The goal of SNSs is also to eventually provide open governance solutions “on the press of a button” for those who are not experienced developers themselves. This motivates that a concrete implementation and usable interfaces to deploy and upgrade SNSs are provided to the community.

To address all of these concerns, we propose the following new approach:

  1. Release the different building blocks in multiple stages, such that the community can make use of intermediate deliverables (e.g., single canisters) as soon as they are ready
  2. Evolve these single building blocks to arrive at a concrete implementation that can be used without engineering efforts
  3. Make the concrete implementation modular and the single components configurable so that each SNS can be configured as suitable for the dapp that it governs

Context with other SNS projects

More concretely, we propose the following initial stages:

  1. Improve the NNS ledger canister so that it can also be used for other tokens
  2. Implement a governance canister (the design presented and discussed here)
  3. Tooling and support for the deployment and upgrade of SNSs that consist of multiple canisters, including the ledger and governance canister from above (design will be presented in a separate forum thread in the coming weeks)
  4. More steps towards allowing SNSs “on the press of a button”, including frontend support, support for initial token distribution etc. (less concrete, this depends on the previous steps and the feedback there)

Proposed design for the open governance canister

Summary design

On a high level, the idea is to reuse only those concepts of the NNS that are relevant.
This would allow us to reuse some code from the NNS governance canister but simplify the design by omitting concepts that are only relevant in the context of the NNS.

More concretely, we propose to reuse the concepts of

  • neurons, which facilitate stake-based voting that guarantees that voters are invested in the respective governance token and therefore incentivized to vote in the best interest of the system.
  • proposals as the SNS should allow users to make suggestions, e.g., how to evolve the associated dapp, and for others to vote on these decisions.

As with the NNS governance, it is expected that the governance canister is deployed with an associated ledger canister, where it is determined how much stake each neuron has.

Moreover, compared to the NNS where some configurations can only be changed by canister upgrades, in this open governance canister most configurations should be defined as parameters that can easily be configured at deployment and changed by proposals. This will allow each developer and community to tweak the governance rules to their needs.

More design details

We next introduce some more details of the design, with a special focus on things that are different compared to the NNS governance canister.

Note that some details have a remark “if feasible in a timely manner”. We propose that we implement these features in the first implementation if the effort is not too large. Otherwise, we propose to favor an earlier release and add those features in a next iteration.

Proposals

In the NNS governance, proposals have both a type, determining what they will do exactly, and a topic, based on which neurons can follow other neurons in the decision making (liquid democracy).
As each SNS will have very different use cases, we propose to omit the concept of proposal topics and facilitate following based on the proposal types.

Moreover, we propose that an open governance canister supports at least the following proposals by default:

  • A proposal to change the governance parameters
  • A proposal to upgrade one canister, that can e.g., be used to upgrade a dapp canister
  • Motion proposals that facilitate discussions in the community but do not have any immediate, automatic effect
Neurons

Regarding neurons, we propose:

  • omitting the neuron attributes and methods that are specific to NNS use cases.
  • having the following neuron attributes (with motivation):
    • (If this is feasible due to storage restrictions) omit the neurons’ ID and use the neurons’ account on the ledger canister as the identifier instead
    • (If this is feasible in a timely manner) provide an access control list for neurons that specifies which principals can perform which neuron actions. For the first version, start with a simple logic that describes two keys similarly to the controller and hot keys in the NNS governance canister. Later, provide methods that allow defining valid access control lists by governance canisters and that allow neuron holders to change the access control of their individual neurons within these valid options.
    • (As in the NNS) The amount of staked governance tokens.
    • (As in the NNS) The time when the neuron was created.
    • (As in the NNS) The neuron’s dissolve state specifying whether a neuron is dissolving, i.e., the timer when the staked tokens can be retrieved is decreasing, or non-dissolving, i.e., the time how much into the future the staked tokens can be retrieved is stopped and the neuron’s age specifying how long the neuron has been in non-dissolving state.These concepts allow incentive systems where neuron holders that commit to the system for a longer time have more say or get more rewards.
    • (As in the NNS) A neuron’s followees. This allows for voting with a liquid democracy, where neurons can choose to delegate their vote to other neurons.
    • (As in the NNS) A neuron’s maturity which keeps track of the rewards that a neuron has collected. This allows governance participation to be rewarded.
  • the following commands for managing neurons (similar to the NNS governance, except for omitting disburse_to_neuron which has an NNS specific use case):
    • Claiming and refreshing of a neuron. This is needed to stake a neuron and then top up a neuron’s stake.
    • Configuring a neuron, including increasing the dissolve delay, start dissolving, and stop dissolving a neuron. This allows a neuron holder to choose the dissolve state and age of their neuron, which are explained above.
    • Making a proposal, registering a vote, and configuring followers, which allow a neuron to participate in governance decisions.
    • Spawning and Merging Maturity, which allows a neuron to mint the governance tokens corresponding to the rewards that it has accumulated. The former allows the neuron holder to retrieve the rewards as tokens in a new neuron with a small dissolve delay and the latter allows a neuron holder to reinvest the rewards by adding them to the neuron’s stake.
    • Disburse which allows a neuron holder to liquidate again the staked tokens.
    • (If this is feasible in a timely manner) Splitting and merging neurons which are convenient methods for neuron holders to organize their neurons.
  • in contrast to the NNS neurons, making all neuron attributes public, including the neurons’ controllers. This simplifies the APIs and allows for more auditability.
  • omitting the proposals of topic “manageNeuron” that allow multiple principals to control a neuron and the associated use cases for the neurons (e.g., in access control and voting). Instead, allow canisters to control neurons.
  • making some implementation improvements along the way.

Security

We consider this to be a security critical feature, as the upgrades of dapps and the value of associated governance tokens are at risk if there are vulnerabilities. We thus plan that both the design and implementation will be reviewed by DFINITY’s security team.

Alternatives considered

Some different approaches that we could have taken and why we decided against them:

  • We could have waited with releasing until we have the full SNS implemented. As argued above, we decided against this as it seemed to be a wish from the community to be able to use the single components as soon as possible.
  • We could have decided to just reuse the NNS governance code.
    We decided against this as there are some NNS specific things in the NNS governance canister that we do not need in the SNS. It also seemed to be a wish from the community to keep things as simple as possible, which supports this.
  • We could have generalized the NNS governance code and then reuse it for both the NNS and the SNS.
    We decided against this as NNS upgrades are security critical and have to be considered carefully. Moreover, it would take more time to generalize the NNS code, taking into account all of the NNS specific components. Therefore, we favored using a new code base for SNS as this will allow for faster feature delivery.

Risks and mitigations

As already discussed, there are security risks involved in this project. Therefore, this project requires thorough testing and security reviews and reasoning. We mitigate the risk of unforeseen findings by involving the testing and security experts early in the process.

Community conversation & Timeline

The NNS team is ready to work on this feature!
To get the design approved by the community, we propose the following schedule:

  1. Jan 11-18th: Design discussion on this forum thread
  2. Jan 18th: Community conversation about the topic
  3. Jan 20th: Developer discussion on Discord
  4. (a few days later): motion proposal submission proposing the above design, potentially adjusted with the feedback from Steps 1 - 3.

Looking forward to hearing your inputs on this!

22 Likes

Thanks for sharing! I have a few questions:

  • Can you list out the “governance parameters” that you envision SNS proposals being allowed to change? For example, I personally think the 8 year max staking period for NNS neurons is too long for SNS; most smaller projects won’t even last 2 years.

Moreover, compared to the NNS where some configurations can only be changed by canister upgrades, in this open governance canister most configurations should be defined as parameters that can easily be configured at deployment and changed by proposals.

  • Can you clarify this? In both cases, governance canisters can only be changed via proposals. Are you saying that the NNS canister can only be changed via “new replica binary” proposals that involve code changes, but here you are proposing that SNS canisters can be changed via proposals that involve no code?

  • Will this SNS open governance canister be created and managed by the NNS (as a controller), as you indicated in your talk? Or will developers need to deploy the SNS governance canister and “blackhole” it themselves?

4 Likes

Thanks for your questions @jzxchiang!

Can you list out the “governance parameters” that you envision SNS proposals being allowed to change? For example, I personally think the 8 year max staking period for NNS neurons is too long for SNS;

I would put pretty much anything that is currently a constant as a parameter. I think if I listed them all right now, I would probably miss some of them. Would it be OK I shared them later, when we have a selection in the code? I think adding or removing them at this point will still be possible, independently of the rest of the design.
That being said, I would definitively see the max staking period as one of these parameter that should be configurable for each SNS. Also, things such as the minimum dissolve delay, the fees etc.

Can you clarify this? In both cases, governance canisters can only be changed via proposals. Are you saying that the NNS canister can only be changed via “new replica binary” proposals that involve code changes, but here you are proposing that SNS canisters can be changed via proposals that involve no code?

Right, it is for sure the case that both things can only be changed by proposal. In neither of the proposals the replica binary is involved. The difference is that if we change constants, this requires a full upgrade of the governance canister, meaning that we have to stop the governance canister, upgrade the wasm, and restart the canister. So basically we do the same as when we change the actual implementation of the governance canister.
However, the special parameters (called NetworkEconomics in the governance canister) are changed, then the effect of an adopted proposal is that a special method is called that just updates these parameters to the new values given in the proposal. This is in some sense less invasive and less risky. Moreover, it means that the actual wasm is not changed.
The latter is important for SNSs as this means that different SNSs can run the same wasm (so users can e.g., verify that this is the wasm that has been “blessed by the NNS community”) but still have different configurations.

Does this clarify things? Do you have a suggestion to how I can express this better in the design proposal?

Will this SNS open governance canister be created and managed by the NNS (as a controller), as you indicated in your talk? Or will developers need to deploy the SNS governance canister and “blackhole” it themselves?

The aim of this project is just to provide an implementation of the governance canister that can be downloaded and used by interested developers. As such it does not have any fixed controller.
The questions of how an SNS can be deployed and who would then be the controller etc will be tackled in a next project (we are actively working on the design and should be able to share it in the coming weeks).

4 Likes

Does this clarify things? Do you have a suggestion to how I can express this better in the design proposal?

Yes, this helps a lot. I totally forgot that SNS (and NNS) proposals simply describe a method that is called (along with their arguments) if a proposal passes. In the case of changing constants, I’m guessing the called method is an install_module or install_wasm type of method. In the case of changing governance parameters like you describe, the called method would be some custom change_gov_param method that is relatively more lightweight.

The point about running the same wasm (for verification purposes) also makes sense.

The questions of how an SNS can be deployed and who would then be the controller etc will be tackled in a next project (we are actively working on the design and should be able to share it in the coming weeks).

Thanks, that makes sense.


On a higher level, I am thinking about what types of projects can benefit immediately from SNS. I’m not convinced that the ambitious, larger-scale projects (think decentralized YouTube, decentralized Twitter, etc) will be comfortable handing over control of their project to a SNS governance canister, at least not right now.

Why? I think partially it is due to how new and untested SNS is, but another is due to the impact on development velocity. Shipping changes will take longer, as they now need to go through motion proposals, upgrade proposals, etc. Yet another is due to the fact that SNS-governed dapps must be open source (or at least should be). Otherwise, nobody would be able to propose or review dapp canister upgrades.

There are other open questions about the tooling needed to perform good governance. Where do voters communicate? Is it a forum like this or a Discord server? Where do voters vote? Will there be an SNS equivalent of nns.ic0.app or do developers need to build their own?

I think a project that meets these criteria would be a great POC to test SNS on:

  • low risk (so probably not DeFi)
  • quick to implement (a month or so, probably just a couple of web pages and a single backend canister)
  • useful

Need to brainstorm what that would be…

3 Likes

I think ICDevs and other DAOs that are trying to make decisions that aren’t executed directly on chain would be good first projects. What do you think @skilesare? We could use the SNS motion proposals to come to decisions on bounties. Especially once the SNS has a default frontend, it should be incredibly simple to spin up an SNS for ICDevs, submit motion proposals, give out “tokens” to board members, and then vote.

@Arthur CycleDAO might be interested in doing something similar, @wpb same with ICPMN.

1 Like

One of my main concerns with the new design (which I think is fantastic BTW) is that it is still somewhat forcing us into a staking model with lockups and rewards. What if we just want a simple token voting SNS? No staking, no lockup periods, no voting rewards…just simple coin voting. For ICDevs I imagine that’s all we’d want at least to start. Not all projects will want the “token” to accrue value and become a tradeable asset, or at least I don’t think we should force everyone into that model. Forcing lockups and rewards seems to do that.

8 Likes

I’d love that. We were going for that with Bounty - ICDevs.org Generic DAO - Axon Fork. We don’t have a token so staking doesn’t really make sense. We need a system where we can hand out votes to known-real people and we don’t really want those votes to be transferable…so the token model works but doesn’t quite fit.

2 Likes

My understanding from @lara’s talk is that you can emulate that by setting dissolve delay to 0 for everyone and removing any age or other bonuses. These should be governance parameters that can be tweaked, I think.

Hey everyone, just a friendly reminder that @lara will be leading a developer discussion today on Discord at 8:00am PST. Hope you can make it!

2 Likes

Thanks for the feedback.
Yes, as @jzxchiang pointed out, some of this should be achievable by setting the parameters correctly.
For example, setting the dissolve delay required to be eligible to zero.
Also, at least long term, rewards will be optional so each SNS can decide when to burn and mint new tokens. I am not sure if it has been decided whether this feature is realised in the first version, but thinking about it, it shouldn’t actually be that hard to make rewards optional.

After this feedback, I would like to at least consider including this in the first version.

3 Likes

Hi all, just an update from my side:
as promised in the first post, we plan to submit a motion proposal with the above design, now that we had the different conversations.
@diegop kindly agreed to help with this.
In order to give the proposal enough visibility, we plan to send it early next week rather than so shortly before the weekend.

Have a great weekend and look out for the proposal next week!

4 Likes

Update:

Proposal is live!

7 Likes

Big concern! How will people use this thing without a front-end supplied? Are we supposed to all create our own front-ends to even start experimenting with this? Even a simple front-end would be nice to have

8 Likes

Thanks for bringing up the concern.
Note that this particular project is just about the governance canister.
A frontend is planned but will be done separately.
I am currently following up internally regarding when we think we can have that.

3 Likes

I’m just worried no one (really it will just be much harder) will use this and try it out without a front-end. And the point of pushing things out in pieces is to get community feedback.

1 Like

That is certainly one goal.
Another goal is also to already make the code available to developers who might want to reuse parts of this to build their own governance / DAO etc.

But it is valuable feedback that I happily take back.

4 Likes

Is there any implementation started for this beyond the proposal and this thread that I can take a look at?

1 Like

Hi all, please find the design proposal for the next stage of the SNS project here.
Looking forward to your questions and feedback!

2 Likes

Yes, the implementation is started. It is still very much work in progress, but you can follow along here https://github.com/dfinity/ic/tree/master/rs/sns

2 Likes

I see a pathway to set the SNS canister to call a remote canister to call a function. I’d like something like:

type RemoteCall {
principal: Principal;
function: Text;
data: Blob; };

In motoko this could use the call_raw functionality coming in 0.9.1. This would allow services canisters to mark the SNS canister as the “Admin” and then the sns could vote on functions to call on various canisters(not just the SNS canister which I think is the current set up).

I’m working on the spec for a service right now that is trying to be governance service agnostic and just assign a governance canister. As long as that canister knows how to call the issue_command function you can use the SNS or something simpler. It would be great if the SNS supported this. I know there are issues with getting stuck on a bad behaving canister, but maybe you can not wait for the await? Or maybe it is a parameter to the type?

1 Like