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 Aug 9, 2023
2 parents 9bb3d3c + 4e5efa0 commit 60be5c9
Show file tree
Hide file tree
Showing 35 changed files with 6,445 additions and 4,420 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"@ethersproject/strings": "^5.6.1",
"@ethersproject/units": "^5.6.1",
"@ethersproject/wallet": "^5.6.2",
"@snapshot-labs/snapshot.js": "^0.4.106",
"@snapshot-labs/snapshot.js": "^0.4.109",
"@spruceid/didkit-wasm-node": "^0.2.1",
"@uniswap/sdk-core": "^3.0.1",
"@uniswap/v3-sdk": "^3.9.0",
Expand Down
9 changes: 9 additions & 0 deletions src/strategies/api-v2-override/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# API V2 Override strategy

Same as the `api-v2` strategy, but passes all voter addresses in the query string / body payload of the API endpoint.
Prefer `api-post` method for better scalability.

## Params

All params are same as the `api-v2` strategy.
Refer to the `api-v2` strategy's documentation for more details.
23 changes: 23 additions & 0 deletions src/strategies/api-v2-override/examples.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[
{
"name": "Example query",
"strategy": {
"name": "api-v2-override",
"params": {
"url": "ipfs://QmbmhTivxYuLE5uhNEALoBmvP7Yg9acA2Lkw9V9PqaEmw6",
"type": "ipfs"
}
},
"network": "1",
"addresses": [
"0xeD2bcC3104Da5F5f8fA988D6e9fAFd74Ae62f319",
"0x3c4B8C52Ed4c29eE402D9c91FfAe1Db2BAdd228D",
"0xd649bACfF66f1C85618c5376ee4F38e43eE53b63",
"0x726022a9fe1322fA9590FB244b8164936bB00489",
"0xc6665eb39d2106fb1DBE54bf19190F82FD535c19",
"0x6ef2376fa6e12dabb3a3ed0fb44e4ff29847af68",
"0x89446aF03652c5257dB5C8E4E85495EB754196c5"
],
"snapshot": 11437846
}
]
17 changes: 17 additions & 0 deletions src/strategies/erc4626-assets-of/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# erc4626-assets-of

Returns the quantity of assets held within a ERC4626 vault by a specific address.

ERC4626 has a `balanceOf` function that returns the number of "shares" owned by an address. This strategy converts the number of shares to the number of assets by using the vault's `convertToAssets` function.

For instance, each share might represent ~1.2 underlying asset tokens. We use the ERC4626's internal `convertToAssets` function to convert the number of shares to the number of assets, which represent protocol governance votes.

Here is an example of parameters:

```json
{
"address": "0x44e4c3668552033419520be229cd9df0c35c4417",
"symbol": "stMGN",
"decimals": 18
}
```
22 changes: 22 additions & 0 deletions src/strategies/erc4626-assets-of/examples.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[
{
"name": "Example query",
"strategy": {
"name": "erc4626-assets-of",
"params": {
"address": "0x44e4c3668552033419520be229cd9df0c35c4417",
"symbol": "MGN",
"decimals": 18
}
},
"network": "42161",
"addresses": [
"0x65877BE34c0c3C3A317d97028FD91bd261410026",
"0x86341e73d9Deb4696B1Ae50DBCe8F2D62FA06023",
"0xb738Ce8df54A6d1035d651D77816ae20AFff3bE6",
"0x0c9a74a6Fe43341e90Ab436439C361452eEb9c6b",
"0x72C861B1C98994d54Cc0c6E98B4379203a1905dA"
],
"snapshot": 117490161
}
]
47 changes: 47 additions & 0 deletions src/strategies/erc4626-assets-of/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { BigNumberish } from '@ethersproject/bignumber';
import { formatUnits } from '@ethersproject/units';

import { Multicaller } from '../../utils';

export const author = '0x-logic';
export const version = '0.0.1';

const abi: string[] = [
'function balanceOf(address account) external view returns (uint256)',
'function convertToAssets(uint256 shares) public view returns (uint256 assets)'
];

export async function strategy(
space,
network,
provider,
addresses,
options,
snapshot
): Promise<Record<string, number>> {
const blockTag = typeof snapshot === 'number' ? snapshot : 'latest';

// 0. Initialize our Multicaller
const multi = new Multicaller(network, provider, abi, { blockTag });

// 1. Get the ERC4626 token balance of each address
addresses.forEach((address: string) =>
multi.call(address, options.address, 'balanceOf', [address])
);
const tokenBalanceResults: Record<string, BigNumberish> =
await multi.execute();

// 2. Convert the ERC4626 token balances to asset balances
Object.entries(tokenBalanceResults).forEach(([address, balance]) =>
multi.call(address, options.address, 'convertToAssets', [balance])
);
const assetBalanceResults: Record<string, BigNumberish> =
await multi.execute();

return Object.fromEntries(
Object.entries(assetBalanceResults).map(([address, assetBalance]) => [
address,
parseFloat(formatUnits(assetBalance, options.decimals))
])
);
}
33 changes: 33 additions & 0 deletions src/strategies/erc4626-assets-of/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "#/definitions/Strategy",
"definitions": {
"Strategy": {
"title": "Strategy",
"type": "object",
"properties": {
"symbol": {
"type": "string",
"title": "Symbol",
"examples": ["e.g. MGN"],
"maxLength": 16
},
"address": {
"type": "string",
"title": "ERC4626 contract address",
"examples": ["e.g. 0x44e4c3668552033419520be229cd9df0c35c4417"],
"pattern": "^0x[a-fA-F0-9]{40}$",
"minLength": 42,
"maxLength": 42
},
"decimals": {
"type": "number",
"title": "Decimals",
"examples": ["e.g. 18"]
}
},
"required": ["address", "decimals"],
"additionalProperties": false
}
}
}
13 changes: 13 additions & 0 deletions src/strategies/eth-balance/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# eth-balance

This strategy is used for use ETH balance as voting power.

The balance displayed may vary depending on the network, and represents the balance of the main currency used on that network (e.g. ETH on Ethereum mainnet, BNB on Binance Smart Chain, etc.).

## Params

This strategy does need any parameters.

| Param | Type | Default | Description |
| --- | --- | --- | --- |
| `symbol`(optional) | `string` | `` | The symbol of the currency to used for the balance. |
20 changes: 20 additions & 0 deletions src/strategies/eth-balance/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "#/definitions/Strategy",
"definitions": {
"Strategy": {
"title": "Strategy",
"type": "object",
"properties": {
"symbol": {
"type": "string",
"title": "Symbol",
"examples": ["e.g. ETH"],
"maxLength": 16
}
},
"required": [],
"additionalProperties": false
}
}
}
12 changes: 12 additions & 0 deletions src/strategies/gelato-staking/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Gelato-Staking

Strategy that returns voting power based on GEL stake.

Here is an example of parameters:

```json
{
"address": "0xc2a813699bF2353380c625e3D6b544dC42963941",
"decimals": 18
}
```
22 changes: 22 additions & 0 deletions src/strategies/gelato-staking/examples.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[
{
"name": "Gelato Staking",
"strategy": {
"name": "gelato-staking",
"params": {
"address": "0xc2a813699bF2353380c625e3D6b544dC42963941",
"decimals": 18
}
},
"network": "1",
"addresses": [
"0x417B4Adc279743FC49F047C323FC668db9E600D8",
"0x3D529c760F3EC4c89Bdd6549DDabE9097C1da6e9",
"0x59eD948390F079F2534C052acc3419d34975E026",
"0xda81a723E748C782284Bbb06AB74e3D0A9dBBC77",
"0x2CAd75e380Ddb12329231DF6793A0343917BE8B3",
"0xeD5cF41b0fD6A3C564c17eE34d9D26Eafc30619b"
],
"snapshot": 17821000
}
]
43 changes: 43 additions & 0 deletions src/strategies/gelato-staking/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { BigNumber } from '@ethersproject/bignumber';
import { Multicaller } from '../../utils';
import { formatUnits } from '@ethersproject/units';

export const author = 'alxdca';
export const version = '0.1.0';

const abi = [
'function stakers() external view returns (address[])',
'function getStake(address) public view returns (uint256)',
'function manager(address) public view returns (address)'
];

const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';

export async function strategy(
space,
network,
provider,
addresses,
options,
snapshot
): Promise<Record<string, number>> {
const blockTag = typeof snapshot === 'number' ? snapshot : 'latest';

const multi = new Multicaller(network, provider, abi, { blockTag });
multi.call('stakers', options.address, 'stakers', []);
const stakersResults: Record<string, string[]> = await multi.execute();

const stakers = stakersResults.stakers;
stakers.forEach((staker) => {
multi.call(`${staker}.stake`, options.address, 'getStake', [staker]);
multi.call(`${staker}.manager`, options.address, 'manager', [staker]);
});
const results: Record<string, { stake: BigNumber; manager: string }> =
await multi.execute();

return Object.entries(results).reduce((prev, [staker, result]) => {
prev[result.manager !== ZERO_ADDRESS ? result.manager : staker] =
parseFloat(formatUnits(result.stake, options.decimals));
return prev;
}, {});
}
33 changes: 33 additions & 0 deletions src/strategies/gelato-staking/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "#/definitions/Strategy",
"definitions": {
"Strategy": {
"title": "Strategy",
"type": "object",
"properties": {
"symbol": {
"type": "string",
"title": "Symbol",
"examples": ["e.g. UNI"],
"maxLength": 16
},
"address": {
"type": "string",
"title": "Contract address",
"examples": ["e.g. 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"],
"pattern": "^0x[a-fA-F0-9]{40}$",
"minLength": 42,
"maxLength": 42
},
"decimals": {
"type": "number",
"title": "Decimals",
"examples": ["e.g. 18"]
}
},
"required": ["address", "decimals"],
"additionalProperties": false
}
}
}
12 changes: 12 additions & 0 deletions src/strategies/hats-protocol-single-vote-per-org/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# hsts-protocol-single-vote-per-org

A strategy to get a single voting power based on checking to see if the addresses own at least one hat within a tree.

Here is an example of parameters:

```json
{
"address": "0x3bc1A0Ad72417f2d411118085256fC53CBdDd137",
"humanReadableTreeId": 44
}
```
20 changes: 20 additions & 0 deletions src/strategies/hats-protocol-single-vote-per-org/examples.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[
{
"name": "Example query",
"strategy": {
"name": "hats-protocol-single-vote-per-org",
"params": {
"address": "0x3bc1A0Ad72417f2d411118085256fC53CBdDd137",
"humanReadableTreeId": 44
}
},
"network": "5",
"addresses": [
"0xc4f6578c24c599F195c0758aD3D4861758d703A3",
"0xa6aF0566EF4eF7E8f38913f69d4e55c06F00A5aC",
"0x00e7332F9Cd4C05a0645AC959Fb1Be60ec24F94f",
"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
],
"snapshot": 9418504
}
]
Loading

0 comments on commit 60be5c9

Please sign in to comment.