Skip to content
This repository was archived by the owner on Aug 22, 2025. It is now read-only.

Commit 3837ea1

Browse files
wa0x6eCopilotChaituVRclaude
authored
feat: filter out addresses not supported by strategies and validation (#1738)
* feat: filter out addresses not supported by strategies and validation Co-Authored-By: Copilot <175728472+Copilot@users.noreply.github.com> * fix: add default supported protocols * refactor: reduce code duplication with a template pattern * refactor: move the strategies length to the base class * test: add unit tests for the validation class * Update src/constants.ts Co-authored-by: Chaitanya <yourchaitu@gmail.com> * fix: remove strategies length validation, delegated to score-api * fix: return false instead of throwing error on unsupported address * perf: better code * fix: throw error on invalid address when calling getVp * ci: run test on CI * fix: add missing functions to default export in utils.ts Added sha256, customFetch, and getFormattedAddressesByProtocol to the default export object to ensure consistency between named exports and default export. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: add support for starknet addresses on math strategy * simplify secret header generation in rocketpool strategy --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Chaitanya <yourchaitu@gmail.com> Co-authored-by: Claude <noreply@anthropic.com>
1 parent 007887f commit 3837ea1

27 files changed

Lines changed: 756 additions & 97 deletions

File tree

.github/workflows/test.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Tests CI
2+
3+
on: [push]
4+
5+
jobs:
6+
tests:
7+
runs-on: ubuntu-latest
8+
9+
strategy:
10+
matrix:
11+
node-version: ['16', '20']
12+
13+
steps:
14+
- uses: actions/checkout@v3
15+
- name: Use Node.js ${{ matrix.node-version }}
16+
uses: actions/setup-node@v3
17+
with:
18+
node-version: ${{ matrix.node-version }}
19+
- name: yarn install, build and run tests
20+
run: |
21+
yarn install --frozen-lockfile
22+
yarn build
23+
yarn test --coverage
24+
- name: Upload coverage reports to Codecov
25+
uses: codecov/codecov-action@v3
26+
with:
27+
token: ${{ secrets.CODECOV_TOKEN }}

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
.DS_Store
22
node_modules
33
dist
4+
coverage
45

56
# Remove some common IDE working directories
67
.idea
78
.vscode
89
.env
9-
.history
10+
.history

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@
1313
"license": "MIT",
1414
"scripts": {
1515
"build": "tsc -p .",
16-
"test": "jest -i strategy.test.ts",
16+
"test": "yarn test:unit && jest -i strategy.test.ts",
1717
"test:vp": "jest -i vp.test.ts",
1818
"test:delegation": "jest -i delegation.test.ts",
1919
"test:validation": "jest -i validation.test.ts",
20+
"test:unit": "jest -i test/unit/",
2021
"prepublishOnly": "npm run build",
2122
"postinstall": "npm run build",
2223
"postbuild": "copyfiles -u 1 \"src/**/*.md\" dist/ && copyfiles -u 1 \"src/**/*.json\" dist/",

src/constants.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { Protocol } from './types';
2+
3+
export const DEFAULT_SUPPORTED_PROTOCOLS: Protocol[] = ['evm'];
4+
export const VALID_PROTOCOLS: Protocol[] = ['evm', 'starknet'];

src/strategies/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,8 @@ import * as prlInSpRL2Balance from './prl-in-sprl2-balance';
487487
import * as edenOnlineOverride from './eden-online-override';
488488
import * as forteStaking from './forte-staking';
489489

490+
import { DEFAULT_SUPPORTED_PROTOCOLS } from '../constants';
491+
490492
const strategies = {
491493
'shroomy-voting-power': shroomyVotingPower,
492494
'apecoin-staking': apecoinStaking,
@@ -1018,6 +1020,7 @@ Object.keys(strategies).forEach(function (strategyName) {
10181020
strategies[strategyName].examples = examples;
10191021
strategies[strategyName].schema = schema;
10201022
strategies[strategyName].about = about;
1023+
strategies[strategyName].supportedProtocols ||= DEFAULT_SUPPORTED_PROTOCOLS;
10211024
});
10221025

10231026
export default strategies;

src/strategies/math/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import {
1313
} from './options';
1414

1515
export const author = 'xJonathanLEI';
16-
export const version = '0.2.2';
16+
export const version = '0.2.3';
17+
export const supportedProtocols = ['evm', 'starknet'];
1718

1819
export async function strategy(
1920
space,

src/strategies/ocean-dao-brightid/index.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export async function strategy(
8181
.filter((address, index, self) => self.indexOf(address) === index); // Remove duplicates
8282

8383
for (const chain of Object.keys(options.strategies)) {
84-
let scores = await getScoresDirect(
84+
const scores = await getScoresDirect(
8585
space,
8686
options.strategies[chain],
8787
chain,
@@ -92,7 +92,7 @@ export async function strategy(
9292

9393
// [{ address: '0x...', score: 0.5 },{ address: '0x...', score: 0.5 }]
9494
// sum scores for each address and return
95-
scores = scores.reduce((finalScores: any, score: any) => {
95+
const addressScores = scores.reduce((finalScores: any, score: any) => {
9696
for (const [address, value] of Object.entries(score)) {
9797
if (!finalScores[address]) {
9898
finalScores[address] = 0;
@@ -105,19 +105,19 @@ export async function strategy(
105105

106106
// sum delegations
107107
addresses.forEach((address) => {
108-
if (!scores[address]) scores[address] = 0;
108+
if (!addressScores[address]) addressScores[address] = 0;
109109
if (delegations[address]) {
110110
delegations[address].forEach((delegator: string) => {
111-
scores[address] += scores[delegator] ?? 0; // add delegator score
112-
scores[delegator] = 0; // set delegator score to 0
111+
addressScores[address] += addressScores[delegator] ?? 0; // add delegator score
112+
addressScores[delegator] = 0; // set delegator score to 0
113113
});
114114
}
115115
});
116116

117-
for (const key of Object.keys(scores)) {
117+
for (const key of Object.keys(addressScores)) {
118118
totalScores[key] = totalScores[key]
119-
? totalScores[key] + scores[key]
120-
: scores[key];
119+
? totalScores[key] + addressScores[key]
120+
: addressScores[key];
121121
}
122122
}
123123

src/strategies/rocketpool-node-operator-delegate-v8/index.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ const signerRegistryAbi = [
1212
'function signerToNode(address) external view returns (address)'
1313
];
1414

15-
const snapshotSecretHeader = sha256(
16-
`https://api.rocketpool.net/mainnet/delegates/block/${process.env.SNAPSHOT_API_STRATEGY_SALT}`
17-
);
15+
function getSnapshotSecretHeader() {
16+
return sha256(
17+
`https://api.rocketpool.net/mainnet/delegates/block/${process.env.SNAPSHOT_API_STRATEGY_SALT}`
18+
);
19+
}
1820

1921
export async function strategy(
2022
space,
@@ -42,7 +44,7 @@ export async function strategy(
4244
'https://api.rocketpool.net/mainnet/delegates/block/' + blockTag,
4345
{
4446
headers: {
45-
'X-Snapshot-API-Secret': snapshotSecretHeader
47+
'X-Snapshot-API-Secret': getSnapshotSecretHeader()
4648
}
4749
}
4850
);

src/strategies/subgraph-split-delegation/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { getAddress } from '@ethersproject/address';
22
import { subgraphRequest, getScoresDirect } from '../../utils';
33
import { Strategy } from '@snapshot-labs/snapshot.js/dist/src/voting/types';
4+
import { Snapshot } from '../../types';
45

56
export const author = 'aragon';
67
export const version = '0.1.0';
@@ -35,7 +36,7 @@ export async function strategy(
3536
subgraphUrl: DEFAULT_BACKEND_URL,
3637
strategies: []
3738
},
38-
snapshot: string | number
39+
snapshot: Snapshot
3940
) {
4041
const blockTag = typeof snapshot === 'number' ? snapshot : 'latest';
4142
const block = await provider.getBlock(blockTag);

src/strategies/ticket/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
export const author = 'bonustrack';
22
export const version = '0.1.0';
33

4+
export const supportedProtocols = ['evm', 'starknet'];
5+
46
export async function strategy(space, network, provider, addresses, options) {
57
return Object.fromEntries(
68
addresses.map((address) => [address, options.value || 1])

0 commit comments

Comments
 (0)