diff --git a/.env.dev b/.env.dev index 229058e8..4080899a 100644 --- a/.env.dev +++ b/.env.dev @@ -21,6 +21,12 @@ ELYSIUM_NODE_URL=https://rpc.elysiumchain.tech CORE_NODE_URL=https://core.public.infstones.com BASE_NODE_URL=https://base.llamarpc.com LINEA_NODE_URL=https://rpc.linea.build +BTTC_NODE_URL=https://rpc.bittorrentchain.io +XAI_NODE_URL= +BAHAMUT_NODE_URL=https://rpc2.bahamut.io/ +TONCENTER_API_KEY= +SKALE-EUROPA_NODE_URL=https://mainnet.skalenodes.com/v1/elated-tan-skat +ETHERLINK_NODE_URL=https://node.mainnet.etherlink.com ##======================== LOGSTASH ======================== LOGSTASH_PORT= LOGSTASH_HOST= @@ -29,7 +35,7 @@ LOGSTASH_INDEX= SLACK_WEBHOOK_URL= SLACK_LOGGING=false -REDIS_HOST= +REDIS_HOST=127.0.0.1 REDIS_PORT=6379 REDIS_USERNAME= REDIS_PASSWORD= diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..98ab62a9 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,30 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Debug npm test with arguments", + "skipFiles": [ + "/**" + ], + "runtimeExecutable": "npm", + "runtimeArgs": [ + "run", + "test", + "--", + "base", + "uniswapv3", + "16905122" + ], + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + "env": { + "TS_NODE_TRANSPILE_ONLY": "true" + } + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md index e873004b..79213664 100644 --- a/README.md +++ b/README.md @@ -513,4 +513,4 @@ assets.forEach((address, index) => { ## Contact -Do not hesitate to contact us with any questions. Here is the [discord](https://discord.com/channels/415573887531745281/1059466542162653284) +Do not hesitate to contact us with any questions. Here is the [discord](https://discord.com/channels/415573887531745281) diff --git a/package-lock.json b/package-lock.json index f7eca7b9..03f4ab6d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,7 @@ "node-fetch": "^2.6.9", "redis": "^4.6.7", "reflect-metadata": "^0.1.13", + "retry": "^0.13.1", "rimraf": "^3.0.2", "rxjs": "^7.2.0", "slack-notify": "^2.0.6", @@ -12582,6 +12583,14 @@ "node": ">=8" } }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "engines": { + "node": ">= 4" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -24396,6 +24405,11 @@ "signal-exit": "^3.0.2" } }, + "retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==" + }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", diff --git a/package.json b/package.json index a7b0a0d9..ee99b1c9 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "start:debug": "nest start --debug --watch", "start:prod": "node dist/main", "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", - "test": "jest --colors --verbose=false --silent=false src/factory/provider.spec.ts", + "test": "jest --colors --verbose=true --silent=false src/factory/provider.spec.ts", "test:watch": "jest --watch", "test:cov": "jest --coverage", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", @@ -44,6 +44,7 @@ "node-fetch": "^2.6.9", "redis": "^4.6.7", "reflect-metadata": "^0.1.13", + "retry": "^0.13.1", "rimraf": "^3.0.2", "rxjs": "^7.2.0", "slack-notify": "^2.0.6", @@ -91,4 +92,4 @@ "coverageDirectory": "../coverage", "testEnvironment": "node" } -} +} \ No newline at end of file diff --git a/src/app.config.ts b/src/app.config.ts index f2f1b01d..927a0b05 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -66,5 +66,10 @@ nodeUrls['CORE_NODE_URL'] = process.env['CORE_NODE_URL']; nodeUrls['LINEA_NODE_URL'] = process.env['LINEA_NODE_URL']; nodeUrls['WAX_NODE_URL'] = process.env['WAX_NODE_URL']; nodeUrls['APTOS_NODE_URL'] = process.env['APTOS_NODE_URL']; +nodeUrls['BTTC_NODE_URL'] = process.env['BTTC_NODE_URL']; +nodeUrls['XAI_NODE_URL'] = process.env['XAI_NODE_URL']; +nodeUrls['BAHAMUT_NODE_URL'] = process.env['BAHAMUT_NODE_URL']; +nodeUrls['SKALE-EUROPA_NODE_URL'] = process.env['SKALE-EUROPA_NODE_URL']; +nodeUrls['ETHERLINK_NODE_URL'] = process.env['ETHERLINK_NODE_URL']; export { config, nodeUrls }; diff --git a/src/factory/providers/ethereum/fluid/fluidLiquidityResolverAbi.json b/src/constants/abi/fluidLiquidityResolverAbi.json similarity index 100% rename from src/factory/providers/ethereum/fluid/fluidLiquidityResolverAbi.json rename to src/constants/abi/fluidLiquidityResolverAbi.json diff --git a/src/factory/providers/base/stargate/abi.json b/src/constants/abi/stargateV1Abi.json similarity index 100% rename from src/factory/providers/base/stargate/abi.json rename to src/constants/abi/stargateV1Abi.json diff --git a/src/constants/contracts.json b/src/constants/contracts.json index 5d32f220..fb3eccce 100644 --- a/src/constants/contracts.json +++ b/src/constants/contracts.json @@ -15,7 +15,9 @@ "zksync-era": "0x5aea5775959fbc2557cc8789bc1bf90a239d9a91", "base": "0x4200000000000000000000000000000000000006", "core": "0x40375C92d9FAf44d2f9db9Bd9ba41a3317a2404f", - "linea": "0xe5d7c2a44ffddf6b295a15c148167daaaf5cf34f" + "linea": "0xe5d7c2a44ffddf6b295a15c148167daaaf5cf34f", + "bttc": "0x0000000000000000000000000000000000001010", + "xai": "0x3fb787101dc6be47cfe18aeee15404dcc842e6af" }, "BULK_BALANCE_ADDRESSES": { "ethereum": "0xb173393e08496209ad1cd9d57c769de76bdcea5a", diff --git a/src/factory/factory.service.ts b/src/factory/factory.service.ts index b93251b9..a67f226d 100644 --- a/src/factory/factory.service.ts +++ b/src/factory/factory.service.ts @@ -37,7 +37,10 @@ export class FactoryService { if (req.block === undefined) { throw new RpcException('Block is undefined'); } - if (this.web3ProviderService.checkNodeUrl(req?.chain)) { + if ( + this.web3ProviderService.checkNodeUrl(req?.chain) && + req.chain !== 'ton' + ) { throw new RpcException('Node URL is not provided'); } diff --git a/src/factory/providers/arbitrum/balancer/abi.json b/src/factory/providers/arbitrum/balancer/abi.json new file mode 100644 index 00000000..ef85e39a --- /dev/null +++ b/src/factory/providers/arbitrum/balancer/abi.json @@ -0,0 +1,16 @@ +{ + "getCurrentTokens": { + "constant": true, + "inputs": [], + "name": "getCurrentTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + } + ], + "payable": false, + "type": "function" + } +} \ No newline at end of file diff --git a/src/factory/providers/arbitrum/balancer/index.ts b/src/factory/providers/arbitrum/balancer/index.ts index aad7f6ef..cbe74ea8 100644 --- a/src/factory/providers/arbitrum/balancer/index.ts +++ b/src/factory/providers/arbitrum/balancer/index.ts @@ -1,71 +1,233 @@ import BigNumber from 'bignumber.js'; import { request, gql } from 'graphql-request'; -import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import basicUtil from '../../../../util/basicUtil'; +import util from '../../../../util/blockchainUtil'; import formatter from '../../../../util/formatter'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import abi from './abi.json'; import { log } from '../../../../util/logger/logger'; -const START_BLOCK = 11700000; -const THEGRAPTH_ENDPOINT = - 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-arbitrum-v2'; -const POOL_COUNT_QUERY = gql` - query getPoolCount($block: Int!) { - balancer(id: 2, block: { number: $block }) { - poolCount - } - } -`; +const START_BLOCK = 72222060; +const THE_GRAPH_API_KEY = process.env?.THE_GRAPH_API_KEY; +const THEGRAPTH_ENDPOINT = `https://gateway-arbitrum.network.thegraph.com/api/${THE_GRAPH_API_KEY}/subgraphs/id/98cQDy6tufTJtshDCuhh9z2kWXsQWBHVh2bqnLHsGAeS`; +const QUERY_SIZE = 1000; const POOLS_QUERY = gql` - query getPools($block: Int!, $skip: Int!) { - pools(skip: $skip, first: 1000, block: { number: $block }) { - tokens { - address - balance - decimals + query getTokens($block: Int!, $skip: Int!) { + pools(block: { number: $block }, skip: $skip, first: ${QUERY_SIZE}) { + tokens { + address + balance + decimals + } } } + `; + +async function v1Tvl(balances, block, chain, provider, web3) { + let _pools; + + try { + _pools = await basicUtil.readFromCache('cache/pools.json', chain, provider); + } catch { + _pools = { + start: START_BLOCK, + pools: [], + tokens: {}, + }; + } + if (!_pools.tokens) { + _pools.tokens = {}; } -`; -async function tvl(params: ITvlParams): Promise> { - const { block, chain, provider, web3 } = params; - if (block < START_BLOCK) { - return {}; + const blocksLimit = 10000; + const poolLogs = []; + for ( + let i = Math.max(_pools.start, START_BLOCK); + i < block; + i += blocksLimit + ) { + const logs = ( + await util.getLogs( + i, + Math.min(i + blocksLimit, block), + '0x8ccec77b0cb63ac2cafd0f5de8cdfadab91ce656d262240ba8a6343bccc5f945', + '0x9424B1412450D0f8Fc2255FAf6046b98213B76Bd', + web3, + ) + ).output; + Array.prototype.push.apply(poolLogs, logs); } - const balances = {}; + const poolPairs = []; - try { - let poolCount; - await request(THEGRAPTH_ENDPOINT, POOL_COUNT_QUERY, { - block: block, - }).then((data) => (poolCount = data.balancer.poolCount)); - - for (let i = 0; i < poolCount; i += 1000) { - let pools; - await request(THEGRAPTH_ENDPOINT, POOLS_QUERY, { - block: block, - skip: i, - }).then((data) => (pools = data.pools)); - - pools.forEach((pool) => { - pool.tokens.forEach((token) => { - balances[token.address] = BigNumber( - balances[token.address] || 0, - ).plus(BigNumber(token.balance).shiftedBy(token.decimals)); + let pools = poolLogs.map((poolLog) => { + return `0x${poolLog.topics[2].slice(26)}`.toLowerCase(); + }); + pools = pools.filter((pool) => !_pools.pools.includes(pool)); + pools = _pools.pools.concat(pools); + + const poolLength = pools.length; + const counts = Math.ceil(poolLength / 12); + const index = new Date().getHours() % 12; + + const recalcPools = pools.slice(index * counts, (index + 1) * counts); + const recalcResults = await util.executeCallOfMultiTargets( + recalcPools, + [abi['getCurrentTokens']], + 'getCurrentTokens', + [], + block, + chain, + web3, + ); + + recalcResults.forEach((result, index) => { + if (result) { + _pools.tokens[recalcPools[index]] = result.map((token) => + token.toLowerCase(), + ); + } + }); + + const newPools = pools.filter((pool) => !_pools.tokens[pool]); + const newResults = await util.executeCallOfMultiTargets( + newPools, + [abi['getCurrentTokens']], + 'getCurrentTokens', + [], + block, + chain, + web3, + ); + + newResults.forEach((result, index) => { + if (result) { + _pools.tokens[newPools[index]] = result.map((token) => + token.toLowerCase(), + ); + } + }); + + await basicUtil.saveIntoCache( + { + start: block, + pools, + tokens: _pools.tokens, + }, + 'cache/pools.json', + chain, + provider, + ); + + for (const pool in _pools.tokens) { + const poolTokens = _pools.tokens[pool]; + if (poolTokens) { + poolTokens.forEach((token) => { + poolPairs.push({ pool, token }); + }); + } + } + + const poolPairLength = poolPairs.length; + for (let i = 0; i < poolPairLength; i += 2000) { + const j = Math.min(i + 2000, poolPairLength); + const balanceCalls = []; + + for (let start = i; start < j; start += 100) { + const end = Math.min(start + 100, poolPairLength); + const subPairs = poolPairs.slice(start, end); + try { + balanceCalls.push( + util.getTokenBalancesOfHolders( + subPairs.map((pair) => pair.pool), + subPairs.map((pair) => pair.token), + block, + chain, + web3, + ), + ); + } catch (e) { + log.error({ + message: e?.message || '', + stack: e?.stack || '', + detail: `Error: v1Tvl of ethereum/balancer`, + endpoint: 'v1Tvl', }); + } + log.info({ + message: `done ${end} out of ${poolPairLength}`, + endpoint: 'v1Tvl of ethereum/balancer', }); + console.log(`done ${end} out of ${poolPairLength}`); + } + + const bulkBalances = await Promise.all(balanceCalls); + + for (const bulkBalance of bulkBalances) { + formatter.sumMultiBalanceOf(balances, bulkBalance); + } + } +} + +async function v2Tvl(balances, block) { + try { + let skip = 0; + while (true) { + try { + const pools = await request(THEGRAPTH_ENDPOINT, POOLS_QUERY, { + block: block, + skip: skip, + }).then((data) => data.pools); + + pools.forEach((pool) => { + pool.tokens.forEach((token) => { + balances[token.address] = BigNumber( + balances[token.address] || 0, + ).plus( + BigNumber(token.balance).shiftedBy(parseInt(token.decimals)), + ); + }); + }); + + if (pools.length < QUERY_SIZE) { + break; + } + skip += QUERY_SIZE; + } catch (e) { + log.error({ + message: e?.message || '', + stack: e?.stack || '', + detail: `Error: v2Tvl of ethereum/balancer`, + endpoint: 'v2Tvl', + }); + throw e; + } } } catch (e) { log.error({ message: e?.message || '', stack: e?.stack || '', - detail: `Error: tvl of polygon/balancer`, - endpoint: 'tvl', + detail: `Error: v2Tvl of ethereum/balancer`, + endpoint: 'v2Tvl', }); throw e; } +} + +async function tvl(params: ITvlParams): Promise> { + const { chain, provider, web3 } = params; + const block = params.block - 100; + if (block < START_BLOCK) { + return {}; + } + + const balances = {}; + + await v1Tvl(balances, block, chain, provider, web3); + await v2Tvl(balances, block); formatter.convertBalancesToFixed(balances); + return { balances }; } diff --git a/src/factory/providers/arbitrum/camelot/index.ts b/src/factory/providers/arbitrum/camelot/index.ts index 297d2b3c..689ebf43 100644 --- a/src/factory/providers/arbitrum/camelot/index.ts +++ b/src/factory/providers/arbitrum/camelot/index.ts @@ -1,13 +1,12 @@ import formatter from '../../../../util/formatter'; import uniswapV2 from '../../../../util/calculators/uniswapV2'; -import uniswapV3 from '../../../../util/calculators/uniswapV3'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; const START_BLOCK = 11700000; -const V3_START_BLOCK = 73691955; +const V3_START_BLOCK = 101163738; const V2_FACTORY_ADDRESS = '0x6EcCab422D763aC031210895C81787E87B43A652'; -const V3_THEGRAPTH_ENDPOINT = - 'https://api.thegraph.com/subgraphs/name/camelotlabs/camelot-amm-v3'; +const V3_FACTORY_ADDRESS = '0x1a3c9B1d2F0529D97f2afC5136Cc23e58f1FD35B'; async function tvl(params: ITvlParams): Promise> { const { block, chain, provider, web3 } = params; @@ -15,6 +14,8 @@ async function tvl(params: ITvlParams): Promise> { return { balances: {} }; } + let balances = {}; + const v2 = await uniswapV2.getTvl( V2_FACTORY_ADDRESS, block, @@ -23,20 +24,21 @@ async function tvl(params: ITvlParams): Promise> { web3, ); - let v3 = { balances: {}, poolBalances: {} }; - if (block > V3_START_BLOCK) { - v3 = await uniswapV3.getTvlFromSubgraph( - V3_THEGRAPTH_ENDPOINT, + if (block >= V3_START_BLOCK) { + balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, block, chain, provider, + web3, + 'algebra', ); } - const balances = formatter.sum([v2.balances, v3.balances]); - const poolBalances = { ...v2.poolBalances, ...v3.poolBalances }; + balances = formatter.sum([v2.balances, balances]); - return { balances, poolBalances }; + return { balances }; } export { tvl }; diff --git a/src/factory/providers/arbitrum/fluid/index.ts b/src/factory/providers/arbitrum/fluid/index.ts new file mode 100644 index 00000000..4742fabd --- /dev/null +++ b/src/factory/providers/arbitrum/fluid/index.ts @@ -0,0 +1,49 @@ +import util from '../../../../util/blockchainUtil'; +import FLUID_LIQUIDITY_RESOLVER_ABI from './../../../../constants/abi/fluidLiquidityResolverAbi.json'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import formatter from '../../../../util/formatter'; + +const FLUID_LIQUIDITY_RESOLVER_ADDRESS = + '0x46859d33E662d4bF18eEED88f74C36256E606e44'; +const FLUID_LIQUIDITY_PROXY_ADDRESS = + '0x52aa899454998be5b000ad077a46bbe360f4e497'; +const START_BLOCK = 220375059; +const ETH_ADDRESS = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { + return { balances: {} }; + } + + const listedTokens = await util.executeCall( + FLUID_LIQUIDITY_RESOLVER_ADDRESS, + FLUID_LIQUIDITY_RESOLVER_ABI, + 'listedTokens', + [], + block, + chain, + web3, + ); + + const balances = { + [util.ZERO_ADDRESS]: await web3.eth.getBalance( + FLUID_LIQUIDITY_PROXY_ADDRESS, + block, + ), + }; + + const tokenBalances = await util.getTokenBalances( + FLUID_LIQUIDITY_PROXY_ADDRESS, + listedTokens.filter((token: any) => token.token !== ETH_ADDRESS), + block, + chain, + web3, + ); + + formatter.sumMultiBalanceOf(balances, tokenBalances); + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/arbitrum/marginly/index.ts b/src/factory/providers/arbitrum/marginly/index.ts index 6218ce66..4bfb2167 100644 --- a/src/factory/providers/arbitrum/marginly/index.ts +++ b/src/factory/providers/arbitrum/marginly/index.ts @@ -4,15 +4,31 @@ import basicUtil from '../../../../util/basicUtil'; import formatter from '../../../../util/formatter'; const START_BLOCK = 144171029; +const TOPICV1 = + '0xd0e737354a56400bbcbd585fbc60373a7d31e55ad3c2543cb7d4075d2052d576'; +const TOPICV15 = + '0x711e3e5dab53990b08943dd1648a41413712f35934fc7775b3dc56345de0919d'; + const FACTORIES = [ - '0x1e36749E00229759dca262cB25Ad8d9B21bEB3F5', -]; -const TOPIC = '0xd0e737354a56400bbcbd585fbc60373a7d31e55ad3c2543cb7d4075d2052d576'; -const typesArray = [ - { type: 'address', name: 'uniswapPool' }, - { type: 'bool', name: 'quoteTokenIsToken0' }, - { type: 'address', name: 'pool' }, + { + factory: '0x1e36749E00229759dca262cB25Ad8d9B21bEB3F5', + topic: TOPICV1, + types: [ + { type: 'address', name: 'uniswapPool' }, + { type: 'bool', name: 'quoteTokenIsToken0' }, + { type: 'address', name: 'pool' }, + ], + }, + { + factory: '0x537A3417Fe03e28F4E9640Bece70887a6938ff92', + topic: TOPICV15, + types: [ + { type: 'uint32', name: 'defaultSwapCallData' }, + { type: 'address', name: 'pool' }, + ], + }, ]; + const BLOCK_LIMIT = 10000; async function tvl(params: ITvlParams): Promise> { @@ -28,10 +44,10 @@ async function tvl(params: ITvlParams): Promise> { pools: object; } = { start: START_BLOCK, pools: {} }; try { - cache = await basicUtil.readFromCache('MarginlyPools.json', chain, provider); + cache = await basicUtil.readFromCache('pools.json', chain, provider); } catch {} - for (const factory of FACTORIES) { + for (const { factory, topic, types } of FACTORIES) { for ( let i = Math.max(cache.start, START_BLOCK); i < block; @@ -40,15 +56,12 @@ async function tvl(params: ITvlParams): Promise> { const logs = await util.getLogs( i, Math.min(i + BLOCK_LIMIT, block), - TOPIC, + topic, factory, web3, ); logs.output.forEach((log) => { - const decodedParameters = formatter.decodeParameters( - typesArray, - log.data, - ); + const decodedParameters = formatter.decodeParameters(types, log.data); const marginlyPool = decodedParameters.pool; console.log(`New Marginly pool: ${marginlyPool}`); const quoteToken = `0x${log.topics[1].slice(26)}`; @@ -61,7 +74,7 @@ async function tvl(params: ITvlParams): Promise> { } cache.start = block; - await basicUtil.saveIntoCache(cache, 'MarginlyPools.json', chain, provider); + await basicUtil.saveIntoCache(cache, 'pools.json', chain, provider); const tokenBalances = await util.getTokenBalancesOfHolders( Object.keys(cache.pools).flatMap((i) => [i, i]), @@ -77,5 +90,5 @@ async function tvl(params: ITvlParams): Promise> { formatter.convertBalancesToFixed(balances); return { balances }; } - -export { tvl }; \ No newline at end of file + +export { tvl }; diff --git a/src/factory/providers/arbitrum/radiant/data.json b/src/factory/providers/arbitrum/radiant/data.json deleted file mode 100644 index 1628c5a2..00000000 --- a/src/factory/providers/arbitrum/radiant/data.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "address": "0x3082cc23568ea640225c2467653db90e9250aaa0", - "name": "Radiant Capital", - "symbol": "RDNT", - "decimals": 18, - "logo": "https://assets.coingecko.com/coins/images/26536/small/Radiant-Logo-200x200.png" -} \ No newline at end of file diff --git a/src/factory/providers/arbitrum/radiant/index.ts b/src/factory/providers/arbitrum/radiant/index.ts index d1b70f29..b2969f5e 100644 --- a/src/factory/providers/arbitrum/radiant/index.ts +++ b/src/factory/providers/arbitrum/radiant/index.ts @@ -1,6 +1,5 @@ import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; import util from '../../../../util/blockchainUtil'; -import ERC20_ABI from '../../../../constants/abi/erc20.json'; import formatter from '../../../../util/formatter'; import abi from '../../polygon/aave/abi.json'; import BigNumber from 'bignumber.js'; diff --git a/src/factory/providers/arbitrum/stargate/abi/poolAbi.json b/src/factory/providers/arbitrum/stargate/abi/poolAbi.json deleted file mode 100644 index 30ed5f1b..00000000 --- a/src/factory/providers/arbitrum/stargate/abi/poolAbi.json +++ /dev/null @@ -1,1940 +0,0 @@ -[ - { - "inputs": [ - { - "internalType": "uint256", - "name": "_poolId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_router", - "type": "address" - }, - { - "internalType": "address", - "name": "_token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_sharedDecimals", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_localDecimals", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_feeLibrary", - "type": "address" - }, - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountLP", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - } - ], - "name": "Burn", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint16", - "name": "dstChainId", - "type": "uint16" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "dstPoolId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "weight", - "type": "uint256" - } - ], - "name": "ChainPathUpdate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint16", - "name": "chainId", - "type": "uint16" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "srcPoolId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "idealBalance", - "type": "uint256" - } - ], - "name": "CreditChainPath", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bool", - "name": "batched", - "type": "bool" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "swapDeltaBP", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "lpDeltaBP", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bool", - "name": "defaultSwapMode", - "type": "bool" - }, - { - "indexed": false, - "internalType": "bool", - "name": "defaultLPMode", - "type": "bool" - } - ], - "name": "DeltaParamUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "feeLibraryAddr", - "type": "address" - } - ], - "name": "FeeLibraryUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "mintFeeBP", - "type": "uint256" - } - ], - "name": "FeesUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountLP", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - } - ], - "name": "InstantRedeemLocal", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountLP", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "mintFeeAmountSD", - "type": "uint256" - } - ], - "name": "Mint", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountLP", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint16", - "name": "chainId", - "type": "uint16" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "dstPoolId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "to", - "type": "bytes" - } - ], - "name": "RedeemLocal", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "_amountSD", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "_amountToMintSD", - "type": "uint256" - } - ], - "name": "RedeemLocalCallback", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint16", - "name": "chainId", - "type": "uint16" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "dstPoolId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountLP", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - } - ], - "name": "RedeemRemote", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint16", - "name": "dstChainId", - "type": "uint16" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "dstPoolId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "credits", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "idealBalance", - "type": "uint256" - } - ], - "name": "SendCredits", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bool", - "name": "swapStop", - "type": "bool" - } - ], - "name": "StopSwapUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint16", - "name": "chainId", - "type": "uint16" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "dstPoolId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "eqReward", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "eqFee", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "protocolFee", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "lpFee", - "type": "uint256" - } - ], - "name": "Swap", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "protocolFee", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "dstFee", - "type": "uint256" - } - ], - "name": "SwapRemote", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - } - ], - "name": "WithdrawMintFeeBalance", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - } - ], - "name": "WithdrawProtocolFeeBalance", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint16", - "name": "srcChainId", - "type": "uint16" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "srcPoolId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "mintAmount", - "type": "uint256" - } - ], - "name": "WithdrawRemote", - "type": "event" - }, - { - "inputs": [], - "name": "BP_DENOMINATOR", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "DOMAIN_SEPARATOR", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "PERMIT_TYPEHASH", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_dstChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_dstPoolId", - "type": "uint256" - } - ], - "name": "activateChainPath", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_amountLP", - "type": "uint256" - } - ], - "name": "amountLPtoLD", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "batched", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bool", - "name": "_fullMode", - "type": "bool" - } - ], - "name": "callDelta", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "chainPathIndexLookup", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "chainPaths", - "outputs": [ - { - "internalType": "bool", - "name": "ready", - "type": "bool" - }, - { - "internalType": "uint16", - "name": "dstChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "dstPoolId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "weight", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lkb", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "credits", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "idealBalance", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "convertRate", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_dstChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_dstPoolId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_weight", - "type": "uint256" - } - ], - "name": "createChainPath", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_dstChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_dstPoolId", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "credits", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "idealBalance", - "type": "uint256" - } - ], - "internalType": "struct Pool.CreditObj", - "name": "_c", - "type": "tuple" - } - ], - "name": "creditChainPath", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "decimals", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "subtractedValue", - "type": "uint256" - } - ], - "name": "decreaseAllowance", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "defaultLPMode", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "defaultSwapMode", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "deltaCredit", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "eqFeePool", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "feeLibrary", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_dstChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_dstPoolId", - "type": "uint256" - } - ], - "name": "getChainPath", - "outputs": [ - { - "components": [ - { - "internalType": "bool", - "name": "ready", - "type": "bool" - }, - { - "internalType": "uint16", - "name": "dstChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "dstPoolId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "weight", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lkb", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "credits", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "idealBalance", - "type": "uint256" - } - ], - "internalType": "struct Pool.ChainPath", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getChainPathsLength", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "addedValue", - "type": "uint256" - } - ], - "name": "increaseAllowance", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amountLP", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - } - ], - "name": "instantRedeemLocal", - "outputs": [ - { - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "localDecimals", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "lpDeltaBP", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amountLD", - "type": "uint256" - } - ], - "name": "mint", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "mintFeeBP", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "mintFeeBalance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "nonces", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "name": "permit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "poolId", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "protocolFeeBalance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amountLP", - "type": "uint256" - }, - { - "internalType": "uint16", - "name": "_dstChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_dstPoolId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_to", - "type": "bytes" - } - ], - "name": "redeemLocal", - "outputs": [ - { - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_srcChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_srcPoolId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amountSD", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_amountToMintSD", - "type": "uint256" - } - ], - "name": "redeemLocalCallback", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_srcChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_srcPoolId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_amountSD", - "type": "uint256" - } - ], - "name": "redeemLocalCheckOnRemote", - "outputs": [ - { - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "mintAmount", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_dstChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_dstPoolId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amountLP", - "type": "uint256" - } - ], - "name": "redeemRemote", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "router", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_dstChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_dstPoolId", - "type": "uint256" - } - ], - "name": "sendCredits", - "outputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "credits", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "idealBalance", - "type": "uint256" - } - ], - "internalType": "struct Pool.CreditObj", - "name": "c", - "type": "tuple" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bool", - "name": "_batched", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "_swapDeltaBP", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_lpDeltaBP", - "type": "uint256" - }, - { - "internalType": "bool", - "name": "_defaultSwapMode", - "type": "bool" - }, - { - "internalType": "bool", - "name": "_defaultLPMode", - "type": "bool" - } - ], - "name": "setDeltaParam", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_mintFeeBP", - "type": "uint256" - } - ], - "name": "setFee", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_feeLibraryAddr", - "type": "address" - } - ], - "name": "setFeeLibrary", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bool", - "name": "_swapStop", - "type": "bool" - } - ], - "name": "setSwapStop", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_dstChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_dstPoolId", - "type": "uint256" - }, - { - "internalType": "uint16", - "name": "_weight", - "type": "uint16" - } - ], - "name": "setWeightForChainPath", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "sharedDecimals", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "stopSwap", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_dstChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_dstPoolId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amountLD", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_minAmountLD", - "type": "uint256" - }, - { - "internalType": "bool", - "name": "newLiquidity", - "type": "bool" - } - ], - "name": "swap", - "outputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "eqFee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "eqReward", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lpFee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "protocolFee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lkbRemove", - "type": "uint256" - } - ], - "internalType": "struct Pool.SwapObj", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "swapDeltaBP", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_srcChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_srcPoolId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "eqFee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "eqReward", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lpFee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "protocolFee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lkbRemove", - "type": "uint256" - } - ], - "internalType": "struct Pool.SwapObj", - "name": "_s", - "type": "tuple" - } - ], - "name": "swapRemote", - "outputs": [ - { - "internalType": "uint256", - "name": "amountLD", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "token", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalLiquidity", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalWeight", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_to", - "type": "address" - } - ], - "name": "withdrawMintFeeBalance", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_to", - "type": "address" - } - ], - "name": "withdrawProtocolFeeBalance", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } -] \ No newline at end of file diff --git a/src/factory/providers/arbitrum/stargate/data.json b/src/factory/providers/arbitrum/stargate/data.json deleted file mode 100644 index 24d540db..00000000 --- a/src/factory/providers/arbitrum/stargate/data.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "address": "0x6694340fc020c5e6b96567843da2df01b2ce1eb6", - "name": "Stargate Finance", - "symbol": "STG", - "decimals": 18, - "logo": "https://assets.coingecko.com/coins/images/24413/small/STG_LOGO.png" -} \ No newline at end of file diff --git a/src/factory/providers/arbitrum/stargate/index.ts b/src/factory/providers/arbitrum/stargate/index.ts index 183ea1fa..b35e4acf 100644 --- a/src/factory/providers/arbitrum/stargate/index.ts +++ b/src/factory/providers/arbitrum/stargate/index.ts @@ -1,25 +1,35 @@ -import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; import util from '../../../../util/blockchainUtil'; import formatter from '../../../../util/formatter'; -import FACTORY_ABI from './abi/factoryAbi.json'; -import POOL_ABI from './abi/poolAbi.json'; -import { WMAIN_ADDRESS } from '../../../../constants/contracts.json'; +import basicUtil from '../../../../util/basicUtil'; +import ABI from '../../../../constants/abi/stargateV1Abi.json'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import stargateV2 from '../../../../util/calculators/stargateV2'; -const START_BLOCK = 11700000; -const FACTORY = '0x55bdb4164d28fbaf0898e0ef14a589ac09ac9970'; -const SGETH = '0x82cbecf39bee528b5476fe6d1550af59a9db6fc0'; +const ROUTER = '0x53Bf833A5d6c4ddA888F69c22C88C9f356a41614'; async function tvl(params: ITvlParams): Promise> { const { block, chain, provider, web3 } = params; - if (block < START_BLOCK) { - return {}; - } - const balances = {}; + let store = { + pools: [], + tokens: {}, + }; + try { + store = await basicUtil.readFromCache('cache/store.json', chain, provider); + } catch {} + const factory = await util.executeCall( + ROUTER, + ABI, + 'factory', + [], + block, + chain, + web3, + ); const allPoolsLength = await util.executeCall( - FACTORY, - FACTORY_ABI, + factory, + ABI, 'allPoolsLength', [], block, @@ -27,46 +37,58 @@ async function tvl(params: ITvlParams): Promise> { web3, ); - const contractParams = []; - for (let i = 0; i < allPoolsLength; i++) { - contractParams.push([i]); + if (store.pools.length < allPoolsLength) { + const newPools = await util.executeMultiCallsOfTarget( + factory, + ABI, + 'allPools', + Array.from( + { length: allPoolsLength - store.pools.length }, + (_, i) => store.pools.length + i, + ), + block, + chain, + web3, + ); + const poolTokens = await util.executeCallOfMultiTargets( + newPools, + ABI, + 'token', + [], + block, + chain, + web3, + ); + + for (const index in newPools) { + if (newPools[index] && poolTokens[index]) { + store.pools.push(newPools[index]); + store.tokens[newPools[index]] = poolTokens[index]; + } else { + break; + } + } + + await basicUtil.saveIntoCache(store, 'cache/store.json', chain, provider); } - const pools = await util.executeMultiCallsOfTarget( - FACTORY, - FACTORY_ABI, - 'allPools', - contractParams, + const tokenBalances = await util.getTokenBalancesOfHolders( + Object.keys(store.tokens), + Object.values(store.tokens), block, chain, web3, ); - const tokens = await util.executeCallOfMultiTargets( - pools, - POOL_ABI, - 'token', - [], - block, - chain, - web3, - ); + const balances = {}; - const balanceResults = await util.getTokenBalancesOfHolders( - pools, - tokens, - block, - chain, - web3, - ); + formatter.sumMultiBalanceOf(balances, tokenBalances); - formatter.sumMultiBalanceOf(balances, balanceResults); - formatter.convertBalancesToFixed(balances); + const v2TokenBalances = await stargateV2.getV2Tvl(chain, block, web3); + formatter.sumMultiBalanceOf(balances, v2TokenBalances); - if (balances[SGETH]) { - balances[WMAIN_ADDRESS.arbitrum] = balances[SGETH]; - delete balances[SGETH]; - } + formatter.convertBalancesToFixed(balances); return { balances }; } + export { tvl }; diff --git a/src/factory/providers/arbitrum/sushiswap/data.json b/src/factory/providers/arbitrum/sushiswap/data.json deleted file mode 100644 index 97f25640..00000000 --- a/src/factory/providers/arbitrum/sushiswap/data.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "address": "0xd4d42f0b6def4ce0383636770ef773390d85c61a", - "name": "Sushi", - "symbol": "SUSHI", - "decimals": 18, - "logo": "https://user-dashboard.s3.us-east-2.amazonaws.com/token_images/prod/35/0x947950bcc74888a40ffa2593c5798f11fc9124c4_large.png" -} \ No newline at end of file diff --git a/src/factory/providers/arbitrum/sushiswap/index.ts b/src/factory/providers/arbitrum/sushiswap/index.ts index 3c1a9fab..8d64c9ea 100644 --- a/src/factory/providers/arbitrum/sushiswap/index.ts +++ b/src/factory/providers/arbitrum/sushiswap/index.ts @@ -1,93 +1,28 @@ -import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; -import uniswapV2 from '../../../../util/calculators/uniswapV2'; -import { trident } from './trident'; -import BigNumber from 'bignumber.js'; -import { gql, request } from 'graphql-request'; import formatter from '../../../../util/formatter'; +import uniswapV2 from '../../../../util/calculators/uniswapV2'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; + +const START_BLOCK = 70; +const FACTORY_ADDRESS = '0xc35DADB65012eC5796536bD9864eD8773aBc74C4'; -const GRAPHQL_API = - 'https://api.thegraph.com/subgraphs/name/sushi-labs/kashi-arbitrum'; -const GRAPHQL_API_FACTORY = - 'https://api.thegraph.com/subgraphs/name/sushi-v2/sushiswap-arbitrum'; -const QUERY_SIZE = 500; -const PAIR = gql` - query getPairs($block: Int!) { - pairs( - block: { number: $block } - orderBy: liquidityUSD - orderDirection: desc - first: ${QUERY_SIZE} - ) { - token0 { - id - } - token1 { - id - } - reserve0 - reserve1 - } - } -`; async function tvl(params: ITvlParams): Promise> { const { block, chain, provider, web3 } = params; - const requestResult = await request(GRAPHQL_API_FACTORY, PAIR, { - block: block, - }); - const dexBalances = {}; - requestResult.pairs.forEach((pair) => { - if (dexBalances[pair.token0.id]) { - dexBalances[pair.token0.id] = BigNumber(pair.reserve0) - .plus(dexBalances[pair.token0.id]) - .toFixed(); - } else { - dexBalances[pair.token0.id] = BigNumber(pair.reserve0).toFixed(); - } - if (dexBalances[pair.token1.id]) { - dexBalances[pair.token1.id] = BigNumber(pair.reserve1) - .plus(dexBalances[pair.token1.id]) - .toFixed(); - } else { - dexBalances[pair.token1.id] = BigNumber(pair.reserve1).toFixed(); - } - }); - - const { balances: tridentBalance } = await trident(params); - - const balances = formatter.sum([dexBalances, tridentBalance]); - - for (const token in balances) { - if (BigNumber(balances[token] || 0).isLessThan(100000)) { - delete balances[token]; - } + if (block < START_BLOCK) { + return {}; } - // const { balances: kashib } = await kashi(params); - return { balances }; -} -async function getPoolVolumes(pools, priorBlockNumber) { - const poolVolumes = await uniswapV2.getPoolVolumes( - GRAPHQL_API, - QUERY_SIZE, - pools, - priorBlockNumber, - null, + const { balances, poolBalances } = await uniswapV2.getTvl( + FACTORY_ADDRESS, + block, + chain, + provider, + web3, ); - return poolVolumes; -} - -async function getTokenVolumes(tokens, priorBlockNumber) { - const tokenVolumes = await uniswapV2.getTokenVolumes( - GRAPHQL_API, - QUERY_SIZE, - tokens, - priorBlockNumber, - null, - ); + formatter.convertBalancesToFixed(balances); - return tokenVolumes; + return { balances, poolBalances }; } -export { tvl, getPoolVolumes, getTokenVolumes }; +export { tvl }; diff --git a/src/factory/providers/arbitrum/sushiswap/trident.ts b/src/factory/providers/arbitrum/sushiswap/trident.ts deleted file mode 100644 index 3b905441..00000000 --- a/src/factory/providers/arbitrum/sushiswap/trident.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; -import BigNumber from 'bignumber.js'; -import { gql, request } from 'graphql-request'; - -const GRAPHQL_API_TRIDENT = - 'https://api.thegraph.com/subgraphs/name/sushi-v2/trident-arbitrum'; -const TOKENS = gql` - query get_tokens($block: Int) { - tokens( - block: { number: $block } - first: 1000 - orderBy: liquidityUSD - orderDirection: desc - where: { liquidityUSD_gt: 0 } - ) { - id - liquidity - } - } -`; -async function trident(params: ITvlParams): Promise> { - const { block, chain, provider, web3 } = params; - - const requestResult = await request(GRAPHQL_API_TRIDENT, TOKENS, { - block: block, - }); - const balances = {}; - requestResult.tokens.forEach((token) => { - if (balances[token.id]) { - balances[token.id] = BigNumber(token.liquidity) - .plus(balances[token.id]) - .toFixed(); - } else { - balances[token.id] = BigNumber(token.liquidity).toFixed(); - } - }); - - for (const token in balances) { - if (BigNumber(balances[token] || 0).isLessThan(100000)) { - delete balances[token]; - } - } - - return { balances }; -} - -export { trident }; diff --git a/src/factory/providers/arbitrum/sushiswapv3/index.ts b/src/factory/providers/arbitrum/sushiswapv3/index.ts index 419f8cd4..f20938de 100644 --- a/src/factory/providers/arbitrum/sushiswapv3/index.ts +++ b/src/factory/providers/arbitrum/sushiswapv3/index.ts @@ -1,74 +1,25 @@ import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; -import { gql, request } from 'graphql-request'; -import BigNumber from 'bignumber.js'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; -const START_BLOCK = 75998697; -const GRAPHQL_API = - 'https://api.thegraph.com/subgraphs/name/sushi-v3/v3-arbitrum'; -const QUERY_SIZE = 200; -const TOKENS = gql` - query getTokens($block: Int) { - tokens(block: {number: $block}, first: ${QUERY_SIZE} orderBy: totalValueLockedUSD, orderDirection: desc) { - id - decimals - totalValueLocked - } - pools(first: ${QUERY_SIZE} orderBy: totalValueLockedToken0 orderDirection: desc) { - id - token0 { - id - decimals - } - token1 { - id - decimals - } - totalValueLockedToken0 - totalValueLockedToken1 - } - } -`; - -const BASE_TOKEN = { - '0xa54b8e178a49f8e5405a4d44bb31f496e5564a05': 'coingecko_pepe', -}; +const V3_START_BLOCK = 75998697; +const V3_FACTORY_ADDRESS = '0x1af415a1EbA07a4986a52B6f2e7dE7003D82231e'; async function tvl(params: ITvlParams): Promise> { const { block, chain, provider, web3 } = params; - - if (block < START_BLOCK) { - return {}; + if (block < V3_START_BLOCK) { + return { balances: {} }; } - const requestResult = await request(GRAPHQL_API, TOKENS, { - block: block, - }); - const balances = {}, - poolBalances = {}; - requestResult.tokens.forEach((token) => { - balances[token.id] = BigNumber(token.totalValueLocked) - .shiftedBy(Number(token.decimals)) - .toFixed(); - if (BASE_TOKEN[token.id]) { - balances[BASE_TOKEN[token.id]] = BigNumber( - token.totalValueLocked, - ).toFixed(); - } - }); - requestResult.pools.forEach((pool) => { - poolBalances[pool.id] = { - tokens: [pool.token0.id, pool.token1.id], - balances: [ - BigNumber(pool.totalValueLockedToken0) - .shiftedBy(Number(pool.token0.decimals)) - .toFixed(), - BigNumber(pool.totalValueLockedToken1) - .shiftedBy(Number(pool.token1.decimals)) - .toFixed(), - ], - }; - }); - return { balances, poolBalances }; + const balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, + block, + chain, + provider, + web3, + ); + + return { balances, poolBalances: {} }; } export { tvl }; diff --git a/src/factory/providers/arbitrum/uniswapv3/index.ts b/src/factory/providers/arbitrum/uniswapv3/index.ts index 65ff5f8d..cbf88061 100644 --- a/src/factory/providers/arbitrum/uniswapv3/index.ts +++ b/src/factory/providers/arbitrum/uniswapv3/index.ts @@ -1,24 +1,25 @@ import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; -import formatter from '../../../../util/formatter'; -import uniswapV3 from '../../../../util/calculators/uniswapV3'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; -const START_BLOCK = 11542645; -const THEGRAPTH_ENDPOINT = - 'https://api.thegraph.com/subgraphs/name/ianlapham/arbitrum-dev'; +const V3_START_BLOCK = 11542645; +const V3_FACTORY_ADDRESS = '0x1F98431c8aD98523631AE4a59f267346ea31F984'; async function tvl(params: ITvlParams): Promise> { const { block, chain, provider, web3 } = params; - if (block < START_BLOCK) { + if (block < V3_START_BLOCK) { return { balances: {} }; } - const { balances, poolBalances } = await uniswapV3.getTvlFromSubgraph( - THEGRAPTH_ENDPOINT, + const balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, block, chain, provider, + web3, ); - formatter.convertBalancesToFixed(balances); - return { balances, poolBalances }; + + return { balances, poolBalances: {} }; } + export { tvl }; diff --git a/src/factory/providers/aurora/stargate/index.ts b/src/factory/providers/aurora/stargate/index.ts new file mode 100644 index 00000000..ce989aa8 --- /dev/null +++ b/src/factory/providers/aurora/stargate/index.ts @@ -0,0 +1,17 @@ +import formatter from '../../../../util/formatter'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import stargateV2 from '../../../../util/calculators/stargateV2'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + const balances = {}; + + const v2TokenBalances = await stargateV2.getV2Tvl(chain, block, web3); + formatter.sumMultiBalanceOf(balances, v2TokenBalances); + + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/aurora/synapse/index.ts b/src/factory/providers/aurora/synapse/index.ts index a6ec51f3..24c06033 100644 --- a/src/factory/providers/aurora/synapse/index.ts +++ b/src/factory/providers/aurora/synapse/index.ts @@ -2,6 +2,7 @@ import util from '../../../../util/blockchainUtil'; import formatter from '../../../../util/formatter'; import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +const START_BLOCK = 56525135; const POOL = '0xcEf6C2e20898C2604886b888552CA6CcF66933B0'; const TOKENS = [ '0x4988a896b1227218e4A686fdE5EabdcAbd91571f', @@ -11,8 +12,8 @@ const TOKENS = [ async function tvl(params: ITvlParams): Promise> { const { block, chain, provider, web3 } = params; - if (block < 56525135) { - return {}; + if (block < START_BLOCK) { + return { balances: {} }; } const tokenBalances = await util.getTokenBalances( diff --git a/src/factory/providers/avalanche/stargate/abi.json b/src/factory/providers/avalanche/stargate/abi.json deleted file mode 100644 index dbeb8a3e..00000000 --- a/src/factory/providers/avalanche/stargate/abi.json +++ /dev/null @@ -1,79 +0,0 @@ -[ - { - "inputs": [], - "name": "factory", - "outputs": [ - { - "internalType": "contract Factory", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "allPoolsLength", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "allPools", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "pools", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "token", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - } -] diff --git a/src/factory/providers/avalanche/stargate/data.json b/src/factory/providers/avalanche/stargate/data.json deleted file mode 100644 index 955e3f4c..00000000 --- a/src/factory/providers/avalanche/stargate/data.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "address": "0x2f6f07cdcf3588944bf4c42ac74ff24bf56e7590", - "name": "Stargate Token", - "symbol": "STG", - "decimals": 18, - "logo": "https://assets.coingecko.com/coins/images/24413/small/STG_LOGO.png" -} \ No newline at end of file diff --git a/src/factory/providers/avalanche/stargate/index.ts b/src/factory/providers/avalanche/stargate/index.ts index 693b561e..ed610255 100644 --- a/src/factory/providers/avalanche/stargate/index.ts +++ b/src/factory/providers/avalanche/stargate/index.ts @@ -1,8 +1,9 @@ import util from '../../../../util/blockchainUtil'; import formatter from '../../../../util/formatter'; import basicUtil from '../../../../util/basicUtil'; -import ABI from './abi.json'; +import ABI from '../../../../constants/abi/stargateV1Abi.json'; import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import stargateV2 from '../../../../util/calculators/stargateV2'; const ROUTER = '0x45A01E4e04F14f7A4a6702c74187c5F6222033cd'; @@ -86,8 +87,11 @@ async function tvl(params: ITvlParams): Promise> { const balances = {}; formatter.sumMultiBalanceOf(balances, tokenBalances); - formatter.convertBalancesToFixed(balances); + const v2TokenBalances = await stargateV2.getV2Tvl(chain, block, web3); + formatter.sumMultiBalanceOf(balances, v2TokenBalances); + + formatter.convertBalancesToFixed(balances); return { balances }; } diff --git a/src/factory/providers/avalanche/sushiswap/index.ts b/src/factory/providers/avalanche/sushiswap/index.ts new file mode 100644 index 00000000..8a221692 --- /dev/null +++ b/src/factory/providers/avalanche/sushiswap/index.ts @@ -0,0 +1,28 @@ +import formatter from '../../../../util/formatter'; +import uniswapV2 from '../../../../util/calculators/uniswapV2'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; + +const START_BLOCK = 506190; +const FACTORY_ADDRESS = '0xc35DADB65012eC5796536bD9864eD8773aBc74C4'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + if (block < START_BLOCK) { + return {}; + } + + const { balances, poolBalances } = await uniswapV2.getTvl( + FACTORY_ADDRESS, + block, + chain, + provider, + web3, + ); + + formatter.convertBalancesToFixed(balances); + + return { balances, poolBalances }; +} + +export { tvl }; diff --git a/src/factory/providers/avalanche/sushiswapv3/index.ts b/src/factory/providers/avalanche/sushiswapv3/index.ts new file mode 100644 index 00000000..a54eec21 --- /dev/null +++ b/src/factory/providers/avalanche/sushiswapv3/index.ts @@ -0,0 +1,25 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; + +const V3_START_BLOCK = 28186391; +const V3_FACTORY_ADDRESS = '0x3e603C14aF37EBdaD31709C4f848Fc6aD5BEc715'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < V3_START_BLOCK) { + return { balances: {} }; + } + + const balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, + block, + chain, + provider, + web3, + ); + + return { balances, poolBalances: {} }; +} + +export { tvl }; diff --git a/src/factory/providers/avalanche/uniswapv3/index.ts b/src/factory/providers/avalanche/uniswapv3/index.ts index 39e4d5ff..cc93d29e 100644 --- a/src/factory/providers/avalanche/uniswapv3/index.ts +++ b/src/factory/providers/avalanche/uniswapv3/index.ts @@ -1,57 +1,25 @@ -import BigNumber from 'bignumber.js'; import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; -import { request, gql } from 'graphql-request'; -import formatter from '../../../../util/formatter'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; -const START_BLOCK = 10000835; -const QUERY_SIZE = 1000; -const SUBGRAPH_ENDPOINT = - 'https://api.thegraph.com/subgraphs/name/lynnshaoyu/uniswap-v3-avax'; -const TOKENS = gql` - query getTokens($id: String!, $block: Int!) { - tokens( - block: { number: $block } - first: ${QUERY_SIZE} - orderBy: id - where: { id_gt: $id } - ) { - id - decimals - totalValueLocked - } - } -`; +const V3_START_BLOCK = 10000835; +const V3_FACTORY_ADDRESS = '0x740b1c1de25031C31FF4fC9A62f554A55cdC1baD'; async function tvl(params: ITvlParams): Promise> { const { block, chain, provider, web3 } = params; - - if (block < START_BLOCK) { - return {}; + if (block < V3_START_BLOCK) { + return { balances: {} }; } - const balances = {}; - - let lastId = ''; - while (true) { - const requestResult = await request(SUBGRAPH_ENDPOINT, TOKENS, { - block: block, - id: lastId, - }); - for (const token of requestResult.tokens) { - balances[token.id.toLowerCase()] = BigNumber( - token.totalValueLocked, - ).shiftedBy(Number(token.decimals)); - } - - if (requestResult.tokens.length < QUERY_SIZE) { - break; - } - - lastId = requestResult.tokens[requestResult.tokens.length - 1].id; - } + const balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, + block, + chain, + provider, + web3, + ); - formatter.convertBalancesToFixed(balances); - return { balances }; + return { balances, poolBalances: {} }; } export { tvl }; diff --git a/src/factory/providers/bahamut/lolik/index.ts b/src/factory/providers/bahamut/lolik/index.ts new file mode 100644 index 00000000..b8f22a72 --- /dev/null +++ b/src/factory/providers/bahamut/lolik/index.ts @@ -0,0 +1,45 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import util from '../../../../util/blockchainUtil'; + +const START_BLOCK = 1338123; + +const STAKING_CONTRACT = '0x780Fb5AcA83F2e3F57EE18cc3094988Ef49D8c3d'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { + return { balances: {} }; + } + + const balance = await util.executeCall( + STAKING_CONTRACT, + [ + { + constant: true, + inputs: [], + name: 'getTotalPooledFtn', + outputs: [ + { + name: '', + type: 'uint256', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + ], + 'getTotalPooledFtn', + [], + block, + chain, + web3, + ); + return { + balances: { + ['ftn']: balance, + }, + }; +} + +export { tvl }; diff --git a/src/factory/providers/bahamut/mutuari/index.ts b/src/factory/providers/bahamut/mutuari/index.ts new file mode 100644 index 00000000..834babce --- /dev/null +++ b/src/factory/providers/bahamut/mutuari/index.ts @@ -0,0 +1,81 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import util from '../../../../util/blockchainUtil'; +import formatter from '../../../../util/formatter'; + +const START_BLOCK = 2799294; + +const CONTRACT_ADDRESS = '0x831fc32221924f8a6d47251327ef67ebcc5cd6dc'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { + return { balances: {} }; + } + + const pool = await util.executeCall( + CONTRACT_ADDRESS, + [ + { + constant: true, + inputs: [], + name: 'mutuariPool', + outputs: [ + { + name: '', + type: 'address', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + ], + 'mutuariPool', + [], + block, + chain, + web3, + ); + + const tokens = await util.executeCall( + pool, + [ + { + constant: true, + inputs: [], + name: 'getReserves', + outputs: [ + { + name: '', + type: 'address[]', + }, + ], + payable: false, + stateMutability: 'view', + type: 'function', + }, + ], + 'getReserves', + [], + block, + chain, + web3, + ); + + const balances = {}; + const balanceResults = await util.getTokenBalances( + pool, + tokens, + block, + chain, + web3, + ); + formatter.sumMultiBalanceOf(balances, balanceResults, chain, provider); + formatter.convertBalancesToFixed(balances); + + return { + balances, + }; +} + +export { tvl }; diff --git a/src/factory/providers/bahamut/silkswap/index.ts b/src/factory/providers/bahamut/silkswap/index.ts new file mode 100644 index 00000000..6aaf6e3c --- /dev/null +++ b/src/factory/providers/bahamut/silkswap/index.ts @@ -0,0 +1,28 @@ +import formatter from '../../../../util/formatter'; +import uniswapV2 from '../../../../util/calculators/uniswapV2'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; + +const START_BLOCK = 2388831; +const FACTORY_ADDRESS = '0xd0c5d23290d63e06a0c4b87f14bd2f7aa551a895'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + if (block < START_BLOCK) { + return {}; + } + + const { balances, poolBalances } = await uniswapV2.getTvl( + FACTORY_ADDRESS, + block, + chain, + provider, + web3, + ); + + formatter.convertBalancesToFixed(balances); + + return { balances, poolBalances }; +} + +export { tvl }; diff --git a/src/factory/providers/bahamut/symbiosis/index.ts b/src/factory/providers/bahamut/symbiosis/index.ts new file mode 100644 index 00000000..74a24cbd --- /dev/null +++ b/src/factory/providers/bahamut/symbiosis/index.ts @@ -0,0 +1,29 @@ +import util from '../../../../util/blockchainUtil'; +import formatter from '../../../../util/formatter'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; + +const START_BLOCK = 1854856; +const HOLDER_ADDRESSES = ['0x318C2B9a03C37702742C3d40C72e4056e430135A']; +const USDC_ADDRESSES = ['0x4237e0A5b55233D5B6D6d1D9BF421723954130D8']; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, web3 } = params; + if (block < START_BLOCK) { + return {}; + } + + const tokenBalances = await util.getTokenBalancesOfEachHolder( + HOLDER_ADDRESSES, + USDC_ADDRESSES, + block, + chain, + web3, + ); + + const balances = {}; + formatter.sumMultiBalanceOf(balances, tokenBalances); + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/base/aavev3/index.ts b/src/factory/providers/base/aavev3/index.ts new file mode 100644 index 00000000..7f1e4817 --- /dev/null +++ b/src/factory/providers/base/aavev3/index.ts @@ -0,0 +1,24 @@ +import formatter from '../../../../util/formatter'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import aaveV3 from '../../../../util/calculators/aaveV3'; + +const START_BLOCK = 2357108; +const POOL_DATA_PROVIDER_V3 = '0x2d8A3C5677189723C4cB8873CfC9C8976FDF38Ac'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { + return {}; + } + + const balances = await aaveV3.getTvl( + POOL_DATA_PROVIDER_V3, + block, + chain, + web3, + ); + + formatter.convertBalancesToFixed(balances); + return { balances }; +} +export { tvl }; diff --git a/src/factory/providers/base/aerodrome/index.ts b/src/factory/providers/base/aerodrome/index.ts new file mode 100644 index 00000000..1dcb68f4 --- /dev/null +++ b/src/factory/providers/base/aerodrome/index.ts @@ -0,0 +1,44 @@ +import formatter from '../../../../util/formatter'; +import uniswapV2 from '../../../../util/calculators/uniswapV2'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; + +const START_BLOCK = 3200559; +const V2_FACTORY_ADDRESS = '0x420DD381b31aEf6683db6B902084cB0FFECe40Da'; +const V3_START_BLOCK = 13843704; +const V3_FACTORY_ADDRESS = '0x5e7BB104d84c7CB9B682AaC2F3d509f5F406809A'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { + return { balances: {} }; + } + + let balances: any; + + const v2 = await uniswapV2.getTvl( + V2_FACTORY_ADDRESS, + block, + chain, + provider, + web3, + true, + ); + + if (block >= V3_START_BLOCK) { + balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, + block, + chain, + provider, + web3, + 'aerodrome', + ); + } + + balances = formatter.sum([v2.balances, balances]); + return { balances, poolBalances: v2.poolBalances }; +} + +export { tvl }; diff --git a/src/factory/providers/base/alienbase/index.ts b/src/factory/providers/base/alienbase/index.ts new file mode 100644 index 00000000..50bf7b02 --- /dev/null +++ b/src/factory/providers/base/alienbase/index.ts @@ -0,0 +1,41 @@ +import formatter from '../../../../util/formatter'; +import uniswapV2 from '../../../../util/calculators/uniswapV2'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import util from '../../../../util/blockchainUtil'; + +const START_BLOCK = 2353671; +const V2_FACTORY_ADDRESS = '0x3E84D913803b02A4a7f027165E8cA42C14C0FdE7'; +const ALB_ADDRESS = '0x1dd2d631c92b1aCdFCDd51A0F7145A50130050C4'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { + return { balances: {} }; + } + + const tvl = await uniswapV2.getTvl( + V2_FACTORY_ADDRESS, + block, + chain, + provider, + web3, + ); + + const tokenBalances = await util.getTokenBalancesOfEachHolder( + [ + '0x52eaecac2402633d98b95213d0b473e069d86590', + '0x365c6d588e8611125De3bEA5B9280C304FA54113', + ], + [ALB_ADDRESS], + block, + chain, + web3, + ); + + formatter.sumMultiBalanceOf(tvl.balances, tokenBalances); + formatter.convertBalancesToFixed(tvl.balances); + + return { balances: tvl.balances, poolBalances: tvl.poolBalances }; +} + +export { tvl }; diff --git a/src/factory/providers/base/balancer/index.ts b/src/factory/providers/base/balancer/index.ts index 4fd8ba06..d2d35955 100644 --- a/src/factory/providers/base/balancer/index.ts +++ b/src/factory/providers/base/balancer/index.ts @@ -29,7 +29,9 @@ const POOLS_QUERY = gql` `; async function tvl(params: ITvlParams): Promise> { - const { block, chain, provider, web3 } = params; + const block = params.block - 100; + const { chain, provider, web3 } = params; + if (block < START_BLOCK) { return {}; } diff --git a/src/factory/providers/base/compound/index.ts b/src/factory/providers/base/compound/index.ts index 5c75df49..c43f9cd8 100644 --- a/src/factory/providers/base/compound/index.ts +++ b/src/factory/providers/base/compound/index.ts @@ -4,8 +4,9 @@ import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; import { request, gql } from 'graphql-request'; const START_BLOCK = 2650000; -const COMPOUND_V3_GRAPHQL_API = - 'https://api.thegraph.com/subgraphs/name/messari/compound-v3-base'; +const THE_GRAPH_API_KEY = process.env?.THE_GRAPH_API_KEY; +const COMPOUND_V3_GRAPHQL_API = `https://gateway-arbitrum.network.thegraph.com/api/${THE_GRAPH_API_KEY}/subgraphs/id/99XPkR9F1exRDdCNyfXrCfEon4K34YoTDn6dgXKmxC72`; + const V3_MARKETS = gql` query getMarkets($block: Int) { markets( @@ -38,7 +39,8 @@ async function addV3MarketBalances(block, balances) { } async function tvl(params: ITvlParams): Promise> { - const { block } = params; + let { block } = params; + block = block - 100; if (block < START_BLOCK) { return { balances: {} }; } diff --git a/src/factory/providers/base/fluid/index.ts b/src/factory/providers/base/fluid/index.ts new file mode 100644 index 00000000..1583d5cf --- /dev/null +++ b/src/factory/providers/base/fluid/index.ts @@ -0,0 +1,49 @@ +import util from '../../../../util/blockchainUtil'; +import FLUID_LIQUIDITY_RESOLVER_ABI from './../../../../constants/abi/fluidLiquidityResolverAbi.json'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import formatter from '../../../../util/formatter'; + +const FLUID_LIQUIDITY_RESOLVER_ADDRESS = + '0x35A915336e2b3349FA94c133491b915eD3D3b0cd'; +const FLUID_LIQUIDITY_PROXY_ADDRESS = + '0x52aa899454998be5b000ad077a46bbe360f4e497'; +const START_BLOCK = 17391473; +const ETH_ADDRESS = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { + return { balances: {} }; + } + + const listedTokens = await util.executeCall( + FLUID_LIQUIDITY_RESOLVER_ADDRESS, + FLUID_LIQUIDITY_RESOLVER_ABI, + 'listedTokens', + [], + block, + chain, + web3, + ); + + const balances = { + [util.ZERO_ADDRESS]: await web3.eth.getBalance( + FLUID_LIQUIDITY_PROXY_ADDRESS, + block, + ), + }; + + const tokenBalances = await util.getTokenBalances( + FLUID_LIQUIDITY_PROXY_ADDRESS, + listedTokens.filter((token: any) => token.token !== ETH_ADDRESS), + block, + chain, + web3, + ); + + formatter.sumMultiBalanceOf(balances, tokenBalances); + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/base/morpho/index.ts b/src/factory/providers/base/morpho/index.ts new file mode 100644 index 00000000..cd0f8127 --- /dev/null +++ b/src/factory/providers/base/morpho/index.ts @@ -0,0 +1,69 @@ +import formatter from '../../../../util/formatter'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import util from '../../../../util/blockchainUtil'; +import basicUtil from '../../../../util/basicUtil'; +import blockchainUtil from '../../../../util/blockchainUtil'; + +const START_BLOCK = 13977148; +const FACTORY_ADDRESS = '0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb'; +const BLOCK_LIMIT = 10000; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + const balances = {}; + if (block < START_BLOCK) { + return { balances }; + } + + let cache: { + start: number; + tokens: string[]; + } = { start: START_BLOCK, tokens: [] }; + try { + cache = await basicUtil.readFromCache('cache.json', chain, provider); + } catch {} + + for ( + let i = Math.max(cache.start, START_BLOCK); + i < block; + i += BLOCK_LIMIT + ) { + const logs = await util.getLogs( + i, + Math.min(i + BLOCK_LIMIT - 1, block), + '0xac4b2400f169220b0c0afdde7a0b32e775ba727ea1cb30b35f935cdaab8683ac', + FACTORY_ADDRESS, + web3, + ); + + logs.output.forEach((log) => { + const firstAddress = `0x${log.data.substring(26, 66)}`; + const secondAddress = `0x${log.data.substring(90, 130)}`; + + if (!cache.tokens.includes(firstAddress)) { + cache.tokens.push(firstAddress); + } + if (!cache.tokens.includes(secondAddress)) { + cache.tokens.push(secondAddress); + } + + cache.start = i += BLOCK_LIMIT; + basicUtil.saveIntoCache(cache, 'cache.json', chain, provider); + }); + } + + const tokenBalances = await blockchainUtil.getTokenBalances( + FACTORY_ADDRESS, + cache.tokens, + block, + chain, + web3, + ); + formatter.sumMultiBalanceOf(balances, tokenBalances); + + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/base/radiant/index.ts b/src/factory/providers/base/radiant/index.ts new file mode 100644 index 00000000..c0774de0 --- /dev/null +++ b/src/factory/providers/base/radiant/index.ts @@ -0,0 +1,97 @@ +import formatter from '../../../../util/formatter'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import util from '../../../../util/blockchainUtil'; +import abi from '../../polygon/aave/abi.json'; +import BigNumber from 'bignumber.js'; + +const START_BLOCK = 14597137; +const REGISTERY_V2 = '0x3eAF348Cf1fEC09C0f8d4f52AD3B8D894206b724'; + +async function balanceOfRegisteredAddress(register, params) { + const { block, chain, provider, web3 } = params; + const providerList = await util.executeCall( + register, + abi, + 'getAddressesProvidersList', + [], + block, + chain, + web3, + ); + const helpers = await util.executeCallOfMultiTargets( + providerList, + abi, + 'getAddress', + ['0x0100000000000000000000000000000000000000000000000000000000000000'], + block, + chain, + web3, + ); + const atokensInfos = await util.executeCallOfMultiTargets( + helpers, + abi, + 'getAllATokens', + [], + block, + chain, + web3, + ); + let atokens = []; + + atokensInfos.forEach((infos) => { + atokens = atokens.concat( + infos.map( + (info) => + info.tokenAddress?.toLowerCase() || info.split(',')[1]?.toLowerCase(), + ), + ); + }); + const pools = {}; + await Promise.all( + atokens.map((address) => getUnderlyings(address, web3, pools)), + ); + + const results = await util.executeMultiCallsOfMultiTargets( + atokens.map((address) => pools[address]), + abi, + 'balanceOf', + atokens.map((address) => [address]), + block, + chain, + web3, + ); + + const balanceResults = {}; + results.forEach((result, index) => { + const balance = BigNumber(result || 0); + if (balance.isGreaterThan(0)) { + balanceResults[pools[atokens[index]]] = balance; + } + }); + return balanceResults; +} + +async function getUnderlyings(address, web3, pools) { + try { + if (!pools[address]) { + const contract = new web3.eth.Contract(abi, address); + const underlying = await contract.methods + .UNDERLYING_ASSET_ADDRESS() + .call(); + pools[address.toLowerCase()] = underlying.toLowerCase(); + } + } catch {} +} + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { + return {}; + } + + const balances = await balanceOfRegisteredAddress(REGISTERY_V2, params); + formatter.convertBalancesToFixed(balances); + + return { balances }; +} +export { tvl }; diff --git a/src/factory/providers/base/stargate/data.json b/src/factory/providers/base/stargate/data.json deleted file mode 100644 index c4a7502e..00000000 --- a/src/factory/providers/base/stargate/data.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "address": "0xe3b53af74a4bf62ae5511055290838050bf764df", - "name": "Stargate Token", - "symbol": "STG", - "decimals": 18, - "logo": "https://assets.coingecko.com/coins/images/24413/small/STG_LOGO.png" -} \ No newline at end of file diff --git a/src/factory/providers/base/stargate/index.ts b/src/factory/providers/base/stargate/index.ts index 074f4572..16c5cba8 100644 --- a/src/factory/providers/base/stargate/index.ts +++ b/src/factory/providers/base/stargate/index.ts @@ -1,9 +1,10 @@ import util from '../../../../util/blockchainUtil'; -import ABI from './abi.json'; +import ABI from '../../../../constants/abi/stargateV1Abi.json'; import CONSTANTS from '../../../../constants/contracts.json'; import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; import basicUtil from '../../../../util/basicUtil'; import formatter from '../../../../util/formatter'; +import stargateV2 from '../../../../util/calculators/stargateV2'; const ROUTER = '0x45f1A95A4D3f3836523F5c83673c797f4d4d263B'; const BASE_TOKENS = { @@ -94,6 +95,10 @@ async function tvl(params: ITvlParams): Promise> { const balances = {}; formatter.sumMultiBalanceOf(balances, tokenBalances); + + const v2TokenBalances = await stargateV2.getV2Tvl(chain, block, web3); + formatter.sumMultiBalanceOf(balances, v2TokenBalances); + formatter.convertBalancesToFixed(balances); return { balances }; diff --git a/src/factory/providers/base/sushiswap/index.ts b/src/factory/providers/base/sushiswap/index.ts new file mode 100644 index 00000000..5a443918 --- /dev/null +++ b/src/factory/providers/base/sushiswap/index.ts @@ -0,0 +1,28 @@ +import formatter from '../../../../util/formatter'; +import uniswapV2 from '../../../../util/calculators/uniswapV2'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; + +const START_BLOCK = 2631214; +const FACTORY_ADDRESS = '0x71524B4f93c58fcbF659783284E38825f0622859'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + if (block < START_BLOCK) { + return {}; + } + + const { balances, poolBalances } = await uniswapV2.getTvl( + FACTORY_ADDRESS, + block, + chain, + provider, + web3, + ); + + formatter.convertBalancesToFixed(balances); + delete balances['0x7f12d13b34f5f4f0a9449c16bcd42f0da47af200']; // token was migrated to another address + return { balances, poolBalances }; +} + +export { tvl }; diff --git a/src/factory/providers/base/swapbased/index.ts b/src/factory/providers/base/swapbased/index.ts index c0932494..0bd57fb3 100644 --- a/src/factory/providers/base/swapbased/index.ts +++ b/src/factory/providers/base/swapbased/index.ts @@ -46,7 +46,7 @@ async function tvl(params: ITvlParams): Promise> { eventLog = ( await util.getLogs( i, - Math.min(block, i + offset), + Math.min(block, i + offset - 1), '0x91ccaa7a278130b65168c3a0c8d3bcae84cf5e43704342bd3ec0b59e59c036db', V3_FACTORY_ADDRESS, web3, diff --git a/src/factory/providers/base/uniswap/index.ts b/src/factory/providers/base/uniswap/index.ts new file mode 100644 index 00000000..163fe44c --- /dev/null +++ b/src/factory/providers/base/uniswap/index.ts @@ -0,0 +1,56 @@ +import { request, gql } from 'graphql-request'; +import BigNumber from 'bignumber.js'; +import formatter from '../../../../util/formatter'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; + +const START_BLOCK = 6601915; +const QUERY_SIZE = 1000; +const THE_GRAPH_API_KEY = process.env?.THE_GRAPH_API_KEY; +const SUBGRAPH_ENDPOINT = `https://gateway-arbitrum.network.thegraph.com/api/${THE_GRAPH_API_KEY}/subgraphs/id/4jGhpKjW4prWoyt5Bwk1ZHUwdEmNWveJcjEyjoTZWCY9`; +const TOKENS = gql` + query getTokens($id: String!, $block: Int!) { + tokens( + block: { number: $block } + first: ${QUERY_SIZE} + orderBy: id + where: { id_gt: $id tradeVolumeUSD_gt: 10000 } + ) { + id + decimals + totalLiquidity + } + } +`; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { + return {}; + } + const balances = {}; + + let lastId = ''; + while (true) { + const requestResult = await request(SUBGRAPH_ENDPOINT, TOKENS, { + block: block - 100, + id: lastId, + }); + + for (const token of requestResult.tokens) { + balances[token.id.toLowerCase()] = BigNumber( + token.totalLiquidity, + ).shiftedBy(Number(token.decimals)); + } + + if (requestResult.tokens.length < QUERY_SIZE) { + break; + } + + lastId = requestResult.tokens[requestResult.tokens.length - 1].id; + } + + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/base/uniswapv3/index.ts b/src/factory/providers/base/uniswapv3/index.ts index 61282bc2..9f4938a2 100644 --- a/src/factory/providers/base/uniswapv3/index.ts +++ b/src/factory/providers/base/uniswapv3/index.ts @@ -1,25 +1,25 @@ import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; -import formatter from '../../../../util/formatter'; -import uniswapV3 from '../../../../util/calculators/uniswapV3'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; -const START_BLOCK = 3403624; -const THEGRAPTH_ENDPOINT = - 'https://api.thegraph.com/subgraphs/name/lynnshaoyu/uniswap-v3-base'; +const V3_START_BLOCK = 1371680; +const V3_FACTORY_ADDRESS = '0x33128a8fC17869897dcE68Ed026d694621f6FDfD'; async function tvl(params: ITvlParams): Promise> { - const { block, chain, provider } = params; - if (block < START_BLOCK) { + const { block, chain, provider, web3 } = params; + if (block < V3_START_BLOCK) { return { balances: {} }; } - const { balances, poolBalances } = await uniswapV3.getTvlFromSubgraph( - THEGRAPTH_ENDPOINT, + const balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, block, chain, provider, - 100, + web3, ); - formatter.convertBalancesToFixed(balances); - return { balances, poolBalances }; + + return { balances, poolBalances: {} }; } + export { tvl }; diff --git a/src/factory/providers/bsc/listadao/index.ts b/src/factory/providers/bsc/listadao/index.ts new file mode 100644 index 00000000..3aa33b91 --- /dev/null +++ b/src/factory/providers/bsc/listadao/index.ts @@ -0,0 +1,86 @@ +import BigNumber from 'bignumber.js'; +import util from '../../../../util/blockchainUtil'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import formatter from '../../../../util/formatter'; + +const stakedListaBnb = '0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B'; +const listaStakeManager = '0x1adB950d8bB3dA4bE104211D5AB038628e477fE6'; +const wbnb = '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + const balances = {}; + + const stakedListaBnbBalance = await util + .getTotalSupply(stakedListaBnb, block, web3) + .then((res) => res.totalSupply); + + balances[wbnb] = await util.executeCall( + listaStakeManager, + [ + { + inputs: [ + { + internalType: 'uint256', + name: '_amountInSlisBnb', + type: 'uint256', + }, + ], + name: 'convertSnBnbToBnb', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + ], + 'convertSnBnbToBnb', + [new BigNumber(stakedListaBnbBalance).toFixed()], + block, + chain, + web3, + ); + + const tokenBalances = await util.getTokenBalancesOfHolders( + [ + '0x986b40C2618fF295a49AC442c5ec40febB26CC54', + '0x6F28FeC449dbd2056b76ac666350Af8773E03873', + '0x91e49983598685DD5ACAc90CEb4061A772f6E5Ae', + '0xA230805C28121cc97B348f8209c79BEBEa3839C0', + '0xf45C3b619Ee86F653805E007fE211B7e930E0b3B', + '0xA230805C28121cc97B348f8209c79BEBEa3839C0', + '0xad9eAAe95617c39019aCC42301a1dCa4ea5b6f65', + '0xd7E33948e2a43e7C1ec2F19937bf5bf8BbF9BaE8', + '0x2367f2Da6fd39De6944218CC9EC706BCdc9a6918', + '0x876cd9a380Ee7712129b52f8293F6f06056c3104', + ], + [ + wbnb, + '0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B', + '0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B', + '0x2170ed0880ac9a755fd29b2688956bd959f933f8', + '0xa2E3356610840701BDf5611a53974510Ae27E2e1', + '0xa2E3356610840701BDf5611a53974510Ae27E2e1', + '0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c', + '0x2416092f143378750bb29b79eD961ab195CcEea5', + '0x04C0599Ae5A44757c0af6F9eC3b93da8976c150A', + '0x80137510979822322193FC997d400D5A6C747bf7', + ], + block, + chain, + web3, + ); + + formatter.sumMultiBalanceOf(balances, tokenBalances, chain, provider); + balances['bnb'] = balances[wbnb]; + delete balances[wbnb]; + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/bsc/pancakeswapv3/index.ts b/src/factory/providers/bsc/pancakeswapv3/index.ts index 39e367a6..7a1c7b96 100644 --- a/src/factory/providers/bsc/pancakeswapv3/index.ts +++ b/src/factory/providers/bsc/pancakeswapv3/index.ts @@ -2,11 +2,12 @@ import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; import pancakeswapV3subgraph from '../../../../util/calculators/pancakeswapV3subgraph'; const START_BLOCK = 26956207; -const THEGRAPTH_ENDPOINT = - 'https://api.thegraph.com/subgraphs/name/messari/pancakeswap-v3-bsc'; +const THE_GRAPH_API_KEY = process.env?.THE_GRAPH_API_KEY; +const THEGRAPTH_ENDPOINT = `https://gateway-arbitrum.network.thegraph.com/api/${THE_GRAPH_API_KEY}/subgraphs/id/A1BC1hzDsK4NTeXBpKQnDBphngpYZAwDUF7dEBfa3jHK`; async function tvl(params: ITvlParams): Promise> { - const { block, chain, provider, web3 } = params; + const { chain, provider, web3 } = params; + const block = params.block - 100; if (block < START_BLOCK) { return { balances: {} }; diff --git a/src/factory/providers/bsc/prdt/index.ts b/src/factory/providers/bsc/prdt/index.ts new file mode 100644 index 00000000..765bf1cf --- /dev/null +++ b/src/factory/providers/bsc/prdt/index.ts @@ -0,0 +1,54 @@ +import util from '../../../../util/blockchainUtil'; +import formatter from '../../../../util/formatter'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import BigNumber from 'bignumber.js'; + +const contracts = [ + '0x31B8A8Ee92961524fD7839DC438fd631D34b49C6', + '0x00199E444155f6a06d74CF36315419d39b874f5c', + '0xE39A6a119E154252214B369283298CDF5396026B', + '0x3Df33217F0f82c99fF3ff448512F22cEf39CC208', + '0x599974D3f2948b50545Fb5aa77C9e0bddc230ADE', + '0x22dB94d719659d7861612E0f43EE28C9FF9909C7', + '0x49eFb44831aD88A9cFFB183d48C0c60bF4028da8', +]; + +const TOKENS = [ + '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d', + '0x55d398326f99059fF775485246999027B3197955', + '0x2170Ed0880ac9A755fd29B2688956BD959F933F8', +]; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + if (block < 30325393) { + return {}; + } + + const balances = {}; + let totalBnbBalance = new BigNumber(0); + + for (const contract of contracts) { + const tokenBalances = await util.getTokenBalances( + contract, + TOKENS, + block, + chain, + web3, + ); + + const bnbBalance = await web3.eth.getBalance(contract, block); + + formatter.sumMultiBalanceOf(balances, tokenBalances, chain, provider); + totalBnbBalance = totalBnbBalance.plus(bnbBalance); + } + + balances['bnb'] = totalBnbBalance.toString(); + + formatter.convertBalancesToFixed(balances); + + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/bsc/radiant/index.ts b/src/factory/providers/bsc/radiant/index.ts new file mode 100644 index 00000000..31188f3a --- /dev/null +++ b/src/factory/providers/bsc/radiant/index.ts @@ -0,0 +1,97 @@ +import formatter from '../../../../util/formatter'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import util from '../../../../util/blockchainUtil'; +import abi from '../../polygon/aave/abi.json'; +import BigNumber from 'bignumber.js'; + +const START_BLOCK = 26831935; +const REGISTERY_V2 = '0x16Cd518fE9db541feA810b3091fBee6829a9B0Ce'; + +async function balanceOfRegisteredAddress(register, params) { + const { block, chain, provider, web3 } = params; + const providerList = await util.executeCall( + register, + abi, + 'getAddressesProvidersList', + [], + block, + chain, + web3, + ); + const helpers = await util.executeCallOfMultiTargets( + providerList, + abi, + 'getAddress', + ['0x0100000000000000000000000000000000000000000000000000000000000000'], + block, + chain, + web3, + ); + const atokensInfos = await util.executeCallOfMultiTargets( + helpers, + abi, + 'getAllATokens', + [], + block, + chain, + web3, + ); + let atokens = []; + + atokensInfos.forEach((infos) => { + atokens = atokens.concat( + infos.map( + (info) => + info.tokenAddress?.toLowerCase() || info.split(',')[1]?.toLowerCase(), + ), + ); + }); + const pools = {}; + await Promise.all( + atokens.map((address) => getUnderlyings(address, web3, pools)), + ); + + const results = await util.executeMultiCallsOfMultiTargets( + atokens.map((address) => pools[address]), + abi, + 'balanceOf', + atokens.map((address) => [address]), + block, + chain, + web3, + ); + + const balanceResults = {}; + results.forEach((result, index) => { + const balance = BigNumber(result || 0); + if (balance.isGreaterThan(0)) { + balanceResults[pools[atokens[index]]] = balance; + } + }); + return balanceResults; +} + +async function getUnderlyings(address, web3, pools) { + try { + if (!pools[address]) { + const contract = new web3.eth.Contract(abi, address); + const underlying = await contract.methods + .UNDERLYING_ASSET_ADDRESS() + .call(); + pools[address.toLowerCase()] = underlying.toLowerCase(); + } + } catch {} +} + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { + return {}; + } + + const balances = await balanceOfRegisteredAddress(REGISTERY_V2, params); + formatter.convertBalancesToFixed(balances); + + return { balances }; +} +export { tvl }; diff --git a/src/factory/providers/bsc/stargate/index.ts b/src/factory/providers/bsc/stargate/index.ts new file mode 100644 index 00000000..61f00000 --- /dev/null +++ b/src/factory/providers/bsc/stargate/index.ts @@ -0,0 +1,94 @@ +import util from '../../../../util/blockchainUtil'; +import formatter from '../../../../util/formatter'; +import basicUtil from '../../../../util/basicUtil'; +import ABI from '../../../../constants/abi/stargateV1Abi.json'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import stargateV2 from '../../../../util/calculators/stargateV2'; + +const ROUTER = '0x4a364f8c717cAAD9A442737Eb7b8A55cc6cf18D8'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + let store = { + pools: [], + tokens: {}, + }; + try { + store = await basicUtil.readFromCache('cache/store.json', chain, provider); + } catch {} + + const factory = await util.executeCall( + ROUTER, + ABI, + 'factory', + [], + block, + chain, + web3, + ); + const allPoolsLength = await util.executeCall( + factory, + ABI, + 'allPoolsLength', + [], + block, + chain, + web3, + ); + + if (store.pools.length < allPoolsLength) { + const newPools = await util.executeMultiCallsOfTarget( + factory, + ABI, + 'allPools', + Array.from( + { length: allPoolsLength - store.pools.length }, + (_, i) => store.pools.length + i, + ), + block, + chain, + web3, + ); + const poolTokens = await util.executeCallOfMultiTargets( + newPools, + ABI, + 'token', + [], + block, + chain, + web3, + ); + + for (const index in newPools) { + if (newPools[index] && poolTokens[index]) { + store.pools.push(newPools[index]); + store.tokens[newPools[index]] = poolTokens[index]; + } else { + break; + } + } + + await basicUtil.saveIntoCache(store, 'cache/store.json', chain, provider); + } + + const tokenBalances = await util.getTokenBalancesOfHolders( + Object.keys(store.tokens), + Object.values(store.tokens), + block, + chain, + web3, + ); + + const balances = {}; + + formatter.sumMultiBalanceOf(balances, tokenBalances); + + const v2TokenBalances = await stargateV2.getV2Tvl(chain, block, web3); + formatter.sumMultiBalanceOf(balances, v2TokenBalances); + + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/bsc/sushiswap/data.json b/src/factory/providers/bsc/sushiswap/data.json deleted file mode 100644 index d9e2c535..00000000 --- a/src/factory/providers/bsc/sushiswap/data.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "address": "0x947950bcc74888a40ffa2593c5798f11fc9124c4", - "name": "SushiToken", - "symbol": "SUSHI", - "decimals": 18, - "logo": "https://user-dashboard.s3.us-east-2.amazonaws.com/token_images/prod/35/0x947950bcc74888a40ffa2593c5798f11fc9124c4_large.png" -} \ No newline at end of file diff --git a/src/factory/providers/bsc/sushiswap/index.ts b/src/factory/providers/bsc/sushiswap/index.ts index 3c85ad40..9576d6e2 100644 --- a/src/factory/providers/bsc/sushiswap/index.ts +++ b/src/factory/providers/bsc/sushiswap/index.ts @@ -4,12 +4,10 @@ import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; const START_BLOCK = 5205069; const FACTORY_ADDRESS = '0xc35DADB65012eC5796536bD9864eD8773aBc74C4'; -const GRAPHQL_API = - 'https://api.thegraph.com/subgraphs/name/sushiswap/bsc-exchange'; -const QUERY_SIZE = 400; async function tvl(params: ITvlParams): Promise> { const { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { return {}; } @@ -27,28 +25,4 @@ async function tvl(params: ITvlParams): Promise> { return { balances, poolBalances }; } -async function getPoolVolumes(pools, priorBlockNumber) { - const poolVolumes = await uniswapV2.getPoolVolumes( - GRAPHQL_API, - QUERY_SIZE, - pools, - priorBlockNumber, - null, - ); - - return poolVolumes; -} - -async function getTokenVolumes(tokens, priorBlockNumber) { - const tokenVolumes = await uniswapV2.getTokenVolumes( - GRAPHQL_API, - QUERY_SIZE, - tokens, - priorBlockNumber, - null, - ); - - return tokenVolumes; -} - -export { tvl, getPoolVolumes, getTokenVolumes }; +export { tvl }; diff --git a/src/factory/providers/bsc/sushiswapv3/index.ts b/src/factory/providers/bsc/sushiswapv3/index.ts new file mode 100644 index 00000000..d6dcc750 --- /dev/null +++ b/src/factory/providers/bsc/sushiswapv3/index.ts @@ -0,0 +1,25 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; + +const V3_START_BLOCK = 26976538; +const V3_FACTORY_ADDRESS = '0x126555dd55a39328F69400d6aE4F782Bd4C34ABb'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < V3_START_BLOCK) { + return { balances: {} }; + } + + const balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, + block, + chain, + provider, + web3, + ); + + return { balances, poolBalances: {} }; +} + +export { tvl }; diff --git a/src/factory/providers/bsc/uniswapv3/index.ts b/src/factory/providers/bsc/uniswapv3/index.ts index c7287459..67ed3058 100644 --- a/src/factory/providers/bsc/uniswapv3/index.ts +++ b/src/factory/providers/bsc/uniswapv3/index.ts @@ -1,25 +1,25 @@ import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; -import formatter from '../../../../util/formatter'; -import uniswapV3 from '../../../../util/calculators/uniswapV3'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; -const START_BLOCK = 0; -const THEGRAPTH_ENDPOINT = - 'https://api.thegraph.com/subgraphs/name/revert-finance/uniswap-v3-bnb'; +const V3_START_BLOCK = 26324014; +const V3_FACTORY_ADDRESS = '0xdB1d10011AD0Ff90774D0C6Bb92e5C5c8b4461F7'; async function tvl(params: ITvlParams): Promise> { - const { block, chain, provider } = params; - if (block < START_BLOCK) { + const { block, chain, provider, web3 } = params; + if (block < V3_START_BLOCK) { return { balances: {} }; } - const { balances, poolBalances } = await uniswapV3.getTvlFromSubgraph( - THEGRAPTH_ENDPOINT, + const balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, block, chain, provider, - 100, + web3, ); - formatter.convertBalancesToFixed(balances); - return { balances, poolBalances }; + + return { balances, poolBalances: {} }; } + export { tvl }; diff --git a/src/factory/providers/bttc/spookyswap/index.ts b/src/factory/providers/bttc/spookyswap/index.ts new file mode 100644 index 00000000..eab46104 --- /dev/null +++ b/src/factory/providers/bttc/spookyswap/index.ts @@ -0,0 +1,323 @@ +import formatter from '../../../../util/formatter'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import BigNumber from 'bignumber.js'; +import { PromisePool } from '@supercharge/promise-pool'; +import Web3 from 'web3'; +import { AbiItem } from 'web3-utils'; +import FACTORY_ABI from '../../../../constants/abi/factory.json'; +import PAIR_ABI from '../../../../constants/abi/uni.json'; +import RESERVES_ABI from '../../../../constants/abi/uniReserves.json'; +import basicUtil from '../../../../util/basicUtil'; +import util from '../../../../util/blockchainUtil'; +import { log } from '../../../../util/logger/logger'; + +const START_BLOCK = 23534368; +const FACTORY_ADDRESS = '0xee4bc42157cf65291ba2fe839ae127e3cc76f741'; +const BTT_ADDRESS = '0x0000000000000000000000000000000000001010'; +const WBTT_ADDRESS = '0x23181f21dea5936e24163ffaba4ea3b316b57f3c'; + +async function getTvl( + factoryAddress: string, + block: number, + chain: string, + provider: string, + web3: Web3, + usePoolMethods = false, +): Promise { + const balances = {}; + const poolBalances = {}; + + let _pairs = []; + let _token01 = {}; + try { + _pairs = await basicUtil.readFromCache( + `cache/${factoryAddress.toLowerCase()}_pairs.json`, + chain, + provider, + ); + } catch { + try { + _pairs = await basicUtil.readFromCache( + 'cache/pairs.json', + chain, + provider, + ); + } catch {} + } + try { + _token01 = await basicUtil.readFromCache( + `cache/${factoryAddress.toLowerCase()}_token01.json`, + chain, + provider, + ); + } catch { + try { + _token01 = await basicUtil.readFromCache( + 'cache/token01.json', + chain, + provider, + ); + } catch {} + } + const contract = new web3.eth.Contract( + FACTORY_ABI as AbiItem[], + factoryAddress, + ); + + let len = 0; + + try { + if (!usePoolMethods) { + len = await contract.methods.allPairsLength().call(null, block); + } else { + len = await contract.methods.allPoolsLength().call(null, block); + } + len = Number(len); + } catch (e) { + console.log(e); + return; + } + + log.info({ + message: `Pair counts: ${len}`, + endpoint: 'getTvl', + }); + + let poolInfos = _pairs; + const pairLength = _pairs.length; + + for (let start = pairLength; start < len; start += 1) { + let pInfos = []; + const end = Math.min(start + 1, len); + log.info({ + message: `Getting Pairs from ${start} to ${end}`, + endpoint: 'getTvl', + }); + for (let i = start; i < end; i++) { + if (!usePoolMethods) { + pInfos.push(contract.methods.allPairs(i).call()); + } else { + pInfos.push(contract.methods.allPools(i).call()); + } + } + try { + pInfos = await Promise.all(pInfos); + pInfos.forEach((info) => poolInfos.push(info)); + } catch (e) { + log.error({ + message: e?.message || '', + stack: e?.stack || '', + detail: `Error: getTvl of ${chain}/${provider}`, + endpoint: 'getTvl', + }); + break; + } + } + + if (pairLength < len) { + await basicUtil.saveIntoCache( + poolInfos, + `cache/${factoryAddress.toLowerCase()}_pairs.json`, + chain, + provider, + ); + } + + poolInfos = poolInfos.slice(0, len); + + const token01Infos = _token01; + const newPools = poolInfos.filter((info) => !_token01[info]); + const newPoolLength = newPools.length; + for (let start = 0; start < newPoolLength; start += 1) { + const end = Math.min(newPoolLength, start + 1); + log.info({ + message: `Getting Token01 from ${start} to ${end}`, + endpoint: 'getTvl', + }); + const subPools = newPools.slice(start, end); + try { + const tokens0 = await util.executeCallOfMultiTargets( + subPools, + PAIR_ABI, + 'token0', + [], + block, + chain, + web3, + ); + const tokens1 = await util.executeCallOfMultiTargets( + subPools, + PAIR_ABI, + 'token1', + [], + block, + chain, + web3, + ); + subPools.forEach((subPool, index) => { + token01Infos[subPool] = {}; + token01Infos[subPool].token0 = tokens0[index]; + token01Infos[subPool].token1 = tokens1[index]; + }); + } catch (e) { + log.error({ + message: e?.message || '', + stack: e?.stack || '', + detail: `Getting Token01 got issue at ${start}`, + endpoint: 'getTvl', + }); + } + } + + await basicUtil.saveIntoCache( + token01Infos, + `cache/${factoryAddress.toLowerCase()}_token01.json`, + chain, + provider, + ); + console.time('Getting PairInfo'); + for (let first = 0; first < poolInfos.length; first += 1) { + const last = Math.min(poolInfos.length, first + 1); + log.info({ + message: `Getting PairInfo from ${first} to ${last}`, + endpoint: 'getTvl', + }); + const getMultiPoolsReserves = []; + for (let start = first; start < last; start += 50) { + const end = Math.min(last, start + 50); + getMultiPoolsReserves.push( + getPoolsReserves( + poolInfos.slice(start, end), + block, + chain, + web3, + provider, + ), + ); + } + + const { results: poolReserves } = await PromisePool.withConcurrency(1) + .for(getMultiPoolsReserves) + .process(async (data) => { + return data; + }); + + poolReserves.forEach((reserves) => { + reserves.forEach((reserve) => { + poolBalances[reserve.pool_address.toLowerCase()] = { + tokens: [ + token01Infos[reserve.pool_address].token0?.toLowerCase(), + token01Infos[reserve.pool_address].token1?.toLowerCase(), + ], + balances: [reserve.reserve0, reserve.reserve1], + }; + + if ( + token01Infos[reserve.pool_address] && + token01Infos[reserve.pool_address].token0 && + reserve.reserve0 + ) { + const token = + token01Infos[reserve.pool_address]?.token0?.toLowerCase(); + if (!balances[token]) { + balances[token] = BigNumber(0); + } + balances[token] = BigNumber(balances[token]).plus( + BigNumber(reserve.reserve0.toString()), + ); + } + if ( + token01Infos[reserve.pool_address] && + token01Infos[reserve.pool_address].token1 && + reserve.reserve1 + ) { + const token = + token01Infos[reserve.pool_address]?.token1?.toLowerCase(); + if (!balances[token]) { + balances[token] = BigNumber(0); + } + balances[token] = BigNumber(balances[token]).plus( + BigNumber(reserve.reserve1.toString()), + ); + } + }); + }); + } + console.timeEnd('Getting PairInfo'); + return { balances, poolBalances }; +} + +async function getPoolsReserves(pInfos, block, chain, web3, provider) { + let poolReserves = []; + try { + poolReserves = await Promise.all( + pInfos.map((pool) => getReserves(pool, block, web3, chain, provider)), + ); + + return poolReserves; + } catch (e) { + log.error({ + message: e?.message || '', + stack: e?.stack || '', + detail: `Error: out getPoolsReserves chain: ${chain} provider: ${provider}`, + endpoint: 'getPoolsReserves', + }); + } + return poolReserves; +} + +async function getReserves(address, block, web3, chain, provider) { + try { + const contract = new web3.eth.Contract(PAIR_ABI, address); + const reserves = await contract.methods.getReserves().call(null, block); + return { + pool_address: address, + reserve0: BigNumber(reserves._reserve0.toString()), + reserve1: BigNumber(reserves._reserve1.toString()), + }; + } catch (e) { + try { + const contract = new web3.eth.Contract(RESERVES_ABI, address); + const reserves = await contract.methods.getReserves().call(null, block); + return { + pool_address: address, + reserve0: BigNumber(reserves._reserve0.toString()), + reserve1: BigNumber(reserves._reserve1.toString()), + }; + } catch (e) { + log.error({ + message: e?.message || '', + stack: e?.stack || '', + detail: `Error: uniswapV2.getReserves chain: ${chain} provider: ${provider}`, + endpoint: 'getReserves', + }); + } + } + return {}; +} +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + if (block < START_BLOCK) { + return {}; + } + + const { balances, poolBalances } = await getTvl( + FACTORY_ADDRESS, + block, + chain, + provider, + web3, + ); + + formatter.convertBalancesToFixed(balances); + + if (balances[WBTT_ADDRESS]) { + balances[BTT_ADDRESS] = balances[WBTT_ADDRESS]; + delete balances[WBTT_ADDRESS]; + } + + return { balances, poolBalances }; +} + +export { tvl }; diff --git a/src/factory/providers/bttc/sushiswap/index.ts b/src/factory/providers/bttc/sushiswap/index.ts new file mode 100644 index 00000000..44d70e59 --- /dev/null +++ b/src/factory/providers/bttc/sushiswap/index.ts @@ -0,0 +1,323 @@ +import formatter from '../../../../util/formatter'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import BigNumber from 'bignumber.js'; +import { PromisePool } from '@supercharge/promise-pool'; +import Web3 from 'web3'; +import { AbiItem } from 'web3-utils'; +import FACTORY_ABI from '../../../../constants/abi/factory.json'; +import PAIR_ABI from '../../../../constants/abi/uni.json'; +import RESERVES_ABI from '../../../../constants/abi/uniReserves.json'; +import basicUtil from '../../../../util/basicUtil'; +import util from '../../../../util/blockchainUtil'; +import { log } from '../../../../util/logger/logger'; + +const START_BLOCK = 28215551; +const FACTORY_ADDRESS = '0xB45e53277a7e0F1D35f2a77160e91e25507f1763'; +const BTT_ADDRESS = '0x0000000000000000000000000000000000001010'; +const WBTT_ADDRESS = '0x23181f21dea5936e24163ffaba4ea3b316b57f3c'; + +async function getTvl( + factoryAddress: string, + block: number, + chain: string, + provider: string, + web3: Web3, + usePoolMethods = false, +): Promise { + const balances = {}; + const poolBalances = {}; + + let _pairs = []; + let _token01 = {}; + try { + _pairs = await basicUtil.readFromCache( + `cache/${factoryAddress.toLowerCase()}_pairs.json`, + chain, + provider, + ); + } catch { + try { + _pairs = await basicUtil.readFromCache( + 'cache/pairs.json', + chain, + provider, + ); + } catch {} + } + try { + _token01 = await basicUtil.readFromCache( + `cache/${factoryAddress.toLowerCase()}_token01.json`, + chain, + provider, + ); + } catch { + try { + _token01 = await basicUtil.readFromCache( + 'cache/token01.json', + chain, + provider, + ); + } catch {} + } + const contract = new web3.eth.Contract( + FACTORY_ABI as AbiItem[], + factoryAddress, + ); + + let len = 0; + + try { + if (!usePoolMethods) { + len = await contract.methods.allPairsLength().call(null, block); + } else { + len = await contract.methods.allPoolsLength().call(null, block); + } + len = Number(len); + } catch (e) { + console.log(e); + return; + } + + log.info({ + message: `Pair counts: ${len}`, + endpoint: 'getTvl', + }); + + let poolInfos = _pairs; + const pairLength = _pairs.length; + + for (let start = pairLength; start < len; start += 1) { + let pInfos = []; + const end = Math.min(start + 1, len); + log.info({ + message: `Getting Pairs from ${start} to ${end}`, + endpoint: 'getTvl', + }); + for (let i = start; i < end; i++) { + if (!usePoolMethods) { + pInfos.push(contract.methods.allPairs(i).call()); + } else { + pInfos.push(contract.methods.allPools(i).call()); + } + } + try { + pInfos = await Promise.all(pInfos); + pInfos.forEach((info) => poolInfos.push(info)); + } catch (e) { + log.error({ + message: e?.message || '', + stack: e?.stack || '', + detail: `Error: getTvl of ${chain}/${provider}`, + endpoint: 'getTvl', + }); + break; + } + } + + if (pairLength < len) { + await basicUtil.saveIntoCache( + poolInfos, + `cache/${factoryAddress.toLowerCase()}_pairs.json`, + chain, + provider, + ); + } + + poolInfos = poolInfos.slice(0, len); + + const token01Infos = _token01; + const newPools = poolInfos.filter((info) => !_token01[info]); + const newPoolLength = newPools.length; + for (let start = 0; start < newPoolLength; start += 1) { + const end = Math.min(newPoolLength, start + 1); + log.info({ + message: `Getting Token01 from ${start} to ${end}`, + endpoint: 'getTvl', + }); + const subPools = newPools.slice(start, end); + try { + const tokens0 = await util.executeCallOfMultiTargets( + subPools, + PAIR_ABI, + 'token0', + [], + block, + chain, + web3, + ); + const tokens1 = await util.executeCallOfMultiTargets( + subPools, + PAIR_ABI, + 'token1', + [], + block, + chain, + web3, + ); + subPools.forEach((subPool, index) => { + token01Infos[subPool] = {}; + token01Infos[subPool].token0 = tokens0[index]; + token01Infos[subPool].token1 = tokens1[index]; + }); + } catch (e) { + log.error({ + message: e?.message || '', + stack: e?.stack || '', + detail: `Getting Token01 got issue at ${start}`, + endpoint: 'getTvl', + }); + } + } + + await basicUtil.saveIntoCache( + token01Infos, + `cache/${factoryAddress.toLowerCase()}_token01.json`, + chain, + provider, + ); + console.time('Getting PairInfo'); + for (let first = 0; first < poolInfos.length; first += 1) { + const last = Math.min(poolInfos.length, first + 1); + log.info({ + message: `Getting PairInfo from ${first} to ${last}`, + endpoint: 'getTvl', + }); + const getMultiPoolsReserves = []; + for (let start = first; start < last; start += 50) { + const end = Math.min(last, start + 50); + getMultiPoolsReserves.push( + getPoolsReserves( + poolInfos.slice(start, end), + block, + chain, + web3, + provider, + ), + ); + } + + const { results: poolReserves } = await PromisePool.withConcurrency(1) + .for(getMultiPoolsReserves) + .process(async (data) => { + return data; + }); + + poolReserves.forEach((reserves) => { + reserves.forEach((reserve) => { + poolBalances[reserve.pool_address.toLowerCase()] = { + tokens: [ + token01Infos[reserve.pool_address].token0?.toLowerCase(), + token01Infos[reserve.pool_address].token1?.toLowerCase(), + ], + balances: [reserve.reserve0, reserve.reserve1], + }; + + if ( + token01Infos[reserve.pool_address] && + token01Infos[reserve.pool_address].token0 && + reserve.reserve0 + ) { + const token = + token01Infos[reserve.pool_address]?.token0?.toLowerCase(); + if (!balances[token]) { + balances[token] = BigNumber(0); + } + balances[token] = BigNumber(balances[token]).plus( + BigNumber(reserve.reserve0.toString()), + ); + } + if ( + token01Infos[reserve.pool_address] && + token01Infos[reserve.pool_address].token1 && + reserve.reserve1 + ) { + const token = + token01Infos[reserve.pool_address]?.token1?.toLowerCase(); + if (!balances[token]) { + balances[token] = BigNumber(0); + } + balances[token] = BigNumber(balances[token]).plus( + BigNumber(reserve.reserve1.toString()), + ); + } + }); + }); + } + console.timeEnd('Getting PairInfo'); + return { balances, poolBalances }; +} + +async function getPoolsReserves(pInfos, block, chain, web3, provider) { + let poolReserves = []; + try { + poolReserves = await Promise.all( + pInfos.map((pool) => getReserves(pool, block, web3, chain, provider)), + ); + + return poolReserves; + } catch (e) { + log.error({ + message: e?.message || '', + stack: e?.stack || '', + detail: `Error: out getPoolsReserves chain: ${chain} provider: ${provider}`, + endpoint: 'getPoolsReserves', + }); + } + return poolReserves; +} + +async function getReserves(address, block, web3, chain, provider) { + try { + const contract = new web3.eth.Contract(PAIR_ABI, address); + const reserves = await contract.methods.getReserves().call(null, block); + return { + pool_address: address, + reserve0: BigNumber(reserves._reserve0.toString()), + reserve1: BigNumber(reserves._reserve1.toString()), + }; + } catch (e) { + try { + const contract = new web3.eth.Contract(RESERVES_ABI, address); + const reserves = await contract.methods.getReserves().call(null, block); + return { + pool_address: address, + reserve0: BigNumber(reserves._reserve0.toString()), + reserve1: BigNumber(reserves._reserve1.toString()), + }; + } catch (e) { + log.error({ + message: e?.message || '', + stack: e?.stack || '', + detail: `Error: uniswapV2.getReserves chain: ${chain} provider: ${provider}`, + endpoint: 'getReserves', + }); + } + } + return {}; +} +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + if (block < START_BLOCK) { + return {}; + } + + const { balances, poolBalances } = await getTvl( + FACTORY_ADDRESS, + block, + chain, + provider, + web3, + ); + + formatter.convertBalancesToFixed(balances); + + if (balances[WBTT_ADDRESS]) { + balances[BTT_ADDRESS] = balances[WBTT_ADDRESS]; + delete balances[WBTT_ADDRESS]; + } + + return { balances, poolBalances }; +} + +export { tvl }; diff --git a/src/factory/providers/celo/sushiswap/data.json b/src/factory/providers/celo/sushiswap/data.json deleted file mode 100644 index 5441876a..00000000 --- a/src/factory/providers/celo/sushiswap/data.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "address": "0xd15ec721c2a896512ad29c671997dd68f9593226", - "name": "Sushi", - "symbol": "SUSHI", - "decimals": 18, - "logo": "https://assets.coingecko.com/coins/images/12271/small/512x512_Logo_no_chop.png" -} \ No newline at end of file diff --git a/src/factory/providers/celo/sushiswap/index.ts b/src/factory/providers/celo/sushiswap/index.ts index 943f5497..6ccc3cf3 100644 --- a/src/factory/providers/celo/sushiswap/index.ts +++ b/src/factory/providers/celo/sushiswap/index.ts @@ -1,15 +1,13 @@ -import uniswapV2 from '../../../../util/calculators/uniswapV2'; import formatter from '../../../../util/formatter'; +import uniswapV2 from '../../../../util/calculators/uniswapV2'; import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; const START_BLOCK = 7253488; const FACTORY_ADDRESS = '0xc35DADB65012eC5796536bD9864eD8773aBc74C4'; -const GRAPHQL_API = - 'https://api.thegraph.com/subgraphs/name/sushiswap/celo-exchange'; -const QUERY_SIZE = 400; async function tvl(params: ITvlParams): Promise> { const { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { return {}; } @@ -27,28 +25,4 @@ async function tvl(params: ITvlParams): Promise> { return { balances, poolBalances }; } -async function getPoolVolumes(pools, priorBlockNumber) { - const poolVolumes = await uniswapV2.getPoolVolumes( - GRAPHQL_API, - QUERY_SIZE, - pools, - priorBlockNumber, - null, - ); - - return poolVolumes; -} - -async function getTokenVolumes(tokens, priorBlockNumber) { - const tokenVolumes = await uniswapV2.getTokenVolumes( - GRAPHQL_API, - QUERY_SIZE, - tokens, - priorBlockNumber, - null, - ); - - return tokenVolumes; -} - -export { tvl, getPoolVolumes, getTokenVolumes }; +export { tvl }; diff --git a/src/factory/providers/celo/uniswapv3/index.ts b/src/factory/providers/celo/uniswapv3/index.ts index aed84cb0..e055f9f4 100644 --- a/src/factory/providers/celo/uniswapv3/index.ts +++ b/src/factory/providers/celo/uniswapv3/index.ts @@ -1,26 +1,25 @@ -import uniswapV3 from '../../../../util/calculators/uniswapV3'; -import formatter from '../../../../util/formatter'; import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; -const START_BLOCK = 13916355; -const THEGRAPTH_ENDPOINT = - 'https://api.thegraph.com/subgraphs/name/jesse-sawa/uniswap-celo'; +const V3_START_BLOCK = 13916355; +const V3_FACTORY_ADDRESS = '0xAfE208a311B21f13EF87E33A90049fC17A7acDEc'; async function tvl(params: ITvlParams): Promise> { - const { block, chain, provider } = params; - - if (block < START_BLOCK) { - return {}; + const { block, chain, provider, web3 } = params; + if (block < V3_START_BLOCK) { + return { balances: {} }; } - const { balances, poolBalances } = await uniswapV3.getTvlFromSubgraph( - THEGRAPTH_ENDPOINT, + const balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, block, chain, provider, + web3, ); - formatter.convertBalancesToFixed(balances); - return { balances, poolBalances }; + + return { balances, poolBalances: {} }; } export { tvl }; diff --git a/src/factory/providers/core/glyphexchange/index.ts b/src/factory/providers/core/glyphexchange/index.ts new file mode 100644 index 00000000..b776e8a9 --- /dev/null +++ b/src/factory/providers/core/glyphexchange/index.ts @@ -0,0 +1,45 @@ +import formatter from '../../../../util/formatter'; +import uniswapV2 from '../../../../util/calculators/uniswapV2'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; + +const START_BLOCK = 12515028; +const V3_START_BLOCK = 15770796; +const V2_FACTORY_ADDRESS = '0x3E723C7B6188E8Ef638DB9685Af45c7CB66f77B9'; +const V3_FACTORY_ADDRESS = '0x74EfE55beA4988e7D92D03EFd8ddB8BF8b7bD597'; //v4 + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { + return { balances: {} }; + } + + let balances = {}; + + const v2 = await uniswapV2.getTvl( + V2_FACTORY_ADDRESS, + block, + chain, + provider, + web3, + ); + + //v4 + if (block >= V3_START_BLOCK) { + balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, + block, + chain, + provider, + web3, + 'algebra', + ); + } + + balances = formatter.sum([v2.balances, balances]); + + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/core/sushiswap/index.ts b/src/factory/providers/core/sushiswap/index.ts new file mode 100644 index 00000000..ec80e7c4 --- /dev/null +++ b/src/factory/providers/core/sushiswap/index.ts @@ -0,0 +1,28 @@ +import formatter from '../../../../util/formatter'; +import uniswapV2 from '../../../../util/calculators/uniswapV2'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; + +const START_BLOCK = 8051339; +const FACTORY_ADDRESS = '0xB45e53277a7e0F1D35f2a77160e91e25507f1763'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + if (block < START_BLOCK) { + return {}; + } + + const { balances, poolBalances } = await uniswapV2.getTvl( + FACTORY_ADDRESS, + block, + chain, + provider, + web3, + ); + + formatter.convertBalancesToFixed(balances); + + return { balances, poolBalances }; +} + +export { tvl }; diff --git a/src/factory/providers/cronos/ebisubay/data.json b/src/factory/providers/cronos/ebisubay/data.json new file mode 100644 index 00000000..87f931f8 --- /dev/null +++ b/src/factory/providers/cronos/ebisubay/data.json @@ -0,0 +1,7 @@ +{ + "address": "0xaf02d78f39c0002d14b95a3be272da02379aff21", + "name": "Fortune", + "symbol": "FRTN", + "decimals": 18, + "logo": "https://assets.coingecko.com/coins/images/30768/standard/fortune_token.png?1696529636" + } \ No newline at end of file diff --git a/src/factory/providers/cronos/ebisubay/index.ts b/src/factory/providers/cronos/ebisubay/index.ts new file mode 100644 index 00000000..03431de4 --- /dev/null +++ b/src/factory/providers/cronos/ebisubay/index.ts @@ -0,0 +1,40 @@ +import formatter from '../../../../util/formatter'; +import uniswapV2 from '../../../../util/calculators/uniswapV2'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import util from '../../../../util/blockchainUtil'; + + +const START_BLOCK = 13195043; +const FACTORY_ADDRESS = '0x5f1D751F447236f486F4268b883782897A902379'; +const BANK_ADDRESS = '0x1E16Aa4Bb965478Df310E8444CD18Fa56603A25F'; +const FRTN_ADDRESS = '0xaf02d78f39c0002d14b95a3be272da02379aff21'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { + return {}; + } + + const { balances, poolBalances } = await uniswapV2.getTvl( + FACTORY_ADDRESS, + block, + chain, + provider, + web3, + ); + + const balanceResults = await util.getTokenBalances( + BANK_ADDRESS, + [FRTN_ADDRESS], + block, + chain, + web3, + ); + + formatter.sumMultiBalanceOf(balances, balanceResults, chain, provider); + formatter.convertBalancesToFixed(balances); + + return { balances, poolBalances }; +} + +export { tvl }; diff --git a/src/factory/providers/ethereum/balancer/index.ts b/src/factory/providers/ethereum/balancer/index.ts index f71fbcca..2ddc2985 100644 --- a/src/factory/providers/ethereum/balancer/index.ts +++ b/src/factory/providers/ethereum/balancer/index.ts @@ -9,9 +9,9 @@ import abi from './abi.json'; import { log } from '../../../../util/logger/logger'; const START_BLOCK = 9562480; -const POOLS_GRAPHQL_API = - 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-v2'; -const QUERY_SIZE = 400; +const THE_GRAPH_API_KEY = process.env?.THE_GRAPH_API_KEY; +const POOLS_GRAPHQL_API = `https://gateway-arbitrum.network.thegraph.com/api/${THE_GRAPH_API_KEY}/subgraphs/id/C4ayEZP2yTXRAB8vSaTrgN4m9anTe9Mdm2ViyiAuV9TV`; +const QUERY_SIZE = 1000; const POOLS_QUERY = gql` query getTokens($block: Int!, $skip: Int!) { pools(block: { number: $block }, skip: $skip, first: ${QUERY_SIZE}) { diff --git a/src/factory/providers/ethereum/eigenlayer/index.ts b/src/factory/providers/ethereum/eigenlayer/index.ts index 471937ec..fe27d1c7 100644 --- a/src/factory/providers/ethereum/eigenlayer/index.ts +++ b/src/factory/providers/ethereum/eigenlayer/index.ts @@ -6,8 +6,9 @@ import formatter from '../../../../util/formatter'; const START_BLOCK = 17445564; const SWETH = '0xf951e335afb289353dc249e82926178eac7ded78'; -const SUBGRAPH_ENDPOINT = - 'https://api.thegraph.com/subgraphs/name/messari/eigenlayer-ethereum'; +const THE_GRAPH_API_KEY = process.env?.THE_GRAPH_API_KEY; +const SUBGRAPH_ENDPOINT = `https://gateway-arbitrum.network.thegraph.com/api/${THE_GRAPH_API_KEY}/subgraphs/id/68g9WSC4QTUJmMpuSbgLNENrcYha4mPmXhWGCoupM7kB`; + const STRATEGY_POOLS = gql` query getPools($block: Int!) { protocols(block: { number: $block }) { @@ -23,7 +24,8 @@ const STRATEGY_POOLS = gql` `; async function tvl(params: ITvlParams): Promise> { - const { block, chain, provider, web3 } = params; + const { chain, provider, web3 } = params; + const block = params.block - 10; if (block < START_BLOCK) { return {}; diff --git a/src/factory/providers/ethereum/euler/index.ts b/src/factory/providers/ethereum/euler/index.ts new file mode 100644 index 00000000..203026fd --- /dev/null +++ b/src/factory/providers/ethereum/euler/index.ts @@ -0,0 +1,83 @@ +import util from '../../../../util/blockchainUtil'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import formatter from '../../../../util/formatter'; + +const START_BLOCK = 20529225; +const FACTORY_ADDRESS = '0x29a56a1b8214D9Cf7c5561811750D5cBDb45CC8e'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + const balances = {}; + if (block < START_BLOCK) { + return { balances }; + } + + const proxyListLength = await util.executeCall( + FACTORY_ADDRESS, + [ + { + inputs: [], + name: 'getProxyListLength', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + ], + 'getProxyListLength', + [], + block, + chain, + web3, + ); + + const proxyList = await util.executeMultiCallsOfTarget( + FACTORY_ADDRESS, + [ + { + inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + name: 'proxyList', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + ], + 'proxyList', + Array.from({ length: proxyListLength }, (v, i) => [i]), + block, + chain, + web3, + ); + + const assets = await util.executeCallOfMultiTargets( + proxyList, + [ + { + inputs: [], + name: 'asset', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + ], + 'asset', + [], + block, + chain, + web3, + ); + + const tokenBalances = await util.getTokenBalancesOfHolders( + proxyList, + assets, + block, + chain, + web3, + ); + + formatter.sumMultiBalanceOf(balances, tokenBalances); + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/ethereum/fluid/index.ts b/src/factory/providers/ethereum/fluid/index.ts index 4337fecc..53b67b0e 100644 --- a/src/factory/providers/ethereum/fluid/index.ts +++ b/src/factory/providers/ethereum/fluid/index.ts @@ -1,14 +1,31 @@ import util from '../../../../util/blockchainUtil'; -import FLUID_LIQUIDITY_RESOLVER_ABI from './fluidLiquidityResolverAbi.json'; +import FLUID_LIQUIDITY_RESOLVER_ABI from './../../../../constants/abi/fluidLiquidityResolverAbi.json'; import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; import formatter from '../../../../util/formatter'; const FLUID_LIQUIDITY_RESOLVER_ADDRESS = '0x741c2Cd25f053a55fd94afF1afAEf146523E1249'; +const FLUID_LIQUIDITY_RESOLVER_ADDRESS_2 = + '0xD7588F6c99605Ab274C211a0AFeC60947668A8Cb'; const FLUID_LIQUIDITY_PROXY_ADDRESS = '0x52aa899454998be5b000ad077a46bbe360f4e497'; const START_BLOCK = 19239123; const ETH_ADDRESS = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'; +const WEETH_ADDRESS = '0xcd5fe23c85820f7b72d0926fc9b05b43e359b7ee'; +const ZIRCUIT_ADDRESS = '0xF047ab4c75cebf0eB9ed34Ae2c186f3611aEAfa6'; +const WEETHS_ADDRESS = '0x917ceE801a67f933F2e6b33fC0cD1ED2d5909D88'; +const ZIRCUIT_ABI = [ + { + inputs: [ + { internalType: 'address', name: '', type: 'address' }, + { internalType: 'address', name: '', type: 'address' }, + ], + name: 'balance', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, +]; async function tvl(params: ITvlParams): Promise> { const { block, chain, provider, web3 } = params; @@ -16,8 +33,13 @@ async function tvl(params: ITvlParams): Promise> { return { balances: {} }; } + const liquidityResolverAddress = + block < 19992056 + ? FLUID_LIQUIDITY_RESOLVER_ADDRESS + : FLUID_LIQUIDITY_RESOLVER_ADDRESS_2; + const listedTokens = await util.executeCall( - FLUID_LIQUIDITY_RESOLVER_ADDRESS, + liquidityResolverAddress, FLUID_LIQUIDITY_RESOLVER_ABI, 'listedTokens', [], @@ -33,6 +55,26 @@ async function tvl(params: ITvlParams): Promise> { ), }; + balances[WEETHS_ADDRESS] = await util.executeCall( + ZIRCUIT_ADDRESS, + ZIRCUIT_ABI, + 'balance', + [WEETHS_ADDRESS, FLUID_LIQUIDITY_PROXY_ADDRESS], + block, + chain, + web3, + ); + + balances[WEETH_ADDRESS] = await util.executeCall( + ZIRCUIT_ADDRESS, + ZIRCUIT_ABI, + 'balance', + [WEETH_ADDRESS, FLUID_LIQUIDITY_PROXY_ADDRESS], + block, + chain, + web3, + ); + const tokenBalances = await util.getTokenBalances( FLUID_LIQUIDITY_PROXY_ADDRESS, listedTokens.filter((token: any) => token.token !== ETH_ADDRESS), diff --git a/src/factory/providers/ethereum/marginly/index.ts b/src/factory/providers/ethereum/marginly/index.ts new file mode 100644 index 00000000..11af3b17 --- /dev/null +++ b/src/factory/providers/ethereum/marginly/index.ts @@ -0,0 +1,83 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import util from '../../../../util/blockchainUtil'; +import basicUtil from '../../../../util/basicUtil'; +import formatter from '../../../../util/formatter'; + +const START_BLOCK = 19824726; +const TOPICV15 = + '0x711e3e5dab53990b08943dd1648a41413712f35934fc7775b3dc56345de0919d'; + +const FACTORIES = [ + { + factory: '0xF8D88A292B0afa85E5Cf0d1195d0D3728Cfd7070', + topic: TOPICV15, + types: [ + { type: 'uint32', name: 'defaultSwapCallData' }, + { type: 'address', name: 'pool' }, + ], + }, +]; + +const BLOCK_LIMIT = 1000; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + const balances = {}; + if (block < START_BLOCK) { + return { balances }; + } + + let cache: { + start: number; + pools: object; + } = { start: START_BLOCK, pools: {} }; + try { + cache = await basicUtil.readFromCache('pools.json', chain, provider); + } catch {} + + for (const { factory, topic, types } of FACTORIES) { + for ( + let i = Math.max(cache.start, START_BLOCK); + i < block; + i += BLOCK_LIMIT + ) { + const logs = await util.getLogs( + i, + Math.min(i + BLOCK_LIMIT, block), + topic, + factory, + web3, + ); + logs.output.forEach((log) => { + const decodedParameters = formatter.decodeParameters(types, log.data); + const marginlyPool = decodedParameters.pool; + console.log(`New Marginly pool: ${marginlyPool}`); + const quoteToken = `0x${log.topics[1].slice(26)}`; + console.log(` quote token: ${quoteToken}`); + const baseToken = `0x${log.topics[2].slice(26)}`; + console.log(` base token: ${baseToken}`); + cache.pools[marginlyPool] = [quoteToken, baseToken]; + }); + } + } + + cache.start = block; + await basicUtil.saveIntoCache(cache, 'pools.json', chain, provider); + + const tokenBalances = await util.getTokenBalancesOfHolders( + Object.keys(cache.pools).flatMap((i) => [i, i]), + Object.keys(cache.pools) + .map((tokens) => cache.pools[tokens]) + .flat(1), + block, + chain, + web3, + ); + + formatter.sumMultiBalanceOf(balances, tokenBalances); + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/ethereum/morpho/index.ts b/src/factory/providers/ethereum/morpho/index.ts new file mode 100644 index 00000000..6b655f07 --- /dev/null +++ b/src/factory/providers/ethereum/morpho/index.ts @@ -0,0 +1,69 @@ +import formatter from '../../../../util/formatter'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import util from '../../../../util/blockchainUtil'; +import basicUtil from '../../../../util/basicUtil'; +import blockchainUtil from '../../../../util/blockchainUtil'; + +const START_BLOCK = 18883124; +const FACTORY_ADDRESS = '0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb'; +const BLOCK_LIMIT = 10000; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + const balances = {}; + if (block < START_BLOCK) { + return { balances }; + } + + let cache: { + start: number; + tokens: string[]; + } = { start: START_BLOCK, tokens: [] }; + try { + cache = await basicUtil.readFromCache('cache.json', chain, provider); + } catch {} + + for ( + let i = Math.max(cache.start, START_BLOCK); + i < block; + i += BLOCK_LIMIT + ) { + const logs = await util.getLogs( + i, + Math.min(i + BLOCK_LIMIT - 1, block), + '0xac4b2400f169220b0c0afdde7a0b32e775ba727ea1cb30b35f935cdaab8683ac', + FACTORY_ADDRESS, + web3, + ); + + logs.output.forEach((log) => { + const firstAddress = `0x${log.data.substring(26, 66)}`; + const secondAddress = `0x${log.data.substring(90, 130)}`; + + if (!cache.tokens.includes(firstAddress)) { + cache.tokens.push(firstAddress); + } + if (!cache.tokens.includes(secondAddress)) { + cache.tokens.push(secondAddress); + } + + cache.start = i += BLOCK_LIMIT; + basicUtil.saveIntoCache(cache, 'cache.json', chain, provider); + }); + } + + const tokenBalances = await blockchainUtil.getTokenBalances( + FACTORY_ADDRESS, + cache.tokens, + block, + chain, + web3, + ); + formatter.sumMultiBalanceOf(balances, tokenBalances); + + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/ethereum/open/index.ts b/src/factory/providers/ethereum/open/index.ts new file mode 100644 index 00000000..caf0affe --- /dev/null +++ b/src/factory/providers/ethereum/open/index.ts @@ -0,0 +1,29 @@ +import util from '../../../../util/blockchainUtil'; +import formatter from '../../../../util/formatter'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; + +const START_BLOCK = 19483155; +const STAKING_CONTRACT = '0x686e8500B6bE8812EB198aAbbbFA14C95c03fC88'; +const OPN_TOKEN = '0xc28eb2250d1ae32c7e74cfb6d6b86afc9beb6509'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { + return {}; + } + + const tokenBalances = await util.getTokenBalances( + STAKING_CONTRACT, + [OPN_TOKEN], + block, + chain, + web3, + ); + + const balances = {}; + formatter.sumMultiBalanceOf(balances, tokenBalances, chain, provider); + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/ethereum/pancakeswapv3/index.ts b/src/factory/providers/ethereum/pancakeswapv3/index.ts index 5c6da910..123aa0ae 100644 --- a/src/factory/providers/ethereum/pancakeswapv3/index.ts +++ b/src/factory/providers/ethereum/pancakeswapv3/index.ts @@ -2,11 +2,12 @@ import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; import pancakeswapV3subgraph from '../../../../util/calculators/pancakeswapV3subgraph'; const START_BLOCK = 16950686; -const THEGRAPTH_ENDPOINT = - 'https://api.thegraph.com/subgraphs/name/messari/pancakeswap-v3-ethereum'; +const THE_GRAPH_API_KEY = process.env?.THE_GRAPH_API_KEY; +const THEGRAPTH_ENDPOINT = `https://gateway-arbitrum.network.thegraph.com/api/${THE_GRAPH_API_KEY}/subgraphs/id/JAGXF8B14mpB8QGKnwhKTs5JxsQZBJQvbDGFcWwL7gbm`; async function tvl(params: ITvlParams): Promise> { - const { block, chain, provider, web3 } = params; + const { chain, provider, web3 } = params; + const block = params.block - 100; if (block < START_BLOCK) { return { balances: {} }; diff --git a/src/factory/providers/ethereum/radiant/index.ts b/src/factory/providers/ethereum/radiant/index.ts new file mode 100644 index 00000000..5f86147c --- /dev/null +++ b/src/factory/providers/ethereum/radiant/index.ts @@ -0,0 +1,97 @@ +import formatter from '../../../../util/formatter'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import util from '../../../../util/blockchainUtil'; +import abi from '../../polygon/aave/abi.json'; +import BigNumber from 'bignumber.js'; + +const START_BLOCK = 18466385; +const REGISTERY_V2 = '0xe969066F2cCcE3145f62f669F151c6D566068BA2'; + +async function balanceOfRegisteredAddress(register, params) { + const { block, chain, provider, web3 } = params; + const providerList = await util.executeCall( + register, + abi, + 'getAddressesProvidersList', + [], + block, + chain, + web3, + ); + const helpers = await util.executeCallOfMultiTargets( + providerList, + abi, + 'getAddress', + ['0x0100000000000000000000000000000000000000000000000000000000000000'], + block, + chain, + web3, + ); + const atokensInfos = await util.executeCallOfMultiTargets( + helpers, + abi, + 'getAllATokens', + [], + block, + chain, + web3, + ); + let atokens = []; + + atokensInfos.forEach((infos) => { + atokens = atokens.concat( + infos.map( + (info) => + info.tokenAddress?.toLowerCase() || info.split(',')[1]?.toLowerCase(), + ), + ); + }); + const pools = {}; + await Promise.all( + atokens.map((address) => getUnderlyings(address, web3, pools)), + ); + + const results = await util.executeMultiCallsOfMultiTargets( + atokens.map((address) => pools[address]), + abi, + 'balanceOf', + atokens.map((address) => [address]), + block, + chain, + web3, + ); + + const balanceResults = {}; + results.forEach((result, index) => { + const balance = BigNumber(result || 0); + if (balance.isGreaterThan(0)) { + balanceResults[pools[atokens[index]]] = balance; + } + }); + return balanceResults; +} + +async function getUnderlyings(address, web3, pools) { + try { + if (!pools[address]) { + const contract = new web3.eth.Contract(abi, address); + const underlying = await contract.methods + .UNDERLYING_ASSET_ADDRESS() + .call(); + pools[address.toLowerCase()] = underlying.toLowerCase(); + } + } catch {} +} + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { + return {}; + } + + const balances = await balanceOfRegisteredAddress(REGISTERY_V2, params); + formatter.convertBalancesToFixed(balances); + + return { balances }; +} +export { tvl }; diff --git a/src/factory/providers/ethereum/stargate/abi.json b/src/factory/providers/ethereum/stargate/abi.json deleted file mode 100644 index edfbdc55..00000000 --- a/src/factory/providers/ethereum/stargate/abi.json +++ /dev/null @@ -1,79 +0,0 @@ -[ - { - "inputs": [], - "name": "factory", - "outputs": [ - { - "internalType": "contract Factory", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "allPoolsLength", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "allPools", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "pools", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "token", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - } -] \ No newline at end of file diff --git a/src/factory/providers/ethereum/stargate/data.json b/src/factory/providers/ethereum/stargate/data.json deleted file mode 100644 index 9b1fb291..00000000 --- a/src/factory/providers/ethereum/stargate/data.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "address": "0xaf5191b0de278c7286d6c7cc6ab6bb8a73ba2cd6", - "name": "Stargate Token", - "symbol": "STG", - "decimals": 18, - "logo": "https://assets.coingecko.com/coins/images/24413/small/STG_LOGO.png" -} \ No newline at end of file diff --git a/src/factory/providers/ethereum/stargate/index.ts b/src/factory/providers/ethereum/stargate/index.ts index 0a3bac68..ce69e3ab 100644 --- a/src/factory/providers/ethereum/stargate/index.ts +++ b/src/factory/providers/ethereum/stargate/index.ts @@ -1,9 +1,10 @@ import util from '../../../../util/blockchainUtil'; -import ABI from './abi.json'; +import ABI from '../../../../constants/abi/stargateV1Abi.json'; import CONSTANTS from '../../../../constants/contracts.json'; import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; import basicUtil from '../../../../util/basicUtil'; import formatter from '../../../../util/formatter'; +import stargateV2 from '../../../../util/calculators/stargateV2'; const ROUTER = '0x8731d54E9D02c286767d56ac03e8037C07e01e98'; const BASE_TOKENS = { @@ -95,8 +96,11 @@ async function tvl(params: ITvlParams): Promise> { const balances = {}; formatter.sumMultiBalanceOf(balances, tokenBalances); - formatter.convertBalancesToFixed(balances); + const v2TokenBalances = await stargateV2.getV2Tvl(chain, block, web3); + formatter.sumMultiBalanceOf(balances, v2TokenBalances); + + formatter.convertBalancesToFixed(balances); return { balances }; } diff --git a/src/factory/providers/ethereum/sushiswap/data.json b/src/factory/providers/ethereum/sushiswap/data.json deleted file mode 100644 index 4015c3d3..00000000 --- a/src/factory/providers/ethereum/sushiswap/data.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "address": "0x6b3595068778dd592e39a122f4f5a5cf09c90fe2", - "name": "SushiToken", - "symbol": "SUSHI", - "decimals": 18, - "logo": "https://user-dashboard.s3.us-east-2.amazonaws.com/token_images/prod/35/0x947950bcc74888a40ffa2593c5798f11fc9124c4_large.png" -} \ No newline at end of file diff --git a/src/factory/providers/ethereum/sushiswap/index.ts b/src/factory/providers/ethereum/sushiswap/index.ts index d4e61be6..b8dc9914 100644 --- a/src/factory/providers/ethereum/sushiswap/index.ts +++ b/src/factory/providers/ethereum/sushiswap/index.ts @@ -1,22 +1,18 @@ -import { kashiLending } from './kashi-lending'; -import BigNumber from 'bignumber.js'; +import formatter from '../../../../util/formatter'; import uniswapV2 from '../../../../util/calculators/uniswapV2'; import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; -import formatter from '../../../../util/formatter'; const START_BLOCK = 10794229; -const FACTORY_ADDRESS = '0xc0aee478e3658e2610c5f7a4a2e1777ce9e4f2ac'; -const GRAPHQL_API = - 'https://api.thegraph.com/subgraphs/name/sushiswap/exchange'; -const QUERY_SIZE = 400; +const FACTORY_ADDRESS = '0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac'; async function tvl(params: ITvlParams): Promise> { const { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { return {}; } - const { balances: dexBalances, poolBalances } = await uniswapV2.getTvl( + const { balances, poolBalances } = await uniswapV2.getTvl( FACTORY_ADDRESS, block, chain, @@ -24,50 +20,9 @@ async function tvl(params: ITvlParams): Promise> { web3, ); - const kashiBalances = await kashiLending({ - block, - chain, - provider, - web3, - } as ITvlParams); - - const balances = formatter.sum([dexBalances, kashiBalances.balances]); - - for (const token in balances) { - if (BigNumber(balances[token] || 0).isLessThan(100000)) { - delete balances[token]; - } - } + formatter.convertBalancesToFixed(balances); return { balances, poolBalances }; } -async function getPoolVolumes(pools, priorBlockNumber) { - const poolVolumes = await uniswapV2.getPoolVolumes( - GRAPHQL_API, - QUERY_SIZE, - pools, - priorBlockNumber, - null, - ); - - return poolVolumes; -} - -async function getTokenVolumes(tokens, priorBlockNumber) { - const tokenVolumes = await uniswapV2.getTokenVolumes( - GRAPHQL_API, - QUERY_SIZE, - tokens, - priorBlockNumber, - null, - ); - - return tokenVolumes; -} - -module.exports = { - tvl, - getPoolVolumes, - getTokenVolumes, -}; +export { tvl }; diff --git a/src/factory/providers/ethereum/sushiswap/kashi-lending.ts b/src/factory/providers/ethereum/sushiswap/kashi-lending.ts deleted file mode 100644 index e060b6de..00000000 --- a/src/factory/providers/ethereum/sushiswap/kashi-lending.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { request, gql } from 'graphql-request'; -import util from '../../../../util/blockchainUtil'; -import BigNumber from 'bignumber.js'; -import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; - -const graphUrl = 'https://api.thegraph.com/subgraphs/name/sushiswap/bentobox'; -const bentoboxQuery = gql` - query get_bentoboxes($block: Int, $tokensSkip: Int) { - bentoBoxes(first: 100, block: { number: $block }) { - id - tokens(first: 1000, orderBy: totalSupplyBase, orderDirection: desc) { - id - } - totalTokens - } - } -`; - -async function kashiLending(params: ITvlParams): Promise> { - const { block, chain, provider, web3 } = params; - console.time('Getting KashiBalance'); - - const boxTokens = []; - const kashiBalances = {}; - - const { bentoBoxes } = await request(graphUrl, bentoboxQuery, { block }); - - for (const bentoBox of bentoBoxes) { - boxTokens.push(...bentoBox.tokens.map((token) => token.id)); - - const boxesBalances = await util.getTokenBalances( - bentoBox.id, - boxTokens, - block, - chain, - web3, - ); - for (const boxBalance of boxesBalances) { - kashiBalances[boxBalance.token] = BigNumber( - kashiBalances[boxBalance.token] || 0, - ).plus(boxBalance.balance); - } - } - console.timeEnd('Getting KashiBalance'); - return { balances: kashiBalances }; -} - -export { kashiLending }; diff --git a/src/factory/providers/ethereum/sushiswapv3/index.ts b/src/factory/providers/ethereum/sushiswapv3/index.ts new file mode 100644 index 00000000..faaaf980 --- /dev/null +++ b/src/factory/providers/ethereum/sushiswapv3/index.ts @@ -0,0 +1,25 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; + +const V3_START_BLOCK = 16955547; +const V3_FACTORY_ADDRESS = '0xbaceb8ec6b9355dfc0269c18bac9d6e2bdc29c4f'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < V3_START_BLOCK) { + return { balances: {} }; + } + + const balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, + block, + chain, + provider, + web3, + ); + + return { balances, poolBalances: {} }; +} + +export { tvl }; diff --git a/src/factory/providers/ethereum/uniswap/index.ts b/src/factory/providers/ethereum/uniswap/index.ts index 742597a2..66edc33f 100644 --- a/src/factory/providers/ethereum/uniswap/index.ts +++ b/src/factory/providers/ethereum/uniswap/index.ts @@ -5,8 +5,8 @@ import formatter from '../../../../util/formatter'; const START_BLOCK = 10000835; const QUERY_SIZE = 1000; -const SUBGRAPH_ENDPOINT = - 'https://api.thegraph.com/subgraphs/name/ianlapham/uniswap-v2-dev'; +const THE_GRAPH_API_KEY = process.env?.THE_GRAPH_API_KEY; +const SUBGRAPH_ENDPOINT = `https://gateway-arbitrum.network.thegraph.com/api/${THE_GRAPH_API_KEY}/subgraphs/id/EYCKATKGBKLWvSfwvBjzfCBmGwYNdVkduYXVivCsLRFu`; const TOKENS = gql` query getTokens($id: String!, $block: Int!) { tokens( @@ -24,7 +24,6 @@ const TOKENS = gql` async function tvl(params: ITvlParams): Promise> { const { block, chain, provider, web3 } = params; - if (block < START_BLOCK) { return {}; } @@ -33,7 +32,7 @@ async function tvl(params: ITvlParams): Promise> { let lastId = ''; while (true) { const requestResult = await request(SUBGRAPH_ENDPOINT, TOKENS, { - block: block, + block: block - 100, id: lastId, }); diff --git a/src/factory/providers/ethereum/uniswapv3/index.ts b/src/factory/providers/ethereum/uniswapv3/index.ts index 2af0ee81..a2d403f3 100644 --- a/src/factory/providers/ethereum/uniswapv3/index.ts +++ b/src/factory/providers/ethereum/uniswapv3/index.ts @@ -1,31 +1,25 @@ -import BigNumber from 'bignumber.js'; import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; -import * as v3TVL from './v3'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; + +const V3_START_BLOCK = 12369621; +const V3_FACTORY_ADDRESS = '0x1F98431c8aD98523631AE4a59f267346ea31F984'; async function tvl(params: ITvlParams): Promise> { const { block, chain, provider, web3 } = params; - - const v3 = await v3TVL.tvl(block, chain, provider, web3); - - const balances = {}; - - for (const token in v3) { - const address = token.toLowerCase(); - if (!balances[address]) { - balances[address] = BigNumber(0); - } - balances[address] = balances[address].plus(v3[token]); + if (block < V3_START_BLOCK) { + return { balances: {} }; } - for (const token in balances) { - if (balances[token].isLessThan(10_000_000_000)) { - delete balances[token]; - } else { - balances[token] = balances[token].toFixed(); - } - } + const balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, + block, + chain, + provider, + web3, + ); - return { balances }; + return { balances, poolBalances: {} }; } export { tvl }; diff --git a/src/factory/providers/ethereum/uniswapv3/v3.ts b/src/factory/providers/ethereum/uniswapv3/v3.ts deleted file mode 100644 index 60b22fd6..00000000 --- a/src/factory/providers/ethereum/uniswapv3/v3.ts +++ /dev/null @@ -1,193 +0,0 @@ -import fetch from 'node-fetch'; -import BigNumber from 'bignumber.js'; -import util from '../../../../util/blockchainUtil'; -import basicUtil from '../../../../util/basicUtil'; -import formatter from '../../../../util/formatter'; -import { log } from '../../../../util/logger/logger'; - -const START_BLOCK = 12369621; -const FACTORY = '0x1F98431c8aD98523631AE4a59f267346ea31F984'; -const SUBGRAPH_ENDPOINT = - 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3'; -const GET_RESERVES = ` - query GET_RESERVES($startPool: String, $block: Int) { - pools (first: 1000, orderBy: id, where: {id_gt: $startPool}, block: {number: $block}) { - id - token0 { - id - decimals - } - token1 { - id - decimals - } - totalValueLockedToken0 - totalValueLockedToken1 - } - } -`; - -async function getReserves(startPool, block) { - const balances = []; - try { - console.log(`[v3] Getting Pair Info from ${startPool}`); - const result = await fetch(SUBGRAPH_ENDPOINT, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - query: GET_RESERVES, - variables: { - startPool, - block, - }, - }), - }) - .then((res) => res.json()) - .then((res) => res.data.pools); - result.forEach((pool) => { - try { - balances.push({ - token: pool.token0.id.toLowerCase(), - balance: new BigNumber(pool.totalValueLockedToken0).times( - 10 ** pool.token0.decimals, - ), - }); - balances.push({ - token: pool.token1.id.toLowerCase(), - balance: new BigNumber(pool.totalValueLockedToken1).times( - 10 ** pool.token1.decimals, - ), - }); - } catch (e) { - log.error({ - message: e?.message || '', - stack: e?.stack || '', - detail: `Error: getReserves of ethereum/uniswapv3`, - endpoint: 'getReserves', - }); - } - }); - } catch (e) { - log.error({ - message: e?.message || '', - stack: e?.stack || '', - detail: `[v3] Issue with SubGraph on from ${startPool}`, - endpoint: 'getReserves', - }); - } - - return balances; -} - -export async function tvl(block, chain, provider, web3) { - if (block < START_BLOCK) { - return {}; - } - - let v3Pairs = { block: START_BLOCK, pairs: [], token01: [] }; - try { - v3Pairs = await basicUtil.readFromCache( - 'cache/v3Pairs.json', - chain, - provider, - ); - } catch {} - - let logs = []; - console.log('[v3] start getting tvl'); - console.log('[v3] get logs1'); - - let offset = 10000; - for (let i = Math.max(v3Pairs.block, START_BLOCK); ; ) { - console.log(`Trying from ${i} with offset ${offset}`); - let eventLog = []; - try { - eventLog = ( - await util.getLogs( - i, - Math.min(block, i + offset), - '0x783cca1c0412dd0d695e784568c96da2e9c22ff989357a2e8b1d9b2b4e6b7118', - FACTORY, - web3, - ) - ).output; - console.log(`Trying from ${i} with offset ${offset}`); - } catch (e) { - log.error({ - message: e?.message || '', - stack: e?.stack || '', - detail: `Error: tvl of ethereum/uniswapv3`, - endpoint: 'tvl', - }); - if (offset > 1000) { - offset -= 2000; - } else if (offset > 100) { - offset -= 200; - } else if (offset > 10) { - offset -= 20; - } else { - break; - } - continue; - } - logs = logs.concat(eventLog); - - i += offset; - if (block < i) { - break; - } - } - - const pairs = v3Pairs.token01; - let pairAddresses = v3Pairs.pairs; - const start = 128 - 40 + 2; - const end = 128 + 2; - - const pairExist = {}; - pairAddresses.forEach((address) => (pairExist[address] = true)); - - pairAddresses = pairAddresses.concat( - // sometimes the full log is emitted - logs - .map((log) => { - let pairAddress = - typeof log === 'string' ? log : `0x${log.data.slice(start, end)}`; - pairAddress = pairAddress.toLowerCase(); - if (typeof log !== 'string') { - pairs[pairAddress] = { - token0Address: `0x${log.topics[1].slice(26)}`, - token1Address: `0x${log.topics[2].slice(26)}`, - }; - } - return pairAddress; - }) - .filter((address) => !pairExist[address]), - ); - - await basicUtil.saveIntoCache( - { - block, - pairs: pairAddresses, - token01: pairs, - }, - 'cache/v3Pairs.json', - chain, - provider, - ); - - const pairLength = pairAddresses.length; - const balanceCalls = []; - const sortedPair = pairAddresses.sort((a, b) => (a > b ? 1 : -1)); - - for (let i = 0; i < pairLength; i += 1000) { - balanceCalls.push(getReserves(sortedPair[i], block - 10)); - } - const balanceResults = await Promise.all(balanceCalls); - const balances = {}; - balanceResults.forEach((result) => { - formatter.sumMultiBalanceOf(balances, result); - }); - return balances; -} diff --git a/src/factory/providers/etherlink/iguana/index.ts b/src/factory/providers/etherlink/iguana/index.ts new file mode 100644 index 00000000..337dfa6a --- /dev/null +++ b/src/factory/providers/etherlink/iguana/index.ts @@ -0,0 +1,25 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; + +const V3_START_BLOCK = 1960368; +const V3_FACTORY_ADDRESS = '0x093cCBAEcb0E0006c8BfFca92E9929d117fEC583'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < V3_START_BLOCK) { + return { balances: {} }; + } + + const balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, + block, + chain, + provider, + web3, + ); + + return { balances, poolBalances: {} }; +} + +export { tvl }; diff --git a/src/factory/providers/etherlink/organicgrowth/index.ts b/src/factory/providers/etherlink/organicgrowth/index.ts new file mode 100644 index 00000000..4e60c9d2 --- /dev/null +++ b/src/factory/providers/etherlink/organicgrowth/index.ts @@ -0,0 +1,83 @@ +import formatter from '../../../../util/formatter'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import util from '../../../../util/blockchainUtil'; +import basicUtil from '../../../../util/basicUtil'; +import blockchainUtil from '../../../../util/blockchainUtil'; + +const START_BLOCK = 308542; +const FACTORY_ADDRESS = '0x9767E409259E314F3C69fe1E7cA0D3161Bba4F5a'; +const BLOCK_LIMIT = 1000; +const OGW1_WXTZ = '0x3571aed54ccea5b69b00516d5a149a6baea77118'; +const WXTZ = '0xc9b53ab2679f573e480d01e0f49e2b5cfb7a3eab'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + const balances = {}; + if (block < START_BLOCK) { + return { balances }; + } + + let cache: { + start: number; + pairs: object; + } = { start: START_BLOCK, pairs: {} }; + try { + cache = await basicUtil.readFromCache('cache.json', chain, provider); + } catch {} + + for ( + let i = Math.max(cache.start, START_BLOCK); + i < block; + i += BLOCK_LIMIT + ) { + const logs = await util.getLogs( + i, + Math.min(i + BLOCK_LIMIT - 1, block), + '0xa92a2b95c8d8436f6ac4c673c61487364f877efb9534d4296fad8ef904546c94', + FACTORY_ADDRESS, + web3, + ); + + logs.output.forEach((log) => { + const weth = `0x${log.topics[1].substring(26, 66)}`; + const token = `0x${log.topics[2].substring(26, 66)}`; + const pair = `0x${log.data.substring(26, 66)}`; + + cache.start = i + BLOCK_LIMIT; + cache.pairs[pair] = { weth, token }; + basicUtil.saveIntoCache(cache, 'cache.json', chain, provider); + }); + } + + const tokens: string[] = []; + const holders: string[] = []; + + for (const pair in cache.pairs) { + if (cache.pairs.hasOwnProperty(pair)) { + tokens.push(cache.pairs[pair].weth); + holders.push(pair); + } + } + + const tokenBalances = await blockchainUtil.getTokenBalancesOfHolders( + Object.keys(cache.pairs), + Object.values(cache.pairs).map((pair) => pair.token), + block, + chain, + web3, + ); + + formatter.sumMultiBalanceOf(balances, tokenBalances); + formatter.sumMultiBalanceOf(balances, tokenBalances); // sum second time, to get other pair token value + + if (balances[OGW1_WXTZ]) { + balances[WXTZ] = balances[OGW1_WXTZ]; + delete balances[OGW1_WXTZ]; + } + + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/etherlink/tachyswap/index.ts b/src/factory/providers/etherlink/tachyswap/index.ts new file mode 100644 index 00000000..bbaba738 --- /dev/null +++ b/src/factory/providers/etherlink/tachyswap/index.ts @@ -0,0 +1,27 @@ +import uniswapV2 from '../../../../util/calculators/uniswapV2'; +import formatter from '../../../../util/formatter'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; + +const START_BLOCK = 384279; +const FACTORY_ADDRESS = '0x033eff22bC5Bd30c597e1fdE8Ca6fB1C1274C688'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { + return { balances: {} }; + } + + const { balances, poolBalances } = await uniswapV2.getTvl( + FACTORY_ADDRESS, + block, + chain, + provider, + web3, + ); + + formatter.convertBalancesToFixed(balances); + + return { balances, poolBalances }; +} + +export { tvl }; diff --git a/src/factory/providers/fantom/stargate/index.ts b/src/factory/providers/fantom/stargate/index.ts new file mode 100644 index 00000000..ec5cb11b --- /dev/null +++ b/src/factory/providers/fantom/stargate/index.ts @@ -0,0 +1,90 @@ +import util from '../../../../util/blockchainUtil'; +import formatter from '../../../../util/formatter'; +import basicUtil from '../../../../util/basicUtil'; +import ABI from '../../../../constants/abi/stargateV1Abi.json'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; + +const ROUTER = '0xAf5191B0De278C7286d6C7CC6ab6BB8A73bA2Cd6'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + let store = { + pools: [], + tokens: {}, + }; + try { + store = await basicUtil.readFromCache('cache/store.json', chain, provider); + } catch {} + + const factory = await util.executeCall( + ROUTER, + ABI, + 'factory', + [], + block, + chain, + web3, + ); + const allPoolsLength = await util.executeCall( + factory, + ABI, + 'allPoolsLength', + [], + block, + chain, + web3, + ); + + if (store.pools.length < allPoolsLength) { + const newPools = await util.executeMultiCallsOfTarget( + factory, + ABI, + 'allPools', + Array.from( + { length: allPoolsLength - store.pools.length }, + (_, i) => store.pools.length + i, + ), + block, + chain, + web3, + ); + const poolTokens = await util.executeCallOfMultiTargets( + newPools, + ABI, + 'token', + [], + block, + chain, + web3, + ); + + for (const index in newPools) { + if (newPools[index] && poolTokens[index]) { + store.pools.push(newPools[index]); + store.tokens[newPools[index]] = poolTokens[index]; + } else { + break; + } + } + + await basicUtil.saveIntoCache(store, 'cache/store.json', chain, provider); + } + + const tokenBalances = await util.getTokenBalancesOfHolders( + Object.keys(store.tokens), + Object.values(store.tokens), + block, + chain, + web3, + ); + + const balances = {}; + + formatter.sumMultiBalanceOf(balances, tokenBalances); + + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/fantom/sushiswap/data.json b/src/factory/providers/fantom/sushiswap/data.json deleted file mode 100644 index 58845315..00000000 --- a/src/factory/providers/fantom/sushiswap/data.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "address": "0xae75a438b2e0cb8bb01ec1e1e376de11d44477cc", - "name": "Sushi", - "symbol": "SUSHI", - "decimals": 18, - "logo": "https://user-dashboard.s3.us-east-2.amazonaws.com/token_images/prod/35/0x947950bcc74888a40ffa2593c5798f11fc9124c4_large.png" -} \ No newline at end of file diff --git a/src/factory/providers/fantom/sushiswap/index.ts b/src/factory/providers/fantom/sushiswap/index.ts index 9c0ff2c5..065f4baf 100644 --- a/src/factory/providers/fantom/sushiswap/index.ts +++ b/src/factory/providers/fantom/sushiswap/index.ts @@ -1,14 +1,9 @@ -import BigNumber from 'bignumber.js'; -import { kashiLending } from './kashi-lending'; import formatter from '../../../../util/formatter'; import uniswapV2 from '../../../../util/calculators/uniswapV2'; import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; const START_BLOCK = 2457879; const FACTORY_ADDRESS = '0xc35DADB65012eC5796536bD9864eD8773aBc74C4'; -const GRAPHQL_API = - 'https://api.thegraph.com/subgraphs/name/sushiswap/fantom-exchange'; -const QUERY_SIZE = 400; async function tvl(params: ITvlParams): Promise> { const { block, chain, provider, web3 } = params; @@ -17,7 +12,7 @@ async function tvl(params: ITvlParams): Promise> { return {}; } - const { balances: dexBalances, poolBalances } = await uniswapV2.getTvl( + const { balances, poolBalances } = await uniswapV2.getTvl( FACTORY_ADDRESS, block, chain, @@ -25,41 +20,9 @@ async function tvl(params: ITvlParams): Promise> { web3, ); - const kashiBalances = await kashiLending(block, chain, web3); - - const balances = formatter.sum([dexBalances, kashiBalances]); - - for (const token in balances) { - if (BigNumber(balances[token] || 0).isLessThan(100000)) { - delete balances[token]; - } - } + formatter.convertBalancesToFixed(balances); return { balances, poolBalances }; } -async function getPoolVolumes(pools, priorBlockNumber) { - const poolVolumes = await uniswapV2.getPoolVolumes( - GRAPHQL_API, - QUERY_SIZE, - pools, - priorBlockNumber, - null, - ); - - return poolVolumes; -} - -async function getTokenVolumes(tokens, priorBlockNumber) { - const tokenVolumes = await uniswapV2.getTokenVolumes( - GRAPHQL_API, - QUERY_SIZE, - tokens, - priorBlockNumber, - null, - ); - - return tokenVolumes; -} - -export { tvl, getPoolVolumes, getTokenVolumes }; +export { tvl }; diff --git a/src/factory/providers/fantom/sushiswap/kashi-lending.ts b/src/factory/providers/fantom/sushiswap/kashi-lending.ts deleted file mode 100644 index 7edc841f..00000000 --- a/src/factory/providers/fantom/sushiswap/kashi-lending.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { request, gql } from 'graphql-request'; -import util from '../../../../util/blockchainUtil'; -import BigNumber from 'bignumber.js'; - -const graphUrl = - 'https://api.thegraph.com/subgraphs/name/sushiswap/fantom-bentobox'; -const bentoboxQuery = gql` - query get_bentoboxes($block: Int, $tokensSkip: Int) { - bentoBoxes(first: 100, block: { number: $block }) { - id - tokens(first: 1000, orderBy: totalSupplyBase, orderDirection: desc) { - id - } - totalTokens - } - } -`; - -async function kashiLending(block, chain, web3) { - console.time('Getting KashiBalance'); - - const boxTokens = []; - const kashiBalances = {}; - - const { bentoBoxes } = await request(graphUrl, bentoboxQuery, { block }); - - for (const bentoBox of bentoBoxes) { - boxTokens.push(...bentoBox.tokens.map((token) => token.id)); - - const boxesBalances = await util.getTokenBalances( - bentoBox.id, - boxTokens, - block, - chain, - web3, - ); - for (const boxBalance of boxesBalances) { - kashiBalances[boxBalance.token] = BigNumber( - kashiBalances[boxBalance.token] || 0, - ).plus(boxBalance.balance); - } - } - - console.timeEnd('Getting KashiBalance'); - - return kashiBalances; -} - -export { kashiLending }; diff --git a/src/factory/providers/fantom/sushiswapv3/index.ts b/src/factory/providers/fantom/sushiswapv3/index.ts new file mode 100644 index 00000000..72ba6736 --- /dev/null +++ b/src/factory/providers/fantom/sushiswapv3/index.ts @@ -0,0 +1,25 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; + +const V3_START_BLOCK = 58860670; +const V3_FACTORY_ADDRESS = '0x7770978eED668a3ba661d51a773d3a992Fc9DDCB'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < V3_START_BLOCK) { + return { balances: {} }; + } + + const balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, + block, + chain, + provider, + web3, + ); + + return { balances, poolBalances: {} }; +} + +export { tvl }; diff --git a/src/factory/providers/linea/lynex/index.ts b/src/factory/providers/linea/lynex/index.ts index 62726080..4fbf2eec 100644 --- a/src/factory/providers/linea/lynex/index.ts +++ b/src/factory/providers/linea/lynex/index.ts @@ -1,5 +1,8 @@ import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; +import uniswapV2 from '../../../../util/calculators/uniswapV2'; +import util from '../../../../util/blockchainUtil'; +import formatter from '../../../../util/formatter'; const V3_START_BLOCK = 143660; const V3_FACTORY_ADDRESS = '0x622b2c98123D303ae067DB4925CD6282B3A08D0F'; @@ -10,16 +13,43 @@ async function tvl(params: ITvlParams): Promise> { return { balances: {} }; } - const balances = await uniswapV3.getTvl( + let balances = await uniswapV3.getTvl( V3_FACTORY_ADDRESS, V3_START_BLOCK, block, chain, provider, web3, - true, + 'algebra', ); + const tokenBalances = await util.getTokenBalances( + '0x8D95f56b0Bac46e8ac1d3A3F12FB1E5BC39b4c0c', + ['0x1a51b19CE03dbE0Cb44C1528E34a7EDD7771E9Af'], + block, + chain, + web3, + ); + + const v2Tvl1 = await uniswapV2.getTvl( + '0x6ed7b91c8133e85921f8028b51a8248488b3336c', + block, + chain, + provider, + web3, + ); + + const v2Tvl2 = await uniswapV2.getTvl( + '0xbc7695fd00e3b32d08124b7a4287493aee99f9ee', + block, + chain, + provider, + web3, + ); + + balances = formatter.sum([balances, v2Tvl1.balances, v2Tvl2.balances]); + formatter.sumMultiBalanceOf(balances, tokenBalances, chain, provider); + formatter.convertBalancesToFixed(balances); return { balances, poolBalances: {} }; } diff --git a/src/factory/providers/linea/stargate/abi.json b/src/factory/providers/linea/stargate/abi.json deleted file mode 100644 index edfbdc55..00000000 --- a/src/factory/providers/linea/stargate/abi.json +++ /dev/null @@ -1,79 +0,0 @@ -[ - { - "inputs": [], - "name": "factory", - "outputs": [ - { - "internalType": "contract Factory", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "allPoolsLength", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "allPools", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "pools", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "token", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - } -] \ No newline at end of file diff --git a/src/factory/providers/linea/stargate/index.ts b/src/factory/providers/linea/stargate/index.ts index 5992462d..f6fc565d 100644 --- a/src/factory/providers/linea/stargate/index.ts +++ b/src/factory/providers/linea/stargate/index.ts @@ -1,9 +1,10 @@ import util from '../../../../util/blockchainUtil'; -import ABI from './abi.json'; +import ABI from '../../../../constants/abi/stargateV1Abi.json'; import CONSTANTS from '../../../../constants/contracts.json'; import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; import basicUtil from '../../../../util/basicUtil'; import formatter from '../../../../util/formatter'; +import stargateV2 from '../../../../util/calculators/stargateV2'; const START_BLOCK = 48078; const ROUTER = '0x2F6F07CDcf3588944Bf4C42aC74ff24bF56e7590'; @@ -97,8 +98,11 @@ async function tvl(params: ITvlParams): Promise> { const balances = {}; formatter.sumMultiBalanceOf(balances, tokenBalances); - formatter.convertBalancesToFixed(balances); + const v2TokenBalances = await stargateV2.getV2Tvl(chain, block, web3); + formatter.sumMultiBalanceOf(balances, v2TokenBalances); + + formatter.convertBalancesToFixed(balances); return { balances }; } diff --git a/src/factory/providers/linea/sushiswap/index.ts b/src/factory/providers/linea/sushiswap/index.ts new file mode 100644 index 00000000..201932ea --- /dev/null +++ b/src/factory/providers/linea/sushiswap/index.ts @@ -0,0 +1,28 @@ +import formatter from '../../../../util/formatter'; +import uniswapV2 from '../../../../util/calculators/uniswapV2'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; + +const START_BLOCK = 631714; +const FACTORY_ADDRESS = '0xFbc12984689e5f15626Bad03Ad60160Fe98B303C'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + if (block < START_BLOCK) { + return {}; + } + + const { balances, poolBalances } = await uniswapV2.getTvl( + FACTORY_ADDRESS, + block, + chain, + provider, + web3, + ); + + formatter.convertBalancesToFixed(balances); + + return { balances, poolBalances }; +} + +export { tvl }; diff --git a/src/factory/providers/linea/sushiswapv3/index.ts b/src/factory/providers/linea/sushiswapv3/index.ts new file mode 100644 index 00000000..f3d2bdc5 --- /dev/null +++ b/src/factory/providers/linea/sushiswapv3/index.ts @@ -0,0 +1,25 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; + +const V3_START_BLOCK = 53256; +const V3_FACTORY_ADDRESS = '0xc35DADB65012eC5796536bD9864eD8773aBc74C4'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < V3_START_BLOCK) { + return { balances: {} }; + } + + const balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, + block, + chain, + provider, + web3, + ); + + return { balances, poolBalances: {} }; +} + +export { tvl }; diff --git a/src/factory/providers/moonbeam/sushiswap/index.ts b/src/factory/providers/moonbeam/sushiswap/index.ts new file mode 100644 index 00000000..b3e6e650 --- /dev/null +++ b/src/factory/providers/moonbeam/sushiswap/index.ts @@ -0,0 +1,28 @@ +import formatter from '../../../../util/formatter'; +import uniswapV2 from '../../../../util/calculators/uniswapV2'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; + +const START_BLOCK = 503713; +const FACTORY_ADDRESS = '0xc35DADB65012eC5796536bD9864eD8773aBc74C4'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + if (block < START_BLOCK) { + return {}; + } + + const { balances, poolBalances } = await uniswapV2.getTvl( + FACTORY_ADDRESS, + block, + chain, + provider, + web3, + ); + + formatter.convertBalancesToFixed(balances); + + return { balances, poolBalances }; +} + +export { tvl }; diff --git a/src/factory/providers/moonbeam/sushiswapv3/index.ts b/src/factory/providers/moonbeam/sushiswapv3/index.ts new file mode 100644 index 00000000..4211b9fb --- /dev/null +++ b/src/factory/providers/moonbeam/sushiswapv3/index.ts @@ -0,0 +1,25 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; + +const V3_START_BLOCK = 3264275; +const V3_FACTORY_ADDRESS = '0x2ecd58F51819E8F8BA08A650BEA04Fc0DEa1d523'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < V3_START_BLOCK) { + return { balances: {} }; + } + + const balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, + block, + chain, + provider, + web3, + ); + + return { balances, poolBalances: {} }; +} + +export { tvl }; diff --git a/src/factory/providers/moonriver/sushiswap/data.json b/src/factory/providers/moonriver/sushiswap/data.json deleted file mode 100644 index b4d63311..00000000 --- a/src/factory/providers/moonriver/sushiswap/data.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "address": "", - "name": "", - "symbol": "", - "decimals": 0, - "logo": "" -} \ No newline at end of file diff --git a/src/factory/providers/moonriver/sushiswap/index.ts b/src/factory/providers/moonriver/sushiswap/index.ts index 5f98e495..b60f35b7 100644 --- a/src/factory/providers/moonriver/sushiswap/index.ts +++ b/src/factory/providers/moonriver/sushiswap/index.ts @@ -4,12 +4,10 @@ import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; const START_BLOCK = 428426; const FACTORY_ADDRESS = '0xc35DADB65012eC5796536bD9864eD8773aBc74C4'; -const GRAPHQL_API = - 'https://api.thegraph.com/subgraphs/name/sushiswap/moonriver-exchange'; -const QUERY_SIZE = 400; async function tvl(params: ITvlParams): Promise> { const { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { return {}; } @@ -27,28 +25,4 @@ async function tvl(params: ITvlParams): Promise> { return { balances, poolBalances }; } -async function getPoolVolumes(pools, priorBlockNumber) { - const poolVolumes = await uniswapV2.getPoolVolumes( - GRAPHQL_API, - QUERY_SIZE, - pools, - priorBlockNumber, - null, - ); - - return poolVolumes; -} - -async function getTokenVolumes(tokens, priorBlockNumber) { - const tokenVolumes = await uniswapV2.getTokenVolumes( - GRAPHQL_API, - QUERY_SIZE, - tokens, - priorBlockNumber, - null, - ); - - return tokenVolumes; -} - -export { tvl, getPoolVolumes, getTokenVolumes }; +export { tvl }; diff --git a/src/factory/providers/moonriver/sushiswapv3/index.ts b/src/factory/providers/moonriver/sushiswapv3/index.ts new file mode 100644 index 00000000..ef30f1cf --- /dev/null +++ b/src/factory/providers/moonriver/sushiswapv3/index.ts @@ -0,0 +1,25 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; + +const V3_START_BLOCK = 3945310; +const V3_FACTORY_ADDRESS = '0x2F255d3f3C0A3726c6c99E74566c4b18E36E3ce6'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < V3_START_BLOCK) { + return { balances: {} }; + } + + const balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, + block, + chain, + provider, + web3, + ); + + return { balances, poolBalances: {} }; +} + +export { tvl }; diff --git a/src/factory/providers/optimism/stargate/abi/factoryAbi.json b/src/factory/providers/optimism/stargate/abi/factoryAbi.json deleted file mode 100644 index 0423ffc3..00000000 --- a/src/factory/providers/optimism/stargate/abi/factoryAbi.json +++ /dev/null @@ -1,199 +0,0 @@ -[ - { - "inputs": [ - { - "internalType": "address", - "name": "_router", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "allPools", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "allPoolsLength", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_poolId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_token", - "type": "address" - }, - { - "internalType": "uint8", - "name": "_sharedDecimals", - "type": "uint8" - }, - { - "internalType": "uint8", - "name": "_localDecimals", - "type": "uint8" - }, - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - } - ], - "name": "createPool", - "outputs": [ - { - "internalType": "address", - "name": "poolAddress", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "defaultFeeLibrary", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "getPool", - "outputs": [ - { - "internalType": "contract Pool", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "router", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_defaultFeeLibrary", - "type": "address" - } - ], - "name": "setDefaultFeeLibrary", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } -] \ No newline at end of file diff --git a/src/factory/providers/optimism/stargate/abi/poolAbi.json b/src/factory/providers/optimism/stargate/abi/poolAbi.json deleted file mode 100644 index 30ed5f1b..00000000 --- a/src/factory/providers/optimism/stargate/abi/poolAbi.json +++ /dev/null @@ -1,1940 +0,0 @@ -[ - { - "inputs": [ - { - "internalType": "uint256", - "name": "_poolId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_router", - "type": "address" - }, - { - "internalType": "address", - "name": "_token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_sharedDecimals", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_localDecimals", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_feeLibrary", - "type": "address" - }, - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountLP", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - } - ], - "name": "Burn", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint16", - "name": "dstChainId", - "type": "uint16" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "dstPoolId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "weight", - "type": "uint256" - } - ], - "name": "ChainPathUpdate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint16", - "name": "chainId", - "type": "uint16" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "srcPoolId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "idealBalance", - "type": "uint256" - } - ], - "name": "CreditChainPath", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bool", - "name": "batched", - "type": "bool" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "swapDeltaBP", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "lpDeltaBP", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bool", - "name": "defaultSwapMode", - "type": "bool" - }, - { - "indexed": false, - "internalType": "bool", - "name": "defaultLPMode", - "type": "bool" - } - ], - "name": "DeltaParamUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "feeLibraryAddr", - "type": "address" - } - ], - "name": "FeeLibraryUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "mintFeeBP", - "type": "uint256" - } - ], - "name": "FeesUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountLP", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - } - ], - "name": "InstantRedeemLocal", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountLP", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "mintFeeAmountSD", - "type": "uint256" - } - ], - "name": "Mint", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountLP", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint16", - "name": "chainId", - "type": "uint16" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "dstPoolId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "to", - "type": "bytes" - } - ], - "name": "RedeemLocal", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "_amountSD", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "_amountToMintSD", - "type": "uint256" - } - ], - "name": "RedeemLocalCallback", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint16", - "name": "chainId", - "type": "uint16" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "dstPoolId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountLP", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - } - ], - "name": "RedeemRemote", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint16", - "name": "dstChainId", - "type": "uint16" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "dstPoolId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "credits", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "idealBalance", - "type": "uint256" - } - ], - "name": "SendCredits", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bool", - "name": "swapStop", - "type": "bool" - } - ], - "name": "StopSwapUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint16", - "name": "chainId", - "type": "uint16" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "dstPoolId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "eqReward", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "eqFee", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "protocolFee", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "lpFee", - "type": "uint256" - } - ], - "name": "Swap", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "protocolFee", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "dstFee", - "type": "uint256" - } - ], - "name": "SwapRemote", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - } - ], - "name": "WithdrawMintFeeBalance", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - } - ], - "name": "WithdrawProtocolFeeBalance", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint16", - "name": "srcChainId", - "type": "uint16" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "srcPoolId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "mintAmount", - "type": "uint256" - } - ], - "name": "WithdrawRemote", - "type": "event" - }, - { - "inputs": [], - "name": "BP_DENOMINATOR", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "DOMAIN_SEPARATOR", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "PERMIT_TYPEHASH", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_dstChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_dstPoolId", - "type": "uint256" - } - ], - "name": "activateChainPath", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_amountLP", - "type": "uint256" - } - ], - "name": "amountLPtoLD", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "batched", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bool", - "name": "_fullMode", - "type": "bool" - } - ], - "name": "callDelta", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "chainPathIndexLookup", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "chainPaths", - "outputs": [ - { - "internalType": "bool", - "name": "ready", - "type": "bool" - }, - { - "internalType": "uint16", - "name": "dstChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "dstPoolId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "weight", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lkb", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "credits", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "idealBalance", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "convertRate", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_dstChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_dstPoolId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_weight", - "type": "uint256" - } - ], - "name": "createChainPath", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_dstChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_dstPoolId", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "credits", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "idealBalance", - "type": "uint256" - } - ], - "internalType": "struct Pool.CreditObj", - "name": "_c", - "type": "tuple" - } - ], - "name": "creditChainPath", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "decimals", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "subtractedValue", - "type": "uint256" - } - ], - "name": "decreaseAllowance", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "defaultLPMode", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "defaultSwapMode", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "deltaCredit", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "eqFeePool", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "feeLibrary", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_dstChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_dstPoolId", - "type": "uint256" - } - ], - "name": "getChainPath", - "outputs": [ - { - "components": [ - { - "internalType": "bool", - "name": "ready", - "type": "bool" - }, - { - "internalType": "uint16", - "name": "dstChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "dstPoolId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "weight", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lkb", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "credits", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "idealBalance", - "type": "uint256" - } - ], - "internalType": "struct Pool.ChainPath", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getChainPathsLength", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "addedValue", - "type": "uint256" - } - ], - "name": "increaseAllowance", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amountLP", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - } - ], - "name": "instantRedeemLocal", - "outputs": [ - { - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "localDecimals", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "lpDeltaBP", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amountLD", - "type": "uint256" - } - ], - "name": "mint", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "mintFeeBP", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "mintFeeBalance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "nonces", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "name": "permit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "poolId", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "protocolFeeBalance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amountLP", - "type": "uint256" - }, - { - "internalType": "uint16", - "name": "_dstChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_dstPoolId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_to", - "type": "bytes" - } - ], - "name": "redeemLocal", - "outputs": [ - { - "internalType": "uint256", - "name": "amountSD", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_srcChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_srcPoolId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amountSD", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_amountToMintSD", - "type": "uint256" - } - ], - "name": "redeemLocalCallback", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_srcChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_srcPoolId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_amountSD", - "type": "uint256" - } - ], - "name": "redeemLocalCheckOnRemote", - "outputs": [ - { - "internalType": "uint256", - "name": "swapAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "mintAmount", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_dstChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_dstPoolId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amountLP", - "type": "uint256" - } - ], - "name": "redeemRemote", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "router", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_dstChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_dstPoolId", - "type": "uint256" - } - ], - "name": "sendCredits", - "outputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "credits", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "idealBalance", - "type": "uint256" - } - ], - "internalType": "struct Pool.CreditObj", - "name": "c", - "type": "tuple" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bool", - "name": "_batched", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "_swapDeltaBP", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_lpDeltaBP", - "type": "uint256" - }, - { - "internalType": "bool", - "name": "_defaultSwapMode", - "type": "bool" - }, - { - "internalType": "bool", - "name": "_defaultLPMode", - "type": "bool" - } - ], - "name": "setDeltaParam", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_mintFeeBP", - "type": "uint256" - } - ], - "name": "setFee", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_feeLibraryAddr", - "type": "address" - } - ], - "name": "setFeeLibrary", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bool", - "name": "_swapStop", - "type": "bool" - } - ], - "name": "setSwapStop", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_dstChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_dstPoolId", - "type": "uint256" - }, - { - "internalType": "uint16", - "name": "_weight", - "type": "uint16" - } - ], - "name": "setWeightForChainPath", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "sharedDecimals", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "stopSwap", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_dstChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_dstPoolId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_amountLD", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_minAmountLD", - "type": "uint256" - }, - { - "internalType": "bool", - "name": "newLiquidity", - "type": "bool" - } - ], - "name": "swap", - "outputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "eqFee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "eqReward", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lpFee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "protocolFee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lkbRemove", - "type": "uint256" - } - ], - "internalType": "struct Pool.SwapObj", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "swapDeltaBP", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "_srcChainId", - "type": "uint16" - }, - { - "internalType": "uint256", - "name": "_srcPoolId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "eqFee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "eqReward", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lpFee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "protocolFee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lkbRemove", - "type": "uint256" - } - ], - "internalType": "struct Pool.SwapObj", - "name": "_s", - "type": "tuple" - } - ], - "name": "swapRemote", - "outputs": [ - { - "internalType": "uint256", - "name": "amountLD", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "token", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalLiquidity", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalWeight", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_to", - "type": "address" - } - ], - "name": "withdrawMintFeeBalance", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_to", - "type": "address" - } - ], - "name": "withdrawProtocolFeeBalance", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } -] \ No newline at end of file diff --git a/src/factory/providers/optimism/stargate/data.json b/src/factory/providers/optimism/stargate/data.json deleted file mode 100644 index 0386a4f0..00000000 --- a/src/factory/providers/optimism/stargate/data.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "address": "0x296f55f8fb28e498b858d0bcda06d955b2cb3f97", - "name": "Stargate Finance", - "symbol": "STG", - "decimals": 18, - "logo": "https://assets.coingecko.com/coins/images/24413/small/STG_LOGO.png" -} \ No newline at end of file diff --git a/src/factory/providers/optimism/stargate/index.ts b/src/factory/providers/optimism/stargate/index.ts index 0d06101d..f1cb2b24 100644 --- a/src/factory/providers/optimism/stargate/index.ts +++ b/src/factory/providers/optimism/stargate/index.ts @@ -1,25 +1,35 @@ -import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; import util from '../../../../util/blockchainUtil'; import formatter from '../../../../util/formatter'; -import FACTORY_ABI from './abi/factoryAbi.json'; -import POOL_ABI from './abi/poolAbi.json'; -import { WMAIN_ADDRESS } from '../../../../constants/contracts.json'; +import basicUtil from '../../../../util/basicUtil'; +import ABI from '../../../../constants/abi/stargateV1Abi.json'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import stargateV2 from '../../../../util/calculators/stargateV2'; -const START_BLOCK = 4535223; -const FACTORY = '0xE3B53AF74a4BF62Ae5511055290838050bf764Df'; -const SGETH = '0xb69c8cbcd90a39d8d3d3ccf0a3e968511c3856a0'; +const ROUTER = '0xB0D502E938ed5f4df2E681fE6E419ff29631d62b'; async function tvl(params: ITvlParams): Promise> { const { block, chain, provider, web3 } = params; - if (block < START_BLOCK) { - return {}; - } - const balances = {}; + let store = { + pools: [], + tokens: {}, + }; + try { + store = await basicUtil.readFromCache('cache/store.json', chain, provider); + } catch {} + const factory = await util.executeCall( + ROUTER, + ABI, + 'factory', + [], + block, + chain, + web3, + ); const allPoolsLength = await util.executeCall( - FACTORY, - FACTORY_ABI, + factory, + ABI, 'allPoolsLength', [], block, @@ -27,46 +37,58 @@ async function tvl(params: ITvlParams): Promise> { web3, ); - const contractParams = []; - for (let i = 0; i < allPoolsLength; i++) { - contractParams.push([i]); + if (store.pools.length < allPoolsLength) { + const newPools = await util.executeMultiCallsOfTarget( + factory, + ABI, + 'allPools', + Array.from( + { length: allPoolsLength - store.pools.length }, + (_, i) => store.pools.length + i, + ), + block, + chain, + web3, + ); + const poolTokens = await util.executeCallOfMultiTargets( + newPools, + ABI, + 'token', + [], + block, + chain, + web3, + ); + + for (const index in newPools) { + if (newPools[index] && poolTokens[index]) { + store.pools.push(newPools[index]); + store.tokens[newPools[index]] = poolTokens[index]; + } else { + break; + } + } + + await basicUtil.saveIntoCache(store, 'cache/store.json', chain, provider); } - const pools = await util.executeMultiCallsOfTarget( - FACTORY, - FACTORY_ABI, - 'allPools', - contractParams, + const tokenBalances = await util.getTokenBalancesOfHolders( + Object.keys(store.tokens), + Object.values(store.tokens), block, chain, web3, ); - const tokens = await util.executeCallOfMultiTargets( - pools, - POOL_ABI, - 'token', - [], - block, - chain, - web3, - ); + const balances = {}; - const balanceResults = await util.getTokenBalancesOfHolders( - pools, - tokens, - block, - chain, - web3, - ); + formatter.sumMultiBalanceOf(balances, tokenBalances); - formatter.sumMultiBalanceOf(balances, balanceResults); - formatter.convertBalancesToFixed(balances); + const v2TokenBalances = await stargateV2.getV2Tvl(chain, block, web3); + formatter.sumMultiBalanceOf(balances, v2TokenBalances); - if (balances[SGETH]) { - balances[WMAIN_ADDRESS.optimism] = balances[SGETH]; - delete balances[SGETH]; - } + formatter.convertBalancesToFixed(balances); return { balances }; } + export { tvl }; diff --git a/src/factory/providers/optimism/sushiswap/index.ts b/src/factory/providers/optimism/sushiswap/index.ts new file mode 100644 index 00000000..dc05872a --- /dev/null +++ b/src/factory/providers/optimism/sushiswap/index.ts @@ -0,0 +1,28 @@ +import formatter from '../../../../util/formatter'; +import uniswapV2 from '../../../../util/calculators/uniswapV2'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; + +const START_BLOCK = 110882086; +const FACTORY_ADDRESS = '0xFbc12984689e5f15626Bad03Ad60160Fe98B303C'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + if (block < START_BLOCK) { + return {}; + } + + const { balances, poolBalances } = await uniswapV2.getTvl( + FACTORY_ADDRESS, + block, + chain, + provider, + web3, + ); + + formatter.convertBalancesToFixed(balances); + + return { balances, poolBalances }; +} + +export { tvl }; diff --git a/src/factory/providers/optimism/sushiswapv3/index.ts b/src/factory/providers/optimism/sushiswapv3/index.ts new file mode 100644 index 00000000..a7b375e8 --- /dev/null +++ b/src/factory/providers/optimism/sushiswapv3/index.ts @@ -0,0 +1,25 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; + +const V3_START_BLOCK = 85432013; +const V3_FACTORY_ADDRESS = '0x9c6522117e2ed1fE5bdb72bb0eD5E3f2bdE7DBe0'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < V3_START_BLOCK) { + return { balances: {} }; + } + + const balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, + block, + chain, + provider, + web3, + ); + + return { balances, poolBalances: {} }; +} + +export { tvl }; diff --git a/src/factory/providers/optimism/uniswapv3/index.ts b/src/factory/providers/optimism/uniswapv3/index.ts index 1245bc35..24fb6513 100644 --- a/src/factory/providers/optimism/uniswapv3/index.ts +++ b/src/factory/providers/optimism/uniswapv3/index.ts @@ -1,24 +1,25 @@ import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; -import formatter from '../../../../util/formatter'; -import uniswapV3 from '../../../../util/calculators/uniswapV3'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; -const START_BLOCK = 0; -const THEGRAPTH_ENDPOINT = - 'https://api.thegraph.com/subgraphs/name/ianlapham/optimism-post-regenesis'; +const V3_START_BLOCK = 0; +const V3_FACTORY_ADDRESS = '0x1F98431c8aD98523631AE4a59f267346ea31F984'; async function tvl(params: ITvlParams): Promise> { const { block, chain, provider, web3 } = params; - if (block < START_BLOCK) { + if (block < V3_START_BLOCK) { return { balances: {} }; } - const { balances, poolBalances } = await uniswapV3.getTvlFromSubgraph( - THEGRAPTH_ENDPOINT, + const balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, block, chain, provider, + web3, ); - formatter.convertBalancesToFixed(balances); - return { balances, poolBalances }; + + return { balances, poolBalances: {} }; } + export { tvl }; diff --git a/src/factory/providers/polygon/balancer/abi.json b/src/factory/providers/polygon/balancer/abi.json new file mode 100644 index 00000000..ef85e39a --- /dev/null +++ b/src/factory/providers/polygon/balancer/abi.json @@ -0,0 +1,16 @@ +{ + "getCurrentTokens": { + "constant": true, + "inputs": [], + "name": "getCurrentTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + } + ], + "payable": false, + "type": "function" + } +} \ No newline at end of file diff --git a/src/factory/providers/polygon/balancer/index.ts b/src/factory/providers/polygon/balancer/index.ts index ef6bb9d6..4f631237 100644 --- a/src/factory/providers/polygon/balancer/index.ts +++ b/src/factory/providers/polygon/balancer/index.ts @@ -1,71 +1,233 @@ import BigNumber from 'bignumber.js'; import { request, gql } from 'graphql-request'; -import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import basicUtil from '../../../../util/basicUtil'; +import util from '../../../../util/blockchainUtil'; import formatter from '../../../../util/formatter'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import abi from './abi.json'; import { log } from '../../../../util/logger/logger'; const START_BLOCK = 15832998; -const THEGRAPTH_ENDPOINT = - 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-polygon-v2'; -const POOL_COUNT_QUERY = gql` - query getPoolCount($block: Int!) { - balancer(id: 2, block: { number: $block }) { - poolCount - } - } -`; +const THE_GRAPH_API_KEY = process.env?.THE_GRAPH_API_KEY; +const THEGRAPTH_ENDPOINT = `https://gateway-arbitrum.network.thegraph.com/api/${THE_GRAPH_API_KEY}/subgraphs/id/H9oPAbXnobBRq1cB3HDmbZ1E8MWQyJYQjT1QDJMrdbNp`; +const QUERY_SIZE = 1000; const POOLS_QUERY = gql` - query getPools($block: Int!, $skip: Int!) { - pools(skip: $skip, first: 1000, block: { number: $block }) { - tokens { - address - balance - decimals + query getTokens($block: Int!, $skip: Int!) { + pools(block: { number: $block }, skip: $skip, first: ${QUERY_SIZE}) { + tokens { + address + balance + decimals + } } } + `; + +async function v1Tvl(balances, block, chain, provider, web3) { + let _pools; + + try { + _pools = await basicUtil.readFromCache('cache/pools.json', chain, provider); + } catch { + _pools = { + start: START_BLOCK, + pools: [], + tokens: {}, + }; + } + if (!_pools.tokens) { + _pools.tokens = {}; } -`; -async function tvl(params: ITvlParams): Promise> { - const { block, chain, provider, web3 } = params; - if (block < START_BLOCK) { - return {}; + const blocksLimit = 10000; + const poolLogs = []; + for ( + let i = Math.max(_pools.start, START_BLOCK); + i < block; + i += blocksLimit + ) { + const logs = ( + await util.getLogs( + i, + Math.min(i + blocksLimit, block), + '0x8ccec77b0cb63ac2cafd0f5de8cdfadab91ce656d262240ba8a6343bccc5f945', + '0x9424B1412450D0f8Fc2255FAf6046b98213B76Bd', + web3, + ) + ).output; + Array.prototype.push.apply(poolLogs, logs); } - const balances = {}; + const poolPairs = []; - try { - let poolCount; - await request(THEGRAPTH_ENDPOINT, POOL_COUNT_QUERY, { - block: block, - }).then((data) => (poolCount = data.balancer.poolCount)); - - for (let i = 0; i < poolCount; i += 1000) { - let pools; - await request(THEGRAPTH_ENDPOINT, POOLS_QUERY, { - block: block, - skip: i, - }).then((data) => (pools = data.pools)); - - pools.forEach((pool) => { - pool.tokens.forEach((token) => { - balances[token.address] = BigNumber( - balances[token.address] || 0, - ).plus(BigNumber(token.balance).shiftedBy(token.decimals)); + let pools = poolLogs.map((poolLog) => { + return `0x${poolLog.topics[2].slice(26)}`.toLowerCase(); + }); + pools = pools.filter((pool) => !_pools.pools.includes(pool)); + pools = _pools.pools.concat(pools); + + const poolLength = pools.length; + const counts = Math.ceil(poolLength / 12); + const index = new Date().getHours() % 12; + + const recalcPools = pools.slice(index * counts, (index + 1) * counts); + const recalcResults = await util.executeCallOfMultiTargets( + recalcPools, + [abi['getCurrentTokens']], + 'getCurrentTokens', + [], + block, + chain, + web3, + ); + + recalcResults.forEach((result, index) => { + if (result) { + _pools.tokens[recalcPools[index]] = result.map((token) => + token.toLowerCase(), + ); + } + }); + + const newPools = pools.filter((pool) => !_pools.tokens[pool]); + const newResults = await util.executeCallOfMultiTargets( + newPools, + [abi['getCurrentTokens']], + 'getCurrentTokens', + [], + block, + chain, + web3, + ); + + newResults.forEach((result, index) => { + if (result) { + _pools.tokens[newPools[index]] = result.map((token) => + token.toLowerCase(), + ); + } + }); + + await basicUtil.saveIntoCache( + { + start: block, + pools, + tokens: _pools.tokens, + }, + 'cache/pools.json', + chain, + provider, + ); + + for (const pool in _pools.tokens) { + const poolTokens = _pools.tokens[pool]; + if (poolTokens) { + poolTokens.forEach((token) => { + poolPairs.push({ pool, token }); + }); + } + } + + const poolPairLength = poolPairs.length; + for (let i = 0; i < poolPairLength; i += 2000) { + const j = Math.min(i + 2000, poolPairLength); + const balanceCalls = []; + + for (let start = i; start < j; start += 100) { + const end = Math.min(start + 100, poolPairLength); + const subPairs = poolPairs.slice(start, end); + try { + balanceCalls.push( + util.getTokenBalancesOfHolders( + subPairs.map((pair) => pair.pool), + subPairs.map((pair) => pair.token), + block, + chain, + web3, + ), + ); + } catch (e) { + log.error({ + message: e?.message || '', + stack: e?.stack || '', + detail: `Error: v1Tvl of ethereum/balancer`, + endpoint: 'v1Tvl', }); + } + log.info({ + message: `done ${end} out of ${poolPairLength}`, + endpoint: 'v1Tvl of ethereum/balancer', }); + console.log(`done ${end} out of ${poolPairLength}`); + } + + const bulkBalances = await Promise.all(balanceCalls); + + for (const bulkBalance of bulkBalances) { + formatter.sumMultiBalanceOf(balances, bulkBalance); + } + } +} + +async function v2Tvl(balances, block) { + try { + let skip = 0; + while (true) { + try { + const pools = await request(THEGRAPTH_ENDPOINT, POOLS_QUERY, { + block: block, + skip: skip, + }).then((data) => data.pools); + + pools.forEach((pool) => { + pool.tokens.forEach((token) => { + balances[token.address] = BigNumber( + balances[token.address] || 0, + ).plus( + BigNumber(token.balance).shiftedBy(parseInt(token.decimals)), + ); + }); + }); + + if (pools.length < QUERY_SIZE) { + break; + } + skip += QUERY_SIZE; + } catch (e) { + log.error({ + message: e?.message || '', + stack: e?.stack || '', + detail: `Error: v2Tvl of ethereum/balancer`, + endpoint: 'v2Tvl', + }); + throw e; + } } } catch (e) { log.error({ message: e?.message || '', stack: e?.stack || '', - detail: `Error: tvl of polygon/balancer`, - endpoint: 'tvl', + detail: `Error: v2Tvl of ethereum/balancer`, + endpoint: 'v2Tvl', }); throw e; } +} + +async function tvl(params: ITvlParams): Promise> { + let { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { + return {}; + } + block = block - 100; + + const balances = {}; + + await v1Tvl(balances, block, chain, provider, web3); + await v2Tvl(balances, block); formatter.convertBalancesToFixed(balances); + return { balances }; } diff --git a/src/factory/providers/polygon/open/index.ts b/src/factory/providers/polygon/open/index.ts new file mode 100644 index 00000000..70d1e194 --- /dev/null +++ b/src/factory/providers/polygon/open/index.ts @@ -0,0 +1,29 @@ +import util from '../../../../util/blockchainUtil'; +import formatter from '../../../../util/formatter'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; + +const START_BLOCK = 54913762; +const STAKING_CONTRACT = '0x686e8500B6bE8812EB198aAbbbFA14C95c03fC88'; +const OPN_TOKEN = '0x7844F79FC841E4F92d974C417031c76F8578c2D5'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { + return {}; + } + + const tokenBalances = await util.getTokenBalances( + STAKING_CONTRACT, + [OPN_TOKEN], + block, + chain, + web3, + ); + + const balances = {}; + formatter.sumMultiBalanceOf(balances, tokenBalances, chain, provider); + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/polygon/quickswap/index.ts b/src/factory/providers/polygon/quickswap/index.ts index 6b6b197a..5019eaca 100644 --- a/src/factory/providers/polygon/quickswap/index.ts +++ b/src/factory/providers/polygon/quickswap/index.ts @@ -7,9 +7,9 @@ import { log } from '../../../../util/logger/logger'; const START_BLOCK = 15474436; const FACTORY_ADDRESS = '0x5757371414417b8c6caad45baef941abc7d3ab32'; -const THEGRAPTH_ENDPOINT = - 'https://api.thegraph.com/subgraphs/name/sameepsi/quickswap-v3'; -const QUERY_SIZE = 400; +const THE_GRAPH_API_KEY = process.env?.THE_GRAPH_API_KEY; +const THEGRAPTH_ENDPOINT = `https://gateway-arbitrum.network.thegraph.com/api/${THE_GRAPH_API_KEY}/subgraphs/id/FqsRcH1XqSjqVx9GRTvEJe959aCbKrcyGgDWBrUkG24g`; +const QUERY_SIZE = 1000; const TOKENS_QUERY = gql` query getTokens($block: Int!, $skip: Int!) { tokens(block: { number: $block }, skip: $skip, first: ${QUERY_SIZE}) { @@ -43,8 +43,8 @@ const POOLS_QUERY = gql` `; async function tvl(params: ITvlParams): Promise> { - const { block, chain, provider, web3 } = params; - + const { chain, provider, web3 } = params; + const block = params.block - 100; if (block < START_BLOCK) { return {}; } diff --git a/src/factory/providers/polygon/stargate/abi.json b/src/factory/providers/polygon/stargate/abi.json deleted file mode 100644 index dbeb8a3e..00000000 --- a/src/factory/providers/polygon/stargate/abi.json +++ /dev/null @@ -1,79 +0,0 @@ -[ - { - "inputs": [], - "name": "factory", - "outputs": [ - { - "internalType": "contract Factory", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "allPoolsLength", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "allPools", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "pools", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "token", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - } -] diff --git a/src/factory/providers/polygon/stargate/data.json b/src/factory/providers/polygon/stargate/data.json deleted file mode 100644 index 955e3f4c..00000000 --- a/src/factory/providers/polygon/stargate/data.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "address": "0x2f6f07cdcf3588944bf4c42ac74ff24bf56e7590", - "name": "Stargate Token", - "symbol": "STG", - "decimals": 18, - "logo": "https://assets.coingecko.com/coins/images/24413/small/STG_LOGO.png" -} \ No newline at end of file diff --git a/src/factory/providers/polygon/stargate/index.ts b/src/factory/providers/polygon/stargate/index.ts index 6a2c1a81..6dd92670 100644 --- a/src/factory/providers/polygon/stargate/index.ts +++ b/src/factory/providers/polygon/stargate/index.ts @@ -1,8 +1,9 @@ import util from '../../../../util/blockchainUtil'; import formatter from '../../../../util/formatter'; import basicUtil from '../../../../util/basicUtil'; -import ABI from './abi.json'; +import ABI from '../../../../constants/abi/stargateV1Abi.json'; import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import stargateV2 from '../../../../util/calculators/stargateV2'; const ROUTER = '0x45A01E4e04F14f7A4a6702c74187c5F6222033cd'; @@ -85,6 +86,10 @@ async function tvl(params: ITvlParams): Promise> { const balances = {}; formatter.sumMultiBalanceOf(balances, tokenBalances); + + const v2TokenBalances = await stargateV2.getV2Tvl(chain, block, web3); + formatter.sumMultiBalanceOf(balances, v2TokenBalances); + formatter.convertBalancesToFixed(balances); return { balances }; } diff --git a/src/factory/providers/polygon/sushiswap/data.json b/src/factory/providers/polygon/sushiswap/data.json deleted file mode 100644 index dbb3b279..00000000 --- a/src/factory/providers/polygon/sushiswap/data.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "address": "0x0b3f868e0be5597d5db7feb59e1cadbb0fdda50a", - "name": "SushiToken (PoS)", - "symbol": "SUSHI", - "decimals": 18, - "logo": "https://user-dashboard.s3.us-east-2.amazonaws.com/token_images/prod/35/0x947950bcc74888a40ffa2593c5798f11fc9124c4_large.png" -} \ No newline at end of file diff --git a/src/factory/providers/polygon/sushiswap/index.ts b/src/factory/providers/polygon/sushiswap/index.ts index 9c4905b5..e5e212cf 100644 --- a/src/factory/providers/polygon/sushiswap/index.ts +++ b/src/factory/providers/polygon/sushiswap/index.ts @@ -4,12 +4,10 @@ import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; const START_BLOCK = 11333218; const FACTORY_ADDRESS = '0xc35DADB65012eC5796536bD9864eD8773aBc74C4'; -const GRAPHQL_API = - 'https://api.thegraph.com/subgraphs/name/sushiswap/matic-exchange'; -const QUERY_SIZE = 400; async function tvl(params: ITvlParams): Promise> { const { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { return {}; } @@ -23,31 +21,8 @@ async function tvl(params: ITvlParams): Promise> { ); formatter.convertBalancesToFixed(balances); - return { balances, poolBalances }; -} - -async function getPoolVolumes(pools, priorBlockNumber) { - const poolVolumes = await uniswapV2.getPoolVolumes( - GRAPHQL_API, - QUERY_SIZE, - pools, - priorBlockNumber, - null, - ); - return poolVolumes; -} - -async function getTokenVolumes(tokens, priorBlockNumber) { - const tokenVolumes = await uniswapV2.getTokenVolumes( - GRAPHQL_API, - QUERY_SIZE, - tokens, - priorBlockNumber, - null, - ); - - return tokenVolumes; + return { balances, poolBalances }; } -export { tvl, getPoolVolumes, getTokenVolumes }; +export { tvl }; diff --git a/src/factory/providers/polygon/sushiswapv3/index.ts b/src/factory/providers/polygon/sushiswapv3/index.ts new file mode 100644 index 00000000..604e4562 --- /dev/null +++ b/src/factory/providers/polygon/sushiswapv3/index.ts @@ -0,0 +1,25 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; + +const V3_START_BLOCK = 41024971; +const V3_FACTORY_ADDRESS = '0x917933899c6a5F8E37F31E19f92CdBFF7e8FF0e2'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < V3_START_BLOCK) { + return { balances: {} }; + } + + const balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, + block, + chain, + provider, + web3, + ); + + return { balances, poolBalances: {} }; +} + +export { tvl }; diff --git a/src/factory/providers/polygon/uniswapv3/index.ts b/src/factory/providers/polygon/uniswapv3/index.ts index 31b6ba71..69279c17 100644 --- a/src/factory/providers/polygon/uniswapv3/index.ts +++ b/src/factory/providers/polygon/uniswapv3/index.ts @@ -1,60 +1,25 @@ -import BigNumber from 'bignumber.js'; -import { request, gql } from 'graphql-request'; import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; -import formatter from '../../../../util/formatter'; -import { log } from '../../../../util/logger/logger'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; -const START_BLOCK = 22757547; -const THEGRAPTH_ENDPOINT = - 'https://api.thegraph.com/subgraphs/name/ianlapham/uniswap-v3-polygon'; -const QUERY_SIZE = 500; -const TOKENS_QUERY = gql` - query getTokens($block: Int!, $skip: Int!) { - tokens(block: { number: $block }, skip: $skip, first: ${QUERY_SIZE}) { - id - decimals - totalValueLocked - } - } -`; +const V3_START_BLOCK = 22757547; +const V3_FACTORY_ADDRESS = '0x1F98431c8aD98523631AE4a59f267346ea31F984'; async function tvl(params: ITvlParams): Promise> { const { block, chain, provider, web3 } = params; - if (block < START_BLOCK) { - return {}; + if (block < V3_START_BLOCK) { + return { balances: {} }; } - const balances = {}; - let skip = 0; - while (skip <= 5000) { - try { - const tokens = await request(THEGRAPTH_ENDPOINT, TOKENS_QUERY, { - block: block, - skip: skip, - }).then((data) => data.tokens); - - tokens.forEach((token) => { - balances[token.id] = BigNumber(token.totalValueLocked).shiftedBy( - parseInt(token.decimals), - ); - }); - if (tokens.length < QUERY_SIZE) { - break; - } - skip += QUERY_SIZE; - } catch (e) { - log.error({ - message: e?.message || '', - stack: e?.stack || '', - detail: `Error: tvl of polygon/uniswapv3`, - endpoint: 'tvl', - }); - throw e; - } - } + const balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, + block, + chain, + provider, + web3, + ); - formatter.convertBalancesToFixed(balances); - return { balances }; + return { balances, poolBalances: {} }; } export { tvl }; diff --git a/src/factory/providers/skale-europa/aquas/index.ts b/src/factory/providers/skale-europa/aquas/index.ts new file mode 100644 index 00000000..1e5d238e --- /dev/null +++ b/src/factory/providers/skale-europa/aquas/index.ts @@ -0,0 +1,28 @@ +import formatter from '../../../../util/formatter'; +import uniswapV2 from '../../../../util/calculators/uniswapV2'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; + +const START_BLOCK = 3823515; +const FACTORY_ADDRESS = '0xc318a82CB7c2B0faf7e355BB8F285016956aBF55'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + if (block < START_BLOCK) { + return {}; + } + + const { balances, poolBalances } = await uniswapV2.getTvl( + FACTORY_ADDRESS, + block, + chain, + provider, + web3, + ); + + formatter.convertBalancesToFixed(balances); + + return { balances, poolBalances }; +} + +export { tvl }; diff --git a/src/factory/providers/skale-europa/meson/index.ts b/src/factory/providers/skale-europa/meson/index.ts new file mode 100644 index 00000000..4c19cef0 --- /dev/null +++ b/src/factory/providers/skale-europa/meson/index.ts @@ -0,0 +1,29 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import axios from 'axios'; +import formatter from '../../../../util/formatter'; +import util from '../../../../util/blockchainUtil'; + +const URI = 'https://relayer.meson.fi/api/v1/list'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + const balances = {}; + const skaleEuropaData = (await axios.get(URI)).data.result.find( + (item: any) => item.id === 'skale-europa', + ); + + const tokenBalances = await util.getTokenBalances( + skaleEuropaData.address, + skaleEuropaData.tokens.map((token: any) => token.addr), + block, + chain, + web3, + ); + + formatter.sumMultiBalanceOf(balances, tokenBalances, chain, provider); + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/skale-europa/ruby-exchange/index.ts b/src/factory/providers/skale-europa/ruby-exchange/index.ts new file mode 100644 index 00000000..04857709 --- /dev/null +++ b/src/factory/providers/skale-europa/ruby-exchange/index.ts @@ -0,0 +1,42 @@ +import formatter from '../../../../util/formatter'; +import uniswapV2 from '../../../../util/calculators/uniswapV2'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import util from '../../../../util/blockchainUtil'; + +const START_BLOCK = 50404; +const FACTORY_ADDRESS = '0x71f7bbbb33550fa5d70ca3f7eead87529f2dc3c8'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + if (block < START_BLOCK) { + return {}; + } + + const { balances, poolBalances } = await uniswapV2.getTvl( + FACTORY_ADDRESS, + block, + chain, + provider, + web3, + ); + + const tokenBalances = await util.getTokenBalances( + '0x45c550dc634bcc271c092a20d36761d3bb834e5d', + [ + '0x73d22d8a2D1f59Bf5Bcf62cA382481a2073FAF58', + '0x1c0491E3396AD6a35f061c62387a95d7218FC515', + '0x5F795bb52dAC3085f578f4877D450e2929D2F13d', + '0xD05C4be5f3be302d376518c9492EC0147Fa5A718', + ], + block, + chain, + web3, + ); + + formatter.sumMultiBalanceOf(balances, tokenBalances, chain, provider); + formatter.convertBalancesToFixed(balances); + return { balances, poolBalances }; +} + +export { tvl }; diff --git a/src/factory/providers/skale-europa/sushiswap/index.ts b/src/factory/providers/skale-europa/sushiswap/index.ts new file mode 100644 index 00000000..f6fb24eb --- /dev/null +++ b/src/factory/providers/skale-europa/sushiswap/index.ts @@ -0,0 +1,28 @@ +import formatter from '../../../../util/formatter'; +import uniswapV2 from '../../../../util/calculators/uniswapV2'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; + +const START_BLOCK = 5124080; +const FACTORY_ADDRESS = '0x1aaF6eB4F85F8775400C1B10E6BbbD98b2FF8483'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + if (block < START_BLOCK) { + return {}; + } + + const { balances, poolBalances } = await uniswapV2.getTvl( + FACTORY_ADDRESS, + block, + chain, + provider, + web3, + ); + + formatter.convertBalancesToFixed(balances); + + return { balances, poolBalances }; +} + +export { tvl }; diff --git a/src/factory/providers/skale-europa/sushiswapv3/index.ts b/src/factory/providers/skale-europa/sushiswapv3/index.ts new file mode 100644 index 00000000..587612b0 --- /dev/null +++ b/src/factory/providers/skale-europa/sushiswapv3/index.ts @@ -0,0 +1,25 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; + +const V3_START_BLOCK = 5124251; +const V3_FACTORY_ADDRESS = '0x51d15889b66A2c919dBbD624d53B47a9E8feC4bB'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < V3_START_BLOCK) { + return { balances: {} }; + } + + const balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + V3_START_BLOCK, + block, + chain, + provider, + web3, + ); + + return { balances, poolBalances: {} }; +} + +export { tvl }; diff --git a/src/factory/providers/ton/bemo/index.ts b/src/factory/providers/ton/bemo/index.ts new file mode 100644 index 00000000..8f84f2ef --- /dev/null +++ b/src/factory/providers/ton/bemo/index.ts @@ -0,0 +1,20 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import formatter from '../../../../util/formatter'; + +const CONTRACT_ADDRESS = 'EQDNhy-nxYFgUqzfUzImBEP67JqsyMIcyk2S5_RwNNEYku0k'; +const METHOD = 'get_full_data'; +const TON_ADDRESS = 'ton'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + const balances = {}; + const response = await web3.eth.call(CONTRACT_ADDRESS, METHOD); + + balances[TON_ADDRESS] = response[1]; + + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/ton/daolama/index.ts b/src/factory/providers/ton/daolama/index.ts new file mode 100644 index 00000000..8b533d52 --- /dev/null +++ b/src/factory/providers/ton/daolama/index.ts @@ -0,0 +1,15 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import formatter from '../../../../util/formatter'; + +const CONTRACT_ADDRESS = 'EQAwsDboFl_iGuaflNn5959HOamenkvQEQDwakO55CY2SGB8'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + const balances = await web3.eth.getAccountBalances(CONTRACT_ADDRESS); + + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/ton/dedust/index.ts b/src/factory/providers/ton/dedust/index.ts new file mode 100644 index 00000000..a81ddabf --- /dev/null +++ b/src/factory/providers/ton/dedust/index.ts @@ -0,0 +1,27 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import axios from 'axios'; +import formatter from '../../../../util/formatter'; +import BigNumber from 'bignumber.js'; + +const POOLS_URI = 'https://api.dedust.io/v1/pools'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + const balances = {}; + const pools = (await axios.get(POOLS_URI)).data; + + pools.forEach((pool) => { + balances[pool.left_token_root] = BigNumber( + balances[pool.left_token_root] || 0, + ).plus(pool.left_token_reserve); + balances[pool.right_token_root] = BigNumber( + balances[pool.right_token_root] || 0, + ).plus(pool.right_token_reserve); + }); + + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/ton/evaa/index.ts b/src/factory/providers/ton/evaa/index.ts new file mode 100644 index 00000000..d976998a --- /dev/null +++ b/src/factory/providers/ton/evaa/index.ts @@ -0,0 +1,15 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import formatter from '../../../../util/formatter'; + +const CONTRACT_ADDRESS = 'EQC8rUZqR_pWV1BylWUlPNBzyiTYVoBEmQkMIQDZXICfnuRr'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + const balances = await web3.eth.getAccountBalances(CONTRACT_ADDRESS); + + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/ton/hipo/index.ts b/src/factory/providers/ton/hipo/index.ts new file mode 100644 index 00000000..d51a38be --- /dev/null +++ b/src/factory/providers/ton/hipo/index.ts @@ -0,0 +1,20 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import formatter from '../../../../util/formatter'; + +const CONTRACT_ADDRESS = 'EQCLyZHP4Xe8fpchQz76O-_RmUhaVc_9BAoGyJrwJrcbz2eZ'; +const METHOD = 'get_treasury_state'; +const TON_ADDRESS = 'ton'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + const balances = {}; + const response = await web3.eth.call(CONTRACT_ADDRESS, METHOD); + + balances[TON_ADDRESS] = response[0]; + + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/ton/megaton/index.ts b/src/factory/providers/ton/megaton/index.ts new file mode 100644 index 00000000..35a07ead --- /dev/null +++ b/src/factory/providers/ton/megaton/index.ts @@ -0,0 +1,32 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import axios from 'axios'; +import formatter from '../../../../util/formatter'; +import BigNumber from 'bignumber.js'; + +const POOLS_URI = 'https://megaton.fi/api/lp/infoList'; +const TON_ADDRESS = 'ton'; +const MEGA_VAULT_ADDRESS = 'EQD9Z7L2oLpWvW-NZFB9njBGg2JqIE2rpJ_Fcocg9IEQ-EGF'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + let balances = {}; + const pools = (await axios.get(POOLS_URI)).data[0]; + + pools.forEach((pool) => { + balances[pool.token0 ?? TON_ADDRESS] = BigNumber( + balances[pool.token0 ?? TON_ADDRESS] || 0, + ).plus(pool.amount0); + balances[pool.token1 ?? TON_ADDRESS] = BigNumber( + balances[pool.token1 ?? TON_ADDRESS] || 0, + ).plus(pool.amount1); + }); + + const vaultBalances = await web3.eth.getAccountBalances(MEGA_VAULT_ADDRESS); + balances = formatter.sum([balances, vaultBalances]); + + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/ton/stakee/index.ts b/src/factory/providers/ton/stakee/index.ts new file mode 100644 index 00000000..7f6e80d2 --- /dev/null +++ b/src/factory/providers/ton/stakee/index.ts @@ -0,0 +1,20 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import formatter from '../../../../util/formatter'; + +const CONTRACT_ADDRESS = 'EQD2_4d91M4TVbEBVyBF8J1UwpMJc361LKVCz6bBlffMW05o'; +const METHOD = 'get_pool_full_data'; +const TON_ADDRESS = 'ton'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + const balances = {}; + const response = await web3.eth.call(CONTRACT_ADDRESS, METHOD); + + balances[TON_ADDRESS] = response[2]; + + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/ton/ston/index.ts b/src/factory/providers/ton/ston/index.ts new file mode 100644 index 00000000..f8f6891d --- /dev/null +++ b/src/factory/providers/ton/ston/index.ts @@ -0,0 +1,34 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import axios from 'axios'; +import formatter from '../../../../util/formatter'; +import BigNumber from 'bignumber.js'; + +const POOLS_URI = 'https://app.ston.fi/rpc'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + const balances = {}; + const pools = ( + await axios.post(POOLS_URI, { + jsonrpc: '2.0', + id: 2, + method: 'pool.list', + params: {}, + }) + ).data.result.pools; + + pools.forEach((pool) => { + balances[pool.token0_address] = BigNumber( + balances[pool.token0_address] || 0, + ).plus(pool.reserve0); + balances[pool.token1_address] = BigNumber( + balances[pool.token1_address] || 0, + ).plus(pool.reserve1); + }); + + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/ton/stormtrade/index.ts b/src/factory/providers/ton/stormtrade/index.ts new file mode 100644 index 00000000..6cdbf912 --- /dev/null +++ b/src/factory/providers/ton/stormtrade/index.ts @@ -0,0 +1,25 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import formatter from '../../../../util/formatter'; + +const CONTRACT_ADDRESSES = [ + 'EQDynReiCeK8xlKRbYArpp4jyzZuF6-tYfhFM0O5ulOs5H0L', + 'EQDpJnZP89Jyxz3euDaXXFUhwCWtaOeRmiUJTi3jGYgF8fnj', + 'EQAz6ehNfL7_8NI7OVh1Qg46HsuC4kFpK-icfqK9J3Frd6CJ', + 'EQBwfRtqEf3ZzhkeGsmXiC7hzTh1C5zZZzLgDH5VL8gENQ2A', +]; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + let balances; + + for (const contractAdress of CONTRACT_ADDRESSES) { + const accountBalances = await web3.eth.getAccountBalances(contractAdress); + balances = formatter.sum([balances, accountBalances]); + } + + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/ton/tonnel/index.ts b/src/factory/providers/ton/tonnel/index.ts new file mode 100644 index 00000000..5b4b5b7c --- /dev/null +++ b/src/factory/providers/ton/tonnel/index.ts @@ -0,0 +1,33 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import formatter from '../../../../util/formatter'; + +const CONTRACT_ADDRESSES = [ + 'EQBemaU1eAM-fJP7tSniJGEmltPjitgGnlrP6UaXI7nzmEuV', + 'EQBZ0-2-isPEN_lIyg9eqXO_RFWrl_PWIJq5K6SVcUwne23W', + 'EQBYpQiQMwGBMzhOlJ52e4yXmcKCB_5uTTJ7bVSGqr-8YANi', + 'EQB-s4WzIgGP9U6DNlFH_kSn0JuxhBCBXr_rKz2ztEiozTto', + 'EQD7U_FPYRFTGgiqrpiKh8_giyrIQHZtokUKvz2EmWvlmViC', + 'EQCZXyOWRih3jtyhdCA7DV7KXluNbzqeIpJPnRkF4KEE1STp', + 'EQC14SC0-P0iOXzn1971HVIDsCzQ0LllY0y5O7EE2pMLe9pT', + 'EQDTs-yjPLn7XzaRRq8pjp7H8Nw4y_OJ51Bk2dcrPlIYgwtV', + 'EQAgoyECSzCIFTFkMIvDLgdUE3D9RxGfYQQGfxy3lBBc_Ke_', + 'EQDzAhS3Ev8cxEBJ96MIqPjxyD_k0L3enzDWnQ3Z-4tUK1h5', + 'EQASyc8d2DjZHrFevnF432NRLc4qwh6HGUPAbMvbofMkeRZl', + 'EQCNoApBzMacKKdTwcvi1iOx78e98bTSaN1Gx_nnmd3Ek5Yn', +]; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + let balances; + + for (const contractAdress of CONTRACT_ADDRESSES) { + const accountBalances = await web3.eth.getAccountBalances(contractAdress); + balances = formatter.sum([balances, accountBalances]); + } + + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/ton/tonstakers/index.ts b/src/factory/providers/ton/tonstakers/index.ts new file mode 100644 index 00000000..c700e48f --- /dev/null +++ b/src/factory/providers/ton/tonstakers/index.ts @@ -0,0 +1,20 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import formatter from '../../../../util/formatter'; + +const CONTRACT_ADDRESS = 'EQCkWxfyhAkim3g2DjKQQg8T5P4g-Q1-K_jErGcDJZ4i-vqR'; +const METHOD = 'get_pool_full_data'; +const TON_ADDRESS = 'ton'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + const balances = {}; + const response = await web3.eth.call(CONTRACT_ADDRESS, METHOD); + + balances[TON_ADDRESS] = response[2]; + + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/ton/tradoor/index.ts b/src/factory/providers/ton/tradoor/index.ts new file mode 100644 index 00000000..cfddb8c7 --- /dev/null +++ b/src/factory/providers/ton/tradoor/index.ts @@ -0,0 +1,15 @@ +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; +import formatter from '../../../../util/formatter'; + +const CONTRACT_ADDRESS = 'EQBPAMNu5Eud9AEvplOjNlRhxI4EkuJEhEMAmxh9erxmImKs'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + + const balances = await web3.eth.getAccountBalances(CONTRACT_ADDRESS); + + formatter.convertBalancesToFixed(balances); + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/xai/camelot/index.ts b/src/factory/providers/xai/camelot/index.ts new file mode 100644 index 00000000..b4c36f63 --- /dev/null +++ b/src/factory/providers/xai/camelot/index.ts @@ -0,0 +1,41 @@ +import formatter from '../../../../util/formatter'; +import uniswapV2 from '../../../../util/calculators/uniswapV2'; +import uniswapV3 from '../../../../util/calculators/uniswapV3chain'; +import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; + +const START_BLOCK = 2398999; +const V2_FACTORY_ADDRESS = '0x18E621B64d7808c3C47bccbbD7485d23F257D26f'; +const V3_FACTORY_ADDRESS = '0xD8676fBdfa5b56BB2298D452c9768f51e80e34AE'; + +async function tvl(params: ITvlParams): Promise> { + const { block, chain, provider, web3 } = params; + if (block < START_BLOCK) { + return { balances: {} }; + } + + let balances = {}; + + const v2 = await uniswapV2.getTvl( + V2_FACTORY_ADDRESS, + block, + chain, + provider, + web3, + ); + + balances = await uniswapV3.getTvl( + V3_FACTORY_ADDRESS, + START_BLOCK, + block, + chain, + provider, + web3, + 'algebra', + ); + + balances = formatter.sum([v2.balances, balances]); + + return { balances }; +} + +export { tvl }; diff --git a/src/factory/providers/zksync-era/woofi/index.ts b/src/factory/providers/zksync-era/woofi/index.ts index eb425153..bad9f623 100644 --- a/src/factory/providers/zksync-era/woofi/index.ts +++ b/src/factory/providers/zksync-era/woofi/index.ts @@ -4,7 +4,7 @@ import { ITvlParams, ITvlReturn } from '../../../../interfaces/ITvl'; import basicUtil from '../../../../util/basicUtil'; const START_BLOCK = 1466617; -const WOOPPV2_ADDRESS = '0x42ED123EB5266A5B8E2B54B2C76180CCF5e72FEe'; +const WOOPPV2_ADDRESS = '0xE656d70bc3550e3EEE9dE7dC79367A44Fd13d975'; const USDC_ADDRESS = '0x3355df6d4c9c3035724fd0e3914de96a5a83aaf4'; async function tvl(params: ITvlParams): Promise> { @@ -16,7 +16,11 @@ async function tvl(params: ITvlParams): Promise> { const tokenBalances = await util.getTokenBalances( WOOPPV2_ADDRESS, - [USDC_ADDRESS, basicUtil.getWmainAddress(chain)], + [ + USDC_ADDRESS, + basicUtil.getWmainAddress(chain), + '0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4', + ], block, chain, web3, diff --git a/src/util/basicUtil.ts b/src/util/basicUtil.ts index cc21660a..874762d5 100644 --- a/src/util/basicUtil.ts +++ b/src/util/basicUtil.ts @@ -4,7 +4,7 @@ import data from './data'; import { log } from './logger/logger'; import { config } from '../app.config'; import Redis from './redis'; -const DEFAULT_DELAY = 20; +const DEFAULT_DELAY = 0; function basicUtil() { function getPath(chain, provider) { @@ -16,11 +16,11 @@ function basicUtil() { } function getDelay(chain) { - return data.CHAINS[chain]?.delay || DEFAULT_DELAY; + return /*data.CHAINS[chain]?.delay ||*/ DEFAULT_DELAY; } async function saveIntoCache(data, fileName, chain, provider) { - await new Promise(function (resolve) { + /*await new Promise(function (resolve) { fse.outputFile( `${getPath(chain, provider)}/${fileName}`, JSON.stringify(data, null, 2), @@ -37,7 +37,7 @@ function basicUtil() { resolve(); }, ); - }); + });*/ await Redis.setCache(`${chain}_${provider}_${fileName}`, data); } diff --git a/src/util/calculators/stargateV2.ts b/src/util/calculators/stargateV2.ts new file mode 100644 index 00000000..6b328d09 --- /dev/null +++ b/src/util/calculators/stargateV2.ts @@ -0,0 +1,113 @@ +import util from '../blockchainUtil'; +import BigNumber from 'bignumber.js'; + +const CONFIG = { + ethereum: { + pools: [ + '0x77b2043768d28E9C9aB44E1aBfC95944bcE57931', + '0xc026395860Db2d07ee33e05fE50ed7bD583189C7', + '0x933597a323Eb81cAe705C5bC29985172fd5A3973', + '0xcDafB1b2dB43f366E48e6F614b8DCCBFeeFEEcD3', + '0x268Ca24DAefF1FaC2ed883c598200CcbB79E931D', + ], + }, + avalanche: { + pools: [ + '0x5634c4a5FEd09819E3c46D86A965Dd9447d86e47', + '0x12dC9256Acc9895B076f6638D628382881e62CeE', + ], + }, + optimism: { + pools: [ + '0xe8CDF27AcD73a434D661C84887215F7598e7d0d3', + '0xcE8CcA271Ebc0533920C83d39F417ED6A0abB7D0', + '0x19cFCE47eD54a88614648DC3f19A5980097007dD', + ], + }, + polygon: { + pools: [ + '0x9Aa02D4Fae7F58b8E8f34c66E756cC734DAc7fe4', + '0xd47b03ee6d86Cf251ee7860FB2ACf9f91B9fD4d7', + ], + }, + arbitrum: { + pools: [ + '0xA45B5130f36CDcA45667738e2a258AB09f4A5f7F', + '0xe8CDF27AcD73a434D661C84887215F7598e7d0d3', + '0xcE8CcA271Ebc0533920C83d39F417ED6A0abB7D0', + ], + }, + base: { + pools: [ + '0xdc181Bd607330aeeBEF6ea62e03e5e1Fb4B6F7C7', + '0x27a16dc786820B16E5c9028b75B99F6f604b5d26', + ], + }, + linea: { + pools: ['0x81F6138153d473E8c5EcebD3DC8Cd4903506B075'], + }, + bsc: { + pools: ['0x138EB30f73BC423c6455C53df6D89CB01d9eBc63'], + }, + aurora: { + pools: ['0x81F6138153d473E8c5EcebD3DC8Cd4903506B075'], + }, +}; + +async function getV2Tvl( + chain: string, + block: number, + web3: any, +): Promise<{ token: string; balance: BigNumber }[]> { + const tokens = await util.executeCallOfMultiTargets( + CONFIG[chain].pools, + [ + { + inputs: [], + name: 'token', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + ], + 'token', + [], + block, + chain, + web3, + ); + + const nativeCoinHolders = CONFIG[chain].pools.filter( + (_, index) => tokens[index] === util.ZERO_ADDRESS, + ); + + let nativeCoinBalances = []; + if (nativeCoinHolders.length > 0) { + nativeCoinBalances = await util.getBalancesOfHolders( + nativeCoinHolders, + block, + chain, + web3, + ); + } + + const tokenBalances = await util.getTokenBalancesOfHolders( + CONFIG[chain].pools, + tokens, + block, + chain, + web3, + ); + + return [...nativeCoinBalances, ...tokenBalances]; +} + +export default { + getV2Tvl, +}; diff --git a/src/util/calculators/uniswapV2.ts b/src/util/calculators/uniswapV2.ts index d99d7d69..b4df8915 100644 --- a/src/util/calculators/uniswapV2.ts +++ b/src/util/calculators/uniswapV2.ts @@ -15,10 +15,17 @@ import { import basicUtil from '../basicUtil'; import util from '../blockchainUtil'; import { log } from '../logger/logger'; +import { retryAsyncFunction, retryPromiseAll } from '../retry'; -async function getReserves(address, block, web3, chain, provider) { +async function getReserves( + address: string, + block: number, + web3: Web3, + chain: string, + provider: string, +) { try { - const contract = new web3.eth.Contract(PAIR_ABI, address); + const contract = new web3.eth.Contract(PAIR_ABI as AbiItem[], address); const reserves = await contract.methods.getReserves().call(null, block); return { pool_address: address, @@ -27,7 +34,10 @@ async function getReserves(address, block, web3, chain, provider) { }; } catch (e) { try { - const contract = new web3.eth.Contract(RESERVES_ABI, address); + const contract = new web3.eth.Contract( + RESERVES_ABI as AbiItem[], + address, + ); const reserves = await contract.methods.getReserves().call(null, block); return { pool_address: address, @@ -47,12 +57,12 @@ async function getReserves(address, block, web3, chain, provider) { } async function getPoolsReserves( - bulk_reserves_contract, - pInfos, - block, - chain, - web3, - provider, + bulk_reserves_contract: any, + pInfos: string[], + block: number, + chain: string, + web3: Web3, + provider: string, ) { let poolReserves = []; try { @@ -61,7 +71,13 @@ async function getPoolsReserves( BULK_RESERVES_DEPOLYED[chain] === undefined ) { poolReserves = await Promise.all( - pInfos.map((pool) => getReserves(pool, block, web3, chain, provider)), + pInfos.map((pool) => + retryAsyncFunction( + getReserves, + [pool, block, web3, chain, provider], + { retries: 2 }, + ), + ), ); } else { try { @@ -72,7 +88,11 @@ async function getPoolsReserves( try { poolReserves = await Promise.all( pInfos.map((pool) => - getReserves(pool, block, web3, chain, provider), + retryAsyncFunction( + getReserves, + [pool, block, web3, chain, provider], + { retries: 2 }, + ), ), ); } catch (e) { @@ -98,7 +118,7 @@ async function getPoolsReserves( } /** - * Gets TVL of Uniswap V2 (or it's clone) using factory address + * Gets TVL of Uniswap V2 (or its clone) using factory address * * @param factoryAddress - The address of factory * @param block - The block number for which data is requested @@ -152,7 +172,6 @@ async function getTvl( ); } catch {} } - const contract = new web3.eth.Contract( FACTORY_ABI as AbiItem[], factoryAddress, @@ -171,7 +190,13 @@ async function getTvl( len = await contract.methods.allPoolsLength().call(null, block); } len = Number(len); - } catch { + } catch (e) { + log.error({ + message: e?.message || '', + stack: e?.stack || '', + detail: `Error: uniswapV2.getTvl of ${chain}/${provider}`, + endpoint: 'usePoolMethods', + }); return; } @@ -184,7 +209,7 @@ async function getTvl( const pairLength = _pairs.length; for (let start = pairLength; start < len; start += 300) { - let pInfos = []; + let pInfos: Promise[] = []; const end = Math.min(start + 300, len); log.info({ message: `Getting Pairs from ${start} to ${end}`, @@ -198,9 +223,7 @@ async function getTvl( } } try { - console.log('start promiseAll'); - pInfos = await Promise.all(pInfos); - console.log('finish promiseAll'); + pInfos = await retryPromiseAll(pInfos, { retries: 2 }); pInfos.forEach((info) => poolInfos.push(info)); } catch (e) { log.error({ diff --git a/src/util/calculators/uniswapV3chain.ts b/src/util/calculators/uniswapV3chain.ts index 198c5171..eff1efeb 100644 --- a/src/util/calculators/uniswapV3chain.ts +++ b/src/util/calculators/uniswapV3chain.ts @@ -2,7 +2,6 @@ import formatter from '../../util/formatter'; import basicUtil from '../../util/basicUtil'; import util from '../../util/blockchainUtil'; import { log } from '../../util/logger/logger'; -import PAIR_ABI from '../../constants/abi/uni.json'; import { IBalances } from '../../interfaces/ITvl'; import Web3 from 'web3'; @@ -10,9 +9,11 @@ const UNISWAP_TOPIC = '0x783cca1c0412dd0d695e784568c96da2e9c22ff989357a2e8b1d9b2b4e6b7118'; const ALGEBRA_TOPIC = '0x91ccaa7a278130b65168c3a0c8d3bcae84cf5e43704342bd3ec0b59e59c036db'; +const AERODROME_TOPIC = + '0xab0d57f0df537bb25e80245ef7748fa62353808c54d6e528a9dd20887aed9ac2'; /** - * Gets TVL of Uniswap V2 (or it's clone) using factory address + * Gets TVL of Uniswap V3 (or its clone) using factory address * * @param factoryAddress - The address of factory * @param startBlock - The block number of factory deploying transaction @@ -31,141 +32,173 @@ async function getTvl( chain: string, provider: string, web3: Web3, - isAlgebra = false, + type: 'default' | 'algebra' | 'aerodrome' = 'default', ): Promise { const balances = {}; let topic: string; - if (isAlgebra) { + if (type === 'algebra') { topic = ALGEBRA_TOPIC; + } else if (type === 'aerodrome') { + topic = AERODROME_TOPIC; } else { topic = UNISWAP_TOPIC; } - let v3Pairs = { block: startBlock, pairs: [], token01: [] }; + const v3Pairs = { block: startBlock, pairs: [], token0: [], token1: [] }; try { - v3Pairs = await basicUtil.readFromCache( - 'cache/v3Pairs.json', + v3Pairs.block = await basicUtil.readFromCache( + `${factoryAddress}/uniswapV3Block.json`, + chain, + provider, + ); + v3Pairs.pairs = await basicUtil.readFromCache( + `${factoryAddress}/uniswapV3Pairs.json`, + chain, + provider, + ); + v3Pairs.token0 = await basicUtil.readFromCache( + `${factoryAddress}/uniswapV3Token0.json`, + chain, + provider, + ); + v3Pairs.token1 = await basicUtil.readFromCache( + `${factoryAddress}/uniswapV3Token1.json`, chain, provider, ); } catch {} + console.log(v3Pairs); + + const token0 = v3Pairs.token0; + const token1 = v3Pairs.token1; + const pairs = v3Pairs.pairs; + const start = 128 - 40 + 2; + const end = 128 + 2; - let logs = []; console.log('[v3] start getting tvl'); - console.log('[v3] get logs1'); let offset = 10000; - for (let i = Math.max(v3Pairs.block, startBlock); ; ) { - console.log(`Trying from ${i} with offset ${offset}`); - let eventLog = []; - try { - eventLog = ( - await util.getLogs( - i, - Math.min(block, i + offset), - topic, - factoryAddress, - web3, - ) - ).output; + + if (Math.max(v3Pairs.block, startBlock) < block) { + for (let i = Math.max(v3Pairs.block, startBlock); ; ) { console.log(`Trying from ${i} with offset ${offset}`); - } catch (e) { - log.error({ - message: e?.message || '', - stack: e?.stack || '', - detail: `Error: tvl of ethereum/uniswapv3`, - endpoint: 'tvl', - }); - if (offset > 1000) { - offset -= 2000; - } else if (offset > 100) { - offset -= 200; - } else if (offset > 10) { - offset -= 20; - } else { - break; + let eventLog = []; + try { + eventLog = ( + await util.getLogs( + i, + Math.min(block, i + offset - 1), + topic, + factoryAddress, + web3, + ) + ).output; + } catch (e) { + log.warning({ + message: e?.message || '', + stack: e?.stack || '', + detail: `Error: tvl of ethereum/uniswapv3`, + endpoint: 'tvl', + }); + if (offset >= 2000) { + offset -= 1000; + } else if (offset > 300) { + offset -= 200; + } else if (offset > 30) { + offset -= 20; + } else { + break; + } + continue; } - continue; - } - logs = logs.concat(eventLog); - i += offset; - if (block < i) { - break; - } - } - - const pairs = v3Pairs.token01; - let pairAddresses = v3Pairs.pairs; - const start = 128 - 40 + 2; - const end = 128 + 2; - - const pairExist = {}; - pairAddresses.forEach((address) => (pairExist[address] = true)); - - pairAddresses = pairAddresses.concat( - logs - .map((log) => { + eventLog.forEach((log) => { let pairAddress: string; - if (isAlgebra) { + if (type !== 'default') { pairAddress = `0x${log.data.slice(-40)}`; } else { pairAddress = `0x${log.data.slice(start, end)}`; } pairAddress = pairAddress.toLowerCase(); - pairs[pairAddress] = { - token0Address: `0x${log.topics[1].slice(26)}`, - token1Address: `0x${log.topics[2].slice(26)}`, - }; + pairs.push(pairAddress); + token0.push(`0x${log.topics[1].slice(26)}`); + token1.push(`0x${log.topics[2].slice(26)}`); + }); - return pairAddress; - }) - .filter((address) => !pairExist[address]), - ); + // Save into cache every 25 iterations + if (((i - Math.max(v3Pairs.block, startBlock)) / offset) % 25 === 0) { + console.log('save'); + await basicUtil.saveIntoCache( + i, + `${factoryAddress}/uniswapV3Block.json`, + chain, + provider, + ); + await basicUtil.saveIntoCache( + pairs, + `${factoryAddress}/uniswapV3Pairs.json`, + chain, + provider, + ); + await basicUtil.saveIntoCache( + token0, + `${factoryAddress}/uniswapV3Token0.json`, + chain, + provider, + ); + await basicUtil.saveIntoCache( + token1, + `${factoryAddress}/uniswapV3Token1.json`, + chain, + provider, + ); + } - await basicUtil.saveIntoCache( - { - block, - pairs: pairAddresses, - token01: pairs, - }, - 'cache/v3Pairs.json', - chain, - provider, - ); + i += offset; + if (block < i) { + break; + } + } - const tokens0 = await util.executeCallOfMultiTargets( - pairAddresses, - PAIR_ABI, - 'token0', - [], - block, - chain, - web3, - ); - const tokens1 = await util.executeCallOfMultiTargets( - pairAddresses, - PAIR_ABI, - 'token1', - [], - block, - chain, - web3, - ); + // Save into cache on the last iteration + await basicUtil.saveIntoCache( + block, + `${factoryAddress}/uniswapV3Block.json`, + chain, + provider, + ); + await basicUtil.saveIntoCache( + pairs, + `${factoryAddress}/uniswapV3Pairs.json`, + chain, + provider, + ); + await basicUtil.saveIntoCache( + token0, + `${factoryAddress}/uniswapV3Token0.json`, + chain, + provider, + ); + await basicUtil.saveIntoCache( + token1, + `${factoryAddress}/uniswapV3Token1.json`, + chain, + provider, + ); + } const token0Balances = await util.getTokenBalancesOfHolders( - pairAddresses, - tokens0.filter(Boolean), + pairs, + token0, block, chain, web3, ); - const token1Balances = await util.getTokenBalancesOfHolders( - pairAddresses, - tokens1.filter(Boolean), + pairs, + token1, block, chain, web3, diff --git a/src/util/data.ts b/src/util/data.ts index d7a1acf1..dd48a241 100644 --- a/src/util/data.ts +++ b/src/util/data.ts @@ -99,6 +99,18 @@ const data = { prefix: 'apt_', delay: 4600, }, + ton: { + prefix: 'ton_', + delay: 0, + }, + 'skale-europa': { + prefix: 'skeur_', + delay: 0, + }, + etherlink: { + prefix: 'etherlink_', + delay: 0, + }, }, FILTERS: { MarketCapInFiat: 'marketCapInFiat', diff --git a/src/util/retry.ts b/src/util/retry.ts new file mode 100644 index 00000000..1507e704 --- /dev/null +++ b/src/util/retry.ts @@ -0,0 +1,43 @@ +import retry from 'retry'; + +/** + * Retry an asynchronous function with specified options. + * @param {Function} asyncFunction - The asynchronous function to retry. + * @param {Array} args - The arguments to pass to the asynchronous function. + * @param {Object} options - Retry options. + * @returns {Promise} - The result of the asynchronous function. + */ +export async function retryAsyncFunction( + asyncFunction: (...args: any[]) => Promise, + args: any[], + options = {}, +): Promise { + return new Promise((resolve, reject) => { + const operation = retry.operation(options); + + operation.attempt(async (currentAttempt) => { + try { + const result = await asyncFunction(...args); + resolve(result); + } catch (error) { + if (operation.retry(error)) { + return; + } + reject(operation.mainError()); + } + }); + }); +} + +/** + * Retry a Promise.all call with specified options. + * @param {Promise[]} promises - The array of promises to retry. + * @param {Object} options - Retry options. + * @returns {Promise} - The result of Promise.all. + */ +export async function retryPromiseAll( + promises: Promise[], + options = {}, +): Promise { + return retryAsyncFunction(Promise.all.bind(Promise), [promises], options); +} diff --git a/src/web3Provider/ton.ts b/src/web3Provider/ton.ts new file mode 100644 index 00000000..1ab3ec4a --- /dev/null +++ b/src/web3Provider/ton.ts @@ -0,0 +1,84 @@ +import { Injectable } from '@nestjs/common'; +import axios from 'axios'; +import Bottleneck from 'bottleneck'; + +const ton_center_api_url = 'https://toncenter.com/api'; +const ton_center_api_headers = { + headers: { + 'X-API-Key': process.env.TONCENTER_API_KEY, + }, +}; +const ton_api_url = 'https://tonapi.io'; + +const limiter = new Bottleneck({ + minTime: 1000, // 1 request per second +}); + +@Injectable() +export class Ton { + async call(address, method, params = []) { + const requestBody = { + address, + method, + stack: params, + }; + + const response = await limiter + .schedule(() => + axios.post( + `${ton_center_api_url}/v2/runGetMethod`, + requestBody, + ton_center_api_headers, + ), + ) + .then((response) => response.data.result); + + const { exit_code, stack } = response; + if (exit_code !== 0) { + throw new Error('Expected a zero exit code, but got ' + exit_code); + } + stack.forEach((i, idx) => { + if (i[0] === 'num') { + stack[idx] = parseInt(i[1], 16); + } + }); + + return stack; + } + + async getAccountBalances(address) { + const balances = {}; + + let response = await axios + .get(`${ton_api_url}/v2/accounts/${address}/jettons?currencies=usd`) + .then((response) => response.data); + for (const balance of response.balances) { + const packedAddress = await limiter + .schedule(() => + axios.get( + `${ton_center_api_url}/v2/packAddress?address=${balance.jetton.address}`, + ton_center_api_headers, + ), + ) + .then((response) => response.data.result); + const customSafePackedAddress = this.customUrlSafeEncode(packedAddress); + balances[customSafePackedAddress] = balance.balance; + } + + response = await limiter + .schedule(() => + axios.get( + `${ton_center_api_url}/v3/account?address=${address}`, + ton_center_api_headers, + ), + ) + .then((response) => response.data); + balances['ton'] = response.balance; + + return balances; + } + + customUrlSafeEncode(address) { + return address.replace(/\//g, '_').replace(/\+/g, '-'); + } +} diff --git a/src/web3Provider/web3Provider.module.ts b/src/web3Provider/web3Provider.module.ts index fbd8bfff..b3d3f1c0 100644 --- a/src/web3Provider/web3Provider.module.ts +++ b/src/web3Provider/web3Provider.module.ts @@ -8,6 +8,7 @@ import { Near } from './near'; import { Tezos } from './tezos'; import { Wax } from './wax'; import { Aptos } from './aptos'; +import { Ton } from './ton'; @Module({ exports: [Web3ProviderService], @@ -21,6 +22,7 @@ import { Aptos } from './aptos'; Tezos, Wax, Aptos, + Ton, ], }) export class Web3ProviderModule {} diff --git a/src/web3Provider/web3Provider.service.ts b/src/web3Provider/web3Provider.service.ts index cf05ed1b..60d5156f 100644 --- a/src/web3Provider/web3Provider.service.ts +++ b/src/web3Provider/web3Provider.service.ts @@ -9,6 +9,7 @@ import { Tezos } from './tezos'; import Web3 from 'web3'; import { Wax } from './wax'; import { Aptos } from './aptos'; +import { Ton } from './ton'; const webSocketConfig = { timeout: 60000, @@ -38,6 +39,7 @@ export class Web3ProviderService { private readonly tezos: Tezos, private readonly wax: Wax, private readonly aptos: Aptos, + private readonly ton: Ton, ) {} async getWeb3(chain = 'ethereum') { @@ -56,7 +58,6 @@ export class Web3ProviderService { nodeUrls[`ETHEREUM_NODE_URL`]); let web3; - console.log(nodeUrls[`${chain.toUpperCase()}_NODE_URL`]); switch (chain) { case 'everscale': { web3 = { eth: this.everscale }; @@ -92,6 +93,10 @@ export class Web3ProviderService { await web3.eth.onModuleInit(); break; } + case 'ton': { + web3 = { eth: this.ton }; + break; + } default: { if (node_url.startsWith('ws')) { web3 = new Web3(