forked from snapshot-labs/snapshot-strategies
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[hopr-staking] Hopr staking (snapshot-labs#76)
* Add strategies for staking program and wx/x/-/hopr tokens. Work despite network (1 or 100) * Keep only staking strategy
- Loading branch information
1 parent
da5a137
commit 3990451
Showing
3 changed files
with
166 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
[ | ||
{ | ||
"name": "Stakes and unclaimed rewards from HOPR Stake program", | ||
"strategy": { | ||
"name": "hopr-staking", | ||
"params": { | ||
"tokenAddress": "0xf5581dfefd8fb0e4aec526be659cfab1f8c781da" | ||
} | ||
}, | ||
"network": "1", | ||
"addresses": [ | ||
"0x04BBB7eA18EA570aE47d4489991645E4E49bBf37", | ||
"0x2aF80738aC01e7883d11c912dFe8322C129ae5C5", | ||
"0x0bb43EFc1a613658177D8f67CcF9CFFD8B25b906", | ||
"0x53e85186ebF5A7d4BD06324F7b9D8B3623EF0307", | ||
"0x2DCDB99930E279f1e9Ad11F491163051432542A0", | ||
"0x4326990033eCd87A5444383Cf8c715E696301910", | ||
"0xEd6a59A7C1D5a88b7cb5eb877A7A6078A7e801C7", | ||
"0xeFC05B0D0C8bE8D4Cb3a220ef582E9f7E6FBCd00", | ||
"0xC7B169b108c5e75991C520AEA97140534291C81D", | ||
"0x04Be52434EB64aDdF373137310551ac42013677c", | ||
"0xBE8C93a8C18AF63aAB449994AFAc13E71240ccC4", | ||
"0xf813773eBDD4759c1B780d745081f046A5B776fB", | ||
"0x7F26C34Ed10bF66602009231bBFF24f2f84e9270", | ||
"0x4abd7276C53279b3aBFFF2B5D8A47c0AFc84833B", | ||
"0x3e1A12a6019ee26418F22B656926fE38F5e58C5f", | ||
"0x7A27A4D91231aCB3282b410Cc784517B417FA0DA" | ||
], | ||
"snapshot": 13269966 | ||
}, | ||
{ | ||
"name": "Stakes and unclaimed rewards from HOPR Stake program", | ||
"strategy": { | ||
"name": "hopr-staking", | ||
"params": { | ||
"tokenAddress": "0xf5581dfefd8fb0e4aec526be659cfab1f8c781da" | ||
} | ||
}, | ||
"network": "100", | ||
"addresses": [ | ||
"0x04BBB7eA18EA570aE47d4489991645E4E49bBf37", | ||
"0x2aF80738aC01e7883d11c912dFe8322C129ae5C5", | ||
"0x0bb43EFc1a613658177D8f67CcF9CFFD8B25b906", | ||
"0x53e85186ebF5A7d4BD06324F7b9D8B3623EF0307", | ||
"0x2DCDB99930E279f1e9Ad11F491163051432542A0", | ||
"0x4326990033eCd87A5444383Cf8c715E696301910", | ||
"0xEd6a59A7C1D5a88b7cb5eb877A7A6078A7e801C7", | ||
"0xeFC05B0D0C8bE8D4Cb3a220ef582E9f7E6FBCd00", | ||
"0xC7B169b108c5e75991C520AEA97140534291C81D", | ||
"0x04Be52434EB64aDdF373137310551ac42013677c", | ||
"0xBE8C93a8C18AF63aAB449994AFAc13E71240ccC4", | ||
"0xf813773eBDD4759c1B780d745081f046A5B776fB", | ||
"0x7F26C34Ed10bF66602009231bBFF24f2f84e9270", | ||
"0x4abd7276C53279b3aBFFF2B5D8A47c0AFc84833B", | ||
"0x3e1A12a6019ee26418F22B656926fE38F5e58C5f", | ||
"0x7A27A4D91231aCB3282b410Cc784517B417FA0DA" | ||
], | ||
"snapshot": 18200908 | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import { formatUnits } from '@ethersproject/units'; | ||
import { BigNumber } from '@ethersproject/bignumber'; | ||
import { subgraphRequest } from '../../utils'; | ||
|
||
export const author = 'QYuQianchen'; | ||
export const version = '0.1.0'; | ||
|
||
const XDAI_BLOCK_SUBGRAPH_URL = | ||
'https://api.thegraph.com/subgraphs/name/1hive/xdai-blocks'; | ||
const HOPR_STAKING_SUBGRAPH_URL = | ||
'https://api.thegraph.com/subgraphs/name/hoprnet/hopr-staking-program'; | ||
const LIMIT = 1000; // 1000 addresses per query in Subgraph | ||
|
||
async function getXdaiBlockNumber(timestamp: number): Promise<number> { | ||
const query = { | ||
blocks: { | ||
__args: { | ||
first: 1, | ||
orderBy: 'number', | ||
orderDirection: 'desc', | ||
where: { | ||
timestamp_lte: timestamp | ||
} | ||
}, | ||
number: true, | ||
timestamp: true | ||
} | ||
}; | ||
const data = await subgraphRequest(XDAI_BLOCK_SUBGRAPH_URL, query); | ||
return Number(data.blocks[0].number); | ||
} | ||
|
||
async function stakingSubgraphQuery( | ||
addresses: string[], | ||
blockNumber: number | ||
): Promise<{ [propName: string]: BigNumber }> { | ||
const query = { | ||
accounts: { | ||
__args: { | ||
first: LIMIT, | ||
block: { | ||
number: blockNumber | ||
}, | ||
where: { | ||
id_in: addresses.map((adr) => adr.toLowerCase()) | ||
} | ||
}, | ||
id: true, | ||
actualStake: true, | ||
virtualStake: true, | ||
unclaimedRewards: true | ||
} | ||
}; | ||
const data = await subgraphRequest(HOPR_STAKING_SUBGRAPH_URL, query); | ||
// map result (data.accounts) to addresses | ||
const entries = data.accounts.map((d) => [ | ||
d.id, | ||
BigNumber.from(d.actualStake).add( | ||
BigNumber.from(d.virtualStake).add(BigNumber.from(d.unclaimedRewards)) | ||
) | ||
]); | ||
return Object.fromEntries(entries); | ||
} | ||
|
||
export async function strategy( | ||
space, | ||
network, | ||
provider, | ||
addresses, | ||
options, | ||
snapshot | ||
) { | ||
const blockTag = typeof snapshot === 'number' ? snapshot : 'latest'; | ||
const isXdai = network === '100'; // either xDAI or ETH mainnet | ||
const [block] = await Promise.all([provider.getBlock(blockTag)]); | ||
|
||
// get the block number for subgraph query | ||
const subgraphBlock = isXdai | ||
? block.number | ||
: await getXdaiBlockNumber(block.timestamp); | ||
|
||
// trim addresses to sub of "LIMIT" addresses. | ||
const addressSubsets = Array.apply( | ||
null, | ||
Array(Math.ceil(addresses.length / LIMIT)) | ||
).map((_e, i) => addresses.slice(i * LIMIT, (i + 1) * LIMIT)); | ||
|
||
const returnedFromSubgraph = await Promise.all( | ||
addressSubsets.map((subset) => stakingSubgraphQuery(subset, subgraphBlock)) | ||
); | ||
|
||
// get and parse balance from subgraph | ||
const subgraphBalance = Object.assign({}, ...returnedFromSubgraph); | ||
const subgraphScore = addresses.map( | ||
(address) => subgraphBalance[address.toLowerCase()] ?? 0 | ||
); | ||
|
||
return Object.fromEntries( | ||
addresses.map((adr, i) => [ | ||
adr, | ||
parseFloat(formatUnits(subgraphScore[i], 18)) // subgraph balance | ||
]) | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters