Skip to content

Commit

Permalink
Merge branch 'snapshot-labs:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
aahna-ashina authored Nov 12, 2023
2 parents 5875405 + b855dfd commit d9b5eeb
Show file tree
Hide file tree
Showing 86 changed files with 3,802 additions and 804 deletions.
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SNAPSHOT_API_STRATEGY_SALT=12345 # Salt for the snapshot API strategy to send a key in header (optional)
PASSPORT_API_KEY= # API key for the passport API (optional for other strategies)
PASSPORT_SCORER_ID= # Scorer ID for the passport API (optional for other strategies)
4 changes: 2 additions & 2 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ updates:
schedule:
interval: "daily"
allow:
# Allow updates for snapshot.js only
- dependency-name: "@snapshot-labs/snapshot.js"
# Allow updates for @snapshot-labs/* only
- dependency-name: "@snapshot-labs/*"
1 change: 0 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,3 @@ jobs:
run: |
yarn install --frozen-lockfile
yarn build
yarn lint
28 changes: 28 additions & 0 deletions .github/workflows/fix-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Fix lint
on:
workflow_dispatch:
schedule:
- cron: 0 10 * * 0

jobs:
fix-lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: '16.10.x'
- name: Run lint script
run: |
yarn install --frozen-lockfile
yarn lint:fix
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
commit-message: Automated lint
title: Automated lint
body: |
- Changes from lint script
Auto-generated by Github Actions
branch: automated-lint
28 changes: 4 additions & 24 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -1,28 +1,8 @@
name: Lint
on:
workflow_dispatch:
schedule:
- cron: 0 10 * * 0

on: [push]

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: '16.10.x'
- name: Run lint script
run: |
yarn install --frozen-lockfile
yarn lint
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
commit-message: Automated lint
title: Automated lint
body: |
- Changes from lint script
Auto-generated by Github Actions
branch: automated-lint
uses: snapshot-labs/actions/.github/workflows/lint.yml@main
secrets: inherit
7 changes: 7 additions & 0 deletions .github/workflows/validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ jobs:

steps:
- uses: actions/checkout@v2.3.4

- name: Create env file
run: |
touch .env
echo PASSPORT_API_KEY=${{ secrets.PASSPORT_API_KEY }} >> .env
echo PASSPORT_SCORER_ID=${{ secrets.PASSPORT_SCORER_ID }} >> .env
- name: yarn install and test validation
run: |
yarn install --frozen-lockfile
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
"prepublishOnly": "npm run build",
"postinstall": "npm run build",
"postbuild": "copyfiles -u 1 \"src/**/*.md\" dist/ && copyfiles -u 1 \"src/**/*.json\" dist/",
"lint": "eslint src/ test/ --ext .ts,.json --fix"
"typecheck": "tsc --noEmit",
"lint": "eslint src/ test/ --ext .ts,.json",
"lint:fix": "yarn lint --fix"
},
"dependencies": {
"@ethersproject/abi": "^5.6.4",
Expand All @@ -34,7 +36,7 @@
"@ethersproject/strings": "^5.6.1",
"@ethersproject/units": "^5.6.1",
"@ethersproject/wallet": "^5.6.2",
"@snapshot-labs/snapshot.js": "^0.6.2",
"@snapshot-labs/snapshot.js": "^0.8.3",
"@spruceid/didkit-wasm-node": "^0.2.1",
"@uniswap/sdk-core": "^3.0.1",
"@uniswap/v3-sdk": "^3.9.0",
Expand Down
9 changes: 4 additions & 5 deletions src/strategies/aave-governance-power/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,23 @@ export async function strategy(
options,
snapshot
) {
const blockTag =
typeof snapshot === 'number'
? snapshot
: await provider.getBlockNumber(snapshot);
const blockTag = typeof snapshot === 'number' ? snapshot : 'latest';

// Early return 0 voting power if governanceStrategy or powerType is not correctly set
if (!options.governanceStrategy || !powerTypesToMethod[options.powerType]) {
return Object.fromEntries(addresses.map((address) => [address, '0']));
}

const blockNumber =
blockTag === 'latest' ? await provider.getBlockNumber(network) : blockTag;
const response: BigNumber[] = await multicall(
network,
provider,
abi,
addresses.map((address: any) => [
options.governanceStrategy,
powerTypesToMethod[options.powerType],
[address.toLowerCase(), blockTag]
[address.toLowerCase(), blockNumber]
]),
{ blockTag }
);
Expand Down
2 changes: 1 addition & 1 deletion src/strategies/aave-governance-power/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"enum": ["vote", "proposition"]
},
"decimals": {
"type": "integer",
"type": "number",
"title": "Decimals",
"examples": ["e.g. 18"],
"minimum": 0,
Expand Down
7 changes: 6 additions & 1 deletion src/strategies/api-v2/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { getAddress } from '@ethersproject/address';
import fetch from 'cross-fetch';
import { formatUnits } from '@ethersproject/units';
import { sha256 } from '../../utils';

export const author = 'snapshot-labs';
export const version = '0.1.0';
Expand Down Expand Up @@ -37,12 +38,16 @@ export async function strategy(
};
body = JSON.stringify(requestBody);
}
const snapshotSecretHeader = sha256(
`${url}${process.env.SNAPSHOT_API_STRATEGY_SALT}`
);

const response = await fetch(url, {
method,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
'Content-Type': 'application/json',
'X-Snapshot-API-Strategy-Secret': snapshotSecretHeader
},
body
});
Expand Down
2 changes: 1 addition & 1 deletion src/strategies/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Voting strategy using a REST API endpoint. Number of votes depends on the return of the API endpoint.

## Cosntructing the API URL
## Constructing the API URL
This strategy will create an `api_url` based on the supplied parameters and the Proposal&Space settings.

`api_url` is constructed as such:
Expand Down
4 changes: 2 additions & 2 deletions src/strategies/brightid/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ This strategy returns a score of 1 for voters verified in a BrightID user regist

Public registries are maintained by BrightID and can be used if a DAO has no interest on setting one up themselves.

Here is an example of parameters for using an public registry contract:
Note that when using an public registry, the network is always set to IDChain(74).
Here is an example of parameters for using a public registry contract:
Note that when using a public registry, the network is always set to IDChain(74).

```json
{
Expand Down
4 changes: 2 additions & 2 deletions src/strategies/ctoken/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Contract call strategy

Allows for calculating the voting weight of cToken holders. This strategy allows for invalidating borrowers from voting and incorperating a waiting period between minting (or receiving) cTokens and votes becoming availible.
Allows for calculating the voting weight of cToken holders. This strategy allows for invalidating borrowers from voting and incorporating a waiting period between minting (or receiving) cTokens and votes becoming available.

## Params

- `offsetCheck` - Offset (or waiting period) between minting and voting becoming availible
- `offsetCheck` - Offset (or waiting period) between minting and voting becoming available
- `borrowingRestricted` - If true, borrowers will have a 0 voting weight

## Examples
Expand Down
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;
}
3 changes: 3 additions & 0 deletions src/strategies/dss-vest-balance-and-unpaid/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# dss-vest-balance-and-unpaid

For an ERC20 token with a [DssVest](https://github.com/makerdao/dss-vest) token vesting contract, this strategy returns the sum of the voters' token balance and the vested but yet unclaimed tokens of the voters.
Loading

0 comments on commit d9b5eeb

Please sign in to comment.