Potential Snapshot Strategies for SongADAO

---------Warning: Technical Thread-------
As I’m doing some research on Snapshot.org, I realised while using a basic erc-721 voting strategy (where 1 SAD NFT = 1 vote) may be okay for Listeners’ voting, Voters’ voting is a lot more complicated.
You can find basic definitions of Listener & Voter here.

Since for Voters, you need to own at least 1 SAD NFT AND be verified with BrightID, technically we can use the existing BrightID strategy (where 1 verified BrightID = 1 vote) and a modified version of the basic erc721 strategy (originally where 1 NFT = 1 vote, modified to 1+ NFT = 1 vote).

I did more research in the process of writing this thread, turns out we can use hold-tokens strategy for said “modified erc721 strategy”, here’s the strategy overview:

And here’s an example, where any balance of SAD nft greater than 1 is considered a vote.

The first address is mine (holding 3 SAD nfts), second is @jonathanmann 's address (holding obviously 1+ SAD nfts), third address is just a random test address.

Correction: The field “minBalance” should be set to 0 for 1+ NFT holdings. (the check is tokenBalance > minBalance)

That mostly concludes it, but I still need someone with more smart contract / BrightID experience to help me on the BrightID strategy, since it seems like it involves quite a bit more technical stuff.


Also, combining strategies is also not tested, not sure if there’s an option where 1 vote from BrightID AND 1 vote from NFT becomes 1 final vote.

1 Like

Can you lay out the general idea you had about integrating BrightID?

So there’s currently a strategy on Snapshot that supports BrightID verification (see BrightID Strategy).
You can find the technical details here.
But with my limited understanding of BrightID I can’t really tell how the contract works and how we may deploy one, since it requires two parameters:

  • context bytes32
    BrightID context used for verifying users.
  • verifier address
    BrightID verifier address that signs BrightID verifications.

We may want to contact someone who works at BrightID to figure this part out, we could do some test deployments on Rinkeby.

Edit: I’ll be digging through the contract source code in the meantime and report back anything I may find useful here.

In my previous comment, I found a working BrightID registry smart contract.

After some in-depth research on how a BrightID node signs verification data, here’s a working smart contract that I deployed on Rinkeby Testnet.

This contract requires two parameters for its constructer:

  • context bytes32
    BrightID context used for verifying users.
  • verifier address
    BrightID verifier address that signs BrightID verifications.

For context, all we need is a valid (registered) BrightID app (every app gets a unique context whenever they register to become an official BrightID app), fortunately, Noble is a registered BrightID app. So context is “Noble” (case sensitive).

For verifier address, it depends on which address the BrightID node uses when signing the verification data, in our case, we’re using the Official BrightID node. So it’s 0xb1d71F62bEe34E9Fc349234C201090c33BCdF6DB.

Now the contract is deployed, we can add new verification data using the register method.
It takes six parameters:

  • _context
    The same context as above, which in our case is “Noble” in byte32, aka 0x4e6f626c65000000000000000000000000000000000000000000000000000000
  • _addrs
    Which address the following verification data is for, in this text example I’ll simply use my own eth address, since I wanna add my verification data into the contract.
  • _timestamp
  • _v
  • _r
  • _s
    All four of these parameters are part of the verification data.

To get _timestamp, _v, _r and _s, all we need to do is calling a simple API on the official BrightID node:

Parameters for this API call are as follows:

  • app
    The app context, in our case it’s “Noble”
  • contextId
    Noble uses eth address as its users’ contextId, so I’ll just insert my eth address here.
  • signed and timestamp
    Controls how the data is returned, we’ll put in eth and seconds here, these will be static.

And behold! We have our four parameters for the contract call: _timestamp, _v, _r and _s

Here’s my test contract call.

And the contract now knows that I’m verified!

Using the snapshot strategy shows the same result:

The second eth address is mine, showing 1 vote.

Continued digging into the membership strategy (for combining both holds-tokens and brightid strategies), I’ve come up with a ULTIMATE strategy that in my testing, works flawlessly with our requirements. Allow me to demonstrate.

The membership strategy allows for membership and voting power to be controlled by seperate strategies, in our case, membership would require getting verified with BrightID, while voting power is determined by the holdings of SAD nfts (1+ holdings = 1 vote).

Here’s the full solution:

Let me explain this monstrosity piece by piece:

First we have membershipStrategy, since interacting with contracts to add your BrightID verification data would require submitting a transaction (see above research about BrightID strategy), which on mainnet would still cost $, in actual deployment we may deploy the contract onto a testnet like Rinkeby.

There’s also a better option, as suggested by the founder of BrightID Adam Stallard: IDchain.

If you’re not familiar with IDchain, think of it as polygon, but for BrightID. Verified users can claim gas tokens for free on IDchain, which could be used for interacting with contracts to add your BrightID verification data, completely eliminating the cost for the users in the process.
That’s why the membershipStrategy is a multichain strategy, where snapshot will execute the BrightID strategy on Rinkeby / IDchain.

But there’s also a problem, the multichain strategy uses subgraphs/custom APIs for fetching the block height on other networks, there is a subgraph for Rinkeby, but not for IDchain (at least I couldn’t find one).

Then comes the votingPowerStrategy, which is rather straight forward, details were already explained in this thread.

And wola! We have a complex strategy for treasury voting! I think we do.



Matt Condon is going to take a look and hopefully give some feedback here.

1 Like

IDChain does have a subgraph.

1 Like