Skip to content

Commit

Permalink
[delegate-registry-v2] Add the delegate registry v2 startegy (snapsho…
Browse files Browse the repository at this point in the history
…t-labs#1205)

* Add delegate-registry strategy

* Rename strategy

* Make it possible to add a cutom backend URL

* Update index.ts

* Update index.ts

* Update src/strategies/delegate-registry-v2/examples.json

* Update src/strategies/delegate-registry-v2/examples.json

* Fix author

* Add doc

* Add the `strategy-zero-gated` validation strategy

* Update src/strategies/delegate-registry-v2/index.ts

Co-authored-by: Chaitanya <[email protected]>

* Add strategies into the delegation-registry-v2 params

* Add todo

* Remove the zero-gated-strategy

* Full implementation with strategies wrapped in the strategy param

* [Delegation Registry 2] Set the maximum number of trategise to 8

---------

Co-authored-by: Chaitanya <[email protected]>
  • Loading branch information
asgeir-s and ChaituVR authored Oct 7, 2023
1 parent ec1cc15 commit ccfecb7
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/strategies/delegate-registry-v2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Delegate Registry v2

A general-purpose delegate registry.

In order to utilize this, the 'Strategy Zero Gated' validation strategy is necessary. This is to prevent the delegator from also using the votes that have been delegated.

This strategy:

- returns a score of 0 for addresses that are delegating to other addresses (PS: addresses that return a score of 0 should not be allowed to vote),
- returns a score greater than 0 for addresses that are delegated to and are not delegating (PS: only the amount delegated to the address is returned; this needs to be merged with the scores from other strategies in the space to get the addresses total score),
- returns nothing for addresses that are not delegating to other addresses or delegated to.
45 changes: 45 additions & 0 deletions src/strategies/delegate-registry-v2/examples.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
[
{
"name": "Example query",
"strategy": {
"name": "delegate-registry-v2",
"params": {
"backendUrl": "https://delegate-registry-backend.vercel.app",
"strategies": [
{
"name": "erc20-balance-of",
"params": {
"address": "0x6b175474e89094c44da98b954eedeac495271d0f",
"symbol": "DAI",
"decimals": 18
}
},
{
"name": "gno",
"params": {
"symbol": "GNO",
"decimals": 18,
"SUBGRAPH_URL": "https://api.thegraph.com/subgraphs/id/QmduKVUHCPjR5tmNEgooXHBMGKqDJWrUPdp6dEMeJM6Kqa"
}
}
]
}
},
"network": "1",
"addresses": [
"0x000e37ed92d86a7667f520c53b73b01ff5c206eb",
"0x000dbf2733da51135c1b21c8ef71a3d474383f0d",
"0xeF8305E140ac520225DAf050e2f71d5fBcC543e7",
"0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11",
"0xeF8305E140ac520225DAf050e2f71d5fBcC543e7",
"0x1E1A51E25f2816335cA436D65e9Af7694BE232ad",
"0x1F717Ce8ff07597ee7c408b5623dF40AaAf1787C",
"0x1c7a9275F2BD5a260A9c31069F77d53473b8ae2e",
"0x1d5E65a087eBc3d03a294412E46CE5D6882969f4",
"0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11",
"0xeF8305E140ac520225DAf050e2f71d5fBcC543e7",
"0x1E1A51E25f2816335cA436D65e9Af7694BE232ad"
],
"snapshot": 17463998
}
]
109 changes: 109 additions & 0 deletions src/strategies/delegate-registry-v2/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import fetch from 'cross-fetch';
import { StaticJsonRpcProvider } from '@ethersproject/providers';
import { Strategy } from '@snapshot-labs/snapshot.js/dist/voting/types';
import { getScoresDirect } from '../../utils';
import { getAddress } from '@ethersproject/address';

export const author = 'gnosis';
export const version = '0.0.1';

const DEFAULT_BACKEND_URL = 'https://delegate-registry-backend.vercel.app';

type Params = {
backendUrl: string;
strategies: Strategy[];
};

/*
This strategy:
- returns a score of 0 for addresses that are delegating to other addresses (PS: addresses that returns a score of 0, should not be allowed to vote),
- returns a score greater than 0, for addresses that are delegated to (PS: only the amount delegated to the address us returned, this needs to be merged with the scores from other strategies in the space),
- returns nothing for addresses that are not delegating to other addresses or delegated to.
*/
export async function strategy(
space: string,
network: string,
provider: StaticJsonRpcProvider,
addresses: string[],
options: Params = { backendUrl: DEFAULT_BACKEND_URL, strategies: [] },
snapshot: string | number
): Promise<Record<string, number>> {
const blockTag = typeof snapshot === 'number' ? snapshot : 'latest';

if (options.strategies.length > 8)
throw new Error('Maximum 8 strategies allowed');

const response = await fetch(
`${options.backendUrl}/api/${space}/snapshot/${blockTag}/strategy-formatted-vote-weights`,
{
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
addresses: addresses,
strategies: options.strategies
})
}
);

const delegationScores = (await response.json()) as [
address: string,
voteWeight: string
][];

// gets an array of all addresses that are in the addresses array, but not present in the response
const addressesNotDelegatingOrDelegatedTo = addresses.filter(
(address) => !delegationScores.find((score) => score[0] === address)
);

const addressesDelegating = delegationScores.filter(
(score) => score[1] === '0'
);

const addressesDelegatedTo = delegationScores.filter(
(score) => score[1] !== '0'
);

const addressesOwnScore = await getScoresDirect(
space,
options.strategies,
network,
provider,
[
...addressesNotDelegatingOrDelegatedTo,
...addressesDelegatedTo.map(([address]) => address)
],
snapshot
);

const delegationObject = addressesDelegatedTo.reduce(
(pre, [address, score]) => {
pre[getAddress(address)] = score;
return pre;
},
{}
);

const addressesScores = addressesOwnScore.reduce((pre, address) => {
const addressKeys = Object.keys(address);
const addressValues = Object.values(address);
addressKeys.forEach((key, index) => {
if (pre.hasOwnProperty(key)) {
pre[getAddress(key)] = pre[getAddress(key)] + addressValues[index];
} else {
pre[getAddress(key)] = addressValues[index];
}
});
return pre;
}, delegationObject);

// add a 0 score for all addressesDelegating
const finalScores = addressesDelegating.reduce((pre, [address]) => {
pre[getAddress(address)] = 0;
return pre;
}, addressesScores);

return finalScores;
}
2 changes: 2 additions & 0 deletions src/strategies/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ import * as erc721CollateralHeld from './erc721-collateral-held';
import * as starlayVeBalanceOfLockerId from './starlay-ve-balance-of-locker-id';
import * as winrStaking from './winr-staking';
import * as spaceid from './spaceid';
import * as delegateRegistryV2 from './delegate-registry-v2';
import * as hatsProtocolSingleVotePerOrg from './hats-protocol-single-vote-per-org';
import * as karmaDiscordRoles from './karma-discord-roles';
import * as seedifyHoldStakingFarming from './seedify-cumulative-voting-power-hodl-staking-farming';
Expand Down Expand Up @@ -925,6 +926,7 @@ const strategies = {
'starlay-ve-balance-of-locker-id': starlayVeBalanceOfLockerId,
'winr-staking': winrStaking,
spaceid,
'delegate-registry-v2': delegateRegistryV2,
'hats-protocol-single-vote-per-org': hatsProtocolSingleVotePerOrg,
'karma-discord-roles': karmaDiscordRoles,
'seedify-cumulative-voting-power-hodl-staking-farming':
Expand Down

0 comments on commit ccfecb7

Please sign in to comment.