diff --git a/dexs/e3/index.ts b/dexs/e3/index.ts index 521d937ac7..17b0c07f7a 100644 --- a/dexs/e3/index.ts +++ b/dexs/e3/index.ts @@ -16,10 +16,7 @@ const fetch: any = async (timestamp: number, _: ChainBlocks, { getLogs, api, cre 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 [tokens0, tokens1] = await Promise.all(['address:getTokenX', 'address:getTokenY'].map((abi: string) => api.multiCall({ abi, calls: lpTokens, }))); const logs: any[][] = await getLogs({ targets: lpTokens, diff --git a/dexs/primex-finance/index.ts b/dexs/primex-finance/index.ts index ccc882b80e..19d3ea29ec 100644 --- a/dexs/primex-finance/index.ts +++ b/dexs/primex-finance/index.ts @@ -1,158 +1,35 @@ -import * as sdk from "@defillama/sdk"; -import { FetchResultVolume, SimpleAdapter } from "../../adapters/types" -import { getBlock } from "../../helpers/getBlock"; -import { ethers } from "ethers"; -import { getPrices } from "../../utils/prices"; -import { config, abi, topics } from "./utils"; - +import { ChainBlocks, FetchOptions, FetchResultVolume, SimpleAdapter } from "../../adapters/types" +import { config, } from "./utils"; + +const abi = { + "SpotSwap": "event SpotSwap(address indexed trader, address indexed receiver, address tokenA, address tokenB, uint256 amountSold, uint256 amountBought)", + "OpenPosition": "event OpenPosition(uint256 indexed positionId, address indexed trader, address indexed openedBy, (uint256 id, uint256 scaledDebtAmount, address bucket, address soldAsset, uint256 depositAmountInSoldAsset, address positionAsset, uint256 positionAmount, address trader, uint256 openBorrowIndex, uint256 createdAt, uint256 updatedConditionsAt, bytes extraParams) position, address feeToken, uint256 protocolFee, uint256 entryPrice, uint256 leverage, (uint256 managerType, bytes params)[] closeConditions)", + "ClosePosition": "event ClosePosition(uint256 indexed positionId, address indexed trader, address indexed closedBy, address bucketAddress, address soldAsset, address positionAsset, uint256 decreasePositionAmount, int256 profit, uint256 positionDebt, uint256 amountOut, uint8 reason)", + "PartialClosePosition": "event PartialClosePosition(uint256 indexed positionId, address indexed trader, address bucketAddress, address soldAsset, address positionAsset, uint256 decreasePositionAmount, uint256 depositedAmount, uint256 scaledDebtAmount, int256 profit, uint256 positionDebt, uint256 amountOut)" +} -const fetch = (chain: string) => async (timestamp: number): Promise => { +const fetch = (chain: string) => async (timestamp: number, _: ChainBlocks, { createBalances, getLogs, }: FetchOptions): Promise => { const { swapManager, positionManager, batchManager } = config[chain]; + const dailyVolume = createBalances() const logsConfig = [ - { - targets: swapManager, - topics: [topics.swap] - }, - { - targets: positionManager, - topics: [topics.openPosition] - }, - { - targets: positionManager, - topics: [topics.closePosition] - }, - { - targets: positionManager, - topics: [topics.partiallyClosePosition] - }, - { - targets: batchManager, - topics: [topics.closePosition] - }, + { targets: swapManager, eventAbi: abi.SpotSwap }, + { targets: positionManager, eventAbi: abi.OpenPosition }, + { targets: positionManager, eventAbi: abi.ClosePosition }, + { targets: positionManager, eventAbi: abi.PartialClosePosition }, + { targets: batchManager, eventAbi: abi.ClosePosition }, ] - const contractInterface = new ethers.Interface(abi) - - const fromTimestamp = timestamp - 60 * 60 * 24 - const toTimestamp = timestamp - const fromBlock = (await getBlock(fromTimestamp, chain, {})); - const toBlock = (await getBlock(toTimestamp, chain, {})); - - const [swapLogs, openPositionLogs, closePositionLogs, partiallyClosePositionLogs, closePositionBatchLogs] = (await Promise.all(logsConfig.map(async ({ targets, topics }) => { - return (await Promise.all(targets.map(target => { - return sdk.getEventLogs({ - target, - toBlock: toBlock, - fromBlock: fromBlock, - chain, - topics - }) - }))).map(r => r as ethers.Log[]).flat() - }))) - - const swapTokens: string[] = swapLogs - .map((log: ethers.Log) => { - const parsedLog = contractInterface.parseLog(log as any); - const tokenA = parsedLog!.args.tokenA.toLowerCase(); - return tokenA - }); - - const openPositionTokens: string[] = openPositionLogs - .map((log: ethers.Log) => { - const parsedLog = contractInterface.parseLog(log as any); - const soldAsset = parsedLog!.args.position.soldAsset.toLowerCase(); - return soldAsset - }); - - const closePositionTokens: string[] = closePositionLogs - .map((log: ethers.Log) => { - const parsedLog = contractInterface.parseLog(log as any); - const soldAsset = parsedLog!.args.soldAsset.toLowerCase(); - return soldAsset - }) - - const partiallyClosePositionTokens: string[] = partiallyClosePositionLogs - .map((log: ethers.Log) => { - const parsedLog = contractInterface.parseLog(log as any); - const soldAsset = parsedLog!.args.soldAsset.toLowerCase(); - return soldAsset - }) - - const closePositionBatchTokens: string[] = closePositionBatchLogs - .map((log: ethers.Log) => { - const parsedLog = contractInterface.parseLog(log as any); - const soldAsset = parsedLog!.args.soldAsset.toLowerCase(); - return soldAsset - }) - - const uniqueTokens = Array.from(new Set(swapTokens.concat(openPositionTokens, closePositionTokens, partiallyClosePositionTokens, closePositionBatchTokens))) - - const priceKeys = uniqueTokens.map((t) => `${chain}:${t}`) - const prices = await getPrices(priceKeys, timestamp); - - const swapVolumeUSD: number = swapLogs - .map((log: ethers.Log) => { - const parsedLog = contractInterface.parseLog(log as any); - const amountSold = Number(parsedLog!.args.amountSold); - const tokenA = parsedLog!.args.tokenA; - const priceA = prices[`${chain}:${tokenA.toLowerCase()}`]?.price || 0; - const decimalsA = prices[`${chain}:${tokenA.toLowerCase()}`]?.decimals || 0; - return (amountSold / 10 ** decimalsA) * priceA; - }) - .reduce((a: number, b: number) => a + b, 0) - - const openPositionVolumeUSD: number = openPositionLogs - .map((log: ethers.Log) => { - const parsedLog = contractInterface.parseLog(log as any); - const soldAsset = parsedLog!.args.position.soldAsset; - const priceSoldAsset = prices[`${chain}:${soldAsset.toLowerCase()}`]?.price || 0; - const decimalsSoldAsset = prices[`${chain}:${soldAsset.toLowerCase()}`]?.decimals || 0; - const depositAmountInSoldAsset = Number(parsedLog!.args.position.depositAmountInSoldAsset) / 10 ** decimalsSoldAsset; - const leverage = Number(parsedLog!.args.leverage) / 10 ** 18 - return depositAmountInSoldAsset * leverage * priceSoldAsset; - }) - .reduce((a: number, b: number) => a + b, 0) - - const closePositionVolumeUSD: number = closePositionLogs - .map((log: ethers.Log) => { - const parsedLog = contractInterface.parseLog(log as any); - const soldAsset = parsedLog!.args.soldAsset; - const priceSoldAsset = prices[`${chain}:${soldAsset.toLowerCase()}`]?.price || 0; - const decimalsSoldAsset = prices[`${chain}:${soldAsset.toLowerCase()}`]?.decimals || 0; - const amountOut = Number(parsedLog!.args.amountOut) / 10 ** decimalsSoldAsset; - return amountOut * priceSoldAsset; - }) - .reduce((a: number, b: number) => a + b, 0) - - const partiallyClosePositionVolumeUSD: number = partiallyClosePositionLogs - .map((log: ethers.Log) => { - const parsedLog = contractInterface.parseLog(log as any); - const soldAsset = parsedLog!.args.soldAsset; - const priceSoldAsset = prices[`${chain}:${soldAsset.toLowerCase()}`]?.price || 0; - const decimalsSoldAsset = prices[`${chain}:${soldAsset.toLowerCase()}`]?.decimals || 0; - const amountOut = Number(parsedLog!.args.amountOut) / 10 ** decimalsSoldAsset; - return amountOut * priceSoldAsset; - }) - .reduce((a: number, b: number) => a + b, 0) + const [swapLogs, openPositionLogs, closePositionLogs, partiallyClosePositionLogs, closePositionBatchLogs] = await Promise.all(logsConfig.map(async (config) => getLogs(config))) - const closePositionBatchVolumeUSD: number = closePositionBatchLogs - .map((log: ethers.Log) => { - const parsedLog = contractInterface.parseLog(log as any); - const soldAsset = parsedLog!.args.soldAsset; - const priceSoldAsset = prices[`${chain}:${soldAsset.toLowerCase()}`]?.price || 0; - const decimalsSoldAsset = prices[`${chain}:${soldAsset.toLowerCase()}`]?.decimals || 0; - const amountOut = Number(parsedLog!.args.amountOut) / 10 ** decimalsSoldAsset; - return amountOut * priceSoldAsset; - }) - .reduce((a: number, b: number) => a + b, 0) + swapLogs.forEach((e: any) => dailyVolume.add(e.tokenA, e.amountSold)) + openPositionLogs.forEach((e: any) => dailyVolume.add(e.position.soldAsset, e.position.amountSold * e.leverage)) + closePositionLogs.forEach((e: any) => dailyVolume.add(e.soldAsset, e.amountOut)) + partiallyClosePositionLogs.forEach((e: any) => dailyVolume.add(e.soldAsset, e.amountOut)) + closePositionBatchLogs.forEach((e: any) => dailyVolume.add(e.soldAsset, e.amountOut)) - const dailyVolume = swapVolumeUSD + openPositionVolumeUSD + closePositionVolumeUSD + partiallyClosePositionVolumeUSD + closePositionBatchVolumeUSD + return { dailyVolume: dailyVolume, timestamp, } - return { - dailyVolume: `${dailyVolume}`, - timestamp - } } const adapters: SimpleAdapter = { diff --git a/dexs/saber/index.ts b/dexs/saber/index.ts index 14bfc18461..91c83e4360 100644 --- a/dexs/saber/index.ts +++ b/dexs/saber/index.ts @@ -1,28 +1,22 @@ -import ADDRESSES from '../../helpers/coreAssets.json' +import { ChainBlocks, FetchOptions } from '../../adapters/types'; import { httpPost } from "../../utils/fetchURL"; -import { getPrices } from "../../utils/prices"; -async function last24h(timestamp: number) { - const data = await httpPost('https://saberqltest.aleph.cloud/', { "query": "{\n pools {\n ammId\n name\n coin {\n chainId\n address\n name\n decimals\n symbol\n logoURI\n }\n pc {\n chainId\n address\n name\n decimals\n symbol\n logoURI\n }\n lp {\n chainId\n address\n name\n decimals\n symbol\n logoURI\n }\n stats {\n tvl_pc\n tvl_coin\n price\n vol24h\n }\n }\n}\n" }) - const coinId = "solana:" + ADDRESSES.solana.SOL; - const prices = await getPrices([coinId], timestamp) - const vol = data.data.pools.reduce( - (a: number, b: any) => - a + b.stats.vol24h * - (b.pc.address === ADDRESSES.solana.SOL ? prices[coinId].price : 1) - , 0) - return { - dailyVolume: vol, - timestamp: Date.now() / 1e3 - } +async function last24h(timestamp: number, _: ChainBlocks, { createBalances }: FetchOptions) { + const { data: { pools } } = await httpPost('https://saberqltest.aleph.cloud/', { "query": "{ pools { stats { vol24h_usd } } }" }) + const dailyVolume = createBalances() + pools.forEach((pool: any) => dailyVolume.addCGToken('tether', pool.stats.vol24h_usd)) + return { + dailyVolume, + timestamp: Math.floor(Date.now() / 1e3) + } } export default { - adapter: { - "solana": { - fetch: last24h, - runAtCurrTime: true, - start: 0, - } + adapter: { + "solana": { + fetch: last24h, + runAtCurrTime: true, + start: 0, } + } } diff --git a/dexs/sanctum/index.ts b/dexs/sanctum/index.ts index df88ae95f8..b7e713e6af 100644 --- a/dexs/sanctum/index.ts +++ b/dexs/sanctum/index.ts @@ -1,22 +1,16 @@ -import { FetchResultVolume, SimpleAdapter } from "../../adapters/types"; +import { ChainBlocks, FetchOptions, FetchResultVolume, SimpleAdapter } from "../../adapters/types"; import { queryDune } from "../../helpers/dune"; -import { getPrices } from "../../utils/prices"; -const fetch = async (timestamp: number): Promise => { +const fetch = async (timestamp: number, _: ChainBlocks, { createBalances }: FetchOptions): Promise => { + const dailyVolume = createBalances() const solDispensed = ( await queryDune("3276095", { endTime: timestamp, }) )[0].sol_dispensed; - const dailyVolume = - solDispensed * - (await getPrices(["coingecko:solana"], timestamp))["coingecko:solana"] - .price; + dailyVolume.addCGToken("solana", solDispensed); - return { - dailyVolume: `${dailyVolume}`, - timestamp, - }; + return { dailyVolume, timestamp, }; }; const adapter: SimpleAdapter = { diff --git a/dexs/saucerswap/index.ts b/dexs/saucerswap/index.ts index 764f88b2bc..ffcc6003d6 100644 --- a/dexs/saucerswap/index.ts +++ b/dexs/saucerswap/index.ts @@ -1,4 +1,4 @@ -import { SimpleAdapter } from "../../adapters/types"; +import { ChainBlocks, FetchOptions, SimpleAdapter } from "../../adapters/types"; import { CHAIN } from "../../helpers/chains"; import { getUniqStartOfTodayTimestamp } from "../../helpers/getUniSubgraphVolume"; import { getPrices } from "../../utils/prices"; @@ -11,26 +11,26 @@ interface IVolumeall { valueHbar: string; } -const fetch = async (timestamp: number) => { - const dayTimestamp = getUniqStartOfTodayTimestamp(new Date(timestamp * 1000)) +const fetch = async (timestamp: number , _: ChainBlocks, { createBalances, startOfDay }: FetchOptions) => { const historicalVolume: IVolumeall[] = (await httpGet(historicalVolumeEndpoint(new Date().getTime() / 1000), { headers: { 'origin': 'https://analytics.saucerswap.finance', }})); const totalVolume = historicalVolume - .filter(volItem => Number(volItem.timestampSeconds) <= dayTimestamp) + .filter(volItem => Number(volItem.timestampSeconds) <= startOfDay) .reduce((acc, { valueHbar }) => acc + Number(valueHbar), 0) - const dailyVolume = historicalVolume - .find(dayItem => Number(dayItem.timestampSeconds) === dayTimestamp)?.valueHbar + const _dailyVolume = historicalVolume + .find(dayItem => Number(dayItem.timestampSeconds) === startOfDay)?.valueHbar - const coinId = "coingecko:hedera-hashgraph"; - const prices = await getPrices([coinId], dayTimestamp) + + const dailyVolume = createBalances() + dailyVolume.addCGToken("hedera-hashgraph", (_dailyVolume as any)/1e8) return { // totalVolume: totalVolume ? String(totalVolume/1e8 * prices[coinId].price) : "0", - dailyVolume: dailyVolume ? String(Number(dailyVolume)/1e8 * prices[coinId].price) : "0", - timestamp: dayTimestamp, + dailyVolume, + timestamp: startOfDay, }; }; diff --git a/dexs/tokenlon/index.ts b/dexs/tokenlon/index.ts index 961c5842e8..3d390e5170 100644 --- a/dexs/tokenlon/index.ts +++ b/dexs/tokenlon/index.ts @@ -1,5 +1,5 @@ import ADDRESSES from '../../helpers/coreAssets.json' -import { FetchResultVolume, SimpleAdapter } from "../../adapters/types"; +import { ChainBlocks, FetchOptions, FetchResultVolume, SimpleAdapter } from "../../adapters/types"; import { CHAIN } from "../../helpers/chains"; import { gql, request } from "graphql-request"; import { Chain } from "@defillama/sdk/build/general"; @@ -21,14 +21,13 @@ type TEndpoint = { }; const endpoints: TEndpoint = { - [CHAIN.ETHEREUM]:"https://api.thegraph.com/subgraphs/name/consenlabs/tokenlon-v5-exchange", + [CHAIN.ETHEREUM]: "https://api.thegraph.com/subgraphs/name/consenlabs/tokenlon-v5-exchange", }; const fetchVolume = (chain: Chain) => { - return async (timestamp: number): Promise => { - const fromTimestamp = timestamp - 60 * 60 * 24 - const toTimestamp = timestamp - const query = gql` + return async (timestamp: number, _: ChainBlocks, { createBalances, fromTimestamp, toTimestamp, }: FetchOptions): Promise => { + const dailyVolume = createBalances() + const query = ` { swappeds(first:1000, where:{timestamp_gte:${fromTimestamp}, timestamp_lte:${toTimestamp}}) { makerAssetAddr @@ -42,22 +41,10 @@ const fetchVolume = (chain: Chain) => { `; const response: IData = (await request(endpoints[chain], query)); const historicalData: IGraph[] = [...response.fillOrders, ...response.swappeds] - const coins = [...new Set(historicalData.map((e: IGraph) => `${chain}:${e.makerAssetAddr}`))] - const prices = await getPrices(coins, toTimestamp); - if (!prices[`ethereum:0x3212b29e33587a00fb1c83346f5dbfa69a458923`]) { - prices[`ethereum:0x3212b29e33587a00fb1c83346f5dbfa69a458923`] = prices[`ethereum:` + ADDRESSES.ethereum.WBTC] // imBTC - } - const dailyVolume = historicalData.map((e: IGraph) => { - const price = prices[`${chain}:${e.makerAssetAddr}`]?.price || 0; - const decimals = prices[`${chain}:${e.makerAssetAddr}`]?.decimals || 0; - return (Number(e.makerAssetAmount) / 10 ** decimals) * price; - }).filter((e: any) => !isNaN(e)) - .reduce((a: number, b: number) => a + b, 0); - - return { - dailyVolume: `${dailyVolume}`, - timestamp: toTimestamp, - }; + historicalData.map((e: IGraph) => { + dailyVolume.add(e.makerAssetAddr, e.makerAssetAmount) + }) + return { dailyVolume, timestamp: toTimestamp } }; }; diff --git a/dexs/velodrome-v2/index.ts b/dexs/velodrome-v2/index.ts index 8c79069e2b..5ccc4d82e5 100644 --- a/dexs/velodrome-v2/index.ts +++ b/dexs/velodrome-v2/index.ts @@ -1,24 +1,11 @@ import { SimpleAdapter } from "../../adapters/types"; import { CHAIN } from "../../helpers/chains"; -import { Chain } from "@defillama/sdk/build/general"; import { fetchV2 } from "./v2"; - -const fetch = (_: Chain) => { - return async (timestamp: number) => { - const [v2] = await Promise.all([fetchV2(timestamp)]) - const dailyVolume = Number(v2.dailyVolume); - return { - dailyVolume: `${dailyVolume}`, - timestamp - } - } -} - const adapter: SimpleAdapter = { adapter: { [CHAIN.OPTIMISM]: { - fetch: fetch(CHAIN.OPTIMISM), + fetch: fetchV2, start: 1677110400 }, }, diff --git a/dexs/velodrome-v2/v2.ts b/dexs/velodrome-v2/v2.ts index 5438fa9c88..3fd736010c 100644 --- a/dexs/velodrome-v2/v2.ts +++ b/dexs/velodrome-v2/v2.ts @@ -1,121 +1,7 @@ -import { 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"; -interface ILog { - data: string; - transactionHash: string; -} +import { getDexVolumeExports } from "../../helpers/dexVolumeLogs"; -type TPrice = { - [s: string]: { - price: number; - decimals: number - }; -} -interface IAmount { - amount0In: string; - amount1In: string; - amount0Out: string; - amount1Out: string; -} -const topic_name = 'Swap(index_topic_1 address sender, index_topic_2 address to, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out)'; -const topic0 = '0xb3e2773606abfd36b5bd91394b3a54d1398336c65005baf7bf7a05efeffaf75b'; const FACTORY_ADDRESS = '0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a'; -type TABI = { - [k: string]: string; -} -const ABIs: TABI = { - "allPoolsLength": "uint256:allPoolsLength", - "allPools": "function allPools(uint256) view returns (address)" -} - -export const fetchV2 = async (timestamp: number) => { - const fromTimestamp = timestamp - 60 * 60 * 24 - const toTimestamp = timestamp - const poolLength = (await sdk.api2.abi.call({ - target: FACTORY_ADDRESS, - chain: CHAIN.OPTIMISM, - abi: ABIs.allPoolsLength, - })); - - const poolsRes = await sdk.api2.abi.multiCall({ - abi: ABIs.allPools, - calls: Array.from(Array(Number(poolLength)).keys()).map((i) => ({ - target: FACTORY_ADDRESS, - params: i, - })), - chain: CHAIN.OPTIMISM - }); - - const lpTokens = poolsRes - - const [underlyingToken0, underlyingToken1] = await Promise.all( - ['address:token0', 'address:token1'].map((method) => - sdk.api2.abi.multiCall({ - abi: method, - calls: lpTokens, - chain: CHAIN.OPTIMISM, - permitFailure: true, - }) - ) - ); - - const tokens0 = underlyingToken0; - const tokens1 = underlyingToken1; - const fromBlock = (await getBlock(fromTimestamp, CHAIN.OPTIMISM, {})); - const toBlock = (await getBlock(toTimestamp, CHAIN.OPTIMISM, {})); - const logs: ILog[][] = (await Promise.all(lpTokens.map((address: string) => sdk.getEventLogs({ - target: address, - topic: topic_name, - toBlock: toBlock, - fromBlock: fromBlock, - chain: CHAIN.OPTIMISM, - topics: [topic0] - })))) as any; - const rawCoins = [...tokens0, ...tokens1].map((e: string) => `${CHAIN.OPTIMISM}:${e}`); - const coins: string[] = [...new Set(rawCoins)] - 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 untrackVolumes: number[] = lpTokens.map((_: string, index: number) => { - const log: IAmount[] = logs[index] - .map((e: ILog) => { return { ...e, data: e.data.replace('0x', '') } }) - .map((p: ILog) => { - const amount0In = Number('0x' + p.data.slice(0, 64)).toString(); - const amount1In = Number('0x' + p.data.slice(64, 128)).toString(); - const amount0Out = Number('0x' + p.data.slice(128, 192)).toString(); - const amount1Out = Number('0x' + p.data.slice(192, 256)).toString(); - return { - amount0In, - amount1In, - amount0Out, - amount1Out, - } as IAmount - }) as IAmount[]; - const token0Price = (prices[`${CHAIN.OPTIMISM}:${tokens0[index]}`]?.price || 0); - const token1Price = (prices[`${CHAIN.OPTIMISM}:${tokens1[index]}`]?.price || 0); - const token0Decimals = (prices[`${CHAIN.OPTIMISM}:${tokens0[index]}`]?.decimals || 0) - const token1Decimals = (prices[`${CHAIN.OPTIMISM}:${tokens1[index]}`]?.decimals || 0) - const totalAmount0 = log - .reduce((a: number, b: IAmount) => Number(b.amount0In) + Number(b.amount0Out) + a, 0) / 10 ** token0Decimals * token0Price; - const totalAmount1 = log - .reduce((a: number, b: IAmount) => Number(b.amount1In) + Number(b.amount1Out) + a, 0) / 10 ** token1Decimals * token1Price; - - const untrackAmountUSD = token0Price !== 0 ? totalAmount0 : token1Price !== 0 ? totalAmount1 : 0; // counted only we have price data - return untrackAmountUSD; - }); - - const dailyVolume = untrackVolumes.reduce((a: number, b: number) => a + b, 0); - return { - dailyVolume: `${dailyVolume}`, - timestamp, - }; -} +const swapEvent = 'event Swap(address indexed sender, address indexed to, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out)'; +export const fetchV2 = getDexVolumeExports({ swapEvent, factory: FACTORY_ADDRESS, chain: 'optimism', pairItemAbi: 'allPools', pairLengthAbi: 'allPoolsLength' }) \ No newline at end of file diff --git a/dexs/zilswap/index.ts b/dexs/zilswap/index.ts index 1a09d3478a..aff785fe07 100644 --- a/dexs/zilswap/index.ts +++ b/dexs/zilswap/index.ts @@ -1,7 +1,6 @@ import fetchURL from "../../utils/fetchURL" -import { SimpleAdapter } from "../../adapters/types"; +import { ChainBlocks, FetchOptions, SimpleAdapter } from "../../adapters/types"; import { getUniqStartOfTodayTimestamp } from "../../helpers/getUniSubgraphVolume"; -import { getPrices } from "../../utils/prices"; const historicalVolumeEndpoint = "https://api.zilstream.com/volume" @@ -10,22 +9,16 @@ interface IVolumeall { time: string; } -const fetch = async (timestamp: number) => { +const fetch = async (timestamp: number, _: ChainBlocks, { createBalances, startOfDay, }: FetchOptions) => { + const dailyVolume = createBalances() const dayTimestamp = getUniqStartOfTodayTimestamp(new Date(timestamp * 1000)) const historicalVolume: IVolumeall[] = (await fetchURL(historicalVolumeEndpoint)); - const _dailyVolume = historicalVolume.filter(volItem => (new Date(volItem.time.split('T')[0]).getTime() / 1000) === dayTimestamp); - const dailyVolume = Math.abs(Number(_dailyVolume[0].value) - Number(_dailyVolume[_dailyVolume.length-1].value)) - const priceId = 'coingecko:zilliqa'; - const prices = await getPrices([priceId], dayTimestamp); - const dailyVolumeUSD = dailyVolume ? `${Number(dailyVolume) * prices[priceId].price}` : undefined - return { - dailyVolume: dailyVolumeUSD ? `${dailyVolumeUSD}` : undefined, - timestamp: dayTimestamp, - }; + const _dailyVolume = historicalVolume.filter(volItem => (new Date(volItem.time.split('T')[0]).getTime() / 1000) === dayTimestamp); + const __dailyVolume = Math.abs(Number(_dailyVolume[0].value) - Number(_dailyVolume[_dailyVolume.length - 1].value)) + dailyVolume.addCGToken("zilliqa", __dailyVolume) + return { dailyVolume, timestamp: startOfDay, }; }; - - const adapter: SimpleAdapter = { adapter: { zilliqa: { diff --git a/fees/Scale.ts b/fees/Scale.ts index 8282c90915..c938fced1f 100644 --- a/fees/Scale.ts +++ b/fees/Scale.ts @@ -1,270 +1,14 @@ -import ADDRESSES from '../helpers/coreAssets.json' -import { FetchResultFees, SimpleAdapter } from "../adapters/types"; +import { 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 { ethers } from "ethers"; +import { getFeesExport } from '../helpers/solidly'; -type TPrice = { - [s: string]: { - price: number; - decimals: number - }; -} - -interface ILog { - data: string; - topics: string[]; - transactionHash: string; -} -interface IAmount { - amount0: number; - amount1: number; -} -interface IBribedAmount { - amount: number; -} -interface IAmountUSD { - amount: number; -} - -const TOPIC_Fees = '0x112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a8602'; -const TOPIC_NotifyRewardAmount = '0x52977ea98a2220a03ee9ba5cb003ada08d394ea10155483c95dc2dc77a7eb24b'; -const TOPIC_Notify = 'event NotifyReward(address indexed from, address indexed reward, uint indexed epoch, uint amount)'; -const INTERFACE_N = new ethers.Interface([TOPIC_Notify]); const VOTER_ADDRESS = '0x46ABb88Ae1F2a35eA559925D99Fdc5441b592687'; const FACTORY_ADDRESS = '0xEd8db60aCc29e14bC867a497D94ca6e3CeB5eC04'; -const CHAIN_USED = CHAIN.BASE; -const CHAIN_SLUG = 'base'; - -type TABI = { - [k: string]: string; -} -const ABIs: TABI = { - "allPairsLength": "uint256:allPairsLength", - "allPairs": "function allPairs(uint256) view returns (address)" -} -const VOTER_ABI: TABI = { - "length": "uint256:length", - "pools": "function pools(uint256) view returns (address)", - "gauges": "function gauges(address) view returns (address)", - "bribes": "function bribes(address) view returns (address)" -} - -const fetch = async (timestamp: number): Promise => { - const fromTimestamp = timestamp - 60 * 60 * 24 - const toTimestamp = timestamp - const poolLength = (await sdk.api2.abi.call({ - target: FACTORY_ADDRESS, - chain: CHAIN_SLUG, - abi: ABIs.allPairsLength, - })); - - const poolsRes = await sdk.api2.abi.multiCall({ - abi: ABIs.allPairs, - target: FACTORY_ADDRESS, - calls: Array.from(Array(Number(poolLength)).keys()), - chain: CHAIN_SLUG - }); - - const lpTokens = poolsRes - - const [underlyingToken0, underlyingToken1] = await Promise.all( - ['address:token0', 'address:token1'].map((method) => - sdk.api2.abi.multiCall({ - abi: method, - calls: lpTokens.map((address: string) => ({ - target: address, - })), - chain: CHAIN_SLUG - }) - ) - ); - - const tokens0 = underlyingToken0; - const tokens1 = underlyingToken1; - - - const poolsGauges = await sdk.api2.abi.multiCall({ - abi: VOTER_ABI.gauges, - target: VOTER_ADDRESS, - calls: lpTokens, - chain: CHAIN_SLUG - }); - - const voterGauges = poolsGauges.filter((_vg: string) => - _vg !== ADDRESSES.null - ); - - - - const poolsGaugesToBribes = await sdk.api2.abi.multiCall({ - abi: VOTER_ABI.bribes, - target: VOTER_ADDRESS, - calls: voterGauges, - chain: CHAIN_SLUG - }); - - const voterBribes = poolsGaugesToBribes; - - - - - - const fromBlock = (await getBlock(fromTimestamp, CHAIN_SLUG, {})); - const toBlock = (await getBlock(toTimestamp, CHAIN_SLUG, {})); - - const tradefeeLogs: ILog[][] = (await Promise.all(lpTokens.map((address: string) => sdk.getEventLogs({ - target: address, - toBlock: toBlock, - fromBlock: fromBlock, - chain: CHAIN_SLUG, - topics: [TOPIC_Fees] - })))) as ILog[][]; - - - const bribeAndFeeLogs: ILog[][] = (await Promise.all(voterBribes.map((address: string) => sdk.getEventLogs({ - target: address, - toBlock: toBlock, - fromBlock: fromBlock, - chain: CHAIN_SLUG, - topics: [TOPIC_NotifyRewardAmount] - })))) as ILog[][]; - - - - var allBribedTokens: string[] = new Array(0); - const listOfBribedTokensByPool: string[][] = bribeAndFeeLogs.map((perBribeLogs: ILog[]) => { - const _innerBT: string[] = perBribeLogs.map((e: ILog) => { - const _l = INTERFACE_N.parseLog(e); - if (_l == null) { return "" } - const _t = `${CHAIN_USED}:${_l.args.reward.toLowerCase()}`; - return _t; - //return `${CHAIN_USED}:${e.topics[2].toLowerCase()}`; - }); - allBribedTokens = allBribedTokens.concat(_innerBT); - return _innerBT; - }); - - allBribedTokens.filter((_ta: string) => { _ta != "" }) - - - - - - - const rawCoins = [...tokens0, ...tokens1, ...allBribedTokens].map((e: string) => `${CHAIN_SLUG}:${e}`); - const coins = [...new Set(rawCoins)]; - - 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 tradefees: number[] = lpTokens.map((_: string, index: number) => { - const token0Decimals = (prices[`${CHAIN_SLUG}:${tokens0[index]}`]?.decimals || 0) - const token1Decimals = (prices[`${CHAIN_SLUG}:${tokens1[index]}`]?.decimals || 0) - const tradefeesLog: IAmount[] = tradefeeLogs[index] - .map((e: ILog) => { return { ...e, data: e.data.replace('0x', '') } }) - .map((p: ILog) => { - const amount0 = Number('0x' + p.data.slice(0, 64)) / 10 ** token0Decimals; - const amount1 = Number('0x' + p.data.slice(64, 128)) / 10 ** token1Decimals; - return { - amount0, - amount1 - } as IAmount - }) as IAmount[]; - const token0Price = (prices[`${CHAIN_SLUG}:${tokens0[index]}`]?.price || 0); - const token1Price = (prices[`${CHAIN_SLUG}:${tokens1[index]}`]?.price || 0); - - const feesAmount0 = tradefeesLog - .reduce((a: number, b: IAmount) => Number(b.amount0) + a, 0) * token0Price; - const feesAmount1 = tradefeesLog - .reduce((a: number, b: IAmount) => Number(b.amount1) + a, 0) * token1Price; - - const feesUSD = feesAmount0 + feesAmount1; - return feesUSD; - }); - - - - const notifiedFees: number[] = voterBribes.map((_: string, index: number) => { - const notifiedFeesLog: IAmountUSD[] = bribeAndFeeLogs[index] - .map((e: ILog) => { return { ...e } }) - .map((p: ILog) => { - const _log = INTERFACE_N.parseLog(p); - if (_log == null || _log.args.from != voterGauges[index]) { - const amount = 0; - return { amount } as IAmountUSD - } - const _token = _log.args.reward; - const _price = (prices[`${CHAIN_SLUG}:${_token}`]?.price || 0); - const _deci = prices[`${CHAIN_SLUG}:${_token}`]?.decimals || 0; - const amount = Number(p.data) / 10 ** _deci * _price; - return { amount } as IAmountUSD - }) as IAmountUSD[]; - - const notifiedFeeAmount = notifiedFeesLog - .reduce((a: number, b: IAmountUSD) => Number(b.amount) + a, 0); - - return notifiedFeeAmount; - }); - - - - - const notifiedBribes: number[] = voterBribes.map((_: string, index: number) => { - const bribesLog: IAmountUSD[] = bribeAndFeeLogs[index] - .map((e: ILog) => { return { ...e } }) - .map((p: ILog) => { - const _log = INTERFACE_N.parseLog(p); - if (_log == null || _log.args.from == voterGauges[index]) { - const amount = 0; - return { amount } as IAmountUSD - } - const _token = _log.args.reward; - const _price = (prices[`${CHAIN_SLUG}:${_token}`]?.price || 0); - const _deci = prices[`${CHAIN_SLUG}:${_token}`]?.decimals || 0; - const amount = Number(p.data) / 10 ** _deci * _price; - return { amount } as IAmountUSD - }) as IAmountUSD[]; - - const bribedAmount = bribesLog.reduce((a: number, b: IBribedAmount) => Number(b.amount) + a, 0); - - return bribedAmount; - }); - - - - - - - - const dailyFees = tradefees.reduce((a: number, b: number) => a + b, 0) - const dailyRevenueFees = notifiedFees.reduce((a: number, b: number) => a + b, 0) - const dailyRevenueBribes = notifiedBribes.reduce((a: number, b: number) => a + b, 0) - - - - return { - dailyFees: `${dailyFees}`, - dailyRevenue: `${dailyRevenueFees}`, - dailyHoldersRevenue: `${dailyRevenueFees}`, - dailyBribesRevenue: `${dailyRevenueBribes}`, - timestamp, - }; -} const adapter: SimpleAdapter = { adapter: { [CHAIN.BASE]: { - fetch, + fetch: getFeesExport({ FACTORY_ADDRESS, VOTER_ADDRESS, }), start: 1695458888, }, } diff --git a/fees/across.ts b/fees/across.ts index c96d7348aa..d36eb7ebef 100644 --- a/fees/across.ts +++ b/fees/across.ts @@ -1,226 +1,16 @@ import { Chain } from "@defillama/sdk/build/general" -import { FetchResultFees, SimpleAdapter } from "../adapters/types" +import { ChainBlocks, FetchOptions, FetchResultFees, 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 abis: any[] = [ - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "originChainId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "destinationChainId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "int64", - "name": "relayerFeePct", - "type": "int64" - }, - { - "indexed": true, - "internalType": "uint32", - "name": "depositId", - "type": "uint32" - }, - { - "indexed": false, - "internalType": "uint32", - "name": "quoteTimestamp", - "type": "uint32" - }, - { - "indexed": false, - "internalType": "address", - "name": "originToken", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "depositor", - "type": "address" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "message", - "type": "bytes" - } - ], - "name": "FundsDeposited", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "totalFilledAmount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "fillAmount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "repaymentChainId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "originChainId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "destinationChainId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "int64", - "name": "relayerFeePct", - "type": "int64" - }, - { - "indexed": false, - "internalType": "int64", - "name": "realizedLpFeePct", - "type": "int64" - }, - { - "indexed": true, - "internalType": "uint32", - "name": "depositId", - "type": "uint32" - }, - { - "indexed": false, - "internalType": "address", - "name": "destinationToken", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "relayer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "depositor", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "message", - "type": "bytes" - }, - { - "components": [ - { - "internalType": "address", - "name": "recipient", - "type": "address" - }, - { - "internalType": "bytes", - "name": "message", - "type": "bytes" - }, - { - "internalType": "int64", - "name": "relayerFeePct", - "type": "int64" - }, - { - "internalType": "bool", - "name": "isSlowRelay", - "type": "bool" - }, - { - "internalType": "int256", - "name": "payoutAdjustmentPct", - "type": "int256" - } - ], - "indexed": false, - "internalType": "struct SpokePool.RelayExecutionInfo", - "name": "updatableRelayData", - "type": "tuple" - } - ], - "name": "FilledRelay", - "type": "event" +const abis = { + "FundsDeposited": "event FundsDeposited(uint256 amount, uint256 originChainId, uint256 indexed destinationChainId, int64 relayerFeePct, uint32 indexed depositId, uint32 quoteTimestamp, address originToken, address recipient, address indexed depositor, bytes message)", + "FilledRelay": "event FilledRelay(uint256 amount, uint256 totalFilledAmount, uint256 fillAmount, uint256 repaymentChainId, uint256 indexed originChainId, uint256 destinationChainId, int64 relayerFeePct, int64 realizedLpFeePct, uint32 indexed depositId, address destinationToken, address relayer, address indexed depositor, address recipient, bytes message, (address recipient, bytes message, int64 relayerFeePct, bool isSlowRelay, int256 payoutAdjustmentPct) updatableRelayData)" } -] const topic0_fund_disposit_v2 = '0xafc4df6845a4ab948b492800d3d8a25d538a102a2bc07cd01f1cfa097fddcff6'; const topic0_filled_replay_v2 = '0x8ab9dc6c19fe88e69bc70221b339c84332752fdd49591b7c51e66bae3947b73c'; -const contract_interface = new ethers.Interface(abis); -type TAddress = { - [key: string]: string; -} - -interface IDataDispositFund { - token: string; - amount: number; - lp_fee_pct: number; -} - -interface IDataReplay { - token: string; - amount: number; - relay_fee_pct: number; - lp_fee_pct: number; -} -const address: TAddress = { +const address: any = { [CHAIN.ETHEREUM]: '0x5c7BCd6E7De5423a257D81B442095A1a6ced35C5', [CHAIN.ARBITRUM]: '0xe35e9842fceaCA96570B734083f4a58e8F7C5f2A', [CHAIN.OPTIMISM]: '0x6f26Bf09B1C792e3228e5467807a900A503c0281', @@ -228,76 +18,25 @@ const address: TAddress = { } 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_fund_disposit: IDataDispositFund[] = (await sdk.getEventLogs({ + return async (timestamp: number, _: ChainBlocks, { createBalances, getLogs, }: FetchOptions): Promise => { + const dailyFees = createBalances() + const logs_fund_disposit = (await getLogs({ target: address[chain], - toBlock: toBlock, - fromBlock: fromBlock, - chain: chain, - topics: [topic0_fund_disposit_v2] - })).map((a: any) => contract_interface.parseLog(a)) - .filter((a: any) => Number(a!.args.destinationChainId) === 288) - .map((a: any) => { - return { - token: a!.args.originToken.toLowerCase(), - amount: Number(a!.args.amount), - lp_fee_pct: Number(a!.args.relayerFeePct) / 10 ** 18 - } as IDataDispositFund - }); + eventAbi: abis.FundsDeposited, + topic: topic0_fund_disposit_v2, + })).filter((a: any) => Number(a!.destinationChainId) === 288) - const logs_filled_replay: IDataReplay[] = (await sdk.getEventLogs({ + const logs_filled_replay = (await getLogs({ target: address[chain], - toBlock: toBlock, - fromBlock: fromBlock, - chain: chain, - topics: [topic0_filled_replay_v2] - })).map((a: any) => { - const data = a.data.replace('0x',''); - const destinationToken = data.slice(448, 512) // 7 - const token = '0x' + destinationToken.slice(24, address.length) - const amount = data.slice(0, 64) - const realizedLpFeePct = data.slice(384, 448) // 6 - const appliedRelayerFeePct = data.slice(320, 384) // 5 - return { - token: token.toLowerCase(), - amount: Number('0x'+amount), - relay_fee_pct: Number('0x'+realizedLpFeePct) / 10 ** 18, - lp_fee_pct: Number('0x'+appliedRelayerFeePct) / 10 ** 18, - } as IDataReplay - }); - - const tokens = [...new Set([ - ...logs_fund_disposit.map((a: IDataDispositFund) => `${chain}:${a.token}`), - ...logs_filled_replay.map((a: IDataReplay) => `${chain}:${a.token}`) - ])]; - - const prices = (await getPrices(tokens, timestamp)); - - const fees_fund_disposit = logs_fund_disposit.map((a: IDataDispositFund) => { - const decimals = prices[`${chain}:${a.token}`].decimals; - const price = prices[`${chain}:${a.token}`].price; - const amount = ((a.amount * a.lp_fee_pct) / 10 ** decimals) * price; - return amount; - }); + eventAbi: abis.FilledRelay, + topic: topic0_filled_replay_v2, + })) - const fees_relay = logs_filled_replay.map((a: IDataReplay) => { - const decimals = prices[`${chain}:${a.token}`].decimals; - const price = prices[`${chain}:${a.token}`].price; - const amount = ((a.amount * (a.lp_fee_pct + a.relay_fee_pct)) / 10 ** decimals) * price; - return amount; - }); - const amount = fees_fund_disposit - .concat(fees_relay) - .reduce((sum: number, amount: number) => sum + amount, 0) + logs_fund_disposit.map((a: any) => dailyFees.add(a.originToken, Number(a.amount * a.relayerFeePct) / 1e18)); + logs_filled_replay.map((a: any) => dailyFees.add(a.destinationToken, Number(a.amount) * Number(a.relayerFeePct + a.realizedLpFeePct) / 1e18)) return { - dailyFees: `${amount}`, - dailySupplySideRevenue: `${amount}`, + dailyFees, + dailySupplySideRevenue: dailyFees, timestamp } } diff --git a/fees/aerodrome/bribes.ts b/fees/aerodrome/bribes.ts index 0af579ccb8..811bb616c4 100644 --- a/fees/aerodrome/bribes.ts +++ b/fees/aerodrome/bribes.ts @@ -1,28 +1,7 @@ import ADDRESSES from '../../helpers/coreAssets.json' -import { ethers } from "ethers"; -import { CHAIN } from "../../helpers/chains"; import { FetchOptions } from '../../adapters/types'; const event_notify_reward = 'event NotifyReward(address indexed from,address indexed reward,uint256 indexed epoch,uint256 amount)'; -const event_geuge_created = 'event GaugeCreated(address indexed poolFactory,address indexed votingRewardsFactory,address indexed gaugeFactory,address pool,address bribeVotingReward,address feeVotingReward,address gauge,address creator)' - -const topic0_geuge_created = '0xef9f7d1ffff3b249c6b9bf2528499e935f7d96bb6d6ec4e7da504d1d3c6279e1'; -const contract_interface = new ethers.Interface([ - event_notify_reward, - event_geuge_created -]); - -interface ILog { - data: string; - transactionHash: string; - topics: string[]; -} - -interface IBribes { - token: string; - amount: number; -} - const gurar = '0x2073D8035bB2b0F2e85aAF5a8732C6f397F9ff9b'; diff --git a/fees/airswap.ts b/fees/airswap.ts index ef65533a8e..b3f8a07dd0 100644 --- a/fees/airswap.ts +++ b/fees/airswap.ts @@ -1,28 +1,8 @@ -import { FetchResultFees, SimpleAdapter } from "../adapters/types"; +import { ChainBlocks, FetchOptions, FetchResultFees, 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; - protocolFee: number; -} 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; @@ -36,42 +16,16 @@ const address: TAddress = { } 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, {})); + return async (timestamp: number, _: ChainBlocks, { createBalances, getLogs, }: FetchOptions): Promise => { + const dailyFees = createBalances(); - const logs: ITx[] = (await sdk.getEventLogs({ + (await getLogs({ 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, - protocolFee: Number(data!.args.protocolFee) - } + eventAbi: event_swap, + })).map((e: any) => { + dailyFees.add(e.signerToken, e.signerAmount.toString() * e.protocolFee.toString() / 10000) }) - const rawCoins = rawData.map((e: IData) => `${chain}:${e.signerToken.toLowerCase()}`); - const coins = [...new Set(rawCoins)] - const prices = await getPrices(coins, timestamp); - const feesAmount: 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) * (e.protocolFee / 10000)) * price; - }); - - const dailyFees = feesAmount.reduce((a: number, b: number) => a + b, 0); - return { - dailyFees: `${dailyFees}`, - dailyRevenue: `${dailyFees}`, - timestamp, - }; + return { dailyFees, dailyRevenue: dailyFees, timestamp, }; } } diff --git a/fees/alchemix.ts b/fees/alchemix.ts index af47a6d286..1856838bf0 100644 --- a/fees/alchemix.ts +++ b/fees/alchemix.ts @@ -1,10 +1,8 @@ import { Adapter, FetchResultFees } from "../adapters/types"; -import { CHAIN} from "../helpers/chains"; +import { CHAIN } from "../helpers/chains"; import { request, gql } from "graphql-request"; -import type { ChainEndpoints } from "../adapters/types" +import type { ChainBlocks, ChainEndpoints, FetchOptions } from "../adapters/types" import { Chain } from '@defillama/sdk/build/general'; -import { getPrices } from "../utils/prices"; - interface IData { yieldToken: string; @@ -41,32 +39,18 @@ const graph = (graphUrls: ChainEndpoints) => { }`; return (chain: Chain) => { - return async (timestamp: number): Promise => { - - const fromTimestamp = timestamp - 60 * 60 * 24 - const toTimestamp = timestamp + return async (timestamp: number, _: ChainBlocks, { createBalances, fromTimestamp, toTimestamp }: FetchOptions): Promise => { + const dailyFees = createBalances() const graphRes: IData[] = (await request(graphUrls[chain], graphQuery, { timestampFrom: fromTimestamp, timestampTo: toTimestamp })).alchemistHarvestEvents; - const coins = [...new Set(graphRes.map((a: IData) => `${chain}:${a.yieldToken.toLowerCase()}`))] - const prices = await getPrices(coins, timestamp); - const feesAmount = graphRes.map((a: IData) => { - const price = prices[`${chain}:${a.yieldToken.toLowerCase()}`].price; - const decimals = prices[`${chain}:${a.yieldToken.toLowerCase()}`].decimals; - const amount = ((Number(a.totalHarvested)) / 10 ** decimals) * price; - return amount; - }).reduce((a: number, b: number) => a + b, 0); - const dailyFee = feesAmount; - const dailyRevenue = dailyFee * 0.1; + graphRes.map((a: IData) => dailyFees.add(a.yieldToken, a.totalHarvested)) + const dailyRevenue = dailyFees.clone(0.1) - return { - dailyFees: `${dailyFee}`, - dailyRevenue: `${dailyRevenue}`, - timestamp - } + return { dailyFees, dailyRevenue, timestamp } } } }; diff --git a/fees/benqi-staked-avax.ts b/fees/benqi-staked-avax.ts index 717a421d5c..039cb6dfc9 100644 --- a/fees/benqi-staked-avax.ts +++ b/fees/benqi-staked-avax.ts @@ -1,46 +1,17 @@ -import { FetchResultFees, SimpleAdapter } from "../adapters/types"; +import { ChainBlocks, FetchOptions, FetchResultFees, SimpleAdapter } from "../adapters/types"; import { CHAIN } from "../helpers/chains"; -import { getBlock } from "../helpers/getBlock"; -import * as sdk from "@defillama/sdk"; -import { getPrices } from "../utils/prices"; const topic0 = '0x8fbf6a230d02fb8f41af8c1ca90b126472e11286c47d7ed86bb2e1fc51a283d8'; const address = '0x2b2c81e08f1af8835a78bb2a90ae924ace0ea4be' -interface ILog { - data: string; - transactionHash: string; - topics: string[]; -} -const fetchFees = async (timestamp: number): Promise => { - const toTimestamp = timestamp - const fromTimestamp = timestamp - 60 * 60 * 24 - const toBlock = await getBlock(toTimestamp, CHAIN.AVAX, {}) - const fromBlock = await getBlock(fromTimestamp, CHAIN.AVAX, {}) - const logs: ILog[] = (await sdk.getEventLogs({ - target: address, - topic: topic0, - toBlock: toBlock, - fromBlock: fromBlock, - chain: CHAIN.AVAX, - topics: [topic0] - })) as ILog[]; - const reward = logs.reduce((acc, log) => { - const amount = Number(log.data) / 10 ** 18 - return acc + amount - }, 0) - const avaxAddress = `${CHAIN.AVAX}:0x2b2c81e08f1af8835a78bb2a90ae924ace0ea4be` - const prices = await getPrices([avaxAddress], timestamp) - const sAVAXPrice = prices[avaxAddress]?.price || 0; - const dailyFees = (reward * sAVAXPrice) / .90 - const dailySupplySideRevenue = dailyFees * 0.90; - const dailyRevenue = dailyFees * 0.1; - return { - dailyFees: dailyFees.toString(), - dailyRevenue: dailyRevenue.toString(), - dailySupplySideRevenue: dailySupplySideRevenue.toString(), - timestamp - } +const fetchFees = async (timestamp: number, _: ChainBlocks, { createBalances, getLogs, }: FetchOptions): Promise => { + const dailyFees = createBalances() + const logs = await getLogs({ target: address, topics: [topic0] }) + logs.map((log) => dailyFees.add('0x2b2c81e08f1af8835a78bb2a90ae924ace0ea4be', log.data)) + dailyFees.resizeBy(1 / 0.9) + const dailyRevenue = dailyFees.clone(0.1) + const dailySupplySideRevenue = dailyFees.clone(0.9) + return { dailyFees, dailyRevenue, dailySupplySideRevenue, timestamp } } const adapters: SimpleAdapter = { diff --git a/fees/blastapi.ts b/fees/blastapi.ts index 7f84550baf..e821a2f344 100644 --- a/fees/blastapi.ts +++ b/fees/blastapi.ts @@ -1,12 +1,7 @@ -import { Adapter, FetchResultFees } from "../adapters/types"; +import { Adapter, ChainBlocks, FetchOptions, FetchResultFees } from "../adapters/types"; import { CHAIN } from "../helpers/chains"; -import { getTimestampAtStartOfDayUTC, getTimestampAtStartOfNextDayUTC } from "../utils/date"; -import * as sdk from "@defillama/sdk"; -import { getPrices } from "../utils/prices"; -import { getBlock } from "../helpers/getBlock"; import { Chain } from "@defillama/sdk/build/general"; -const topic0 = '0x5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62'; type TMarketPlaceAddress = { [l: string | Chain]: string; @@ -18,59 +13,18 @@ const marketplace_address: TMarketPlaceAddress = { [CHAIN.MOONBEAM]: '0xfb181a48b102580539b9b8aca6b1617ef0c80bf8', [CHAIN.FANTOM]: '0xfb181a48b102580539b9b8aca6b1617ef0c80bf8', [CHAIN.POLYGON]: '0xfb181a48b102580539b9b8aca6b1617ef0c80bf8', - // [CHAIN.XDAI]: '0xfb181a48b102580539b9b8aca6b1617ef0c80bf8', + [CHAIN.XDAI]: '0xfb181a48b102580539b9b8aca6b1617ef0c80bf8', [CHAIN.OPTIMISM]: '0xfb181a48b102580539b9b8aca6b1617ef0c80bf8', } -interface ITx { - data: string; - transactionHash: string; - topics: string[]; -} - -interface IData { - contract_address: string; - amount: number; -} - const fetch = (chain: Chain) => { - return async (timestamp: number): Promise => { - const todaysTimestamp = getTimestampAtStartOfDayUTC(timestamp) - const yesterdaysTimestamp = getTimestampAtStartOfNextDayUTC(timestamp) - - const fromBlock = (await getBlock(todaysTimestamp, chain, {})); - const toBlock = (await getBlock(yesterdaysTimestamp, chain, {})); - const logs: ITx[] = (await sdk.getEventLogs({ + return async (timestamp: number , _: ChainBlocks, { createBalances, getLogs, }: FetchOptions): Promise => { + const dailyFees = createBalances(); + (await getLogs({ target: marketplace_address[chain], - fromBlock: fromBlock, - toBlock: toBlock, - topics: [topic0], - chain: chain - })).map((e: any) => { return { data: e.data.replace('0x', ''), transactionHash: e.transactionHash, topics: e.topics } as ITx}); - - - const rawLogsData: IData[] = logs.map((tx: ITx) => { - const amount = Number('0x' + tx.data); - const address = tx.topics[2]; - const contract_address = '0x' + address.slice(26, address.length); - return { - amount: amount, - contract_address: contract_address - } as IData - }); - const tokens = [...new Set(rawLogsData.map((e: IData) => `${chain}:${e.contract_address.toLowerCase()}`))] - const prices = await getPrices(tokens, timestamp); - const feesAmounts: number[] = rawLogsData.map((e: IData) => { - const price = prices[`${chain}:${e.contract_address.toLowerCase()}`].price; - const decimals = prices[`${chain}:${e.contract_address.toLowerCase()}`].decimals; - return (e.amount / 10 ** decimals) * price; - }) - const dailyFees = feesAmounts.reduce((a: number, b: number) => a+b,0); - return { - dailyFees: dailyFees.toString(), - dailyRevenue: dailyFees.toString(), - timestamp - } + eventAbi: 'event Deposit (address indexed account, address indexed erc20, uint256 amount)' + })).forEach((e: any) => dailyFees.add(e.erc20, e.amount)) + return { dailyFees, timestamp, dailyRevenue: dailyFees }; } } @@ -100,10 +54,10 @@ const adapter: Adapter = { fetch: fetch(CHAIN.POLYGON), start: 1675382400, }, - // [CHAIN.XDAI]: { - // fetch: fetch(CHAIN.XDAI), - // start: 1675382400, - // }, + [CHAIN.XDAI]: { + fetch: fetch(CHAIN.XDAI), + start: 1675382400, + }, [CHAIN.OPTIMISM]: { fetch: fetch(CHAIN.OPTIMISM), start: 1675382400, diff --git a/fees/blazebot.ts b/fees/blazebot.ts index 28a6c37d12..a192cb198e 100644 --- a/fees/blazebot.ts +++ b/fees/blazebot.ts @@ -1,16 +1,13 @@ -import ADDRESSES from '../helpers/coreAssets.json' -import {Adapter, FetchResultFees} from "../adapters/types"; -import {CHAIN} from "../helpers/chains"; -import {Chain} from "@defillama/sdk/build/general"; -import {request, gql} from "graphql-request"; -import {getTimestampAtStartOfDayUTC} from "../utils/date"; -import { getPrices } from "../utils/prices"; +import { Adapter, ChainBlocks, FetchOptions, FetchResultFees } from "../adapters/types"; +import { CHAIN } from "../helpers/chains"; +import { Chain } from "@defillama/sdk/build/general"; +import { request, } from "graphql-request"; type TEndpoint = { [s: Chain | string]: string; } const endpoints: TEndpoint = { - [CHAIN.BASE]: "https://subgraphs.blazebot.io/subgraphs/name/blazebot/stats", + [CHAIN.BASE]: "https://subgraphs.blazebot.io/subgraphs/name/blazebot/stats", } interface ISwap { @@ -18,11 +15,9 @@ interface ISwap { fee: BigInt; } const graphs = (chain: Chain) => { - return async (timestamp: number): Promise => { - const todaysTimestamp = getTimestampAtStartOfDayUTC(timestamp) - const fromTimestamp = todaysTimestamp - 60 * 60 * 24 - const toTimestamp =todaysTimestamp - const query = gql` + return async (timestamp: number, _: ChainBlocks, { createBalances, fromTimestamp, toTimestamp }: FetchOptions): Promise => { + const dailyFees = createBalances() + const query = ` { fees(where: { timestamp_gte: ${fromTimestamp} @@ -33,28 +28,20 @@ const graphs = (chain: Chain) => { } } ` - const graphRes: ISwap[] = (await request(endpoints[chain], query)).fees; + const graphRes: ISwap[] = (await request(endpoints[chain], query)).fees; - const ethAddress = "ethereum:" + ADDRESSES.null; - const ethPrice = (await getPrices([ethAddress], timestamp))[ethAddress].price; - const dailyFees = graphRes.map((e: ISwap) => { - const decimals = 18; - return (Number(e.fee) / 10 ** decimals) * ethPrice - }).reduce((a: number, b: number) => a + b, 0) - return { - dailyFees: `${dailyFees}`, - timestamp, - }; - } + graphRes.map((e: ISwap) => dailyFees.addGasToken(e.fee)) + return { dailyFees, timestamp } + } } const adapter: Adapter = { - adapter: { - [CHAIN.BASE]: { - fetch: graphs(CHAIN.BASE), - start: 1694131200, - }, - } + adapter: { + [CHAIN.BASE]: { + fetch: graphs(CHAIN.BASE), + start: 1694131200, + }, + } } export default adapter; diff --git a/fees/bsc.ts b/fees/bsc.ts index d4b2bf1028..9671c64273 100644 --- a/fees/bsc.ts +++ b/fees/bsc.ts @@ -1,14 +1,9 @@ -import ADDRESSES from '../helpers/coreAssets.json' import { Adapter, ProtocolType } from "../adapters/types"; import { BSC } from "../helpers/chains"; -import { request, gql } from "graphql-request"; -import type { ChainEndpoints } from "../adapters/types" +import { request, } from "graphql-request"; +import type { ChainEndpoints, FetchOptions } from "../adapters/types" import { Chain } from '@defillama/sdk/build/general'; -import { getPrices } from "../utils/prices"; -import { getBlock } from "../helpers/getBlock"; import { ChainBlocks } from "../adapters/types"; -import BigNumber from "bignumber.js"; -import { getTimestampAtStartOfPreviousDayUTC, getTimestampAtStartOfDayUTC } from "../utils/date"; const endpoints = { [BSC]: @@ -18,39 +13,28 @@ const endpoints = { const graphs = (graphUrls: ChainEndpoints) => { return (chain: Chain) => { - return async (timestamp: number, chainBlocks: ChainBlocks) => { - const todaysTimestamp = getTimestampAtStartOfDayUTC(timestamp) - const yesterdaysTimestamp = getTimestampAtStartOfPreviousDayUTC(timestamp) + return async (timestamp: number, _chainBlocks: ChainBlocks, { createBalances, getFromBlock, getToBlock, }: FetchOptions) => { + const dailyFees = createBalances() - const todaysBlock = (await getBlock(todaysTimestamp, chain, chainBlocks)); - const yesterdaysBlock = (await getBlock(yesterdaysTimestamp, chain, {})); - - const graphQuery = gql - `query txFees { - yesterday: fee(id: "1", block: { number: ${yesterdaysBlock} }) { + const graphQuery = `query txFees { + yesterday: fee(id: "1", block: { number: ${await getFromBlock()} }) { totalFees } - today: fee(id: "1", block: { number: ${todaysBlock} }) { + today: fee(id: "1", block: { number: ${await getToBlock()} }) { totalFees } }`; const graphRes = await request(graphUrls[chain], graphQuery); - const dailyFee = new BigNumber(graphRes["today"]["totalFees"]).minus(new BigNumber(graphRes["yesterday"]["totalFees"])) - - const bnbAddress = "bsc:" + ADDRESSES.null; - const pricesObj: any = await getPrices([bnbAddress], todaysTimestamp); - const latestPrice = new BigNumber(pricesObj[bnbAddress]["price"]) - - const finalDailyFee = dailyFee.multipliedBy(latestPrice) - const finalTotalFee = new BigNumber(graphRes["today"]["totalFees"]).multipliedBy(latestPrice) + const dailyFee = graphRes["today"]["totalFees"] - graphRes["yesterday"]["totalFees"] + console.log(dailyFee, graphRes) + dailyFees.addGasToken(dailyFee * 1e18) return { - timestamp, - totalFees: finalTotalFee.toString(), - dailyFees: finalDailyFee.toString(), - dailyRevenue: timestamp<1638234000?"0":(finalDailyFee.times(0.1)).toString(), // https://github.com/bnb-chain/BEPs/blob/master/BEP95.md + timestamp, dailyFees, + // totalFees: finalTotalFee.toString(), + dailyRevenue: timestamp < 1638234000 ? 0: dailyFees.clone(0.1), // https://github.com/bnb-chain/BEPs/blob/master/BEP95.md }; }; }; @@ -60,8 +44,8 @@ const graphs = (graphUrls: ChainEndpoints) => { const adapter: Adapter = { adapter: { [BSC]: { - fetch: graphs(endpoints)(BSC), - start: 1598671449, + fetch: graphs(endpoints)(BSC), + start: 1598671449, }, }, protocolType: ProtocolType.CHAIN diff --git a/fees/cardano.ts b/fees/cardano.ts index e78df6f95a..1670c7c79e 100644 --- a/fees/cardano.ts +++ b/fees/cardano.ts @@ -1,8 +1,7 @@ -import { Adapter, FetchResult, ProtocolType } from "../adapters/types"; +import { Adapter, ChainBlocks, FetchOptions, FetchResult, ProtocolType } from "../adapters/types"; import { IDate } from "../helpers/bitqueryFees"; import { CHAIN } from "../helpers/chains"; import { getTimestampAtStartOfDayUTC, getTimestampAtStartOfNextDayUTC } from "../utils/date"; -import { getPrices } from "../utils/prices"; import { httpPost } from "../utils/fetchURL"; @@ -35,7 +34,8 @@ const adapterQuery = async (form: string, till: string, network: string): Promis return result; } const startTime = 1577836800; -const fetch = async (timestamp: number): Promise => { +const fetch = async (timestamp: number , _: ChainBlocks, { createBalances }: FetchOptions): Promise => { + const dailyFees = createBalances() const dayTimestamp = getTimestampAtStartOfDayUTC(timestamp); const startTimestamp = getTimestampAtStartOfDayUTC(startTime); const tillTimestamp = getTimestampAtStartOfNextDayUTC(timestamp); @@ -43,15 +43,12 @@ const fetch = async (timestamp: number): Promise => { const till = new Date((tillTimestamp - 1) * 1000).toISOString(); const result: ITxAda[] = await adapterQuery(form, till, "cardano"); const totalFees = result.filter((a: ITxAda) => new Date(a.date.date).getTime() <= new Date(till).getTime()).reduce((a: number, b: ITxAda)=> a + b.feeValue, 0); - const dailyFees = result.find((a: ITxAda) => (getTimestampAtStartOfDayUTC(new Date(a.date.date).getTime()) /1000) === getTimestampAtStartOfDayUTC(new Date(dayTimestamp).getTime()))?.feeValue - const price_id = 'coingecko:cardano' - const price = (await getPrices([price_id], dayTimestamp))[price_id].price; - const dailyFeesUsd = (dailyFees || 0) * price; - const totalFeesUsd = (totalFees * price) + const _dailyFees = result.find((a: ITxAda) => (getTimestampAtStartOfDayUTC(new Date(a.date.date).getTime()) /1000) === getTimestampAtStartOfDayUTC(new Date(dayTimestamp).getTime()))?.feeValue + dailyFees.addCGToken('cardano', _dailyFees) return { timestamp, - totalFees: totalFeesUsd.toString(), - dailyFees: dailyFeesUsd.toString(), + dailyFees, + // totalFees, }; }; diff --git a/fees/clever.ts b/fees/clever.ts index b2ea7f98b8..d6de35ceaf 100644 --- a/fees/clever.ts +++ b/fees/clever.ts @@ -1,11 +1,8 @@ import { Adapter } from "../adapters/types"; import { ETHEREUM } from "../helpers/chains"; -import { request, gql } from "graphql-request"; -import type { ChainEndpoints } from "../adapters/types"; +import { request, } from "graphql-request"; +import type { ChainBlocks, ChainEndpoints, FetchOptions } from "../adapters/types"; import { Chain } from "@defillama/sdk/build/general"; -import { getTimestampAtStartOfDayUTC } from "../utils/date"; -import { getPrices } from "../utils/prices"; -import BigNumber from "bignumber.js"; const endpoints = { [ETHEREUM]: @@ -14,52 +11,19 @@ const endpoints = { const graph = (graphUrls: ChainEndpoints) => { return (chain: Chain) => { - return async (timestamp: number) => { - const dateId = Math.floor(getTimestampAtStartOfDayUTC(timestamp)); + return async (_timestamp: number, _: ChainBlocks, { createBalances, startOfDay }: FetchOptions) => { + const dailyRevenue = createBalances() + const dateId = Math.floor(startOfDay); - const graphQuery = gql`{ - dailyRevenueSnapshot(id: ${dateId}) { - cvxRevenue - fraxRevenue - } - }`; + const graphQuery = `{ dailyRevenueSnapshot(id: ${dateId}) { cvxRevenue fraxRevenue } }`; - const { dailyRevenueSnapshot } = await request( - graphUrls[chain], - graphQuery - ); - if (!dailyRevenueSnapshot) { - return { - timestamp, - dailyFees: "0", - dailyRevenue: "0", - }; - } - Object.keys(dailyRevenueSnapshot).map(function (k) { - dailyRevenueSnapshot[k] = new BigNumber(dailyRevenueSnapshot[k]); - }); - const snapshot = dailyRevenueSnapshot; + const { dailyRevenueSnapshot: snapshot } = await request(graphUrls[chain], graphQuery); + if (!snapshot) throw new Error("No data found"); - const coins = ["convex-finance", "frax"].map( - (item) => `coingecko:${item}` - ); - const coinsUnique = [...new Set(coins)]; - const prices = await getPrices(coinsUnique, timestamp); - const cvxPrice = prices["coingecko:convex-finance"]; - const fraxPrice = prices["coingecko:frax"]; - - const cvxRevenue = snapshot.cvxRevenue.times(cvxPrice.price); - const fraxRevenue = snapshot.fraxRevenue.times(fraxPrice.price); - - const dailyRevenue = cvxRevenue.plus(fraxRevenue); - - const dailyFees = dailyRevenue * 2; - - return { - timestamp, - dailyFees: dailyFees.toString(), - dailyRevenue: dailyRevenue.toString(), - }; + dailyRevenue.addCGToken("convex-finance", snapshot.cvxRevenue); + dailyRevenue.addCGToken("frax", snapshot.fraxRevenue); + const dailyFees = dailyRevenue.clone(2); + return { timestamp: startOfDay, dailyFees, dailyRevenue, } }; }; }; diff --git a/fees/concentrator.ts b/fees/concentrator.ts index 665c72544e..6edbe8d741 100644 --- a/fees/concentrator.ts +++ b/fees/concentrator.ts @@ -1,11 +1,9 @@ import { Adapter } from "../adapters/types"; import { ETHEREUM } from "../helpers/chains"; import { request, gql } from "graphql-request"; -import type { ChainEndpoints } from "../adapters/types"; +import type { ChainBlocks, ChainEndpoints, FetchOptions } from "../adapters/types"; import { Chain } from "@defillama/sdk/build/general"; import { getTimestampAtStartOfDayUTC } from "../utils/date"; -import { getPrices } from "../utils/prices"; -import BigNumber from "bignumber.js"; const endpoints = { [ETHEREUM]: @@ -14,7 +12,7 @@ const endpoints = { const graph = (graphUrls: ChainEndpoints) => { return (chain: Chain) => { - return async (timestamp: number) => { + return async (timestamp: number, _: ChainBlocks, { createBalances }: FetchOptions) => { const dateId = Math.floor(getTimestampAtStartOfDayUTC(timestamp)); const graphQuery = gql`{ dailyRevenueSnapshot(id: ${dateId}) { @@ -22,37 +20,12 @@ const graph = (graphUrls: ChainEndpoints) => { } }`; - const { dailyRevenueSnapshot } = await request( - graphUrls[chain], - graphQuery - ); - if (!dailyRevenueSnapshot) { - return { - timestamp, - dailyFees: "0", - dailyRevenue: "0", - }; - } - Object.keys(dailyRevenueSnapshot).map(function (k) { - dailyRevenueSnapshot[k] = new BigNumber(dailyRevenueSnapshot[k]); - }); - const snapshot = dailyRevenueSnapshot; - - const coins = ["aladdin-cvxcrv", "convex-crv"].map((item) => `coingecko:${item}`); - const coinsUnique = [...new Set(coins)]; - const prices = await getPrices(coinsUnique, timestamp); - const aCRVPrice = prices["coingecko:aladdin-cvxcrv"]; - const CRVPrice = prices["coingecko:convex-crv"]; - - const dailyRevenue = snapshot.aCRVRevenue.times(aCRVPrice?.price ?? CRVPrice.price); - - const dailyFees = dailyRevenue * 2; - - return { - timestamp, - dailyFees: dailyFees.toString(), - dailyRevenue: dailyRevenue.toString(), - }; + const { dailyRevenueSnapshot: snapshot } = await request(graphUrls[chain], graphQuery); + if (!snapshot) throw new Error("No data found"); + const dailyRevenue = createBalances(); + dailyRevenue.addCGToken("aladdin-crv", snapshot.aCRVRevenue); + const dailyFees = dailyRevenue.clone(2); + return { timestamp, dailyFees, dailyRevenue }; }; }; }; diff --git a/fees/crv-usd.ts b/fees/crv-usd.ts index 3d08994d19..58d942d440 100644 --- a/fees/crv-usd.ts +++ b/fees/crv-usd.ts @@ -1,10 +1,6 @@ -import ADDRESSES from '../helpers/coreAssets.json' import { Chain } from "@defillama/sdk/build/general"; -import { FetchResultFees, SimpleAdapter } from "../adapters/types"; +import { ChainBlocks, FetchOptions, FetchResultFees, SimpleAdapter } from "../adapters/types"; import { CHAIN } from "../helpers/chains"; -import { getBlock } from "../helpers/getBlock"; -import * as sdk from "@defillama/sdk"; -import { getPrices } from "../utils/prices"; type TContract = { [s: string | Chain]: string[]; @@ -19,42 +15,13 @@ const controller: TContract = { '0x8472a9a7632b173c8cf3a86d3afec50c35548e76' ] } -const topic0 = '0x5393ab6ef9bb40d91d1b04bbbeb707fbf3d1eb73f46744e2d179e4996026283f'; -interface ILog { - data: string; - transactionHash: string; - topics: string[]; -} const fetchFees = (chain: Chain) => { - return async (timestamp: number): Promise => { - const toTimestamp = timestamp - const fromTimestamp = timestamp - 60 * 60 * 24 - const fromBlock = (await getBlock(fromTimestamp, chain, {})); - const toBlock = (await getBlock(toTimestamp, chain, {})); - - const logs: ILog[] = (await Promise.all(controller[chain].map((address: string) => sdk.getEventLogs({ - target: address, - toBlock: toBlock, - fromBlock: fromBlock, - chain: chain, - topics: [topic0] - })))).flat(); - const crvUSDAddress = `${CHAIN.ETHEREUM}:0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E` - const prices = await getPrices([crvUSDAddress], timestamp); - const crvUSDPrice = prices[crvUSDAddress]?.price || 1; - const dailyFees = logs.reduce((acc: number, log: ILog) => { - const data = log.data.replace('0x', ''); - const fee = (Number('0x' + data.slice(0, 64)) / 1e18) * crvUSDPrice; - return acc + fee; - }, 0) - - return { - dailyFees: `${dailyFees}`, - dailyHoldersRevenue: `${dailyFees}`, - dailyRevenue: `${dailyFees}`, - timestamp - } + return async (timestamp: number, _: ChainBlocks, { createBalances, getLogs, }: FetchOptions): Promise => { + const dailyFees = createBalances() + const logs = await getLogs({ targets: controller[chain], eventAbi: 'event CollectFees (uint256 amount, uint256 new_supply)' }) + logs.forEach((i: any) => dailyFees.add('0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E', i.amount)) + return { dailyFees, timestamp, dailyRevenue: dailyFees, dailyHoldersRevenue: dailyFees } } } diff --git a/fees/e3.ts b/fees/e3.ts index 025955edd5..9e0df3bfe9 100644 --- a/fees/e3.ts +++ b/fees/e3.ts @@ -1,27 +1,10 @@ -import { SimpleAdapter } from "../adapters/types"; +import { ChainBlocks, FetchOptions, 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 { - protocolFeesX: number; - protocolFeesY: number; - totalFeesX: number; - totalFeesY: 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; @@ -32,104 +15,56 @@ const ABIs: TABI = { } 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 + return async (timestamp: number, _: ChainBlocks, { createBalances, api, getLogs, }: FetchOptions) => { - const [underlyingToken0, underlyingToken1] = await Promise.all( + const lpTokens = await api.fetchList({ lengthAbi: ABIs.getNumberOfLBPairs, itemAbi: ABIs.getLBPairAtIndex, target: FACTORY_ADDRESS }) + const dailyFees = createBalances(); + const dailyRevenue = createBalances(); + const [tokenXs, tokenYs] = await Promise.all( ['address:getTokenX', 'address:getTokenY'].map((method: string) => - sdk.api2.abi.multiCall({ + api.multiCall({ abi: method, - calls: lpTokens.map((address: string) => ({ - target: address, - })), - chain: _chain + calls: lpTokens, }) ) ); - - 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: any[] = 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 protocolFeesX = Number('0x' + '0'.repeat(32) + value!.args.protocolFees.replace('0x', '').slice(0, 32)) / 10 ** token1Decimals - const protocolFeesY = Number('0x' + '0'.repeat(32) + value!.args.protocolFees.replace('0x', '').slice(32, 64)) / 10 ** token0Decimals - const totalFeesX = Number('0x' + '0'.repeat(32) + value!.args.totalFees.replace('0x', '').slice(0, 32)) / 10 ** token1Decimals; - const totalFeesY = Number('0x' + '0'.repeat(32) + value!.args.totalFees.replace('0x', '').slice(32, 64)) / 10 ** token0Decimals; - return { - protocolFeesX, - protocolFeesY, - totalFeesX, - totalFeesY, - // tx: p.transactionHash, // for debugging - // token0Decimals, - // token1Decimals - } as IAmount + const decimalsXs = await api.multiCall({ abi: 'erc20:decimals', calls: tokenXs }) + const decimalsYs = await api.multiCall({ abi: 'erc20:decimals', calls: tokenYs }) + + const logs: any[][] = await getLogs({ + targets: lpTokens, + eventAbi: event_swap, + flatten: false, + }) + + lpTokens.map((_: string, index: number) => { + logs[index] + .map((p: any) => { + const token0 = tokenXs[index]; + const token1 = tokenYs[index]; + const decimalsX = decimalsXs[index]; + const decimalsY = decimalsYs[index]; + const protocolFeesY = Number('0x' + p.protocolFees.replace('0x', '').slice(0, 32)) + const protocolFeesX = Number('0x' + p.protocolFees.replace('0x', '').slice(32, 64)) + const totalFeesY = Number('0x' + p.totalFees.replace('0x', '').slice(0, 32)); + const totalFeesX = Number('0x' + p.totalFees.replace('0x', '').slice(32, 64)); + dailyFees.add(token0, totalFeesX ) + dailyFees.add(token1, totalFeesY ) + dailyRevenue.add(token0, protocolFeesX) + dailyRevenue.add(token1, protocolFeesY) }); - - const token0Price = (prices[`${_chain}:${tokens0[index]}`]?.price || 0); - const token1Price = (prices[`${_chain}:${tokens1[index]}`]?.price || 0); - const protocolFeesX = log - .reduce((a: number, b: IAmount) => Number(b.protocolFeesX) + a, 0) * token1Price; - const protocolFeesY = log - .reduce((a: number, b: IAmount) => Number(b.protocolFeesY) + a, 0) * token0Price; - const totalFeesX = log - .reduce((a: number, b: IAmount) => Number(b.totalFeesX) + a, 0) * token1Price; - const totalFeesY = log - .reduce((a: number, b: IAmount) => Number(b.totalFeesY) + a, 0) * token0Price; - - return ({ - totalFees: (totalFeesX + totalFeesY), - protocolFees: (protocolFeesX + protocolFeesY) - }); }); - const dailyFees = untrackVolumes.reduce((a: number, b: any) => a + b.totalFees, 0); - const dailyProtocolFees = untrackVolumes.reduce((a: number, b: any) => a + b.protocolFees, 0); + const dailySupplySideRevenue = dailyFees.clone(); + dailySupplySideRevenue.subtract(dailyRevenue); + return { - dailyFees: `${dailyFees}`, - dailyUserFees: `${dailyFees}`, - dailyProtocolRevenue: `${dailyProtocolFees}`, - dailyRevenue: `${dailyProtocolFees}`, - dailyHoldersRevenue: `${dailyProtocolFees}`, - dailySupplySideRevenue: `${dailyFees - dailyProtocolFees}`, + dailyFees: dailyFees, + dailyUserFees: dailyFees, + dailyRevenue: dailyRevenue, + dailyProtocolRevenue: dailyRevenue, + dailyHoldersRevenue: dailyRevenue, + dailySupplySideRevenue, timestamp, }; } diff --git a/fees/ekubo.ts b/fees/ekubo.ts index 9bcbeb312b..1ef36fcf86 100644 --- a/fees/ekubo.ts +++ b/fees/ekubo.ts @@ -1,30 +1,26 @@ -import { Adapter } from "../adapters/types"; +import { Adapter, ChainBlocks, FetchOptions } from "../adapters/types"; import { CHAIN } from "../helpers/chains"; import fetchURL from "../utils/fetchURL"; -import { getPrices } from "../utils/prices"; -const toki = (n:any) =>"starknet:0x"+BigInt(n).toString(16).padStart("049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7".length, "0") +const toki = (n: any) => "starknet:0x" + BigInt(n).toString(16).padStart("049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7".length, "0") -async function getDimension(responseRaw:any[], key: string, timestamp:number){ - const response = responseRaw - .map(t=>({token: toki(t.token), vol: t[key]})) - const prices = await getPrices(response.map(t=>t.token), timestamp) - return response.map((token) => { - const price = prices[token.token] - if(price === undefined){ return 0 } - const usdVal = Number(token.vol) * price.price / (10**price.decimals) - return usdVal - }).reduce((a: number, b: number) => a+b,0); +function getDimension(responseRaw: any[], key: string, balances: any) { + const response = responseRaw + .map(t => ({ token: toki(t.token), vol: t[key] })) + response.map((token) => { + balances.addTokenVannila(token.token, token.vol) + }) + return balances } -const fetch = async (timestamp: number) => { - const fees = await getDimension((await fetchURL("https://mainnet-api.ekubo.org/overview")).volumeByToken_24h, "fees", timestamp) - const rev = await getDimension((await fetchURL("https://mainnet-api.ekubo.org/overview")).revenueByToken_24h, "revenue", timestamp) +const fetch = async (timestamp: number, _: ChainBlocks, { createBalances }: FetchOptions) => { + const dailyFees = getDimension((await fetchURL("https://mainnet-api.ekubo.org/overview")).volumeByToken_24h, "fees", createBalances()) + const dailyRevenue = getDimension((await fetchURL("https://mainnet-api.ekubo.org/overview")).revenueByToken_24h, "revenue", createBalances()) return { - timestamp: timestamp, - dailyFees: `${fees}`, - dailyRevenue: `${rev}`, - }; + dailyFees, + dailyRevenue, + timestamp, + } } const adapter: Adapter = { diff --git a/fees/equalizer-exchange.ts b/fees/equalizer-exchange.ts index 3f38dbdae1..f461759b82 100644 --- a/fees/equalizer-exchange.ts +++ b/fees/equalizer-exchange.ts @@ -1,278 +1,14 @@ -import ADDRESSES from '../helpers/coreAssets.json' -import { FetchResultFees, SimpleAdapter } from "../adapters/types"; +import { 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 { ethers } from "ethers"; +import { getFeesExport } from '../helpers/solidly'; -type TPrice = { - [s: string]: { - price: number; - decimals: number - }; -} - -interface ILog { - data: string; - topics: string[]; - transactionHash: string; -} -interface IAmount { - amount0: number; - amount1: number; -} -interface IBribeAndFeeAmount { - amount: number; -} -interface IBribedAmount { - amount: number; -} -interface IAmountUSD { - amount: number; -} - -const TOPIC_Fees = '0x112c256902bf554b6ed882d2936687aaeb4225e8cd5b51303c90ca6cf43a8602'; -const TOPIC_NotifyRewardAmount = '0x52977ea98a2220a03ee9ba5cb003ada08d394ea10155483c95dc2dc77a7eb24b'; -const TOPIC_Notify = 'event NotifyReward(address indexed from, address indexed reward, uint indexed epoch, uint amount)'; -const INTERFACE_N = new ethers.Interface([TOPIC_Notify]); const VOTER_ADDRESS = '0xE3D1A117dF7DCaC2eB0AC8219341bAd92f18dAC1'; const FACTORY_ADDRESS = '0xc6366EFD0AF1d09171fe0EBF32c7943BB310832a'; -const CHAIN_USED = CHAIN.FANTOM; -const CHAIN_SLUG = 'fantom'; - -type TABI = { - [k: string]: string; -} -const ABIs: TABI = { - "allPairsLength": "uint256:allPairsLength", - "allPairs": "function allPairs(uint256) view returns (address)" -} - -const VOTER_ABI: TABI = { - "length": "uint256:length", - "pools": "function pools(uint256) view returns (address)", - "gauges": "function gauges(address) view returns (address)", - "bribes": "function bribes(address) view returns (address)" -} - -const fetch = async (timestamp: number): Promise => { - const fromTimestamp = timestamp - 60 * 60 * 24 - const toTimestamp = timestamp - - const poolLength = (await sdk.api2.abi.call({ - target: FACTORY_ADDRESS, - chain: CHAIN_SLUG, - abi: ABIs.allPairsLength, - })); - - const poolsRes = await sdk.api2.abi.multiCall({ - abi: ABIs.allPairs, - target: FACTORY_ADDRESS, - calls: Array.from(Array(Number(poolLength)).keys()), - chain: CHAIN_SLUG - }); - - const lpTokens = poolsRes - - const [underlyingToken0, underlyingToken1] = await Promise.all( - ['address:token0', 'address:token1'].map((method) => - sdk.api2.abi.multiCall({ - abi: method, - calls: lpTokens.map((address: string) => ({ - target: address, - })), - chain: CHAIN_SLUG - }) - ) - ); - - const tokens0 = underlyingToken0; - const tokens1 = underlyingToken1; - - - const poolsGauges = await sdk.api2.abi.multiCall({ - abi: VOTER_ABI.gauges, - target: VOTER_ADDRESS, - calls: lpTokens, - chain: CHAIN_SLUG - }); - - const voterGauges = poolsGauges.filter((_vg: string) => - _vg !== ADDRESSES.null - ); - - - - const poolsGaugesToBribes = await sdk.api2.abi.multiCall({ - abi: VOTER_ABI.bribes, - target: VOTER_ADDRESS, - calls: voterGauges, - chain: CHAIN_SLUG - }); - - const voterBribes = poolsGaugesToBribes; - - - - - - const fromBlock = (await getBlock(fromTimestamp, CHAIN_SLUG, {})); - const toBlock = (await getBlock(toTimestamp, CHAIN_SLUG, {})); - - const tradefeeLogs: ILog[][] = (await Promise.all(lpTokens.map((address: string) => sdk.getEventLogs({ - target: address, - toBlock: toBlock, - fromBlock: fromBlock, - chain: CHAIN_SLUG, - topics: [TOPIC_Fees] - })))) as ILog[][]; - - - const bribeAndFeeLogs: ILog[][] = (await Promise.all(voterBribes.map((address: string) => sdk.getEventLogs({ - target: address, - toBlock: toBlock, - fromBlock: fromBlock, - chain: CHAIN_SLUG, - topics: [TOPIC_NotifyRewardAmount] - })))) as ILog[][]; - - - - var allBribedTokens: string[] = new Array(0); - const listOfBribedTokensByPool: string[][] = bribeAndFeeLogs.map((perBribeLogs: ILog[]) => { - const _innerBT: string[] = perBribeLogs.map((e: ILog) => { - const _l = INTERFACE_N.parseLog(e); - if (_l == null) { return "" } - const _t = `${CHAIN_USED}:${_l.args.reward.toLowerCase()}`; - return _t; - //return `${CHAIN_USED}:${e.topics[2].toLowerCase()}`; - }); - allBribedTokens = allBribedTokens.concat(_innerBT); - return _innerBT; - }); - - allBribedTokens.filter((_ta: string) => { _ta != "" }) - - - - - - - const rawCoins = [...tokens0, ...tokens1, ...allBribedTokens].map((e: string) => `${CHAIN_SLUG}:${e}`); - const coins = [...new Set(rawCoins)]; - - // const prices = await getPrices(coins, timestamp); - // { getPrices } function breaks above 100 tokens..splitting into chunks of 100 - - 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 tradefees: number[] = lpTokens.map((_: string, index: number) => { - const token0Decimals = (prices[`${CHAIN_SLUG}:${tokens0[index]}`]?.decimals || 0) - const token1Decimals = (prices[`${CHAIN_SLUG}:${tokens1[index]}`]?.decimals || 0) - const tradefeesLog: IAmount[] = tradefeeLogs[index] - .map((e: ILog) => { return { ...e, data: e.data.replace('0x', '') } }) - .map((p: ILog) => { - const amount0 = Number('0x' + p.data.slice(0, 64)) / 10 ** token0Decimals; - const amount1 = Number('0x' + p.data.slice(64, 128)) / 10 ** token1Decimals; - return { - amount0, - amount1 - } as IAmount - }) as IAmount[]; - const token0Price = (prices[`${CHAIN_SLUG}:${tokens0[index]}`]?.price || 0); - const token1Price = (prices[`${CHAIN_SLUG}:${tokens1[index]}`]?.price || 0); - - const feesAmount0 = tradefeesLog - .reduce((a: number, b: IAmount) => Number(b.amount0) + a, 0) * token0Price; - const feesAmount1 = tradefeesLog - .reduce((a: number, b: IAmount) => Number(b.amount1) + a, 0) * token1Price; - - const feesUSD = feesAmount0 + feesAmount1; - return feesUSD; - }); - - - - const notifiedFees: number[] = voterBribes.map((_: string, index: number) => { - const notifiedFeesLog: IAmountUSD[] = bribeAndFeeLogs[index] - .map((e: ILog) => { return { ...e } }) - .map((p: ILog) => { - const _log = INTERFACE_N.parseLog(p); - if (_log == null || _log.args.from != voterGauges[index]) { - const amount = 0; - return { amount } as IAmountUSD - } - const _token = _log.args.reward; - const _price = (prices[`${CHAIN_SLUG}:${_token}`]?.price || 0); - const _deci = prices[`${CHAIN_SLUG}:${_token}`]?.decimals || 0; - const amount = Number(p.data) / 10 ** _deci * _price; - return { amount } as IAmountUSD - }) as IAmountUSD[]; - - const notifiedFeeAmount = notifiedFeesLog - .reduce((a: number, b: IAmountUSD) => Number(b.amount) + a, 0); - - return notifiedFeeAmount; - }); - - - - - const notifiedBribes: number[] = voterBribes.map((_: string, index: number) => { - const bribesLog: IAmountUSD[] = bribeAndFeeLogs[index] - .map((e: ILog) => { return { ...e } }) - .map((p: ILog) => { - const _log = INTERFACE_N.parseLog(p); - if (_log == null || _log.args.from == voterGauges[index]) { - const amount = 0; - return { amount } as IAmountUSD - } - const _token = _log.args.reward; - const _price = (prices[`${CHAIN_SLUG}:${_token}`]?.price || 0); - const _deci = prices[`${CHAIN_SLUG}:${_token}`]?.decimals || 0; - const amount = Number(p.data) / 10 ** _deci * _price; - return { amount } as IAmountUSD - }) as IAmountUSD[]; - - const bribedAmount = bribesLog.reduce((a: number, b: IBribedAmount) => Number(b.amount) + a, 0); - - return bribedAmount; - }); - - - - - - - - const dailyFees = tradefees.reduce((a: number, b: number) => a + b, 0) - const dailyRevenueFees = notifiedFees.reduce((a: number, b: number) => a + b, 0) - const dailyRevenueBribes = notifiedBribes.reduce((a: number, b: number) => a + b, 0) - - - - return { - dailyFees: `${dailyFees}`, - dailyRevenue: `${dailyRevenueFees}`, - dailyHoldersRevenue: `${dailyRevenueFees}`, - dailyBribesRevenue: `${dailyRevenueBribes}`, - timestamp, - }; -} const adapter: SimpleAdapter = { adapter: { [CHAIN.FANTOM]: { - fetch, + fetch: getFeesExport({ VOTER_ADDRESS, FACTORY_ADDRESS }), start: 1670544000, }, } diff --git a/fees/ethereum/index.ts b/fees/ethereum/index.ts index 5a2ff93e86..cd32573681 100644 --- a/fees/ethereum/index.ts +++ b/fees/ethereum/index.ts @@ -1,5 +1,5 @@ import ADDRESSES from '../../helpers/coreAssets.json' -import { Adapter, ProtocolType } from "../../adapters/types"; +import { Adapter, ChainBlocks, FetchOptions, ProtocolType } from "../../adapters/types"; import { ETHEREUM } from "../../helpers/chains"; import { getTimestampAtStartOfPreviousDayUTC, getTimestampAtStartOfDayUTC } from "../../utils/date"; import { getOneDayFees } from "../../helpers/getChainFees"; @@ -14,42 +14,36 @@ interface IChartItem { Result: number } -const graphs = () => { - return () => { - return async (timestamp: number) => { - const todaysTimestamp = getTimestampAtStartOfDayUTC(timestamp) - const yesterdaysTimestamp = getTimestampAtStartOfPreviousDayUTC(timestamp) - const today = new Date(todaysTimestamp * 1000).toISOString() - const yesterday = new Date(yesterdaysTimestamp * 1000).toISOString() - - const dailyFee = await getOneDayFees('eth', yesterday, today); - const burnData: IChartItem[] = (await fetchURL(burnEndpoint)).chart.jsonFile.Series['ETH Burned']['Data'] - - const dailyRevEth = burnData - .filter(item => item.Timestamp === yesterdaysTimestamp) - .find(item => item)?.Result || 0 - - const ethAddress = "ethereum:" + ADDRESSES.ethereum.WETH; - const pricesObj: any = await getPrices([ethAddress], todaysTimestamp); - const latestPrice = new BigNumber(pricesObj[ethAddress]["price"]) - - const dailyRev = latestPrice.multipliedBy(new BigNumber(dailyRevEth)) - - return { - timestamp, - dailyFees: dailyFee.toString(), - dailyRevenue: dailyRev.toString(), - dailyHoldersRevenue: dailyRev.toString(), - }; - }; +const fetch = async (timestamp: number, _: ChainBlocks, { createBalances }: FetchOptions) => { + const todaysTimestamp = getTimestampAtStartOfDayUTC(timestamp) + const yesterdaysTimestamp = getTimestampAtStartOfPreviousDayUTC(timestamp) + const today = new Date(todaysTimestamp * 1000).toISOString() + const yesterday = new Date(yesterdaysTimestamp * 1000).toISOString() + + const dailyFees = await getOneDayFees('eth', yesterday, today); + const burnData: IChartItem[] = (await fetchURL(burnEndpoint)).chart.jsonFile.Series['ETH Burned']['Data'] + + const dailyRevEth = burnData + .filter(item => item.Timestamp === yesterdaysTimestamp) + .find(item => item)?.Result || 0 + + + const dailyRev = createBalances() + dailyRev.addGasToken(dailyRevEth * 10 ** 18) + + return { + timestamp, + dailyFees, + dailyRevenue: dailyRev, + dailyHoldersRevenue: dailyRev, }; }; const adapter: Adapter = { adapter: { [ETHEREUM]: { - fetch: graphs()(), - start: 1438228800, + fetch, + start: 1438228800, }, }, protocolType: ProtocolType.CHAIN diff --git a/fees/fantom.ts b/fees/fantom.ts index 1aaa5d0476..5039c56b48 100644 --- a/fees/fantom.ts +++ b/fees/fantom.ts @@ -1,23 +1,19 @@ -import { Adapter, ProtocolType } from "../adapters/types"; +import { Adapter, ChainBlocks, FetchOptions, ProtocolType } from "../adapters/types"; import { CHAIN } from "../helpers/chains"; import { queryDune } from "../helpers/dune"; -import { getPrices } from "../utils/prices"; const adapter: Adapter = { adapter: { [CHAIN.FANTOM]: { - fetch: async (timestamp: number) => { + fetch: async (timestamp: number , _: ChainBlocks, { createBalances }: FetchOptions) => { // select sum(gas_price*(gas_used/1e18)) from fantom.transactions where block_time > from_unixtime({{endTime}}) - interval '1' day and block_time < from_unixtime({{endTime}}) const fees = (await queryDune("2849077", { endTime: timestamp }))[0]._col0 - const usdFees = fees * (await getPrices(["coingecko:fantom"], timestamp))["coingecko:fantom"].price; - - return { - timestamp, - dailyFees: usdFees.toString(), - dailyRevenue: (usdFees*0.3).toString(), - }; + const dailyFees = createBalances() + dailyFees.addGasToken(fees * 1e18) + const dailyRevenue = dailyFees.clone(0.3) + return { dailyFees, dailyRevenue, timestamp } }, start: 1575158400 }, diff --git a/fees/fvm-exchange.ts b/fees/fvm-exchange.ts index 1834c1a23a..c878c87c51 100644 --- a/fees/fvm-exchange.ts +++ b/fees/fvm-exchange.ts @@ -1,21 +1,5 @@ -import { FetchResultFees, SimpleAdapter } from "../adapters/types"; +import { ChainBlocks, FetchOptions, FetchResultFees, 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"; - -interface ILog { - data: string; - transactionHash: string; - topics: string[]; -} -interface IAmount { - amount0: number; - amount1: number; -} - -const topic0 = - "0xf5b850648f086f3f988a2c06dd4214f39db9fa92ee563e6246c398361d1963ad"; const FACTORY_ADDRESS = "0x472f3C3c9608fe0aE8d702f3f8A2d12c410C881A"; type TABI = { @@ -25,125 +9,20 @@ const ABIs: TABI = { "allPairsLength": "uint256:allPairsLength", "allPairs": "function allPairs(uint256) view returns (address)" } -process.env.FANTOM_BATCH_MAX_COUNT = "10"; // 10 is the default value - -const fetch = async (timestamp: number): Promise => { - const fromTimestamp = timestamp - 60 * 60 * 24; - const toTimestamp = timestamp; - const poolLength = ( - await sdk.api2.abi.call({ - target: FACTORY_ADDRESS, - chain: CHAIN.FANTOM, - abi: ABIs.allPairsLength, - }) - ); - - const poolsRes = await sdk.api2.abi.multiCall({ - abi: ABIs.allPairs, - calls: Array.from(Array(Number(poolLength)).keys()).map((i) => ({ - target: FACTORY_ADDRESS, - params: i, - })), - chain: CHAIN.FANTOM, - permitFailure: true, - }); - - const lpTokens = poolsRes - - const [underlyingToken0, underlyingToken1] = await Promise.all( - ["address:token0", "address:token1"].map((method) => - sdk.api2.abi.multiCall({ - abi: method, - calls: lpTokens, - chain: CHAIN.FANTOM, - permitFailure: true, - }) - ) - ); - - const tokens0 = underlyingToken0; - const tokens1 = underlyingToken1; - const fromBlock = await getBlock(fromTimestamp, CHAIN.FANTOM, {}); - const toBlock = await getBlock(toTimestamp, CHAIN.FANTOM, {}); - const logs: ILog[][] = ( - await Promise.all( - lpTokens.map((address: string) => - sdk.getEventLogs({ - target: address, - toBlock: toBlock, - fromBlock: fromBlock, - chain: CHAIN.FANTOM, - topics: [topic0], - skipCache: true, - }) - ) - ) - ) as any - - const rawCoins = [...tokens0, ...tokens1].map( - (e: string) => `${CHAIN.FANTOM}:${e}` - ); - const coins = [...new Set(rawCoins)]; - const prices = await getPrices(coins, timestamp); - const fees: number[] = lpTokens.map((_: string, index: number) => { - const token0Decimals = - prices[`${CHAIN.FANTOM}:${tokens0[index]}`]?.decimals || 0; - const token1Decimals = - prices[`${CHAIN.FANTOM}:${tokens1[index]}`]?.decimals || 0; - const log: IAmount[] = logs[index] - .map((e: ILog) => { - return { ...e, data: e.data.replace("0x", "") }; - }) - .map((p: ILog) => { - // event GaugeFees(address indexed token, uint amount, address externalBribe); - const [, token] = p.topics; - const isToken0 = - "0x" + token.substring(26).toLowerCase() === - tokens0[index].toLowerCase(); - const isToken1 = - "0x" + token.substring(26).toLowerCase() === - tokens1[index].toLowerCase(); - if (isToken0) { - return { - amount0: - Number("0x" + p.data.slice(0, 64)) / 10 ** token0Decimals, - amount1: 0, - }; - } - if (isToken1) { - return { - amount0: 0, - amount1: - Number("0x" + p.data.slice(0, 64)) / 10 ** token1Decimals, - }; - } - return { - amount0: 0, - amount1: 0, - } as IAmount; - }) as IAmount[]; - - const token0Price = - prices[`${CHAIN.FANTOM}:${tokens0[index]}`]?.price || 0; - const token1Price = - prices[`${CHAIN.FANTOM}:${tokens1[index]}`]?.price || 0; - const feesAmount0 = - log.reduce((a: number, b: IAmount) => Number(b.amount0) + a, 0) * - token0Price; - const feesAmount1 = - log.reduce((a: number, b: IAmount) => Number(b.amount1) + a, 0) * - token1Price; +const fetch = async (timestamp: number, _: ChainBlocks, { createBalances, getLogs, api }: FetchOptions): Promise => { + const dailyFees = createBalances() + const lpTokens = await api.fetchList({ lengthAbi: ABIs.allPairsLength, itemAbi: ABIs.allPairs, target: FACTORY_ADDRESS }); - const feesUSD = feesAmount0 + feesAmount1; - return feesUSD; - }); + (await getLogs({ + targets: lpTokens, + eventAbi: "event GaugeFees (address indexed token, uint256 amount, address externalBribe)", + })).map((e: any) => dailyFees.add(e.token, e.amount)) - const dailyFees = fees.reduce((a: number, b: number) => a + b, 0); return { - dailyFees: `${dailyFees}`, - dailyRevenue: `${dailyFees}`, - dailyHoldersRevenue: `${dailyFees}`, + dailyFees: dailyFees, + dailyRevenue: dailyFees, + dailyHoldersRevenue: dailyFees, timestamp, }; }; diff --git a/fees/gains-network.ts b/fees/gains-network.ts index c4eb0ac47a..40f057c386 100644 --- a/fees/gains-network.ts +++ b/fees/gains-network.ts @@ -1,93 +1,31 @@ -import { Adapter, FetchResultFees } from "../adapters/types"; +import { Adapter, ChainBlocks, FetchOptions, FetchResultFees } from "../adapters/types"; import { CHAIN } from "../helpers/chains"; -import * as sdk from "@defillama/sdk"; -import { getTimestampAtStartOfDayUTC, getTimestampAtStartOfNextDayUTC } from "../utils/date"; -import { getBlock } from "../helpers/getBlock"; -import BigNumber from "bignumber.js"; -import { getPrices } from "../utils/prices"; +import ADDRESSES from "../helpers/coreAssets.json"; import { Chain } from "@defillama/sdk/build/general"; -interface IEvent { - name: string; - topic: string; -} - type IAddresses = { [s: string | Chain]: string[]; }; -type CollateralConfig = { - precision: BigNumber; - slug: string; -}; - -interface ITx { - address: string; - data: string; -} - -const event: IEvent[] = [ - { - name: "DevGovFeeCharged(address indexed trader, uint valueDai)", - topic: "0x4628f3d38f72d5f9e077d3965e10cd3242ff1316aa2bf81f054c0dfb25408406", - }, - { - name: "SssFeeCharged(address indexed trader, uint valueDai)", - topic: "0xd1e388cc27c5125a80cf538c12b26dc5a784071d324a81a736e4d17f238588e4", - }, - { - name: "ReferralFeeCharged(address indexed trader, uint valueDai)", - topic: "0x0f5273269f52308b9c40fafda3ca13cc42f715fcd795365e87f351f59e249313", - }, - { - name: "NftBotFeeCharged(address indexed trader, uint valueDai)", - topic: "0xcada75418f444febbe725c87360b063440c54e00e82d578010de1ed009d756c5", - }, - { - name: "DaiVaultFeeCharged(address indexed trader, uint valueDai)", - topic: "0x60c73da98faf96842eabd77a0c73964cd189dbaf2c9ae90923a3fed137f30e3e", - }, - { - name: "LpFeeCharged(address indexed trader, uint valueDai)", - topic: "0xf3dd1b8102b506743ce65a97636e91051e861f4f8f7e3eb87f2d95d0a616cea2", - }, - { - name: "TriggerFeeCharged(address indexed trader, uint valueDai)", - topic: "0x17fa86cf4833d28c6224a940e6bd001f2db0cb3d89d69727765679b3efee6559", - }, - { - name: "GovFeeCharged(address indexed trader, uint valueDai, bool distributed)", - topic: "0xccd80d359a6fbe0bfa5cbb1ecf0854adbe8c67b4ed6bf10d3c0d78c2be0f48cb", - }, - { - name: "BorrowingFeeCharged(address indexed trader, uint tradeValueDai, uint feeValueDai)", - topic: "0xe7d34775bf6fd7b34e703a903ef79ab16166ebdffce96a66f4d2f84b6263bb29", - }, +const event: string[] = [ + "event DevGovFeeCharged(address indexed trader, uint valueDai)", + "event SssFeeCharged(address indexed trader, uint valueDai)", + "event ReferralFeeCharged(address indexed trader, uint valueDai)", + "event NftBotFeeCharged(address indexed trader, uint valueDai)", + "event DaiVaultFeeCharged(address indexed trader, uint valueDai)", + "event LpFeeCharged(address indexed trader, uint valueDai)", + "event TriggerFeeCharged(address indexed trader, uint valueDai)", + "event GovFeeCharged(address indexed trader, uint valueDai, bool distributed)", + "event BorrowingFeeCharged(address indexed trader, uint tradeValueDai, uint valueDai)", ]; -const ONE_E_18 = new BigNumber("10").pow(18); -const ONE_E_6 = new BigNumber("10").pow(6); - -const USDC_CONFIG: CollateralConfig = { - precision: ONE_E_6, - slug: "coingecko:usdc", -}; -const ETH_CONFIG: CollateralConfig = { - precision: ONE_E_18, - slug: "coingecko:eth", -}; -const DAI_CONFIG: CollateralConfig = { - precision: ONE_E_18, - slug: "coingecko:dai", -}; - -const addressConfig: { [a: string]: CollateralConfig } = { - "0x82e59334da8c667797009bbe82473b55c7a6b311": DAI_CONFIG, - "0x0bbed2eac3237ba128643670b7cf3be475933755": ETH_CONFIG, - "0x2ac6749d0affd42c8d61ef25e433f92e375a1aef": USDC_CONFIG, - "0x298a695906e16aea0a184a2815a76ead1a0b7522": DAI_CONFIG, - "0x62a9f50c92a57c719ff741133caa55c7a81ce019": ETH_CONFIG, - "0x4542256c583bcad66a19a525b57203773a6485bf": USDC_CONFIG, +const addressConfig: { [a: string]: string } = { + "0x82e59334da8c667797009bbe82473b55c7a6b311": ADDRESSES.polygon.DAI, + "0x0bbed2eac3237ba128643670b7cf3be475933755": ADDRESSES.polygon.WETH, + "0x2ac6749d0affd42c8d61ef25e433f92e375a1aef": ADDRESSES.polygon.USDC_CIRCLE, + "0x298a695906e16aea0a184a2815a76ead1a0b7522": ADDRESSES.arbitrum.DAI, + "0x62a9f50c92a57c719ff741133caa55c7a81ce019": ADDRESSES.arbitrum.WETH, + "0x4542256c583bcad66a19a525b57203773a6485bf": ADDRESSES.arbitrum.USDC_CIRCLE, }; const contract_addresses: IAddresses = { @@ -104,75 +42,23 @@ const contract_addresses: IAddresses = { }; const fetch = (chain: Chain) => { - return async (timestamp: number): Promise => { - const fromTimestamp = getTimestampAtStartOfDayUTC(timestamp); - const toTimestamp = getTimestampAtStartOfNextDayUTC(timestamp); - - const fromBlock = await getBlock(fromTimestamp, chain, {}); - const toBlock = await getBlock(toTimestamp, chain, {}); - const [ - devFeeCall, - ssFeeCall, - referralFeeCall, - nftBotFeeCall, - daiVaultCall, - lpFeeCall, - triggerFeeCall, - govFeeCall, - borrowingFeeCall, - ]: any = await Promise.all( - event.map((e: IEvent) => - sdk.getEventLogs({ - targets: contract_addresses[chain], - topic: e.name, - toBlock: toBlock, - fromBlock: fromBlock, - chain: chain, - topics: [e.topic], - }) - ) - ); - - const prices = await getPrices(["coingecko:dai", "coingecko:eth", "coingecko:usdc"], fromTimestamp); - - const reducer = (a: BigNumber, c: BigNumber) => a.plus(c); - const convertToUsd = (data: string, config: CollateralConfig) => - new BigNumber(data).div(config.precision || ONE_E_18).times(prices[config.slug]?.price || 1); - const reduceToBn = (e: ITx[]) => e.map((p: ITx) => convertToUsd(p.data, addressConfig[p.address])).reduce(reducer, new BigNumber("0")); - - const devFeeValume = reduceToBn(devFeeCall); - const ssFeeVol = reduceToBn(ssFeeCall); - const referralFeeVol = reduceToBn(referralFeeCall); - const nftBotFeeVol = reduceToBn(nftBotFeeCall); - const daiVaultVol = reduceToBn(daiVaultCall); - const lpFeeVol = reduceToBn(lpFeeCall); - const triggerFeeVol = reduceToBn(triggerFeeCall); - const govFeeVol = govFeeCall - .map((p: ITx) => convertToUsd(p.data.slice(0, 66), addressConfig[p.address])) - .reduce(reducer, new BigNumber("0")); - const borrowingFeeVol = borrowingFeeCall - .map((p: ITx) => convertToUsd("0x" + p.data.slice(66, 130), addressConfig[p.address])) - .reduce(reducer, new BigNumber("0")); - - const dailyHoldersRevenue = ssFeeVol.toString(); - const dailyRevenue = devFeeValume.plus(ssFeeVol).plus(govFeeVol).toString(); - const dailyFees = devFeeValume - .plus(ssFeeVol) - .plus(govFeeVol) - .plus(referralFeeVol) - .plus(nftBotFeeVol) - .plus(daiVaultVol) - .plus(lpFeeVol) - .plus(triggerFeeVol) - .plus(borrowingFeeVol) - .toString(); - - return { - timestamp, - dailyFees, - dailyRevenue, - dailyHoldersRevenue, - } as FetchResultFees; + return async (timestamp: number, _: ChainBlocks, { createBalances, getLogs, }: FetchOptions): Promise => { + const dailyFees = createBalances() + const dailyRevenue = createBalances() + const dailyHoldersRevenue = createBalances() + + for (const target of contract_addresses[chain]) { + const token = addressConfig[target] + const [ + devFee, ssFee, referralFee, nftBotFee, daiVault, lpFee, triggerFee, govFee, borrowingFee, + ]: any = await Promise.all(event.map((eventAbi) => getLogs({ target, eventAbi }))); + + [devFee, ssFee, referralFee, nftBotFee, daiVault, lpFee, triggerFee, govFee, borrowingFee,].flat().forEach((i: any) => dailyFees.add(token, i.valueDai)); + [devFee, ssFee, govFee,].flat().forEach((i: any) => dailyRevenue.add(token, i.valueDai)); + ssFee.forEach((i: any) => dailyHoldersRevenue.add(token, i.valueDai)); + } + + return { timestamp, dailyFees, dailyRevenue, dailyHoldersRevenue, } }; }; diff --git a/fees/gambit.ts b/fees/gambit.ts index 94526eccf7..7e0add6d19 100644 --- a/fees/gambit.ts +++ b/fees/gambit.ts @@ -1,93 +1,31 @@ -import { Adapter, FetchResultFees } from "../adapters/types"; +import { Adapter, ChainBlocks, FetchOptions, FetchResultFees } from "../adapters/types"; import { CHAIN } from "../helpers/chains"; -import * as sdk from "@defillama/sdk"; -import { getTimestampAtStartOfDayUTC, getTimestampAtStartOfNextDayUTC } from "../utils/date"; -import { getBlock } from "../helpers/getBlock"; -import BigNumber from "bignumber.js"; -import { getPrices } from "../utils/prices"; -import { Chain } from "@defillama/sdk/build/general"; +import ADDRESSES from "../helpers/coreAssets.json"; - -interface IEvent { - name: string; - topic: string; -} -const event: IEvent[] = [ - { - name: 'DevGovFeeCharged(address indexed trader, uint valueUsdc)', - topic: '0x4628f3d38f72d5f9e077d3965e10cd3242ff1316aa2bf81f054c0dfb25408406' - }, - { - name: 'SssFeeCharged(address indexed trader, uint valueUsdc)', - topic: '0xd1e388cc27c5125a80cf538c12b26dc5a784071d324a81a736e4d17f238588e4' - }, - { - name: 'ReferralFeeCharged(address indexed trader, uint valueUsdc)', - topic: '0x0f5273269f52308b9c40fafda3ca13cc42f715fcd795365e87f351f59e249313' - }, - { - name: 'UsdcVaultFeeCharged(address indexed trader, uint valueUsdc)', - topic: '0x8e8e632c3a076f70e7ef29ecf97a7363c57c48b744e1bafe2f8099ec5677c208' - } +const events = [ + 'event DevGovFeeCharged(address indexed trader, uint valueUsdc)', + 'event SssFeeCharged(address indexed trader, uint valueUsdc)', + 'event ReferralFeeCharged(address indexed trader, uint valueUsdc)', + 'event UsdcVaultFeeCharged(address indexed trader, uint valueUsdc)', ]; -interface ITx { - data: string; -} - const FEE_ADDRESS = { [CHAIN.ERA]: ["0xE95a6FCC476Dc306749c2Ac62fB4637c27ac578d", "0x6cf71FaeA3771D56e72c72501e7172e79116E2A3", "0x50853A14cD14CC6A891BF034A204A15d294AF056", "0x240d75373f9941b8F7FbA660b9ae73dfa655f7Da"], [CHAIN.ARBITRUM]: ["0x8d85f4615ea5F2Ea8D91C196aaD4C04D8416865C", "0xB88C3A703B3565cb7bfdB1806Ba3728C54dd4b91"], }; -const BIG_TEN = new BigNumber('10'); - -const USDC_DECIMAL = 6 +const fetch = (addressList: string[]) => { + return async (timestamp: number, _: ChainBlocks, { createBalances, getLogs, chain, }: FetchOptions): Promise => { + const USDC = (ADDRESSES as any)[chain].USDC; -const fetch = (addressList: string[], chain: Chain) => { - return async (timestamp: number): Promise => { - const todaysTimestamp = getTimestampAtStartOfDayUTC(timestamp) - const yesterdaysTimestamp = getTimestampAtStartOfNextDayUTC(timestamp) - - const todaysBlock = (await getBlock(todaysTimestamp, chain, {})); - const yesterdaysBlock = (await getBlock(yesterdaysTimestamp, chain, {})); - - const [devFeeCall, sssFeeCall, referralFeeCall, usdcVaultFeeCall]: any = (await Promise.all( - event.map(async (e: IEvent) => { - return Promise.all( - addressList.map(async (address) => { - return sdk.getEventLogs({ - target: address, - topic: e.name, - toBlock: yesterdaysBlock, - fromBlock: todaysBlock, - chain: chain, - topics: [e.topic], - }); - }) - ); - }) + const [devFeeVol, ssFeeVol, referralFeeVol, usdcVaultFeeVol]: any = (await Promise.all( + events.map(async (e: string) => (await getLogs({ targets: addressList, eventAbi: e })).reduce((acc, i) => acc + Number(i.valueUsdc), 0)) )); + const dailyFees = createBalances() + const dailyRevenue = createBalances() + dailyRevenue.add(USDC, devFeeVol + ssFeeVol) + dailyFees.add(USDC, devFeeVol + ssFeeVol + referralFeeVol + usdcVaultFeeVol) - let devFeeOutput: any[] = [] - let sssFeeOutput: any[] = [] - let referralFeeOutput: any[] = [] - let usdcVaultFeeOutput: any[] = [] - for (let i = 0; i < devFeeCall.length; i++) { - devFeeOutput = devFeeOutput.concat(devFeeCall[i]); - sssFeeOutput = sssFeeOutput.concat(sssFeeCall[i]); - referralFeeOutput = referralFeeOutput.concat(referralFeeCall[i]); - usdcVaultFeeOutput = usdcVaultFeeOutput.concat(usdcVaultFeeCall[i]); - } - - const devFeeVol = devFeeOutput.map((p: ITx) => new BigNumber(p.data)).reduce((a: BigNumber, c: BigNumber) => a.plus(c), new BigNumber('0')); - const ssFeeVol = sssFeeOutput.map((p: ITx) => new BigNumber(p.data)).reduce((a: BigNumber, c: BigNumber) => a.plus(c), new BigNumber('0')); - const referralFeeVol = referralFeeOutput.map((p: ITx) => new BigNumber(p.data)).reduce((a: BigNumber, c: BigNumber) => a.plus(c), new BigNumber('0')); - const usdcVaultFeeVol = usdcVaultFeeOutput.map((p: ITx) => new BigNumber(p.data)).reduce((a: BigNumber, c: BigNumber) => a.plus(c), new BigNumber('0')); - const prices = await getPrices(['coingecko:usdc'], todaysTimestamp); - const usdcPrice = prices['coingecko:usdc']?.price || 1; - const dailyRevenue = devFeeVol.plus(ssFeeVol).times(usdcPrice).div(BIG_TEN.pow(USDC_DECIMAL)).toString(); - const dailyFees = devFeeVol.plus(ssFeeVol).plus(referralFeeVol).plus(usdcVaultFeeVol).times(usdcPrice).div(BIG_TEN.pow(USDC_DECIMAL)).toString(); return { timestamp, dailyFees, @@ -100,11 +38,11 @@ const fetch = (addressList: string[], chain: Chain) => { const adapter: Adapter = { adapter: { [CHAIN.ERA]: { - fetch: fetch(FEE_ADDRESS[CHAIN.ERA], CHAIN.ERA), + fetch: fetch(FEE_ADDRESS[CHAIN.ERA]), start: 1690848000, // 2023/08/01 00:00:00 }, [CHAIN.ARBITRUM]: { - fetch: fetch(FEE_ADDRESS[CHAIN.ARBITRUM], CHAIN.ARBITRUM), + fetch: fetch(FEE_ADDRESS[CHAIN.ARBITRUM]), start: 1698883200, // 2023/11/02 00:00:00 }, }, diff --git a/fees/get-protocol.ts b/fees/get-protocol.ts index c86a09b58e..793fd1cdd2 100644 --- a/fees/get-protocol.ts +++ b/fees/get-protocol.ts @@ -1,22 +1,20 @@ -import { Adapter } from "../adapters/types"; +import { Adapter, ChainBlocks, FetchOptions } from "../adapters/types"; import { POLYGON } from "../helpers/chains"; import { request, gql } from "graphql-request"; -import { getTimestampAtStartOfDayUTC } from "../utils/date"; -import { getPrices } from "../utils/prices"; const PROTOCOL_SUBGRAPH = "https://api.thegraph.com/subgraphs/name/getprotocol/get-protocol-subgraph"; const TOKEN_SUBGRAPH_POLYGON = "https://api.thegraph.com/subgraphs/name/getprotocol/get-token-polygon"; const TOKEN_SUBGRAPH_ETHEREUM = "https://api.thegraph.com/subgraphs/name/getprotocol/get-token-ethereum"; -const PRICE_ID = "coingecko:get-token"; +const PRICE_ID = "get-token"; const sumKeys = (keys: string[], obj: any) => keys.reduce((tally: number, key: string) => tally + (obj[key] || 0), 0); const graphs = () => { - return async (timestamp: number) => { - const beginningOfDay = getTimestampAtStartOfDayUTC(timestamp); + return async (timestamp: number, _: ChainBlocks, { createBalances, startOfDay, }: FetchOptions) => { + const beginningOfDay = startOfDay; const dateId = Math.floor(beginningOfDay / 86400); - const revenueQuery = gql` + const revenueQuery = ` { protocolDay(id: ${dateId}) { reservedFuel @@ -39,33 +37,40 @@ const graphs = () => { const graphRevenue = await request(PROTOCOL_SUBGRAPH, revenueQuery); const graphPolyFees = await request(TOKEN_SUBGRAPH_POLYGON, feesQuery); const graphEthFees = await request(TOKEN_SUBGRAPH_ETHEREUM, feesQuery); - const getUSD = (await getPrices([PRICE_ID], beginningOfDay))[PRICE_ID].price; - const integratorFees = parseFloat(graphRevenue.protocolDay.reservedFuel) * getUSD; - const dailyHoldersRevenue = parseFloat(graphRevenue.protocolDay.holdersRevenue) * getUSD; - const dailyProtocolRevenue = parseFloat(graphRevenue.protocolDay.treasuryRevenue) * getUSD; - const dailyRevenue = dailyProtocolRevenue + dailyHoldersRevenue; + const dailyFees = createBalances() + const dailyUserFees = createBalances() + const dailyRevenue = createBalances() + const dailyHoldersRevenue = createBalances() + const dailyProtocolRevenue = createBalances() + dailyFees.addCGToken(PRICE_ID, +graphRevenue.protocolDay.reservedFuel); + dailyUserFees.addCGToken(PRICE_ID, +graphRevenue.protocolDay.reservedFuel); + dailyHoldersRevenue.addCGToken(PRICE_ID, +graphRevenue.protocolDay.holdersRevenue); + dailyProtocolRevenue.addCGToken(PRICE_ID, +graphRevenue.protocolDay.treasuryRevenue); + dailyRevenue.addBalances(dailyHoldersRevenue) + dailyRevenue.addBalances(dailyProtocolRevenue) + // Transform staking rewards from both Polygon and Ethereum networks into an object indexed by the reward type. // The value of the each type will be the USD amount of GET rewarded using the price at that point in time. const stakingFees = graphEthFees.stakingRewards.concat(graphPolyFees.stakingRewards).reduce( (tally: any, reward: any) => ({ - [reward.type]: ((tally[reward.type] || 0) + Number(BigInt(reward.totalRewards) / BigInt(10e18))) * getUSD, + [reward.type]: ((tally[reward.type] || 0) + Number(BigInt(reward.totalRewards) / BigInt(10e18))), }), {} ); // dailyFees includes the Uniswap LP collected fees, the dailyUserFees does not. - const dailyFees = integratorFees + sumKeys(["WITHDRAWAL_FEE", "REDISTRIBUTE", "UNISWAP_LP_FEE"], stakingFees); - const dailyUserFees = integratorFees + sumKeys(["WITHDRAWAL_FEE", "REDISTRIBUTE"], stakingFees); + dailyFees.addCGToken('tether', +sumKeys(["WITHDRAWAL_FEE", "REDISTRIBUTE"], stakingFees)); + dailyUserFees.addCGToken('tether', +sumKeys(["WITHDRAWAL_FEE", "REDISTRIBUTE"], stakingFees)); return { timestamp, - dailyFees: dailyFees.toString(), - dailyUserFees: dailyUserFees.toString(), - dailyRevenue: dailyRevenue.toString(), - dailyHoldersRevenue: dailyHoldersRevenue.toString(), - dailyProtocolRevenue: dailyProtocolRevenue.toString(), + dailyFees: dailyFees, + dailyUserFees: dailyUserFees, + dailyRevenue: dailyRevenue, + dailyHoldersRevenue: dailyHoldersRevenue, + dailyProtocolRevenue: dailyProtocolRevenue, }; }; }; diff --git a/fees/joe-v2.1.ts b/fees/joe-v2.1.ts index 22a32ef3e2..05cfcfc595 100644 --- a/fees/joe-v2.1.ts +++ b/fees/joe-v2.1.ts @@ -1,28 +1,9 @@ -import { FetchResultFees, SimpleAdapter } from "../adapters/types"; +import { ChainBlocks, FetchOptions, FetchResultFees, 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 { - protocolFeesX: number; - protocolFeesY: number; - totalFeesX: number; - totalFeesY: 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 contract_interface = new ethers.Interface([ - event_swap -]); type TPool = { [c: string]: string[]; @@ -69,83 +50,55 @@ const pools: TPool = { } const graph = (chain: Chain) => { - return async (timestamp: number): Promise => { - const fromTimestamp = timestamp - 60 * 60 * 24 - const toTimestamp = timestamp + return async (timestamp: number , _: ChainBlocks, { createBalances, getLogs, api }: FetchOptions): Promise => { + const dailyFees = createBalances(); + const dailyRevenue = createBalances(); const lpTokens = pools[chain] - const [underlyingToken0, underlyingToken1] = await Promise.all( + const [tokenXs, tokenYs] = await Promise.all( ['address:getTokenX', 'address:getTokenY'].map((method: string) => - sdk.api2.abi.multiCall({ + api.multiCall({ abi: method, - calls: lpTokens.map((address: string) => ({ - target: address, - })), - chain: chain + calls: lpTokens, }) ) ); + const decimalsXs = await api.multiCall({ abi: 'erc20:decimals', calls: tokenXs}) + const decimalsYs = await api.multiCall({ abi: 'erc20:decimals', calls: tokenYs}) - 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 logs: any[][] = await getLogs({ + targets: lpTokens, + eventAbi: event_swap, + flatten: false, + }) - const rawCoins = [...tokens0, ...tokens1].map((e: string) => `${chain}:${e}`); - const coins = [...new Set(rawCoins)] - const prices = await getPrices(coins, timestamp); - - - const untrackVolumes: any[] = 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 protocolFeesX = Number('0x' + '0'.repeat(32) + value!.args.protocolFees.replace('0x', '').slice(0, 32)) / 10 ** token1Decimals - const protocolFeesY = Number('0x' + '0'.repeat(32) + value!.args.protocolFees.replace('0x', '').slice(32, 64)) / 10 ** token0Decimals - const totalFeesX = Number('0x' + '0'.repeat(32) + value!.args.totalFees.replace('0x', '').slice(0, 32)) / 10 ** token1Decimals; - const totalFeesY = Number('0x' + '0'.repeat(32) + value!.args.totalFees.replace('0x', '').slice(32, 64)) / 10 ** token0Decimals; - return { - protocolFeesX, - protocolFeesY, - totalFeesX, - totalFeesY, - // tx: p.transactionHash, // for debugging - // token0Decimals, - // token1Decimals - } as IAmount + lpTokens.map((_: string, index: number) => { + logs[index] + .map((p: any) => { + const token0 = tokenXs[index]; + const token1 = tokenYs[index]; + const decimalsX = decimalsXs[index]; + const decimalsY = decimalsYs[index]; + const protocolFeesY = Number('0x' + p.protocolFees.replace('0x', '').slice(0, 32)) + const protocolFeesX = Number('0x' + p.protocolFees.replace('0x', '').slice(32, 64)) + const totalFeesY = Number('0x' + p.totalFees.replace('0x', '').slice(0, 32)); + const totalFeesX = Number('0x' + p.totalFees.replace('0x', '').slice(32, 64)); + dailyFees.add(token0, totalFeesX / 10 ** (18 - decimalsX)) + dailyFees.add(token1, totalFeesY / 10 ** (18 - decimalsY)) + dailyRevenue.add(token0, protocolFeesX / 10 ** (18 - decimalsX)) + dailyRevenue.add(token1, protocolFeesY / 10 ** (18 - decimalsY)) }); - - const token0Price = (prices[`${chain}:${tokens0[index]}`]?.price || 0); - const token1Price = (prices[`${chain}:${tokens1[index]}`]?.price || 0); - const totalFeesX = log - .reduce((a: number, b: IAmount) => Number(b.totalFeesX) + a, 0) * token1Price; - const totalFeesY = log - .reduce((a: number, b: IAmount) => Number(b.totalFeesY) + a, 0) * token0Price; - const totalProtocolFeesX = log.reduce((a: number, b: IAmount) => Number(b.protocolFeesX) + a, 0) * token1Price; - const totalProtocolFeesY = log.reduce((a: number, b: IAmount) => Number(b.protocolFeesY) + a, 0) * token0Price; - return { - fees: (totalFeesX + totalFeesY), - rev: (totalProtocolFeesX + totalProtocolFeesY), - }; }); - const dailyFees = untrackVolumes.reduce((a: number, b: any) => a + b.fees, 0); - const dailyRevenue = untrackVolumes.reduce((a: number, b: any) => a + b.rev, 0); + const dailySupplySideRevenue = dailyFees.clone(); + dailySupplySideRevenue.subtract(dailyRevenue); return { - dailyFees: `${dailyFees}`, - dailyRevenue: `${dailyRevenue}`, - dailyHoldersRevenue: `${dailyRevenue}`, - dailySupplySideRevenue: dailyFees ? `${(dailyFees || 0) - (dailyRevenue || 0)}` : undefined, + dailyFees: dailyFees, + dailyUserFees: dailyFees, + dailyRevenue: dailyRevenue, + dailyProtocolRevenue: dailyRevenue, + dailyHoldersRevenue: dailyRevenue, + dailySupplySideRevenue, timestamp, }; } diff --git a/fees/liquity.ts b/fees/liquity.ts index 5c87a27b1a..9a800950e9 100644 --- a/fees/liquity.ts +++ b/fees/liquity.ts @@ -1,9 +1,5 @@ -import ADDRESSES from '../helpers/coreAssets.json' -import { Adapter, ChainBlocks, ProtocolType } from "../adapters/types"; +import { Adapter, ChainBlocks, FetchOptions, } from "../adapters/types"; import { CHAIN } from "../helpers/chains"; -import { getBlock } from "../helpers/getBlock"; -import { getTimestampAtStartOfDayUTC, getTimestampAtStartOfNextDayUTC } from "../utils/date"; -import { getPrices } from "../utils/prices"; const { request, gql } = require("graphql-request"); @@ -20,12 +16,8 @@ interface IDailyResponse { const adapter: Adapter = { adapter: { [CHAIN.ETHEREUM]: { - fetch: async (timestamp: number, _: ChainBlocks) => { - const todaysTimestamp = getTimestampAtStartOfDayUTC(timestamp) - const yesterdaysTimestamp = getTimestampAtStartOfNextDayUTC(timestamp) - - const startOfDayBlock = (await getBlock(todaysTimestamp, "ethereum", {})); - const endOfDayBlock = (await getBlock(yesterdaysTimestamp, "ethereum", {})); + fetch: async (timestamp: number, _: ChainBlocks, { createBalances, getFromBlock, getToBlock, }: FetchOptions) => { + const dailyFees = createBalances() const graphQueryDaily = gql `query fees($startOfDayBlock: Int!, $endOfDayBlock: Int!) { @@ -40,21 +32,18 @@ const adapter: Adapter = { }`; - const graphResDaily: IDailyResponse = await request(URL, graphQueryDaily, {startOfDayBlock, endOfDayBlock}); + const graphResDaily: IDailyResponse = await request(URL, graphQueryDaily, {startOfDayBlock: await getFromBlock(), endOfDayBlock: await getToBlock()}); const borrowingFees = Number(graphResDaily.today.totalBorrowingFeesPaid) - Number(graphResDaily.yesterday.totalBorrowingFeesPaid); const redemptionFeesETH = Number(graphResDaily.today.totalRedemptionFeesPaid) - Number(graphResDaily.yesterday.totalRedemptionFeesPaid); - const ethAddress = "ethereum:" + ADDRESSES.null; - const pricesObj: any = await getPrices([ethAddress], todaysTimestamp); - const latestPrice = pricesObj[ethAddress]["price"] - const redemptionFeesUSD = redemptionFeesETH * latestPrice; - const dailyFee = borrowingFees + redemptionFeesUSD; + dailyFees.addCGToken('tether', borrowingFees); + dailyFees.addGasToken(redemptionFeesETH * 10 ** 18); return { timestamp, - dailyFees: dailyFee.toString(), - dailyRevenue: dailyFee.toString(), - dailyHoldersRevenue: dailyFee.toString(), + dailyFees: dailyFees, + dailyRevenue: dailyFees, + dailyHoldersRevenue: dailyFees, }; }, start: 1575158400 diff --git a/fees/llamalend.ts b/fees/llamalend.ts index 8717999241..ca3a5d7003 100644 --- a/fees/llamalend.ts +++ b/fees/llamalend.ts @@ -1,11 +1,8 @@ -import ADDRESSES from '../helpers/coreAssets.json' import { Adapter } from "../adapters/types"; import { CHAIN } from "../helpers/chains"; -import { request, gql } from "graphql-request"; -import type { ChainEndpoints } from "../adapters/types" +import { request, } from "graphql-request"; +import type { ChainBlocks, ChainEndpoints, FetchOptions } from "../adapters/types" import { Chain } from '@defillama/sdk/build/general'; -import { getBlock } from "../helpers/getBlock"; -import { getPrices } from "../utils/prices"; const endpoints = { [CHAIN.ETHEREUM]: "https://api.thegraph.com/subgraphs/name/0xngmi/llamalend", @@ -18,12 +15,11 @@ interface IGraph { } const graphs = (graphUrls: ChainEndpoints) => { return (chain: Chain) => { - return async (timestamp: number) => { - const todaysBlock = (await getBlock(timestamp, chain, {})); - const graphQuery = gql - ` + return async (timestamp: number , _: ChainBlocks, { createBalances, getToBlock }: FetchOptions) => { + const dailyFees = createBalances(); + const graphQuery = ` { - loans(where:{owner_not: ADDRESSES.null}, block:{ number: ${todaysBlock}}) { + loans(where:{owner_not: ADDRESSES.null}, block:{ number: ${await getToBlock()}}) { interest borrowed } @@ -31,19 +27,13 @@ const graphs = (graphUrls: ChainEndpoints) => { `; const graphRes: IGraph[] = (await request(graphUrls[chain], graphQuery)).loans; - const ethAddress = "ethereum:" + ADDRESSES.null; - const ethPrice = (await getPrices([ethAddress], timestamp))[ethAddress].price; - const dailyFeePerSec = graphRes.reduce((a: number, b: IGraph) => a + (Number(b.interest) * Number(b.borrowed)), 0) - const dailyFee = dailyFeePerSec / 1e36 * ONE_DAY_IN_SECONDS * ethPrice; + graphRes.map((b: IGraph) => dailyFees.addGasToken((Number(b.interest) * Number(b.borrowed) * ONE_DAY_IN_SECONDS / 1e18))) return { timestamp: timestamp, - dailyFees: dailyFee.toString(), - dailyUserFees: dailyFee.toString(), - dailySupplySideRevenue: dailyFee.toString(), - dailyRevenue: "0", - dailyHoldersRevenue: "0", - dailyProtocolRevenue: "0" + dailyFees: dailyFees, + dailyUserFees: dailyFees, + dailySupplySideRevenue: dailyFees, }; }; }; diff --git a/fees/looksrare.ts b/fees/looksrare.ts index ba1f3614d5..5bef9d3628 100644 --- a/fees/looksrare.ts +++ b/fees/looksrare.ts @@ -1,61 +1,40 @@ -import ADDRESSES from '../helpers/coreAssets.json' -import { Adapter } from "../adapters/types"; +import { Adapter, ChainBlocks, FetchOptions } from "../adapters/types"; import { ETHEREUM } from "../helpers/chains"; import { Chain } from '@defillama/sdk/build/general'; -import { getTimestampAtStartOfDayUTC, getTimestampAtStartOfNextDayUTC } from "../utils/date"; -import { getPrices } from "../utils/prices"; -import * as sdk from "@defillama/sdk"; -import { getBlock } from "../helpers/getBlock"; -const address = "0x0000000000e655fae4d56241588680f86e3b2377"; +const address = "0x0000000000e655fae4d56241588680f86e3b2377"; const topic0_taker_bid = "0x3ee3de4684413690dee6fff1a0a4f92916a1b97d1c5a83cdf24671844306b2e3"; const topic0_taker_ask = "0x9aaa45d6db2ef74ead0751ea9113263d1dec1b50cea05f0ca2002cb8063564a4"; - -interface ITx { - data: string; - transactionHash: string; - topics: string[]; +const eventAbis = { + "TakerAsk": "event TakerAsk((bytes32 orderHash, uint256 orderNonce, bool isNonceInvalidated) nonceInvalidationParameters, address askUser, address bidUser, uint256 strategyId, address currency, address collection, uint256[] itemIds, uint256[] amounts, address[2] feeRecipients, uint256[3] feeAmounts)", + "TakerBid": "event TakerBid((bytes32 orderHash, uint256 orderNonce, bool isNonceInvalidated) nonceInvalidationParameters, address bidUser, address bidRecipient, uint256 strategyId, address currency, address collection, uint256[] itemIds, uint256[] amounts, address[2] feeRecipients, uint256[3] feeAmounts)", } -const graphs = (chain: Chain) => { - return async (timestamp: number) => { - const todaysTimestamp = getTimestampAtStartOfDayUTC(timestamp) - const yesterdaysTimestamp = getTimestampAtStartOfNextDayUTC(timestamp) - - const fromBlock = (await getBlock(todaysTimestamp, chain, {})); - const toBlock = (await getBlock(yesterdaysTimestamp, chain, {})); +const graphs = (_chain: Chain) => { + return async (timestamp: number, _: ChainBlocks, { createBalances, getLogs, }: FetchOptions) => { - const logs_bid: ITx[] = (await sdk.getEventLogs({ + const logs_bid = await getLogs({ target: address, - fromBlock: fromBlock, - toBlock: toBlock, topics: [topic0_taker_bid], - chain: chain - })).map((e: any) => { return { data: e.data.replace('0x', ''), transactionHash: e.transactionHash, topics: e.topics } as ITx}) + eventAbi:eventAbis.TakerBid + }) - const logs_ask: ITx[] = (await sdk.getEventLogs({ + const logs_ask = await getLogs({ target: address, - fromBlock: fromBlock, - toBlock: toBlock, topics: [topic0_taker_ask], - chain: chain - })).map((e: any) => { return { data: e.data.replace('0x', ''), transactionHash: e.transactionHash, topics: e.topics } as ITx}) + eventAbi:eventAbis.TakerAsk, + }) const logs = logs_bid.concat(logs_ask) - - const rawLogsData: number[] = logs.map((tx: ITx) => { - const amount = Number('0x' + tx.data.slice(896, 960)) / 10 ** 18; - return amount; + const dailyFees = createBalances() + logs.map((tx: any) => { + dailyFees.add(tx.currency, tx.feeAmounts[2]) }); - const ethAddress = "ethereum:" + ADDRESSES.null; - const ethPrice = (await getPrices([ethAddress], timestamp))[ethAddress].price; - const dailyFee = rawLogsData.reduce((a: number, b: number) => a+b, 0); - const dailyFeeUSD = dailyFee * ethPrice; return { timestamp, - dailyFees: dailyFeeUSD.toString(), - dailyRevenue: dailyFeeUSD.toString(), - dailyHoldersRevenue: dailyFeeUSD.toString(), + dailyFees: dailyFees, + dailyRevenue: dailyFees, + dailyHoldersRevenue: dailyFees, }; }; }; @@ -64,8 +43,8 @@ const graphs = (chain: Chain) => { const adapter: Adapter = { adapter: { [ETHEREUM]: { - fetch: graphs(ETHEREUM), - start: 1640775864, + fetch: graphs(ETHEREUM), + start: 1640775864, }, } } diff --git a/fees/metamask.ts b/fees/metamask.ts index 4904e819b1..5b5f02805f 100644 --- a/fees/metamask.ts +++ b/fees/metamask.ts @@ -1,16 +1,8 @@ import { Chain } from "@defillama/sdk/build/general" import { CHAIN } from "../helpers/chains"; -import { Adapter, FetchResultFees } from "../adapters/types"; +import { Adapter, ChainBlocks, FetchOptions, FetchResultFees } from "../adapters/types"; import { queryFlipside } from "../helpers/flipsidecrypto"; -import { getBlock } from "../helpers/getBlock"; -import { getPrices } from "../utils/prices"; -type TPrice = { - [s: string]: { - price: number; - decimals: number - }; -} interface IVolume { amount: number; tokenAddress: string; @@ -38,12 +30,8 @@ const blackList: TKeyArray = { } const graph = (chain: Chain) => { - return async (timestamp: number): Promise => { + return async (timestamp: number , _: ChainBlocks, { createBalances, getFromBlock, getToBlock, }: FetchOptions): Promise => { - const fromTimestamp = timestamp - 60 * 60 * 24 - const toTimestamp = timestamp - const startblock = (await getBlock(fromTimestamp, chain, {})); - const endblock = (await getBlock(toTimestamp, chain, {})); const query = ` select input_data, @@ -51,7 +39,7 @@ const graph = (chain: Chain) => { from ${chain}.core.fact_transactions WHERE to_address = '${address[chain]}' - and BLOCK_NUMBER > ${startblock} AND BLOCK_NUMBER < ${endblock} + and BLOCK_NUMBER > ${await getFromBlock()} AND BLOCK_NUMBER < ${await getToBlock()} ` @@ -67,39 +55,18 @@ const graph = (chain: Chain) => { tx: a[1] } as IVolume }) - const coins = [...new Set(rawData.map((a: IVolume) => `${chain}:${a.tokenAddress.toLowerCase()}`))] - const coins_split = []; - 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 dailyFees = createBalances() - const volumeUSD: IVolume[] = rawData.map((e: IVolume) => { - const price = prices[`${chain}:${e.tokenAddress.toLowerCase()}`]?.price || 0; - const decimals = prices[`${chain}:${e.tokenAddress.toLowerCase()}`]?.decimals || 0; - if (!price || !decimals) return { - amount: 0, - tokenAddress: e.tokenAddress, - tx: e.tx - } as IVolume; - const amount = (Number(e.amount) / 10 ** decimals) * price; - return { - amount: amount, - tokenAddress: e.tokenAddress, - tx: e.tx - } as IVolume - }).filter((a: IVolume) => !isNaN(a.amount)) - .filter((a: IVolume) => !blackList[chain]?.includes(a.tokenAddress.toLowerCase())) - .filter((a: IVolume) => a.amount < 10_000_000) - const dailyVolume = volumeUSD.reduce((a: number, b: IVolume) => a + b.amount, 0); - const dailyFees = dailyVolume * 0.0085 + rawData.map((e: IVolume) => { + dailyFees.add(e.tokenAddress, e.amount) + }) + + dailyFees.resizeBy(0.0085) return { - dailyFees: `${dailyFees}`, - dailyProtocolRevenue: `${dailyFees}`, - dailyRevenue: `${dailyFees}`, + dailyFees: dailyFees, + dailyProtocolRevenue: dailyFees, + dailyRevenue: dailyFees, timestamp } diff --git a/fees/nftearth.ts b/fees/nftearth.ts index e819203f64..87f4c99637 100644 --- a/fees/nftearth.ts +++ b/fees/nftearth.ts @@ -1,5 +1,5 @@ import ADDRESSES from '../helpers/coreAssets.json' -import { Adapter, FetchResultFees } from "../adapters/types"; +import { Adapter, ChainBlocks, FetchOptions, FetchResultFees } from "../adapters/types"; import { CHAIN } from "../helpers/chains"; import { getTimestampAtStartOfDayUTC, getTimestampAtStartOfNextDayUTC } from "../utils/date"; import * as sdk from "@defillama/sdk"; @@ -29,72 +29,48 @@ interface ISaleData { creator_fee: number; marketplace_fee: number; } +const event_order_fulfilled = "event OrderFulfilled(bytes32 orderHash, address indexed offerer, address indexed zone, address recipient, (uint8 itemType, address token, uint256 identifier, uint256 amount)[] offer, (uint8 itemType, address token, uint256 identifier, uint256 amount, address recipient)[] consideration)" -const fetch = (chain: Chain) => { - return async (timestamp: number): Promise => { - const todaysTimestamp = getTimestampAtStartOfDayUTC(timestamp) - const yesterdaysTimestamp = getTimestampAtStartOfNextDayUTC(timestamp) - const fromBlock = (await getBlock(todaysTimestamp, chain, {})); - const toBlock = (await getBlock(yesterdaysTimestamp, chain, {})); - const logs: ITx[] = (await sdk.getEventLogs({ - target: marketplace_address[chain], - fromBlock: fromBlock, - toBlock: toBlock, - topics: [topic0], - chain: chain - })).map((e: any) => { return { data: e.data.replace('0x', ''), transactionHash: e.transactionHash } as ITx}); - - const ethAddress = chain !== CHAIN.POLYGON ? ["ethereum:" + ADDRESSES.null]: 'ethereum:' + ADDRESSES.ethereum.MATIC; - const payableToken: string[] = logs.map((tx: ITx) => { - const postionPayableToken = Number(tx.data.slice(320, 384)) === 1 ? 6 : 11; - const address = tx.data.slice(postionPayableToken*64, (postionPayableToken*64)+64); // 11 - const contract_address = '0x' + address.slice(24, address.length); - return `${chain}:${contract_address}`; - }); - - const prices = await getPrices([ethAddress, ...new Set(payableToken)], timestamp); - const ethPrice = prices[ethAddress].price; +const fetch = (_chain: Chain) => { + return async (timestamp: number, _: ChainBlocks, _options: FetchOptions): Promise => { + // project is dead + // TODO: add project dead flag + return { dailyFees: '0', dailyRevenue: '0', timestamp } + /* const dailyFees = createBalances() + const dailyRevenue = createBalances() + const logs= await getLogs({ + target: marketplace_address[chain], + topics: [topic0], + }) - const rawLogsData: ISaleData[] = logs.map((tx: ITx) => { + logs.map((tx: any) => { const postionPayableToken = Number(tx.data.slice(320, 384)) === 1 ? 6 : 11; const address = tx.data.slice(postionPayableToken*64, (postionPayableToken*64)+64); // 11 const contract_address = '0x' + address.slice(24, address.length); - const thereIsNotCreatorFee = tx.data.length === 1280; - const _price = prices[`${chain}:${contract_address}`]?.price || ethPrice; - const _decimal = prices[`${chain}:${contract_address}`]?.decimals || 18; - const amount = Number('0x' + tx.data.slice(832, 896)) / 10 ** _decimal; // 13 - - const creator_fee = (Number('0x' + tx.data.slice(1152, 1216)) / 10 ** _decimal) * _price; // 18 - const marketplace_fee = (Number('0x' + tx.data.slice(1472, 1536)) / 10 ** _decimal) * _price; // 23 + const creator_fee = Number('0x' + tx.data.slice(1152, 1216)) // 18 + const marketplace_fee = Number('0x' + tx.data.slice(1472, 1536))// 23 + dailyFees.add(contract_address, creator_fee) + dailyFees.add(contract_address, marketplace_fee) + dailyRevenue.add(contract_address, marketplace_fee) - return { - amount: amount, - contract_address: contract_address, - creator_fee: thereIsNotCreatorFee ? 0 : creator_fee, - marketplace_fee: thereIsNotCreatorFee ? creator_fee : marketplace_fee, - } }); - const marketplace_fee = rawLogsData.reduce((a: number, b: ISaleData) => a + b.marketplace_fee, 0); - const creator_fee = rawLogsData.reduce((a: number, b: ISaleData) => a + b.creator_fee, 0); - const dailyFees = (marketplace_fee + creator_fee); - const dailyRevenue = (marketplace_fee); return { dailyFees: dailyFees.toString(), dailyRevenue: dailyRevenue.toString(), timestamp - } + }*/ } } const adapter: Adapter = { adapter: { [CHAIN.OPTIMISM]: { - fetch: fetch(CHAIN.OPTIMISM), - start: 1675036800, + fetch: fetch(CHAIN.OPTIMISM), + start: 1675036800, }, [CHAIN.ARBITRUM]: { fetch: fetch(CHAIN.ARBITRUM), diff --git a/fees/opensea/seaport.ts b/fees/opensea/seaport.ts index 721d43b6e7..06b24f2451 100644 --- a/fees/opensea/seaport.ts +++ b/fees/opensea/seaport.ts @@ -37,6 +37,7 @@ const contracts: IConrtact[] = [ } ] const topic0 = '0x9d9af8e38d66c62e2c12f0225249fd9d721c54b83f48d9352c97c6cacdcb6f31'; +const event_order_fulfilled = "event OrderFulfilled(bytes32 orderHash, address indexed offerer, address indexed zone, address recipient, (uint8 itemType, address token, uint256 identifier, uint256 amount)[] offer, (uint8 itemType, address token, uint256 identifier, uint256 amount, address recipient)[] consideration)" const fees_collector = '0x0000a26b00c1f0df003000390027140000faa719'; export const fetch = async (timestamp: number): Promise => { diff --git a/fees/pendle.ts b/fees/pendle.ts index f80420b505..4e04d45094 100644 --- a/fees/pendle.ts +++ b/fees/pendle.ts @@ -1,13 +1,8 @@ -import ADDRESSES from '../helpers/coreAssets.json' -import { FetchResultFees, SimpleAdapter } from "../adapters/types"; +import { ChainBlocks, FetchOptions, FetchResultFees, SimpleAdapter } from "../adapters/types"; import { CHAIN } from "../helpers/chains"; -import { ethers } from "ethers"; -import { getBlock } from "../helpers/getBlock"; -import { getPrices } from "../utils/prices"; import { Chain } from "@defillama/sdk/build/general"; -import * as sdk from "@defillama/sdk"; -import request, { gql } from "graphql-request"; - +import request from "graphql-request"; +import { addTokensReceived } from '../helpers/token'; type IConfig = { [s: string | Chain]: { @@ -16,7 +11,7 @@ type IConfig = { }; } -const gqlQuery = gql` +const gqlQuery = ` { assets(first: 1000, where: { type_in: ["SY"] @@ -27,10 +22,6 @@ const gqlQuery = gql` } ` -const STETH_ETHEREUM = "ethereum:" + ADDRESSES.ethereum.STETH -const SY_WSTETH_ARBITRUM = "0x80c12d5b6cc494632bf11b03f09436c8b61cc5df"; -const SY_WSTETH_OP = "0x96a528f4414ac3ccd21342996c93f2ecdec24286" - const chainConfig: IConfig = { [CHAIN.ETHEREUM]: { endpoint: 'https://api.thegraph.com/subgraphs/name/pendle-finance/core-mainnet-23-dec-18', @@ -50,106 +41,21 @@ const chainConfig: IConfig = { } } -const interface_parser = new ethers.Interface([ - "event Transfer(address indexed from, address indexed to, uint256 value)", -]); - const fetch = (chain: Chain) => { - return async (timestamp: number): Promise => { - const fromTimestamp = timestamp - 60 * 60 * 24 - const toTimestamp = timestamp - const startblock = (await getBlock(fromTimestamp, chain, {})); - const endblock = (await getBlock(toTimestamp, chain, {})); + return async (timestamp: number, _: ChainBlocks, options: FetchOptions): Promise => { + const { api } = options const allSy: string[] = (await request(chainConfig[chain].endpoint, gqlQuery)).assets.filter((token: any) => token.type === 'SY').map((token: any) => token.id.toLowerCase()) + const rewardTokens: string[] = (await api.multiCall({ permitFailure: true, abi: getRewardTokensABI, calls: allSy })).flat() + const dailyFees = await addTokensReceived({ options, target: chainConfig[chain].treasury, tokens: rewardTokens.concat(allSy) }) + const dailyRevenue = dailyFees.clone(0.3) + const dailySupplySideRevenue = dailyFees.clone(0.7) - const rewardTokens: string[] = (await sdk.api2.abi.multiCall({ - permitFailure: true, - abi: getRewardTokensABI, - calls: allSy.map((sy: string) => ({ - target: sy, - })), - chain: chain, - })).flat().map((a: string) => a.toLowerCase()) - - const assetInfos = (await sdk.api2.abi.multiCall({ - permitFailure: true, - abi: assetInfoABI, - calls: allSy.map((sy: string) => ({ - target: sy, - })), - chain: chain, - })) - - const allAssets: string[] = assetInfos.map((assetInfo: any) => assetInfo.assetAddress) - - const allSyType0: string[] = allSy.filter((_: any, i: number) => assetInfos[i].assetType === '0') - const exchangeRatesType0 = (await sdk.api2.abi.multiCall({ - permitFailure: true, - abi: exchangeRateABI, - calls: allSyType0.map((sy: string) => ({ - target: sy, - })), - chain: chain, - })) - - const rewardTokensSet = new Set(rewardTokens) - const allRewardTokens: string[] = Array.from(rewardTokensSet) - - - const prices = await getPrices(allRewardTokens.concat(allAssets).map((a) => `${chain}:${a.toLowerCase()}`).concat([STETH_ETHEREUM]), timestamp) - function getPriceFor(token: string) { - if (!prices[`${chain}:${token.toLowerCase()}`]) return null; - return prices[`${chain}:${token.toLowerCase()}`]; - } - - const treasuryFilter = ethers.zeroPadValue(chainConfig[chain].treasury, 32) - - const allTransferEvents = (await Promise.all(allRewardTokens.concat(allSy).map((address: any) => sdk.getEventLogs({ - target: address, - toBlock: endblock, - fromBlock: startblock, - chain: chain, - topics: ['0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', null as any, treasuryFilter], - })))).flat() - .map((e) => { - return { address: e.address.toLowerCase(), args: interface_parser.parseLog(e)!.args, tx: e.transactionHash } - }); - let totalFee = 0; - - for (let e of allTransferEvents) { - if (allRewardTokens.includes(e.address)) { - const tokenPrice = getPriceFor(e.address) - if (tokenPrice) { - totalFee += Number(e!.args.value) * tokenPrice.price / (10 ** tokenPrice.decimals) - } - } else { - const idAll = allSy.indexOf(e.address) - if (idAll === -1) { - continue; - } - const assetPrice = [SY_WSTETH_ARBITRUM, SY_WSTETH_OP].includes(e.address) ? prices[STETH_ETHEREUM] : getPriceFor(assetInfos[idAll].assetAddress) - if (!assetPrice) { - continue; - } - - let amount; - if (assetInfos[idAll].assetType === '1') { - amount = Number(e!.args.value); - } else { - const idAsset0 = allSyType0.indexOf(e.address) - amount = Number(e!.args.value) * exchangeRatesType0[idAsset0] / (10 ** 18) - } - totalFee += amount * assetPrice.price / (10 ** assetInfos[idAll].assetDecimals); - } - } - const dailyRevenue = totalFee * 0.3; - const dailySupplySideRevenue = totalFee - dailyRevenue; return { - dailyFees: `${totalFee}`, - dailyRevenue: `${totalFee}`, - dailyHoldersRevenue: `${dailyRevenue}`, - dailySupplySideRevenue: `${dailySupplySideRevenue}`, + dailyFees: dailyFees, + dailyRevenue: dailyFees, + dailyHoldersRevenue: dailyRevenue, + dailySupplySideRevenue: dailySupplySideRevenue, timestamp } } @@ -178,8 +84,4 @@ const adapter: SimpleAdapter = { const getRewardTokensABI = "address[]:getRewardTokens" -const assetInfoABI = "function assetInfo() view returns (uint8 assetType, address assetAddress, uint8 assetDecimals)" - -const exchangeRateABI = "uint256:exchangeRate" - export default adapter; diff --git a/fees/qidao.ts b/fees/qidao.ts index d2f86c44bc..42ec27fa2c 100644 --- a/fees/qidao.ts +++ b/fees/qidao.ts @@ -1,22 +1,12 @@ -import { FetchResultFees, SimpleAdapter } from "../adapters/types"; -import { CHAIN, XDAI } from "../helpers/chains"; -import * as sdk from "@defillama/sdk"; -import { getBlock } from "../helpers/getBlock"; -import { getPrices } from "../utils/prices"; +import { ChainBlocks, FetchOptions, FetchResultFees, SimpleAdapter } from "../adapters/types"; +import { CHAIN, } from "../helpers/chains"; import { Chain } from "@defillama/sdk/build/general"; -import { ethers } from "ethers"; type TAddress = { [s: string | Chain]: string; } -interface ILog { - data: string; - transactionHash: string; - topics: string[]; -} - const Vault_Fee_Manager_Contracts: TAddress = { [CHAIN.ARBITRUM]: '0xdCC1c692110E0e53Bd57D5B2234867E9C5B98158', [CHAIN.POLYGON]: '0x11606d99AD8aAC49E033B14c89552F585028bA7d', @@ -35,78 +25,28 @@ const Performance_Fee_Management_Contracts: TAddress = { const event_fees_withdraw = 'event FeeWithdrawn(address token,uint256 amount)'; const event_token_earned = 'event TokensEarned(address indexed perfToken,address indexed recipient,uint256 amount)'; -const topic0_fees_withdraw = '0x78473f3f373f7673597f4f0fa5873cb4d375fea6d4339ad6b56dbd411513cb3f'; -const topic0_token_earned = '0x7750c36249a9e8cdc4a6fb8a68035d55429ff67a4db8b110026b1375dd9d380c'; - -const contract_interface = new ethers.Interface([ - event_fees_withdraw, - event_token_earned -]); - -interface IRAW { - token: string; - amount: number; -} - - const fetch = (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 log_withdraw_fees: ILog[] = Vault_Fee_Manager_Contracts[chain] ? (await sdk.getEventLogs({ + return async (timestamp: number, _: ChainBlocks, { createBalances, getLogs, }: FetchOptions): Promise => { + const dailyFees = createBalances() + const log_withdraw_fees = Vault_Fee_Manager_Contracts[chain] ? (await getLogs({ target: Vault_Fee_Manager_Contracts[chain], - toBlock: toBlock, - fromBlock: fromBlock, - chain: chain, - topics: [topic0_fees_withdraw] - })) as ILog[] : []; + eventAbi: event_fees_withdraw + })) : [] - const log_token_earned: ILog[] = Performance_Fee_Management_Contracts[chain] ? (await sdk.getEventLogs({ + const log_token_earned = Performance_Fee_Management_Contracts[chain] ? (await getLogs({ target: Performance_Fee_Management_Contracts[chain], - toBlock: toBlock, - fromBlock: fromBlock, - chain: chain, - topics: [topic0_token_earned] - })) as ILog[] : []; - - const raw_withdraw: IRAW[] = log_withdraw_fees.map((e: ILog) => { - const value = contract_interface.parseLog(e); - const token = value!.args.token; - const amount = Number(value!.args.amount); - return { - token: token, - amount: amount, - } as IRAW - }) - - const raw_token_earned: IRAW[] = log_token_earned.map((e: ILog) => { - const value = contract_interface.parseLog(e); - const token = value!.args.perfToken; - const amount = Number(value!.args.amount); - return { - token: token, - amount: amount, - } as IRAW - }) + eventAbi: event_token_earned + })) : [] - const coins = [...new Set([...raw_withdraw, ...raw_token_earned].map((e: IRAW) => `${chain}:${e.token}`.toLowerCase()))] - const prices = await getPrices(coins, timestamp); - const dailyFeesUSD = [...raw_withdraw, ...raw_token_earned].map((e: IRAW) => { - const price = (prices[`${chain}:${e.token}`.toLowerCase()]?.price || 0); - const decimals = (prices[`${chain}:${e.token}`.toLowerCase()]?.decimals || 0); - return (Number(e.amount) / 10 ** decimals) * price; - }).reduce((a: number, b: number) => a + b, 0) - const dailyFees = dailyFeesUSD; - const dailyRevenue = dailyFees * .5; - const totalSupplySideRevenue = dailyFees * .5; + log_withdraw_fees.map((e: any) => dailyFees.add(e.token, e.amount)) + log_token_earned.map((e: any) => dailyFees.add(e.perfToken, e.amount)) + const dailyRevenue = dailyFees.clone(0.5) + const totalSupplySideRevenue = dailyFees.clone(0.5) return { - dailyFees: `${dailyFees}`, - dailyRevenue: `${dailyRevenue}`, - dailyHoldersRevenue: `${dailyRevenue}`, - dailySupplySideRevenue: `${totalSupplySideRevenue}`, + dailyFees, + dailyRevenue, + dailyHoldersRevenue: dailyRevenue, + dailySupplySideRevenue: totalSupplySideRevenue, timestamp } } diff --git a/fees/railgun.ts b/fees/railgun.ts index 68c138c514..b0b4b634c0 100644 --- a/fees/railgun.ts +++ b/fees/railgun.ts @@ -1,10 +1,6 @@ import { Chain } from "@defillama/sdk/build/general"; -import { getBlock } from "../helpers/getBlock"; -import { FetchResultFees, SimpleAdapter } from "../adapters/types"; +import { ChainBlocks, FetchOptions, FetchResultFees, SimpleAdapter } from "../adapters/types"; import { CHAIN } from "../helpers/chains"; -import * as sdk from "@defillama/sdk"; -import { get } from "http"; -import { getPrices } from "../utils/prices"; type IContract = { @@ -23,84 +19,28 @@ const topic0_shield = '0x3a5b9dc26075a3801a6ddccf95fec485bb7500a91b44cec1add984c const topic0_unshield = '0xd93cf895c7d5b2cd7dc7a098b678b3089f37d91f48d9b83a0800a91cbdf05284'; // token index 2 // amount index 5 - - -interface ILog { - blockNumber: number, - blockHash: string, - transactionHash: string, - transactionIndex: number, - address: string, - data: string, - topics: string[], - logIndex: number, - removed: boolean, -} -interface IFees { - token: string; - amount: number; +const eventAbis = { + "Shield": "event Shield(uint256 treeNumber, uint256 startPosition, (bytes32 npk, (uint8 tokenType, address tokenAddress, uint256 tokenSubID) token, uint120 value)[] commitments, (bytes32[3] encryptedBundle, bytes32 shieldKey)[] shieldCiphertext, uint256[] fees)", + "Unshield": "event Unshield(address to, (uint8 tokenType, address tokenAddress, uint256 tokenSubID) token, uint256 amount, uint256 fee)", } const fetchFees = (chain: Chain) => { - return async (timestamp: number): Promise => { - const toTimestamp = timestamp; - const fromTimestamp = timestamp - 24 * 60 * 60; - const toBlock = await getBlock(toTimestamp, chain, {}); - const fromBlock = await getBlock(fromTimestamp, chain, {}); - const logs_shield: ILog[] = (await sdk.getEventLogs({ - target: contract[chain], - topics: [topic0_shield], - fromBlock, - toBlock, - chain, - })) as ILog[]; - - const logs_unshield: ILog[] = (await sdk.getEventLogs({ - target: contract[chain], - topics: [topic0_unshield], - fromBlock, - toBlock, - chain, - })) as ILog[]; - - const shield_fees: IFees[] = logs_shield.map((log) => { - const data = log.data.replace('0x', ''); - const token = data.slice(64 * 8, (64 * 8) + 64); - const contract_address = '0x' + token.slice(24, token.length); - const amount = Number('0x'+data.slice((64 * 17), (64 * 17) + 64)); - return { - token: contract_address, - amount, - } - }); - const unshield_fees: IFees[] = logs_unshield.map((log) => { - const data = log.data.replace('0x', ''); - const token = data.slice(64 * 2, (64 * 2) + 64); - const contract_address = '0x' + token.slice(24, token.length); - const amount = Number('0x'+data.slice((64 * 5), (64 * 5) + 64)); - return { - token: contract_address, - amount, - } - }); - const tokens = [...shield_fees, ...unshield_fees].map((e) => e.token); - const coins = [...new Set(tokens)].map((e: string) => `${chain}:${e}`); - const prices = await getPrices([...coins], timestamp); - - const dailyFees = [...shield_fees, ...unshield_fees].reduce((a: number, b: IFees) => { - const price = prices[`${chain}:${b.token}`]?.price || 0; - const decimals = prices[`${chain}:${b.token}`]?.decimals || 0; - if (price === 0 || decimals === 0) return a; - const amount = (b.amount / 10 ** decimals) * price - const oneMillion = 1000000; - if (amount > oneMillion) return a; - return a + (b.amount / 10 ** decimals) * price; - },0) + return async (timestamp: number, _: ChainBlocks, { createBalances, getLogs, }: FetchOptions): Promise => { + const dailyFees = createBalances() + const logs_shield = await getLogs({ target: contract[chain], topics: [topic0_shield], eventAbi: eventAbis.Shield }) + const logs_unshield = await getLogs({ target: contract[chain], topics: [topic0_unshield], eventAbi: eventAbis.Unshield }) + + logs_shield.forEach((log) => { + dailyFees.addTokens(log.commitments.map((i: any) => i.token.tokenAddress), log.fees) + }) + logs_unshield.forEach((log) => { + dailyFees.add(log.token.tokenAddress, log.fee) + }) return { - dailyFees: dailyFees.toString(), - dailyRevenue: dailyFees.toString(), - dailyBribesRevenue: dailyFees.toString(), + dailyFees: dailyFees, + dailyRevenue: dailyFees, + dailyBribesRevenue: dailyFees, timestamp, } } diff --git a/fees/sharesgram.ts b/fees/sharesgram.ts index 56721e59c1..274d9c5c2e 100644 --- a/fees/sharesgram.ts +++ b/fees/sharesgram.ts @@ -1,72 +1,12 @@ -import ADDRESSES from '../helpers/coreAssets.json' -import { getBalance } from "@defillama/sdk/build/eth"; -import { Adapter, ChainBlocks, FetchResultFees } from "../adapters/types" +import { Adapter, } from "../adapters/types" import { CHAIN } from "../helpers/chains" -import { getBlock } from "../helpers/getBlock"; -import BigNumber from "bignumber.js"; -import { getPrices } from "../utils/prices"; - - -const holder_wallet_address = '0x6adfaef59fdd3522e8673d1a13418413beeeea57'; -const protocol_wallet_address = '0xefb9a25a5d892bdf587103a226e6dd0369b220de'; - -const fetch = async (timestamp: number, chainBlocks: ChainBlocks): Promise => { - const toTimestamp = timestamp; - const fromTimestamp = timestamp - 60 * 60 * 24 - const todaysBlock = (await getBlock(toTimestamp, CHAIN.BASE, chainBlocks)); - const yesterdaysBlock = (await getBlock(fromTimestamp, CHAIN.BASE, {})); - - const [ - holderBalanceStart, - holderBalanceEnd, - protocolBalanceStart, - protocolBalanceEnd, - ] = (await Promise.all([ - getBalance({ - target: holder_wallet_address, - block: yesterdaysBlock, - chain: CHAIN.BASE - }), - getBalance({ - target: holder_wallet_address, - block: todaysBlock, - chain: CHAIN.BASE - }), - getBalance({ - target: protocol_wallet_address, - block: yesterdaysBlock, - chain: CHAIN.BASE - }), - getBalance({ - target: protocol_wallet_address, - block: todaysBlock, - chain: CHAIN.BASE - }), - ])).map(i => i.output) - const ethBalance = (new BigNumber(holderBalanceEnd).minus(holderBalanceStart)) - .plus((new BigNumber(protocolBalanceEnd).minus(protocolBalanceStart))) - const fees: BigNumber = ethBalance.dividedBy(10 ** 18) - const dailyFee: number = fees.dividedBy(.7).toNumber() - const ethAddress = "ethereum:" + ADDRESSES.null; - const pricesObj: any = await getPrices([ethAddress], toTimestamp); - const latestPrice = pricesObj[ethAddress]["price"] - const dailyFees = dailyFee * latestPrice; - const dailyRevenue = dailyFees * .7; - const dailyHolderRev = dailyFees * .5; - const dailyProtocolRevenue = dailyFees * .2; - return { - dailyFees: dailyFees.toString(), - dailyRevenue: dailyRevenue.toString(), - dailyProtocolRevenue: dailyProtocolRevenue.toString(), - dailyHoldersRevenue: dailyHolderRev.toString(), - timestamp - } -} +import { getFeesExport } from '../helpers/friend-tech'; +// TODO: mark project as dead const adapter: Adapter = { adapter: { [CHAIN.BASE]: { - fetch, + fetch: getFeesExport('0xbe74a95d159e8e323b8c1a70f825efc85fed27c4'), start: 1693180800 } } diff --git a/fees/solana.ts b/fees/solana.ts index d8b3ebe677..04b37be79d 100644 --- a/fees/solana.ts +++ b/fees/solana.ts @@ -1,4 +1,4 @@ -import { Adapter, ProtocolType } from "../adapters/types"; +import { Adapter, ChainBlocks, FetchOptions, ProtocolType } from "../adapters/types"; import { CHAIN } from "../helpers/chains"; import { getTimestampAtStartOfDayUTC } from "../utils/date"; import { getPrices } from "../utils/prices"; @@ -13,24 +13,19 @@ interface IFees { const adapter: Adapter = { adapter: { [CHAIN.SOLANA]: { - fetch: async (timestamp: number) => { - const ts = getTimestampAtStartOfDayUTC(timestamp) - const next = ts + 86400; - const dailyFees: IFees = (await queryDune('3277066', { - endTime: next, - }))[0] + fetch: async (timestamp: number , _: ChainBlocks, { createBalances, startOfDay }: FetchOptions) => { + const next = startOfDay + 86400; + const _dailyFees: IFees = (await queryDune('3277066', { endTime: next, }))[0] - - const solanaFee = dailyFees.total_fees; - const pricesObj = await getPrices(["coingecko:solana"], ts); - const usdFees = (solanaFee * pricesObj["coingecko:solana"].price); - const dailyRevenue = usdFees * 0.5; + const dailyFees = createBalances() + dailyFees.addCGToken('solana', _dailyFees.total_fees) + const dailyRevenue = dailyFees.clone(0.5) return { timestamp, - dailyFees: usdFees.toString(), - dailyRevenue: dailyRevenue.toString(), - dailyHoldersRevenue: dailyRevenue.toString(), + dailyFees: dailyFees, + dailyRevenue: dailyRevenue, + dailyHoldersRevenue: dailyRevenue, }; }, start: 1610841600 diff --git a/fees/stakewise.ts b/fees/stakewise.ts index 9702ddd41a..95c8fa7281 100644 --- a/fees/stakewise.ts +++ b/fees/stakewise.ts @@ -1,72 +1,35 @@ -import ADDRESSES from '../helpers/coreAssets.json' -import { FetchResultFees, SimpleAdapter } from "../adapters/types" +import { ChainBlocks, FetchOptions, FetchResultFees, SimpleAdapter } from "../adapters/types" import { CHAIN } from "../helpers/chains" -import { getBlock } from "../helpers/getBlock" -import * as sdk from "@defillama/sdk" -import { ethers } from "ethers" -import { getPrices } from "../utils/prices" const reth2Address = '0x20bc832ca081b91433ff6c17f85701b6e92486c5'; -const reth2Topic = '0xb9c8611ba2eb0880a25df0ebde630048817ebee5f33710af0da51958c621ffd7'; -const reth2Interface = new ethers.Interface([ - 'event RewardsUpdated(uint256 periodRewards,uint256 totalRewards,uint256 rewardPerToken,uint256 distributorReward,uint256 protocolReward)' -]); - const osTokenCtrlAddress = '0x2A261e60FB14586B474C208b1B7AC6D0f5000306'; -const osTokenCtrlTopic = '0xb27a3a9979877b12952e21e91eeded34f5ecc7d5147544ca7b58fa9cd85e30be' -const osTokenCtrlInterface = new ethers.Interface([ - 'event StateUpdated(uint256 profitAccrued,uint256 treasuryShares,uint256 treasuryAssets)' -]); -const ethAddress = "ethereum:" + ADDRESSES.null; - -interface ILog { - data: string; - transactionHash: string; - topics: string[]; -} - -const fetchFees = async (timestamp: number): Promise => { - const fromTimestamp = timestamp - 60 * 60 * 24 - const toTimestamp = timestamp - const fromBlock = (await getBlock(fromTimestamp, CHAIN.ETHEREUM, {})); - const toBlock = (await getBlock(toTimestamp, CHAIN.ETHEREUM, {})); +const fetchFees = async (timestamp: number , _: ChainBlocks, { createBalances, getLogs, }: FetchOptions): Promise => { + const dailyFees = createBalances() + const dailyRevenue = createBalances() + const dailySupplySideRevenue = createBalances() // fetch rETH2 logs - let logs: ILog[] = (await sdk.getEventLogs({ + let logs= await getLogs({ target: reth2Address, - toBlock: toBlock, - fromBlock: fromBlock, - topics: [reth2Topic], - chain: CHAIN.ETHEREUM - })) as ILog[] - const rEth2Rewards = logs.map((log: ILog) => { - const value = reth2Interface.parseLog(log); - return Number(value!.args.periodRewards) / 10 ** 18; + eventAbi: 'event RewardsUpdated(uint256 periodRewards,uint256 totalRewards,uint256 rewardPerToken,uint256 distributorReward,uint256 protocolReward)' + }) + const rEth2Rewards = logs.map((log: any) => { + return Number(log.periodRewards) }).reduce((a: number, b: number) => a + b, 0); // fetch osETH logs - logs = (await sdk.getEventLogs({ + logs = await getLogs({ target: osTokenCtrlAddress, - toBlock: toBlock, - fromBlock: fromBlock, - topics: [osTokenCtrlTopic], - chain: CHAIN.ETHEREUM - })) as ILog[] - const osEthRewards = logs.map((log: ILog) => { - const value = osTokenCtrlInterface.parseLog(log); - return Number(value!.args.profitAccrued) / 10 ** 18; + eventAbi: 'event StateUpdated(uint256 profitAccrued,uint256 treasuryShares,uint256 treasuryAssets)' + }) + const osEthRewards = logs.map((log: any) => { + return Number(log.profitAccrued) }).reduce((a: number, b: number) => a + b, 0); - const ethPrice = (await getPrices([ethAddress], timestamp))[ethAddress].price; - let dailyFees = (osEthRewards + rEth2Rewards) * ethPrice; - const dailyRevenue = ((osEthRewards * 0.05) + (rEth2Rewards * 0.1)) * ethPrice; - const dailySupplySideRevenue = ((osEthRewards * 0.95) + (rEth2Rewards * 0.9)) * ethPrice; - return { - dailyFees: `${dailyFees}`, - dailyRevenue: `${dailyRevenue}`, - dailySupplySideRevenue: `${dailySupplySideRevenue}`, - timestamp - } + dailyFees.addGasToken(osEthRewards + rEth2Rewards) + dailyRevenue.addGasToken((osEthRewards * 0.05) + (rEth2Rewards * 0.1)) + dailySupplySideRevenue.addGasToken((osEthRewards * 0.95) + (rEth2Rewards * 0.9)) + return { dailyFees, dailyRevenue, dailySupplySideRevenue, timestamp } } diff --git a/fees/stargate.ts b/fees/stargate.ts index e7e9cf04d0..02ee411e13 100644 --- a/fees/stargate.ts +++ b/fees/stargate.ts @@ -1,35 +1,11 @@ import ADDRESSES from '../helpers/coreAssets.json' -import { Adapter, FetchResultFees } from "../adapters/types"; +import { Adapter, ChainBlocks, FetchOptions, FetchResultFees } from "../adapters/types"; import { CHAIN } from "../helpers/chains"; import { Chain } from "@defillama/sdk/build/general"; -import { getPrices } from "../utils/prices"; -import { getBlock } from "../helpers/getBlock"; -import * as sdk from "@defillama/sdk"; -import { ethers } from "ethers"; - -interface ILog { - data: string; - transactionHash: string; - topics: string[]; - address: string; -} - -const topic0_swap = '0x34660fc8af304464529f48a778e03d03e4d34bcd5f9b6f0cfbf3cd238c642f7f' -const topic0_swap_remote = '0xfb2b592367452f1c437675bed47f5e1e6c25188c17d7ba01a12eb030bc41ccef' const event0_swap = 'event Swap(uint16 chainId,uint256 dstPoolId,address from,uint256 amountSD,uint256 eqReward,uint256 eqFee,uint256 protocolFee,uint256 lpFee)' const event0_swap_remote = 'event SwapRemote( address to,uint256 amountSD,uint256 protocolFee,uint256 dstFee)' -const contract_interface = new ethers.Interface([ - event0_swap, - event0_swap_remote -]); - -interface IFee { - amount: number; - contract: string; -} - type IAddress = { [s: string | Chain]: string[]; } @@ -71,80 +47,28 @@ type IMap = { } const mapTokenPrice: IMap = { - ['0x101816545f6bd2b1076434b54383a1e633390a2e'.toLowerCase()]: 'ethereum:' + ADDRESSES.null, - ['0x915a55e36a01285a14f05de6e81ed9ce89772f8e'.toLowerCase()]: 'ethereum:' + ADDRESSES.null, - ['0xd22363e3762ca7339569f3d33eade20127d5f98c'.toLowerCase()]: 'ethereum:' + ADDRESSES.null, - ['0x892785f33CdeE22A30AEF750F285E18c18040c3e'.toLowerCase()]: 'ethereum:' + ADDRESSES.ethereum.USDC, - ['0xB6CfcF89a7B22988bfC96632aC2A9D6daB60d641'.toLowerCase()]: 'ethereum:' + ADDRESSES.ethereum.USDT, - ['0x38EA452219524Bb87e18dE1C24D3bB59510BD783'.toLowerCase()]: 'ethereum:' + ADDRESSES.ethereum.USDT, // USDT - ['0xdf0770dF86a8034b3EFEf0A1Bb3c889B8332FF56'.toLowerCase()]: 'ethereum:' + ADDRESSES.ethereum.USDC, // USDC - ['0x1205f31718499dBf1fCa446663B532Ef87481fe1'.toLowerCase()]: 'ethereum:' + ADDRESSES.ethereum.USDC, - ['0x29e38769f23701A2e4A8Ef0492e19dA4604Be62c'.toLowerCase()]: 'ethereum:' + ADDRESSES.ethereum.USDT, - ['0x9aA83081AA06AF7208Dcc7A4cB72C94d057D2cda'.toLowerCase()]: 'ethereum:' + ADDRESSES.ethereum.USDT, - ['0x98a5737749490856b401DB5Dc27F522fC314A4e1'.toLowerCase()]: 'coingecko:binance-usd', - ['0x12edeA9cd262006cC3C4E77c90d2CD2DD4b1eb97'.toLowerCase()]: 'ethereum:' + ADDRESSES.ethereum.USDC, - ['0xDecC0c09c3B5f6e92EF4184125D5648a66E35298'.toLowerCase()]: 'ethereum:' + ADDRESSES.ethereum.USDC + ['0x101816545f6bd2b1076434b54383a1e633390a2e'.toLowerCase()]: ADDRESSES.null, + ['0x915a55e36a01285a14f05de6e81ed9ce89772f8e'.toLowerCase()]: ADDRESSES.null, + ['0xd22363e3762ca7339569f3d33eade20127d5f98c'.toLowerCase()]: ADDRESSES.null, } const fetch = (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: ILog[] = (await Promise.all(contract_address[chain].map((address: string) => sdk.getEventLogs({ - target: address, - toBlock: toBlock, - fromBlock: fromBlock, - chain: chain, - topics: [topic0_swap] - })))).flat(); - - const logs_swap_remote: ILog[] = (await Promise.all(contract_address[chain].map((address: string) => sdk.getEventLogs({ - target: address, - toBlock: toBlock, - fromBlock: fromBlock, - chain: chain, - topics: [topic0_swap_remote] - })))).flat(); - const logs_swap: IFee[] = logs.map((e: ILog) => { - const value = contract_interface.parseLog(e); - const amount = Number(value!.args.protocolFee); - return { - amount: amount, - contract: e.address - } - }); - const swap_remote: IFee[] = logs_swap_remote.map((e: ILog) => { - const value = contract_interface.parseLog(e); - const amount = Number(value!.args.protocolFee); - return { - amount: amount, - contract: e.address - } - }); - const coins = [...new Set(logs_swap.concat(swap_remote).map((e: IFee) => mapTokenPrice[e.contract.toLowerCase()]))]; - const prices = await getPrices(coins, timestamp); - if (prices['coingecko:binance-usd']) - prices['coingecko:binance-usd'].decimals = 18 - const dailyFees = [...logs_swap, ...swap_remote].map((e: IFee) => { - const price = prices[mapTokenPrice[e.contract.toLowerCase()]].price; - const decimals = prices[mapTokenPrice[e.contract.toLowerCase()]].decimals; - return (Number(e.amount) / 10 ** decimals) * price; - }).reduce((a: number, b: number) => a + b, 0) - return { - dailyFees: dailyFees.toString(), - dailyRevenue: dailyFees.toString(), - timestamp: timestamp - } + return async (timestamp: number, _: ChainBlocks, { createBalances, getLogs }: FetchOptions): Promise => { + const dailyFees = createBalances() + const transform = (a: string) => mapTokenPrice[a.toLowerCase()] ?? a + const logs = await getLogs({ targets: contract_address[chain], eventAbi: event0_swap, flatten: false, }) + const logs_swap_remote = await getLogs({ targets: contract_address[chain], eventAbi: event0_swap_remote, flatten: false }) + logs.forEach((_: any, index: number) => _.forEach((log: any) => dailyFees.add(transform(contract_address[chain][index]), log.protocolFee))) + logs_swap_remote.forEach((_: any, index: number) => _.forEach((log: any) => dailyFees.add(transform(contract_address[chain][index]), log.protocolFee))) + return { dailyFees, dailyRevenue: dailyFees, timestamp, } } } const adapter: Adapter = { adapter: { [CHAIN.ETHEREUM]: { - fetch: fetch(CHAIN.ETHEREUM), - start: 1661990400, + fetch: fetch(CHAIN.ETHEREUM), + start: 1661990400, }, [CHAIN.ARBITRUM]: { fetch: fetch(CHAIN.ARBITRUM), diff --git a/fees/stealcam.ts b/fees/stealcam.ts index 2d4b66e0dd..a896b1d254 100644 --- a/fees/stealcam.ts +++ b/fees/stealcam.ts @@ -1,51 +1,31 @@ -import { FetchResultFees, SimpleAdapter } from "../adapters/types"; +import { ChainBlocks, FetchOptions, FetchResultFees, 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 { ethers } from "ethers"; const address = '0x2f60c9cee6450a8090e17a79e3dd2615a1c419eb' const event_fees_distibute = 'event Stolen (address from, address to, uint256 id, uint256 value)'; -const contract_interface = new ethers.Interface([ - event_fees_distibute -]); -const fetch = async (timestamp: number): Promise => { - const fromTimestamp = timestamp - 60 * 60 * 24 - const toTimestamp = timestamp - const fromBlock = (await getBlock(fromTimestamp, CHAIN.ARBITRUM, {})); - const toBlock = (await getBlock(toTimestamp, CHAIN.ARBITRUM, {})); - const prices = await getPrices([ - "coingecko:ethereum" - ], timestamp); - const dailyFees = (await sdk.getEventLogs({ - target: address, - fromBlock: fromBlock, - toBlock: toBlock, - topics: ['0xbd1d1f579700e7d5d89a06ef937990d5f920f734ad1b9b945b354c9643dfd322'], - chain: CHAIN.ARBITRUM - })).map((e: any) => contract_interface.parseLog(e)) - .map((e: any) => { - return Number(e!.args.value) / 10 ** 18; - }).reduce((a: number, b: number) => a + b/10, 0) * prices["coingecko:ethereum"].price - const dailyRevenue = dailyFees; - return { - dailyFees: `${dailyFees}`, - dailyRevenue: `${dailyRevenue}`, - timestamp - } +const fetch = async (timestamp: number, _: ChainBlocks, { createBalances, getLogs, }: FetchOptions): Promise => { + const dailyFees = createBalances(); + (await getLogs({ + target: address, + eventAbi: event_fees_distibute, + })).map((e: any) => dailyFees.addGasToken(e.value)) + return { + dailyFees, + dailyRevenue: dailyFees, + timestamp + } } const adapter: SimpleAdapter = { - adapter: { - [CHAIN.ARBITRUM]: { - fetch: fetch, - start: 1678406400, - }, - } + adapter: { + [CHAIN.ARBITRUM]: { + fetch: fetch, + start: 1678406400, + }, + } }; export default adapter; diff --git a/fees/tron.ts b/fees/tron.ts index 63dc77857c..aad44ec933 100644 --- a/fees/tron.ts +++ b/fees/tron.ts @@ -1,30 +1,28 @@ -import { Adapter, ProtocolType } from "../adapters/types"; +import { Adapter, ChainBlocks, FetchOptions, ProtocolType } from "../adapters/types"; import { CHAIN } from "../helpers/chains"; -import { getTimestampAtStartOfDayUTC } from "../utils/date"; -import { getPrices } from "../utils/prices"; import { httpGet } from "../utils/fetchURL"; const adapter: Adapter = { adapter: { [CHAIN.TRON]: { - fetch: async (timestamp: number) => { - const ts = getTimestampAtStartOfDayUTC(timestamp) - const today = new Date(ts * 1000).toISOString().substring(0, "2022-11-03".length) - const dailyFees = await httpGet(`https://apilist.tronscanapi.com/api/turnover?size=1000&start=1575158400000&end=${Date.now()}&type=0`); - const trxFeesToday = dailyFees.data.find((d:any)=>d.day===today) - const pricesObj = await getPrices(["coingecko:tron"], ts); - const usdFees = (trxFeesToday.total_trx_burn*pricesObj["coingecko:tron"].price).toString() // excludes trx burned for USDD + fetch: async (timestamp: number, _: ChainBlocks, { createBalances, startOfDay }: FetchOptions) => { + const dailyFees = createBalances() + const ts = startOfDay + const today = new Date(ts * 1000).toISOString().substring(0, "2022-11-03".length) + const _dailyFees = await httpGet(`https://apilist.tronscanapi.com/api/turnover?size=1000&start=1575158400000&end=${Date.now()}&type=0`); + const trxFeesToday = _dailyFees.data.find((d: any) => d.day === today) + dailyFees.addCGToken('tron', trxFeesToday.total_trx_burn) - return { - timestamp, - dailyFees: usdFees, - dailyRevenue: usdFees, - dailyHoldersRevenue: usdFees, - }; - }, - start: 1575158400 + return { + timestamp, + dailyFees: dailyFees, + dailyRevenue: dailyFees, + dailyHoldersRevenue: dailyFees, + }; + }, + start: 1575158400 }, -}, + }, protocolType: ProtocolType.CHAIN } diff --git a/fees/uniswap-lab.ts b/fees/uniswap-lab.ts index 24328258a1..fc26a0d46b 100644 --- a/fees/uniswap-lab.ts +++ b/fees/uniswap-lab.ts @@ -1,120 +1,26 @@ import ADDRESSES from '../helpers/coreAssets.json' -import { FetchResultFees, SimpleAdapter } from "../adapters/types"; +import { ChainBlocks, FetchOptions, FetchResultFees, SimpleAdapter } from "../adapters/types"; import { CHAIN } from "../helpers/chains"; -import { getPrices } from "../utils/prices"; -import { queryFlipside } from "../helpers/flipsidecrypto"; -import { Chain } from "@defillama/sdk/build/general"; +import { addTokensReceived } from '../helpers/token'; -interface tokenInfo { - token: string; - amount: number; +const config: any = { + ethereum: { tokens: [ADDRESSES.ethereum.USDC], targets: ['0x163c5e051049e92915017fe7bb9b8ce6182bcbb1', '0x6460d14dbaeb27aefec8ebef85db35defa31c3b9'] }, + optimism: { tokens: [ADDRESSES.optimism.USDC_CIRCLE], targets: ['0xd4ce1f1b8640c1988360a6729d9a73c85a0c80a3'] }, + polygon: { tokens: [ADDRESSES.polygon.USDC], targets: ['0xce946931adf7afc0797de2a76270a28458f487ed'] }, + arbitrum: { tokens: [ADDRESSES.arbitrum.USDC_CIRCLE], targets: ['0xd4ce1f1b8640c1988360a6729d9a73c85a0c80a3'] }, } -const fetchFees = (chain: Chain) => { - return async (timestamp: number): Promise => { - const now = new Date(timestamp * 1e3) - const dayAgo = new Date(now.getTime() - 1000 * 60 * 60 * 24) - const query = ` - SELECT - data, - contract_address, - '${CHAIN.ETHEREUM}' as chain - from - ethereum.core.fact_event_logs - WHERE - contract_address ='${ADDRESSES.ethereum.USDC}' - and topics[0] = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef' - and ( - topics[2] = '0x0000000000000000000000006460d14dbaeb27aefec8ebef85db35defa31c3b9' - or - topics[2] = '0x000000000000000000000000163c5e051049e92915017fe7bb9b8ce6182bcbb1' - ) - AND BLOCK_TIMESTAMP BETWEEN '${dayAgo.toISOString()}' AND '${now.toISOString()}' - union all - SELECT - data, - contract_address, - '${CHAIN.OPTIMISM}' as chain - from - ${CHAIN.OPTIMISM}.core.fact_event_logs - WHERE - contract_address ='${ADDRESSES.optimism.USDC_CIRCLE}' - and topics[0] = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef' - and topics[2] = '0x000000000000000000000000d4ce1f1b8640c1988360a6729d9a73c85a0c80a3' - AND BLOCK_TIMESTAMP BETWEEN '${dayAgo.toISOString()}' AND '${now.toISOString()}' - union all - SELECT - data, - contract_address, - '${CHAIN.POLYGON}' as chain - from - ${CHAIN.POLYGON}.core.fact_event_logs - WHERE - contract_address ='${ADDRESSES.polygon.USDC}' - and topics[0] = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef' - and topics[2] = '0x000000000000000000000000ce946931adf7afc0797de2a76270a28458f487ed' - AND BLOCK_TIMESTAMP BETWEEN '${dayAgo.toISOString()}' AND '${now.toISOString()}' - union all - SELECT - data, - contract_address, - '${CHAIN.ARBITRUM}' as chain - from - ${CHAIN.ARBITRUM}.core.fact_event_logs - WHERE - contract_address ='${ADDRESSES.arbitrum.USDC_CIRCLE}' - and topics[0] = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef' - and topics[2] = '0x000000000000000000000000d4ce1f1b8640c1988360a6729d9a73c85a0c80a3' - AND BLOCK_TIMESTAMP BETWEEN '${dayAgo.toISOString()}' AND '${now.toISOString()}' - ` - const token_tranfer = await queryFlipside(query, 260) - const token_info: tokenInfo[] = token_tranfer.filter((e: any) => e[2] === chain).map((item: any) => { - const token = item[1]; - const amount = Number(item[0]); - return { - token, - amount - } - }) - const coins = [...new Set(token_info.map((item: any) => `${chain}:${item.token}`))]; - const prices = await getPrices(coins, timestamp); - const fees = token_info.reduce((acc: number, item: any) => { - const price = prices[`${chain}:${item.token}`]?.price || 0; - const decimals = prices[`${chain}:${item.token}`]?.decimals || 0; - if (price === 0 || decimals === 0) return acc; - const fee = (Number(item.amount) / 10 ** decimals) * price; - return acc + fee; - }, 0) - const dailyFees = fees; - const dailyRevenue = dailyFees; - const dailyProtocolRevenue = dailyFees; - return { - dailyFees: `${dailyFees}`, - dailyProtocolRevenue: `${dailyProtocolRevenue}`, - dailyRevenue: `${dailyRevenue}`, - timestamp - } - } +const fetch = async (timestamp: number, _: ChainBlocks, options: FetchOptions): Promise => { + const dailyFees = await addTokensReceived({ ...config[options.chain], options}) + return { timestamp, dailyFees, dailyBribesRevenue: dailyFees, dailyRevenue: dailyFees } } const adapters: SimpleAdapter = { adapter: { - [CHAIN.ETHEREUM]: { - fetch: fetchFees(CHAIN.ETHEREUM), - start: 1696896000 - }, - [CHAIN.OPTIMISM]: { - fetch: fetchFees(CHAIN.OPTIMISM), - start: 1696896000 - }, - [CHAIN.POLYGON]: { - fetch: fetchFees(CHAIN.POLYGON), - start: 1696896000 - }, - [CHAIN.ARBITRUM]: { - fetch: fetchFees(CHAIN.ARBITRUM), - start: 1696896000 - } + [CHAIN.ETHEREUM]: { fetch, start: 1696896000 }, + [CHAIN.OPTIMISM]: { fetch, start: 1696896000 }, + [CHAIN.POLYGON]: { fetch, start: 1696896000 }, + [CHAIN.ARBITRUM]: { fetch, start: 1696896000 } } } export default adapters; diff --git a/fees/usdo.ts b/fees/usdo.ts index 80d2e2eff4..b3dae9427d 100644 --- a/fees/usdo.ts +++ b/fees/usdo.ts @@ -36,6 +36,7 @@ const contract_interface = new ethers.Interface([ ]); const fetch = async (timestamp: number): Promise => { + throw new Error("I think neither of these should be counted as fees? or we just count 0.5% of redeemed USDO as fees?") const fromTimestamp = timestamp - 60 * 60 * 24 const toTimestamp = timestamp diff --git a/fees/velodrome-v2/bribes.ts b/fees/velodrome-v2/bribes.ts index b0bbf8019b..b110a111d1 100644 --- a/fees/velodrome-v2/bribes.ts +++ b/fees/velodrome-v2/bribes.ts @@ -1,33 +1,27 @@ import * as sdk from "@defillama/sdk"; -import { CHAIN } from "../../helpers/chains"; +import { FetchOptions } from "../../adapters/types"; const event_notify_reward = 'event NotifyReward(address indexed from,address indexed reward,uint256 indexed epoch,uint256 amount)'; const event_geuge_created = 'event GaugeCreated(address indexed poolFactory,address indexed votingRewardsFactory,address indexed gaugeFactory,address pool,address bribeVotingReward,address feeVotingReward,address gauge,address creator)' -export const fees_bribes = async (fromBlock: number, toBlock: number, _: number): Promise => { - const api = new sdk.ChainApi({ chain: CHAIN.OPTIMISM }); +export const fees_bribes = async ({ getLogs, createBalances, getToBlock }: FetchOptions): Promise => { const voter = '0x41c914ee0c7e1a5edcd0295623e6dc557b5abf3c'; - const logs_geuge_created = (await api.getLogs({ + const dailyFees = createBalances() + const logs_geuge_created = (await getLogs({ target: voter, fromBlock: 105896851, - toBlock: toBlock, - chain: CHAIN.OPTIMISM, - onlyArgs: true, + toBlock: await getToBlock(), eventAbi: event_geuge_created, + cacheInCloud: true, })) const bribes_contract: string[] = logs_geuge_created.map((e: any) => e.bribeVotingReward.toLowerCase()); - const logs = await api.getLogs({ + const logs = await getLogs({ targets: bribes_contract, - toBlock: toBlock, - fromBlock: fromBlock, - chain: CHAIN.OPTIMISM, - onlyArgs: true, eventAbi: event_notify_reward, }) - - logs.forEach((e: any) => { - api.add(e.reward, e.amount) + logs.map((e: any) => { + dailyFees.add(e.reward, e.amount) }) - return api.getUSDValue(); + return dailyFees; } diff --git a/fees/velodrome-v2/index.ts b/fees/velodrome-v2/index.ts index 7d3ffdd02a..2dc4259a76 100644 --- a/fees/velodrome-v2/index.ts +++ b/fees/velodrome-v2/index.ts @@ -1,25 +1,17 @@ -import { Adapter, Fetch, FetchOptions, FetchResultFees } from '../../adapters/types'; -import { CHAIN, OPTIMISM } from '../../helpers/chains'; +import { Adapter, FetchOptions, FetchResultFees } from '../../adapters/types'; +import { OPTIMISM } from '../../helpers/chains'; import { fetchV2 } from './velodrome-v2'; import { fees_bribes } from './bribes'; -import { getBlock } from '../../helpers/getBlock'; const getFees = async (timestamp: number, _, fetchOptions: FetchOptions): Promise => { - const fromTimestamp = timestamp - 60 * 60 * 24 - const toTimestamp = timestamp - const fromBlock = (await getBlock(fromTimestamp, CHAIN.OPTIMISM, {})); - const toBlock = (await getBlock(toTimestamp, CHAIN.OPTIMISM, {})); - const [feeV2, bribes] = await Promise.all([fetchV2(fromBlock, toBlock,timestamp, fetchOptions), fees_bribes(fromBlock, toBlock, timestamp)]); - const dailyFees = Number(feeV2.dailyFees); - const dailyRevenue = Number(feeV2.dailyRevenue); - const dailyHoldersRevenue = Number(feeV2.dailyHoldersRevenue); + const { getFromBlock, getToBlock, } = fetchOptions + const fromBlock = await getFromBlock() + const toBlock = await getToBlock() + const [feeV2, bribes] = await Promise.all([fetchV2(fromBlock, toBlock,timestamp, fetchOptions), fees_bribes(fetchOptions)]); return { - dailyFees: `${dailyFees}`, - dailyRevenue: `${dailyRevenue}`, - dailyHoldersRevenue: `${dailyHoldersRevenue}`, - dailyBribesRevenue: `${bribes}`, - timestamp + ...feeV2, + dailyBribesRevenue: bribes, } } diff --git a/fees/velodrome-v2/velodrome-v2.ts b/fees/velodrome-v2/velodrome-v2.ts index 03670a8fab..0762bfba6d 100644 --- a/fees/velodrome-v2/velodrome-v2.ts +++ b/fees/velodrome-v2/velodrome-v2.ts @@ -4,6 +4,6 @@ import { getDexFees } from "../../helpers/dexVolumeLogs"; const FACTORY_ADDRESS = '0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a'; -export const fetchV2 = async (fromBlock: number, toBlock: number, timestamp: number, fetchOptions: FetchOptions): Promise => { +export const fetchV2 = async (fromBlock: number, toBlock: number, timestamp: number, fetchOptions: FetchOptions): Promise => { return getDexFees({ chain: CHAIN.OPTIMISM, fromBlock, toBlock, factory: FACTORY_ADDRESS, timestamp, lengthAbi: 'allPoolsLength', itemAbi: 'allPools', fetchOptions }) } diff --git a/fees/vesta-finance.ts b/fees/vesta-finance.ts index 3d84552622..2e8af265a2 100644 --- a/fees/vesta-finance.ts +++ b/fees/vesta-finance.ts @@ -1,45 +1,17 @@ -import ADDRESSES from '../helpers/coreAssets.json' -import { Adapter, FetchResultFees } from "../adapters/types"; +import { Adapter, ChainBlocks, FetchOptions, FetchResultFees } 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"; import { Chain } from "@defillama/sdk/build/general"; -import { ethers } from "ethers"; -import { getPrices } from "../utils/prices"; -const topic0_fee_paid = '0x150276cb173fff450b089197a2ff8a9b82d3efbf988df82ba90a00bbe48602f5'; -const topic0_trove_liq = '0x44b1a33c624451b36e8d636828145aa4eb39bd6cc5e2cf623bb270d3abc38c88'; -const topic0_reward_staker = '0x562ff1d6fee77720385c79d29bef3c90c5a796b161826766d09a972bda104a3c'; -const topic0_evt_tranfer = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'; -const topic0_liq = '0xa3f221854f649364e9a3bb384dd1ff938482664f4a0eac0f6e39a542f5193bd3'; -const topic0_redemption = '0x08b6f1ce3f9ab2722e8ea40c31a3e3a806a41702c5994f29af43dc0c1f2837df'; -const topic0_interest_minted = '0x2ee35aad2e33f2a57a13f55b273b9ab5bf3cdd683fe413a7d9e22bcb8b3f67dd'; -const topic0_asset_sent = '0xf89c3306c782ffbbe4593aa5673e97e9ad6a8c65d240405e8986363fada66392'; const event_redemption = 'event Redemption(address indexed _asset,uint256 _attemptedVSTAmount,uint256 _actualVSTAmount,uint256 _AssetSent,uint256 _AssetFee)'; -const event_trove_liq = 'event TroveLiquidated(address indexed _asset,address indexed _borrower,uint256 _debt,uint256 _coll,uint8 operation)'; const event_borrow_fees_paid = 'event VSTBorrowingFeePaid(address indexed _asset,address indexed _borrower,uint256 _VSTFee)'; const event_interate_mint = 'event InterestMinted(address indexed module,uint256 interestMinted)'; const event_liq_event = 'event Liquidation(address indexed _asset,uint256 _liquidatedDebt,uint256 _liquidatedColl,uint256 _collGasCompensation,uint256 _VSTGasCompensation)'; -const event_asset_sent = 'event AssetSent(address _to,address indexed _asset,uint256 _amount)'; const event_reward_staker = 'event RewardReceived(uint256 reward)'; const VST_ADDRESS = "0x64343594ab9b56e99087bfa6f2335db24c2d1f17"; -const ACTIVE_POOL_ADDRESS = "0xbe3de7fb9aa09b3fa931868fb49d5ba5fee2ebb1"; -const ZERO_ADDRESS = ADDRESSES.null; const GMX_STAKER = "0xB9b8f95568D5a305c6D70D10Cc1361d9Df3e9F9a"; const GLP_STAKER = "0xDB607928F10Ca503Ee6678522567e80D8498D759"; -const ETHEREUM = ADDRESSES.arbitrum.WETH; -const contract_interface = new ethers.Interface([ - event_redemption, - event_trove_liq, - event_borrow_fees_paid, - event_interate_mint, - event_liq_event, - event_asset_sent, - event_reward_staker, -]); type TAddress = { [l: string | Chain]: string; @@ -54,200 +26,33 @@ const invest_addres: TAddress = { [CHAIN.ARBITRUM]: '0x0f5d5e424765bf3b49f932f0e9b8e6f3791d33b1' } -interface ITx { - data: string; - transactionHash: string; - topics: string[]; -} - -interface IOutput { - asset: string; - fees: number; - tx?: string; - to?: string; -} - const fetch = (chain: Chain) => { - return async (timestamp: number): Promise => { - const todaysTimestamp = getTimestampAtStartOfDayUTC(timestamp) - const yesterdaysTimestamp = getTimestampAtStartOfNextDayUTC(timestamp) - - const fromBlock = (await getBlock(todaysTimestamp, chain, {})); - const toBlock = (await getBlock(yesterdaysTimestamp, chain, {})); - const fee_paid_logs: number[] = (await sdk.getEventLogs({ - target: address[chain], - fromBlock: fromBlock, - toBlock: toBlock, - topics: [topic0_fee_paid], - chain: chain - })) - .map((e: any) => { return { data: e.data, transactionHash: e.transactionHash, topics: e.topics } as ITx }) - .map((e: any) => contract_interface.parseLog(e)) - .map((e: any) => Number(e!.args._VSTFee) / 10 ** 18); - - - const redemption_logs: IOutput[] = (await sdk.getEventLogs({ - target: troveMagaer[chain], - fromBlock: fromBlock, - toBlock: toBlock, - topics: [topic0_redemption], - chain: chain - })).map((e: any) => { return { data: e.data, transactionHash: e.transactionHash, topics: e.topics } as ITx }) - .map((e: any) => { return { ...contract_interface.parseLog(e), ...e } }) - .map((e: any) => { - return { - asset: e!.args._asset, - fees: Number(e!.args._AssetFee), - tx: e.transactionHash - } - }); - - const liq_logs: any[] = (await sdk.getEventLogs({ - target: troveMagaer[chain], - fromBlock: fromBlock, - toBlock: toBlock, - topics: [topic0_liq], - chain: chain - })).map((e: any) => { return { data: e.data, transactionHash: e.transactionHash, topics: e.topics } as ITx }) - .map((e: any) => { return { ...contract_interface.parseLog(e), ...e } }) - .map((e: any) => { - return { - asset: e!.args._asset, - fees: Number(e!.args._liquidatedColl), - tx: e.transactionHash - } - }); - const liq_hash = liq_logs.map((e: any) => e.tx.toLowerCase()) - const vst_burn_amount: number = (await Promise.all( - liq_logs.map((e: IOutput) => sdk.getEventLogs({ - target: VST_ADDRESS, - fromBlock: fromBlock, - toBlock: toBlock, - topics: [ - topic0_evt_tranfer, - ethers.zeroPadValue(hexStripZeros(e.asset), 32), - ethers.zeroPadValue(hexStripZeros(ZERO_ADDRESS), 32)], - chain: chain, - })))).map((e: any) => e.map((p: any) => { - return { - data: p.data, - transactionHash: p.transactionHash - } as ITx - })) - .flat() - .filter((e: ITx) => liq_hash.includes(e.transactionHash.toLowerCase())) - .map((e: ITx) => { - return Number(e.data) / 10 ** 18; - }).reduce((a: number, b: number) => a + b, 0); + return async (timestamp: number, _: ChainBlocks, { createBalances, getLogs, }: FetchOptions): Promise => { + const dailyFees = createBalances(); + (await getLogs({ target: address[chain], eventAbi: event_borrow_fees_paid })).forEach((e: any) => { + dailyFees.add(VST_ADDRESS, e._VSTFee) + }); - const asset_liq = liq_logs.map((e: IOutput) => e.asset.toLowerCase()) - const asset_sent_logs: any[] = (await sdk.getEventLogs({ - target: ACTIVE_POOL_ADDRESS, - fromBlock: fromBlock, - toBlock: toBlock, - topics: [ - topic0_asset_sent - ], - chain: chain, - })) - .map((e: any) => { return { data: e.data, transactionHash: e.transactionHash, topics: e.topics } as ITx }) - .filter((e: ITx) => liq_hash.includes(e.transactionHash.toLowerCase())) - .map((e: any) => { return { ...contract_interface.parseLog(e), ...e } }) - .filter((e: any) => asset_liq.includes(e!.args._to.toLowerCase())) - .map((e: any) => { - return { - asset: e!.args._asset, - fees: Number(e!.args._amount), - tx: e.transactionHash - } - }); + (await getLogs({ target: invest_addres[chain], eventAbi: event_interate_mint })).forEach((e: any) => { + dailyFees.add(VST_ADDRESS, e.interestMinted) + }); - // const liq_trove_logs: IOutput[] = (await sdk.getEventLogs({ - // target: troveMagaer[chain], - // fromBlock: fromBlock, - // toBlock: toBlock, - // topics: [topic0_trove_liq], - // chain: chain - // })).map((e: any) => { return { data: e.data, transactionHash: e.transactionHash, topics: e.topics } as ITx}) - // .map((e: any) => contract_interface.parseLog(e)) - // .map((e: any) => { - // return { - // asset: e!.args._asset, - // fees: Number(e!.args._debt) - // } - // }); + (await getLogs({ target: troveMagaer[chain], eventAbi: event_redemption })).forEach((e: any) => { + dailyFees.add(e._asset, e._AssetFee) + }); - const reward_gmx_staker: number[] = (await sdk.getEventLogs({ - target: GMX_STAKER, - fromBlock: fromBlock, - toBlock: toBlock, - topics: [topic0_reward_staker], - chain: chain - })) - .map((e: any) => { return { data: e.data, transactionHash: e.transactionHash, topics: e.topics } as ITx }) - .map((e: any) => contract_interface.parseLog(e)) - .map((e: any) => Number(e!.args.reward) / 10 ** 18); + (await getLogs({ target: troveMagaer[chain], eventAbi: event_liq_event })).forEach((e: any) => { + dailyFees.add(e._asset, e._liquidatedColl) + dailyFees.add(VST_ADDRESS, e._liquidatedDebt * -1) + }); - const reward_glp_staker: number[] = (await sdk.getEventLogs({ - target: GLP_STAKER, - fromBlock: fromBlock, - toBlock: toBlock, - topics: [topic0_reward_staker], - chain: chain - })) - .map((e: any) => { return { data: e.data, transactionHash: e.transactionHash, topics: e.topics } as ITx }) - .map((e: any) => contract_interface.parseLog(e)) - .map((e: any) => Number(e!.args.reward) / 10 ** 18); + (await getLogs({ target: GMX_STAKER, eventAbi: event_reward_staker, })) + .map((e: any) => { dailyFees.addGasToken(e.reward) }); - const interate_mint_logs = (await sdk.getEventLogs({ - target: invest_addres[chain], - fromBlock: fromBlock, - toBlock: toBlock, - topics: [topic0_interest_minted], - chain: chain - })).map((e: any) => { return { data: e.data, transactionHash: e.transactionHash, topics: e.topics } as ITx }) - .map((e: any) => contract_interface.parseLog(e)) - .map((e: any) => Number(e!.args.interestMinted) / 10 ** 18); + (await getLogs({ target: GLP_STAKER, eventAbi: event_reward_staker, })) + .map((e: any) => { dailyFees.addGasToken(e.reward) }); - const rawCoins = [ - ...redemption_logs.map((e: IOutput) => e.asset), - VST_ADDRESS, - ETHEREUM - ].map((e: string) => `${chain}:${e.toLowerCase()}`); - const coins = [...new Set(rawCoins)] - const prices = await getPrices(coins, timestamp); - const vst_price = prices[`${chain}:${VST_ADDRESS.toLowerCase()}`].price; - const ether_price = prices[`${chain}:${ETHEREUM.toLowerCase()}`].price; - - const redemption_fees = redemption_logs.map((e: IOutput) => { - const price = prices[`${chain}:${e.asset.toLowerCase()}`]; - return (e.fees / 10 ** price.decimals) * price.price; - }).reduce((a: number, b: number) => a + b, 0); - - - // const liq_trove_fees = liq_trove_logs.map((e: IOutput) => { - // const price = prices[`${chain}:${e.asset.toLowerCase()}`]; - // return (e.fees / 10 ** price.decimals) * price.price; - // }).reduce((a: number, b: number) => a+b,0); - - const asset_sent = asset_sent_logs.map((e: IOutput) => { - const price = prices[`${chain}:${e.asset.toLowerCase()}`]; - return (e.fees / 10 ** price.decimals) * price.price; - }).reduce((a: number, b: number) => a + b, 0); - - // const liq_trove_fees_usd = liq_trove_fees * (0.5 / 100) + 30; - const reward_received = [...reward_gmx_staker, ...reward_glp_staker].reduce((a: number, b: number) => a + b, 0) - const reward_received_usd = reward_received * ether_price; - const borrow_paid_fees = fee_paid_logs.reduce((a: number, b: number) => a + b, 0); - const interate_mint_fees = interate_mint_logs.reduce((e: number, b: number) => e + b, 0) - const vst_burn_amount_usd = vst_price * vst_burn_amount; - const liq_fees_usd = asset_sent - vst_burn_amount_usd; - const dailyFees = (borrow_paid_fees + interate_mint_fees + redemption_fees + liq_fees_usd + reward_received_usd); - return { - dailyFees: dailyFees.toString(), - dailyRevenue: dailyFees.toString(), - timestamp - } + return { dailyFees, dailyRevenue: dailyFees, timestamp } } } @@ -260,12 +65,4 @@ const adapter: Adapter = { } } -export default adapter; - - -function hexStripZeros(value: string): string { - value = value.substring(2); - let offset = 0; - while (offset < value.length && value[offset] === "0") { offset++; } - return "0x" + value.substring(offset); -} \ No newline at end of file +export default adapter; \ No newline at end of file diff --git a/fees/zonic.ts b/fees/zonic.ts index 223e2b02fd..8e9386df20 100644 --- a/fees/zonic.ts +++ b/fees/zonic.ts @@ -1,13 +1,7 @@ -import ADDRESSES from '../helpers/coreAssets.json' -import { Adapter, FetchResultFees } from "../adapters/types"; +import { Adapter, ChainBlocks, FetchOptions, FetchResultFees } from "../adapters/types"; import { CHAIN } from "../helpers/chains"; -import { getTimestampAtStartOfDayUTC, getTimestampAtStartOfNextDayUTC } from "../utils/date"; -import * as sdk from "@defillama/sdk"; -import { getPrices } from "../utils/prices"; -import { getBlock } from "../helpers/getBlock"; import { Chain } from "@defillama/sdk/build/general"; -const topic0 = '0x31d8f0f884ca359b1c76fda3fd0e25e5f67c2a5082158630f6f3900cb27de467'; type TMarketPlaceAddress = { [l: string | Chain]: string; @@ -22,66 +16,27 @@ const marketplace_address: TMarketPlaceAddress = { [CHAIN.LINEA]: '0x1A7b46C660603EBB5FBe3AE51e80AD21dF00bDd1' } -interface ITx { - data: string; - transactionHash: string; -} - -interface ISaleData { - contract_address: string; - amount: number; - creator_fee: number; - marketplace_fee: number; -} - const fetch = (chain: Chain) => { - return async (timestamp: number): Promise => { - const todaysTimestamp = getTimestampAtStartOfDayUTC(timestamp) - const yesterdaysTimestamp = getTimestampAtStartOfNextDayUTC(timestamp) - - const fromBlock = (await getBlock(todaysTimestamp, chain, {})); - const toBlock = (await getBlock(yesterdaysTimestamp, chain, {})); - const logs: ITx[] = (await sdk.getEventLogs({ + return async (timestamp: number, _: ChainBlocks, { createBalances, getLogs, }: FetchOptions): Promise => { + const dailyFees = createBalances() + const dailyRevenue = createBalances(); + (await getLogs({ target: marketplace_address[chain], - fromBlock: fromBlock, - toBlock: toBlock, - topics: [topic0], - chain: chain - })).map((e: any) => { return { data: e.data.replace('0x', ''), transactionHash: e.transactionHash } as ITx}); - - const rawLogsData: ISaleData[] = logs.map((tx: ITx) => { - const amount = Number('0x' + tx.data.slice(320, 384)) / 10 ** 18; - const creator_fee = Number('0x' + tx.data.slice(384, 448)) / 10 ** 18; - const marketplace_fee = Number('0x' + tx.data.slice(448, 512)) / 10 ** 18; - const address = tx.data.slice(128, 192); - const contract_address = '0x' + address.slice(24, address.length); - return { - amount: amount, - contract_address: contract_address, - creator_fee: creator_fee, - marketplace_fee: marketplace_fee - } as ISaleData - }); - - const ethAddress = "ethereum:" + ADDRESSES.null; - const ethPrice = (await getPrices([ethAddress], timestamp))[ethAddress].price; - const marketplace_fee = rawLogsData.reduce((a: number, b: ISaleData) => a+b.marketplace_fee, 0); - const creator_fee = rawLogsData.reduce((a: number, b: ISaleData) => a+b.creator_fee, 0); - const dailyFees = (marketplace_fee + creator_fee) * ethPrice; - const dailyRevenue = (marketplace_fee) * ethPrice; - return { - dailyFees: dailyFees.toString(), - dailyRevenue: dailyRevenue.toString(), - timestamp - } + eventAbi: 'event ZonicBasicOrderFulfilled (address offerer, address buyer, address token, uint256 identifier, address currency, uint256 totalPrice, uint256 creatorFee, uint256 marketplaceFee, address saleId)' + })).forEach((e: any) => { + dailyFees.addGasToken(e.marketplaceFee) + dailyFees.addGasToken(e.creatorFee) + dailyRevenue.addGasToken(e.marketplaceFee) + }) + return { dailyFees, dailyRevenue, timestamp } } } const adapter: Adapter = { adapter: { [CHAIN.OPTIMISM]: { - fetch: fetch(CHAIN.OPTIMISM), - start: 1675382400, + fetch: fetch(CHAIN.OPTIMISM), + start: 1675382400, }, [CHAIN.ARBITRUM]: { fetch: fetch(CHAIN.ARBITRUM), diff --git a/helpers/dexVolumeLogs.ts b/helpers/dexVolumeLogs.ts index d12c2f2d2b..c685be3a5d 100644 --- a/helpers/dexVolumeLogs.ts +++ b/helpers/dexVolumeLogs.ts @@ -1,18 +1,18 @@ import { FetchOptions } from "../adapters/types"; -const swapEvent = "event Swap(address indexed sender, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out, address indexed to)" +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[], fetchOptions: FetchOptions, } +type getDexVolumeParams = { chain: string, fromTimestamp: number, toTimestamp?: number, factory?: string, timestamp: number, pools?: string[], fetchOptions: FetchOptions, pairLengthAbi?: string, pairItemAbi?: string, swapEvent?: string, } 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 getDexVolumeExportsParamsV3 = { chain: string, factory?: string, pools?: string[], factoryFromBlock?: number, } +type getDexVolumeExportsParams = { chain: string, factory?: string, pools?: string[], pairLengthAbi?: string, pairItemAbi?: string, } +type getDexVolumeExportsParamsV3 = { chain: string, factory?: string, pools?: string[], factoryFromBlock?: number, swapEvent?: string, } -export async function getDexVolume({ factory, timestamp, pools, fetchOptions, }: getDexVolumeParams) { +export async function getDexVolume({ factory, timestamp, pools, fetchOptions, pairLengthAbi = 'allPairsLength', pairItemAbi = 'allPairs', swapEvent = _swapEvent }: getDexVolumeParams) { const { api } = fetchOptions; - if (!pools) pools = await api.fetchList({ lengthAbi: 'allPairsLength', itemAbi: 'allPairs', target: factory! }) + if (!pools) pools = await api.fetchList({ lengthAbi: pairLengthAbi, itemAbi: pairItemAbi, target: factory! }) const token0s = await api.multiCall({ abi: 'address:token0', calls: pools! }) const token1s = await api.multiCall({ abi: 'address:token1', calls: pools! }) @@ -33,10 +33,9 @@ export async function getDexVolume({ factory, timestamp, pools, fetchOptions, }: api.add(token1, i.amount1Out) }) }) - const { usdTvl } = await api.getUSDJSONs() return { timestamp, - dailyVolume: Number(usdTvl).toFixed(0), + dailyVolume: api.getBalancesV2(), } } @@ -57,7 +56,7 @@ export async function getDexFees({ factory, timestamp, pools, lengthAbi = 'allPa if (!pools) pools = await api.fetchList({ lengthAbi, itemAbi, target: factory! }) const token0s = await api.multiCall({ abi: 'address:token0', calls: pools!, permitFailure: true, }) - const token1s = await api.multiCall({ abi: 'address:token1', calls: pools!, permitFailure: true, }) + const token1s = await api.multiCall({ abi: 'address:token1', calls: pools!, permitFailure: true, }) const logs = await fetchOptions.getLogs({ targets: pools, @@ -73,8 +72,7 @@ export async function getDexFees({ factory, timestamp, pools, lengthAbi = 'allPa api.add(token1, i.amount1) }) }) - const { usdTvl } = await api.getUSDJSONs() - const value = Number(usdTvl).toFixed(0) + const value = api.getBalancesV2() return { timestamp, dailyFees: value, @@ -130,7 +128,7 @@ export async function getDexVolumeFeeV3({ factory, timestamp, pools, factoryFrom }) return { timestamp, - dailyVolume: await api.getUSDString(), + dailyVolume: await api.getBalancesV2(), } } diff --git a/helpers/getChainFees.ts b/helpers/getChainFees.ts index 37a2f4f602..59fbaa7b99 100644 --- a/helpers/getChainFees.ts +++ b/helpers/getChainFees.ts @@ -9,10 +9,7 @@ export const chainAdapter = (adapterKey: string, assetID: string, startTime: num return { timestamp, - dailyFees: dailyFee.toString(), - totalRevenue: "0", - dailyRevenue: "0", - dailyHoldersRevenue: "0", + dailyFees: dailyFee, }; }; diff --git a/helpers/solidly.ts b/helpers/solidly.ts new file mode 100644 index 0000000000..bb685c2a46 --- /dev/null +++ b/helpers/solidly.ts @@ -0,0 +1,75 @@ +import ADDRESSES from './coreAssets.json' +import { ChainBlocks, FetchOptions, FetchResultFees, } from "../adapters/types"; + +const TOPIC_Notify = 'event NotifyReward(address indexed from, address indexed reward, uint indexed epoch, uint amount)'; + +type TABI = { + [k: string]: string; +} +const ABIs: TABI = { + "allPairsLength": "uint256:allPairsLength", + "allPairs": "function allPairs(uint256) view returns (address)" +} + +const VOTER_ABI: TABI = { + "length": "uint256:length", + "pools": "function pools(uint256) view returns (address)", + "gauges": "function gauges(address) view returns (address)", + "bribes": "function bribes(address) view returns (address)" +} + +export function getFeesExport({ VOTER_ADDRESS, FACTORY_ADDRESS, }: { VOTER_ADDRESS: string, FACTORY_ADDRESS: string }) { + return async (timestamp: number, _: ChainBlocks, { createBalances, api, getLogs, }: FetchOptions): Promise => { + + const dailyFees = createBalances() + const dailyRevenue = createBalances() + const dailyBribesRevenue = createBalances() + + const lpTokens = await api.fetchList({ lengthAbi: ABIs.allPairsLength, itemAbi: ABIs.allPairs, target: FACTORY_ADDRESS }); + + const [tokens0, tokens1] = await Promise.all( + ['address:token0', 'address:token1'].map((method) => api.multiCall({ abi: method, calls: lpTokens, })) + ); + + + const poolsGauges = await api.multiCall({ abi: VOTER_ABI.gauges, target: VOTER_ADDRESS, calls: lpTokens, }); + + const voterGauges = poolsGauges.filter((_vg: string) => _vg !== ADDRESSES.null); + + const voterBribes = await api.multiCall({ + abi: VOTER_ABI.bribes, target: VOTER_ADDRESS, + calls: voterGauges, + }); + + + const tradefeeLogs = await getLogs({ + targets: lpTokens, + flatten: false, + eventAbi: 'event Fees (address indexed sender, uint256 amount0, uint256 amount1)' + }) + + const bribeAndFeeLogs = await getLogs({ targets: voterBribes, eventAbi: TOPIC_Notify, flatten: false, }) + bribeAndFeeLogs.forEach((e: any, idx: number) => { + const voterGauge = voterGauges[idx].toLowerCase() + e.forEach((l: any) => { + if (l.from.toLowerCase() !== voterGauge) + dailyBribesRevenue.add(l.reward, l.amount) + else + dailyRevenue.add(l.reward, l.amount) + + }) + }) + + lpTokens.map((_: string, index: number) => { + const token0 = tokens0[index] + const token1 = tokens1[index] + tradefeeLogs[index] + .map((p: any) => { + dailyFees.add(token0, p.amount0) + dailyFees.add(token1, p.amount1) + }) + }); + + return { dailyFees, dailyRevenue: dailyRevenue, dailyHoldersRevenue: dailyRevenue, dailyBribesRevenue, timestamp, }; + } +} diff --git a/helpers/token.ts b/helpers/token.ts index 72accd5466..6959343899 100644 --- a/helpers/token.ts +++ b/helpers/token.ts @@ -4,6 +4,7 @@ import * as sdk from '@defillama/sdk' import axios from 'axios' import { getCache, setCache } from "./cache"; import { ethers } from "ethers"; +import { getUniqueAddresses } from '@defillama/sdk/build/generalUtil'; export const nullAddress = ADDRESSES.null @@ -73,6 +74,8 @@ export async function addTokensReceived(params: { if (!tokens?.length) return balances + tokens = getUniqueAddresses(tokens, options.chain) + const toAddressFilter = target ? ethers.zeroPadValue(target, 32) : null if (fromAddressFilter) fromAddressFilter = ethers.zeroPadValue(fromAddressFilter, 32) const logs = await getLogs({