Towards more auditable SNSs (example: Neurons’ Fund)

Following the goal of decentralisation, all users should be able to audit the SNSs without the need to trust any third party to do so. For example, any user should be able to monitor and self-validate their SNS swap contribution, without the need to trust someone else to do it for them.

Good news: Most information for auditing SNSs via the public canister API is already in place. For example, one can verify that, after a swap succeeds, the Neurons’ Fund participants got their correct SNS neuron baskets. This could be done by analyzing the responses of NnsGov.get_neurons_fund_audit_info and Swap.list_sns_neuron_recipes. However, the analysis involved requires some knowledge about how the canisters are implemented, what the fields in the response payloads actually mean, etc.

To streamline the process, we plan to publish a DFX plugin that will enable the following syntax:

dfx sns audit $PROPOSAL_ID # proposed syntax

where $PROPOSAL_ID is the ID of the NNS proposal for creating the SNS that is to be audited. This new plugin will bring together some tooling that we have been using in the NNS team while building SNS-related features. We will make a separate announcement when the first version of the plugin is published.

First example: Auditing that the Neurons’ Fund participation follows the new Matched Funding rules. Feel free to take a look at a very early prototype which can be accessed from the IC monorepo by running:

bazel run //rs/nervous_system/neurons_fund/nfplot -- https://ic0.app $SWAP_CANISTER --audit

Note that only completed SNSs with Matched Funding are currently supported by this prototype.

Example output from running the above command with sns-testing:

✅ Number of Neurons' Fund neurons whose maturity was initially reserved (5) >= number of Neurons' Fund neurons who actually participated in the swap (5).
✅ Number of Neurons' Fund neurons whose maturity was initially reserved (5) >= number of Neurons' Fund neurons who have been refunded (5).
✅ initial_amount_icp_e8s (299700299700) == final_amount_icp_e8s (299700299700) + refunded_amount_icp_e8s (0).
✅ initial_amount_icp_e8s (2997002997) == final_amount_icp_e8s (2997002997) + refunded_amount_icp_e8s (0).
✅ initial_amount_icp_e8s (1000000000000) == final_amount_icp_e8s (1000000000000) + refunded_amount_icp_e8s (0).
✅ initial_amount_icp_e8s (29970029970) == final_amount_icp_e8s (29970029970) + refunded_amount_icp_e8s (0).
✅ initial_amount_icp_e8s (1000000000000) == final_amount_icp_e8s (1000000000000) + refunded_amount_icp_e8s (0).
✅ 15 SNS neurons created for 5 Neurons' Fund participants (3 SNS neurons per basket)
✅ Participation amount of 2997002997 ICP e8s results in 1464343242 SNS token e8s (error = 0.0000000037203250843418525163% = 0.0544783289529907175 SNS e8s)
✅ Participation amount of 29970029970 ICP e8s results in 14643432420 SNS token e8s (error = 0.0000000037203250843418525163% = 0.544783289529907175 SNS e8s)
✅ Participation amount of 299700299700 ICP e8s results in 146434324205 SNS token e8s (error = 0.0000000003058250842009762188% = 0.44783289529907175 SNS e8s)
✅ Participation amount of 1000000000000 ICP e8s results in 488602528432 SNS token e8s (error = 0.0000000001363490602238979123% = 0.66620495574723560 SNS e8s)
✅ Participation amount of 1000000000000 ICP e8s results in 488602528432 SNS token e8s (error = 0.0000000001363490602238979123% = 0.66620495574723560 SNS e8s)

Which other checks should we automate for SNS audits? We would love to hear your thoughts!

4 Likes