diff --git a/adapters/types.ts b/adapters/types.ts index c524a2b3e2..f88c610e22 100644 --- a/adapters/types.ts +++ b/adapters/types.ts @@ -1,4 +1,4 @@ -import { Balances, util } from '@defillama/sdk'; +import { Balances, ChainApi, util } from '@defillama/sdk'; const { blocks: { getChainBlocks } } = util @@ -26,10 +26,12 @@ export type FetchOptions = { getFromBlock: () => Promise; getToBlock: () => Promise; chain: string, + api: ChainApi, } export type FetchGetLogsOptions = { - eventAbi: string, + eventAbi?: string, + topic?: string, target?: string, targets?: string[], onlyArgs?: boolean, diff --git a/adapters/utils/runAdapter.ts b/adapters/utils/runAdapter.ts index f123bbdf95..dfd707946a 100644 --- a/adapters/utils/runAdapter.ts +++ b/adapters/utils/runAdapter.ts @@ -1,4 +1,4 @@ -import { Balances, getEventLogs } from '@defillama/sdk' +import { Balances, ChainApi, getEventLogs } from '@defillama/sdk' import { BaseAdapter, ChainBlocks, DISABLED_ADAPTER_KEY, FetchGetLogsOptions, FetchResultGeneric, } from '../types' import { getBlock } from "../../helpers/getBlock"; @@ -44,20 +44,21 @@ export default async function runAdapter(volumeAdapter: BaseAdapter, cleanCurren } function getOptionsObject(timestamp: number, chain: string, chainBlocks: ChainBlocks) { + const closeToCurrentTime = Math.trunc(Date.now() / 1000) - timestamp < 12 * 60 * 60 // 12 hours + const withinTwoHours = Math.trunc(Date.now() / 1000) - timestamp < 2 * 60 * 60 // 2 hours const createBalances: () => Balances = () => { - const closeToCurrentTime = Math.trunc(Date.now() / 1000) - timestamp < 12 * 60 * 60 // 12 hours - return new Balances({ timestamp: closeToCurrentTime ? timestamp : undefined, chain }) + return new Balances({ timestamp: closeToCurrentTime ? undefined : timestamp, chain }) } const toTimestamp = timestamp - 1 const fromTimestamp = toTimestamp - ONE_DAY_IN_SECONDS const fromChainBlocks = {} const getFromBlock = async () => await getBlock(fromTimestamp, chain, fromChainBlocks) const getToBlock = async () => await getBlock(toTimestamp, chain, chainBlocks) - const getLogs = async ({ target, targets, onlyArgs = true, fromBlock, toBlock, flatten = true, eventAbi, topics, }: FetchGetLogsOptions) => { + const getLogs = async ({ target, targets, onlyArgs = true, fromBlock, toBlock, flatten = true, eventAbi, topics, topic, }: FetchGetLogsOptions) => { fromBlock = fromBlock ?? await getFromBlock() toBlock = toBlock ?? await getToBlock() - return getEventLogs({ fromBlock, toBlock, chain, target, targets, onlyArgs, flatten, eventAbi, topics, }) + return getEventLogs({ fromBlock, toBlock, chain, target, targets, onlyArgs, flatten, eventAbi, topics, topic, }) } return { @@ -69,6 +70,7 @@ export default async function runAdapter(volumeAdapter: BaseAdapter, cleanCurren getToBlock, getLogs, chain, + api: new ChainApi({ chain, timestamp: withinTwoHours ? undefined : timestamp, }), } } diff --git a/cli/utils.ts b/cli/utils.ts index df2f589833..95feec5748 100644 --- a/cli/utils.ts +++ b/cli/utils.ts @@ -35,8 +35,8 @@ export function printVolumes(volumes: any[], baseAdapter?: BaseAdapter) { else if (!methodology) console.log("NO METHODOLOGY SPECIFIED") Object.entries(element).forEach(([attribute, value]) => { if (!exclude2Print.includes(attribute)) { - const valueFormatted = typeof value === 'object' ? JSON.stringify(value, null, 2) : attribute==="timestamp"?value: humanizeNumber(Number(value)) - console.info(`${camelCaseToSpaces(attribute)}: ${valueFormatted}`) + const valueFormatted = typeof value === 'object' ? JSON.stringify(value, null, 2) : attribute === "timestamp" ? value + ` (${new Date((value as any) * 1e3).toISOString()})` : humanizeNumber(Number(value)) + console.info(`${camelCaseToSpaces(attribute)}: ${valueFormatted}`) if (valueFormatted !== undefined && typeof methodology === 'object' && methodology[attribute.slice(5)]) console.log("└─ Methodology:", methodology?.[attribute.slice(5)]) } diff --git a/dexs/aerodrome/index.ts b/dexs/aerodrome/index.ts index 1af2fe4ffa..6d271e322b 100644 --- a/dexs/aerodrome/index.ts +++ b/dexs/aerodrome/index.ts @@ -1,17 +1,7 @@ -import { FetchResultFees, FetchResultVolume, SimpleAdapter } from "../../adapters/types" +import { FetchOptions, FetchResultVolume, SimpleAdapter } from "../../adapters/types" import { CHAIN } from "../../helpers/chains" -import * as sdk from "@defillama/sdk"; -import { getBlock } from "../../helpers/getBlock"; -import { ethers } from "ethers"; -import { getPrices } from "../../utils/prices"; const gurar = '0x2073D8035bB2b0F2e85aAF5a8732C6f397F9ff9b'; -type TPrice = { - [s: string]: { - price: number; - decimals: number - }; -} const abis: any = { "forSwaps": "function forSwaps() view returns ((address lp, bool stable, address token0, address token1, address factory)[])" } @@ -28,17 +18,11 @@ interface ILog { transactionHash: string; topics: string[]; } -const topic0_swap = '0xb3e2773606abfd36b5bd91394b3a54d1398336c65005baf7bf7a05efeffaf75b' const event_swap = 'event Swap(address indexed sender,address indexed to,uint256 amount0In,uint256 amount1In,uint256 amount0Out,uint256 amount1Out)' -const contract_interface = new ethers.Interface([ - event_swap -]) - -const fetch = async (timestamp: number): Promise => { - const fromTimestamp = timestamp - 60 * 60 * 24 - const toTimestamp = timestamp - const forSwaps: IForSwap[] = (await sdk.api2.abi.call({ +const fetch = async (timestamp: number, _: any, { api, getLogs, createBalances, }: FetchOptions): Promise => { + const dailyVolume = createBalances() + const forSwaps: IForSwap[] = (await api.call({ target: gurar, abi: abis.forSwaps, chain: CHAIN.BASE, @@ -50,55 +34,28 @@ const fetch = async (timestamp: number): Promise => { } }) - const fromBlock = (await getBlock(fromTimestamp, CHAIN.BASE, {})); - const toBlock = (await getBlock(toTimestamp, CHAIN.BASE, {})); - - const logs: ILog[] = (await Promise.all(forSwaps.map((forSwaps: IForSwap) => sdk.getEventLogs({ - target: forSwaps.lp, - toBlock: toBlock, - fromBlock: fromBlock, - chain: CHAIN.BASE, - topics: [topic0_swap] - })))).flat(); + const targets = forSwaps.map((forSwap: IForSwap) => forSwap.lp) - const coins = [...new Set([ - ...forSwaps.map((log: IForSwap) => `${CHAIN.BASE}:${log.token0}`), - ...forSwaps.map((log: IForSwap) => `${CHAIN.BASE}:${log.token1}`) - ])] + const logs: ILog[][] = await getLogs({ + targets, + eventAbi: event_swap, + flatten: false, + }) - const coins_split: string[][] = []; - for (let i = 0; i < coins.length; i += 100) { - coins_split.push(coins.slice(i, i + 100)) - } - const prices_result: any = (await Promise.all(coins_split.map((a: string[]) => getPrices(a, timestamp)))).flat().flat().flat(); - const prices: TPrice = Object.assign({}, {}); - prices_result.map((a: any) => Object.assign(prices, a)) - const volumeUSD: number = logs.map((log: ILog) => { - const value = contract_interface.parseLog(log); - const amount0In = Number(value!.args.amount0In); - const amount1In = Number(value!.args.amount1In); - const amount0Out = Number(value!.args.amount0Out); - const amount1Out = Number(value!.args.amount1Out); - const { token0, token1 } = forSwaps.find((forSwap: IForSwap) => forSwap.lp.toLowerCase() === log.address.toLowerCase()) as IForSwap - const token0Decimals = prices[`${CHAIN.BASE}:${token0}`]?.decimals || 0 - const token1Decimals = prices[`${CHAIN.BASE}:${token1}`]?.decimals || 0 - const price0 = prices[`${CHAIN.BASE}:${token0}`]?.price || 0 - const price1 = prices[`${CHAIN.BASE}:${token1}`]?.price || 0 - const totalAmount0 = ((amount0In + amount0Out) / 10 ** token0Decimals) * price0 - const totalAmount1 = ((amount1In + amount1Out) / 10 ** token1Decimals) * price1 - const untrackAmountUSD = price0 !== 0 ? totalAmount0 : price1 !== 0 ? totalAmount1 : 0; - return untrackAmountUSD; - }).reduce((a: number, b: number) => a + b, 0) + logs.forEach((logs: ILog[], idx: number) => { + const { token0, token1 } = forSwaps[idx] + logs.forEach((log: any) => { + dailyVolume.add(token0, log.amount0Out) + dailyVolume.add(token1, log.amount1Out) + }) + }) - return { - dailyVolume: `${volumeUSD}`, - timestamp - } + return { dailyVolume, timestamp } } const adapters: SimpleAdapter = { adapter: { [CHAIN.BASE]: { - fetch: fetch, + fetch: fetch as any, start: 1693180800, } } diff --git a/dexs/airswap/index.ts b/dexs/airswap/index.ts index 6068de2816..fac0ab7400 100644 --- a/dexs/airswap/index.ts +++ b/dexs/airswap/index.ts @@ -1,27 +1,7 @@ -import { FetchResultVolume, SimpleAdapter } from "../../adapters/types"; +import { Fetch, FetchOptions, FetchResultVolume, SimpleAdapter } from "../../adapters/types"; import { CHAIN } from "../../helpers/chains"; -import * as sdk from "@defillama/sdk"; -import { getBlock } from "../../helpers/getBlock"; -import { getPrices } from "../../utils/prices"; -import { Chain } from "@defillama/sdk/build/general"; -import { ethers, } from "ethers"; - -interface ITx { - data: string; - transactionHash: string; - topics: string[]; -} -interface IData { - signerAmount: number; - signerToken: string; -} const event_swap = 'event SwapERC20(uint256 indexed nonce,address indexed signerWallet,address signerToken,uint256 signerAmount,uint256 protocolFee,address indexed senderWallet,address senderToken,uint256 senderAmount)'; -const topic0 = '0xb651f2787ff61b5ab14f3936f2daebdad3d84aeb74438e82870cc3b7aee71e90'; - -const contract_interface = new ethers.Interface([ - event_swap -]); type TAddress = { [c: string]: string; @@ -34,67 +14,24 @@ const address: TAddress = { [CHAIN.ARBITRUM]: '0xd82FA167727a4dc6D6F55830A2c47aBbB4b3a0F8' } -const graph = (chain: Chain) => { - return async (timestamp: number): Promise => { - const fromTimestamp = timestamp - 60 * 60 * 24 - const toTimestamp = timestamp - const fromBlock = (await getBlock(fromTimestamp, chain, {})); - const toBlock = (await getBlock(toTimestamp, chain, {})); - - const logs: ITx[] = (await sdk.getEventLogs({ - target: address[chain], - toBlock: toBlock, - fromBlock: fromBlock, - chain: chain, - topics: [topic0] - })).map((e: any) => { return { data: e.data, transactionHash: e.transactionHash, topics: e.topics } as ITx }); - const rawData = logs.map((e: ITx) => { - const data = contract_interface.parseLog(e); - return { - signerAmount: Number(data!.args.signerAmount), - signerToken: data!.args.signerToken, - } - }) - const rawCoins = rawData.map((e: IData) => `${chain}:${e.signerToken.toLowerCase()}`); - const coins = [...new Set(rawCoins)] - const prices = await getPrices(coins, timestamp); - const untrackVolumes: number[] = rawData.map((e: IData) => { - const decimals = prices[`${chain}:${e.signerToken.toLowerCase()}`].decimals; - const price = prices[`${chain}:${e.signerToken.toLowerCase()}`].price; - return (Number(e.signerAmount) / 10 ** decimals) * price; - }); - - const dailyVolume = untrackVolumes.reduce((a: number, b: number) => a + b, 0); - return { - dailyVolume: `${dailyVolume}`, - timestamp, - }; - } -} +const fetch = (async (timestamp: number, _: any, { getLogs, createBalances, chain }: FetchOptions): Promise => { + const dailyVolume = createBalances(); + const logs = (await getLogs({ + target: address[chain], + eventAbi: event_swap, + })) + logs.forEach(i => dailyVolume.add(i.signerToken, i.signerAmount)) + return { dailyVolume, timestamp, }; +}) as Fetch const adapter: SimpleAdapter = { adapter: { - [CHAIN.ETHEREUM]: { - fetch: graph(CHAIN.ETHEREUM), - start: 1680307200, - }, - [CHAIN.POLYGON]: { - fetch: graph(CHAIN.POLYGON), - start: 1680307200, - }, - [CHAIN.AVAX]: { - fetch: graph(CHAIN.AVAX), - start: 1680307200, - }, - [CHAIN.BSC]: { - fetch: graph(CHAIN.BSC), - start: 1680307200, - }, - [CHAIN.ARBITRUM]: { - fetch: graph(CHAIN.ARBITRUM), - start: 1689811200, - }, + [CHAIN.ETHEREUM]: { fetch, start: 1680307200, }, + [CHAIN.POLYGON]: { fetch, start: 1680307200, }, + [CHAIN.AVAX]: { fetch, start: 1680307200, }, + [CHAIN.BSC]: { fetch, start: 1680307200, }, + [CHAIN.ARBITRUM]: { fetch, start: 1689811200, }, } }; diff --git a/dexs/e3/index.ts b/dexs/e3/index.ts index 905a315e76..521d937ac7 100644 --- a/dexs/e3/index.ts +++ b/dexs/e3/index.ts @@ -1,28 +1,9 @@ -import { SimpleAdapter } from "../../adapters/types"; +import { ChainBlocks, SimpleAdapter } from "../../adapters/types"; import { CHAIN } from "../../helpers/chains"; -import * as sdk from "@defillama/sdk"; -import { getBlock } from "../../helpers/getBlock"; -import { getPrices } from "../../utils/prices"; -import { Chain } from "@defillama/sdk/build/general"; -import { ethers, } from "ethers"; -interface ILog { - data: string; - transactionHash: string; - topics: string[]; -} -interface IAmount { - amountInX: number; - amountInY: number; -} const event_swap = 'event Swap(address indexed sender,address indexed to,uint24 id,bytes32 amountsIn,bytes32 amountsOut,uint24 volatilityAccumulator,bytes32 totalFees,bytes32 protocolFees)'; -const topic0 = '0xad7d6f97abf51ce18e17a38f4d70e975be9c0708474987bb3e26ad21bd93ca70'; const FACTORY_ADDRESS = '0x8597db3ba8de6baadeda8cba4dac653e24a0e57b'; -const contract_interface = new ethers.Interface([ - event_swap -]); - type TABI = { [k: string]: string; } @@ -31,101 +12,40 @@ const ABIs: TABI = { "getLBPairAtIndex": "function getLBPairAtIndex(uint256 index) view returns (address lbPair)" } -const graph = (_chain: Chain) => { - return async (timestamp: number) => { - const fromTimestamp = timestamp - 60 * 60 * 24 - const toTimestamp = timestamp - const poolLength = (await sdk.api2.abi.call({ - target: FACTORY_ADDRESS, - chain: _chain, - abi: ABIs.getNumberOfLBPairs, - })); - - const poolsRes = await sdk.api2.abi.multiCall({ - abi: ABIs.getLBPairAtIndex, - calls: Array.from(Array(Number(poolLength)).keys()).map((i) => ({ - target: FACTORY_ADDRESS, - params: i, - })), - chain: _chain - }); - - const lpTokens = poolsRes - - const [underlyingToken0, underlyingToken1] = await Promise.all( - ['address:getTokenX', 'address:getTokenY'].map((abi: string) => - sdk.api2.abi.multiCall({ - abi, - calls: lpTokens, - chain: _chain - }) - ) - ); - - const tokens0 = underlyingToken0; - const tokens1 = underlyingToken1; - const fromBlock = (await getBlock(fromTimestamp, _chain, {})); - const toBlock = (await getBlock(toTimestamp, _chain, {})); - - const logs: ILog[][] = (await Promise.all(lpTokens.map((address: string) => sdk.getEventLogs({ - target: address, - toBlock: toBlock, - fromBlock: fromBlock, - chain: _chain, - topics: [topic0] - })))) as any; - - const rawCoins = [...tokens0, ...tokens1].map((e: string) => `${_chain}:${e}`); - const coins = [...new Set(rawCoins)] - const prices = await getPrices(coins, timestamp); - - - const untrackVolumes: number[] = lpTokens.map((_: string, index: number) => { - const token0Decimals = prices[`${_chain}:${tokens0[index]}`]?.decimals || 0 - const token1Decimals = prices[`${_chain}:${tokens1[index]}`]?.decimals || 0 - const log: IAmount[] = logs[index] - .map((e: ILog) => { return { ...e } }) - .map((p: ILog) => { - const value = contract_interface.parseLog(p); - const amountInX = Number('0x' + '0'.repeat(32) + value!.args.amountsIn.replace('0x', '').slice(0, 32)) / 10 ** token1Decimals - const amountInY = Number('0x' + '0'.repeat(32) + value!.args.amountsIn.replace('0x', '').slice(32, 64)) / 10 ** token0Decimals - return { - amountInX, - amountInY, - } as IAmount - }) as IAmount[]; - - const token0Price = (prices[`${_chain}:${tokens0[index]}`]?.price || 0); - const token1Price = (prices[`${_chain}:${tokens1[index]}`]?.price || 0); - const totalAmountInX = log - .reduce((a: number, b: IAmount) => Number(b.amountInX) + a, 0) * token1Price; - const totalAmountInY = log - .reduce((a: number, b: IAmount) => Number(b.amountInY) + a, 0) * token0Price; - const untrackAmountUSD = (totalAmountInX + totalAmountInY); // counted only we have price data - return untrackAmountUSD; - }); - const dailyVolume = untrackVolumes.reduce((a: number, b: number) => a + b, 0); - return { - dailyVolume: `${dailyVolume}`, - timestamp, - }; - } +const fetch: any = async (timestamp: number, _: ChainBlocks, { getLogs, api, createBalances }) => { + const dailyVolume = createBalances(); + const lpTokens = await api.fetchList({ lengthAbi: ABIs.getNumberOfLBPairs, itemAbi: ABIs.getLBPairAtIndex, target: FACTORY_ADDRESS }) + + const [underlyingToken0, underlyingToken1] = await Promise.all(['address:getTokenX', 'address:getTokenY'].map((abi: string) => api.multiCall({ abi, calls: lpTokens, }))); + + const tokens0 = underlyingToken0; + const tokens1 = underlyingToken1; + + const logs: any[][] = await getLogs({ + targets: lpTokens, + flatten: false, + eventAbi: event_swap, + }) as any; + + logs.forEach((logs: any[], index: number) => { + const token0 = tokens0[index]; + const token1 = tokens1[index]; + logs.forEach((log: any) => { + const amountInX = Number('0x' + '0'.repeat(32) + log.amountsOut.replace('0x', '').slice(0, 32)) + const amountInY = Number('0x' + '0'.repeat(32) + log.amountsOut.replace('0x', '').slice(32, 64)) + dailyVolume.add(token1, amountInX); + dailyVolume.add(token0, amountInY); + }) + }) + + return { dailyVolume, timestamp, }; } const adapter: SimpleAdapter = { adapter: { - [CHAIN.FANTOM]: { - fetch: graph(CHAIN.FANTOM), - start: 1681130543, - }, - [CHAIN.ARBITRUM]: { - fetch: graph(CHAIN.ARBITRUM), - start: 1686459416, - }, - [CHAIN.BASE]: { - fetch: graph(CHAIN.BASE), - start: 1691547000, - } + [CHAIN.FANTOM]: { fetch, start: 1681130543, }, + [CHAIN.ARBITRUM]: { fetch, start: 1686459416, }, + [CHAIN.BASE]: { fetch, start: 1691547000, } } }; diff --git a/dexs/emdx/index.ts b/dexs/emdx/index.ts index af7e1082af..4f38518bca 100644 --- a/dexs/emdx/index.ts +++ b/dexs/emdx/index.ts @@ -1,44 +1,22 @@ -import { Adapter } from "../../adapters/types"; +import { Adapter, FetchOptions } from "../../adapters/types"; import { CHAIN } from "../../helpers/chains"; -import { getTimestampAtStartOfDayUTC, getTimestampAtStartOfNextDayUTC } from "../../utils/date"; -import * as sdk from "@defillama/sdk"; -import { getBlock } from "../../helpers/getBlock"; const address = '0xbfb083840b0507670b92456264164e5fecd0430b'; -const topic0 = '0x4c7b764f428c13bbea8cc8da90ebe6eef4dafeb27a4e3d9041d64208c47ca7c2'; +const topic = '0x4c7b764f428c13bbea8cc8da90ebe6eef4dafeb27a4e3d9041d64208c47ca7c2'; -interface ITx { - data: string; - transactionHash: string; -} - -const fetch = async (timestamp: number) => { - const todaysTimestamp = getTimestampAtStartOfDayUTC(timestamp) - const yesterdaysTimestamp = getTimestampAtStartOfNextDayUTC(timestamp) - - const fromBlock = (await getBlock(todaysTimestamp, CHAIN.AVAX, {})); - const toBlock = (await getBlock(yesterdaysTimestamp, CHAIN.AVAX, {})); - const logs: ITx[] = (await sdk.getEventLogs({ - target: address, - fromBlock: fromBlock, - toBlock: toBlock, - topics: [topic0], - chain: CHAIN.AVAX - })).map((e: any) => { return { data: e.data.replace('0x', ''), transactionHash: e.transactionHash } as ITx}); - const dailyVolume = logs.map((tx: ITx) => { - const amount = Number('0x' + tx.data.slice(64, 128)) / 10 ** 18; +const fetch: any = async (timestamp: number, _, { getLogs, }: FetchOptions) => { + const logs: any[] = await getLogs({ target: address, topic, }) + const dailyVolume = logs.map((tx: any) => { + const amount = Number('0x' + tx.data.slice(64, 128)) / 10 ** 18; return amount; - }).reduce((a: number, b: number) => a+b,0); - return { - timestamp: timestamp, - dailyVolume: dailyVolume ? `${dailyVolume}` : undefined, - }; + }).reduce((a: number, b: number) => a + b, 0); + return { timestamp, dailyVolume, }; } const adapter: Adapter = { adapter: { [CHAIN.AVAX]: { - fetch: fetch, + fetch, start: 1653134400 }, } diff --git a/dexs/gains-network/index.ts b/dexs/gains-network/index.ts index c68a5167d1..78a744b4b2 100644 --- a/dexs/gains-network/index.ts +++ b/dexs/gains-network/index.ts @@ -1,9 +1,6 @@ import { FetchResultVolume, SimpleAdapter } from "../../adapters/types"; import { CHAIN } from "../../helpers/chains"; -import * as sdk from "@defillama/sdk"; -import { getBlock } from "../../helpers/getBlock"; import { Chain } from "@defillama/sdk/build/general"; -import { getTimestampAtStartOfDayUTC, getTimestampAtStartOfNextDayUTC } from "../../utils/date"; type IAddresses = { [s: string | Chain]: string[]; @@ -41,80 +38,58 @@ const contract_addresses: IAddresses = { ], }; -const fetch = (chain: Chain) => { - return async (timestamp: number): Promise => { - const fromTimestamp = getTimestampAtStartOfDayUTC(timestamp); - const toTimestamp = getTimestampAtStartOfNextDayUTC(timestamp); +const fetch: any = async (timestamp: number, _, { getLogs, createBalances, chain }): Promise => { + const limitLogs: ILog[] = ( + (await Promise.all( + topic0_limit_ex.map(async (topic0) => + getLogs({ + targets: contract_addresses[chain], + topics: [topic0], + }) + ) + )) as ILog[][] + ).flat(); - const fromBlock = await getBlock(fromTimestamp, chain, {}); - const toBlock = await getBlock(toTimestamp, chain, {}); - const limitLogs: ILog[] = ( - (await Promise.all( - topic0_limit_ex.map(async (topic0) => - sdk.getEventLogs({ - targets: contract_addresses[chain], - toBlock: toBlock, - fromBlock: fromBlock, - chain: chain, - topics: [topic0], - }) - ) - )) as ILog[][] - ).reduce((acc, curr) => [...acc, ...curr], []); + const marketLogs: ILog[] = ( + (await Promise.all( + topic0_market_ex.map(async (topic0) => + getLogs({ + targets: contract_addresses[chain], + topics: [topic0], + }) + ) + )) as ILog[][] + ).flat(); - const marketLogs: ILog[] = ( - (await Promise.all( - topic0_market_ex.map(async (topic0) => - sdk.getEventLogs({ - targets: contract_addresses[chain], - toBlock: toBlock, - fromBlock: fromBlock, - chain: chain, - topics: [topic0], - }) - ) - )) as ILog[][] - ).reduce((acc, curr) => [...acc, ...curr], []); + const limit_volume = limitLogs + .map((e: ILog) => { + const data = e.data.replace("0x", ""); + const leverage = Number("0x" + data.slice(512, 576)); + const positionSizeDai = Number("0x" + data.slice(896, 960)) / (precisionException[e.address] ?? 1e18); + const collateralPrice = (data.length === 1216 ? Number("0x" + data.slice(1088, 1152)) : 1e8) / 1e8; + return leverage * positionSizeDai * collateralPrice; + }) + .reduce((a: number, b: number) => a + b, 0); - const limit_volume = limitLogs - .map((e: ILog) => { - const data = e.data.replace("0x", ""); - const leverage = Number("0x" + data.slice(512, 576)); - const positionSizeDai = Number("0x" + data.slice(896, 960)) / (precisionException[e.address] ?? 1e18); - const collateralPrice = (data.length === 1216 ? Number("0x" + data.slice(1088, 1152)) : 1e8) / 1e8; - return leverage * positionSizeDai * collateralPrice; - }) - .reduce((a: number, b: number) => a + b, 0); + const market_volume = marketLogs + .map((e: ILog) => { + const data = e.data.replace("0x", ""); + const leverage = Number("0x" + data.slice(448, 512)); + const positionSizeDai = Number("0x" + data.slice(832, 896)) / (precisionException[e.address] ?? 1e18); + const collateralPrice = (data.length === 1088 ? Number("0x" + data.slice(1024, 1088)) : 1e8) / 1e8; + return leverage * positionSizeDai * collateralPrice; + }) + .reduce((a: number, b: number) => a + b, 0); - const market_volume = marketLogs - .map((e: ILog) => { - const data = e.data.replace("0x", ""); - const leverage = Number("0x" + data.slice(448, 512)); - const positionSizeDai = Number("0x" + data.slice(832, 896)) / (precisionException[e.address] ?? 1e18); - const collateralPrice = (data.length === 1088 ? Number("0x" + data.slice(1024, 1088)) : 1e8) / 1e8; - return leverage * positionSizeDai * collateralPrice; - }) - .reduce((a: number, b: number) => a + b, 0); + const dailyVolume = limit_volume + market_volume; - const dailyVolume = limit_volume + market_volume; - - return { - dailyVolume: `${dailyVolume}`, - timestamp, - }; - }; + return { dailyVolume, timestamp, }; }; const adapter: SimpleAdapter = { adapter: { - [CHAIN.ARBITRUM]: { - fetch: fetch(CHAIN.ARBITRUM), - start: 1684972800, - }, - [CHAIN.POLYGON]: { - fetch: fetch(CHAIN.POLYGON), - start: 1684972800, - }, + [CHAIN.ARBITRUM]: { fetch, start: 1684972800, }, + [CHAIN.POLYGON]: { fetch, start: 1684972800, }, }, }; diff --git a/helpers/dexVolumeLogs.ts b/helpers/dexVolumeLogs.ts index 6e283d95ff..8f76fd9770 100644 --- a/helpers/dexVolumeLogs.ts +++ b/helpers/dexVolumeLogs.ts @@ -1,34 +1,26 @@ -import * as sdk from "@defillama/sdk"; +import { FetchOptions } from "../adapters/types"; const swapEvent = "event Swap(address indexed sender, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out, address indexed to)" // const swapTopic = "0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822" -type getDexVolumeParams = { chain: string, fromTimestamp: number, toTimestamp?: number, factory?: string, timestamp: number, pools?: string[] } -type getDexVolumeFeeParamsV3 = { chain: string, fromTimestamp: number, toTimestamp?: number, factory?: string, factoryFromBlock?: number, timestamp: number, pools?: string[], isFee?: boolean } +type getDexVolumeParams = { chain: string, fromTimestamp: number, toTimestamp?: number, factory?: string, timestamp: number, pools?: string[], fetchOptions: FetchOptions, } +type getDexVolumeFeeParamsV3 = { chain: string, fromTimestamp: number, toTimestamp?: number, factory?: string, factoryFromBlock?: number, timestamp: number, pools?: string[], isFee?: boolean, fetchOptions: FetchOptions, } -type getDexVolumeExportsParams = { chain: string, factory?: string, pools?: string[] } +type getDexVolumeExportsParams = { chain: string, factory?: string, pools?: string[], } type getDexVolumeExportsParamsV3 = { chain: string, factory?: string, pools?: string[], factoryFromBlock?: number, } -export async function getDexVolume({ chain, fromTimestamp, toTimestamp, factory, timestamp, pools }: getDexVolumeParams) { - if (!toTimestamp) toTimestamp = timestamp - const api = new sdk.ChainApi({ chain, timestamp: toTimestamp }); - const fromBlock = (await sdk.blocks.getBlock(chain, fromTimestamp)).block; - const toBlock = (await sdk.blocks.getBlock(chain, toTimestamp)).block; - // await api.getBlock(); +export async function getDexVolume({ factory, timestamp, pools, fetchOptions, }: getDexVolumeParams) { + const { api } = fetchOptions; if (!pools) pools = await api.fetchList({ lengthAbi: 'allPairsLength', itemAbi: 'allPairs', target: factory! }) const token0s = await api.multiCall({ abi: 'address:token0', calls: pools! }) const token1s = await api.multiCall({ abi: 'address:token1', calls: pools! }) - const logs = await sdk.getEventLogs({ + const logs = await fetchOptions.getLogs({ targets: pools, - toBlock: toBlock, - fromBlock: fromBlock, - chain, eventAbi: swapEvent, flatten: false, - onlyArgs: true, }); logs.forEach((log: any[], index: number) => { const token0 = token0s[index] @@ -49,38 +41,28 @@ export async function getDexVolume({ chain, fromTimestamp, toTimestamp, factory, } export function getDexVolumeExports(options: getDexVolumeExportsParams) { - return async (timestamp: number) => { - const params = { ...options, timestamp, fromTimestamp: timestamp - 60 * 60 * 24, toTimestamp: timestamp } + return async (timestamp: number, _cb: any, fetchOptions: FetchOptions) => { + const params = { ...options, timestamp, fromTimestamp: fetchOptions.fromTimestamp, toTimestamp: fetchOptions.toTimestamp, fetchOptions } return getDexVolume(params) } } -type getDexFeesParams = { chain: string, fromTimestamp?: number, toTimestamp?: number, factory?: string, timestamp: number, pools?: string[], lengthAbi?: string, itemAbi?: string, fromBlock?: number, toBlock?: number, } +type getDexFeesParams = { chain: string, fromTimestamp?: number, toTimestamp?: number, factory?: string, timestamp: number, pools?: string[], lengthAbi?: string, itemAbi?: string, fromBlock?: number, toBlock?: number, fetchOptions: FetchOptions, } type getDexFeesExportParams = { chain: string, factory?: string, pools?: string[], lengthAbi?: string, itemAbi?: string, } const feesEvent = "event Fees(address indexed sender, uint256 amount0, uint256 amount1)" // const feesTopic = '0x112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a8602' -export async function getDexFees({ chain, fromTimestamp, toTimestamp, factory, timestamp, pools, lengthAbi = 'allPairsLength', itemAbi = 'allPairs', fromBlock, toBlock, }: getDexFeesParams) { - if (!toTimestamp) toTimestamp = timestamp - const api = new sdk.ChainApi({ chain, timestamp: toTimestamp }); - if (!fromBlock) - fromBlock = (await sdk.blocks.getBlock(chain, fromTimestamp)).block; - if (!toBlock) - toBlock = (await sdk.blocks.getBlock(chain, toTimestamp)).block; - // await api.getBlock(); +export async function getDexFees({ factory, timestamp, pools, lengthAbi = 'allPairsLength', itemAbi = 'allPairs', fetchOptions, }: getDexFeesParams) { + const { api } = fetchOptions if (!pools) pools = await api.fetchList({ lengthAbi, itemAbi, target: factory! }) const token0s = await api.multiCall({ abi: 'address:token0', calls: pools! }) const token1s = await api.multiCall({ abi: 'address:token1', calls: pools! }) - const logs = await sdk.getEventLogs({ + const logs = await fetchOptions.getLogs({ targets: pools, - toBlock: toBlock, - fromBlock: fromBlock, - chain, eventAbi: feesEvent, flatten: false, - onlyArgs: true, }); logs.forEach((log: any[], index: number) => { const token0 = token0s[index] @@ -102,8 +84,8 @@ export async function getDexFees({ chain, fromTimestamp, toTimestamp, factory, t } export function getDexFeesExports(options: getDexFeesExportParams) { - return async (timestamp: number) => { - const params = { ...options, timestamp, fromTimestamp: timestamp - 60 * 60 * 24, toTimestamp: timestamp } + return async (timestamp: number, _cb: any, fetchOptions: FetchOptions) => { + const params = { ...options, timestamp, fromTimestamp: fetchOptions.fromTimestamp, toTimestamp: fetchOptions.toTimestamp, fetchOptions, } return getDexFees(params) } } @@ -111,38 +93,25 @@ export function getDexFeesExports(options: getDexFeesExportParams) { const v3PoolCreated = 'event PoolCreated(address indexed token0,address indexed token1,uint24 indexed fee,int24 tickSpacing,address pool)'; const v3SwapEvent = 'event Swap(address indexed sender,address indexed recipient,int256 amount0,int256 amount1,uint160 sqrtPriceX96,uint128 liquidity,int24 tick)' -export async function getDexVolumeFeeV3({ chain, fromTimestamp, toTimestamp, factory, timestamp, pools, factoryFromBlock, isFee = false, }: getDexVolumeFeeParamsV3) { - if (!toTimestamp) toTimestamp = timestamp - const api = new sdk.ChainApi({ chain, timestamp: toTimestamp }); - const fromBlock = (await sdk.blocks.getBlock(chain, fromTimestamp)).block; - const toBlock = (await sdk.blocks.getBlock(chain, toTimestamp)).block; - // await api.getBlock(); +export async function getDexVolumeFeeV3({ factory, timestamp, pools, factoryFromBlock, isFee = false, fetchOptions: { getLogs, api }, }: getDexVolumeFeeParamsV3) { if (!pools) { - const logs = await sdk.getEventLogs({ + const logs = await getLogs({ target: factory, - toBlock: toBlock, fromBlock: factoryFromBlock, - chain, eventAbi: v3PoolCreated, - onlyArgs: true, }); pools = logs.map((log: any) => log.pool) } - // const token0s = await api.multiCall({ abi: 'address:token0', calls: pools! }) let fees = [] as any if (isFee) fees = await api.multiCall({ abi: 'function fee() view returns (uint24)', calls: pools! }) const token1s = await api.multiCall({ abi: 'address:token1', calls: pools! }) - const logs = await sdk.getEventLogs({ + const logs = await getLogs({ targets: pools, - toBlock: toBlock, - fromBlock: fromBlock, - chain, eventAbi: v3SwapEvent, flatten: false, - onlyArgs: true, }); logs.forEach((log: any[], index: number) => { const token1 = token1s[index] @@ -166,16 +135,16 @@ export async function getDexVolumeFeeV3({ chain, fromTimestamp, toTimestamp, fac } export function getDexVolumeExportsV3(options: getDexVolumeExportsParamsV3) { - return async (timestamp: number) => { - const params = { ...options, timestamp, fromTimestamp: timestamp - 60 * 60 * 24, toTimestamp: timestamp } + return async (timestamp: number, _cb: any, fetchOptions: FetchOptions) => { + const params = { ...options, timestamp, fromTimestamp: fetchOptions.fromTimestamp, toTimestamp: fetchOptions.toTimestamp, fetchOptions } return getDexVolumeFeeV3(params) } } export function getDexFeesExportsV3(options: getDexVolumeExportsParamsV3) { - return async (timestamp: number) => { - const params = { ...options, timestamp, fromTimestamp: timestamp - 60 * 60 * 24, toTimestamp: timestamp, isFee: true, } + return async (timestamp: number, _cb: any, fetchOptions: FetchOptions) => { + const params = { ...options, timestamp, fromTimestamp: fetchOptions.fromTimestamp, toTimestamp: fetchOptions.toTimestamp, fetchOptions, isFee: true, } return getDexVolumeFeeV3(params) } }