Skip to content

Commit

Permalink
[hopr-bridged-balance] Hopr bridged balance (snapshot-labs#75)
Browse files Browse the repository at this point in the history
* Add strategies for staking program and wx/x/-/hopr tokens. Work despite network (1 or 100)

* Keep only bridged balance

* Reduce function ABI to minimum

Co-authored-by: Chaitanya <[email protected]>

Co-authored-by: Chaitanya <[email protected]>
  • Loading branch information
QYuQianchen and ChaituVR authored Sep 23, 2021
1 parent fc4d950 commit da5a137
Show file tree
Hide file tree
Showing 3 changed files with 248 additions and 2 deletions.
64 changes: 64 additions & 0 deletions src/strategies/hopr-bridged-balance/examples.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
[
{
"name": "Get bridged HOPR token balance",
"strategy": {
"name": "hopr-bridged-balance",
"params": {
"xHopr": "0xd057604a14982fe8d88c5fc25aac3267ea142a08",
"wxHopr": "0xD4fdec44DB9D44B8f2b6d529620f9C0C7066A2c1",
"hopr": "0xf5581dfefd8fb0e4aec526be659cfab1f8c781da"
}
},
"network": "100",
"addresses": [
"0x04BBB7eA18EA570aE47d4489991645E4E49bBf37",
"0x2aF80738aC01e7883d11c912dFe8322C129ae5C5",
"0x0bb43EFc1a613658177D8f67CcF9CFFD8B25b906",
"0x53e85186ebF5A7d4BD06324F7b9D8B3623EF0307",
"0x2DCDB99930E279f1e9Ad11F491163051432542A0",
"0x4326990033eCd87A5444383Cf8c715E696301910",
"0xEd6a59A7C1D5a88b7cb5eb877A7A6078A7e801C7",
"0xeFC05B0D0C8bE8D4Cb3a220ef582E9f7E6FBCd00",
"0xC7B169b108c5e75991C520AEA97140534291C81D",
"0x04Be52434EB64aDdF373137310551ac42013677c",
"0xBE8C93a8C18AF63aAB449994AFAc13E71240ccC4",
"0xf813773eBDD4759c1B780d745081f046A5B776fB",
"0x7F26C34Ed10bF66602009231bBFF24f2f84e9270",
"0x4abd7276C53279b3aBFFF2B5D8A47c0AFc84833B",
"0x3e1A12a6019ee26418F22B656926fE38F5e58C5f",
"0x7A27A4D91231aCB3282b410Cc784517B417FA0DA"
],
"snapshot": 18200908
},
{
"name": "Get bridged HOPR token balance",
"strategy": {
"name": "hopr-bridged-balance",
"params": {
"xHopr": "0xd057604a14982fe8d88c5fc25aac3267ea142a08",
"wxHopr": "0xD4fdec44DB9D44B8f2b6d529620f9C0C7066A2c1",
"hopr": "0xf5581dfefd8fb0e4aec526be659cfab1f8c781da"
}
},
"network": "1",
"addresses": [
"0x04BBB7eA18EA570aE47d4489991645E4E49bBf37",
"0x2aF80738aC01e7883d11c912dFe8322C129ae5C5",
"0x0bb43EFc1a613658177D8f67CcF9CFFD8B25b906",
"0x53e85186ebF5A7d4BD06324F7b9D8B3623EF0307",
"0x2DCDB99930E279f1e9Ad11F491163051432542A0",
"0x4326990033eCd87A5444383Cf8c715E696301910",
"0xEd6a59A7C1D5a88b7cb5eb877A7A6078A7e801C7",
"0xeFC05B0D0C8bE8D4Cb3a220ef582E9f7E6FBCd00",
"0xC7B169b108c5e75991C520AEA97140534291C81D",
"0x04Be52434EB64aDdF373137310551ac42013677c",
"0xBE8C93a8C18AF63aAB449994AFAc13E71240ccC4",
"0xf813773eBDD4759c1B780d745081f046A5B776fB",
"0x7F26C34Ed10bF66602009231bBFF24f2f84e9270",
"0x4abd7276C53279b3aBFFF2B5D8A47c0AFc84833B",
"0x3e1A12a6019ee26418F22B656926fE38F5e58C5f",
"0x7A27A4D91231aCB3282b410Cc784517B417FA0DA"
],
"snapshot": 13269966
}
]
180 changes: 180 additions & 0 deletions src/strategies/hopr-bridged-balance/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
import { formatUnits } from '@ethersproject/units';
import { BigNumber } from '@ethersproject/bignumber';
import { multicall, subgraphRequest } from '../../utils';

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

const tokenAbi = [ 'function balanceOf(address) view returns (uint256)' ]

const XDAI_BLOCK_SUBGRAPH_URL =
'https://api.thegraph.com/subgraphs/name/1hive/xdai-blocks';
const MAINNET_BLOCK_SUBGRAPH_URL =
'https://api.thegraph.com/subgraphs/name/blocklytics/ethereum-blocks';
const HOPR_XDAI_SUBGRAPH_URL =
'https://api.thegraph.com/subgraphs/name/hoprnet/hopr-on-xdai';
const HOPR_MAINNET_SUBGRAPH_URL =
'https://api.thegraph.com/subgraphs/name/hoprnet/hopr-on-mainnet';
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 getMainnetBlockNumber(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(MAINNET_BLOCK_SUBGRAPH_URL, query);
return Number(data.blocks[0].number);
}

async function xHoprSubgraphQuery(
addresses: string[],
blockNumber: number
): Promise<{ [propName: string]: number }> {
const query = {
accounts: {
__args: {
first: LIMIT,
block: {
number: blockNumber
},
where: {
id_in: addresses.map((adr) => adr.toLowerCase())
}
},
id: true,
totalBalance: true
}
};
const data = await subgraphRequest(HOPR_XDAI_SUBGRAPH_URL, query);
// map result (data.accounts) to addresses
const entries = data.accounts.map((d) => [d.id, Number(d.totalBalance)]);
return Object.fromEntries(entries);
}

async function hoprSubgraphQuery(
addresses: string[],
blockNumber: number
): Promise<{ [propName: string]: number }> {
const query = {
accounts: {
__args: {
first: LIMIT,
block: {
number: blockNumber
},
where: {
id_in: addresses.map((adr) => adr.toLowerCase())
}
},
id: true,
amount: true
}
};
const data = await subgraphRequest(HOPR_MAINNET_SUBGRAPH_URL, query);
// map result (data.accounts) to addresses
const entries = data.accounts.map((d) => [d.id, Number(d.amount)]);
return Object.fromEntries(entries);
}

export async function strategy(
space,
network,
provider,
addresses,
options,
snapshot
) {
const blockTag = typeof snapshot === 'number' ? snapshot : 'latest';
const isEth = network === '1'; // either ETH mainnet or xDAI

const [res, block] = await Promise.all([
multicall(
network,
provider,
tokenAbi,
addresses
.map((address: any) => [
isEth ? options.hopr : options.xHopr,
'balanceOf',
[address]
])
.concat(
isEth
? []
: addresses.map((address: any) => [
options.wxHopr,
'balanceOf',
[address]
])
),
{ blockTag }
),
provider.getBlock(blockTag)
]);

const currentNetwork: BigNumber[] = isEth
? res.map((r) => r[0] as BigNumber)
: addresses.map((r, i) =>
(res[i][0] as BigNumber).add(res[i + addresses.length][0] as BigNumber)
);
const subgraphBlock = isEth
? await getXdaiBlockNumber(block.timestamp)
: await getMainnetBlockNumber(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 = isEth
? await Promise.all(
addressSubsets.map((subset) =>
xHoprSubgraphQuery(subset, subgraphBlock)
)
)
: await Promise.all(
addressSubsets.map((subset) => hoprSubgraphQuery(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(
currentNetwork.map((value, i) => [
addresses[i], // current network balance
parseFloat(formatUnits(value, 18)) + subgraphScore[i] // subgraph balance
])
);
}
6 changes: 4 additions & 2 deletions src/strategies/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,9 @@ import * as hasrock from './has-rock';
import * as flexaCapacityStaking from './flexa-capacity-staking';
import * as sunriseGamingUniv2Lp from './sunrisegaming-univ2-lp';
import * as sunriseGamingStaking from './sunrisegaming-staking';
import * as singleStakingPoolsBalanceOf from './single-staking-pools-balanceof'
import * as occStakeOf from './occ-stake-of'
import * as singleStakingPoolsBalanceOf from './single-staking-pools-balanceof';
import * as occStakeOf from './occ-stake-of';
import * as hoprBridgedBalance from './hopr-bridged-balance';

const strategies = {
coordinape,
Expand Down Expand Up @@ -303,6 +304,7 @@ const strategies = {
'sunrisegaming-univ2-lp': sunriseGamingUniv2Lp,
'sunrisegaming-staking': sunriseGamingStaking,
'single-staking-pools-balanceof': singleStakingPoolsBalanceOf,
'hopr-bridged-balance': hoprBridgedBalance,
'occ-stake-of': occStakeOf
};

Expand Down

0 comments on commit da5a137

Please sign in to comment.