diff --git a/src/strategies/index.ts b/src/strategies/index.ts index e5e2e0b22..5ac4b506d 100644 --- a/src/strategies/index.ts +++ b/src/strategies/index.ts @@ -157,6 +157,7 @@ import * as hoprBridgedBalance from './hopr-bridged-balance'; import * as lootCharacterGuilds from './loot-character-guilds'; import * as cyberkongz from './cyberkongz'; import * as compLikeVotesInclusive from './comp-like-votes-inclusive'; +import * as mstable from './mstable'; const strategies = { coordinape, @@ -315,7 +316,8 @@ const strategies = { 'holds-tokens': holdsTokens, 'loot-character-guilds': lootCharacterGuilds, 'cyberkongz': cyberkongz, - 'comp-like-votes-inclusive': compLikeVotesInclusive + 'comp-like-votes-inclusive': compLikeVotesInclusive, + mstable }; Object.keys(strategies).forEach(function (strategyName) { diff --git a/src/strategies/mstable/README.md b/src/strategies/mstable/README.md new file mode 100644 index 000000000..d80eca54e --- /dev/null +++ b/src/strategies/mstable/README.md @@ -0,0 +1,19 @@ +# mstable + +Calls getVotes() on both the stkMTA and stkBPT contracts, these balances are then summed to generate a users vMTA balance. + +## Examples + +```JSON +{ + "strategies": [ + { + "name": "mstable", + "params": { + "stkBPT": "0xefbe22085d9f29863cfb77eed16d3cc0d927b011", + "stkMTA": "0x8f2326316eC696F6d023E37A9931c2b2C177a3D7", + } + } + ] +} +``` diff --git a/src/strategies/mstable/examples.json b/src/strategies/mstable/examples.json new file mode 100644 index 000000000..2623860d9 --- /dev/null +++ b/src/strategies/mstable/examples.json @@ -0,0 +1,18 @@ +[ + { + "name": "mstable", + "strategy": { + "name": "mstable", + "params": { + "stkBPT": "0xefbe22085d9f29863cfb77eed16d3cc0d927b011", + "stkMTA": "0x8f2326316eC696F6d023E37A9931c2b2C177a3D7" + } + }, + "network": "1", + "addresses": [ + "0x2ee8670d2b936985d5fb1ee968810c155d3bb9ca", + "0x19f12c947d25ff8a3b748829d8001ca09a28d46d" + ], + "snapshot": 13236086 + } +] diff --git a/src/strategies/mstable/index.ts b/src/strategies/mstable/index.ts new file mode 100644 index 000000000..c030eb64c --- /dev/null +++ b/src/strategies/mstable/index.ts @@ -0,0 +1,61 @@ +import { formatUnits } from '@ethersproject/units'; +import { multicall } from '../../utils'; + +export const author = 'chrisjgf'; +export const version = '0.0.1'; + +const abi = [ 'function getVotes(address account) view returns (uint256)' ]; + +const chunk = (arr, size) => + Array.from({ length: Math.ceil(arr.length / size) }, (v, i) => + arr.slice(i * size, i * size + size) + ); + +export async function strategy( + space, + network, + provider, + addresses, + options, + snapshot +): Promise> { + const blockTag = typeof snapshot === 'number' ? snapshot : 'latest'; + + const stkMTAQuery = addresses.map((address: any) => [ + options.stkMTA, + 'getVotes', + [address] + ]); + + const stkBPTQuery = addresses.map((address: any) => [ + options.stkBPT, + 'getVotes', + [address] + ]); + + const response = await multicall( + network, + provider, + abi, + [...stkMTAQuery, ...stkBPTQuery], + { blockTag } + ); + + const chunks = chunk(response, addresses.length); + const stkMTABalances = chunks[0]; + const stkBPTBalances = chunks[1]; + + return Object.fromEntries( + Array(addresses.length) + .fill('x') + .map((_, i) => [ + addresses[i], + parseFloat( + formatUnits( + stkMTABalances[i][0].add(stkBPTBalances[i][0]).toString(), + 18 + ) + ) + ]) + ); +}