diff --git a/app/middleware/sessionMiddleware.ts b/app/middleware/sessionMiddleware.ts index 34425f9f0..140f0fbdd 100644 --- a/app/middleware/sessionMiddleware.ts +++ b/app/middleware/sessionMiddleware.ts @@ -31,7 +31,7 @@ export async function sessionMiddleware(req: Request, res: Response, next: NextF Sentry.setUser({ id: accountAddress?.toLowerCase() }); - if (chainId && networkContext.isValidChainId(chainId)) { + if (chainId && networkContext.isValidChainId(chainId as any)) { initRequestScopedContext(); setRequestScopedContextValue('chainId', chainId); diff --git a/modules/content/content.resolvers.ts b/modules/content/content.resolvers.ts index 981e46af9..23bdbee8c 100644 --- a/modules/content/content.resolvers.ts +++ b/modules/content/content.resolvers.ts @@ -4,7 +4,7 @@ import { networkContext } from '../network/network-context.service'; const contentResolvers: Resolvers = { Query: { contentGetNewsItems: async () => { - return await networkContext.config.contentService.getNewsItems(); + return await networkContext.services.contentService.getNewsItems(); }, }, }; diff --git a/modules/network/arbitrum.ts b/modules/network/arbitrum/data.ts similarity index 54% rename from modules/network/arbitrum.ts rename to modules/network/arbitrum/data.ts index 5a5264910..3d8ed160f 100644 --- a/modules/network/arbitrum.ts +++ b/modules/network/arbitrum/data.ts @@ -1,24 +1,8 @@ -import { BigNumber, ethers } from 'ethers'; -import { DeploymentEnv, NetworkConfig, NetworkData } from './network-config-types'; -import { tokenService } from '../token/token.service'; -import { PhantomStableAprService } from '../pool/lib/apr-data-sources/phantom-stable-apr.service'; -import { BoostedPoolAprService } from '../pool/lib/apr-data-sources/boosted-pool-apr.service'; -import { SwapFeeAprService } from '../pool/lib/apr-data-sources/swap-fee-apr.service'; -import { GaugeAprService } from '../pool/lib/apr-data-sources/ve-bal-gauge-apr.service'; -import { GaugeStakingService } from '../pool/lib/staking/gauge-staking.service'; -import { BptPriceHandlerService } from '../token/lib/token-price-handlers/bpt-price-handler.service'; -import { LinearWrappedTokenPriceHandlerService } from '../token/lib/token-price-handlers/linear-wrapped-token-price-handler.service'; -import { SwapsPriceHandlerService } from '../token/lib/token-price-handlers/swaps-price-handler.service'; -import { UserSyncGaugeBalanceService } from '../user/lib/user-sync-gauge-balance.service'; -import { every } from '../../worker/intervals'; -import { GithubContentService } from '../content/github-content.service'; -import { gaugeSubgraphService } from '../subgraphs/gauge-subgraph/gauge-subgraph.service'; -import { CoingeckoPriceHandlerService } from '../token/lib/token-price-handlers/coingecko-price-handler.service'; -import { coingeckoService } from '../coingecko/coingecko.service'; -import { IbTokensAprService } from '../pool/lib/apr-data-sources/ib-tokens-apr.service'; -import { env } from '../../app/env'; +import { BigNumber } from '@ethersproject/bignumber'; +import { env } from '../../../app/env'; +import { DeploymentEnv, NetworkData } from "../network-config-types"; -const arbitrumNetworkData: NetworkData = { +export const arbitrumNetworkData: NetworkData = { chain: { slug: 'arbitrum', id: 42161, @@ -221,127 +205,3 @@ const arbitrumNetworkData: NetworkData = { }, }, }; - -export const arbitrumNetworkConfig: NetworkConfig = { - data: arbitrumNetworkData, - contentService: new GithubContentService(), - provider: new ethers.providers.JsonRpcProvider({ url: arbitrumNetworkData.rpcUrl, timeout: 60000 }), - poolAprServices: [ - 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]), - ], - poolStakingServices: [new GaugeStakingService(gaugeSubgraphService, arbitrumNetworkData.bal!.address)], - tokenPriceHandlers: [ - new CoingeckoPriceHandlerService(coingeckoService), - new BptPriceHandlerService(), - new LinearWrappedTokenPriceHandlerService(), - new SwapsPriceHandlerService(), - ], - userStakedBalanceServices: [new UserSyncGaugeBalanceService()], - /* - For sub-minute jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. - This is needed because the minimum alarm period is 1 minute and we want the alarm to trigger already after 1 minute instead of 3. - - For every 1 days jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. - This is needed because the maximum alarm evaluation period is 1 day (period * evaluationPeriod). - */ - workerJobs: [ - { - name: 'update-token-prices', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(2, 'minutes'), - }, - { - name: 'update-liquidity-for-inactive-pools', - interval: every(1, 'days'), - alarmEvaluationPeriod: 1, - alarmDatapointsToAlarm: 1, - }, - { - name: 'update-liquidity-for-active-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(8, 'minutes') : every(4, 'minutes'), - }, - { - name: 'update-pool-apr', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(7, 'minutes') : every(5, 'minutes'), - }, - { - name: 'load-on-chain-data-for-pools-with-active-updates', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(9, 'minutes') : every(5, 'minutes'), - }, - { - name: 'sync-new-pools-from-subgraph', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(12, 'minutes') : every(8, 'minutes'), - }, - { - name: 'sync-tokens-from-pool-tokens', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(7, 'minutes'), - }, - { - name: 'update-liquidity-24h-ago-for-all-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(8, 'minutes'), - }, - { - name: 'cache-average-block-time', - interval: every(1, 'hours'), - }, - { - name: 'sync-staking-for-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(10, 'minutes'), - }, - { - name: 'sync-latest-snapshots-for-all-pools', - interval: every(90, 'minutes'), - }, - { - name: 'update-lifetime-values-for-all-pools', - interval: every(45, 'minutes'), - }, - { - name: 'sync-changed-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(2, 'minutes') : every(1, 'minutes'), - alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - }, - { - name: 'user-sync-wallet-balances-for-all-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(29, 'minutes') : every(9, 'minutes'), - }, - { - name: 'user-sync-staked-balances', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(31, 'minutes') : every(11, 'minutes'), - }, - { - name: 'sync-coingecko-coinids', - interval: every(2, 'hours'), - }, - { - name: 'purge-old-tokenprices', - interval: every(1, 'days'), - alarmEvaluationPeriod: 1, - alarmDatapointsToAlarm: 1, - }, - { - name: 'update-fee-volume-yield-all-pools', - interval: every(75, 'minutes'), - }, - { - name: 'sync-vebal-balances', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(14, 'minutes'), - }, - { - name: 'sync-vebal-totalSupply', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(16, 'minutes'), - }, - ], -}; diff --git a/modules/network/arbitrum/index.ts b/modules/network/arbitrum/index.ts new file mode 100644 index 000000000..23ef3e3f0 --- /dev/null +++ b/modules/network/arbitrum/index.ts @@ -0,0 +1,9 @@ +import { JsonRpcProvider } from '@ethersproject/providers'; +import { arbitrumNetworkData as data } from './data'; +import { arbitrumWorkerJobs as workerJobs } from './workers'; + +export class ArbitrumNetworkConfig { + static data = data; + static workerJobs = workerJobs; + static provider = new JsonRpcProvider({ url: data.rpcUrl, timeout: 60000 }) +}; diff --git a/modules/network/arbitrum/services.ts b/modules/network/arbitrum/services.ts new file mode 100644 index 000000000..dd678cd84 --- /dev/null +++ b/modules/network/arbitrum/services.ts @@ -0,0 +1,43 @@ +import { tokenService } from '../../token/token.service'; +import { PhantomStableAprService } from '../../pool/lib/apr-data-sources/phantom-stable-apr.service'; +import { BoostedPoolAprService } from '../../pool/lib/apr-data-sources/boosted-pool-apr.service'; +import { SwapFeeAprService } from '../../pool/lib/apr-data-sources/swap-fee-apr.service'; +import { GaugeAprService } from '../../pool/lib/apr-data-sources/ve-bal-gauge-apr.service'; +import { GaugeStakingService } from '../../pool/lib/staking/gauge-staking.service'; +import { BptPriceHandlerService } from '../../token/lib/token-price-handlers/bpt-price-handler.service'; +import { LinearWrappedTokenPriceHandlerService } from '../../token/lib/token-price-handlers/linear-wrapped-token-price-handler.service'; +import { SwapsPriceHandlerService } from '../../token/lib/token-price-handlers/swaps-price-handler.service'; +import { UserSyncGaugeBalanceService } from '../../user/lib/user-sync-gauge-balance.service'; +import { GithubContentService } from '../../content/github-content.service'; +import { gaugeSubgraphService } from '../../subgraphs/gauge-subgraph/gauge-subgraph.service'; +import { CoingeckoPriceHandlerService } from '../../token/lib/token-price-handlers/coingecko-price-handler.service'; +import { coingeckoService } from '../../coingecko/coingecko.service'; +import { IbTokensAprService } from '../../pool/lib/apr-data-sources/ib-tokens-apr.service'; +import { arbitrumNetworkData as data } from './data'; + +export const arbitrumCreateServices = () => ({ + contentService: new GithubContentService(), + poolAprServices: [ + new IbTokensAprService( + data.ibAprConfig, + data.chain.prismaId, + data.balancer.yieldProtocolFeePercentage, + data.balancer.swapProtocolFeePercentage, + ), + new PhantomStableAprService( + data.chain.prismaId, + data.balancer.yieldProtocolFeePercentage, + ), + new BoostedPoolAprService(), + new SwapFeeAprService(data.balancer.swapProtocolFeePercentage), + new GaugeAprService(tokenService, [data.bal!.address]), + ], + poolStakingServices: [new GaugeStakingService(gaugeSubgraphService, data.bal!.address)], + tokenPriceHandlers: [ + new CoingeckoPriceHandlerService(coingeckoService), + new BptPriceHandlerService(), + new LinearWrappedTokenPriceHandlerService(), + new SwapsPriceHandlerService(), + ], + userStakedBalanceServices: [new UserSyncGaugeBalanceService()], +}); diff --git a/modules/network/arbitrum/workers.ts b/modules/network/arbitrum/workers.ts new file mode 100644 index 000000000..e59837e72 --- /dev/null +++ b/modules/network/arbitrum/workers.ts @@ -0,0 +1,99 @@ +import { every } from '../../../worker/intervals'; +import { env } from '../../../app/env'; +import { DeploymentEnv, WorkerJob } from '../network-config-types'; + +/* +For sub-minute jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. +This is needed because the minimum alarm period is 1 minute and we want the alarm to trigger already after 1 minute instead of 3. + +For every 1 days jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. +This is needed because the maximum alarm evaluation period is 1 day (period * evaluationPeriod). +*/ +export const arbitrumWorkerJobs: WorkerJob[] = [ + { + name: 'update-token-prices', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(2, 'minutes'), + }, + { + name: 'update-liquidity-for-inactive-pools', + interval: every(1, 'days'), + alarmEvaluationPeriod: 1, + alarmDatapointsToAlarm: 1, + }, + { + name: 'update-liquidity-for-active-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(8, 'minutes') : every(4, 'minutes'), + }, + { + name: 'update-pool-apr', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(7, 'minutes') : every(5, 'minutes'), + }, + { + name: 'load-on-chain-data-for-pools-with-active-updates', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(9, 'minutes') : every(5, 'minutes'), + }, + { + name: 'sync-new-pools-from-subgraph', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(12, 'minutes') : every(8, 'minutes'), + }, + { + name: 'sync-tokens-from-pool-tokens', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(7, 'minutes'), + }, + { + name: 'update-liquidity-24h-ago-for-all-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(8, 'minutes'), + }, + { + name: 'cache-average-block-time', + interval: every(1, 'hours'), + }, + { + name: 'sync-staking-for-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(10, 'minutes'), + }, + { + name: 'sync-latest-snapshots-for-all-pools', + interval: every(90, 'minutes'), + }, + { + name: 'update-lifetime-values-for-all-pools', + interval: every(45, 'minutes'), + }, + { + name: 'sync-changed-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(2, 'minutes') : every(1, 'minutes'), + alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + }, + { + name: 'user-sync-wallet-balances-for-all-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(29, 'minutes') : every(9, 'minutes'), + }, + { + name: 'user-sync-staked-balances', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(31, 'minutes') : every(11, 'minutes'), + }, + { + name: 'sync-coingecko-coinids', + interval: every(2, 'hours'), + }, + { + name: 'purge-old-tokenprices', + interval: every(1, 'days'), + alarmEvaluationPeriod: 1, + alarmDatapointsToAlarm: 1, + }, + { + name: 'update-fee-volume-yield-all-pools', + interval: every(75, 'minutes'), + }, + { + name: 'sync-vebal-balances', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(14, 'minutes'), + }, + { + name: 'sync-vebal-totalSupply', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(16, 'minutes'), + }, +]; diff --git a/modules/network/avalanche.ts b/modules/network/avalanche/data.ts similarity index 54% rename from modules/network/avalanche.ts rename to modules/network/avalanche/data.ts index 5725ea5b6..42ee6ffef 100644 --- a/modules/network/avalanche.ts +++ b/modules/network/avalanche/data.ts @@ -1,24 +1,8 @@ -import { BigNumber, ethers } from 'ethers'; -import { DeploymentEnv, NetworkConfig, NetworkData } from './network-config-types'; -import { tokenService } from '../token/token.service'; -import { PhantomStableAprService } from '../pool/lib/apr-data-sources/phantom-stable-apr.service'; -import { BoostedPoolAprService } from '../pool/lib/apr-data-sources/boosted-pool-apr.service'; -import { SwapFeeAprService } from '../pool/lib/apr-data-sources/swap-fee-apr.service'; -import { GaugeAprService } from '../pool/lib/apr-data-sources/ve-bal-gauge-apr.service'; -import { GaugeStakingService } from '../pool/lib/staking/gauge-staking.service'; -import { BptPriceHandlerService } from '../token/lib/token-price-handlers/bpt-price-handler.service'; -import { LinearWrappedTokenPriceHandlerService } from '../token/lib/token-price-handlers/linear-wrapped-token-price-handler.service'; -import { SwapsPriceHandlerService } from '../token/lib/token-price-handlers/swaps-price-handler.service'; -import { UserSyncGaugeBalanceService } from '../user/lib/user-sync-gauge-balance.service'; -import { every } from '../../worker/intervals'; -import { GithubContentService } from '../content/github-content.service'; -import { gaugeSubgraphService } from '../subgraphs/gauge-subgraph/gauge-subgraph.service'; -import { coingeckoService } from '../coingecko/coingecko.service'; -import { CoingeckoPriceHandlerService } from '../token/lib/token-price-handlers/coingecko-price-handler.service'; -import { env } from '../../app/env'; -import { IbTokensAprService } from '../pool/lib/apr-data-sources/ib-tokens-apr.service'; +import { BigNumber } from '@ethersproject/bignumber'; +import { env } from '../../../app/env'; +import { DeploymentEnv, NetworkData } from "../network-config-types"; -const avalancheNetworkData: NetworkData = { +export const avalancheNetworkData: NetworkData = { chain: { slug: 'avalanche', id: 43114, @@ -211,127 +195,3 @@ const avalancheNetworkData: NetworkData = { }, }, }; - -export const avalancheNetworkConfig: NetworkConfig = { - data: avalancheNetworkData, - contentService: new GithubContentService(), - provider: new ethers.providers.JsonRpcProvider({ url: avalancheNetworkData.rpcUrl, timeout: 60000 }), - poolAprServices: [ - 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]), - ], - poolStakingServices: [new GaugeStakingService(gaugeSubgraphService, avalancheNetworkData.bal!.address)], - tokenPriceHandlers: [ - new CoingeckoPriceHandlerService(coingeckoService), - new BptPriceHandlerService(), - new LinearWrappedTokenPriceHandlerService(), - new SwapsPriceHandlerService(), - ], - userStakedBalanceServices: [new UserSyncGaugeBalanceService()], - /* - For sub-minute jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. - This is needed because the minimum alarm period is 1 minute and we want the alarm to trigger already after 1 minute instead of 3. - - For every 1 days jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. - This is needed because the maximum alarm evaluation period is 1 day (period * evaluationPeriod). - */ - workerJobs: [ - { - name: 'update-token-prices', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(2, 'minutes'), - }, - { - name: 'update-liquidity-for-inactive-pools', - interval: every(1, 'days'), - alarmEvaluationPeriod: 1, - alarmDatapointsToAlarm: 1, - }, - { - name: 'update-liquidity-for-active-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(8, 'minutes') : every(4, 'minutes'), - }, - { - name: 'update-pool-apr', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(7, 'minutes') : every(5, 'minutes'), - }, - { - name: 'load-on-chain-data-for-pools-with-active-updates', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(9, 'minutes') : every(5, 'minutes'), - }, - { - name: 'sync-new-pools-from-subgraph', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(12, 'minutes') : every(8, 'minutes'), - }, - { - name: 'sync-tokens-from-pool-tokens', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(7, 'minutes'), - }, - { - name: 'update-liquidity-24h-ago-for-all-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(8, 'minutes'), - }, - { - name: 'cache-average-block-time', - interval: every(1, 'hours'), - }, - { - name: 'sync-staking-for-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(10, 'minutes'), - }, - { - name: 'sync-latest-snapshots-for-all-pools', - interval: every(90, 'minutes'), - }, - { - name: 'update-lifetime-values-for-all-pools', - interval: every(45, 'minutes'), - }, - { - name: 'sync-changed-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(2, 'minutes') : every(1, 'minutes'), - alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - }, - { - name: 'user-sync-wallet-balances-for-all-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(29, 'minutes') : every(9, 'minutes'), - }, - { - name: 'user-sync-staked-balances', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(31, 'minutes') : every(11, 'minutes'), - }, - { - name: 'sync-coingecko-coinids', - interval: every(2, 'hours'), - }, - { - name: 'purge-old-tokenprices', - interval: every(1, 'days'), - alarmEvaluationPeriod: 1, - alarmDatapointsToAlarm: 1, - }, - { - name: 'update-fee-volume-yield-all-pools', - interval: every(75, 'minutes'), - }, - { - name: 'sync-vebal-balances', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(14, 'minutes'), - }, - { - name: 'sync-vebal-totalSupply', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(16, 'minutes'), - }, - ], -}; diff --git a/modules/network/avalanche/index.ts b/modules/network/avalanche/index.ts new file mode 100644 index 000000000..6f6ec1f6c --- /dev/null +++ b/modules/network/avalanche/index.ts @@ -0,0 +1,9 @@ +import { JsonRpcProvider } from '@ethersproject/providers'; +import { avalancheNetworkData as data } from './data'; +import { avalancheWorkerJobs as workerJobs } from './workers'; + +export class AvalancheNetworkConfig { + static data = data; + static workerJobs = workerJobs; + static provider = new JsonRpcProvider({ url: data.rpcUrl, timeout: 60000 }) +}; diff --git a/modules/network/avalanche/services.ts b/modules/network/avalanche/services.ts new file mode 100644 index 000000000..1066a062b --- /dev/null +++ b/modules/network/avalanche/services.ts @@ -0,0 +1,43 @@ +import { tokenService } from '../../token/token.service'; +import { PhantomStableAprService } from '../../pool/lib/apr-data-sources/phantom-stable-apr.service'; +import { BoostedPoolAprService } from '../../pool/lib/apr-data-sources/boosted-pool-apr.service'; +import { SwapFeeAprService } from '../../pool/lib/apr-data-sources/swap-fee-apr.service'; +import { GaugeAprService } from '../../pool/lib/apr-data-sources/ve-bal-gauge-apr.service'; +import { GaugeStakingService } from '../../pool/lib/staking/gauge-staking.service'; +import { BptPriceHandlerService } from '../../token/lib/token-price-handlers/bpt-price-handler.service'; +import { LinearWrappedTokenPriceHandlerService } from '../../token/lib/token-price-handlers/linear-wrapped-token-price-handler.service'; +import { SwapsPriceHandlerService } from '../../token/lib/token-price-handlers/swaps-price-handler.service'; +import { UserSyncGaugeBalanceService } from '../../user/lib/user-sync-gauge-balance.service'; +import { GithubContentService } from '../../content/github-content.service'; +import { gaugeSubgraphService } from '../../subgraphs/gauge-subgraph/gauge-subgraph.service'; +import { CoingeckoPriceHandlerService } from '../../token/lib/token-price-handlers/coingecko-price-handler.service'; +import { coingeckoService } from '../../coingecko/coingecko.service'; +import { IbTokensAprService } from '../../pool/lib/apr-data-sources/ib-tokens-apr.service'; +import { avalancheNetworkData as data } from './data'; + +export const avalancheCreateServices = () => ({ + contentService: new GithubContentService(), + poolAprServices: [ + new IbTokensAprService( + data.ibAprConfig, + data.chain.prismaId, + data.balancer.yieldProtocolFeePercentage, + data.balancer.swapProtocolFeePercentage, + ), + new PhantomStableAprService( + data.chain.prismaId, + data.balancer.yieldProtocolFeePercentage, + ), + new BoostedPoolAprService(), + new SwapFeeAprService(data.balancer.swapProtocolFeePercentage), + new GaugeAprService(tokenService, [data.bal!.address]), + ], + poolStakingServices: [new GaugeStakingService(gaugeSubgraphService, data.bal!.address)], + tokenPriceHandlers: [ + new CoingeckoPriceHandlerService(coingeckoService), + new BptPriceHandlerService(), + new LinearWrappedTokenPriceHandlerService(), + new SwapsPriceHandlerService(), + ], + userStakedBalanceServices: [new UserSyncGaugeBalanceService()], +}); diff --git a/modules/network/avalanche/workers.ts b/modules/network/avalanche/workers.ts new file mode 100644 index 000000000..bc92f03ff --- /dev/null +++ b/modules/network/avalanche/workers.ts @@ -0,0 +1,99 @@ +import { every } from '../../../worker/intervals'; +import { env } from '../../../app/env'; +import { DeploymentEnv, WorkerJob } from '../network-config-types'; + +/* +For sub-minute jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. +This is needed because the minimum alarm period is 1 minute and we want the alarm to trigger already after 1 minute instead of 3. + +For every 1 days jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. +This is needed because the maximum alarm evaluation period is 1 day (period * evaluationPeriod). +*/ +export const avalancheWorkerJobs: WorkerJob[] = [ + { + name: 'update-token-prices', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(2, 'minutes'), + }, + { + name: 'update-liquidity-for-inactive-pools', + interval: every(1, 'days'), + alarmEvaluationPeriod: 1, + alarmDatapointsToAlarm: 1, + }, + { + name: 'update-liquidity-for-active-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(8, 'minutes') : every(4, 'minutes'), + }, + { + name: 'update-pool-apr', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(7, 'minutes') : every(5, 'minutes'), + }, + { + name: 'load-on-chain-data-for-pools-with-active-updates', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(9, 'minutes') : every(5, 'minutes'), + }, + { + name: 'sync-new-pools-from-subgraph', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(12, 'minutes') : every(8, 'minutes'), + }, + { + name: 'sync-tokens-from-pool-tokens', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(7, 'minutes'), + }, + { + name: 'update-liquidity-24h-ago-for-all-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(8, 'minutes'), + }, + { + name: 'cache-average-block-time', + interval: every(1, 'hours'), + }, + { + name: 'sync-staking-for-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(10, 'minutes'), + }, + { + name: 'sync-latest-snapshots-for-all-pools', + interval: every(90, 'minutes'), + }, + { + name: 'update-lifetime-values-for-all-pools', + interval: every(45, 'minutes'), + }, + { + name: 'sync-changed-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(2, 'minutes') : every(1, 'minutes'), + alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + }, + { + name: 'user-sync-wallet-balances-for-all-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(29, 'minutes') : every(9, 'minutes'), + }, + { + name: 'user-sync-staked-balances', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(31, 'minutes') : every(11, 'minutes'), + }, + { + name: 'sync-coingecko-coinids', + interval: every(2, 'hours'), + }, + { + name: 'purge-old-tokenprices', + interval: every(1, 'days'), + alarmEvaluationPeriod: 1, + alarmDatapointsToAlarm: 1, + }, + { + name: 'update-fee-volume-yield-all-pools', + interval: every(75, 'minutes'), + }, + { + name: 'sync-vebal-balances', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(14, 'minutes'), + }, + { + name: 'sync-vebal-totalSupply', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(16, 'minutes'), + }, +]; diff --git a/modules/network/base.ts b/modules/network/base.ts deleted file mode 100644 index 51e43a18b..000000000 --- a/modules/network/base.ts +++ /dev/null @@ -1,235 +0,0 @@ -import { BigNumber, ethers } from 'ethers'; -import { DeploymentEnv, NetworkConfig, NetworkData } from './network-config-types'; -import { tokenService } from '../token/token.service'; -import { BoostedPoolAprService } from '../pool/lib/apr-data-sources/boosted-pool-apr.service'; -import { SwapFeeAprService } from '../pool/lib/apr-data-sources/swap-fee-apr.service'; -import { GaugeAprService } from '../pool/lib/apr-data-sources/ve-bal-gauge-apr.service'; -import { GaugeStakingService } from '../pool/lib/staking/gauge-staking.service'; -import { BptPriceHandlerService } from '../token/lib/token-price-handlers/bpt-price-handler.service'; -import { LinearWrappedTokenPriceHandlerService } from '../token/lib/token-price-handlers/linear-wrapped-token-price-handler.service'; -import { SwapsPriceHandlerService } from '../token/lib/token-price-handlers/swaps-price-handler.service'; -import { UserSyncGaugeBalanceService } from '../user/lib/user-sync-gauge-balance.service'; -import { every } from '../../worker/intervals'; -import { GithubContentService } from '../content/github-content.service'; -import { gaugeSubgraphService } from '../subgraphs/gauge-subgraph/gauge-subgraph.service'; -import { CoingeckoPriceHandlerService } from '../token/lib/token-price-handlers/coingecko-price-handler.service'; -import { coingeckoService } from '../coingecko/coingecko.service'; -import { env } from '../../app/env'; -import { IbTokensAprService } from '../pool/lib/apr-data-sources/ib-tokens-apr.service'; - -const baseNetworkData: NetworkData = { - chain: { - slug: 'base', - id: 8453, - nativeAssetAddress: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', - wrappedNativeAssetAddress: '0x4200000000000000000000000000000000000006', - prismaId: 'BASE', - gqlId: 'BASE', - }, - subgraphs: { - startDate: '2023-07-10', - balancer: 'https://api.studio.thegraph.com/query/24660/balancer-base-v2/version/latest', - beetsBar: '', - blocks: 'https://api.studio.thegraph.com/query/48427/bleu-base-blocks/version/latest', - gauge: 'https://api.studio.thegraph.com/query/24660/balancer-gauges-base/version/latest', - veBalLocks: 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gauges', - userBalances: '', - }, - eth: { - address: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', - addressFormatted: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', - symbol: 'ETH', - name: 'Ether', - }, - weth: { - address: '0x4200000000000000000000000000000000000006', - addressFormatted: '0x4200000000000000000000000000000000000006', - }, - coingecko: { - nativeAssetId: 'ethereum', - platformId: 'base', - excludedTokenAddresses: [], - }, - tokenPrices: { - maxHourlyPriceHistoryNumDays: 100, - }, - rpcUrl: 'https://base.gateway.tenderly.co/7mM7DbBouY1JjnQd9MMDsd', - rpcMaxBlockRange: 500, - sanity: { - projectId: '', - dataset: '', - }, - protocolToken: 'bal', - bal: { - address: '0x4158734d47fc9692176b5085e0f52ee0da5d47f1', - }, - veBal: { - address: '0xc128a9954e6c874ea3d62ce62b468ba073093f25', - delegationProxy: '0xd87f44df0159dc78029ab9ca7d7e57e7249f5acd', - }, - balancer: { - vault: '0xba12222222228d8ba445958a75a0704d566bf2c8', - composableStablePoolFactories: ['0x8df317a729fcaa260306d7de28888932cb579b88'], - weightedPoolV2Factories: ['0x4c32a8a8fda4e24139b51b456b42290f51d6a1c4'], - swapProtocolFeePercentage: 0.5, - yieldProtocolFeePercentage: 0.5, - }, - ibAprConfig: { - defaultHandlers: { - cbETH: { - tokenAddress: '0x2ae3f1ec7f1f5012cfeab0185bfc7aa3cf0dec22', - sourceUrl: 'https://api.exchange.coinbase.com/wrapped-assets/CBETH/', - path: 'apy', - scale: 1, - isIbYield: true, - }, - }, - }, - multicall: '0xca11bde05977b3631167028862be2a173976ca11', - multicall3: '0xca11bde05977b3631167028862be2a173976ca11', - avgBlockSpeed: 2, - sor: { - main: { - url: 'https://uu6cfghhd5lqa7py3nojxkivd40zuugb.lambda-url.ca-central-1.on.aws/', - maxPools: 8, - forceRefresh: false, - gasPrice: BigNumber.from(10), - swapGas: BigNumber.from('1000000'), - }, - canary: { - url: 'https://ksa66wlkjbvteijxmflqjehsay0jmekw.lambda-url.eu-central-1.on.aws/', - maxPools: 8, - forceRefresh: false, - gasPrice: BigNumber.from(10), - swapGas: BigNumber.from('1000000'), - }, - }, - monitoring: { - main: { - alarmTopicArn: 'arn:aws:sns:ca-central-1:118697801881:api_alarms', - }, - canary: { - alarmTopicArn: 'arn:aws:sns:eu-central-1:118697801881:api_alarms', - }, - }, -}; - -export const baseNetworkConfig: NetworkConfig = { - data: baseNetworkData, - contentService: new GithubContentService(), - provider: new ethers.providers.JsonRpcProvider({ url: baseNetworkData.rpcUrl, timeout: 60000 }), - poolAprServices: [ - 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]), - ], - poolStakingServices: [new GaugeStakingService(gaugeSubgraphService, baseNetworkData.bal!.address)], - tokenPriceHandlers: [ - new CoingeckoPriceHandlerService(coingeckoService), - new BptPriceHandlerService(), - new LinearWrappedTokenPriceHandlerService(), - new SwapsPriceHandlerService(), - ], - userStakedBalanceServices: [new UserSyncGaugeBalanceService()], - /* - For sub-minute jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. - This is needed because the minimum alarm period is 1 minute and we want the alarm to trigger already after 1 minute instead of 3. - - For every 1 days jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. - This is needed because the maximum alarm evaluation period is 1 day (period * evaluationPeriod). - */ - workerJobs: [ - { - name: 'update-token-prices', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(2, 'minutes'), - }, - { - name: 'update-liquidity-for-inactive-pools', - interval: every(1, 'days'), - alarmEvaluationPeriod: 1, - alarmDatapointsToAlarm: 1, - }, - { - name: 'update-liquidity-for-active-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(8, 'minutes') : every(4, 'minutes'), - }, - { - name: 'update-pool-apr', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(7, 'minutes') : every(5, 'minutes'), - }, - { - name: 'load-on-chain-data-for-pools-with-active-updates', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(9, 'minutes') : every(5, 'minutes'), - }, - { - name: 'sync-new-pools-from-subgraph', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(12, 'minutes') : every(8, 'minutes'), - }, - { - name: 'sync-tokens-from-pool-tokens', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(7, 'minutes'), - }, - { - name: 'update-liquidity-24h-ago-for-all-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(8, 'minutes'), - }, - { - name: 'cache-average-block-time', - interval: every(1, 'hours'), - }, - { - name: 'sync-staking-for-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(10, 'minutes'), - }, - { - name: 'sync-latest-snapshots-for-all-pools', - interval: every(90, 'minutes'), - }, - { - name: 'update-lifetime-values-for-all-pools', - interval: every(45, 'minutes'), - }, - { - name: 'sync-changed-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(2, 'minutes') : every(1, 'minutes'), - alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - }, - { - name: 'user-sync-wallet-balances-for-all-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(29, 'minutes') : every(9, 'minutes'), - }, - { - name: 'user-sync-staked-balances', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(31, 'minutes') : every(11, 'minutes'), - }, - { - name: 'sync-coingecko-coinids', - interval: every(2, 'hours'), - }, - { - name: 'purge-old-tokenprices', - interval: every(1, 'days'), - alarmEvaluationPeriod: 1, - alarmDatapointsToAlarm: 1, - }, - { - name: 'update-fee-volume-yield-all-pools', - interval: every(75, 'minutes'), - }, - { - name: 'sync-vebal-balances', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(14, 'minutes'), - }, - { - name: 'sync-vebal-totalSupply', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(16, 'minutes'), - }, - ], -}; diff --git a/modules/network/base/data.ts b/modules/network/base/data.ts new file mode 100644 index 000000000..8c8d19713 --- /dev/null +++ b/modules/network/base/data.ts @@ -0,0 +1,99 @@ +import { BigNumber } from '@ethersproject/bignumber'; +import { NetworkData } from "../network-config-types"; + +export const baseNetworkData: NetworkData = { + chain: { + slug: 'base', + id: 8453, + nativeAssetAddress: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + wrappedNativeAssetAddress: '0x4200000000000000000000000000000000000006', + prismaId: 'BASE', + gqlId: 'BASE', + }, + subgraphs: { + startDate: '2023-07-10', + balancer: 'https://api.studio.thegraph.com/query/24660/balancer-base-v2/version/latest', + beetsBar: '', + blocks: 'https://api.studio.thegraph.com/query/48427/bleu-base-blocks/version/latest', + gauge: 'https://api.studio.thegraph.com/query/24660/balancer-gauges-base/version/latest', + veBalLocks: 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gauges', + userBalances: '', + }, + eth: { + address: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', + addressFormatted: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + symbol: 'ETH', + name: 'Ether', + }, + weth: { + address: '0x4200000000000000000000000000000000000006', + addressFormatted: '0x4200000000000000000000000000000000000006', + }, + coingecko: { + nativeAssetId: 'ethereum', + platformId: 'base', + excludedTokenAddresses: [], + }, + tokenPrices: { + maxHourlyPriceHistoryNumDays: 100, + }, + rpcUrl: 'https://base.gateway.tenderly.co/7mM7DbBouY1JjnQd9MMDsd', + rpcMaxBlockRange: 500, + sanity: { + projectId: '', + dataset: '', + }, + protocolToken: 'bal', + bal: { + address: '0x4158734d47fc9692176b5085e0f52ee0da5d47f1', + }, + veBal: { + address: '0xc128a9954e6c874ea3d62ce62b468ba073093f25', + delegationProxy: '0xd87f44df0159dc78029ab9ca7d7e57e7249f5acd', + }, + balancer: { + vault: '0xba12222222228d8ba445958a75a0704d566bf2c8', + composableStablePoolFactories: ['0x8df317a729fcaa260306d7de28888932cb579b88'], + weightedPoolV2Factories: ['0x4c32a8a8fda4e24139b51b456b42290f51d6a1c4'], + swapProtocolFeePercentage: 0.5, + yieldProtocolFeePercentage: 0.5, + }, + ibAprConfig: { + defaultHandlers: { + cbETH: { + tokenAddress: '0x2ae3f1ec7f1f5012cfeab0185bfc7aa3cf0dec22', + sourceUrl: 'https://api.exchange.coinbase.com/wrapped-assets/CBETH/', + path: 'apy', + scale: 1, + isIbYield: true, + }, + }, + }, + multicall: '0xca11bde05977b3631167028862be2a173976ca11', + multicall3: '0xca11bde05977b3631167028862be2a173976ca11', + avgBlockSpeed: 2, + sor: { + main: { + url: 'https://uu6cfghhd5lqa7py3nojxkivd40zuugb.lambda-url.ca-central-1.on.aws/', + maxPools: 8, + forceRefresh: false, + gasPrice: BigNumber.from(10), + swapGas: BigNumber.from('1000000'), + }, + canary: { + url: 'https://ksa66wlkjbvteijxmflqjehsay0jmekw.lambda-url.eu-central-1.on.aws/', + maxPools: 8, + forceRefresh: false, + gasPrice: BigNumber.from(10), + swapGas: BigNumber.from('1000000'), + }, + }, + monitoring: { + main: { + alarmTopicArn: 'arn:aws:sns:ca-central-1:118697801881:api_alarms', + }, + canary: { + alarmTopicArn: 'arn:aws:sns:eu-central-1:118697801881:api_alarms', + }, + }, +}; diff --git a/modules/network/base/index.ts b/modules/network/base/index.ts new file mode 100644 index 000000000..ee3b31ec9 --- /dev/null +++ b/modules/network/base/index.ts @@ -0,0 +1,9 @@ +import { JsonRpcProvider } from '@ethersproject/providers'; +import { baseNetworkData as data } from './data'; +import { baseWorkerJobs as workerJobs } from './workers'; + +export class BaseNetworkConfig { + static data = data; + static workerJobs = workerJobs; + static provider = new JsonRpcProvider({ url: data.rpcUrl, timeout: 60000 }) +}; diff --git a/modules/network/base/services.ts b/modules/network/base/services.ts new file mode 100644 index 000000000..7d09208b8 --- /dev/null +++ b/modules/network/base/services.ts @@ -0,0 +1,38 @@ +import { tokenService } from '../../token/token.service'; +import { BoostedPoolAprService } from '../../pool/lib/apr-data-sources/boosted-pool-apr.service'; +import { SwapFeeAprService } from '../../pool/lib/apr-data-sources/swap-fee-apr.service'; +import { GaugeAprService } from '../../pool/lib/apr-data-sources/ve-bal-gauge-apr.service'; +import { GaugeStakingService } from '../../pool/lib/staking/gauge-staking.service'; +import { BptPriceHandlerService } from '../../token/lib/token-price-handlers/bpt-price-handler.service'; +import { LinearWrappedTokenPriceHandlerService } from '../../token/lib/token-price-handlers/linear-wrapped-token-price-handler.service'; +import { SwapsPriceHandlerService } from '../../token/lib/token-price-handlers/swaps-price-handler.service'; +import { UserSyncGaugeBalanceService } from '../../user/lib/user-sync-gauge-balance.service'; +import { GithubContentService } from '../../content/github-content.service'; +import { gaugeSubgraphService } from '../../subgraphs/gauge-subgraph/gauge-subgraph.service'; +import { CoingeckoPriceHandlerService } from '../../token/lib/token-price-handlers/coingecko-price-handler.service'; +import { coingeckoService } from '../../coingecko/coingecko.service'; +import { IbTokensAprService } from '../../pool/lib/apr-data-sources/ib-tokens-apr.service'; +import { baseNetworkData as data } from './data'; + +export const baseCreateServices = () => ({ + contentService: new GithubContentService(), + poolAprServices: [ + new IbTokensAprService( + data.ibAprConfig, + data.chain.prismaId, + data.balancer.yieldProtocolFeePercentage, + data.balancer.swapProtocolFeePercentage, + ), + new BoostedPoolAprService(), + new SwapFeeAprService(data.balancer.swapProtocolFeePercentage), + new GaugeAprService(tokenService, [data.bal!.address]), + ], + poolStakingServices: [new GaugeStakingService(gaugeSubgraphService, data.bal!.address)], + tokenPriceHandlers: [ + new CoingeckoPriceHandlerService(coingeckoService), + new BptPriceHandlerService(), + new LinearWrappedTokenPriceHandlerService(), + new SwapsPriceHandlerService(), + ], + userStakedBalanceServices: [new UserSyncGaugeBalanceService()], +}); diff --git a/modules/network/base/workers.ts b/modules/network/base/workers.ts new file mode 100644 index 000000000..1dbcd16ed --- /dev/null +++ b/modules/network/base/workers.ts @@ -0,0 +1,99 @@ +import { every } from '../../../worker/intervals'; +import { env } from '../../../app/env'; +import { DeploymentEnv, WorkerJob } from '../network-config-types'; + +/* +For sub-minute jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. +This is needed because the minimum alarm period is 1 minute and we want the alarm to trigger already after 1 minute instead of 3. + +For every 1 days jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. +This is needed because the maximum alarm evaluation period is 1 day (period * evaluationPeriod). +*/ +export const baseWorkerJobs: WorkerJob[] = [ + { + name: 'update-token-prices', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(2, 'minutes'), + }, + { + name: 'update-liquidity-for-inactive-pools', + interval: every(1, 'days'), + alarmEvaluationPeriod: 1, + alarmDatapointsToAlarm: 1, + }, + { + name: 'update-liquidity-for-active-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(8, 'minutes') : every(4, 'minutes'), + }, + { + name: 'update-pool-apr', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(7, 'minutes') : every(5, 'minutes'), + }, + { + name: 'load-on-chain-data-for-pools-with-active-updates', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(9, 'minutes') : every(5, 'minutes'), + }, + { + name: 'sync-new-pools-from-subgraph', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(12, 'minutes') : every(8, 'minutes'), + }, + { + name: 'sync-tokens-from-pool-tokens', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(7, 'minutes'), + }, + { + name: 'update-liquidity-24h-ago-for-all-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(8, 'minutes'), + }, + { + name: 'cache-average-block-time', + interval: every(1, 'hours'), + }, + { + name: 'sync-staking-for-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(10, 'minutes'), + }, + { + name: 'sync-latest-snapshots-for-all-pools', + interval: every(90, 'minutes'), + }, + { + name: 'update-lifetime-values-for-all-pools', + interval: every(45, 'minutes'), + }, + { + name: 'sync-changed-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(2, 'minutes') : every(1, 'minutes'), + alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + }, + { + name: 'user-sync-wallet-balances-for-all-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(29, 'minutes') : every(9, 'minutes'), + }, + { + name: 'user-sync-staked-balances', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(31, 'minutes') : every(11, 'minutes'), + }, + { + name: 'sync-coingecko-coinids', + interval: every(2, 'hours'), + }, + { + name: 'purge-old-tokenprices', + interval: every(1, 'days'), + alarmEvaluationPeriod: 1, + alarmDatapointsToAlarm: 1, + }, + { + name: 'update-fee-volume-yield-all-pools', + interval: every(75, 'minutes'), + }, + { + name: 'sync-vebal-balances', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(14, 'minutes'), + }, + { + name: 'sync-vebal-totalSupply', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(16, 'minutes'), + }, +]; diff --git a/modules/network/fantom.ts b/modules/network/fantom/data.ts similarity index 53% rename from modules/network/fantom.ts rename to modules/network/fantom/data.ts index 07c7ed9bf..74ff6d6d5 100644 --- a/modules/network/fantom.ts +++ b/modules/network/fantom/data.ts @@ -1,33 +1,7 @@ -import { BigNumber, ethers } from 'ethers'; -import { DeploymentEnv, NetworkConfig, NetworkData } from './network-config-types'; -import { SpookySwapAprService } from '../pool/lib/apr-data-sources/fantom/spooky-swap-apr.service'; -import { tokenService } from '../token/token.service'; -import { PhantomStableAprService } from '../pool/lib/apr-data-sources/phantom-stable-apr.service'; -import { BoostedPoolAprService } from '../pool/lib/apr-data-sources/boosted-pool-apr.service'; -import { SwapFeeAprService } from '../pool/lib/apr-data-sources/swap-fee-apr.service'; -import { MasterchefFarmAprService } from '../pool/lib/apr-data-sources/fantom/masterchef-farm-apr.service'; -import { ReliquaryFarmAprService } from '../pool/lib/apr-data-sources/fantom/reliquary-farm-apr.service'; -import { MasterChefStakingService } from '../pool/lib/staking/master-chef-staking.service'; -import { masterchefService } from '../subgraphs/masterchef-subgraph/masterchef.service'; -import { ReliquaryStakingService } from '../pool/lib/staking/reliquary-staking.service'; -import { reliquarySubgraphService } from '../subgraphs/reliquary-subgraph/reliquary.service'; -import { BeetsPriceHandlerService } from '../token/lib/token-price-handlers/beets-price-handler.service'; -import { FbeetsPriceHandlerService } from '../token/lib/token-price-handlers/fbeets-price-handler.service'; -import { ClqdrPriceHandlerService } from '../token/lib/token-price-handlers/clqdr-price-handler.service'; -import { BptPriceHandlerService } from '../token/lib/token-price-handlers/bpt-price-handler.service'; -import { LinearWrappedTokenPriceHandlerService } from '../token/lib/token-price-handlers/linear-wrapped-token-price-handler.service'; -import { SwapsPriceHandlerService } from '../token/lib/token-price-handlers/swaps-price-handler.service'; -import { UserSyncMasterchefFarmBalanceService } from '../user/lib/user-sync-masterchef-farm-balance.service'; -import { UserSyncReliquaryFarmBalanceService } from '../user/lib/user-sync-reliquary-farm-balance.service'; -import { every } from '../../worker/intervals'; -import { SanityContentService } from '../content/sanity-content.service'; -import { CoingeckoPriceHandlerService } from '../token/lib/token-price-handlers/coingecko-price-handler.service'; -import { coingeckoService } from '../coingecko/coingecko.service'; -import { env } from '../../app/env'; -import { IbTokensAprService } from '../pool/lib/apr-data-sources/ib-tokens-apr.service'; -import { BeetswarsGaugeVotingAprService } from '../pool/lib/apr-data-sources/fantom/beetswars-gauge-voting-apr'; +import { BigNumber } from '@ethersproject/bignumber'; +import { NetworkData } from "../network-config-types"; -const fantomNetworkData: NetworkData = { +export const fantomNetworkData: NetworkData = { chain: { slug: 'fantom', id: 250, @@ -294,163 +268,3 @@ const fantomNetworkData: NetworkData = { }, }, }; - -export const fantomNetworkConfig: NetworkConfig = { - data: fantomNetworkData, - contentService: new SanityContentService(), - provider: new ethers.providers.JsonRpcProvider({ url: fantomNetworkData.rpcUrl, timeout: 60000 }), - poolAprServices: [ - new IbTokensAprService( - fantomNetworkData.ibAprConfig, - fantomNetworkData.chain.prismaId, - fantomNetworkData.balancer.yieldProtocolFeePercentage, - fantomNetworkData.balancer.swapProtocolFeePercentage, - ), - // new SpookySwapAprService(tokenService, fantomNetworkData.spooky!.xBooContract), - new PhantomStableAprService( - fantomNetworkData.chain.prismaId, - fantomNetworkData.balancer.yieldProtocolFeePercentage, - ), - new BoostedPoolAprService(), - new SwapFeeAprService(fantomNetworkData.balancer.swapProtocolFeePercentage), - new MasterchefFarmAprService(fantomNetworkData.beets!.address), - new ReliquaryFarmAprService(fantomNetworkData.beets!.address), - new BeetswarsGaugeVotingAprService(), - ], - poolStakingServices: [ - new MasterChefStakingService(masterchefService, fantomNetworkData.masterchef!.excludedFarmIds), - new ReliquaryStakingService(fantomNetworkData.reliquary!.address, reliquarySubgraphService), - ], - tokenPriceHandlers: [ - new BeetsPriceHandlerService( - fantomNetworkData.beets!.address, - fantomNetworkData.beets!.beetsPriceProviderRpcUrl, - ), - new FbeetsPriceHandlerService(fantomNetworkData.fbeets!.address, fantomNetworkData.fbeets!.poolId), - new ClqdrPriceHandlerService(), - new CoingeckoPriceHandlerService(coingeckoService), - new BptPriceHandlerService(), - new LinearWrappedTokenPriceHandlerService(), - new SwapsPriceHandlerService(), - ], - userStakedBalanceServices: [ - new UserSyncMasterchefFarmBalanceService( - fantomNetworkData.fbeets!.address, - fantomNetworkData.fbeets!.farmId, - fantomNetworkData.masterchef!.address, - fantomNetworkData.masterchef!.excludedFarmIds, - ), - new UserSyncReliquaryFarmBalanceService(fantomNetworkData.reliquary!.address), - ], - /* - For sub-minute jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. - This is needed because the minimum alarm period is 1 minute and we want the alarm to trigger already after 1 minute instead of 3. - - For every 1 days jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. - This is needed because the maximum alarm evaluation period is 1 day (period * evaluationPeriod). - */ - workerJobs: [ - { - name: 'update-token-prices', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(2, 'minutes'), - }, - { - name: 'update-liquidity-for-inactive-pools', - interval: every(1, 'days'), - alarmEvaluationPeriod: 1, - alarmDatapointsToAlarm: 1, - }, - { - name: 'update-liquidity-for-active-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(6, 'minutes') : every(2, 'minutes'), - }, - { - name: 'update-pool-apr', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(6, 'minutes') : every(2, 'minutes'), - }, - { - name: 'load-on-chain-data-for-pools-with-active-updates', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(4, 'minutes') : every(1, 'minutes'), - }, - { - name: 'sync-new-pools-from-subgraph', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(6, 'minutes') : every(2, 'minutes'), - }, - { - name: 'sync-sanity-pool-data', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(9, 'minutes') : every(3, 'minutes'), - }, - { - name: 'sync-tokens-from-pool-tokens', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(5, 'minutes'), - }, - { - name: 'update-liquidity-24h-ago-for-all-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(5, 'minutes'), - }, - { - name: 'cache-average-block-time', - interval: every(1, 'hours'), - }, - { - name: 'sync-staking-for-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(5, 'minutes'), - }, - { - name: 'cache-protocol-data', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(5, 'minutes') : every(1, 'minutes'), - }, - { - name: 'sync-latest-snapshots-for-all-pools', - interval: every(90, 'minutes'), - }, - { - name: 'update-lifetime-values-for-all-pools', - interval: every(50, 'minutes'), - }, - { - name: 'sync-changed-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(2, 'minutes') : every(30, 'seconds'), - alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - }, - { - name: 'user-sync-wallet-balances-for-all-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(5, 'minutes') : every(20, 'seconds'), - alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - }, - { - name: 'user-sync-staked-balances', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(5, 'minutes') : every(20, 'seconds'), - alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - }, - { - name: 'sync-latest-reliquary-snapshots', - interval: every(1, 'hours'), - }, - { - name: 'sync-latest-relic-snapshots', - interval: every(1, 'hours'), - }, - { - name: 'purge-old-tokenprices', - interval: every(1, 'days'), - alarmEvaluationPeriod: 1, - alarmDatapointsToAlarm: 1, - }, - { - name: 'sync-coingecko-coinids', - interval: every(2, 'hours'), - }, - { - name: 'update-fee-volume-yield-all-pools', - interval: every(1, 'hours'), - }, - { - name: 'feed-data-to-datastudio', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(5, 'minutes') : every(1, 'minutes'), - }, - ], -}; diff --git a/modules/network/fantom/index.ts b/modules/network/fantom/index.ts new file mode 100644 index 000000000..9da16bad5 --- /dev/null +++ b/modules/network/fantom/index.ts @@ -0,0 +1,9 @@ +import { JsonRpcProvider } from '@ethersproject/providers'; +import { fantomNetworkData as data } from './data'; +import { fantomWorkerJobs as workerJobs } from './workers'; + +export class FantomNetworkConfig { + static data = data; + static workerJobs = workerJobs; + static provider = new JsonRpcProvider({ url: data.rpcUrl, timeout: 60000 }) +}; diff --git a/modules/network/fantom/services.ts b/modules/network/fantom/services.ts new file mode 100644 index 000000000..8ba0e8b9c --- /dev/null +++ b/modules/network/fantom/services.ts @@ -0,0 +1,69 @@ +import { SpookySwapAprService } from '../../pool/lib/apr-data-sources/fantom/spooky-swap-apr.service'; +import { tokenService } from '../../token/token.service'; +import { PhantomStableAprService } from '../../pool/lib/apr-data-sources/phantom-stable-apr.service'; +import { BoostedPoolAprService } from '../../pool/lib/apr-data-sources/boosted-pool-apr.service'; +import { SwapFeeAprService } from '../../pool/lib/apr-data-sources/swap-fee-apr.service'; +import { MasterchefFarmAprService } from '../../pool/lib/apr-data-sources/fantom/masterchef-farm-apr.service'; +import { ReliquaryFarmAprService } from '../../pool/lib/apr-data-sources/fantom/reliquary-farm-apr.service'; +import { MasterChefStakingService } from '../../pool/lib/staking/master-chef-staking.service'; +import { masterchefService } from '../../subgraphs/masterchef-subgraph/masterchef.service'; +import { ReliquaryStakingService } from '../../pool/lib/staking/reliquary-staking.service'; +import { reliquarySubgraphService } from '../../subgraphs/reliquary-subgraph/reliquary.service'; +import { BeetsPriceHandlerService } from '../../token/lib/token-price-handlers/beets-price-handler.service'; +import { FbeetsPriceHandlerService } from '../../token/lib/token-price-handlers/fbeets-price-handler.service'; +import { ClqdrPriceHandlerService } from '../../token/lib/token-price-handlers/clqdr-price-handler.service'; +import { BptPriceHandlerService } from '../../token/lib/token-price-handlers/bpt-price-handler.service'; +import { LinearWrappedTokenPriceHandlerService } from '../../token/lib/token-price-handlers/linear-wrapped-token-price-handler.service'; +import { SwapsPriceHandlerService } from '../../token/lib/token-price-handlers/swaps-price-handler.service'; +import { UserSyncMasterchefFarmBalanceService } from '../../user/lib/user-sync-masterchef-farm-balance.service'; +import { UserSyncReliquaryFarmBalanceService } from '../../user/lib/user-sync-reliquary-farm-balance.service'; +import { SanityContentService } from '../../content/sanity-content.service'; +import { CoingeckoPriceHandlerService } from '../../token/lib/token-price-handlers/coingecko-price-handler.service'; +import { coingeckoService } from '../../coingecko/coingecko.service'; +import { IbTokensAprService } from '../../pool/lib/apr-data-sources/ib-tokens-apr.service'; +import { BeetswarsGaugeVotingAprService } from '../../pool/lib/apr-data-sources/fantom/beetswars-gauge-voting-apr'; +import { fantomNetworkData as data } from './data'; + +export const fantomCreateServices = () => ({ + contentService: new SanityContentService(), + poolAprServices: [ + new IbTokensAprService( + data.ibAprConfig, + data.chain.prismaId, + data.balancer.yieldProtocolFeePercentage, + data.balancer.swapProtocolFeePercentage, + ), + // new SpookySwapAprService(tokenService, data.spooky!.xBooContract), + new PhantomStableAprService( + data.chain.prismaId, + data.balancer.yieldProtocolFeePercentage, + ), + new BoostedPoolAprService(), + new SwapFeeAprService(data.balancer.swapProtocolFeePercentage), + new MasterchefFarmAprService(data.beets!.address), + new ReliquaryFarmAprService(data.beets!.address), + new BeetswarsGaugeVotingAprService(), + ], + poolStakingServices: [ + new MasterChefStakingService(masterchefService, data.masterchef!.excludedFarmIds), + new ReliquaryStakingService(data.reliquary!.address, reliquarySubgraphService), + ], + tokenPriceHandlers: [ + new BeetsPriceHandlerService(data.beets!.address, data.beets!.beetsPriceProviderRpcUrl), + new FbeetsPriceHandlerService(data.fbeets!.address, data.fbeets!.poolId), + new ClqdrPriceHandlerService(), + new CoingeckoPriceHandlerService(coingeckoService), + new BptPriceHandlerService(), + new LinearWrappedTokenPriceHandlerService(), + new SwapsPriceHandlerService(), + ], + userStakedBalanceServices: [ + new UserSyncMasterchefFarmBalanceService( + data.fbeets!.address, + data.fbeets!.farmId, + data.masterchef!.address, + data.masterchef!.excludedFarmIds, + ), + new UserSyncReliquaryFarmBalanceService(data.reliquary!.address), + ], +}); diff --git a/modules/network/fantom/workers.ts b/modules/network/fantom/workers.ts new file mode 100644 index 000000000..b707ee142 --- /dev/null +++ b/modules/network/fantom/workers.ts @@ -0,0 +1,115 @@ +import { every } from '../../../worker/intervals'; +import { env } from '../../../app/env'; +import { DeploymentEnv, WorkerJob } from '../network-config-types'; + +/* +For sub-minute jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. +This is needed because the minimum alarm period is 1 minute and we want the alarm to trigger already after 1 minute instead of 3. + +For every 1 days jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. +This is needed because the maximum alarm evaluation period is 1 day (period * evaluationPeriod). +*/ +export const fantomWorkerJobs: WorkerJob[] = [ + { + name: 'update-token-prices', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(2, 'minutes'), + }, + { + name: 'update-liquidity-for-inactive-pools', + interval: every(1, 'days'), + alarmEvaluationPeriod: 1, + alarmDatapointsToAlarm: 1, + }, + { + name: 'update-liquidity-for-active-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(6, 'minutes') : every(2, 'minutes'), + }, + { + name: 'update-pool-apr', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(6, 'minutes') : every(2, 'minutes'), + }, + { + name: 'load-on-chain-data-for-pools-with-active-updates', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(4, 'minutes') : every(1, 'minutes'), + }, + { + name: 'sync-new-pools-from-subgraph', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(6, 'minutes') : every(2, 'minutes'), + }, + { + name: 'sync-sanity-pool-data', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(9, 'minutes') : every(3, 'minutes'), + }, + { + name: 'sync-tokens-from-pool-tokens', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(5, 'minutes'), + }, + { + name: 'update-liquidity-24h-ago-for-all-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(5, 'minutes'), + }, + { + name: 'cache-average-block-time', + interval: every(1, 'hours'), + }, + { + name: 'sync-staking-for-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(5, 'minutes'), + }, + { + name: 'cache-protocol-data', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(5, 'minutes') : every(1, 'minutes'), + }, + { + name: 'sync-latest-snapshots-for-all-pools', + interval: every(90, 'minutes'), + }, + { + name: 'update-lifetime-values-for-all-pools', + interval: every(50, 'minutes'), + }, + { + name: 'sync-changed-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(2, 'minutes') : every(30, 'seconds'), + alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + }, + { + name: 'user-sync-wallet-balances-for-all-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(5, 'minutes') : every(20, 'seconds'), + alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + }, + { + name: 'user-sync-staked-balances', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(5, 'minutes') : every(20, 'seconds'), + alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + }, + { + name: 'sync-latest-reliquary-snapshots', + interval: every(1, 'hours'), + }, + { + name: 'sync-latest-relic-snapshots', + interval: every(1, 'hours'), + }, + { + name: 'purge-old-tokenprices', + interval: every(1, 'days'), + alarmEvaluationPeriod: 1, + alarmDatapointsToAlarm: 1, + }, + { + name: 'sync-coingecko-coinids', + interval: every(2, 'hours'), + }, + { + name: 'update-fee-volume-yield-all-pools', + interval: every(1, 'hours'), + }, + { + name: 'feed-data-to-datastudio', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(5, 'minutes') : every(1, 'minutes'), + }, +]; diff --git a/modules/network/gnosis.ts b/modules/network/gnosis.ts deleted file mode 100644 index 5c4f30d84..000000000 --- a/modules/network/gnosis.ts +++ /dev/null @@ -1,264 +0,0 @@ -import { BigNumber, ethers } from 'ethers'; -import { DeploymentEnv, NetworkConfig, NetworkData } from './network-config-types'; -import { tokenService } from '../token/token.service'; -import { PhantomStableAprService } from '../pool/lib/apr-data-sources/phantom-stable-apr.service'; -import { BoostedPoolAprService } from '../pool/lib/apr-data-sources/boosted-pool-apr.service'; -import { SwapFeeAprService } from '../pool/lib/apr-data-sources/swap-fee-apr.service'; -import { GaugeAprService } from '../pool/lib/apr-data-sources/ve-bal-gauge-apr.service'; -import { GaugeStakingService } from '../pool/lib/staking/gauge-staking.service'; -import { BptPriceHandlerService } from '../token/lib/token-price-handlers/bpt-price-handler.service'; -import { LinearWrappedTokenPriceHandlerService } from '../token/lib/token-price-handlers/linear-wrapped-token-price-handler.service'; -import { SwapsPriceHandlerService } from '../token/lib/token-price-handlers/swaps-price-handler.service'; -import { UserSyncGaugeBalanceService } from '../user/lib/user-sync-gauge-balance.service'; -import { every } from '../../worker/intervals'; -import { GithubContentService } from '../content/github-content.service'; -import { gaugeSubgraphService } from '../subgraphs/gauge-subgraph/gauge-subgraph.service'; -import { coingeckoService } from '../coingecko/coingecko.service'; -import { CoingeckoPriceHandlerService } from '../token/lib/token-price-handlers/coingecko-price-handler.service'; -import { env } from '../../app/env'; -import { IbTokensAprService } from '../pool/lib/apr-data-sources/ib-tokens-apr.service'; - -const gnosisNetworkData: NetworkData = { - chain: { - slug: 'gnosis', - id: 100, - nativeAssetAddress: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', - wrappedNativeAssetAddress: '0xe91d153e0b41518a2ce8dd3d7944fa863463a97d', - prismaId: 'GNOSIS', - gqlId: 'GNOSIS', - }, - subgraphs: { - startDate: '2021-08-23', - balancer: 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gnosis-chain-v2', - beetsBar: 'https://', - blocks: 'https://api.thegraph.com/subgraphs/name/rebase-agency/gnosis-chain-blocks', - gauge: 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gauges-gnosis-chain', - veBalLocks: 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gauges', - userBalances: 'https://', - }, - eth: { - address: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', - addressFormatted: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', - symbol: 'xDAI', - name: 'xDAI', - }, - weth: { - address: '0xe91d153e0b41518a2ce8dd3d7944fa863463a97d', - addressFormatted: '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d', - }, - coingecko: { - nativeAssetId: 'xdai', - platformId: 'xdai', - excludedTokenAddresses: [], - }, - tokenPrices: { - maxHourlyPriceHistoryNumDays: 100, - }, - rpcUrl: - (env.DEPLOYMENT_ENV as DeploymentEnv) === 'main' ? `https://rpc.gnosischain.com` : 'https://gnosis.drpc.org', - rpcMaxBlockRange: 2000, - protocolToken: 'bal', - bal: { - address: '0x7ef541e2a22058048904fe5744f9c7e4c57af717', - }, - veBal: { - address: '0xc128a9954e6c874ea3d62ce62b468ba073093f25', - delegationProxy: '0x7a2535f5fb47b8e44c02ef5d9990588313fe8f05', - }, - balancer: { - vault: '0xba12222222228d8ba445958a75a0704d566bf2c8', - composableStablePoolFactories: [ - '0x76578ecf9a141296ec657847fb45b0585bcda3a6', - '0xc128468b7ce63ea702c1f104d55a2566b13d3abd', - '0xd87f44df0159dc78029ab9ca7d7e57e7249f5acd', - '0x4bdcc2fb18aeb9e2d281b0278d946445070eada7', - ], - weightedPoolV2Factories: [ - '0x6cad2ea22bfa7f4c14aae92e47f510cd5c509bc7', - '0xf302f9f50958c5593770fdf4d4812309ff77414f', - '0xc128a9954e6c874ea3d62ce62b468ba073093f25', - ], - swapProtocolFeePercentage: 0.5, - yieldProtocolFeePercentage: 0.5, - }, - multicall: '0xbb6fab6b627947dae0a75808250d8b2652952cb5', - multicall3: '0xca11bde05977b3631167028862be2a173976ca11', - avgBlockSpeed: 1, - sor: { - main: { - url: '', - maxPools: 8, - forceRefresh: false, - gasPrice: BigNumber.from(10), - swapGas: BigNumber.from('1000000'), - }, - canary: { - url: '', - maxPools: 8, - forceRefresh: false, - gasPrice: BigNumber.from(10), - swapGas: BigNumber.from('1000000'), - }, - }, - ibAprConfig: { - defaultHandlers: { - wstETH: { - tokenAddress: '0x6c76971f98945ae98dd7d4dfca8711ebea946ea6', - sourceUrl: 'https://eth-api.lido.fi/v1/protocol/steth/apr/sma', - path: 'data.smaApr', - isIbYield: true, - }, - }, - }, - datastudio: { - main: { - user: 'datafeed-service@datastudio-366113.iam.gserviceaccount.com', - sheetId: '11anHUEb9snGwvB-errb5HvO8TvoLTRJhkDdD80Gxw1Q', - databaseTabName: 'Database v2', - compositionTabName: 'Pool Composition v2', - emissionDataTabName: 'EmissionData', - }, - canary: { - user: 'datafeed-service@datastudio-366113.iam.gserviceaccount.com', - sheetId: '1HnJOuRQXGy06tNgqjYMzQNIsaCSCC01Yxe_lZhXBDpY', - databaseTabName: 'Database v2', - compositionTabName: 'Pool Composition v2', - emissionDataTabName: 'EmissionData', - }, - }, - monitoring: { - main: { - alarmTopicArn: 'arn:aws:sns:ca-central-1:118697801881:api_alarms', - }, - canary: { - alarmTopicArn: 'arn:aws:sns:eu-central-1:118697801881:api_alarms', - }, - }, - beefy: { - linearPools: [''], - }, -}; - -export const gnosisNetworkConfig: NetworkConfig = { - data: gnosisNetworkData, - contentService: new GithubContentService(), - provider: new ethers.providers.JsonRpcProvider({ url: gnosisNetworkData.rpcUrl, timeout: 60000 }), - poolAprServices: [ - 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]), - ], - poolStakingServices: [new GaugeStakingService(gaugeSubgraphService, gnosisNetworkData.bal!.address)], - tokenPriceHandlers: [ - new CoingeckoPriceHandlerService(coingeckoService), - new BptPriceHandlerService(), - new LinearWrappedTokenPriceHandlerService(), - new SwapsPriceHandlerService(), - ], - userStakedBalanceServices: [new UserSyncGaugeBalanceService()], - /* - For sub-minute jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. - This is needed because the minimum alarm period is 1 minute and we want the alarm to trigger already after 1 minute instead of 3. - - For every 1 days jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. - This is needed because the maximum alarm evaluation period is 1 day (period * evaluationPeriod). - */ - workerJobs: [ - { - name: 'update-token-prices', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(2, 'minutes'), - }, - { - name: 'update-liquidity-for-inactive-pools', - interval: every(1, 'days'), - alarmEvaluationPeriod: 1, - alarmDatapointsToAlarm: 1, - }, - { - name: 'update-liquidity-for-active-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(8, 'minutes') : every(4, 'minutes'), - }, - { - name: 'update-pool-apr', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(7, 'minutes') : every(5, 'minutes'), - }, - { - name: 'load-on-chain-data-for-pools-with-active-updates', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(9, 'minutes') : every(5, 'minutes'), - }, - { - name: 'sync-new-pools-from-subgraph', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(12, 'minutes') : every(8, 'minutes'), - }, - { - name: 'sync-tokens-from-pool-tokens', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(7, 'minutes'), - }, - { - name: 'update-liquidity-24h-ago-for-all-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(8, 'minutes'), - }, - { - name: 'cache-average-block-time', - interval: every(1, 'hours'), - }, - { - name: 'sync-staking-for-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(10, 'minutes'), - }, - { - name: 'sync-latest-snapshots-for-all-pools', - interval: every(90, 'minutes'), - }, - { - name: 'update-lifetime-values-for-all-pools', - interval: every(45, 'minutes'), - }, - { - name: 'sync-changed-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(2, 'minutes') : every(1, 'minutes'), - alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - }, - { - name: 'user-sync-wallet-balances-for-all-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(29, 'minutes') : every(9, 'minutes'), - }, - { - name: 'user-sync-staked-balances', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(31, 'minutes') : every(11, 'minutes'), - }, - { - name: 'sync-coingecko-coinids', - interval: every(2, 'hours'), - }, - { - name: 'purge-old-tokenprices', - interval: every(1, 'days'), - alarmEvaluationPeriod: 1, - alarmDatapointsToAlarm: 1, - }, - { - name: 'update-fee-volume-yield-all-pools', - interval: every(75, 'minutes'), - }, - { - name: 'sync-vebal-balances', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(14, 'minutes'), - }, - { - name: 'sync-vebal-totalSupply', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(16, 'minutes'), - }, - ], -}; diff --git a/modules/network/gnosis/data.ts b/modules/network/gnosis/data.ts new file mode 100644 index 000000000..631256c64 --- /dev/null +++ b/modules/network/gnosis/data.ts @@ -0,0 +1,124 @@ +import { BigNumber } from '@ethersproject/bignumber'; +import { DeploymentEnv, NetworkData } from "../network-config-types"; +import { env } from '../../../app/env'; + +export const gnosisNetworkData: NetworkData = { + chain: { + slug: 'gnosis', + id: 100, + nativeAssetAddress: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + wrappedNativeAssetAddress: '0xe91d153e0b41518a2ce8dd3d7944fa863463a97d', + prismaId: 'GNOSIS', + gqlId: 'GNOSIS', + }, + subgraphs: { + startDate: '2021-08-23', + balancer: 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gnosis-chain-v2', + beetsBar: 'https://', + blocks: 'https://api.thegraph.com/subgraphs/name/rebase-agency/gnosis-chain-blocks', + gauge: 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gauges-gnosis-chain', + veBalLocks: 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gauges', + userBalances: 'https://', + }, + eth: { + address: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', + addressFormatted: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + symbol: 'xDAI', + name: 'xDAI', + }, + weth: { + address: '0xe91d153e0b41518a2ce8dd3d7944fa863463a97d', + addressFormatted: '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d', + }, + coingecko: { + nativeAssetId: 'xdai', + platformId: 'xdai', + excludedTokenAddresses: [], + }, + tokenPrices: { + maxHourlyPriceHistoryNumDays: 100, + }, + rpcUrl: + (env.DEPLOYMENT_ENV as DeploymentEnv) === 'main' ? `https://rpc.gnosischain.com` : 'https://gnosis.drpc.org', + rpcMaxBlockRange: 2000, + protocolToken: 'bal', + bal: { + address: '0x7ef541e2a22058048904fe5744f9c7e4c57af717', + }, + veBal: { + address: '0xc128a9954e6c874ea3d62ce62b468ba073093f25', + delegationProxy: '0x7a2535f5fb47b8e44c02ef5d9990588313fe8f05', + }, + balancer: { + vault: '0xba12222222228d8ba445958a75a0704d566bf2c8', + composableStablePoolFactories: [ + '0x76578ecf9a141296ec657847fb45b0585bcda3a6', + '0xc128468b7ce63ea702c1f104d55a2566b13d3abd', + '0xd87f44df0159dc78029ab9ca7d7e57e7249f5acd', + '0x4bdcc2fb18aeb9e2d281b0278d946445070eada7', + ], + weightedPoolV2Factories: [ + '0x6cad2ea22bfa7f4c14aae92e47f510cd5c509bc7', + '0xf302f9f50958c5593770fdf4d4812309ff77414f', + '0xc128a9954e6c874ea3d62ce62b468ba073093f25', + ], + swapProtocolFeePercentage: 0.5, + yieldProtocolFeePercentage: 0.5, + }, + multicall: '0xbb6fab6b627947dae0a75808250d8b2652952cb5', + multicall3: '0xca11bde05977b3631167028862be2a173976ca11', + avgBlockSpeed: 1, + sor: { + main: { + url: '', + maxPools: 8, + forceRefresh: false, + gasPrice: BigNumber.from(10), + swapGas: BigNumber.from('1000000'), + }, + canary: { + url: '', + maxPools: 8, + forceRefresh: false, + gasPrice: BigNumber.from(10), + swapGas: BigNumber.from('1000000'), + }, + }, + ibAprConfig: { + defaultHandlers: { + wstETH: { + tokenAddress: '0x6c76971f98945ae98dd7d4dfca8711ebea946ea6', + sourceUrl: 'https://eth-api.lido.fi/v1/protocol/steth/apr/sma', + path: 'data.smaApr', + isIbYield: true, + }, + }, + }, + datastudio: { + main: { + user: 'datafeed-service@datastudio-366113.iam.gserviceaccount.com', + sheetId: '11anHUEb9snGwvB-errb5HvO8TvoLTRJhkDdD80Gxw1Q', + databaseTabName: 'Database v2', + compositionTabName: 'Pool Composition v2', + emissionDataTabName: 'EmissionData', + }, + canary: { + user: 'datafeed-service@datastudio-366113.iam.gserviceaccount.com', + sheetId: '1HnJOuRQXGy06tNgqjYMzQNIsaCSCC01Yxe_lZhXBDpY', + databaseTabName: 'Database v2', + compositionTabName: 'Pool Composition v2', + emissionDataTabName: 'EmissionData', + }, + }, + monitoring: { + main: { + alarmTopicArn: 'arn:aws:sns:ca-central-1:118697801881:api_alarms', + }, + canary: { + alarmTopicArn: 'arn:aws:sns:eu-central-1:118697801881:api_alarms', + }, + }, + beefy: { + linearPools: [''], + }, +}; diff --git a/modules/network/gnosis/index.ts b/modules/network/gnosis/index.ts new file mode 100644 index 000000000..085af9ec2 --- /dev/null +++ b/modules/network/gnosis/index.ts @@ -0,0 +1,9 @@ +import { JsonRpcProvider } from '@ethersproject/providers'; +import { gnosisNetworkData as data } from './data'; +import { gnosisWorkerJobs as workerJobs } from './workers'; + +export class GnosisNetworkConfig { + static data = data; + static workerJobs = workerJobs; + static provider = new JsonRpcProvider({ url: data.rpcUrl, timeout: 60000 }) +}; diff --git a/modules/network/gnosis/services.ts b/modules/network/gnosis/services.ts new file mode 100644 index 000000000..33b3e25f5 --- /dev/null +++ b/modules/network/gnosis/services.ts @@ -0,0 +1,43 @@ +import { tokenService } from '../../token/token.service'; +import { PhantomStableAprService } from '../../pool/lib/apr-data-sources/phantom-stable-apr.service'; +import { BoostedPoolAprService } from '../../pool/lib/apr-data-sources/boosted-pool-apr.service'; +import { SwapFeeAprService } from '../../pool/lib/apr-data-sources/swap-fee-apr.service'; +import { BptPriceHandlerService } from '../../token/lib/token-price-handlers/bpt-price-handler.service'; +import { LinearWrappedTokenPriceHandlerService } from '../../token/lib/token-price-handlers/linear-wrapped-token-price-handler.service'; +import { SwapsPriceHandlerService } from '../../token/lib/token-price-handlers/swaps-price-handler.service'; +import { CoingeckoPriceHandlerService } from '../../token/lib/token-price-handlers/coingecko-price-handler.service'; +import { coingeckoService } from '../../coingecko/coingecko.service'; +import { IbTokensAprService } from '../../pool/lib/apr-data-sources/ib-tokens-apr.service'; +import { GithubContentService } from '../../content/github-content.service'; +import { GaugeAprService } from '../../pool/lib/apr-data-sources/ve-bal-gauge-apr.service'; +import { GaugeStakingService } from '../../pool/lib/staking/gauge-staking.service'; +import { gaugeSubgraphService } from '../../subgraphs/gauge-subgraph/gauge-subgraph.service'; +import { UserSyncGaugeBalanceService } from '../../user/lib/user-sync-gauge-balance.service'; +import { gnosisNetworkData as data } from './data'; + +export const gnosisCreateServices = () => ({ + contentService: new GithubContentService(), + poolAprServices: [ + new IbTokensAprService( + data.ibAprConfig, + data.chain.prismaId, + data.balancer.yieldProtocolFeePercentage, + data.balancer.swapProtocolFeePercentage, + ), + new PhantomStableAprService( + data.chain.prismaId, + data.balancer.yieldProtocolFeePercentage, + ), + new BoostedPoolAprService(), + new SwapFeeAprService(data.balancer.swapProtocolFeePercentage), + new GaugeAprService(tokenService, [data.bal!.address]), + ], + poolStakingServices: [new GaugeStakingService(gaugeSubgraphService, data.bal!.address)], + tokenPriceHandlers: [ + new CoingeckoPriceHandlerService(coingeckoService), + new BptPriceHandlerService(), + new LinearWrappedTokenPriceHandlerService(), + new SwapsPriceHandlerService(), + ], + userStakedBalanceServices: [new UserSyncGaugeBalanceService()], +}); diff --git a/modules/network/gnosis/workers.ts b/modules/network/gnosis/workers.ts new file mode 100644 index 000000000..b068c5ee1 --- /dev/null +++ b/modules/network/gnosis/workers.ts @@ -0,0 +1,99 @@ +import { every } from '../../../worker/intervals'; +import { env } from '../../../app/env'; +import { DeploymentEnv, WorkerJob } from '../network-config-types'; + +/* +For sub-minute jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. +This is needed because the minimum alarm period is 1 minute and we want the alarm to trigger already after 1 minute instead of 3. + +For every 1 days jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. +This is needed because the maximum alarm evaluation period is 1 day (period * evaluationPeriod). +*/ +export const gnosisWorkerJobs: WorkerJob[] = [ + { + name: 'update-token-prices', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(2, 'minutes'), + }, + { + name: 'update-liquidity-for-inactive-pools', + interval: every(1, 'days'), + alarmEvaluationPeriod: 1, + alarmDatapointsToAlarm: 1, + }, + { + name: 'update-liquidity-for-active-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(8, 'minutes') : every(4, 'minutes'), + }, + { + name: 'update-pool-apr', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(7, 'minutes') : every(5, 'minutes'), + }, + { + name: 'load-on-chain-data-for-pools-with-active-updates', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(9, 'minutes') : every(5, 'minutes'), + }, + { + name: 'sync-new-pools-from-subgraph', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(12, 'minutes') : every(8, 'minutes'), + }, + { + name: 'sync-tokens-from-pool-tokens', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(7, 'minutes'), + }, + { + name: 'update-liquidity-24h-ago-for-all-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(8, 'minutes'), + }, + { + name: 'cache-average-block-time', + interval: every(1, 'hours'), + }, + { + name: 'sync-staking-for-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(10, 'minutes'), + }, + { + name: 'sync-latest-snapshots-for-all-pools', + interval: every(90, 'minutes'), + }, + { + name: 'update-lifetime-values-for-all-pools', + interval: every(45, 'minutes'), + }, + { + name: 'sync-changed-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(2, 'minutes') : every(1, 'minutes'), + alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + }, + { + name: 'user-sync-wallet-balances-for-all-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(29, 'minutes') : every(9, 'minutes'), + }, + { + name: 'user-sync-staked-balances', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(31, 'minutes') : every(11, 'minutes'), + }, + { + name: 'sync-coingecko-coinids', + interval: every(2, 'hours'), + }, + { + name: 'purge-old-tokenprices', + interval: every(1, 'days'), + alarmEvaluationPeriod: 1, + alarmDatapointsToAlarm: 1, + }, + { + name: 'update-fee-volume-yield-all-pools', + interval: every(75, 'minutes'), + }, + { + name: 'sync-vebal-balances', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(14, 'minutes'), + }, + { + name: 'sync-vebal-totalSupply', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(16, 'minutes'), + }, +]; diff --git a/modules/network/mainnet.ts b/modules/network/mainnet/data.ts similarity index 65% rename from modules/network/mainnet.ts rename to modules/network/mainnet/data.ts index e693631bb..e04be2f5f 100644 --- a/modules/network/mainnet.ts +++ b/modules/network/mainnet/data.ts @@ -1,22 +1,6 @@ -import { BigNumber, ethers } from 'ethers'; -import { DeploymentEnv, NetworkConfig, NetworkData } from './network-config-types'; -import { tokenService } from '../token/token.service'; -import { PhantomStableAprService } from '../pool/lib/apr-data-sources/phantom-stable-apr.service'; -import { BoostedPoolAprService } from '../pool/lib/apr-data-sources/boosted-pool-apr.service'; -import { SwapFeeAprService } from '../pool/lib/apr-data-sources/swap-fee-apr.service'; -import { GaugeAprService } from '../pool/lib/apr-data-sources/ve-bal-gauge-apr.service'; -import { GaugeStakingService } from '../pool/lib/staking/gauge-staking.service'; -import { BptPriceHandlerService } from '../token/lib/token-price-handlers/bpt-price-handler.service'; -import { LinearWrappedTokenPriceHandlerService } from '../token/lib/token-price-handlers/linear-wrapped-token-price-handler.service'; -import { SwapsPriceHandlerService } from '../token/lib/token-price-handlers/swaps-price-handler.service'; -import { UserSyncGaugeBalanceService } from '../user/lib/user-sync-gauge-balance.service'; -import { every } from '../../worker/intervals'; -import { GithubContentService } from '../content/github-content.service'; -import { gaugeSubgraphService } from '../subgraphs/gauge-subgraph/gauge-subgraph.service'; -import { coingeckoService } from '../coingecko/coingecko.service'; -import { CoingeckoPriceHandlerService } from '../token/lib/token-price-handlers/coingecko-price-handler.service'; -import { IbTokensAprService } from '../pool/lib/apr-data-sources/ib-tokens-apr.service'; -import { env } from '../../app/env'; +import { BigNumber } from '@ethersproject/bignumber'; +import { DeploymentEnv, NetworkData } from "../network-config-types"; +import { env } from '../../../app/env'; const underlyingTokens = { USDC: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', @@ -365,136 +349,3 @@ export const mainnetNetworkData: NetworkData = { }, }, }; - -export const mainnetNetworkConfig: NetworkConfig = { - data: mainnetNetworkData, - contentService: new GithubContentService(), - provider: new ethers.providers.JsonRpcProvider({ url: mainnetNetworkData.rpcUrl, timeout: 60000 }), - poolAprServices: [ - 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]), - ], - poolStakingServices: [new GaugeStakingService(gaugeSubgraphService, mainnetNetworkData.bal!.address)], - tokenPriceHandlers: [ - new CoingeckoPriceHandlerService(coingeckoService), - new BptPriceHandlerService(), - new LinearWrappedTokenPriceHandlerService(), - new SwapsPriceHandlerService(), - ], - userStakedBalanceServices: [new UserSyncGaugeBalanceService()], - /* - For sub-minute jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. - This is needed because the minimum alarm period is 1 minute and we want the alarm to trigger already after 1 minute instead of 3. - - For every 1 days jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. - This is needed because the maximum alarm evaluation period is 1 day (period * evaluationPeriod). - */ - workerJobs: [ - { - name: 'update-token-prices', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(2, 'minutes'), - }, - { - name: 'update-liquidity-for-inactive-pools', - interval: every(1, 'days'), - alarmEvaluationPeriod: 1, - alarmDatapointsToAlarm: 1, - }, - { - name: 'update-liquidity-for-active-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(8, 'minutes') : every(4, 'minutes'), - }, - { - name: 'update-pool-apr', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(7, 'minutes') : every(5, 'minutes'), - }, - { - name: 'load-on-chain-data-for-pools-with-active-updates', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(9, 'minutes') : every(5, 'minutes'), - }, - { - name: 'sync-new-pools-from-subgraph', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(12, 'minutes') : every(8, 'minutes'), - }, - { - name: 'sync-tokens-from-pool-tokens', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(7, 'minutes'), - }, - { - name: 'update-liquidity-24h-ago-for-all-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(8, 'minutes'), - }, - { - name: 'cache-average-block-time', - interval: every(1, 'hours'), - }, - { - name: 'sync-staking-for-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(10, 'minutes'), - }, - { - name: 'sync-latest-snapshots-for-all-pools', - interval: every(90, 'minutes'), - }, - { - name: 'update-lifetime-values-for-all-pools', - interval: every(45, 'minutes'), - }, - { - name: 'sync-changed-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(2, 'minutes') : every(1, 'minutes'), - alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - }, - { - name: 'user-sync-wallet-balances-for-all-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(29, 'minutes') : every(9, 'minutes'), - }, - { - name: 'user-sync-staked-balances', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(31, 'minutes') : every(11, 'minutes'), - }, - { - name: 'sync-coingecko-coinids', - interval: every(2, 'hours'), - }, - { - name: 'purge-old-tokenprices', - interval: every(1, 'days'), - alarmEvaluationPeriod: 1, - alarmDatapointsToAlarm: 1, - }, - { - name: 'update-fee-volume-yield-all-pools', - interval: every(75, 'minutes'), - }, - { - name: 'sync-vebal-balances', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(14, 'minutes'), - }, - { - name: 'sync-vebal-totalSupply', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(16, 'minutes'), - }, - { - name: 'sync-vebal-voting-gauges', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(5, 'minutes'), - }, - // The following are multichain jobs and should only run once for all chains. - { - name: 'sync-global-coingecko-prices', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(2, 'minutes'), - }, - ], -}; diff --git a/modules/network/mainnet/index.ts b/modules/network/mainnet/index.ts new file mode 100644 index 000000000..749ea6caf --- /dev/null +++ b/modules/network/mainnet/index.ts @@ -0,0 +1,9 @@ +import { JsonRpcProvider } from '@ethersproject/providers'; +import { mainnetNetworkData as data } from './data'; +import { mainnetWorkerJobs as workerJobs } from './workers'; + +export class MainnetNetworkConfig { + static data = data; + static workerJobs = workerJobs; + static provider = new JsonRpcProvider({ url: data.rpcUrl, timeout: 60000 }) +}; diff --git a/modules/network/mainnet/services.ts b/modules/network/mainnet/services.ts new file mode 100644 index 000000000..4b0aaa0e1 --- /dev/null +++ b/modules/network/mainnet/services.ts @@ -0,0 +1,43 @@ +import { tokenService } from '../../token/token.service'; +import { PhantomStableAprService } from '../../pool/lib/apr-data-sources/phantom-stable-apr.service'; +import { BoostedPoolAprService } from '../../pool/lib/apr-data-sources/boosted-pool-apr.service'; +import { SwapFeeAprService } from '../../pool/lib/apr-data-sources/swap-fee-apr.service'; +import { BptPriceHandlerService } from '../../token/lib/token-price-handlers/bpt-price-handler.service'; +import { LinearWrappedTokenPriceHandlerService } from '../../token/lib/token-price-handlers/linear-wrapped-token-price-handler.service'; +import { SwapsPriceHandlerService } from '../../token/lib/token-price-handlers/swaps-price-handler.service'; +import { CoingeckoPriceHandlerService } from '../../token/lib/token-price-handlers/coingecko-price-handler.service'; +import { coingeckoService } from '../../coingecko/coingecko.service'; +import { IbTokensAprService } from '../../pool/lib/apr-data-sources/ib-tokens-apr.service'; +import { GithubContentService } from '../../content/github-content.service'; +import { GaugeAprService } from '../../pool/lib/apr-data-sources/ve-bal-gauge-apr.service'; +import { GaugeStakingService } from '../../pool/lib/staking/gauge-staking.service'; +import { gaugeSubgraphService } from '../../subgraphs/gauge-subgraph/gauge-subgraph.service'; +import { UserSyncGaugeBalanceService } from '../../user/lib/user-sync-gauge-balance.service'; +import { mainnetNetworkData as data } from './data'; + +export const mainnetCreateServices = () => ({ + contentService: new GithubContentService(), + poolAprServices: [ + new IbTokensAprService( + data.ibAprConfig, + data.chain.prismaId, + data.balancer.yieldProtocolFeePercentage, + data.balancer.swapProtocolFeePercentage, + ), + new PhantomStableAprService( + data.chain.prismaId, + data.balancer.yieldProtocolFeePercentage, + ), + new BoostedPoolAprService(), + new SwapFeeAprService(data.balancer.swapProtocolFeePercentage), + new GaugeAprService(tokenService, [data.bal!.address]), + ], + poolStakingServices: [new GaugeStakingService(gaugeSubgraphService, data.bal!.address)], + tokenPriceHandlers: [ + new CoingeckoPriceHandlerService(coingeckoService), + new BptPriceHandlerService(), + new LinearWrappedTokenPriceHandlerService(), + new SwapsPriceHandlerService(), + ], + userStakedBalanceServices: [new UserSyncGaugeBalanceService()], +}); diff --git a/modules/network/mainnet/workers.ts b/modules/network/mainnet/workers.ts new file mode 100644 index 000000000..af506c722 --- /dev/null +++ b/modules/network/mainnet/workers.ts @@ -0,0 +1,108 @@ +import { every } from '../../../worker/intervals'; +import { env } from '../../../app/env'; +import { DeploymentEnv, WorkerJob } from '../network-config-types'; + +/* +For sub-minute jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. +This is needed because the minimum alarm period is 1 minute and we want the alarm to trigger already after 1 minute instead of 3. + +For every 1 days jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. +This is needed because the maximum alarm evaluation period is 1 day (period * evaluationPeriod). +*/ +export const mainnetWorkerJobs: WorkerJob[] = [ + { + name: 'update-token-prices', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(2, 'minutes'), + }, + { + name: 'update-liquidity-for-inactive-pools', + interval: every(1, 'days'), + alarmEvaluationPeriod: 1, + alarmDatapointsToAlarm: 1, + }, + { + name: 'update-liquidity-for-active-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(8, 'minutes') : every(4, 'minutes'), + }, + { + name: 'update-pool-apr', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(7, 'minutes') : every(5, 'minutes'), + }, + { + name: 'load-on-chain-data-for-pools-with-active-updates', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(9, 'minutes') : every(5, 'minutes'), + }, + { + name: 'sync-new-pools-from-subgraph', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(12, 'minutes') : every(8, 'minutes'), + }, + { + name: 'sync-tokens-from-pool-tokens', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(7, 'minutes'), + }, + { + name: 'update-liquidity-24h-ago-for-all-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(8, 'minutes'), + }, + { + name: 'cache-average-block-time', + interval: every(1, 'hours'), + }, + { + name: 'sync-staking-for-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(10, 'minutes'), + }, + { + name: 'sync-latest-snapshots-for-all-pools', + interval: every(90, 'minutes'), + }, + { + name: 'update-lifetime-values-for-all-pools', + interval: every(45, 'minutes'), + }, + { + name: 'sync-changed-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(2, 'minutes') : every(1, 'minutes'), + alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + }, + { + name: 'user-sync-wallet-balances-for-all-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(29, 'minutes') : every(9, 'minutes'), + }, + { + name: 'user-sync-staked-balances', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(31, 'minutes') : every(11, 'minutes'), + }, + { + name: 'sync-coingecko-coinids', + interval: every(2, 'hours'), + }, + { + name: 'purge-old-tokenprices', + interval: every(1, 'days'), + alarmEvaluationPeriod: 1, + alarmDatapointsToAlarm: 1, + }, + { + name: 'update-fee-volume-yield-all-pools', + interval: every(75, 'minutes'), + }, + { + name: 'sync-vebal-balances', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(14, 'minutes'), + }, + { + name: 'sync-vebal-totalSupply', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(16, 'minutes'), + }, + { + name: 'sync-vebal-voting-gauges', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(5, 'minutes'), + }, + // The following are multichain jobs and should only run once for all chains. + { + name: 'sync-global-coingecko-prices', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(2, 'minutes'), + }, +]; diff --git a/modules/network/network-config-types.ts b/modules/network/network-config-types.ts index a34c742e2..d96770139 100644 --- a/modules/network/network-config-types.ts +++ b/modules/network/network-config-types.ts @@ -10,14 +10,18 @@ import { AaveAprConfig, IbAprConfig } from './apr-config-types'; export interface NetworkConfig { data: NetworkData; + provider: BaseProvider; + workerJobs: WorkerJob[]; +} + +export interface NetworkServices { contentService: ContentService; poolStakingServices: PoolStakingService[]; poolAprServices: PoolAprService[]; userStakedBalanceServices: UserStakedBalanceService[]; tokenPriceHandlers: TokenPriceHandler[]; - provider: BaseProvider; - workerJobs: WorkerJob[]; } + export interface WorkerJob { name: string; interval: number; diff --git a/modules/network/network-config.ts b/modules/network/network-config.ts index 7cc0786da..06851ae11 100644 --- a/modules/network/network-config.ts +++ b/modules/network/network-config.ts @@ -1,39 +1,41 @@ -import { fantomNetworkConfig } from './fantom'; -import { optimismNetworkConfig } from './optimism'; -import { NetworkConfig } from './network-config-types'; -import { mainnetNetworkConfig } from './mainnet'; -import { arbitrumNetworkConfig } from './arbitrum'; -import { polygonNetworkConfig } from './polygon'; -import { gnosisNetworkConfig } from './gnosis'; -import { zkevmNetworkConfig } from './zkevm'; -import { avalancheNetworkConfig } from './avalanche'; -import { baseNetworkConfig } from './base'; +import { FantomNetworkConfig } from './fantom'; +import { OptimismNetworkConfig } from './optimism'; +import type { NetworkConfig } from './network-config-types'; +import { MainnetNetworkConfig } from './mainnet'; +import { ArbitrumNetworkConfig } from './arbitrum'; +import { PolygonNetworkConfig } from './polygon'; +import { GnosisNetworkConfig } from './gnosis'; +import { ZkevmNetworkConfig } from './zkevm'; +import { AvalancheNetworkConfig } from './avalanche'; +import { BaseNetworkConfig } from './base'; import { Chain } from '@prisma/client'; -import { keyBy, pickBy } from 'lodash'; export const AllNetworkConfigs: { [chainId: string]: NetworkConfig } = { - '250': fantomNetworkConfig, - '10': optimismNetworkConfig, - '1': mainnetNetworkConfig, - '42161': arbitrumNetworkConfig, - '137': polygonNetworkConfig, - '100': gnosisNetworkConfig, - '1101': zkevmNetworkConfig, - '43114': avalancheNetworkConfig, - '8453': baseNetworkConfig, + '250': FantomNetworkConfig, + '10': OptimismNetworkConfig, + '1': MainnetNetworkConfig, + '42161': ArbitrumNetworkConfig, + '137': PolygonNetworkConfig, + '100': GnosisNetworkConfig, + '1101': ZkevmNetworkConfig, + '43114': AvalancheNetworkConfig, + '8453': BaseNetworkConfig, }; export const AllNetworkConfigsKeyedOnChain: { [chain in Chain]: NetworkConfig } = { - FANTOM: fantomNetworkConfig, - OPTIMISM: optimismNetworkConfig, - MAINNET: mainnetNetworkConfig, - ARBITRUM: arbitrumNetworkConfig, - POLYGON: polygonNetworkConfig, - GNOSIS: gnosisNetworkConfig, - ZKEVM: zkevmNetworkConfig, - AVALANCHE: avalancheNetworkConfig, - BASE: baseNetworkConfig, + FANTOM: FantomNetworkConfig, + OPTIMISM: OptimismNetworkConfig, + MAINNET: MainnetNetworkConfig, + ARBITRUM: ArbitrumNetworkConfig, + POLYGON: PolygonNetworkConfig, + GNOSIS: GnosisNetworkConfig, + ZKEVM: ZkevmNetworkConfig, + AVALANCHE: AvalancheNetworkConfig, + BASE: BaseNetworkConfig, }; -export const BalancerChainIds = ['1', '137', '42161', '100', '1101', '43114', '8453']; -export const BeethovenChainIds = ['250', '10']; +export const BalancerChainIds = ['1', '137', '42161', '100', '1101', '43114', '8453'] as const; +export const BeethovenChainIds = ['250', '10'] as const; +const allChains = [...BalancerChainIds, ...BeethovenChainIds] as const; + +export type ChainIDs = typeof allChains[number]; diff --git a/modules/network/network-context.service.ts b/modules/network/network-context.service.ts index 3522175c8..33ec6ac03 100644 --- a/modules/network/network-context.service.ts +++ b/modules/network/network-context.service.ts @@ -1,33 +1,44 @@ -import { AllNetworkConfigs, BalancerChainIds, BeethovenChainIds } from './network-config'; +import { AllNetworkConfigs, BalancerChainIds, BeethovenChainIds, ChainIDs } from './network-config'; import { env } from '../../app/env'; import { Chain } from '@prisma/client'; -import { NetworkConfig, NetworkData } from './network-config-types'; +import type { NetworkConfig, NetworkData, NetworkServices } from './network-config-types'; import { BaseProvider } from '@ethersproject/providers'; import { getRequestScopeContextValue } from '../context/request-scoped-context'; +import { networkServiceFactories } from './network-service-factories'; -export class NetworkContextService { - constructor(private readonly defaultChainId: string) {} +const services: Map = new Map(); - public isValidChainId(chainId: string) { - return !!AllNetworkConfigs[chainId]; +class NetworkContextService { + constructor( + private readonly defaultChainId: ChainIDs = env.DEFAULT_CHAIN_ID as ChainIDs, + private configs = AllNetworkConfigs + ) {} + + public isValidChainId(chainId: ChainIDs) { + return !!this.configs[chainId]; } - public get config(): NetworkConfig { - const chainId = getRequestScopeContextValue('chainId'); + get chainId(): ChainIDs { + const chainId = getRequestScopeContextValue('chainId'); - if (chainId) { - return AllNetworkConfigs[chainId]; - } + return chainId ?? this.defaultChainId; + } - return AllNetworkConfigs[this.defaultChainId]; + public get config(): NetworkConfig { + return this.configs[this.chainId]; } public get data(): NetworkData { return this.config.data; } - public get chainId(): string { - return `${this.data.chain.id}`; + public get services(): NetworkServices { + if (!services.get(this.chainId)) { + // TODO: We might need to start passing all the configuration data down to the service factories + services.set(this.chainId, networkServiceFactories[this.chainId]()); + } + + return services.get(this.chainId)!; } public get chain(): Chain { @@ -47,16 +58,16 @@ export class NetworkContextService { } public get isBalancerChain(): boolean { - return BalancerChainIds.includes(this.chainId); + return BalancerChainIds.includes(this.chainId as any); } public get isBeethovenChain(): boolean { - return BeethovenChainIds.includes(this.chainId); + return BeethovenChainIds.includes(this.chainId as any); } - public get protocolSupportedChainIds(): string[] { + public get protocolSupportedChainIds(): typeof BalancerChainIds | typeof BeethovenChainIds { return this.isBalancerChain ? BalancerChainIds : BeethovenChainIds; } } -export const networkContext = new NetworkContextService(env.DEFAULT_CHAIN_ID); +export const networkContext = new NetworkContextService(env.DEFAULT_CHAIN_ID as ChainIDs, AllNetworkConfigs); diff --git a/modules/network/network-service-factories.ts b/modules/network/network-service-factories.ts new file mode 100644 index 000000000..eb1136d34 --- /dev/null +++ b/modules/network/network-service-factories.ts @@ -0,0 +1,21 @@ +import { fantomCreateServices } from './fantom/services'; +import { optimismCreateServices } from './optimism/services'; +import { mainnetCreateServices } from './mainnet/services'; +import { arbitrumCreateServices } from './arbitrum/services'; +import { polygonCreateServices } from './polygon/services'; +import { gnosisCreateServices } from './gnosis/services'; +import { zkevmCreateServices } from './zkevm/services'; +import { avalancheCreateServices } from './avalanche/services'; +import { baseCreateServices } from './base/services'; + +export const networkServiceFactories = { + '250': fantomCreateServices, + '10': optimismCreateServices, + '1': mainnetCreateServices, + '42161': arbitrumCreateServices, + '137': polygonCreateServices, + '100': gnosisCreateServices, + '1101': zkevmCreateServices, + '43114': avalancheCreateServices, + '8453': baseCreateServices, +}; diff --git a/modules/network/optimism.ts b/modules/network/optimism/data.ts similarity index 53% rename from modules/network/optimism.ts rename to modules/network/optimism/data.ts index bed1cce39..ccf3151c1 100644 --- a/modules/network/optimism.ts +++ b/modules/network/optimism/data.ts @@ -1,25 +1,8 @@ -import { BigNumber, ethers } from 'ethers'; -import { DeploymentEnv, NetworkConfig, NetworkData } from './network-config-types'; -import { tokenService } from '../token/token.service'; -import { PhantomStableAprService } from '../pool/lib/apr-data-sources/phantom-stable-apr.service'; -import { BoostedPoolAprService } from '../pool/lib/apr-data-sources/boosted-pool-apr.service'; -import { SwapFeeAprService } from '../pool/lib/apr-data-sources/swap-fee-apr.service'; -import { GaugeAprService } from '../pool/lib/apr-data-sources/ve-bal-gauge-apr.service'; -import { GaugeStakingService } from '../pool/lib/staking/gauge-staking.service'; -import { BeetsPriceHandlerService } from '../token/lib/token-price-handlers/beets-price-handler.service'; -import { BptPriceHandlerService } from '../token/lib/token-price-handlers/bpt-price-handler.service'; -import { LinearWrappedTokenPriceHandlerService } from '../token/lib/token-price-handlers/linear-wrapped-token-price-handler.service'; -import { SwapsPriceHandlerService } from '../token/lib/token-price-handlers/swaps-price-handler.service'; -import { UserSyncGaugeBalanceService } from '../user/lib/user-sync-gauge-balance.service'; -import { every } from '../../worker/intervals'; -import { SanityContentService } from '../content/sanity-content.service'; -import { gaugeSubgraphService } from '../subgraphs/gauge-subgraph/gauge-subgraph.service'; -import { coingeckoService } from '../coingecko/coingecko.service'; -import { CoingeckoPriceHandlerService } from '../token/lib/token-price-handlers/coingecko-price-handler.service'; -import { IbTokensAprService } from '../pool/lib/apr-data-sources/ib-tokens-apr.service'; -import { env } from '../../app/env'; +import { BigNumber } from '@ethersproject/bignumber'; +import { NetworkData } from "../network-config-types"; +import { env } from '../../../app/env'; -const optimismNetworkData: NetworkData = { +export const optimismNetworkData: NetworkData = { chain: { slug: 'optimism', id: 10, @@ -262,143 +245,3 @@ const optimismNetworkData: NetworkData = { }, }, }; - -export const optimismNetworkConfig: NetworkConfig = { - data: optimismNetworkData, - contentService: new SanityContentService(), - provider: new ethers.providers.JsonRpcProvider({ url: optimismNetworkData.rpcUrl, timeout: 60000 }), - poolAprServices: [ - 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, [optimismNetworkData.beets!.address, optimismNetworkData.bal!.address]), - ], - poolStakingServices: [new GaugeStakingService(gaugeSubgraphService, optimismNetworkData.bal!.address)], - tokenPriceHandlers: [ - new BeetsPriceHandlerService( - optimismNetworkData.beets!.address, - optimismNetworkData.beets!.beetsPriceProviderRpcUrl, - ), - new CoingeckoPriceHandlerService(coingeckoService), - new BptPriceHandlerService(), - new LinearWrappedTokenPriceHandlerService(), - new SwapsPriceHandlerService(), - ], - userStakedBalanceServices: [new UserSyncGaugeBalanceService()], - /* - For sub-minute jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. - This is needed because the minimum alarm period is 1 minute and we want the alarm to trigger already after 1 minute instead of 3. - - For every 1 days jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. - This is needed because the maximum alarm evaluation period is 1 day (period * evaluationPeriod). - */ - workerJobs: [ - { - name: 'update-token-prices', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(2, 'minutes'), - }, - { - name: 'update-liquidity-for-inactive-pools', - interval: every(1, 'days'), - alarmEvaluationPeriod: 1, - alarmDatapointsToAlarm: 1, - }, - { - name: 'update-liquidity-for-active-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(6, 'minutes') : every(2, 'minutes'), - }, - { - name: 'update-pool-apr', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(6, 'minutes') : every(2, 'minutes'), - }, - { - name: 'load-on-chain-data-for-pools-with-active-updates', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(4, 'minutes') : every(1, 'minutes'), - }, - { - name: 'sync-new-pools-from-subgraph', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(6, 'minutes') : every(2, 'minutes'), - }, - { - name: 'sync-sanity-pool-data', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(9, 'minutes') : every(3, 'minutes'), - }, - { - name: 'sync-tokens-from-pool-tokens', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(5, 'minutes'), - }, - { - name: 'update-liquidity-24h-ago-for-all-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(5, 'minutes'), - }, - { - name: 'cache-average-block-time', - interval: every(1, 'hours'), - }, - { - name: 'sync-staking-for-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(5, 'minutes'), - }, - { - name: 'sync-latest-snapshots-for-all-pools', - interval: every(90, 'minutes'), - }, - { - name: 'update-lifetime-values-for-all-pools', - interval: every(50, 'minutes'), - }, - { - name: 'sync-changed-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(2, 'minutes') : every(30, 'seconds'), - alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - }, - { - name: 'user-sync-wallet-balances-for-all-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(5, 'minutes') : every(20, 'seconds'), - alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - }, - { - name: 'user-sync-staked-balances', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(5, 'minutes') : every(20, 'seconds'), - alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - }, - { - name: 'sync-coingecko-coinids', - interval: every(2, 'hours'), - }, - { - name: 'purge-old-tokenprices', - interval: every(1, 'days'), - alarmEvaluationPeriod: 1, - alarmDatapointsToAlarm: 1, - }, - { - name: 'update-fee-volume-yield-all-pools', - interval: every(1, 'hours'), - }, - { - name: 'sync-vebal-balances', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(9, 'minutes') : every(3, 'minutes'), - }, - { - name: 'sync-vebal-totalSupply', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(5, 'minutes'), - }, - { - name: 'feed-data-to-datastudio', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(5, 'minutes') : every(1, 'minutes'), - }, - ], -}; diff --git a/modules/network/optimism/index.ts b/modules/network/optimism/index.ts new file mode 100644 index 000000000..de22f595b --- /dev/null +++ b/modules/network/optimism/index.ts @@ -0,0 +1,9 @@ +import { JsonRpcProvider } from '@ethersproject/providers'; +import { optimismNetworkData as data } from './data'; +import { optimismWorkerJobs as workerJobs } from './workers'; + +export class OptimismNetworkConfig { + static data = data; + static workerJobs = workerJobs; + static provider = new JsonRpcProvider({ url: data.rpcUrl, timeout: 60000 }) +}; diff --git a/modules/network/optimism/services.ts b/modules/network/optimism/services.ts new file mode 100644 index 000000000..f6c08924a --- /dev/null +++ b/modules/network/optimism/services.ts @@ -0,0 +1,45 @@ +import { tokenService } from '../../token/token.service'; +import { PhantomStableAprService } from '../../pool/lib/apr-data-sources/phantom-stable-apr.service'; +import { BoostedPoolAprService } from '../../pool/lib/apr-data-sources/boosted-pool-apr.service'; +import { SwapFeeAprService } from '../../pool/lib/apr-data-sources/swap-fee-apr.service'; +import { BptPriceHandlerService } from '../../token/lib/token-price-handlers/bpt-price-handler.service'; +import { LinearWrappedTokenPriceHandlerService } from '../../token/lib/token-price-handlers/linear-wrapped-token-price-handler.service'; +import { SwapsPriceHandlerService } from '../../token/lib/token-price-handlers/swaps-price-handler.service'; +import { CoingeckoPriceHandlerService } from '../../token/lib/token-price-handlers/coingecko-price-handler.service'; +import { coingeckoService } from '../../coingecko/coingecko.service'; +import { IbTokensAprService } from '../../pool/lib/apr-data-sources/ib-tokens-apr.service'; +import { GaugeAprService } from '../../pool/lib/apr-data-sources/ve-bal-gauge-apr.service'; +import { GaugeStakingService } from '../../pool/lib/staking/gauge-staking.service'; +import { gaugeSubgraphService } from '../../subgraphs/gauge-subgraph/gauge-subgraph.service'; +import { UserSyncGaugeBalanceService } from '../../user/lib/user-sync-gauge-balance.service'; +import { BeetsPriceHandlerService } from '../../token/lib/token-price-handlers/beets-price-handler.service'; +import { SanityContentService } from '../../content/sanity-content.service'; +import { optimismNetworkData as data } from './data'; + +export const optimismCreateServices = () => ({ + contentService: new SanityContentService(), + poolAprServices: [ + new IbTokensAprService( + data.ibAprConfig, + data.chain.prismaId, + data.balancer.yieldProtocolFeePercentage, + data.balancer.swapProtocolFeePercentage, + ), + new PhantomStableAprService( + data.chain.prismaId, + data.balancer.yieldProtocolFeePercentage, + ), + new BoostedPoolAprService(), + new SwapFeeAprService(data.balancer.swapProtocolFeePercentage), + new GaugeAprService(tokenService, [data.beets!.address, data.bal!.address]), + ], + poolStakingServices: [new GaugeStakingService(gaugeSubgraphService, data.bal!.address)], + tokenPriceHandlers: [ + new BeetsPriceHandlerService(data.beets!.address, data.beets!.beetsPriceProviderRpcUrl), + new CoingeckoPriceHandlerService(coingeckoService), + new BptPriceHandlerService(), + new LinearWrappedTokenPriceHandlerService(), + new SwapsPriceHandlerService(), + ], + userStakedBalanceServices: [new UserSyncGaugeBalanceService()], +}); diff --git a/modules/network/optimism/workers.ts b/modules/network/optimism/workers.ts new file mode 100644 index 000000000..8da06b8f1 --- /dev/null +++ b/modules/network/optimism/workers.ts @@ -0,0 +1,111 @@ +import { every } from '../../../worker/intervals'; +import { env } from '../../../app/env'; +import { DeploymentEnv, WorkerJob } from '../network-config-types'; + +/* +For sub-minute jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. +This is needed because the minimum alarm period is 1 minute and we want the alarm to trigger already after 1 minute instead of 3. + +For every 1 days jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. +This is needed because the maximum alarm evaluation period is 1 day (period * evaluationPeriod). +*/ +export const optimismWorkerJobs: WorkerJob[] = [ + { + name: 'update-token-prices', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(2, 'minutes'), + }, + { + name: 'update-liquidity-for-inactive-pools', + interval: every(1, 'days'), + alarmEvaluationPeriod: 1, + alarmDatapointsToAlarm: 1, + }, + { + name: 'update-liquidity-for-active-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(6, 'minutes') : every(2, 'minutes'), + }, + { + name: 'update-pool-apr', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(6, 'minutes') : every(2, 'minutes'), + }, + { + name: 'load-on-chain-data-for-pools-with-active-updates', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(4, 'minutes') : every(1, 'minutes'), + }, + { + name: 'sync-new-pools-from-subgraph', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(6, 'minutes') : every(2, 'minutes'), + }, + { + name: 'sync-sanity-pool-data', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(9, 'minutes') : every(3, 'minutes'), + }, + { + name: 'sync-tokens-from-pool-tokens', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(5, 'minutes'), + }, + { + name: 'update-liquidity-24h-ago-for-all-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(5, 'minutes'), + }, + { + name: 'cache-average-block-time', + interval: every(1, 'hours'), + }, + { + name: 'sync-staking-for-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(5, 'minutes'), + }, + { + name: 'sync-latest-snapshots-for-all-pools', + interval: every(90, 'minutes'), + }, + { + name: 'update-lifetime-values-for-all-pools', + interval: every(50, 'minutes'), + }, + { + name: 'sync-changed-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(2, 'minutes') : every(30, 'seconds'), + alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + }, + { + name: 'user-sync-wallet-balances-for-all-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(5, 'minutes') : every(20, 'seconds'), + alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + }, + { + name: 'user-sync-staked-balances', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(5, 'minutes') : every(20, 'seconds'), + alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + }, + { + name: 'sync-coingecko-coinids', + interval: every(2, 'hours'), + }, + { + name: 'purge-old-tokenprices', + interval: every(1, 'days'), + alarmEvaluationPeriod: 1, + alarmDatapointsToAlarm: 1, + }, + { + name: 'update-fee-volume-yield-all-pools', + interval: every(1, 'hours'), + }, + { + name: 'sync-vebal-balances', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(9, 'minutes') : every(3, 'minutes'), + }, + { + name: 'sync-vebal-totalSupply', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(5, 'minutes'), + }, + { + name: 'feed-data-to-datastudio', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(5, 'minutes') : every(1, 'minutes'), + }, +]; diff --git a/modules/network/polygon.ts b/modules/network/polygon/data.ts similarity index 59% rename from modules/network/polygon.ts rename to modules/network/polygon/data.ts index cf3c9227f..258bf9033 100644 --- a/modules/network/polygon.ts +++ b/modules/network/polygon/data.ts @@ -1,24 +1,8 @@ -import { BigNumber, ethers } from 'ethers'; -import { DeploymentEnv, NetworkConfig, NetworkData } from './network-config-types'; -import { tokenService } from '../token/token.service'; -import { PhantomStableAprService } from '../pool/lib/apr-data-sources/phantom-stable-apr.service'; -import { BoostedPoolAprService } from '../pool/lib/apr-data-sources/boosted-pool-apr.service'; -import { SwapFeeAprService } from '../pool/lib/apr-data-sources/swap-fee-apr.service'; -import { GaugeAprService } from '../pool/lib/apr-data-sources/ve-bal-gauge-apr.service'; -import { GaugeStakingService } from '../pool/lib/staking/gauge-staking.service'; -import { BptPriceHandlerService } from '../token/lib/token-price-handlers/bpt-price-handler.service'; -import { LinearWrappedTokenPriceHandlerService } from '../token/lib/token-price-handlers/linear-wrapped-token-price-handler.service'; -import { SwapsPriceHandlerService } from '../token/lib/token-price-handlers/swaps-price-handler.service'; -import { UserSyncGaugeBalanceService } from '../user/lib/user-sync-gauge-balance.service'; -import { every } from '../../worker/intervals'; -import { GithubContentService } from '../content/github-content.service'; -import { gaugeSubgraphService } from '../subgraphs/gauge-subgraph/gauge-subgraph.service'; -import { coingeckoService } from '../coingecko/coingecko.service'; -import { CoingeckoPriceHandlerService } from '../token/lib/token-price-handlers/coingecko-price-handler.service'; -import { IbTokensAprService } from '../pool/lib/apr-data-sources/ib-tokens-apr.service'; -import { env } from '../../app/env'; +import { BigNumber } from '@ethersproject/bignumber'; +import { NetworkData } from "../network-config-types"; +import { env } from '../../../app/env'; -const polygonNetworkData: NetworkData = { +export const polygonNetworkData: NetworkData = { chain: { slug: 'polygon', id: 137, @@ -256,127 +240,3 @@ const polygonNetworkData: NetworkData = { }, }, }; - -export const polygonNetworkConfig: NetworkConfig = { - data: polygonNetworkData, - contentService: new GithubContentService(), - provider: new ethers.providers.JsonRpcProvider({ url: polygonNetworkData.rpcUrl, timeout: 60000 }), - poolAprServices: [ - 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]), - ], - poolStakingServices: [new GaugeStakingService(gaugeSubgraphService, polygonNetworkData.bal!.address)], - tokenPriceHandlers: [ - new CoingeckoPriceHandlerService(coingeckoService), - new BptPriceHandlerService(), - new LinearWrappedTokenPriceHandlerService(), - new SwapsPriceHandlerService(), - ], - userStakedBalanceServices: [new UserSyncGaugeBalanceService()], - /* - For sub-minute jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. - This is needed because the minimum alarm period is 1 minute and we want the alarm to trigger already after 1 minute instead of 3. - - For every 1 days jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. - This is needed because the maximum alarm evaluation period is 1 day (period * evaluationPeriod). - */ - workerJobs: [ - { - name: 'update-token-prices', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(2, 'minutes'), - }, - { - name: 'update-liquidity-for-inactive-pools', - interval: every(1, 'days'), - alarmEvaluationPeriod: 1, - alarmDatapointsToAlarm: 1, - }, - { - name: 'update-liquidity-for-active-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(8, 'minutes') : every(4, 'minutes'), - }, - { - name: 'update-pool-apr', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(7, 'minutes') : every(5, 'minutes'), - }, - { - name: 'load-on-chain-data-for-pools-with-active-updates', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(9, 'minutes') : every(5, 'minutes'), - }, - { - name: 'sync-new-pools-from-subgraph', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(12, 'minutes') : every(8, 'minutes'), - }, - { - name: 'sync-tokens-from-pool-tokens', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(7, 'minutes'), - }, - { - name: 'update-liquidity-24h-ago-for-all-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(8, 'minutes'), - }, - { - name: 'cache-average-block-time', - interval: every(1, 'hours'), - }, - { - name: 'sync-staking-for-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(10, 'minutes'), - }, - { - name: 'sync-latest-snapshots-for-all-pools', - interval: every(90, 'minutes'), - }, - { - name: 'update-lifetime-values-for-all-pools', - interval: every(45, 'minutes'), - }, - { - name: 'sync-changed-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(2, 'minutes') : every(1, 'minutes'), - alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - }, - { - name: 'user-sync-wallet-balances-for-all-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(29, 'minutes') : every(9, 'minutes'), - }, - { - name: 'user-sync-staked-balances', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(31, 'minutes') : every(11, 'minutes'), - }, - { - name: 'sync-coingecko-coinids', - interval: every(2, 'hours'), - }, - { - name: 'purge-old-tokenprices', - interval: every(1, 'days'), - alarmEvaluationPeriod: 1, - alarmDatapointsToAlarm: 1, - }, - { - name: 'update-fee-volume-yield-all-pools', - interval: every(75, 'minutes'), - }, - { - name: 'sync-vebal-balances', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(14, 'minutes'), - }, - { - name: 'sync-vebal-totalSupply', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(16, 'minutes'), - }, - ], -}; diff --git a/modules/network/polygon/index.ts b/modules/network/polygon/index.ts new file mode 100644 index 000000000..b4eea7318 --- /dev/null +++ b/modules/network/polygon/index.ts @@ -0,0 +1,9 @@ +import { JsonRpcProvider } from '@ethersproject/providers'; +import { polygonNetworkData as data } from './data'; +import { polygonWorkerJobs as workerJobs } from './workers'; + +export class PolygonNetworkConfig { + static data = data; + static workerJobs = workerJobs; + static provider = new JsonRpcProvider({ url: data.rpcUrl, timeout: 60000 }) +}; diff --git a/modules/network/polygon/services.ts b/modules/network/polygon/services.ts new file mode 100644 index 000000000..dedc95700 --- /dev/null +++ b/modules/network/polygon/services.ts @@ -0,0 +1,43 @@ +import { tokenService } from '../../token/token.service'; +import { PhantomStableAprService } from '../../pool/lib/apr-data-sources/phantom-stable-apr.service'; +import { BoostedPoolAprService } from '../../pool/lib/apr-data-sources/boosted-pool-apr.service'; +import { SwapFeeAprService } from '../../pool/lib/apr-data-sources/swap-fee-apr.service'; +import { BptPriceHandlerService } from '../../token/lib/token-price-handlers/bpt-price-handler.service'; +import { LinearWrappedTokenPriceHandlerService } from '../../token/lib/token-price-handlers/linear-wrapped-token-price-handler.service'; +import { SwapsPriceHandlerService } from '../../token/lib/token-price-handlers/swaps-price-handler.service'; +import { CoingeckoPriceHandlerService } from '../../token/lib/token-price-handlers/coingecko-price-handler.service'; +import { coingeckoService } from '../../coingecko/coingecko.service'; +import { IbTokensAprService } from '../../pool/lib/apr-data-sources/ib-tokens-apr.service'; +import { GithubContentService } from '../../content/github-content.service'; +import { GaugeAprService } from '../../pool/lib/apr-data-sources/ve-bal-gauge-apr.service'; +import { GaugeStakingService } from '../../pool/lib/staking/gauge-staking.service'; +import { gaugeSubgraphService } from '../../subgraphs/gauge-subgraph/gauge-subgraph.service'; +import { UserSyncGaugeBalanceService } from '../../user/lib/user-sync-gauge-balance.service'; +import { polygonNetworkData as data } from './data'; + +export const polygonCreateServices = () => ({ + contentService: new GithubContentService(), + poolAprServices: [ + new IbTokensAprService( + data.ibAprConfig, + data.chain.prismaId, + data.balancer.yieldProtocolFeePercentage, + data.balancer.swapProtocolFeePercentage, + ), + new PhantomStableAprService( + data.chain.prismaId, + data.balancer.yieldProtocolFeePercentage, + ), + new BoostedPoolAprService(), + new SwapFeeAprService(data.balancer.swapProtocolFeePercentage), + new GaugeAprService(tokenService, [data.bal!.address]), + ], + poolStakingServices: [new GaugeStakingService(gaugeSubgraphService, data.bal!.address)], + tokenPriceHandlers: [ + new CoingeckoPriceHandlerService(coingeckoService), + new BptPriceHandlerService(), + new LinearWrappedTokenPriceHandlerService(), + new SwapsPriceHandlerService(), + ], + userStakedBalanceServices: [new UserSyncGaugeBalanceService()], +}); diff --git a/modules/network/polygon/workers.ts b/modules/network/polygon/workers.ts new file mode 100644 index 000000000..a00b4d658 --- /dev/null +++ b/modules/network/polygon/workers.ts @@ -0,0 +1,99 @@ +import { every } from '../../../worker/intervals'; +import { env } from '../../../app/env'; +import { DeploymentEnv, WorkerJob } from '../network-config-types'; + +/* +For sub-minute jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. +This is needed because the minimum alarm period is 1 minute and we want the alarm to trigger already after 1 minute instead of 3. + +For every 1 days jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. +This is needed because the maximum alarm evaluation period is 1 day (period * evaluationPeriod). +*/ +export const polygonWorkerJobs: WorkerJob[] = [ + { + name: 'update-token-prices', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(2, 'minutes'), + }, + { + name: 'update-liquidity-for-inactive-pools', + interval: every(1, 'days'), + alarmEvaluationPeriod: 1, + alarmDatapointsToAlarm: 1, + }, + { + name: 'update-liquidity-for-active-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(8, 'minutes') : every(4, 'minutes'), + }, + { + name: 'update-pool-apr', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(7, 'minutes') : every(5, 'minutes'), + }, + { + name: 'load-on-chain-data-for-pools-with-active-updates', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(9, 'minutes') : every(5, 'minutes'), + }, + { + name: 'sync-new-pools-from-subgraph', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(12, 'minutes') : every(8, 'minutes'), + }, + { + name: 'sync-tokens-from-pool-tokens', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(7, 'minutes'), + }, + { + name: 'update-liquidity-24h-ago-for-all-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(8, 'minutes'), + }, + { + name: 'cache-average-block-time', + interval: every(1, 'hours'), + }, + { + name: 'sync-staking-for-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(10, 'minutes'), + }, + { + name: 'sync-latest-snapshots-for-all-pools', + interval: every(90, 'minutes'), + }, + { + name: 'update-lifetime-values-for-all-pools', + interval: every(45, 'minutes'), + }, + { + name: 'sync-changed-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(2, 'minutes') : every(1, 'minutes'), + alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + }, + { + name: 'user-sync-wallet-balances-for-all-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(29, 'minutes') : every(9, 'minutes'), + }, + { + name: 'user-sync-staked-balances', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(31, 'minutes') : every(11, 'minutes'), + }, + { + name: 'sync-coingecko-coinids', + interval: every(2, 'hours'), + }, + { + name: 'purge-old-tokenprices', + interval: every(1, 'days'), + alarmEvaluationPeriod: 1, + alarmDatapointsToAlarm: 1, + }, + { + name: 'update-fee-volume-yield-all-pools', + interval: every(75, 'minutes'), + }, + { + name: 'sync-vebal-balances', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(14, 'minutes'), + }, + { + name: 'sync-vebal-totalSupply', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(16, 'minutes'), + }, +]; diff --git a/modules/network/zkevm.ts b/modules/network/zkevm.ts deleted file mode 100644 index cc45ad53e..000000000 --- a/modules/network/zkevm.ts +++ /dev/null @@ -1,282 +0,0 @@ -import { BigNumber, ethers } from 'ethers'; -import { DeploymentEnv, NetworkConfig, NetworkData } from './network-config-types'; -import { tokenService } from '../token/token.service'; -import { PhantomStableAprService } from '../pool/lib/apr-data-sources/phantom-stable-apr.service'; -import { BoostedPoolAprService } from '../pool/lib/apr-data-sources/boosted-pool-apr.service'; -import { SwapFeeAprService } from '../pool/lib/apr-data-sources/swap-fee-apr.service'; -import { GaugeAprService } from '../pool/lib/apr-data-sources/ve-bal-gauge-apr.service'; -import { GaugeStakingService } from '../pool/lib/staking/gauge-staking.service'; -import { BptPriceHandlerService } from '../token/lib/token-price-handlers/bpt-price-handler.service'; -import { LinearWrappedTokenPriceHandlerService } from '../token/lib/token-price-handlers/linear-wrapped-token-price-handler.service'; -import { SwapsPriceHandlerService } from '../token/lib/token-price-handlers/swaps-price-handler.service'; -import { UserSyncGaugeBalanceService } from '../user/lib/user-sync-gauge-balance.service'; -import { every } from '../../worker/intervals'; -import { GithubContentService } from '../content/github-content.service'; -import { gaugeSubgraphService } from '../subgraphs/gauge-subgraph/gauge-subgraph.service'; -import { CoingeckoPriceHandlerService } from '../token/lib/token-price-handlers/coingecko-price-handler.service'; -import { coingeckoService } from '../coingecko/coingecko.service'; -import { env } from '../../app/env'; -import { IbTokensAprService } from '../pool/lib/apr-data-sources/ib-tokens-apr.service'; - -const zkevmNetworkData: NetworkData = { - chain: { - slug: 'zkevm', - id: 1101, - nativeAssetAddress: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', - wrappedNativeAssetAddress: '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', - prismaId: 'ZKEVM', - gqlId: 'ZKEVM', - }, - subgraphs: { - startDate: '2023-05-17', - balancer: 'https://api.studio.thegraph.com/query/24660/balancer-polygon-zk-v2/version/latest', - beetsBar: 'https://', - blocks: 'https://api.studio.thegraph.com/query/48427/bleu-polygon-zkevm-blocks/version/latest', - gauge: 'https://api.studio.thegraph.com/query/24660/balancer-gauges-polygon-zk/version/latest', - veBalLocks: 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gauges', - userBalances: 'https://', - }, - eth: { - address: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', - addressFormatted: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', - symbol: 'ETH', - name: 'Ether', - }, - weth: { - address: '0x4f9a0e7fd2bf6067db6994cf12e4495df938e6e9', - addressFormatted: '0x4F9A0e7FD2Bf6067db6994CF12E4495Df938E6e9', - }, - coingecko: { - nativeAssetId: 'ethereum', - platformId: 'polygon-zkevm', - excludedTokenAddresses: [], - }, - tokenPrices: { - maxHourlyPriceHistoryNumDays: 100, - }, - rpcUrl: - env.ALCHEMY_API_KEY && (env.DEPLOYMENT_ENV as DeploymentEnv) === 'main' - ? `https://polygonzkevm-mainnet.g.alchemy.com/v2/${env.ALCHEMY_API_KEY}` - : 'https://zkevm-rpc.com', - rpcMaxBlockRange: 2000, - protocolToken: 'bal', - bal: { - address: '0x120ef59b80774f02211563834d8e3b72cb1649d6', - }, - veBal: { - address: '0xc128a9954e6c874ea3d62ce62b468ba073093f25', - delegationProxy: '0xc7e5ed1054a24ef31d827e6f86caa58b3bc168d7', - }, - balancer: { - vault: '0xba12222222228d8ba445958a75a0704d566bf2c8', - composableStablePoolFactories: [ - '0x8ea89804145c007e7d226001a96955ad53836087', - '0x956ccab09898c0af2aca5e6c229c3ad4e93d9288', - ], - weightedPoolV2Factories: ['0x03f3fb107e74f2eac9358862e91ad3c692712054'], - swapProtocolFeePercentage: 0.5, - yieldProtocolFeePercentage: 0.5, - }, - multicall: '0xca11bde05977b3631167028862be2a173976ca11', - multicall3: '0xca11bde05977b3631167028862be2a173976ca11', - masterchef: { - address: '0x0000000000000000000000000000000000000000', - excludedFarmIds: [], - }, - avgBlockSpeed: 1, - sor: { - main: { - url: 'https://uu6cfghhd5lqa7py3nojxkivd40zuugb.lambda-url.ca-central-1.on.aws/', - maxPools: 8, - forceRefresh: false, - gasPrice: BigNumber.from(10), - swapGas: BigNumber.from('1000000'), - }, - canary: { - url: 'https://ksa66wlkjbvteijxmflqjehsay0jmekw.lambda-url.eu-central-1.on.aws/', - maxPools: 8, - forceRefresh: false, - gasPrice: BigNumber.from(10), - swapGas: BigNumber.from('1000000'), - }, - }, - ibAprConfig: { - ovix: { - tokens: { - USDT: { - yieldAddress: '0xad41c77d99e282267c1492cdefe528d7d5044253', - wrappedAddress: '0x550d3bb1f77f97e4debb45d4f817d7b9f9a1affb', - }, - USDC: { - yieldAddress: '0x68d9baa40394da2e2c1ca05d30bf33f52823ee7b', - wrappedAddress: '0x3a6789fc7c05a83cfdff5d2f9428ad9868b4ff85', - }, - }, - }, - defaultHandlers: { - wstETH: { - tokenAddress: '0x5d8cff95d7a57c0bf50b30b43c7cc0d52825d4a9', - sourceUrl: 'https://eth-api.lido.fi/v1/protocol/steth/apr/sma', - path: 'data.smaApr', - isIbYield: true, - }, - rETH: { - tokenAddress: '0xb23c20efce6e24acca0cef9b7b7aa196b84ec942', - sourceUrl: 'https://rocketpool.net/api/mainnet/payload', - path: 'rethAPR', - isIbYield: true, - }, - }, - }, - beefy: { - linearPools: [''], - }, - datastudio: { - main: { - user: 'datafeed-service@datastudio-366113.iam.gserviceaccount.com', - sheetId: '11anHUEb9snGwvB-errb5HvO8TvoLTRJhkDdD80Gxw1Q', - databaseTabName: 'Database v2', - compositionTabName: 'Pool Composition v2', - emissionDataTabName: 'EmissionData', - }, - canary: { - user: 'datafeed-service@datastudio-366113.iam.gserviceaccount.com', - sheetId: '1HnJOuRQXGy06tNgqjYMzQNIsaCSCC01Yxe_lZhXBDpY', - databaseTabName: 'Database v2', - compositionTabName: 'Pool Composition v2', - emissionDataTabName: 'EmissionData', - }, - }, - monitoring: { - main: { - alarmTopicArn: 'arn:aws:sns:ca-central-1:118697801881:api_alarms', - }, - canary: { - alarmTopicArn: 'arn:aws:sns:eu-central-1:118697801881:api_alarms', - }, - }, -}; - -export const zkevmNetworkConfig: NetworkConfig = { - data: zkevmNetworkData, - contentService: new GithubContentService(), - provider: new ethers.providers.JsonRpcProvider({ url: zkevmNetworkData.rpcUrl, timeout: 60000 }), - poolAprServices: [ - 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]), - ], - poolStakingServices: [new GaugeStakingService(gaugeSubgraphService, zkevmNetworkData.bal!.address)], - tokenPriceHandlers: [ - new CoingeckoPriceHandlerService(coingeckoService), - new BptPriceHandlerService(), - new LinearWrappedTokenPriceHandlerService(), - new SwapsPriceHandlerService(), - ], - userStakedBalanceServices: [new UserSyncGaugeBalanceService()], - /* - For sub-minute jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. - This is needed because the minimum alarm period is 1 minute and we want the alarm to trigger already after 1 minute instead of 3. - - For every 1 days jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. - This is needed because the maximum alarm evaluation period is 1 day (period * evaluationPeriod). - */ - workerJobs: [ - { - name: 'update-token-prices', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(2, 'minutes'), - }, - { - name: 'update-liquidity-for-inactive-pools', - interval: every(1, 'days'), - alarmEvaluationPeriod: 1, - alarmDatapointsToAlarm: 1, - }, - { - name: 'update-liquidity-for-active-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(8, 'minutes') : every(4, 'minutes'), - }, - { - name: 'update-pool-apr', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(7, 'minutes') : every(5, 'minutes'), - }, - { - name: 'load-on-chain-data-for-pools-with-active-updates', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(9, 'minutes') : every(5, 'minutes'), - }, - { - name: 'sync-new-pools-from-subgraph', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(12, 'minutes') : every(8, 'minutes'), - }, - { - name: 'sync-tokens-from-pool-tokens', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(7, 'minutes'), - }, - { - name: 'update-liquidity-24h-ago-for-all-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(8, 'minutes'), - }, - { - name: 'cache-average-block-time', - interval: every(1, 'hours'), - }, - { - name: 'sync-staking-for-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(10, 'minutes'), - }, - { - name: 'sync-latest-snapshots-for-all-pools', - interval: every(90, 'minutes'), - }, - { - name: 'update-lifetime-values-for-all-pools', - interval: every(45, 'minutes'), - }, - { - name: 'sync-changed-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(2, 'minutes') : every(1, 'minutes'), - alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, - }, - { - name: 'user-sync-wallet-balances-for-all-pools', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(29, 'minutes') : every(9, 'minutes'), - }, - { - name: 'user-sync-staked-balances', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(31, 'minutes') : every(11, 'minutes'), - }, - { - name: 'sync-coingecko-coinids', - interval: every(2, 'hours'), - }, - { - name: 'purge-old-tokenprices', - interval: every(1, 'days'), - alarmEvaluationPeriod: 1, - alarmDatapointsToAlarm: 1, - }, - { - name: 'update-fee-volume-yield-all-pools', - interval: every(75, 'minutes'), - }, - { - name: 'sync-vebal-balances', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(14, 'minutes'), - }, - { - name: 'sync-vebal-totalSupply', - interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(16, 'minutes'), - }, - ], -}; diff --git a/modules/network/zkevm/data.ts b/modules/network/zkevm/data.ts new file mode 100644 index 000000000..3d5627997 --- /dev/null +++ b/modules/network/zkevm/data.ts @@ -0,0 +1,142 @@ +import { BigNumber } from '@ethersproject/bignumber'; +import { DeploymentEnv, NetworkData } from "../network-config-types"; +import { env } from '../../../app/env'; + +export const zkevmNetworkData: NetworkData = { + chain: { + slug: 'zkevm', + id: 1101, + nativeAssetAddress: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + wrappedNativeAssetAddress: '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', + prismaId: 'ZKEVM', + gqlId: 'ZKEVM', + }, + subgraphs: { + startDate: '2023-05-17', + balancer: 'https://api.studio.thegraph.com/query/24660/balancer-polygon-zk-v2/version/latest', + beetsBar: 'https://', + blocks: 'https://api.studio.thegraph.com/query/48427/bleu-polygon-zkevm-blocks/version/latest', + gauge: 'https://api.studio.thegraph.com/query/24660/balancer-gauges-polygon-zk/version/latest', + veBalLocks: 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gauges', + userBalances: 'https://', + }, + eth: { + address: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', + addressFormatted: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + symbol: 'ETH', + name: 'Ether', + }, + weth: { + address: '0x4f9a0e7fd2bf6067db6994cf12e4495df938e6e9', + addressFormatted: '0x4F9A0e7FD2Bf6067db6994CF12E4495Df938E6e9', + }, + coingecko: { + nativeAssetId: 'ethereum', + platformId: 'polygon-zkevm', + excludedTokenAddresses: [], + }, + tokenPrices: { + maxHourlyPriceHistoryNumDays: 100, + }, + rpcUrl: + env.ALCHEMY_API_KEY && (env.DEPLOYMENT_ENV as DeploymentEnv) === 'main' + ? `https://polygonzkevm-mainnet.g.alchemy.com/v2/${env.ALCHEMY_API_KEY}` + : 'https://zkevm-rpc.com', + rpcMaxBlockRange: 2000, + protocolToken: 'bal', + bal: { + address: '0x120ef59b80774f02211563834d8e3b72cb1649d6', + }, + veBal: { + address: '0xc128a9954e6c874ea3d62ce62b468ba073093f25', + delegationProxy: '0xc7e5ed1054a24ef31d827e6f86caa58b3bc168d7', + }, + balancer: { + vault: '0xba12222222228d8ba445958a75a0704d566bf2c8', + composableStablePoolFactories: [ + '0x8ea89804145c007e7d226001a96955ad53836087', + '0x956ccab09898c0af2aca5e6c229c3ad4e93d9288', + ], + weightedPoolV2Factories: ['0x03f3fb107e74f2eac9358862e91ad3c692712054'], + swapProtocolFeePercentage: 0.5, + yieldProtocolFeePercentage: 0.5, + }, + multicall: '0xca11bde05977b3631167028862be2a173976ca11', + multicall3: '0xca11bde05977b3631167028862be2a173976ca11', + masterchef: { + address: '0x0000000000000000000000000000000000000000', + excludedFarmIds: [], + }, + avgBlockSpeed: 1, + sor: { + main: { + url: 'https://uu6cfghhd5lqa7py3nojxkivd40zuugb.lambda-url.ca-central-1.on.aws/', + maxPools: 8, + forceRefresh: false, + gasPrice: BigNumber.from(10), + swapGas: BigNumber.from('1000000'), + }, + canary: { + url: 'https://ksa66wlkjbvteijxmflqjehsay0jmekw.lambda-url.eu-central-1.on.aws/', + maxPools: 8, + forceRefresh: false, + gasPrice: BigNumber.from(10), + swapGas: BigNumber.from('1000000'), + }, + }, + ibAprConfig: { + ovix: { + tokens: { + USDT: { + yieldAddress: '0xad41c77d99e282267c1492cdefe528d7d5044253', + wrappedAddress: '0x550d3bb1f77f97e4debb45d4f817d7b9f9a1affb', + }, + USDC: { + yieldAddress: '0x68d9baa40394da2e2c1ca05d30bf33f52823ee7b', + wrappedAddress: '0x3a6789fc7c05a83cfdff5d2f9428ad9868b4ff85', + }, + }, + }, + defaultHandlers: { + wstETH: { + tokenAddress: '0x5d8cff95d7a57c0bf50b30b43c7cc0d52825d4a9', + sourceUrl: 'https://eth-api.lido.fi/v1/protocol/steth/apr/sma', + path: 'data.smaApr', + isIbYield: true, + }, + rETH: { + tokenAddress: '0xb23c20efce6e24acca0cef9b7b7aa196b84ec942', + sourceUrl: 'https://rocketpool.net/api/mainnet/payload', + path: 'rethAPR', + isIbYield: true, + }, + }, + }, + beefy: { + linearPools: [''], + }, + datastudio: { + main: { + user: 'datafeed-service@datastudio-366113.iam.gserviceaccount.com', + sheetId: '11anHUEb9snGwvB-errb5HvO8TvoLTRJhkDdD80Gxw1Q', + databaseTabName: 'Database v2', + compositionTabName: 'Pool Composition v2', + emissionDataTabName: 'EmissionData', + }, + canary: { + user: 'datafeed-service@datastudio-366113.iam.gserviceaccount.com', + sheetId: '1HnJOuRQXGy06tNgqjYMzQNIsaCSCC01Yxe_lZhXBDpY', + databaseTabName: 'Database v2', + compositionTabName: 'Pool Composition v2', + emissionDataTabName: 'EmissionData', + }, + }, + monitoring: { + main: { + alarmTopicArn: 'arn:aws:sns:ca-central-1:118697801881:api_alarms', + }, + canary: { + alarmTopicArn: 'arn:aws:sns:eu-central-1:118697801881:api_alarms', + }, + }, +}; diff --git a/modules/network/zkevm/index.ts b/modules/network/zkevm/index.ts new file mode 100644 index 000000000..0dcb3196f --- /dev/null +++ b/modules/network/zkevm/index.ts @@ -0,0 +1,9 @@ +import { JsonRpcProvider } from '@ethersproject/providers'; +import { zkevmNetworkData as data } from './data'; +import { zkevmWorkerJobs as workerJobs } from './workers'; + +export class ZkevmNetworkConfig { + static data = data; + static workerJobs = workerJobs; + static provider = new JsonRpcProvider({ url: data.rpcUrl, timeout: 60000 }) +}; diff --git a/modules/network/zkevm/services.ts b/modules/network/zkevm/services.ts new file mode 100644 index 000000000..3998520ea --- /dev/null +++ b/modules/network/zkevm/services.ts @@ -0,0 +1,43 @@ +import { tokenService } from '../../token/token.service'; +import { PhantomStableAprService } from '../../pool/lib/apr-data-sources/phantom-stable-apr.service'; +import { BoostedPoolAprService } from '../../pool/lib/apr-data-sources/boosted-pool-apr.service'; +import { SwapFeeAprService } from '../../pool/lib/apr-data-sources/swap-fee-apr.service'; +import { BptPriceHandlerService } from '../../token/lib/token-price-handlers/bpt-price-handler.service'; +import { LinearWrappedTokenPriceHandlerService } from '../../token/lib/token-price-handlers/linear-wrapped-token-price-handler.service'; +import { SwapsPriceHandlerService } from '../../token/lib/token-price-handlers/swaps-price-handler.service'; +import { CoingeckoPriceHandlerService } from '../../token/lib/token-price-handlers/coingecko-price-handler.service'; +import { coingeckoService } from '../../coingecko/coingecko.service'; +import { IbTokensAprService } from '../../pool/lib/apr-data-sources/ib-tokens-apr.service'; +import { GithubContentService } from '../../content/github-content.service'; +import { GaugeAprService } from '../../pool/lib/apr-data-sources/ve-bal-gauge-apr.service'; +import { GaugeStakingService } from '../../pool/lib/staking/gauge-staking.service'; +import { gaugeSubgraphService } from '../../subgraphs/gauge-subgraph/gauge-subgraph.service'; +import { UserSyncGaugeBalanceService } from '../../user/lib/user-sync-gauge-balance.service'; +import { zkevmNetworkData as data } from './data'; + +export const zkevmCreateServices = () => ({ + contentService: new GithubContentService(), + poolAprServices: [ + new IbTokensAprService( + data.ibAprConfig, + data.chain.prismaId, + data.balancer.yieldProtocolFeePercentage, + data.balancer.swapProtocolFeePercentage, + ), + new PhantomStableAprService( + data.chain.prismaId, + data.balancer.yieldProtocolFeePercentage, + ), + new BoostedPoolAprService(), + new SwapFeeAprService(data.balancer.swapProtocolFeePercentage), + new GaugeAprService(tokenService, [data.bal!.address]), + ], + poolStakingServices: [new GaugeStakingService(gaugeSubgraphService, data.bal!.address)], + tokenPriceHandlers: [ + new CoingeckoPriceHandlerService(coingeckoService), + new BptPriceHandlerService(), + new LinearWrappedTokenPriceHandlerService(), + new SwapsPriceHandlerService(), + ], + userStakedBalanceServices: [new UserSyncGaugeBalanceService()], +}); diff --git a/modules/network/zkevm/workers.ts b/modules/network/zkevm/workers.ts new file mode 100644 index 000000000..118877b41 --- /dev/null +++ b/modules/network/zkevm/workers.ts @@ -0,0 +1,99 @@ +import { every } from '../../../worker/intervals'; +import { env } from '../../../app/env'; +import { DeploymentEnv, WorkerJob } from '../network-config-types'; + +/* +For sub-minute jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. +This is needed because the minimum alarm period is 1 minute and we want the alarm to trigger already after 1 minute instead of 3. + +For every 1 days jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. +This is needed because the maximum alarm evaluation period is 1 day (period * evaluationPeriod). +*/ +export const zkevmWorkerJobs: WorkerJob[] = [ + { + name: 'update-token-prices', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(2, 'minutes'), + }, + { + name: 'update-liquidity-for-inactive-pools', + interval: every(1, 'days'), + alarmEvaluationPeriod: 1, + alarmDatapointsToAlarm: 1, + }, + { + name: 'update-liquidity-for-active-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(8, 'minutes') : every(4, 'minutes'), + }, + { + name: 'update-pool-apr', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(7, 'minutes') : every(5, 'minutes'), + }, + { + name: 'load-on-chain-data-for-pools-with-active-updates', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(9, 'minutes') : every(5, 'minutes'), + }, + { + name: 'sync-new-pools-from-subgraph', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(12, 'minutes') : every(8, 'minutes'), + }, + { + name: 'sync-tokens-from-pool-tokens', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(7, 'minutes'), + }, + { + name: 'update-liquidity-24h-ago-for-all-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(8, 'minutes'), + }, + { + name: 'cache-average-block-time', + interval: every(1, 'hours'), + }, + { + name: 'sync-staking-for-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(15, 'minutes') : every(10, 'minutes'), + }, + { + name: 'sync-latest-snapshots-for-all-pools', + interval: every(90, 'minutes'), + }, + { + name: 'update-lifetime-values-for-all-pools', + interval: every(45, 'minutes'), + }, + { + name: 'sync-changed-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(2, 'minutes') : every(1, 'minutes'), + alarmEvaluationPeriod: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + alarmDatapointsToAlarm: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? 3 : 1, + }, + { + name: 'user-sync-wallet-balances-for-all-pools', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(29, 'minutes') : every(9, 'minutes'), + }, + { + name: 'user-sync-staked-balances', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(31, 'minutes') : every(11, 'minutes'), + }, + { + name: 'sync-coingecko-coinids', + interval: every(2, 'hours'), + }, + { + name: 'purge-old-tokenprices', + interval: every(1, 'days'), + alarmEvaluationPeriod: 1, + alarmDatapointsToAlarm: 1, + }, + { + name: 'update-fee-volume-yield-all-pools', + interval: every(75, 'minutes'), + }, + { + name: 'sync-vebal-balances', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(14, 'minutes'), + }, + { + name: 'sync-vebal-totalSupply', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(20, 'minutes') : every(16, 'minutes'), + }, +]; diff --git a/modules/pool/lib/pool-apr-updater.service.ts b/modules/pool/lib/pool-apr-updater.service.ts index 4f7fd330b..c03eff110 100644 --- a/modules/pool/lib/pool-apr-updater.service.ts +++ b/modules/pool/lib/pool-apr-updater.service.ts @@ -10,7 +10,7 @@ export class PoolAprUpdaterService { constructor() {} private get aprServices(): PoolAprService[] { - return networkContext.config.poolAprServices; + return networkContext.services.poolAprServices; } public async updatePoolAprs() { diff --git a/modules/pool/lib/pool-gql-loader.service.ts b/modules/pool/lib/pool-gql-loader.service.ts index b381545ee..199d59786 100644 --- a/modules/pool/lib/pool-gql-loader.service.ts +++ b/modules/pool/lib/pool-gql-loader.service.ts @@ -92,7 +92,7 @@ export class PoolGqlLoaderService { } public async getFeaturedPoolGroups(): Promise { - const featuredPoolGroups = await networkContext.config.contentService.getFeaturedPoolGroups(); + const featuredPoolGroups = await networkContext.services.contentService.getFeaturedPoolGroups(); const poolIds = featuredPoolGroups .map((group) => group.items diff --git a/modules/pool/pool.service.ts b/modules/pool/pool.service.ts index 852a03bc0..c9ab6826d 100644 --- a/modules/pool/pool.service.ts +++ b/modules/pool/pool.service.ts @@ -54,11 +54,11 @@ export class PoolService { ) {} private get poolStakingServices(): PoolStakingService[] { - return networkContext.config.poolStakingServices; + return networkContext.services.poolStakingServices; } private get contentService(): ContentService { - return networkContext.config.contentService; + return networkContext.services.contentService; } public async getGqlPool(id: string): Promise { diff --git a/modules/token/lib/token-price.service.ts b/modules/token/lib/token-price.service.ts index 1d5b77fa9..567938629 100644 --- a/modules/token/lib/token-price.service.ts +++ b/modules/token/lib/token-price.service.ts @@ -20,7 +20,7 @@ export class TokenPriceService { constructor() {} private get handlers(): TokenPriceHandler[] { - return networkContext.config.tokenPriceHandlers; + return networkContext.services.tokenPriceHandlers; } public async getWhiteListedCurrentTokenPrices(chains: Chain[]): Promise { diff --git a/modules/token/token.service.ts b/modules/token/token.service.ts index 4e1eb374c..9ae674495 100644 --- a/modules/token/token.service.ts +++ b/modules/token/token.service.ts @@ -24,7 +24,7 @@ export class TokenService { } public async syncTokenContentData() { - await networkContext.config.contentService.syncTokenContentData(); + await networkContext.services.contentService.syncTokenContentData(); } public async getToken(address: string): Promise { @@ -239,7 +239,7 @@ export class TokenService { await prisma.prismaTokenType.deleteMany({ where: { chain: networkContext.chain }, }); - await networkContext.config.contentService.syncTokenContentData(); + await networkContext.services.contentService.syncTokenContentData(); } } diff --git a/modules/user/user.service.ts b/modules/user/user.service.ts index fd603906c..178b7e5a7 100644 --- a/modules/user/user.service.ts +++ b/modules/user/user.service.ts @@ -24,7 +24,7 @@ export class UserService { ) {} private get stakedSyncServices(): UserStakedBalanceService[] { - return networkContext.config.userStakedBalanceServices; + return networkContext.services.userStakedBalanceServices; } public async getUserPoolBalances(address: string, chains: Chain[]): Promise { diff --git a/modules/vebal/debug-voting-list.spec.ts b/modules/vebal/debug-voting-list.spec.ts index 4a9f0331a..51f0dd013 100644 --- a/modules/vebal/debug-voting-list.spec.ts +++ b/modules/vebal/debug-voting-list.spec.ts @@ -3,14 +3,15 @@ import { setMainnetRpcProviderForTesting } from '../../test/utils'; import { VotingGaugesRepository } from './voting-gauges.repository'; import { VeBalVotingListService } from './vebal-voting-list.service'; import { initRequestScopedContext, setRequestScopedContextValue } from '../context/request-scoped-context'; -import { AllNetworkConfigs } from '../network/network-config'; -import { mainnetNetworkConfig } from '../network/mainnet'; const defaultAnvilRpcUrl = 'http://127.0.0.1:8555'; setMainnetRpcProviderForTesting(defaultAnvilRpcUrl); // TODO: understand why mainnetConfig is undefined in test context -AllNetworkConfigs['1'] = mainnetNetworkConfig; +// AllNetworkConfigs are undefined when creating networkContext instance +// not sure exactly where, but moving services away from the config object fixes the issue +// +// AllNetworkConfigs['1'] = MainnetNetworkConfig; beforeEach(() => { initRequestScopedContext(); diff --git a/modules/vebal/voting-gauges.repository.ts b/modules/vebal/voting-gauges.repository.ts index 4485a35bf..369161b0f 100644 --- a/modules/vebal/voting-gauges.repository.ts +++ b/modules/vebal/voting-gauges.repository.ts @@ -4,7 +4,7 @@ import { keyBy, mapValues } from 'lodash'; import { formatFixed } from '@ethersproject/bignumber'; import { BigNumber, Contract } from 'ethers'; import { formatEther } from 'ethers/lib/utils'; -import { mainnetNetworkConfig } from '../network/mainnet'; +import { MainnetNetworkConfig } from '../network/mainnet'; import gaugeControllerAbi from './abi/gaugeController.json'; import gaugeControllerHelperAbi from './abi/gaugeControllerHelper.json'; import rootGaugeAbi from './abi/rootGauge.json'; @@ -15,9 +15,9 @@ import { v1RootGaugeRecipients } from './special-pools/streamer-v1-gauges'; import { Multicaller3 } from '../web3/multicaller3'; import { networkContext } from '../network/network-context.service'; -const gaugeControllerAddress = mainnetNetworkConfig.data.gaugeControllerAddress!; +const gaugeControllerAddress = MainnetNetworkConfig.data.gaugeControllerAddress!; // Helper contract that wraps gaugeControllerAddress contract to allow checkpointing and getting the updated relative weight -const gaugeControllerHelperAddress = mainnetNetworkConfig.data.gaugeControllerHelperAddress!; +const gaugeControllerHelperAddress = MainnetNetworkConfig.data.gaugeControllerHelperAddress!; export type VotingGauge = { gaugeAddress: string; @@ -236,7 +236,7 @@ export class VotingGaugesRepository { } getGaugeControllerContract() { - return new Contract(gaugeControllerAddress, gaugeControllerAbi, mainnetNetworkConfig.provider); + return new Contract(gaugeControllerAddress, gaugeControllerAbi, MainnetNetworkConfig.provider); } async fetchGaugeAddresses(totalGauges: number) { diff --git a/test/utils.ts b/test/utils.ts index cb46bb5d1..e825905c5 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -1,5 +1,5 @@ import { providers } from 'ethers'; -import { mainnetNetworkConfig } from '../modules/network/mainnet'; +import { MainnetNetworkConfig } from '../modules/network/mainnet'; // anvil --fork-url https://eth-mainnet.alchemyapi.io/v2/7gYoDJEw6-QyVP5hd2UfZyelzDIDemGz --port 8555 --fork-block-number=17878719 @@ -9,7 +9,7 @@ const defaultAnvilRpcUrl = 'http://127.0.0.1:8555'; export function setMainnetRpcProviderForTesting(httpRpc = defaultAnvilRpcUrl) { console.log(`🤖 Integration tests using ${httpRpc} as rpc url`); - mainnetNetworkConfig.provider = getRpcProvider(httpRpc); + MainnetNetworkConfig.provider = getRpcProvider(httpRpc); } export function getRpcProvider(httpRpc = defaultAnvilRpcUrl) {