From d6344051c611633feed718e98f1b22b15b624ba8 Mon Sep 17 00:00:00 2001 From: gmbronco <83549293+gmbronco@users.noreply.github.com> Date: Thu, 19 Oct 2023 12:27:06 +0200 Subject: [PATCH] YB tokens refactor, new Maker on Gnosis source (#489) * simplified yb tokens apr handler * adding maker gnosis self-config handler * pass configuration to services * ignore debug scripts * removing leftover console.log * adding maker apr type * dep info --- .gitignore | 2 +- modules/network/arbitrum.ts | 9 +- modules/network/avalanche.ts | 9 +- modules/network/base.ts | 7 +- modules/network/fantom.ts | 9 +- modules/network/gnosis.ts | 9 +- modules/network/mainnet.ts | 9 +- modules/network/optimism.ts | 9 +- modules/network/polygon.ts | 9 +- modules/network/zkevm.ts | 9 +- .../ib-linear-apr-handlers.ts | 222 +++++++----------- .../sources/aave-apr-handler.ts | 9 +- .../sources/ankr-apr-handler.ts | 14 +- .../sources/beefy-apr-handler.ts | 25 +- .../sources/bloom-apr-handler.ts | 16 +- .../sources/default-apr-handler.ts | 12 +- .../sources/euler-apr-handler.ts | 1 + .../sources/gearbox-apr-handler.ts | 6 +- .../sources/idle-apr-handler.ts | 6 +- .../ib-linear-apr-handlers/sources/index.ts | 16 ++ .../sources/maker-apr-handler.ts | 12 +- .../sources/maker-gnosis-apr-handler.ts | 36 +++ .../sources/ovix-apr-handler.ts | 1 + .../sources/reaper-crypt-apr-handler.ts | 8 +- .../sources/tessera-apr-handler.ts | 6 +- .../sources/tetu-apr-handler.ts | 1 + .../sources/tranchess-apr-handler.ts | 6 +- .../sources/yearn-apr-handler.ts | 8 +- .../apr-data-sources/ib-tokens-apr.service.ts | 22 +- .../phantom-stable-apr.service.ts | 14 +- modules/pool/lib/pool-usd-data.service.ts | 4 + .../pool/lib/staking/gauge-staking.service.ts | 2 - modules/pool/pool.prisma | 1 + .../migration.sql | 2 + prisma/schema.prisma | 1 + tsconfig.json | 6 +- 36 files changed, 324 insertions(+), 214 deletions(-) create mode 100644 modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/index.ts create mode 100644 modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/maker-gnosis-apr-handler.ts create mode 100644 prisma/migrations/20231019072204_adding_maker_apr_group/migration.sql diff --git a/.gitignore b/.gitignore index f570c71dc..709b8be0b 100644 --- a/.gitignore +++ b/.gitignore @@ -9,9 +9,9 @@ node_modules/ *-error.log **/generated/* +debug debug.ts schema.ts -debug.ts graphql_schema_generated*.ts i18n/* google-service-account.json diff --git a/modules/network/arbitrum.ts b/modules/network/arbitrum.ts index 2b933ed32..a4de660bb 100644 --- a/modules/network/arbitrum.ts +++ b/modules/network/arbitrum.ts @@ -225,8 +225,13 @@ export const arbitrumNetworkConfig: NetworkConfig = { contentService: new GithubContentService(), provider: new ethers.providers.JsonRpcProvider({ url: arbitrumNetworkData.rpcUrl, timeout: 60000 }), poolAprServices: [ - new IbTokensAprService(arbitrumNetworkData.ibAprConfig), - new PhantomStableAprService(), + new IbTokensAprService( + arbitrumNetworkData.ibAprConfig, + arbitrumNetworkData.chain.prismaId, + arbitrumNetworkData.balancer.yieldProtocolFeePercentage, + arbitrumNetworkData.balancer.swapProtocolFeePercentage + ), + new PhantomStableAprService(arbitrumNetworkData.chain.prismaId, arbitrumNetworkData.balancer.yieldProtocolFeePercentage), new BoostedPoolAprService(), new SwapFeeAprService(arbitrumNetworkData.balancer.swapProtocolFeePercentage), new GaugeAprService(tokenService, [arbitrumNetworkData.bal!.address]), diff --git a/modules/network/avalanche.ts b/modules/network/avalanche.ts index fb0b432fa..814cae39f 100644 --- a/modules/network/avalanche.ts +++ b/modules/network/avalanche.ts @@ -217,8 +217,13 @@ export const avalancheNetworkConfig: NetworkConfig = { contentService: new GithubContentService(), provider: new ethers.providers.JsonRpcProvider({ url: avalancheNetworkData.rpcUrl, timeout: 60000 }), poolAprServices: [ - new IbTokensAprService(avalancheNetworkData.ibAprConfig), - new PhantomStableAprService(), + new IbTokensAprService( + avalancheNetworkData.ibAprConfig, + avalancheNetworkData.chain.prismaId, + avalancheNetworkData.balancer.yieldProtocolFeePercentage, + avalancheNetworkData.balancer.swapProtocolFeePercentage + ), + new PhantomStableAprService(avalancheNetworkData.chain.prismaId, avalancheNetworkData.balancer.yieldProtocolFeePercentage), new BoostedPoolAprService(), new SwapFeeAprService(avalancheNetworkData.balancer.swapProtocolFeePercentage), new GaugeAprService(tokenService, [avalancheNetworkData.bal!.address]), diff --git a/modules/network/base.ts b/modules/network/base.ts index e7f00f4d8..d50b492e8 100644 --- a/modules/network/base.ts +++ b/modules/network/base.ts @@ -119,7 +119,12 @@ export const baseNetworkConfig: NetworkConfig = { contentService: new GithubContentService(), provider: new ethers.providers.JsonRpcProvider({ url: baseNetworkData.rpcUrl, timeout: 60000 }), poolAprServices: [ - new IbTokensAprService(baseNetworkData.ibAprConfig), + new IbTokensAprService( + baseNetworkData.ibAprConfig, + baseNetworkData.chain.prismaId, + baseNetworkData.balancer.yieldProtocolFeePercentage, + baseNetworkData.balancer.swapProtocolFeePercentage + ), new BoostedPoolAprService(), new SwapFeeAprService(baseNetworkData.balancer.swapProtocolFeePercentage), new GaugeAprService(tokenService, [baseNetworkData.bal!.address]), diff --git a/modules/network/fantom.ts b/modules/network/fantom.ts index 16d4a7d56..c0846e05d 100644 --- a/modules/network/fantom.ts +++ b/modules/network/fantom.ts @@ -300,9 +300,14 @@ export const fantomNetworkConfig: NetworkConfig = { contentService: new SanityContentService(), provider: new ethers.providers.JsonRpcProvider({ url: fantomNetworkData.rpcUrl, timeout: 60000 }), poolAprServices: [ - new IbTokensAprService(fantomNetworkData.ibAprConfig), + new IbTokensAprService( + fantomNetworkData.ibAprConfig, + fantomNetworkData.chain.prismaId, + fantomNetworkData.balancer.yieldProtocolFeePercentage, + fantomNetworkData.balancer.swapProtocolFeePercentage + ), // new SpookySwapAprService(tokenService, fantomNetworkData.spooky!.xBooContract), - new PhantomStableAprService(), + new PhantomStableAprService(fantomNetworkData.chain.prismaId, fantomNetworkData.balancer.yieldProtocolFeePercentage), new BoostedPoolAprService(), new SwapFeeAprService(fantomNetworkData.balancer.swapProtocolFeePercentage), new MasterchefFarmAprService(fantomNetworkData.beets!.address), diff --git a/modules/network/gnosis.ts b/modules/network/gnosis.ts index f5780ac4f..20ff09076 100644 --- a/modules/network/gnosis.ts +++ b/modules/network/gnosis.ts @@ -143,8 +143,13 @@ export const gnosisNetworkConfig: NetworkConfig = { contentService: new GithubContentService(), provider: new ethers.providers.JsonRpcProvider({ url: gnosisNetworkData.rpcUrl, timeout: 60000 }), poolAprServices: [ - new IbTokensAprService(gnosisNetworkData.ibAprConfig), - new PhantomStableAprService(), + new IbTokensAprService( + gnosisNetworkData.ibAprConfig, + gnosisNetworkData.chain.prismaId, + gnosisNetworkData.balancer.yieldProtocolFeePercentage, + gnosisNetworkData.balancer.swapProtocolFeePercentage, + ), + new PhantomStableAprService(gnosisNetworkData.chain.prismaId, gnosisNetworkData.balancer.yieldProtocolFeePercentage), new BoostedPoolAprService(), new SwapFeeAprService(gnosisNetworkData.balancer.swapProtocolFeePercentage), new GaugeAprService(tokenService, [gnosisNetworkData.bal!.address]), diff --git a/modules/network/mainnet.ts b/modules/network/mainnet.ts index c41b220c5..11911007b 100644 --- a/modules/network/mainnet.ts +++ b/modules/network/mainnet.ts @@ -364,8 +364,13 @@ export const mainnetNetworkConfig: NetworkConfig = { contentService: new GithubContentService(), provider: new ethers.providers.JsonRpcProvider({ url: mainnetNetworkData.rpcUrl, timeout: 60000 }), poolAprServices: [ - new IbTokensAprService(mainnetNetworkData.ibAprConfig), - new PhantomStableAprService(), + new IbTokensAprService( + mainnetNetworkData.ibAprConfig, + mainnetNetworkData.chain.prismaId, + mainnetNetworkData.balancer.yieldProtocolFeePercentage, + mainnetNetworkData.balancer.swapProtocolFeePercentage + ), + new PhantomStableAprService(mainnetNetworkData.chain.prismaId, mainnetNetworkData.balancer.yieldProtocolFeePercentage), new BoostedPoolAprService(), new SwapFeeAprService(mainnetNetworkData.balancer.swapProtocolFeePercentage), new GaugeAprService(tokenService, [mainnetNetworkData.bal!.address]), diff --git a/modules/network/optimism.ts b/modules/network/optimism.ts index 730d8e55e..d122e7a5f 100644 --- a/modules/network/optimism.ts +++ b/modules/network/optimism.ts @@ -258,8 +258,13 @@ export const optimismNetworkConfig: NetworkConfig = { contentService: new SanityContentService(), provider: new ethers.providers.JsonRpcProvider({ url: optimismNetworkData.rpcUrl, timeout: 60000 }), poolAprServices: [ - new IbTokensAprService(optimismNetworkData.ibAprConfig), - new PhantomStableAprService(), + new IbTokensAprService( + optimismNetworkData.ibAprConfig, + optimismNetworkData.chain.prismaId, + optimismNetworkData.balancer.yieldProtocolFeePercentage, + optimismNetworkData.balancer.swapProtocolFeePercentage, + ), + new PhantomStableAprService(optimismNetworkData.chain.prismaId, optimismNetworkData.balancer.yieldProtocolFeePercentage), new BoostedPoolAprService(), new SwapFeeAprService(optimismNetworkData.balancer.swapProtocolFeePercentage), new GaugeAprService(tokenService, [ diff --git a/modules/network/polygon.ts b/modules/network/polygon.ts index f5041268b..38ccc9889 100644 --- a/modules/network/polygon.ts +++ b/modules/network/polygon.ts @@ -262,8 +262,13 @@ export const polygonNetworkConfig: NetworkConfig = { contentService: new GithubContentService(), provider: new ethers.providers.JsonRpcProvider({ url: polygonNetworkData.rpcUrl, timeout: 60000 }), poolAprServices: [ - new IbTokensAprService(polygonNetworkData.ibAprConfig), - new PhantomStableAprService(), + new IbTokensAprService( + polygonNetworkData.ibAprConfig, + polygonNetworkData.chain.prismaId, + polygonNetworkData.balancer.yieldProtocolFeePercentage, + polygonNetworkData.balancer.swapProtocolFeePercentage + ), + new PhantomStableAprService(polygonNetworkData.chain.prismaId, polygonNetworkData.balancer.yieldProtocolFeePercentage), new BoostedPoolAprService(), new SwapFeeAprService(polygonNetworkData.balancer.swapProtocolFeePercentage), new GaugeAprService(tokenService, [polygonNetworkData.bal!.address]), diff --git a/modules/network/zkevm.ts b/modules/network/zkevm.ts index b87b04156..2f976e611 100644 --- a/modules/network/zkevm.ts +++ b/modules/network/zkevm.ts @@ -162,8 +162,13 @@ export const zkevmNetworkConfig: NetworkConfig = { contentService: new GithubContentService(), provider: new ethers.providers.JsonRpcProvider({ url: zkevmNetworkData.rpcUrl, timeout: 60000 }), poolAprServices: [ - new IbTokensAprService(zkevmNetworkData.ibAprConfig), - new PhantomStableAprService(), + new IbTokensAprService( + zkevmNetworkData.ibAprConfig, + zkevmNetworkData.chain.prismaId, + zkevmNetworkData.balancer.yieldProtocolFeePercentage, + zkevmNetworkData.balancer.swapProtocolFeePercentage, + ), + new PhantomStableAprService(zkevmNetworkData.chain.prismaId, zkevmNetworkData.balancer.yieldProtocolFeePercentage), new BoostedPoolAprService(), new SwapFeeAprService(zkevmNetworkData.balancer.swapProtocolFeePercentage), new GaugeAprService(tokenService, [zkevmNetworkData.bal!.address]), diff --git a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/ib-linear-apr-handlers.ts b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/ib-linear-apr-handlers.ts index 6b3ae0816..4f399d649 100644 --- a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/ib-linear-apr-handlers.ts +++ b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/ib-linear-apr-handlers.ts @@ -1,169 +1,113 @@ -import { AaveAprHandler } from './sources/aave-apr-handler'; -import { AnkrAprHandler } from './sources/ankr-apr-handler'; -import { DefaultAprHandler } from './sources/default-apr-handler'; -import { EulerAprHandler } from './sources/euler-apr-handler'; -import { GearboxAprHandler } from './sources/gearbox-apr-handler'; -import { IdleAprHandler } from './sources/idle-apr-handler'; -import { OvixAprHandler } from './sources/ovix-apr-handler'; -import { TesseraAprHandler } from './sources/tessera-apr-handler'; -import { TetuAprHandler } from './sources/tetu-apr-handler'; -import { TranchessAprHandler } from './sources/tranchess-apr-handler'; -import { YearnAprHandler } from './sources/yearn-apr-handler'; -import { ReaperCryptAprHandler } from './sources/reaper-crypt-apr-handler'; -import { BeefyAprHandler } from './sources/beefy-apr-handler'; +import * as sources from './sources'; import { IbAprConfig } from '../../../../network/apr-config-types'; -import { MakerAprHandler } from './sources/maker-apr-handler'; -import { BloomAprHandler } from './sources/bloom-apr-handler'; +import { Chain } from '@prisma/client'; + +const sourceToHandler = { + aave: sources.AaveAprHandler, + ankr: sources.AnkrAprHandler, + beefy: sources.BeefyAprHandler, + bloom: sources.BloomAprHandler, + euler: sources.EulerAprHandler, + gearbox: sources.GearboxAprHandler, + idle: sources.IdleAprHandler, + maker: sources.MakerAprHandler, + ovix: sources.OvixAprHandler, + reaper: sources.ReaperCryptAprHandler, + tessera: sources.TesseraAprHandler, + tetu: sources.TetuAprHandler, + tranchess: sources.TranchessAprHandler, + yearn: sources.YearnAprHandler, + defaultHandlers: sources.DefaultAprHandler, +} export class IbLinearAprHandlers { private handlers: AprHandler[] = []; fixedAprTokens?: { [tokenName: string]: { address: string; apr: number; group?: string; isIbYield?: boolean } }; - constructor(aprConfig: IbAprConfig) { - this.handlers = this.buildAprHandlers(aprConfig); - this.fixedAprTokens = aprConfig.fixedAprHandler; + constructor(aprConfig: IbAprConfig, private chain?: Chain) { + const { fixedAprHandler, ...config } = aprConfig; + this.handlers = this.buildAprHandlers(config); + this.fixedAprTokens = fixedAprHandler; } - buildAprHandlers(aprConfig: IbAprConfig) { + private buildAprHandlers(aprConfig: IbAprConfig) { const handlers: AprHandler[] = []; - if (aprConfig.aave) { - for (const config of Object.values(aprConfig.aave)) { - const aaveHandler = new AaveAprHandler(config); - handlers.push(aaveHandler); - } - } - if (aprConfig.ankr) { - const ankrHandler = new AnkrAprHandler(aprConfig.ankr); - handlers.push(ankrHandler); - } - if (aprConfig.beefy) { - const beefyHandler = new BeefyAprHandler(aprConfig.beefy); - handlers.push(beefyHandler); - } - if (aprConfig.bloom) { - const bloomAprHandler = new BloomAprHandler(aprConfig.bloom); - handlers.push(bloomAprHandler); - } - if (aprConfig.euler) { - const eulerHandler = new EulerAprHandler(aprConfig.euler); - handlers.push(eulerHandler); - } - if (aprConfig.gearbox) { - const gearboxHandler = new GearboxAprHandler(aprConfig.gearbox); - handlers.push(gearboxHandler); - } - if (aprConfig.idle) { - const idleHandler = new IdleAprHandler(aprConfig.idle); - handlers.push(idleHandler); - } - if (aprConfig.maker) { - const makerHandler = new MakerAprHandler(aprConfig.maker); - handlers.push(makerHandler); - } - if (aprConfig.ovix) { - const ovixHandler = new OvixAprHandler({ - ...aprConfig.ovix, - }); - handlers.push(ovixHandler); - } - if (aprConfig.reaper) { - const reaperCryptHandler = new ReaperCryptAprHandler({ ...aprConfig.reaper }); - handlers.push(reaperCryptHandler); - } - if (aprConfig.tessera) { - const tesseraHandler = new TesseraAprHandler({ - ...aprConfig.tessera, - }); - handlers.push(tesseraHandler); - } - if (aprConfig.tetu) { - const tetuHandler = new TetuAprHandler(aprConfig.tetu); - handlers.push(tetuHandler); - } - if (aprConfig.tranchess) { - const tranchessHandler = new TranchessAprHandler(aprConfig.tranchess); - handlers.push(tranchessHandler); - } - if (aprConfig.yearn) { - const yearnHandler = new YearnAprHandler(aprConfig.yearn); - handlers.push(yearnHandler); - } - if (aprConfig.defaultHandlers) { - for (const handlerConfig of Object.values(aprConfig.defaultHandlers)) { - const handler = new DefaultAprHandler(handlerConfig); - handlers.push(handler); + + // Add handlers from global configuration + for (const [source, config] of Object.entries(aprConfig)) { + const Handler = sourceToHandler[source as keyof typeof sourceToHandler]; + + // Handle nested configs + if (source === 'aave' || source === 'defaultHandlers') { + for (const nestedConfig of Object.values(config)) { + handlers.push(new Handler(nestedConfig as any)); + } + } else { + handlers.push(new Handler(config)); } } - return handlers; - } - // Any IB Yield tokens (such as rETH, wstETH) need to be added here. Linear Wrapped Tokens must NOT be added here. - buildIbYieldTokens(aprConfig: IbAprConfig): string[] { - const ibYieldTokenNamesForDefaultHandler = [ - 'rEth', - 'stETH', - 'wstETH', - 'cbETH', - 'sfrxETH', - 'USDR', - 'swETH', - 'wjAURA', - 'qETH', - 'ankrETH', - 'ankrFTM', - 'sFTMx', - 'stMATIC', - 'MATICX', - 'wbETH', - 'ETHx', - ].map((token) => token.toLowerCase()); + // Add handlers from self-configured sources + Object.values(sources as unknown as any[]) + .filter((source): source is { chains: Chain[], Handler: AprHandlerConstructor } => 'chains' in source) + .filter((source) => this.chain && source.chains.includes(this.chain)) + .forEach((source) => { + handlers.push(new source.Handler()); + }); - return [ - ...Object.values(aprConfig?.ankr?.tokens || {}).map((token) => token.address), - ...Object.keys(aprConfig?.defaultHandlers || {}).filter((handler) => - ibYieldTokenNamesForDefaultHandler.includes(handler.toLowerCase()), - ), - ...Object.keys(aprConfig?.fixedAprHandler || {}).filter((handler) => - ibYieldTokenNamesForDefaultHandler.includes(handler.toLowerCase()), - ), - ]; + return handlers; } async fetchAprsFromAllHandlers(): Promise { - let aprs: TokenApr[] = []; - for (const handler of this.handlers) { - const fetchedResponse: { [key: string]: { apr: number; isIbYield: boolean } } = await handler.getAprs(); - for (const [address, { apr, isIbYield }] of Object.entries(fetchedResponse)) { - aprs.push({ - apr, - isIbYield, - group: handler.group, - address, - }); - } - } - if (this.fixedAprTokens) { - for (const { address, apr, isIbYield, group } of Object.values(this.fixedAprTokens)) { - aprs.push({ - apr, - isIbYield: isIbYield ?? false, - group, - address, - }); + let aprs: TokenApr[] = this.fixedAprTokens + ? Object.values(this.fixedAprTokens).map(({ address, apr, isIbYield, group }) => ({ + apr, + address, + isIbYield: isIbYield ?? false, + group + })) + : []; + + const results = await Promise.allSettled(this.handlers.map((handler) => handler.getAprs(this.chain))); + + for (const result of results) { + if (result.status === 'fulfilled') { + aprs = aprs.concat( + Object.entries(result.value).map(([address, { apr, isIbYield, group }]) => ({ + apr, + address, + isIbYield, + group + })), + ); + } else { + console.error('Failed to fetch APRs from handler', result.reason); } } + return aprs; } } +interface AprHandlerConstructor { + new (config?: any): AprHandler; +} + export interface AprHandler { - group: string | undefined; - getAprs(): Promise<{ [tokenAddress: string]: { apr: number; isIbYield: boolean } }>; + group?: string; + getAprs(chain?: Chain): Promise<{ + [tokenAddress: string]: { + /** Defined as float, eg: 0.01 is 1% */ + apr: number; + isIbYield: boolean + group?: string; + } + }>; } export type TokenApr = { apr: number; address: string; - group?: string; isIbYield: boolean; + group?: string; }; diff --git a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/aave-apr-handler.ts b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/aave-apr-handler.ts index f2b72156b..5312b1985 100644 --- a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/aave-apr-handler.ts +++ b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/aave-apr-handler.ts @@ -14,8 +14,7 @@ export class AaveAprHandler implements AprHandler { }; }; subgraphUrl: string; - - readonly group = 'AAVE'; + group = 'AAVE'; readonly query = `query getReserves($aTokens: [String!], $underlyingAssets: [Bytes!]) { reserves( @@ -81,7 +80,11 @@ export class AaveAprHandler implements AprHandler { .map(({ wrappedTokens, underlyingAssetAddress, isIbYield }) => { const apr = aprsByUnderlyingAddress[underlyingAssetAddress]; return Object.values(wrappedTokens).map((wrappedTokenAddress) => ({ - [wrappedTokenAddress]: { apr, isIbYield: isIbYield ?? false }, + [wrappedTokenAddress]: { + apr, + isIbYield: isIbYield ?? false, + group: this.group, + }, })); }) .flat() diff --git a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/ankr-apr-handler.ts b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/ankr-apr-handler.ts index 2f89875ed..86c4e446d 100644 --- a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/ankr-apr-handler.ts +++ b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/ankr-apr-handler.ts @@ -12,14 +12,13 @@ export class AnkrAprHandler implements AprHandler { }; }; url: string; - readonly group = undefined; - constructor(aprHandlerConfig: AnkrAprConfig) { - this.tokens = aprHandlerConfig.tokens; - this.url = aprHandlerConfig.sourceUrl; + constructor(config: AnkrAprConfig) { + this.tokens = config.tokens; + this.url = config.sourceUrl; } - async getAprs(): Promise<{ [tokenAddress: string]: { apr: number; isIbYield: boolean } }> { + async getAprs() { try { const { data } = await axios.get(this.url); const services = (data as { services: { serviceName: string; apy: string }[] }).services; @@ -29,7 +28,10 @@ export class AnkrAprHandler implements AprHandler { if (!service) { return [address, 0]; } - return [address, { apr: parseFloat(service.apy) / 1e2, isIbYield: isIbYield ?? false }]; + return [address, { + apr: parseFloat(service.apy) / 1e2, + isIbYield: isIbYield ?? false, + }]; }), ); return aprs; diff --git a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/beefy-apr-handler.ts b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/beefy-apr-handler.ts index 1a6e50fef..98e44bea3 100644 --- a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/beefy-apr-handler.ts +++ b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/beefy-apr-handler.ts @@ -12,20 +12,27 @@ export class BeefyAprHandler implements AprHandler { }; }; sourceUrl: string; - group: string | undefined = 'BEEFY'; + group = 'BEEFY'; - constructor(aprConfig: BeefyAprConfig) { - this.tokens = aprConfig.tokens; - this.sourceUrl = aprConfig.sourceUrl; + constructor(config: BeefyAprConfig) { + this.tokens = config.tokens; + this.sourceUrl = config.sourceUrl; } - async getAprs(): Promise<{ [p: string]: { apr: number; isIbYield: boolean } }> { + async getAprs() { try { const { data: aprData } = await axios.get(this.sourceUrl); - const aprs: { [tokenAddress: string]: { apr: number; isIbYield: boolean } } = {}; - for (const { address, vaultId, isIbYield } of Object.values(this.tokens)) { - aprs[address] = { apr: aprData[vaultId].vaultApr, isIbYield: isIbYield ?? false }; - } + const aprs = Object.values(this.tokens).map(({ address, vaultId, isIbYield }) => { + const apr = aprData[vaultId]?.vaultApr ?? 0; + return { + [address]: { + apr, + isIbYield: isIbYield ?? false, + group: this.group + } + }; + }); + return aprs; } catch (error) { console.error(`Beefy IB APR hanlder failed: `, error); diff --git a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/bloom-apr-handler.ts b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/bloom-apr-handler.ts index fed2cc55c..3f7e352ed 100644 --- a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/bloom-apr-handler.ts +++ b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/bloom-apr-handler.ts @@ -5,16 +5,16 @@ import { abi as bloomBpsFeed } from './abis/bloom-bps-feed'; import * as Sentry from '@sentry/node'; export class BloomAprHandler implements AprHandler { - group: string | undefined; + group = "BLOOM"; tokens: BloomAprConfig['tokens']; - constructor(aprConfig: BloomAprConfig) { - this.tokens = aprConfig.tokens; + constructor(config: BloomAprConfig) { + this.tokens = config.tokens; } - async getAprs(): Promise<{ [p: string]: { apr: number; isIbYield: boolean } }> { - const aprs: { [p: string]: { apr: number; isIbYield: boolean } } = {}; + async getAprs() { + const aprs: { [p: string]: { apr: number; isIbYield: boolean, group?: string } } = {}; for (const { address, feedAddress, isIbYield } of Object.values(this.tokens)) { try { const feedContract = getContractAt(feedAddress, bloomBpsFeed); @@ -23,7 +23,11 @@ export class BloomAprHandler implements AprHandler { continue; } const tokenApr = (Number(currentRate) - 10000) / 10000; - aprs[address] = { apr: tokenApr, isIbYield: isIbYield ?? false }; + aprs[address] = { + apr: tokenApr, + isIbYield: isIbYield ?? false, + group: this.group + }; } catch (error) { console.error(`Bloom APR Failed for token ${address}: `, error); Sentry.captureException(`Bloom APR Failed for token ${address}: ${error}`); diff --git a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/default-apr-handler.ts b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/default-apr-handler.ts index e48dc0b4e..3e393f780 100644 --- a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/default-apr-handler.ts +++ b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/default-apr-handler.ts @@ -8,8 +8,8 @@ export class DefaultAprHandler implements AprHandler { url: string; path: string; scale: number; - group: string | undefined = undefined; - isIbYield: boolean | undefined; + group?: string; + isIbYield?: boolean; constructor(aprHandlerConfig: { sourceUrl: string; @@ -33,7 +33,13 @@ export class DefaultAprHandler implements AprHandler { const value = this.path === '' ? data : this.getValueFromPath(data, this.path); const scaledValue = parseFloat(value) / this.scale; - return { [this.tokenAddress]: { apr: scaledValue, isIbYield: this.isIbYield ?? false } }; + return { + [this.tokenAddress]: { + apr: scaledValue, + isIbYield: this.isIbYield ?? false, + group: this.group + } + }; } catch (error) { console.error(`Failed to fetch APRs in url ${this.url}:`, error); Sentry.captureException(`Failed to fetch default IB APRs in url ${this.url}: ${error}`); diff --git a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/euler-apr-handler.ts b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/euler-apr-handler.ts index f6edc5479..960954f78 100644 --- a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/euler-apr-handler.ts +++ b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/euler-apr-handler.ts @@ -60,6 +60,7 @@ export class EulerAprHandler implements AprHandler { Object.values(this.tokens).find( ({ address }) => address.toLowerCase() === eTokenAddress.toLowerCase(), )?.isIbYield ?? false, + group: this.group, }, ]); diff --git a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/gearbox-apr-handler.ts b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/gearbox-apr-handler.ts index 96e77624d..490d6f441 100644 --- a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/gearbox-apr-handler.ts +++ b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/gearbox-apr-handler.ts @@ -31,7 +31,11 @@ export class GearboxAprHandler implements AprHandler { ); return [ dieselToken, - { apr: Number(depositAPY_RAY.slice(0, 27)) / 1e27, isIbYield: tokenObj?.isIbYield ?? false }, + { + apr: Number(depositAPY_RAY.slice(0, 27)) / 1e27, + isIbYield: tokenObj?.isIbYield ?? false, + group: this.group, + }, ]; }); return Object.fromEntries(aprEntries); diff --git a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/idle-apr-handler.ts b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/idle-apr-handler.ts index 3782bf6e4..24857b410 100644 --- a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/idle-apr-handler.ts +++ b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/idle-apr-handler.ts @@ -32,7 +32,11 @@ export class IdleAprHandler implements AprHandler { }); const [json] = data as { idleRate: string }[]; const value = Number(json.idleRate) / 1e20; - return [wrapped4626Address, { apr: value, isIbYield: isIbYield ?? false }]; + return [wrapped4626Address, { + apr: value, + isIbYield: isIbYield ?? false, + group: this.group, + }]; }); const res = Array(Object.keys(this.tokens).length); for (const [index, aprPromise] of aprPromises.entries()) { diff --git a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/index.ts b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/index.ts new file mode 100644 index 000000000..94a5dff90 --- /dev/null +++ b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/index.ts @@ -0,0 +1,16 @@ +export * from './aave-apr-handler'; +export * from './ankr-apr-handler'; +export * from './default-apr-handler'; +export * from './euler-apr-handler'; +export * from './gearbox-apr-handler'; +export * from './idle-apr-handler'; +export * from './ovix-apr-handler'; +export * from './tessera-apr-handler'; +export * from './tetu-apr-handler'; +export * from './tranchess-apr-handler'; +export * from './yearn-apr-handler'; +export * from './reaper-crypt-apr-handler'; +export * from './beefy-apr-handler'; +export * from './maker-apr-handler'; +export * as MakerGnosis from './maker-gnosis-apr-handler'; +export * from './bloom-apr-handler'; diff --git a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/maker-apr-handler.ts b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/maker-apr-handler.ts index 20220f187..0b47bf9be 100644 --- a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/maker-apr-handler.ts +++ b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/maker-apr-handler.ts @@ -5,7 +5,7 @@ import { abi as makerPotAbi } from './abis/maker-pot'; import * as Sentry from '@sentry/node'; export class MakerAprHandler implements AprHandler { - group: string | undefined; + group = 'MAKER'; tokens: { [tokenName: string]: { address: string; @@ -18,8 +18,8 @@ export class MakerAprHandler implements AprHandler { this.tokens = aprConfig.tokens; } - async getAprs(): Promise<{ [p: string]: { apr: number; isIbYield: boolean } }> { - const aprs: { [p: string]: { apr: number; isIbYield: boolean } } = {}; + async getAprs() { + const aprs: { [p: string]: { apr: number; isIbYield: boolean, group: string } } = {}; for (const { address, potAddress, isIbYield } of Object.values(this.tokens)) { try { const potContract = getContractAt(potAddress, makerPotAbi); @@ -28,7 +28,11 @@ export class MakerAprHandler implements AprHandler { continue; } const tokenApr = (Number(dsr) * 10 ** -27 - 1) * 365 * 24 * 60 * 60; - aprs[address] = { apr: tokenApr, isIbYield: isIbYield ?? false }; + aprs[address] = { + apr: tokenApr, + isIbYield: isIbYield ?? false, + group: this.group + }; } catch (error) { console.error(`Maker APR Failed for token ${address}: `, error); Sentry.captureException(`Maker APR Failed for token ${address}: ${error}`); diff --git a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/maker-gnosis-apr-handler.ts b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/maker-gnosis-apr-handler.ts new file mode 100644 index 000000000..a89220193 --- /dev/null +++ b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/maker-gnosis-apr-handler.ts @@ -0,0 +1,36 @@ +import { AprHandler } from '../ib-linear-apr-handlers'; +import { getContractAt } from '../../../../../web3/contract'; +import { Chain } from '@prisma/client'; + +const helperAbi = ['function vaultAPY() view returns (uint256)']; + +/** Sets the config data used internally */ +const config = { + "GNOSIS": { + sdaiAddress: '0xaf204776c7245bf4147c2612bf6e5972ee483701', + helperAddress: '0xd499b51fcfc66bd31248ef4b28d656d67e591a94', + } +} + +/** Makes handler callable by chain */ +export const chains = Object.keys(config) as Chain[]; + +export class Handler implements AprHandler { + async getAprs(chain: Chain) { + if (chain !== 'GNOSIS') { + throw `Handler supports GNOSIS only, but called for ${chain}` + } + + const helper = getContractAt(config[chain].helperAddress, helperAbi); + const vaultAPY = await helper.vaultAPY(); + const apr = Number(vaultAPY) * (10 ** -18); + + return { + [config[chain].sdaiAddress]: { + apr, + isIbYield: true, + group: 'MAKER' + } + } + } +} diff --git a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/ovix-apr-handler.ts b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/ovix-apr-handler.ts index 3f3d0a7e1..a8206b52d 100644 --- a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/ovix-apr-handler.ts +++ b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/ovix-apr-handler.ts @@ -30,6 +30,7 @@ export class OvixAprHandler implements AprHandler { { apr: Math.pow(1 + (borrowRate as BigNumber).toNumber() / 1e18, 365 * 24 * 60 * 60) - 1, isIbYield: isIbYield ?? false, + group: this.group, }, ]; }); diff --git a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/reaper-crypt-apr-handler.ts b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/reaper-crypt-apr-handler.ts index a9d0196d7..6acf75005 100644 --- a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/reaper-crypt-apr-handler.ts +++ b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/reaper-crypt-apr-handler.ts @@ -45,7 +45,7 @@ export class ReaperCryptAprHandler implements AprHandler { this.averageAPRAcrossLastNHarvests = aprConfig.onchainSource?.averageAPRAcrossLastNHarvests; } - async getAprs(): Promise<{ [p: string]: { apr: number; isIbYield: boolean } }> { + async getAprs() { let multiStrategyAprs = {}; let singleStrategyAprs = {}; this.wstETHBaseApr = await this.getWstEthBaseApr(); @@ -122,7 +122,11 @@ export class ReaperCryptAprHandler implements AprHandler { } return { ...acc, - [id]: { apr: tokenApr, isIbYield: token.isIbYield ?? false }, + [id]: { + apr: tokenApr, + isIbYield: token.isIbYield ?? false, + group: this.group, + }, }; }, {}); } catch (error) { diff --git a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/tessera-apr-handler.ts b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/tessera-apr-handler.ts index ccdce1f15..f1d67f18f 100644 --- a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/tessera-apr-handler.ts +++ b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/tessera-apr-handler.ts @@ -31,7 +31,11 @@ export class TesseraAprHandler implements AprHandler { const staked = BigInt(pool.stakedAmount); const reward = BigInt(pool.currentTimeRange.rewardsPerHour) * BigInt(24 * 365); const apr = Number(reward.toString()) / Number(staked.toString()); - aprEntries.push([tokenAddress, { apr, isIbYield: isIbYield ?? false }]); + aprEntries.push([tokenAddress, { + apr, + isIbYield: isIbYield ?? false, + group: this.group + }]); } catch (error) { console.error('Failed to fetch Tessera Ape Coin APR:', error); Sentry.captureException(`Tessera IB APR handler failed: ${error}`); diff --git a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/tetu-apr-handler.ts b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/tetu-apr-handler.ts index 2db4746f9..d42480aac 100644 --- a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/tetu-apr-handler.ts +++ b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/tetu-apr-handler.ts @@ -35,6 +35,7 @@ export class TetuAprHandler implements AprHandler { apr: t.apr / 100, isIbYield: Object.values(this.tokens).find(({ address }) => address === t.vault)?.isIbYield ?? false, + group: this.group, }, ]); return Object.fromEntries(aprs); diff --git a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/tranchess-apr-handler.ts b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/tranchess-apr-handler.ts index 37bea641d..aec8047ee 100644 --- a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/tranchess-apr-handler.ts +++ b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/tranchess-apr-handler.ts @@ -30,7 +30,11 @@ export class TranchessAprHandler implements AprHandler { ).filter(({ name }) => name === underlyingAssetName)[0].weeklyAveragePnlPercentage; return [ address, - { apr: (365 * Number(weeklyAveragePnlPercentage)) / 1e18, isIbYield: isIbYield ?? false }, + { + apr: (365 * Number(weeklyAveragePnlPercentage)) / 1e18, + isIbYield: isIbYield ?? false, + group: this.group + }, ]; }); // The key weeklyAveragePnlPercentage is the daily yield of qETH in 18 decimals, timing 365 should give you the APR. diff --git a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/yearn-apr-handler.ts b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/yearn-apr-handler.ts index 1451b2f3d..ac519fad0 100644 --- a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/yearn-apr-handler.ts +++ b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/yearn-apr-handler.ts @@ -12,12 +12,16 @@ export class YearnAprHandler implements AprHandler { this.sourceUrl = aprHandlerConfig.sourceUrl; this.isIbYield = aprHandlerConfig.isIbYield; } - async getAprs(): Promise<{ [p: string]: { apr: number; isIbYield: boolean } }> { + async getAprs() { try { const { data } = await axios.get(this.sourceUrl); const aprs = Object.fromEntries( data.map(({ address, apy: { net_apy } }) => { - return [address.toLowerCase(), { apr: net_apy, isIbYield: this.isIbYield ?? false }]; + return [address.toLowerCase(), { + apr: net_apy, + isIbYield: this.isIbYield ?? false, + group: this.group + }]; }), ); return aprs; diff --git a/modules/pool/lib/apr-data-sources/ib-tokens-apr.service.ts b/modules/pool/lib/apr-data-sources/ib-tokens-apr.service.ts index dc3dda53c..d689eecd7 100644 --- a/modules/pool/lib/apr-data-sources/ib-tokens-apr.service.ts +++ b/modules/pool/lib/apr-data-sources/ib-tokens-apr.service.ts @@ -1,9 +1,8 @@ import { PoolAprService } from '../../pool-types'; import { PrismaPoolWithTokens } from '../../../../prisma/prisma-types'; import { prisma } from '../../../../prisma/prisma-client'; -import { networkContext } from '../../../network/network-context.service'; import { prismaBulkExecuteOperations } from '../../../../prisma/prisma-util'; -import { PrismaPoolAprItemGroup, PrismaPoolAprType, PrismaPoolLinearData } from '@prisma/client'; +import { Chain, PrismaPoolAprItemGroup, PrismaPoolAprType, PrismaPoolLinearData } from '@prisma/client'; import { IbLinearAprHandlers as IbTokensAprHandlers, TokenApr } from './ib-linear-apr-handlers/ib-linear-apr-handlers'; import { tokenService } from '../../../token/token.service'; import { collectsYieldFee } from '../pool-utils'; @@ -12,8 +11,13 @@ import { IbAprConfig } from '../../../network/apr-config-types'; export class IbTokensAprService implements PoolAprService { private ibTokensAprHandlers: IbTokensAprHandlers; - constructor(aprConfig: IbAprConfig) { - this.ibTokensAprHandlers = new IbTokensAprHandlers(aprConfig); + constructor( + aprConfig: IbAprConfig, + private chain: Chain, + private defaultYieldFee: number, + private defaultSwapFee: number + ) { + this.ibTokensAprHandlers = new IbTokensAprHandlers(aprConfig, chain); } getAprServiceName(): string { @@ -33,7 +37,7 @@ export class IbTokensAprService implements PoolAprService { }); const poolsWithIbTokensExpanded = await prisma.prismaPool.findMany({ - where: { chain: networkContext.chain, id: { in: poolsWithIbTokens.map((pool) => pool.id) } }, + where: { chain: this.chain, id: { in: poolsWithIbTokens.map((pool) => pool.id) } }, include: { dynamicData: true, tokens: { @@ -76,10 +80,10 @@ export class IbTokensAprService implements PoolAprService { if (collectsYieldFee(pool) && token.dynamicData && token.dynamicData.priceRate !== '1.0') { const protocolYieldFeePercentage = pool.dynamicData?.protocolYieldFee ? parseFloat(pool.dynamicData.protocolYieldFee) - : networkContext.data.balancer.yieldProtocolFeePercentage; + : this.defaultYieldFee; aprInPoolAfterFees = pool.type === 'META_STABLE' - ? aprInPoolAfterFees * (1 - networkContext.data.balancer.swapProtocolFeePercentage) + ? aprInPoolAfterFees * (1 - this.defaultSwapFee) : aprInPoolAfterFees * (1 - protocolYieldFeePercentage); } @@ -90,7 +94,7 @@ export class IbTokensAprService implements PoolAprService { const data = { id: itemId, - chain: networkContext.chain, + chain: this.chain, poolId: pool.id, title: `${token.token.symbol} APR`, apr: aprInPoolAfterFees, @@ -100,7 +104,7 @@ export class IbTokensAprService implements PoolAprService { operations.push( prisma.prismaPoolAprItem.upsert({ - where: { id_chain: { id: itemId, chain: networkContext.chain } }, + where: { id_chain: { id: itemId, chain: this.chain } }, create: data, update: data, }), diff --git a/modules/pool/lib/apr-data-sources/phantom-stable-apr.service.ts b/modules/pool/lib/apr-data-sources/phantom-stable-apr.service.ts index 06f738c6b..fff2dc917 100644 --- a/modules/pool/lib/apr-data-sources/phantom-stable-apr.service.ts +++ b/modules/pool/lib/apr-data-sources/phantom-stable-apr.service.ts @@ -2,9 +2,11 @@ import { PoolAprService } from '../../pool-types'; import { PrismaPoolWithTokens, prismaPoolWithExpandedNesting } from '../../../../prisma/prisma-types'; import { prisma } from '../../../../prisma/prisma-client'; import { collectsYieldFee } from '../pool-utils'; -import { networkContext } from '../../../network/network-context.service'; +import { Chain } from '@prisma/client'; export class PhantomStableAprService implements PoolAprService { + constructor(private chain: Chain, private defaultProtocolFee: number) {} + public getAprServiceName(): string { return 'PhantomStableAprService'; } @@ -14,17 +16,17 @@ export class PhantomStableAprService implements PoolAprService { const phantomStablePoolsExpanded = await prisma.prismaPool.findMany({ ...prismaPoolWithExpandedNesting, - where: { chain: networkContext.chain, id: { in: phantomStablePools.map((pool) => pool.id) } }, + where: { chain: this.chain, id: { in: phantomStablePools.map((pool) => pool.id) } }, }); for (const pool of phantomStablePoolsExpanded) { const protocolYieldFeePercentage = pool.dynamicData?.protocolYieldFee ? parseFloat(pool.dynamicData.protocolYieldFee) - : networkContext.data.balancer.yieldProtocolFeePercentage; + : this.defaultProtocolFee; const linearPoolTokens = pool.tokens.filter((token) => token.nestedPool?.type === 'LINEAR'); const linearPoolIds = linearPoolTokens.map((token) => token.nestedPool?.id || ''); const aprItems = await prisma.prismaPoolAprItem.findMany({ - where: { poolId: { in: linearPoolIds }, type: 'LINEAR_BOOSTED', chain: networkContext.chain }, + where: { poolId: { in: linearPoolIds }, type: 'LINEAR_BOOSTED', chain: this.chain }, }); for (const token of linearPoolTokens) { @@ -36,10 +38,10 @@ export class PhantomStableAprService implements PoolAprService { const userApr = collectsYieldFee(pool) ? apr * (1 - protocolYieldFeePercentage) : apr; await prisma.prismaPoolAprItem.upsert({ - where: { id_chain: { id: itemId, chain: networkContext.chain } }, + where: { id_chain: { id: itemId, chain: this.chain } }, create: { id: itemId, - chain: networkContext.chain, + chain: this.chain, poolId: pool.id, apr: userApr, title: aprItem.title, diff --git a/modules/pool/lib/pool-usd-data.service.ts b/modules/pool/lib/pool-usd-data.service.ts index 24b7cff6c..da03195d0 100644 --- a/modules/pool/lib/pool-usd-data.service.ts +++ b/modules/pool/lib/pool-usd-data.service.ts @@ -260,6 +260,10 @@ export class PoolUsdDataService { await prismaBulkExecuteOperations(operations); } + /** + * This function depends on pools data to be up to date, so it should be called after + * poolService.syncAllPoolsFromSubgraph or mutation poolSyncAllPoolsFromSubgraph + */ public async updateLifetimeValuesForAllPools() { let updates: any[] = []; const subgraphPools = await this.balancerSubgraphService.getAllPools({}); diff --git a/modules/pool/lib/staking/gauge-staking.service.ts b/modules/pool/lib/staking/gauge-staking.service.ts index f73e0dbf8..99ac67a8b 100644 --- a/modules/pool/lib/staking/gauge-staking.service.ts +++ b/modules/pool/lib/staking/gauge-staking.service.ts @@ -302,8 +302,6 @@ export class GaugeStakingService implements PoolStakingService { totalSupply: string; }[]; - console.log(onchainRates) - return onchainRates; } diff --git a/modules/pool/pool.prisma b/modules/pool/pool.prisma index bcab89d2b..16767b4df 100644 --- a/modules/pool/pool.prisma +++ b/modules/pool/pool.prisma @@ -310,6 +310,7 @@ enum PrismaPoolAprItemGroup { TETU OVIX EULER + MAKER DEFAULT } diff --git a/prisma/migrations/20231019072204_adding_maker_apr_group/migration.sql b/prisma/migrations/20231019072204_adding_maker_apr_group/migration.sql new file mode 100644 index 000000000..e967ea1ea --- /dev/null +++ b/prisma/migrations/20231019072204_adding_maker_apr_group/migration.sql @@ -0,0 +1,2 @@ +-- AlterEnum +ALTER TYPE "PrismaPoolAprItemGroup" ADD VALUE 'MAKER'; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 1d2572799..9ec3e38d1 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -356,6 +356,7 @@ enum PrismaPoolAprItemGroup { TETU OVIX EULER + MAKER DEFAULT } diff --git a/tsconfig.json b/tsconfig.json index d95f5a8e4..c4157392a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,5 +10,9 @@ "resolveJsonModule": true, "outDir": "./dist", "skipLibCheck": true - } + }, + "exclude": [ + "node_modules", + "debug" + ] }