Possible New Snapshot Strategy for Social Proposals

Update 3/21/22: This strategy is now live on Snapshot! ERC-20 Votes With Override

As well as a separate report tool: snapshot-override-report

==================================================================

I wrote a new Snapshot strategy (yet to be merged): erc20-votes-with-override

It works the same way as the existing erc20-votes strategy we use, except that it also allows individuals who delegated to someone else to still vote individually if they want!

So if you see your delegate vote differently than you want to, you can override that vote by individually voting yourself on the proposal. Or, if your delegate doesn’t vote at all, you can still vote individually on a proposal. You must still actually be delegated though, if your account is not delegated then your local token balance will not count towards your voting power, same as today.

Using a strategy like this could improve voter participation. Maybe some people would like to vote on a single issue, but don’t want to spend the gas/effort to delegate to themselves, vote, and then delegate back. And since it’s on Snapshot, it’s all gas-free for everyone.

This might only make sense for social (off-chain only) proposals because of the possible discrepancy in off-chain Snapshot versus actual on-chain votes. But, it sounds like a strategy like this could still help out a lot on social proposals like EP 6.1.

Appreciate any thoughts you have, and your code review too!

Check it out here: [erc20-votes-with-override] Adding ERC-20 votes with override strategy. by serenae-fansubs · Pull Request #448 · snapshot-labs/snapshot-strategies · GitHub

7 Likes

Would there be any way to get a count of ‘override votes’, if only via a graphql API? That way we could use something like this on executable proposals, and determine at the end how much the outcome was affected by people voting differently from their delegates.

1 Like

I believe that should be possible yes. If we query the Snapshot API to get the list of voters on a proposal, then we only need to determine which of those voters had delegated to someone else at that block height. A multicall to delegates, then filter where the delegator != delegate, and those would be the override votes. Or, getVotes where the votes = 0 would also mean that account was an override vote.

I’m assuming that would only be possible once CCIP-read support is there right, so we can query that Snapshot data?

2 Likes

I wasn’t thinking of doing it onchain, just of surfacing this after a vote so we know how much the result was affected by overrides.

1 Like

Ahh gotcha, yep that’s a good idea :+1:

I think this is an excellent solution for social proposals on Snapshot. Makes sense and if there is no on-chain component for the vote, I don’t see any downsides. Only increases individual users’ rights, thanks for the work on this @serenae!

3 Likes

Really great idea! The inability for pre-delegated voters to switch their vote after a snapshot starts was one of the issues people raised during/after EP6.1. I don’t really see any downsides to allowing something like this.

Semi-related, but is it possible to hold a “secret” vote, where the voting outcome (and voting records) aren’t released until after the vote passes? There’s a lot of research into the pros and cons of an open vs closed ballot voting system, but curious if anyone has given it any thought as it relates to ENS DAO voting process.

3 Likes

I could be wrong, but on Snapshot anyway, I don’t think a secret vote system is possible at the moment, the choices of each voter are recorded transparently. Sounds interesting though, I wonder if this is something Snapshot is considering for the future…

1 Like

You are right, it is not possible to vote anonymously on Snapshot so far

Update: This strategy is now live on Snapshot!

Here’s the actual code, merged into the Snapshot Labs repository: ERC-20 Votes With Override

I included an in-depth readme on that page as well explaining the strategy, and how to handle Snapshot delegations too.

I have also written a tool on the side that (per @nick.eth’s suggestion) will analyze a proposal using this strategy, and print a report on which delegators overrode their delegates, and how much that affected the overall outcome (with deltas for each proposal choice). It can print it out in human-readable format on the command line, or in JSON format if you want to hook it into something else. Check that out here: snapshot-override-report

Finally, I have a proposal up on my space to demonstrate the strategy: :cat: or :dog:?

Go vote on it, both delegates and delegators!

4 Likes

Now the question is, do we need to take a DAO-wide vote to adopt this method of voting?

Alright, one day later, here are the current results:

And here’s the override report:

Proposal Cats or Dogs
=====================

Overriding Delegators
=====================
355.9 0xb5f0a2d8fd54a0cdd5f3e9c26874022ce85187e9 (meringue.eth)
989.2 0xdb67213ec151a91fba968ea90f2af485f3fca8c1 (tarnover.eth)
25.29 0xaf01943aa20acf34da7e7ddf56f6c8d40afd1b11
940.6 0xe0a97c2634c0b1d2530b2f92e46697460692ca0c (physikal.eth)
368.9 0x865c723e8ed40e6490b606d27c85ce1031e62c0c (calibrium.eth)
125.6 0xdc8d9112242a91da4cbada87e05dbc20fd802783 (mwegehaupt.eth)
21.03 0xa26b719d2057b6b2e8b44554c02e77de46eb660f (policywonk.eth)
51.14 0x29823c339f7a9bfd536b07bb6204871a2c6efc7f

Overridden Vote Deltas
======================

Choice "🐱" (1): -1837.9632805505278
Overriding Delegators:
    25.29 0xaf01943aa20acf34da7e7ddf56f6c8d40afd1b11

Choice "🐶" (2): 2827.157667851258
Overriding Delegators:
    355.9 0xb5f0a2d8fd54a0cdd5f3e9c26874022ce85187e9 (meringue.eth)
    989.2 0xdb67213ec151a91fba968ea90f2af485f3fca8c1 (tarnover.eth)
    940.6 0xe0a97c2634c0b1d2530b2f92e46697460692ca0c (physikal.eth)
    368.9 0x865c723e8ed40e6490b606d27c85ce1031e62c0c (calibrium.eth)
    125.6 0xdc8d9112242a91da4cbada87e05dbc20fd802783 (mwegehaupt.eth)
    21.03 0xa26b719d2057b6b2e8b44554c02e77de46eb660f (policywonk.eth)
    51.14 0x29823c339f7a9bfd536b07bb6204871a2c6efc7f

Nick voted :cat: and his total delegated voting power for that snapshot is ~240291. However, you can see that multiple delegators of his chose :dog: instead, so his total weight on the proposal is now down to ~238848.

Example: physikal.eth is delegated to nick.eth, so he has 0 voting power and is normally unable to vote on Snapshot proposals. But on this proposal he overrode nick.eth with ~941 votes.

The current report also highlights a couple of other interesting cases.

For instance, tarnover.eth is delegated to imtoken.eth. And even though imtoken.eth has not voted on the proposal, tarnover.eth is still able to vote! If imtoken.eth were to vote later on the proposal, then at that point the ~989 votes from tarnover.eth would be deducted from imtoken.eth’s delegated voting power. That is also why the deltas in the report don’t add up to zero, they actually add up to ~989! In this case, tarnover.eth’s vote is not overriding :cat:, it’s overriding the choice of “not voting at all”.

Also, coltron.eth voted :dog: but another account overrode him and voted :cat:. If you add up all the other :dog: overrides besides tarnover.eth, it comes to ~1863. But the total delta on :cat: is only -1838, and that’s because that other account overrode coltron.eth and voted for :cat: with 25 votes. And again, even though coltron.eth’s total delegated voting power is 339, you can see that on the Snapshot proposal he only has 314 votes because of the override.

There are lots of other interesting cases that can occur too. Like even if you don’t own any $ENS and have never delegated your account, you can still vote if someone else delegates to you (and that is true of the regular erc20-votes strategy too). You can also delegate your own tokens to someone else, and another person can delegate their tokens to you, creating a sort of daisy-chain of delegations. When you vote with this strategy, you always have access to your own local token balance (as long as you have them delegated). Then you’ll also have any additional delegated voting power, minus the balances of any delegators that have also voted.

Hope that all makes sense, let me know if you have any questions!

3 Likes

In case you’re interested here’s also the JSON version of the report:

