Files
DefiLlama-Adapters/projects/dehive/index.js
2022-02-09 14:25:40 +02:00

297 lines
8.6 KiB
JavaScript

const sdk = require("@defillama/sdk");
const BigNumber = require("bignumber.js");
const abi = require('./abi.json')
const assetsInfo = require("./assetsInfo");
const EXPORT_TYPE_TVL = 0;
const EXPORT_TYPE_DHV_STAKING = 1;
const EXPORT_TYPE_POOL2 = 2;
async function stakingTvl(chain, meta, ethBlock) {
return (await sdk.api.abi.call({
target: meta.stakingAddress,
abi: abi.poolInfo,
params: meta.poolId,
chain,
block: ethBlock
})).output.poolSupply;
}
async function stakingDhvTvl(chain, meta, ethBlock) {
return (await sdk.api.abi.call({
target: meta.tokenAddress,
abi: abi.balanceOf,
params: meta.stakingAddress,
chain,
block: ethBlock
})).output;
}
async function lpStakingTvl(chain, meta, ethBlock) {
const { poolSupply } = (await sdk.api.abi.call({
target: meta.stakingAddress,
abi: abi.poolInfo,
params: meta.poolId,
chain,
block: ethBlock
})).output;
const poolSupplyBN = new BigNumber(poolSupply);
const lpTotalSupply = (await sdk.api.abi.call({
target: meta.lpAddress,
abi: abi.totalSupply,
chain,
block: ethBlock
})).output;
const lpTotalSupplyBN = new BigNumber(lpTotalSupply);
const tvl = [];
for (let i = 0; i < meta.underlying.length; i++) {
const underlyingLpBalance = (await sdk.api.abi.call({
target: meta.underlying[i],
abi: abi.balanceOf,
params: meta.lpAddress,
chain,
block: ethBlock
})).output;
const underlyingLpBalanceBN = new BigNumber(underlyingLpBalance);
const underlyingTvl = poolSupplyBN.multipliedBy(underlyingLpBalanceBN).div(lpTotalSupplyBN);
tvl.push([meta.underlying[i], underlyingTvl.integerValue().toFixed()]);
}
if (!!meta.dhvToken) {
const dhvBalance = (await sdk.api.abi.call({
target: meta.dhvToken,
abi: abi.balanceOf,
params: meta.stakingAddress,
chain,
block: ethBlock
})).output;
tvl.push([meta.dhvToken, dhvBalance]);
}
return tvl;
}
async function crvStakingTvl(chain, meta, ethBlock) {
const { strategy } = (await sdk.api.abi.call({
target: meta.stakingAddress,
abi: abi.impulseMultiPoolInfo,
params: meta.poolId,
chain,
block: ethBlock
})).output;
const wantLockedTotal = (await sdk.api.abi.call({
target: strategy,
abi: abi.wantLockedTotal,
chain,
block: ethBlock
})).output;
const underlyingList = (await sdk.api.abi.call({
target: strategy,
abi: abi.listUnderlying,
chain,
block: ethBlock
})).output;
const underlyingAmount = (await sdk.api.abi.call({
target: strategy,
abi: abi.wantPriceInUnderlying,
params: wantLockedTotal,
chain,
block: ethBlock
})).output;
return underlyingList.map((_, i) => [underlyingList[i], underlyingAmount[i]]);
}
async function impulseStakingTvl(chain, meta, ethBlock) {
if (chain === 'bsc') {
return await lpStakingTvl(chain, meta, ethBlock); // from staking pool
}
const { strategy } = (await sdk.api.abi.call({
target: meta.stakingAddress,
abi: abi.impulseMultiPoolInfo,
params: meta.poolId,
chain,
block: ethBlock
})).output;
const wantLockedTotal = (await sdk.api.abi.call({
target: strategy,
abi: abi.wantLockedTotal,
chain,
block: ethBlock
})).output;
const usdToken = (await sdk.api.abi.call({
target: strategy,
abi: abi.usdToken,
chain,
block: ethBlock
})).output;
const wantPrice = (await sdk.api.abi.call({
target: strategy,
abi: abi.wantPriceInUsd,
params: wantLockedTotal,
chain,
block: ethBlock
})).output;
let tvl = await lpStakingTvl(chain, meta, ethBlock); // from staking pool
tvl.push([usdToken, wantPrice]); // from strategy
return tvl;
}
async function clusterTvl(chain, meta, ethBlock) {
const poolSupply = (await sdk.api.abi.call({
target: meta.clusterAddress,
abi: "erc20:totalSupply",
chain,
block: ethBlock
})).output;
const underlyingList = (await sdk.api.abi.call({
target: meta.clusterAddress,
abi: abi.getUnderlyings,
chain,
block: ethBlock
})).output;
const underlyingAmount = (await sdk.api.abi.call({
target: meta.clusterAddress,
abi: abi.getUnderlyingsAmountsFromClusterAmount,
params: poolSupply,
chain,
block: ethBlock
})).output;
return underlyingList.map((_, i) => [underlyingList[i], underlyingAmount[i]]);
}
async function chainTvl(chain, chainBlocks, exportType) {
const tvl = {};
const transform = addr => `${chain}:${addr}`
const block = chainBlocks[chain]
for (const staking of assetsInfo[chain]) {
let calculateTvlFunction = undefined;
switch (staking.tvl) {
case "stakingTvl":
calculateTvlFunction = stakingTvl;
break;
case "stakingDhvTvl":
calculateTvlFunction = stakingDhvTvl;
break;
case "lpStakingTvl":
calculateTvlFunction = lpStakingTvl;
break;
case "crvStakingTvl":
calculateTvlFunction = crvStakingTvl;
break;
case "clusterTvl":
calculateTvlFunction = clusterTvl;
break;
case "impulseStakingTvl":
calculateTvlFunction = impulseStakingTvl;
break;
default:
console.log('unknown tvl type', JSON.stringify(staking, null,4));
continue;
}
if (
(staking.tvl === "stakingDhvTvl" && exportType !== EXPORT_TYPE_DHV_STAKING)
|| (staking.tvl !== "stakingDhvTvl" && exportType === EXPORT_TYPE_DHV_STAKING)
|| (staking.tvl === "lpStakingTvl" && exportType === EXPORT_TYPE_POOL2 && (staking.isPool2 !== true))
|| (staking.tvl === "lpStakingTvl" && exportType !== EXPORT_TYPE_POOL2 && (staking.isPool2 === true))
) {
continue;
}
const tvls = await calculateTvlFunction(chain, staking.meta, block);
if (typeof tvls === 'string') {
sdk.util.sumSingleBalance(tvl, transform(staking.meta.tokenAddress), tvls)
} else {
for (let i = 0; i < tvls.length; i++) {
sdk.util.sumSingleBalance(tvl, transform(tvls[i][0]), tvls[i][1])
}
}
}
return tvl
}
async function ethereumTvl(timestamp, ethBlock, chainBlocks) {
return chainTvl('ethereum', chainBlocks, EXPORT_TYPE_TVL);
}
async function polygonTvl(timestamp, ethBlock, chainBlocks) {
return chainTvl('polygon', chainBlocks, EXPORT_TYPE_TVL);
}
async function bscTvl(timestamp, ethBlock, chainBlocks) {
return chainTvl('bsc', chainBlocks, EXPORT_TYPE_TVL);
}
async function xdaiTvl(timestamp, ethBlock, chainBlocks) {
return chainTvl('xdai', chainBlocks, EXPORT_TYPE_TVL);
}
async function ethereumStaking(timestamp, ethBlock, chainBlocks) {
return chainTvl('ethereum', chainBlocks, EXPORT_TYPE_DHV_STAKING);
}
async function polygonStaking(timestamp, ethBlock, chainBlocks) {
return chainTvl('polygon', chainBlocks, EXPORT_TYPE_DHV_STAKING);
}
async function bscStaking(timestamp, ethBlock, chainBlocks) {
return chainTvl('bsc', chainBlocks, EXPORT_TYPE_DHV_STAKING);
}
async function xdaiStaking(timestamp, ethBlock, chainBlocks) {
return chainTvl('xdai', chainBlocks, EXPORT_TYPE_DHV_STAKING);
}
async function ethereumPool2(timestamp, ethBlock, chainBlocks) {
return chainTvl('ethereum', chainBlocks, EXPORT_TYPE_POOL2);
}
async function polygonPool2(timestamp, ethBlock, chainBlocks) {
return chainTvl('polygon', chainBlocks, EXPORT_TYPE_POOL2);
}
async function bscPool2(timestamp, ethBlock, chainBlocks) {
return chainTvl('bsc', chainBlocks, EXPORT_TYPE_POOL2);
}
async function xdaiPool2(timestamp, ethBlock, chainBlocks) {
return chainTvl('xdai', chainBlocks, EXPORT_TYPE_POOL2);
}
module.exports = {
ethereum: {
tvl: ethereumTvl,
pool2: ethereumPool2,
staking: ethereumStaking
},
polygon: {
tvl: polygonTvl,
pool2: polygonPool2,
staking: polygonStaking
},
bsc: {
tvl: bscTvl,
pool2: bscPool2,
staking: bscStaking
},
xdai: {
tvl: xdaiTvl,
pool2: xdaiPool2,
staking: xdaiStaking
}
};