Snapshot Voting

Summary so far:

  • Voting should be based off of a custom snapshot strategy using a node operator’s effective RPL stake as it is the best way to to determine if RPL is working for the protocol
  • Voting should apply a quorum to prevent low interest/participation topics from being passed
  • Voting should use Support/Oppose to keep thing simple

During our initial research, for Snapshot voting to work using the effective stake of a node operator, the address connected to Snapshot to perform the vote will have be a registered node and contain an effective stake RPL balance. This means that transactions would need to come from the node wallet. Connecting the node wallet to the likes of Metamask is risky, ideally the CLI should be able to perform these transactions.

For security reasons, voting would need to be actioned via the Smart Node CLI. Voting via the CLI would require users to log into their node and interact with the Smart Node CLI a lot more, which increases their risk exposure.

Delegation

While investigating the great work performed by @peteris, his project influenced us to change our focus from providing voting options in the Smart Node CLI to simply allowing node operator’s to delegate their votes to another address or delegate representative.

Strategies for discussion

The data below uses a sample of node operator addresses from larger node operators to smaller node operators which shows the vote weight for different strategies.

Pure Effective Stake

Captures the node’s effective RPL stake using the pure effective stake numbers.

npm run test --strategy=rocketpool-node-operator-pure

Scores with latest snapshot [
  {
    '0x17Fa597cEc16Ab63A7ca00Fb351eb4B29Ffa6f46': 915782.4728596018,
    '0xca317A4ecCbe0Dd5832dE2A7407e3c03F88b2CdD': 385000.7551590216,
    '0x327260c50634136551bfE4e4eB082281555AAfAE': 65789.4897712646,
    '0x5d8172792a9e649053c07366E3a7C24a37F0C534': 360000,
    '0x701F4dcEAD1049FA01F321d49F6dca525cF4A5A5': 31163.697649235244,
    '0xb8ed9ea221bf33d37360A76DDD52bA7b1E66AA5C': 278324,
    '0xbfaf9BFa09F26EF8104A6d5FF09afdCC9300E5bc': 108069.95232078587,
    '0x174E0b45C03318B0C9bc03573028605B26764931': 17660.13855285447,
    '0x5f4cb66c9b1ed8a4758a059fdb10e0f72c307d8a': 202.94944811433797,
    '0x24609303b67051ef77735e34d671e2a13e3da35d': 845.807411429498,
    '0xe35854cde18a3cc4706134b4850dd861a55b9a30': 1012.4869184922566,
    '0x53938f795ab6c57070aad32905a70a2e5961a887': 257.78352692864814
  }
]

Half Square Root Effective Stake

Captures the node’s effective RPL stake and half square root the result.

npm run test --strategy=rocketpool-node-operator-half-square-root

Scores with latest snapshot [
  {
    '0x17Fa597cEc16Ab63A7ca00Fb351eb4B29Ffa6f46': 478.4826205985965,
    '0xca317A4ecCbe0Dd5832dE2A7407e3c03F88b2CdD': 310.24214541186274,
    '0x327260c50634136551bfE4e4eB082281555AAfAE': 128.24730969036406,
    '0x5d8172792a9e649053c07366E3a7C24a37F0C534': 300,
    '0x701F4dcEAD1049FA01F321d49F6dca525cF4A5A5': 88.26621331125976,
    '0xb8ed9ea221bf33d37360A76DDD52bA7b1E66AA5C': 263.78210705049725,
    '0xbfaf9BFa09F26EF8104A6d5FF09afdCC9300E5bc': 164.369973170882,
    '0x174E0b45C03318B0C9bc03573028605B26764931': 66.44572701245444,
    '0x5f4cb66c9b1ed8a4758a059fdb10e0f72c307d8a': 7.123016357455913,
    '0x24609303b67051ef77735e34d671e2a13e3da35d': 14.541384145169072,
    '0xe35854cde18a3cc4706134b4850dd861a55b9a30': 15.90979979833386,
    '0x53938f795ab6c57070aad32905a70a2e5961a887': 8.027819238881879
  }
]

Cube Root Effective Stake

Captures the node’s effective RPL stake and Math.cbrt() the result.

npm run test --strategy=rocketpool-node-operator-cubed-root

Scores with latest snapshot [
  {
    '0x17Fa597cEc16Ab63A7ca00Fb351eb4B29Ffa6f46': 97.11003465505995,
    '0xca317A4ecCbe0Dd5832dE2A7407e3c03F88b2CdD': 72.74791105169768,
    '0x327260c50634136551bfE4e4eB082281555AAfAE': 40.36938866880965,
    '0x5d8172792a9e649053c07366E3a7C24a37F0C534': 71.13786608980126,
    '0x701F4dcEAD1049FA01F321d49F6dca525cF4A5A5': 31.469003741138312,
    '0xb8ed9ea221bf33d37360A76DDD52bA7b1E66AA5C': 65.2905337712814,
    '0xbfaf9BFa09F26EF8104A6d5FF09afdCC9300E5bc': 47.63231104255781,
    '0x174E0b45C03318B0C9bc03573028605B26764931': 26.04142241031916,
    '0x5f4cb66c9b1ed8a4758a059fdb10e0f72c307d8a': 5.876642769716152,
    '0x24609303b67051ef77735e34d671e2a13e3da35d': 9.457082161279882,
    '0xe35854cde18a3cc4706134b4850dd861a55b9a30': 10.041451005652124,
    '0x53938f795ab6c57070aad32905a70a2e5961a887': 6.364315786097583
  }
]

Where to from here

To keep things simple, ideally we would want to pick one strategy (or iterate on the proposed ones, pull requests are welcome) for the Snapshot Space.

For example, if the community are happy with the Cubed Root Stake strategy, we would apply

  • Cube Root Effective Stake

to the Snapshot space and all proposals would use these strategies for voting.

We are currently working on adding delegation capabilities into the Smart Node Stack.

If you want to perform your own analysis and play with the code, the repo is available here GitHub - rocket-pool/snapshot-strategies at add-rocketpool-node-operator-strategies

4 Likes