{
  "overrides": {
    "0xb5f0a2d8fd54a0cdd5f3e9c26874022ce85187e9": {
      "choice": 2,
      "balance": 355.9046315292889,
      "delegate": "0xb8c2c29ee19d8307cb7255e1cd9cbde883a267d5",
      "delegateChoice": 1
    },
    "0xdb67213ec151a91fba968ea90f2af485f3fca8c1": {
      "choice": 2,
      "balance": 989.19438730073,
      "delegate": "0x4e88f436422075c1417357bf957764c127b2cc93",
      "delegateChoice": null
    },
    "0xaf01943aa20acf34da7e7ddf56f6c8d40afd1b11": {
      "choice": 1,
      "balance": 25.28513361,
      "delegate": "0x1d5460f896521ad685ea4c3f2c679ec0b6806359",
      "delegateChoice": 2
    },
    "0xe0a97c2634c0b1d2530b2f92e46697460692ca0c": {
      "choice": 2,
      "balance": 940.6246195767995,
      "delegate": "0xb8c2c29ee19d8307cb7255e1cd9cbde883a267d5",
      "delegateChoice": 1
    },
    "0x865c723e8ed40e6490b606d27c85ce1031e62c0c": {
      "choice": 2,
      "balance": 368.9309805551006,
      "delegate": "0x29a82e07b96c405ac99a8023f767d2971546de70",
      "delegateChoice": 1
    },
    "0xdc8d9112242a91da4cbada87e05dbc20fd802783": {
      "choice": 2,
      "balance": 125.62230681923658,
      "delegate": "0xb8c2c29ee19d8307cb7255e1cd9cbde883a267d5",
      "delegateChoice": 1
    },
    "0xa26b719d2057b6b2e8b44554c02e77de46eb660f": {
      "choice": 2,
      "balance": 21.027949222167088,
      "delegate": "0xb8c2c29ee19d8307cb7255e1cd9cbde883a267d5",
      "delegateChoice": 1
    },
    "0x29823c339f7a9bfd536b07bb6204871a2c6efc7f": {
      "choice": 2,
      "balance": 51.13792645793504,
      "delegate": "0x29a82e07b96c405ac99a8023f767d2971546de70",
      "delegateChoice": 1
    }
  },
  "deltas": {
    "1": {
      "name": "🐱",
      "delta": -1837.9632805505278,
      "delegates": [
        "0xb8c2c29ee19d8307cb7255e1cd9cbde883a267d5",
        "0x29a82e07b96c405ac99a8023f767d2971546de70"
      ],
      "delegators": [
        "0xaf01943aa20acf34da7e7ddf56f6c8d40afd1b11"
      ]
    },
    "2": {
      "name": "🐶",
      "delta": 2827.157667851258,
      "delegates": [
        "0x1d5460f896521ad685ea4c3f2c679ec0b6806359"
      ],
      "delegators": [
        "0xb5f0a2d8fd54a0cdd5f3e9c26874022ce85187e9",
        "0xdb67213ec151a91fba968ea90f2af485f3fca8c1",
        "0xe0a97c2634c0b1d2530b2f92e46697460692ca0c",
        "0x865c723e8ed40e6490b606d27c85ce1031e62c0c",
        "0xdc8d9112242a91da4cbada87e05dbc20fd802783",
        "0xa26b719d2057b6b2e8b44554c02e77de46eb660f",
        "0x29823c339f7a9bfd536b07bb6204871a2c6efc7f"
      ]
    }
  },
  "primaryNames": {
    "0xb5f0a2d8fd54a0cdd5f3e9c26874022ce85187e9": "meringue.eth",
    "0xb8c2c29ee19d8307cb7255e1cd9cbde883a267d5": "nick.eth",
    "0xdb67213ec151a91fba968ea90f2af485f3fca8c1": "tarnover.eth",
    "0x4e88f436422075c1417357bf957764c127b2cc93": "imtoken.eth",
    "0x1d5460f896521ad685ea4c3f2c679ec0b6806359": "coltron.eth",
    "0xe0a97c2634c0b1d2530b2f92e46697460692ca0c": "physikal.eth",
    "0x865c723e8ed40e6490b606d27c85ce1031e62c0c": "calibrium.eth",
    "0x29a82e07b96c405ac99a8023f767d2971546de70": "serenae.eth",
    "0xdc8d9112242a91da4cbada87e05dbc20fd802783": "mwegehaupt.eth",
    "0xa26b719d2057b6b2e8b44554c02e77de46eb660f": "policywonk.eth"
  }
}

There’s a bit more information in the JSON version like for each delegator you can see which delegate they overrode and what the choice of that delegate was. And for each choice delta you can also see which delegates were overridden. I omitted that from the human-readable format to be a little more succinct.

2 Likes