diff --git a/src/modules/farm/base-module/services/farm.abi.service.ts b/src/modules/farm/base-module/services/farm.abi.service.ts index 0f98d6ebb..3e304f92b 100644 --- a/src/modules/farm/base-module/services/farm.abi.service.ts +++ b/src/modules/farm/base-module/services/farm.abi.service.ts @@ -100,6 +100,16 @@ export class FarmAbiService return response.firstValue.valueOf().toString(); } + async getAllFarmingTokenIds(farmAddresses: string[]): Promise { + return await getAllKeys( + this.cacheService, + farmAddresses, + 'farm.farmingTokenID', + this.farmingTokenID.bind(this), + CacheTtlInfo.Token, + ); + } + @ErrorLoggerAsync({ logArgs: true, }) diff --git a/src/modules/farm/base-module/services/farm.base.service.ts b/src/modules/farm/base-module/services/farm.base.service.ts index e959e8a2c..594393774 100644 --- a/src/modules/farm/base-module/services/farm.base.service.ts +++ b/src/modules/farm/base-module/services/farm.base.service.ts @@ -63,13 +63,10 @@ export abstract class FarmServiceBase { } async getAllFarmingTokens(farmAddresses: string[]): Promise { - const farmingTokenIDs = await getAllKeys( - this.cachingService, + const farmingTokenIDs = await this.farmAbi.getAllFarmingTokenIds( farmAddresses, - 'farm.farmingTokenID', - this.farmAbi.farmingTokenID.bind(this.farmAbi), - CacheTtlInfo.Token, ); + return this.tokenService.getAllTokensMetadata(farmingTokenIDs); } diff --git a/src/modules/farm/v2/services/farm.v2.compute.service.ts b/src/modules/farm/v2/services/farm.v2.compute.service.ts index 8762d2a5b..c60c48cdb 100644 --- a/src/modules/farm/v2/services/farm.v2.compute.service.ts +++ b/src/modules/farm/v2/services/farm.v2.compute.service.ts @@ -21,6 +21,7 @@ import { WeeklyRewardsSplittingComputeService } from 'src/submodules/weekly-rewa import { IFarmComputeServiceV2 } from './interfaces'; import { WeekTimekeepingAbiService } from 'src/submodules/week-timekeeping/services/week-timekeeping.abi.service'; import { computeValueUSD } from 'src/utils/token.converters'; +import { getAllKeys } from 'src/utils/get.many.utils'; @Injectable() export class FarmComputeServiceV2 @@ -98,6 +99,16 @@ export class FarmComputeServiceV2 .toFixed(); } + async getAllBaseAPR(farmAddresses: string[]): Promise { + return await getAllKeys( + this.cachingService, + farmAddresses, + 'farm.farmBaseAPR', + this.farmBaseAPR.bind(this), + CacheTtlInfo.ContractState, + ); + } + async computeMintedRewards(farmAddress: string): Promise { const [toBeMinted, boostedYieldsRewardsPercenatage] = await Promise.all( [ @@ -620,4 +631,14 @@ export class FarmComputeServiceV2 return bnRawMaxBoostedApr.toFixed(); } + + async getAllMaxBoostedAPR(farmAddresses: string[]): Promise { + return await getAllKeys( + this.cachingService, + farmAddresses, + 'farm.maxBoostedApr', + this.maxBoostedApr.bind(this), + CacheTtlInfo.ContractState, + ); + } } diff --git a/src/modules/pair/mocks/pair.abi.service.mock.ts b/src/modules/pair/mocks/pair.abi.service.mock.ts index 4eae74ca5..eef021124 100644 --- a/src/modules/pair/mocks/pair.abi.service.mock.ts +++ b/src/modules/pair/mocks/pair.abi.service.mock.ts @@ -11,9 +11,19 @@ export class PairAbiServiceMock implements IPairAbiService { async firstTokenID(pairAddress: string): Promise { return PairsData(pairAddress).firstToken.identifier; } + async getAllFirstTokenID(pairAddresses: string[]): Promise { + return pairAddresses.map( + (pairAddress) => PairsData(pairAddress).firstToken.identifier, + ); + } async secondTokenID(pairAddress: string): Promise { return PairsData(pairAddress).secondToken.identifier; } + async getAllSecondTokenID(pairAddresses: string[]): Promise { + return pairAddresses.map( + (pairAddress) => PairsData(pairAddress).secondToken.identifier, + ); + } async lpTokenID(pairAddress: string): Promise { return PairsData(pairAddress)?.liquidityPoolToken.identifier; } diff --git a/src/modules/pair/pair.resolver.ts b/src/modules/pair/pair.resolver.ts index 8534a18b4..4734d9b8a 100644 --- a/src/modules/pair/pair.resolver.ts +++ b/src/modules/pair/pair.resolver.ts @@ -285,7 +285,7 @@ export class PairResolver { @ResolveField() async feesUSD24h(@Parent() parent: PairModel): Promise { - return this.pairCompute.feesUSD(parent.address, '24h'); + return this.pairComputeLoader.feesUSD24hLoader.load(parent.address); } @ResolveField() diff --git a/src/modules/pair/services/pair.abi.loader.ts b/src/modules/pair/services/pair.abi.loader.ts index 9011b42d4..a0405e7fb 100644 --- a/src/modules/pair/services/pair.abi.loader.ts +++ b/src/modules/pair/services/pair.abi.loader.ts @@ -60,13 +60,7 @@ export class PairAbiLoader { public readonly totalFeePercentLoader = new DataLoader( async (addresses: string[]) => { - return getAllKeys( - this.cacheService, - addresses, - 'pair.totalFeePercent', - this.pairAbi.totalFeePercent.bind(this.pairAbi), - CacheTtlInfo.ContractState, - ); + return this.pairAbi.getAllTotalFeePercent(addresses); }, { cache: false, @@ -75,13 +69,7 @@ export class PairAbiLoader { public readonly specialFeePercentLoader = new DataLoader( async (addresses: string[]) => { - return getAllKeys( - this.cacheService, - addresses, - 'pair.specialFeePercent', - this.pairAbi.specialFeePercent.bind(this.pairAbi), - CacheTtlInfo.ContractState, - ); + return this.pairAbi.getAllSpecialFeePercent(addresses); }, { cache: false, diff --git a/src/modules/pair/services/pair.abi.service.ts b/src/modules/pair/services/pair.abi.service.ts index 8c4864a35..bf412ddb2 100644 --- a/src/modules/pair/services/pair.abi.service.ts +++ b/src/modules/pair/services/pair.abi.service.ts @@ -64,6 +64,16 @@ export class PairAbiService return response.firstValue.valueOf().toString(); } + async getAllFirstTokenID(pairAddresses: string[]): Promise { + return await getAllKeys( + this.cachingService, + pairAddresses, + 'pair.firstTokenID', + this.firstTokenID.bind(this), + CacheTtlInfo.Token, + ); + } + @ErrorLoggerAsync({ logArgs: true, }) @@ -85,6 +95,16 @@ export class PairAbiService return response.firstValue.valueOf().toString(); } + async getAllSecondTokenID(pairAddresses: string[]): Promise { + return await getAllKeys( + this.cachingService, + pairAddresses, + 'pair.secondTokenID', + this.secondTokenID.bind(this), + CacheTtlInfo.Token, + ); + } + @ErrorLoggerAsync({ logArgs: true, }) @@ -241,6 +261,16 @@ export class PairAbiService return response.firstValue.valueOf().toNumber(); } + async getAllTotalFeePercent(pairAddresses: string[]): Promise { + return await getAllKeys( + this.cachingService, + pairAddresses, + 'pair.totalFeePercent', + this.totalFeePercent.bind(this), + CacheTtlInfo.ContractState, + ); + } + @ErrorLoggerAsync({ logArgs: true, }) @@ -267,6 +297,16 @@ export class PairAbiService return response.firstValue.valueOf().toNumber(); } + async getAllSpecialFeePercent(pairAddresses: string[]): Promise { + return await getAllKeys( + this.cachingService, + pairAddresses, + 'pair.specialFeePercent', + this.specialFeePercent.bind(this), + CacheTtlInfo.ContractState, + ); + } + @ErrorLoggerAsync({ logArgs: true, }) diff --git a/src/modules/pair/services/pair.compute.loader.ts b/src/modules/pair/services/pair.compute.loader.ts index 6db7487ac..d9d784c80 100644 --- a/src/modules/pair/services/pair.compute.loader.ts +++ b/src/modules/pair/services/pair.compute.loader.ts @@ -174,6 +174,15 @@ export class PairComputeLoader { }, ); + public readonly feesUSD24hLoader = new DataLoader( + async (addresses: string[]) => { + return await this.pairCompute.getAllFeesUSD(addresses); + }, + { + cache: false, + }, + ); + public readonly previous24hFeesUSDLoader = new DataLoader( async (addresses: string[]) => { return await getAllKeys( @@ -206,13 +215,7 @@ export class PairComputeLoader { public readonly typeLoader = new DataLoader( async (addresses: string[]) => { - return await getAllKeys( - this.cacheService, - addresses, - 'pair.type', - this.pairCompute.type.bind(this.pairCompute), - CacheTtlInfo.ContractState, - ); + return await this.pairCompute.getAllType(addresses); }, { cache: false, diff --git a/src/modules/pair/services/pair.compute.service.ts b/src/modules/pair/services/pair.compute.service.ts index c3f6e00bf..7fd3ecdab 100644 --- a/src/modules/pair/services/pair.compute.service.ts +++ b/src/modules/pair/services/pair.compute.service.ts @@ -96,6 +96,16 @@ export class PairComputeService implements IPairComputeService { .toFixed(); } + async getAllFirstTokensPrice(pairAddresses: string[]): Promise { + return await getAllKeys( + this.cachingService, + pairAddresses, + 'pair.firstTokenPrice', + this.firstTokenPrice.bind(this), + CacheTtlInfo.Price, + ); + } + @ErrorLoggerAsync({ logArgs: true, }) @@ -125,6 +135,16 @@ export class PairComputeService implements IPairComputeService { .toFixed(); } + async getAllSecondTokensPrice(pairAddresses: string[]): Promise { + return await getAllKeys( + this.cachingService, + pairAddresses, + 'pair.secondTokenPrice', + this.secondTokenPrice.bind(this), + CacheTtlInfo.Price, + ); + } + @ErrorLoggerAsync({ logArgs: true, }) @@ -175,6 +195,16 @@ export class PairComputeService implements IPairComputeService { return firstTokenValueUSD.plus(secondTokenValueUSD).toFixed(); } + async getAllLpTokensPriceUSD(pairAddresses: string[]): Promise { + return await getAllKeys( + this.cachingService, + pairAddresses, + 'pair.lpTokenPriceUSD', + this.lpTokenPriceUSD.bind(this), + CacheTtlInfo.Price, + ); + } + @ErrorLoggerAsync({ logArgs: true, }) @@ -313,6 +343,18 @@ export class PairComputeService implements IPairComputeService { .multipliedBy(firstTokenPriceUSD); } + async getAllFirstTokensLockedValueUSD( + pairAddresses: string[], + ): Promise { + return await getAllKeys( + this.cachingService, + pairAddresses, + 'pair.firstTokenLockedValueUSD', + this.firstTokenLockedValueUSD.bind(this), + CacheTtlInfo.ContractInfo, + ); + } + @ErrorLoggerAsync({ logArgs: true, }) @@ -343,6 +385,18 @@ export class PairComputeService implements IPairComputeService { .multipliedBy(secondTokenPriceUSD); } + async getAllSecondTokensLockedValueUSD( + pairAddresses: string[], + ): Promise { + return await getAllKeys( + this.cachingService, + pairAddresses, + 'pair.secondTokenLockedValueUSD', + this.secondTokenLockedValueUSD.bind(this), + CacheTtlInfo.ContractInfo, + ); + } + @ErrorLoggerAsync({ logArgs: true, }) @@ -391,6 +445,18 @@ export class PairComputeService implements IPairComputeService { return values24h[0]?.value ?? undefined; } + async getAllPrevious24hLockedValueUSD( + pairAddresses: string[], + ): Promise { + return await getAllKeys( + this.cachingService, + pairAddresses, + 'pair.previous24hLockedValueUSD', + this.previous24hLockedValueUSD.bind(this), + CacheTtlInfo.ContractInfo, + ); + } + @ErrorLoggerAsync({ logArgs: true, }) @@ -507,8 +573,8 @@ export class PairComputeService implements IPairComputeService { remoteTtl: CacheTtlInfo.Analytics.remoteTtl, localTtl: CacheTtlInfo.Analytics.localTtl, }) - async feesUSD(pairAddress: string, time: string): Promise { - return await this.computeFeesUSD(pairAddress, time); + async feesUSD(pairAddress: string): Promise { + return await this.computeFeesUSD(pairAddress, '24h'); } async computeFeesUSD(pairAddress: string, time: string): Promise { @@ -523,6 +589,16 @@ export class PairComputeService implements IPairComputeService { }); } + async getAllFeesUSD(pairAddresses: string[]): Promise { + return await getAllKeys( + this.cachingService, + pairAddresses, + 'pair.feesUSD', + this.feesUSD.bind(this), + CacheTtlInfo.Analytics, + ); + } + @ErrorLoggerAsync({ logArgs: true, }) @@ -537,8 +613,8 @@ export class PairComputeService implements IPairComputeService { async computePrevious24hFeesUSD(pairAddress: string): Promise { const [fees24h, fees48h] = await Promise.all([ - this.feesUSD(pairAddress, '24h'), - this.feesUSD(pairAddress, '48h'), + this.computeFeesUSD(pairAddress, '24h'), + this.computeFeesUSD(pairAddress, '48h'), ]); return new BigNumber(fees48h).minus(fees24h).toFixed(); } @@ -558,7 +634,7 @@ export class PairComputeService implements IPairComputeService { async computeFeesAPR(pairAddress: string): Promise { const [fees24h, lockedValueUSD, specialFeePercent, totalFeesPercent] = await Promise.all([ - this.feesUSD(pairAddress, '24h'), + this.feesUSD(pairAddress), this.computeLockedValueUSD(pairAddress), this.pairAbi.specialFeePercent(pairAddress), this.pairAbi.totalFeePercent(pairAddress), @@ -575,6 +651,16 @@ export class PairComputeService implements IPairComputeService { return !feesAPR.isNaN() ? feesAPR.toFixed() : '0'; } + async getAllFeesAPR(pairAddresses: string[]): Promise { + return await getAllKeys( + this.cachingService, + pairAddresses, + 'pair.feesAPR', + this.feesAPR.bind(this), + CacheTtlInfo.ContractInfo, + ); + } + @ErrorLoggerAsync({ logArgs: true, }) @@ -601,6 +687,16 @@ export class PairComputeService implements IPairComputeService { return leastType(firstTokenType, secondTokenType); } + async getAllType(pairAddresses: string[]): Promise { + return await getAllKeys( + this.cachingService, + pairAddresses, + 'pair.type', + this.type.bind(this), + CacheTtlInfo.ContractState, + ); + } + async computePermanentLockedValueUSD( pairAddress: string, firstTokenAmount: BigNumber, @@ -684,8 +780,8 @@ export class PairComputeService implements IPairComputeService { ); const lpTokenID = await this.pairAbi.lpTokenID(pairAddress); - const farmingTokenIDs = await Promise.all( - addresses.map((address) => this.farmAbi.farmingTokenID(address)), + const farmingTokenIDs = await this.farmAbi.getAllFarmingTokenIds( + addresses, ); return farmingTokenIDs.includes(lpTokenID); @@ -799,8 +895,8 @@ export class PairComputeService implements IPairComputeService { const lpTokenID = await this.pairAbi.lpTokenID(pairAddress); - const farmingTokenIDs = await Promise.all( - addresses.map((address) => this.farmAbi.farmingTokenID(address)), + const farmingTokenIDs = await this.farmAbi.getAllFarmingTokenIds( + addresses, ); const farmAddressIndex = farmingTokenIDs.findIndex( @@ -814,6 +910,30 @@ export class PairComputeService implements IPairComputeService { return addresses[farmAddressIndex]; } + async getAllPairsFarmAddress(pairAddresses: string[]): Promise { + const farmAddresses = farmsAddresses([FarmVersion.V2]).filter( + (address) => farmType(address) !== FarmRewardType.DEPRECATED, + ); + const farmingTokenIds = await this.farmAbi.getAllFarmingTokenIds( + farmAddresses, + ); + const allLpTokenIDs = await this.pairService.getAllLpTokensIds( + pairAddresses, + ); + + return allLpTokenIDs.map((lpTokenID) => { + const farmAddressIndex = farmingTokenIds.findIndex( + (tokenID) => tokenID === lpTokenID, + ); + + if (farmAddressIndex === -1) { + return undefined; + } + + return farmAddresses[farmAddressIndex]; + }); + } + async getPairFarmToken(pairAddress: string): Promise { const farmAddress = await this.getPairFarmAddress(pairAddress); @@ -864,6 +984,43 @@ export class PairComputeService implements IPairComputeService { : stakingProxyAddresses[stakingProxyIndex]; } + async getAllPairsStakingProxyAddress( + pairAddresses: string[], + ): Promise { + const stakingProxyAddresses = + await this.remoteConfigGetterService.getStakingProxyAddresses(); + + const stakingProxyPairAddresses = + await this.stakingProxyAbiService.getAllPairAddresses( + stakingProxyAddresses, + ); + const allFarmAddresses = await this.getAllPairsFarmAddress( + pairAddresses, + ); + + const allLpFarmAddresses = + await this.stakingProxyAbiService.getAllLpFarmAddresses( + stakingProxyAddresses, + ); + + return pairAddresses.map((pairAddress, index) => { + if ( + !stakingProxyPairAddresses.includes(pairAddress) || + allFarmAddresses[index] === undefined + ) { + return undefined; + } + + const stakingProxyIndex = allLpFarmAddresses.findIndex( + (address) => address === allFarmAddresses[index], + ); + + return stakingProxyIndex === -1 + ? undefined + : stakingProxyAddresses[stakingProxyIndex]; + }); + } + async computeCompoundedApr(pairAddress: string): Promise { const [feesAPR, farmAddress, stakingFarmAddress] = await Promise.all([ this.feesAPR(pairAddress), diff --git a/src/modules/pair/services/pair.service.ts b/src/modules/pair/services/pair.service.ts index ee169abe8..e4fd196ac 100644 --- a/src/modules/pair/services/pair.service.ts +++ b/src/modules/pair/services/pair.service.ts @@ -43,13 +43,7 @@ export class PairService { } async getAllFirstTokens(pairAddresses: string[]): Promise { - const tokenIDs = await getAllKeys( - this.cachingService, - pairAddresses, - 'pair.firstTokenID', - this.pairAbi.firstTokenID.bind(this.pairAbi), - CacheTtlInfo.Token, - ); + const tokenIDs = await this.pairAbi.getAllFirstTokenID(pairAddresses); return this.tokenService.getAllTokensMetadata(tokenIDs); } @@ -60,13 +54,7 @@ export class PairService { } async getAllSecondTokens(pairAddresses: string[]): Promise { - const tokenIDs = await getAllKeys( - this.cachingService, - pairAddresses, - 'pair.secondTokenID', - this.pairAbi.secondTokenID.bind(this.pairAbi), - CacheTtlInfo.Token, - ); + const tokenIDs = await this.pairAbi.getAllSecondTokenID(pairAddresses); return this.tokenService.getAllTokensMetadata(tokenIDs); } diff --git a/src/modules/pair/services/pair.setter.service.ts b/src/modules/pair/services/pair.setter.service.ts index ed21bb69d..6f08ec8fd 100644 --- a/src/modules/pair/services/pair.setter.service.ts +++ b/src/modules/pair/services/pair.setter.service.ts @@ -275,13 +275,9 @@ export class PairSetterService extends GenericSetterService { ); } - async setFeesUSD( - pairAddress: string, - value: string, - time: string, - ): Promise { + async setFeesUSD(pairAddress: string, value: string): Promise { return await this.setData( - this.getCacheKey('feesUSD', pairAddress, time), + this.getCacheKey('feesUSD', pairAddress), value, CacheTtlInfo.Analytics.remoteTtl, CacheTtlInfo.Analytics.localTtl, diff --git a/src/modules/router/services/router.compute.service.ts b/src/modules/router/services/router.compute.service.ts index 0cb095ff7..6b85ddfd0 100644 --- a/src/modules/router/services/router.compute.service.ts +++ b/src/modules/router/services/router.compute.service.ts @@ -60,7 +60,7 @@ export class RouterComputeService { let totalFeesUSD = new BigNumber(0); const promises = pairsAddress.map((pairAddress) => - this.pairCompute.feesUSD(pairAddress, time), + this.pairCompute.computeFeesUSD(pairAddress, time), ); const feesUSD = await Promise.all(promises); diff --git a/src/modules/router/services/router.service.ts b/src/modules/router/services/router.service.ts index 03e6fed23..0ce7ce4b0 100644 --- a/src/modules/router/services/router.service.ts +++ b/src/modules/router/services/router.service.ts @@ -287,10 +287,8 @@ export class RouterService { ); break; case PairSortableFields.FEES_24: - sortFieldData = await Promise.all( - pairsMetadata.map((pair) => - this.pairCompute.feesUSD(pair.address, '24h'), - ), + sortFieldData = await this.pairCompute.getAllFeesUSD( + pairsMetadata.map((pair) => pair.address), ); break; case PairSortableFields.TRADES_COUNT: diff --git a/src/modules/staking-proxy/services/staking.proxy.abi.service.ts b/src/modules/staking-proxy/services/staking.proxy.abi.service.ts index d51cb68d6..c592a203f 100644 --- a/src/modules/staking-proxy/services/staking.proxy.abi.service.ts +++ b/src/modules/staking-proxy/services/staking.proxy.abi.service.ts @@ -43,6 +43,18 @@ export class StakingProxyAbiService return response.firstValue.valueOf().toString(); } + async getAllLpFarmAddresses( + stakingProxyAddresses: string[], + ): Promise { + return await getAllKeys( + this.cachingService, + stakingProxyAddresses, + 'stakeProxy.lpFarmAddress', + this.lpFarmAddress.bind(this), + new CacheTtlInfo(Constants.oneHour(), Constants.oneMinute() * 45), + ); + } + @ErrorLoggerAsync({ logArgs: true, }) @@ -66,6 +78,18 @@ export class StakingProxyAbiService return response.firstValue.valueOf().toString(); } + async getAllStakingFarmAddresses( + stakingProxyAddresses: string[], + ): Promise { + return await getAllKeys( + this.cachingService, + stakingProxyAddresses, + 'stakeProxy.stakingFarmAddress', + this.stakingFarmAddress.bind(this), + new CacheTtlInfo(Constants.oneHour(), Constants.oneMinute() * 45), + ); + } + @ErrorLoggerAsync({ logArgs: true, }) @@ -87,6 +111,18 @@ export class StakingProxyAbiService return response.firstValue.valueOf().toString(); } + async getAllPairAddresses( + stakingProxyAddresses: string[], + ): Promise { + return await getAllKeys( + this.cachingService, + stakingProxyAddresses, + 'stakeProxy.pairAddress', + this.pairAddress.bind(this), + new CacheTtlInfo(Constants.oneHour(), Constants.oneMinute() * 45), + ); + } + @ErrorLoggerAsync({ logArgs: true, }) @@ -108,6 +144,18 @@ export class StakingProxyAbiService return response.firstValue.valueOf().toString(); } + async getAllStakingTokenIDs( + stakingProxyAddresses: string[], + ): Promise { + return await getAllKeys( + this.cachingService, + stakingProxyAddresses, + 'stakeProxy.stakingTokenID', + this.stakingTokenID.bind(this), + new CacheTtlInfo(Constants.oneHour(), Constants.oneMinute() * 45), + ); + } + @ErrorLoggerAsync({ logArgs: true, }) diff --git a/src/modules/staking/services/staking.abi.service.ts b/src/modules/staking/services/staking.abi.service.ts index 9a6ad786a..49e4c26ee 100644 --- a/src/modules/staking/services/staking.abi.service.ts +++ b/src/modules/staking/services/staking.abi.service.ts @@ -539,6 +539,18 @@ export class StakingAbiService return response.firstValue.valueOf().toNumber(); } + async getAllBoostedYieldsRewardsPercenatage( + stakeAddresses: string[], + ): Promise { + return await getAllKeys( + this.cachingService, + stakeAddresses, + 'stake.boostedYieldsRewardsPercenatage', + this.boostedYieldsRewardsPercenatage.bind(this), + CacheTtlInfo.ContractState, + ); + } + @ErrorLoggerAsync({ logArgs: true, }) @@ -576,6 +588,18 @@ export class StakingAbiService }); } + async getAllBoostedYieldsFactors( + stakeAddresses: string[], + ): Promise { + return await getAllKeys( + this.cachingService, + stakeAddresses, + 'stake.boostedYieldsFactors', + this.boostedYieldsFactors.bind(this), + CacheTtlInfo.ContractState, + ); + } + @ErrorLoggerAsync({ logArgs: true, }) diff --git a/src/modules/staking/services/staking.compute.service.ts b/src/modules/staking/services/staking.compute.service.ts index 807556c06..294218b35 100644 --- a/src/modules/staking/services/staking.compute.service.ts +++ b/src/modules/staking/services/staking.compute.service.ts @@ -18,6 +18,9 @@ import { WeeklyRewardsSplittingAbiService } from 'src/submodules/weekly-rewards- import { EsdtTokenPayment } from 'src/models/esdtTokenPayment.model'; import { MXApiService } from 'src/services/multiversx-communication/mx.api.service'; import { WeekTimekeepingAbiService } from 'src/submodules/week-timekeeping/services/week-timekeeping.abi.service'; +import { CacheService } from '@multiversx/sdk-nestjs-cache'; +import { getAllKeys } from 'src/utils/get.many.utils'; +import { BoostedYieldsFactors } from 'src/modules/farm/models/farm.v2.model'; @Injectable() export class StakingComputeService { @@ -32,6 +35,7 @@ export class StakingComputeService { private readonly weeklyRewardsSplittingAbi: WeeklyRewardsSplittingAbiService, private readonly weeklyRewardsSplittingCompute: WeeklyRewardsSplittingComputeService, private readonly apiService: MXApiService, + private readonly cachingService: CacheService, ) {} async computeStakeRewardsForPosition( @@ -244,6 +248,16 @@ export class StakingComputeService { .toFixed(); } + async getAllStakeFarmAPR(stakeAddresses: string[]): Promise { + return await getAllKeys( + this.cachingService, + stakeAddresses, + 'stake.stakeFarmAPR', + this.stakeFarmAPR.bind(this), + CacheTtlInfo.ContractState, + ); + } + @ErrorLoggerAsync({ logArgs: true, }) @@ -306,17 +320,7 @@ export class StakingComputeService { this.stakeFarmAPR(stakeAddress), ]); - const bnBoostedRewardsPercentage = new BigNumber( - boostedYieldsRewardsPercentage, - ) - .dividedBy(constantsConfig.MAX_PERCENT) - .multipliedBy(100); - - const boostedAPR = new BigNumber(apr).multipliedBy( - bnBoostedRewardsPercentage.dividedBy(100), - ); - - return boostedAPR.toFixed(); + return this.calculateBoostedApr(apr, boostedYieldsRewardsPercentage); } @ErrorLoggerAsync({ @@ -334,14 +338,11 @@ export class StakingComputeService { this.stakingAbi.boostedYieldsRewardsPercenatage(stakeAddress), ]); - const bnRawMaxBoostedApr = new BigNumber(baseAPR) - .multipliedBy(boostedYieldsFactors.maxRewardsFactor) - .multipliedBy(boostedYieldsRewardsPercentage) - .dividedBy( - constantsConfig.MAX_PERCENT - boostedYieldsRewardsPercentage, - ); - - return bnRawMaxBoostedApr.toFixed(); + return this.calculateMaxBoostedApr( + baseAPR, + boostedYieldsFactors, + boostedYieldsRewardsPercentage, + ); } async computeRewardsRemainingDays(stakeAddress: string): Promise { @@ -991,4 +992,74 @@ export class StakingComputeService { return true; } + + async getAllBaseAndMaxBoostedAPRs( + stakeAddresses: string[], + ): Promise<{ baseAPR: string; maxBoostedAPR: string }[]> { + const allAPRs = await this.getAllStakeFarmAPR(stakeAddresses); + const allBoostedYieldsRewardsPercentage = + await this.stakingAbi.getAllBoostedYieldsRewardsPercenatage( + stakeAddresses, + ); + const allBoostedYieldsFactors = + await this.stakingAbi.getAllBoostedYieldsFactors(stakeAddresses); + + const allBoostedAPR = allAPRs.map((apr, index) => + this.calculateBoostedApr( + apr, + allBoostedYieldsRewardsPercentage[index], + ), + ); + + const allBaseAPR = allAPRs.map((apr, index) => + new BigNumber(apr).minus(allBoostedAPR[index]).toFixed(), + ); + + const allMaxBoostedAPR = allBaseAPR.map((baseAPR, index) => + this.calculateMaxBoostedApr( + baseAPR, + allBoostedYieldsFactors[index], + allBoostedYieldsRewardsPercentage[index], + ), + ); + + return allBaseAPR.map((baseAPR, index) => { + return { + baseAPR: baseAPR, + maxBoostedAPR: allMaxBoostedAPR[index], + }; + }); + } + + private calculateBoostedApr( + apr: string, + boostedYieldsRewardsPercentage: number, + ): string { + const bnBoostedRewardsPercentage = new BigNumber( + boostedYieldsRewardsPercentage, + ) + .dividedBy(constantsConfig.MAX_PERCENT) + .multipliedBy(100); + + const boostedAPR = new BigNumber(apr).multipliedBy( + bnBoostedRewardsPercentage.dividedBy(100), + ); + + return boostedAPR.toFixed(); + } + + private calculateMaxBoostedApr( + baseAPR: string, + boostedYieldsFactors: BoostedYieldsFactors, + boostedYieldsRewardsPercentage: number, + ): string { + const bnRawMaxBoostedApr = new BigNumber(baseAPR) + .multipliedBy(boostedYieldsFactors.maxRewardsFactor) + .multipliedBy(boostedYieldsRewardsPercentage) + .dividedBy( + constantsConfig.MAX_PERCENT - boostedYieldsRewardsPercentage, + ); + + return bnRawMaxBoostedApr.toFixed(); + } } diff --git a/src/services/crons/pair.cache.warmer.service.ts b/src/services/crons/pair.cache.warmer.service.ts index dbb139e33..78f2bcc57 100644 --- a/src/services/crons/pair.cache.warmer.service.ts +++ b/src/services/crons/pair.cache.warmer.service.ts @@ -140,11 +140,7 @@ export class PairCacheWarmerService { time, ), this.pairSetterService.setVolumeUSD(pairAddress, volumeUSD24h), - this.pairSetterService.setFeesUSD( - pairAddress, - feesUSD24h, - time, - ), + this.pairSetterService.setFeesUSD(pairAddress, feesUSD24h), ]); await this.deleteCacheKeys(cachedKeys); }