From 3b67f7cd47fd570cb9e58045ec4585d6f46f84c7 Mon Sep 17 00:00:00 2001 From: Karelian Pie <78794805+karelianpie@users.noreply.github.com> Date: Wed, 13 Apr 2022 17:02:33 +1000 Subject: [PATCH] test: Add test for `EarningsInterface#assetHistoricEarnings` (#271) * test: Add test for EarningsInterface#assetHistoricEarnings * fix: Type `AssetHistoricEarningsResponse` * refactor: Use nullish coalescing operator * fix: Types * fix: Remove BlockLabel * fix: no-useless-computed-key * fix: Lint --- src/interfaces/earnings.spec.ts | 65 ++++++++++++++++++++++++++++++++- src/interfaces/earnings.ts | 52 ++++++++++++-------------- 2 files changed, 86 insertions(+), 31 deletions(-) diff --git a/src/interfaces/earnings.spec.ts b/src/interfaces/earnings.spec.ts index 2cbb5c09..2e1f4d00 100644 --- a/src/interfaces/earnings.spec.ts +++ b/src/interfaces/earnings.spec.ts @@ -270,8 +270,69 @@ describe("EarningsInterface", () => { }); }); - // eslint-disable-next-line @typescript-eslint/no-empty-function - describe.skip("assetHistoricEarnings", () => {}); + describe("assetHistoricEarnings", () => { + beforeEach(() => { + subgraphFetchQueryMock.mockResolvedValue({ + data: { + block_30380: { + strategies: [ + { + latestReport: { + totalGain: "303000000000000000000", + totalLoss: "80000000000000000000", + }, + }, + ], + vaultDayData: [{ timestamp: "1648887421" }], + }, + block_36140: { + strategies: [ + { + latestReport: { + totalGain: "361000000000000000000", + totalLoss: "40000000000000000000", + }, + }, + ], + vaultDayData: [{ timestamp: "1648801021" }], + }, + block_41900: { + strategies: [ + { + latestReport: { + totalGain: "419000000000000000000", + totalLoss: "0", + }, + }, + ], + vaultDayData: [{ timestamp: "1648714621" }], + }, + vault: { + token: { + id: "0xVaultTokenId", + decimals: "18", + }, + }, + }, + }); + oracleGetPriceUsdcMock.mockResolvedValue("6000000"); + }); + + it("should return the asset historic earnings", async () => { + const actual = await earningsInterface.assetHistoricEarnings("0x00", 3, 42000); + + expect(actual).toEqual({ + assetAddress: "0x00", + dayData: [ + { date: "2022-04-02T08:17:01.000Z", earnings: { amount: "223000000000000000000", amountUsdc: "1338000000" } }, + { date: "2022-04-01T08:17:01.000Z", earnings: { amount: "321000000000000000000", amountUsdc: "1926000000" } }, + { date: "2022-03-31T08:17:01.000Z", earnings: { amount: "419000000000000000000", amountUsdc: "2514000000" } }, + ], + decimals: "18", + }); + expect(actual.dayData.length).toEqual(3); + }); + }); // eslint-disable-next-line @typescript-eslint/no-empty-function describe.skip("accountHistoricEarnings", () => {}); diff --git a/src/interfaces/earnings.ts b/src/interfaces/earnings.ts index 5dea6f49..1ee876c9 100644 --- a/src/interfaces/earnings.ts +++ b/src/interfaces/earnings.ts @@ -27,9 +27,17 @@ import { EarningsDayData, EarningsUserData, } from "../types/custom/earnings"; +import { toBN } from "../utils"; const BigZero = new BigNumber(0); +interface StrategiesResponse { + latestReport?: { + totalGain: string; + totalLoss: string; + }; +} + export class EarningsInterface extends ServiceInterface { /** * @deprecated @@ -210,19 +218,7 @@ export class EarningsInterface extends ServiceInterface { fromDaysAgo: number, latestBlockNumber?: number ): Promise { - interface StrategiesResponse { - latestReport?: { - totalGain: string; - totalLoss: string; - }; - } - - let blockNumber: number; - if (latestBlockNumber) { - blockNumber = latestBlockNumber; - } else { - blockNumber = await this.ctx.provider.read.getBlockNumber(); - } + let blockNumber = latestBlockNumber ?? (await this.ctx.provider.read.getBlockNumber()); blockNumber -= this.blockOffset(); // subgraph might be slightly behind latest block @@ -231,32 +227,32 @@ export class EarningsInterface extends ServiceInterface { .map((day) => blockNumber - day * this.blocksPerDay()); // eslint-disable-next-line @typescript-eslint/no-explicit-any - const response = await this.yearn.services.subgraph.fetchQuery(ASSET_HISTORIC_EARNINGS(blocks), { + const { data } = await this.yearn.services.subgraph.fetchQuery(ASSET_HISTORIC_EARNINGS(blocks), { id: vault, }); - const data = response.data; - const labels = blocks.map((block) => `block_${block}`); - const token = data.vault.token.id as string; + const token = data.vault.token.id as Address; const priceUsdc = await this.yearn.services.oracle.getPriceUsdc(token).then((price) => new BigNumber(price)); const earningsDayData = labels.map((label) => { const strategies: StrategiesResponse[] = data[label].strategies; - const totalGain = strategies - .map((strategy) => (strategy.latestReport ? new BigNumber(strategy.latestReport.totalGain) : new BigNumber(0))) - .reduce((sum, value) => sum.plus(value)); - const totalLoss = strategies - .map((strategy) => (strategy.latestReport ? new BigNumber(strategy.latestReport.totalLoss) : new BigNumber(0))) - .reduce((sum, value) => sum.plus(value)); + const { totalGain, totalLoss } = strategies.reduce( + ({ totalGain, totalLoss }, { latestReport }) => { + if (latestReport) { + totalGain = totalGain.plus(toBN(latestReport.totalGain)); + totalLoss = totalLoss.plus(toBN(latestReport.totalLoss)); + } + return { totalGain, totalLoss }; + }, + { totalGain: toBN(0), totalLoss: toBN(0) } + ); const amountEarnt = totalGain.minus(totalLoss); - const amountUsdc = priceUsdc - .multipliedBy(amountEarnt) - .dividedBy(new BigNumber(10).pow(new BigNumber(data.vault.token.decimals))); + const amountUsdc = priceUsdc.multipliedBy(amountEarnt).dividedBy(toBN(10).pow(toBN(data.vault.token.decimals))); const dayData: EarningsDayData = { earnings: { @@ -269,13 +265,11 @@ export class EarningsInterface extends ServiceInterface { return dayData; }); - const result: AssetHistoricEarnings = { + return { assetAddress: vault, dayData: earningsDayData, decimals: data.vault.token.decimals, }; - - return result; } async accountHistoricEarnings(