Restriction for SNS swap participation - Design


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.


There are two options for restricting participation:

  1. Users confirm that they comply with rules defined in a human-readable text.
  2. 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 and get_init will serve confirmation_text and restricted_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.


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.


I would like a better understanding of how the SNS will work.

I have a neuron with staked tokens in the IC dashboard and all the Maturity is automatically staked.

I assume I don’t use any of my staked neurons in the IC for staking on the SNS and will have to provide new ICP tokens within my token account creating a new neuron or using main to stake these new ICP tokens for any project that I am interested in?

Then not only will I have to be actively voting on the IC but now will have to actively vote on all projects I have staked in that may or may not have, following, setup and I assume I will be able to do this from the IC dashboard.

Or will I have to go to other dashboards to do the voting?

Have I missed something?

What I would like to see is a Market Cap type page for the new project to fill in on their project.

Who Are the Founder
What Makes it Unique

And so on……

I was disappointed to see a project last week make a novice mistake of the use of usernames. After 4 decades it seems that we have not been able to perfect a simple thing like a username.

This is what I call over qualified students with no understanding of the past, with claims of having high and many degrees but no experience, repeating the past mistakes or as I call them, stupids.

How embarrassing and a stain to that project.

Will there be efforts to black list VPNs? Otherwise we end up with something like:


Why not use elective kyc?

This puts the kyc or geolocation in the hands of the SNS launchers.

Hand wavy gates aren’t going to stand up in court.

(Edit: I’m not saying we shouldn’t do ip filtering as well. I’m also speaking from specific experience here with OGY and regulators in Switzerland where we were advised to have significant KYC for our public sale. It wasn’t fun or easy but what we were told was a minimum requirement for the safety of those creating the token.)


Now we’re starting to touch on the main issues with SNSes that @lastmjs, @skilesare, and many other prominent members of the community raised forcefully last year with the SNS being both a securities nightmare and being directly linked to the NNS.

If just one of the SNS projects decides not to Geoblock the U.S. and the SEC clamps down, then any SNS or NNS domains could be blocked in the U.S. as a result.

It would be much better if each SNS ran through its own independent domain or was more decoupled from the NNS, but this currently isn’t the case.

The individual SNSes have no incentive to geoblock (as long as not US based, they want as much financial participation as possible), so the brunt of the blowback will fall on the NNS and the greater IC.

Many of the large projects and investment on the IC is U.S. based, so I hope for the IC’s sake that DFINITY doesn’t rush this and considers all worst case scenarios before proceeding (like they did with ckBTC).

One additional question. How does this geoblocking affect the participants in the community fund, and their SNS investments?


I assume I don’t use any of my staked neurons in the IC for staking on the SNS and will have to provide new ICP tokens within my token account creating a new neuron or using main to stake these new ICP tokens for any project that I am interested in?

There are two ways how to participate:

  1. Directly participating in an SNS decentralization swap. For this you need ICP with which you can participate in the swap. You will get SNS tokens locked in SNS neurons in return when the swap was successful. There are different frontends which allow you to have an ICP wallet and participate in the swaps. One example is the NNS frontend dapp.
  2. If you would like to participate with your staked ICP, you can do so by handing over your funds to the Community Fund. You can do so for example on the NNS frontend dapp. For tokens in this fund, the NNS community decides in which SNS swap they participate.

You should be able to find more info on SNSs here

Then not only will I have to be actively voting on the IC but now will have to actively vote on all projects I have staked in that may or may not have, following, setup

Right, you then have the opportunity to vote in all SNS DAOs where you own a certain stake of the DAO’s token.

and I assume I will be able to do this from the IC dashboard.
Or will I have to go to other dashboards to do the voting?

I am not sure here what you refer to with IC dashboard. As far as I know you cannot vote on this IC dashboard.
The SNS DAO framework is build in such a way that anyone can provide a “frontend” for SNSs, i.e., an interface through wich users can interact with the SNS. Some dapps also choose to build the governance of the DAO into the frontend of the dapp. For example, in OpenChat you can vote within the chat dapp on proposals from the OpenChat SNS and other SNSs.
So it could be that for different SNS DAOs there are different options.
However, there are some frontends or interfaces that will allow to vote on all SNSs. All the SNS DAOs will for example be visible in the NNS frontend dapp and voting will be supported there going forward.

Thanks for the feedback and ideas!
In this feature the idea is to focus on the above design described and not black list VPNs. But it could be something to look into later.
I also think there are other interesting options. In the context of airdrops etc, it has also been discussed that one could allow projects to pre-approve certain principals or their attributes (be it users from dapps, NNS neuron holders, etc) to get airdrops or to have early access to the sale or other things.
This could be generalised to requiring some features from all SNS swap participants and also to leave that up to the respective projects…
I think a lot of interesting ideas and potential use cases are still to be explored!

How does this geoblocking affect the participants in the community fund, and their SNS investments?

The community fund neurons are owned by the NNS and as such there is no geo-restrictions applied to them.

@lara If I can opt-in or out of the community fund at any time, then the NNS may be the temporary and programmatic custodian of these neurons, but I am still the “owner”.

This weakens the legal argument that geo-blocking doesn’t apply to the community fund. Since the NNS facilitates the community fund, this then puts the NNS at risk of being blocked by a governmental/regulatory agency.

Quick update. The SNS API changes for this feature are scheduled for next week. Here’s a summary of these changes:

  • SNS swap canister’s Init type (available via swap.get_init().init) will have two new optional fields:

    • confirmation_text — expected confirmation text that the swap participants must accept.
    • restricted_countries — list of ISO alpha2 codes of countries, the users from which shouldn’t participate in the swap.
  • The swap.refresh_buyer_tokens function’s request payload will have a new optional field (also called confirmation_text).

    • For an SNS that will have some confirmation text for the swap participants, a frontend should instantiate the confirmation_text argument of refresh_buyer_tokens with the confirmation text that had been displayed to the participant and the participant has accepted.
  • The SNS-CLI tool will support both confirmation_text and restricted_countries as optional fields in the sns_init.yaml file.

    • Developers will find more details by running sns-cli init-config-file new with the upcoming version of sns-cli.

Please let us know if you have further questions!


Hi all,
just wanted to provide the update that this feature has largely been released. The only thing that remains is the SNS-CLI tool which will follow shortly.
I want to point out again that if you are building a frontend for the SNS swap, then you might need to update your dapp to be compatible with upcoming swaps if they choose to use this new settings.


Last update: this feature is fully completed now!