diff --git a/src/api/incentives/calculateAssetIncentivesApy.ts b/src/api/incentives/calculateAssetIncentivesApy.ts index 584695fa..bee28a91 100644 --- a/src/api/incentives/calculateAssetIncentivesApy.ts +++ b/src/api/incentives/calculateAssetIncentivesApy.ts @@ -1,5 +1,5 @@ import getMarket from 'api/markets/getMarket' -import getAssetIncentive from 'api/incentives/getAssetIncentive' +import getTotalActiveEmissionValue from 'api/incentives/getTotalActiveEmissionValue' import getUnderlyingLiquidityAmount from 'api/markets/getMarketUnderlyingLiquidityAmount' import { BN } from 'utils/helpers' import { SECONDS_IN_A_YEAR } from 'utils/constants' @@ -11,28 +11,26 @@ export default async function calculateAssetIncentivesApy( denom: string, ): Promise { try { - const [assetIncentive, market] = await Promise.all([getAssetIncentive(denom), getMarket(denom)]) + const [totalActiveEmissionValue, market] = await Promise.all([ + getTotalActiveEmissionValue(denom), + getMarket(denom), + ]) - if (!assetIncentive) return null + if (!totalActiveEmissionValue) return null - const [marketLiquidityAmount, assetPrice, baseAssetPrice] = await Promise.all([ + const [marketLiquidityAmount, assetPrice] = await Promise.all([ getUnderlyingLiquidityAmount(market), getPrice(denom), - getPrice(assetIncentive.denom), ]) const assetDecimals = (ASSETS.find(byDenom(denom)) as Asset).decimals - const baseDecimals = (ASSETS.find(byDenom(assetIncentive.denom)) as Asset).decimals const marketLiquidityValue = BN(marketLiquidityAmount) .shiftedBy(-assetDecimals) .multipliedBy(assetPrice) const marketReturns = BN(market.liquidityRate).multipliedBy(marketLiquidityValue) - const annualEmission = BN(assetIncentive.emission_rate) - .multipliedBy(SECONDS_IN_A_YEAR) - .shiftedBy(-baseDecimals) - .multipliedBy(baseAssetPrice) + const annualEmission = totalActiveEmissionValue.multipliedBy(SECONDS_IN_A_YEAR) const totalAnnualReturnsValue = annualEmission.plus(marketReturns) const incentivesApy = totalAnnualReturnsValue.dividedBy(marketLiquidityValue).multipliedBy(100) diff --git a/src/api/incentives/getAssetIncentive.ts b/src/api/incentives/getAssetIncentive.ts deleted file mode 100644 index dece84a1..00000000 --- a/src/api/incentives/getAssetIncentive.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { getIncentivesQueryClient } from 'api/cosmwasm-client' -import { ActiveEmission } from 'types/generated/mars-incentives/MarsIncentives.types' - -export default async function getAssetIncentive(denom: string): Promise { - try { - const client = await getIncentivesQueryClient() - const activeEmissions = await client.activeEmissions({ - collateralDenom: denom, - }) - - if (activeEmissions.length === 0) { - throw 'Asset has no active incentive emission.' - } - - // TODO: handle multiple emissions https://delphilabs.atlassian.net/browse/MP-3237 - return activeEmissions[0] - } catch (ex) { - return null - } -} diff --git a/src/api/incentives/getTotalActiveEmissionValue.ts b/src/api/incentives/getTotalActiveEmissionValue.ts new file mode 100644 index 00000000..5df183b3 --- /dev/null +++ b/src/api/incentives/getTotalActiveEmissionValue.ts @@ -0,0 +1,35 @@ +import { getIncentivesQueryClient } from 'api/cosmwasm-client' +import getPrice from 'api/prices/getPrice' +import { ASSETS } from 'constants/assets' +import { BN_ZERO } from 'constants/math' +import { byDenom } from 'utils/array' +import { BN } from 'utils/helpers' + +export default async function getTotalActiveEmissionValue( + denom: string, +): Promise { + try { + const client = await getIncentivesQueryClient() + const activeEmissions = await client.activeEmissions({ + collateralDenom: denom, + }) + + if (activeEmissions.length === 0) { + throw 'Asset has no active incentive emission.' + } + + const prices = await Promise.all( + activeEmissions.map((activeEmission) => getPrice(activeEmission.denom)), + ) + + return activeEmissions.reduce((accumulation, current, index) => { + const price = prices[index] + const decimals = ASSETS.find(byDenom(current.denom))?.decimals as number + const emissionValue = BN(current.emission_rate).shiftedBy(-decimals).multipliedBy(price) + + return accumulation.plus(emissionValue) + }, BN_ZERO) + } catch (ex) { + return null + } +}