diff --git a/src/strategies/holds-tokens/README.md b/src/strategies/holds-tokens/README.md new file mode 100644 index 000000000..8289b9e56 --- /dev/null +++ b/src/strategies/holds-tokens/README.md @@ -0,0 +1,14 @@ +# holds-tokens + +This strategy return the balances of the voters for a specific ERC20 or ERC721 and maps them to the number of votes that voter gets based on holding a set of tokens. + +Here is an example of parameters: + +```json +{ + "tokenAddresses": [ + {"address": "0x7Bd29408f11D2bFC23c34f18275bBf23bB716Bc7", "network": "1", "decimals": 0, "minBalance": 1}, + {"address": "0xc34cbca32e355636c7f52dd8beab0af2396ebd79", "network": "137", "decimals": 0, "minBalance": 1} + ] +} +``` diff --git a/src/strategies/holds-tokens/examples.json b/src/strategies/holds-tokens/examples.json new file mode 100644 index 000000000..3f5b6eb1b --- /dev/null +++ b/src/strategies/holds-tokens/examples.json @@ -0,0 +1,24 @@ +[ + { + "name": "Example query", + "strategy": { + "name": "holds-tokens", + "params": { + "symbol": "ABC", + "tokenAddresses": [ + {"address": "0x7Bd29408f11D2bFC23c34f18275bBf23bB716Bc7", "network": "1", "decimals": 0, "minBalance": 0}, + {"address": "0xc34cbca32e355636c7f52dd8beab0af2396ebd79", "network": "137", "decimals": 0, "minBalance": 0} + ] + } + }, + "network": "1", + "addresses": [ + "0xC5e38233Cc0D7CFf9340e6139367aBA498EC9b18", + "0x2009a752a50D3CDe486d7b5921944377B729E747", + "0x7b15e6c439b27a553b65a9904ce571da6691a0fb", + "0x8d2f3a76a76f055d62a931678ab16b042e7badeb", + "0xEDe64a571CFe98B936271B935a955620f387E05A" + ], + "snapshot": 13317369 + } +] diff --git a/src/strategies/holds-tokens/index.ts b/src/strategies/holds-tokens/index.ts new file mode 100644 index 000000000..1f9b0ab47 --- /dev/null +++ b/src/strategies/holds-tokens/index.ts @@ -0,0 +1,41 @@ +import { strategy as multichainStrategy } from '../multichain'; + +export const author = 'lightninglu10'; +export const version = '0.1.0'; + +export async function strategy( + space, + network, + provider, + addresses, + options, + snapshot +) { + const tokens = options.tokenAddresses || []; + + options.strategies = tokens.map((token) => ({ + "name": "erc20-with-balance", + "network": token.network, + "params": { + "address": token.address, + "decimals": token.decimals, + "minBalance": token.minBalance + } + })); + + const scores: any = await multichainStrategy( + space, + network, + provider, + addresses, + options, + snapshot + ); + + return Object.fromEntries( + Object.entries(scores).map((address: any) => [ + address[0], + (address[1] === tokens.length) ? 1 : 0 + ]) + ); +} diff --git a/src/strategies/index.ts b/src/strategies/index.ts index e737dd7d2..994b35fb0 100644 --- a/src/strategies/index.ts +++ b/src/strategies/index.ts @@ -144,6 +144,7 @@ import * as eglVote from './egl-vote'; import * as mcnFarm from './mcn-farm'; import * as snowswap from './snowswap'; import * as meebitsdao from './meebitsdao'; +import * as holdsTokens from './holds-tokens'; import * as crucibleERC20BalanceOf from './crucible-erc20-balance-of'; import * as hasrock from './has-rock'; import * as flexaCapacityStaking from './flexa-capacity-staking'; @@ -309,6 +310,7 @@ const strategies = { 'hopr-staking': hoprStaking, 'hopr-bridged-balance': hoprBridgedBalance, 'occ-stake-of': occStakeOf, + 'holds-tokens': holdsTokens, 'loot-character-guilds': lootCharacterGuilds };