TLDR;
This design proposes an extension to the SNS that allows SNSs to define restrictions on who can participate in the SNS swap. Restrictions are defined per SNS and confirmed by the NNS community, similarly to other SNS parameters. The design allows to restrict participation by two mechanisms: 1) asking users to confirm an SNS-specific confirmation text and 2) restricting participation for users whose IP address is from a country listed in an SNS-specific restriction list. A SNS can also choose whether to use both mechanisms, only one of them, or not to use any restriction.
Background & Motivation
When an SNS is launched, it goes through a decentralization swap. In this swap, participants provide ICP and in return receive a share of the SNS DAO’s governance power in the form of SNS neurons. In the current design swaps are open for anyone to participate.
Different projects in the community have requested a feature that allows SNSs to restrict participation in the swap, for example by geographic location. This design is addressing this request.
Design
There are two options for restricting participation:
- Users confirm that they comply with rules defined in a human-readable text.
- The SNS or its frontend automatically restricts access to the swap based on some information about the users. The design proposes to do so by using the user browser’s IP address and restricting IPs that are in a defined list of countries.
Different SNS projects might have different needs. Thus the design allows each SNS to define and configure participation restrictions by 1) a confirmation text that satisfies the SNS’s requirements for participants to validate, and 2) a list of restricted countries where users cannot participate. An SNS can also define neither of the options or both.
Let us look at each of the options in more detail. As everyone can build a frontend for the SNS swap, this design describes what the user flow looks like on a high level and the proposed realization of it on the NNS frontend dapp. Other SNS swap frontends might choose to implement the flow slightly differently.
User Confirmation
When the SNS is initialized, the SNS swap can be configured to specify a confirmation text.
If a swap specifies such a text, then users who want to participate have to confirm the text to be able to participate. This is a flexible way of asking for user confirmation as the text can be set in each SNS individually.
The user flow will look as follows:
- The frontend first retrieves the swap information from the SNS swap canister (or from the aggregator canister that caches this information). Up until now, this included, for example, what kind of participations are valid. With this design, this information will be extended to also include the confirmation text if is set.
- When a user wants to participate in the swap, the frontend displays the retrieved confirmation text to the user and asks them to confirm it. A user can only participate in the swap if they have confirmed the text.
- When a user participates, the frontend includes the confirmation text in the request that it sends to the SNS swap canister. This allows the SNS swap to confirm that the frontend was aware of the (correct) confirmation text before registering the participation.
On the NNS FE dapp this confirmation text is shown in the first step of the participation modal, where the user also selects the account and amount to participate with. The user will have to check a checkbox to proceed to the next step of the participation.
Geo-restriction by IP address
In addition to the above, the SNS swap can be initialized with a list of restricted countries, specifying a set of countries from which participation in the swap is restricted. If such a list is defined, the frontend checks whether a user’s IP address is in one of the countries in the list. If this is the case, the frontend does not display the option of swap participation to the user.
- The frontend first retrieves the swap information from the SNS swap canister. This also includes the restriction list if one is set.
- If there is a restriction list and a user wants to participate in the swap, the frontend determines if the IP address of the user is in one of the restricted countries. This design is agnostic to what service is used by the frontend for mapping IP addresses to countries. It is also possible to use multiple different services.
- Only if the user’s IP is not in any of the restricted countries, the user can continue with the swap participation.
The NNS FE dapp will use two services to retrieve the user location based on the IP address. The services can be combined in different ways, for example choosing one of them randomly or using one service as default and falling back to the second one when the request to the first one fails. This is a more robust design than only one service.
The NNS FE dapp will use the services GeoIPLookup and IP Location in the beginning. Both offer a free service.
The user’s location will only be fetched if the SNS project requires restriction by country and it will not be used for any other purpose. If the list of restricted countries is empty, there won’t be such a check.
Using these existing services allows for a fast implementation. If needed, the NNS can choose to upgrade the NNS frontend dapp to exchange these services with other ones, possibly including web3 services in the future.
How the NNS chooses the restrictions for new SNSs
Both the confirmation text and the list of restricted countries are set when an SNS is initialized. Currently an SNS launch involves two NNS proposals: one for initializing the launch process and one for starting the decentralization swap after the SNS canisters are installed. During the second proposal, NNS voters should check all SNS settings, including those in the swap.
This design does not change this process, rather it adds two more parameters that the NNS voters should check — the confirmation text and list of restricted countries. It is thus the NNS community who decides which restrictions are suitable for a given SNS.
Remark: An upcoming feature will simplify the SNS launch process to only require one proposal. After this, the confirmation text and restriction list will be set and voted on in the new single proposal like all other SNS parameters.
API changes
To help those who integrate with the current SNS swap, let us explicitly list the APIs that will change with this design.
- The list of restricted countries (
restricted_countries
) contains country codes in the ISO 3166-1 alpha-2 standard. - The confirmation text (
confirmation_text
) is a plain text (up to 1,000 characters). - The SNS swap canister’s methods
get_state
andget_init
will serveconfirmation_text
andrestricted_countries
- The SNS swap canister’s method
refresh_buyer_tokens
will have a new optional argument (confirmation_text
). For SNSs that are set up with a confirmation text, this argument must match the expected confirmation text for each successful participation.
Timeline
We expect that this feature requires around 5 weeks of engineering work.
As restricting swap participation has been directly requested by projects preparing for an SNS launch in the near future, the priority of this feature is considered high. Nevertheless, work on other SNS features, such as the “one proposal solution” continue in parallel.