diff --git a/adapters/types.ts b/adapters/types.ts index c78e9f45d7..40f29e3a95 100644 --- a/adapters/types.ts +++ b/adapters/types.ts @@ -39,6 +39,7 @@ export type FetchGetLogsOptions = { toBlock?: number, flatten?: boolean, cacheInCloud?: boolean, + skipCacheRead?: boolean, topics?: string[], } diff --git a/adapters/utils/runAdapter.ts b/adapters/utils/runAdapter.ts index e3eb004626..4a5a7a09f1 100644 --- a/adapters/utils/runAdapter.ts +++ b/adapters/utils/runAdapter.ts @@ -54,11 +54,11 @@ export default async function runAdapter(volumeAdapter: BaseAdapter, cleanCurren const fromChainBlocks = {} const getFromBlock = async () => await getBlock(fromTimestamp, chain, fromChainBlocks) const getToBlock = async () => await getBlock(toTimestamp, chain, chainBlocks) - const getLogs = async ({ target, targets, onlyArgs = true, fromBlock, toBlock, flatten = true, eventAbi, topics, topic, cacheInCloud = false, }: FetchGetLogsOptions) => { + const getLogs = async ({ target, targets, onlyArgs = true, fromBlock, toBlock, flatten = true, eventAbi, topics, topic, cacheInCloud = false, skipCacheRead = false,}: FetchGetLogsOptions) => { fromBlock = fromBlock ?? await getFromBlock() toBlock = toBlock ?? await getToBlock() - return getEventLogs({ fromBlock, toBlock, chain, target, targets, onlyArgs, flatten, eventAbi, topics, topic, cacheInCloud, }) + return getEventLogs({ fromBlock, toBlock, chain, target, targets, onlyArgs, flatten, eventAbi, topics, topic, cacheInCloud, skipCacheRead, }) } return { diff --git a/aggregators/aggre/index.ts b/aggregators/aggre/index.ts index 4da32796c2..15b4cd4bc3 100644 --- a/aggregators/aggre/index.ts +++ b/aggregators/aggre/index.ts @@ -1,8 +1,6 @@ import { Chain } from "@defillama/sdk/build/general"; -import { FetchResultAggregators, SimpleAdapter } from "../../adapters/types"; -import { getBlock } from "../../helpers/getBlock"; +import { FetchOptions, FetchResultAggregators, SimpleAdapter } from "../../adapters/types"; import { CHAIN } from "../../helpers/chains"; -import * as sdk from "@defillama/sdk"; let abi = ["event SwapExecuted(address indexed user, address tokenIn, address tokenOut, uint amountIn, uint amountOut, uint swapType)"]; @@ -14,34 +12,13 @@ const contract: IContract = { [CHAIN.SCROLL]: '0xcf8bcaCb401C31774EA39296b367B9DaB4F72267', } -const fetch = (chain: Chain) => { - return async (timestamp: number): Promise => { - const fromTimestamp = timestamp - 60 * 60 * 24; - const toTimestamp = timestamp; - - - const api = new sdk.ChainApi({ chain, timestamp }); - const fromBlock = (await getBlock(fromTimestamp, chain, {})); - const toBlock = (await getBlock(toTimestamp, chain, {})); - const logs = (await api.getLogs({ - target: contract[chain], - toBlock: toBlock, - fromBlock: fromBlock, - chain, - eventAbi: abi[0], - onlyArgs: true, - })) - - logs.map((parsed: any) => { - api.add(parsed.tokenOut, parsed.amountOut) - }); - const VUSD = Number(await api.getUSDValue()).toFixed(0); +const fetch: any = async (timestamp: number, _, { getLogs, createBalances, chain, }: FetchOptions): Promise => { + const dailyVolume = createBalances(); + const logs = (await getLogs({ target: contract[chain], eventAbi: abi[0], })) - return { - dailyVolume: VUSD, - timestamp, - }; - }; + logs.map((log: any) => dailyVolume.add(log.tokenOut, log.amountOut)); + + return { dailyVolume, timestamp, }; }; const adapter: SimpleAdapter = { @@ -49,7 +26,7 @@ const adapter: SimpleAdapter = { return { ...acc, [chain]: { - fetch: fetch(chain), + fetch, start: 1698660910, } } diff --git a/aggregators/jumper-exchange/index.ts b/aggregators/jumper-exchange/index.ts index d33088dbb5..5ee72a6b3d 100644 --- a/aggregators/jumper-exchange/index.ts +++ b/aggregators/jumper-exchange/index.ts @@ -1,7 +1,6 @@ import { Chain } from "@defillama/sdk/build/general"; -import { FetchResultVolume, SimpleAdapter } from "../../adapters/types"; +import { FetchOptions, FetchResultVolume, SimpleAdapter } from "../../adapters/types"; import { CHAIN } from "../../helpers/chains"; -import * as sdk from "@defillama/sdk"; type IContract = { [c: string | Chain]: string; @@ -18,44 +17,22 @@ const contract: IContract = { [CHAIN.POLYGON_ZKEVM]: '0x1231deb6f5749ef6ce6943a275a1d3e7486f4eae', [CHAIN.FANTOM]: '0x1231deb6f5749ef6ce6943a275a1d3e7486f4eae' } -interface IData { - integrator: string; - fromAssetId: string; - toAssetId: string; - fromAmount: number; - toAmount: number; -} -const fetch = (chain: Chain) => { - return async (timestamp: number): Promise => { - const fromTimestamp = timestamp - 60 * 60 * 24; - const toTimestamp = timestamp; - const api = new sdk.ChainApi({ chain, timestamp }); - const data: IData[] = (await api.getLogs({ - target: contract[chain], - fromTimestamp, toTimestamp, - chain: chain, - onlyArgs: true, - eventAbi: 'event LiFiGenericSwapCompleted(bytes32 indexed transactionId, string integrator, string referrer, address receiver, address fromAssetId, address toAssetId, uint256 fromAmount, uint256 toAmount)' - })) as any - console.log(data.length, chain) - data.forEach((e: IData) => api.add(e.toAssetId, e.toAmount)); - const { usdTvl } = await api.getUSDJSONs() - return { - dailyVolume: Number(usdTvl).toFixed(0), - timestamp, - } as any; - }; +const fetch: any = async (timestamp: number, _, { chain, getLogs, createBalances, }: FetchOptions): Promise => { + const dailyVolume = createBalances(); + const data: any[] = await getLogs({ + target: contract[chain], + eventAbi: 'event LiFiGenericSwapCompleted(bytes32 indexed transactionId, string integrator, string referrer, address receiver, address fromAssetId, address toAssetId, uint256 fromAmount, uint256 toAmount)' + }) + data.forEach((e: any) => dailyVolume.add(e.toAssetId, e.toAmount)); + return { dailyVolume, timestamp, } as any; }; const adapter: SimpleAdapter = { adapter: Object.keys(contract).reduce((acc, chain) => { return { ...acc, - [chain]: { - fetch: fetch(chain), - start: 1691625600, - } + [chain]: { fetch, start: 1691625600, } } }, {}) }; diff --git a/dexs/hummus/index.ts b/dexs/hummus/index.ts index 17eecc468f..1e71a712bc 100644 --- a/dexs/hummus/index.ts +++ b/dexs/hummus/index.ts @@ -1,85 +1,26 @@ -import { DISABLED_ADAPTER_KEY, FetchResult, SimpleAdapter } from "../../adapters/types"; +import { DISABLED_ADAPTER_KEY, FetchOptions, FetchResult, SimpleAdapter } from "../../adapters/types"; import { CHAIN } from "../../helpers/chains"; import disabledAdapter from "../../helpers/disabledAdapter"; -import { getBlock } from "../../helpers/getBlock"; -import { getUniqStartOfTodayTimestamp } from "../../helpers/getUniSubgraphVolume"; -import * as sdk from "@defillama/sdk"; -import * as ethers from "ethers"; - -interface ILog { - data: string; - transactionHash: string; - topics: string[]; -} const abi_event = { swap: "event Swap(address indexed sender, address fromToken, address toToken, uint256 fromAmount, uint256 toAmount, address indexed to)", }; -const abi_event_interface = new ethers.Interface( - Object.values(abi_event) -); - -const swap_topic = - "0x54787c404bb33c88e86f4baf88183a3b0141d0a848e6a9f7a13b66ae3a9b73d1"; - -const tokens = [ - "0xEA32A96608495e54156Ae48931A7c20f0dcc1a21", - "0xbB06DCA3AE6887fAbF931640f67cab3e3a16F4dC", - "0x4c078361FC9BbB78DF910800A991C7c3DD2F6ce0", -]; -const decimals = [6, 6, 18]; - -const fetch = async (timestamp: number): Promise => { - const dayTimestamp = getUniqStartOfTodayTimestamp(new Date(timestamp * 1000)); - const dayID = dayTimestamp / 86400; - - const fromBlock = await getBlock((dayID - 1) * 86400, CHAIN.METIS, {}); - const toBlock = await getBlock(dayID * 86400, CHAIN.METIS, {}); - - const logs: ILog[] = ( - await Promise.resolve( - sdk.getEventLogs({ - target: "0x248fD66e6ED1E0B325d7b80F5A7e7d8AA2b2528b", - toBlock: toBlock, - fromBlock: fromBlock, - chain: CHAIN.METIS, - topics: [swap_topic], - }) - ) - ) as ILog[]; - - let dailyVolume = 0; - - logs.forEach((log) => { - const args = abi_event_interface.parseLog(log)!.args; - let vol = 0; - let tokenIndex = -1; - - if (args.fromAmount < args.toAmount) { - tokenIndex = tokens.findIndex((address) => address === args.fromToken); - vol = args.fromAmount / 10 ** decimals[tokenIndex]; - } else { - tokenIndex = tokens.findIndex((address) => address === args.toToken); - vol = args.toAmount / 10 ** decimals[tokenIndex]; - } - if (!isNaN(vol)) { - dailyVolume += vol; - } - }); +const fetch: any = async (timestamp: number, _, { getLogs, createBalances, toTimestamp }: FetchOptions) => { + const dailyVolume = createBalances(); + const logs: any[] = await getLogs({ target: "0x248fD66e6ED1E0B325d7b80F5A7e7d8AA2b2528b", eventAbi: abi_event.swap, }) + console.log(logs, logs.length) + logs.forEach((log: any) => dailyVolume.add(log.toToken, Number(log.toAmount))); - return { - dailyVolume: dailyVolume ? `${dailyVolume}` : undefined, - timestamp: dayTimestamp, - }; + return { dailyVolume, timestamp: toTimestamp, }; }; const adapter: SimpleAdapter = { adapter: { [DISABLED_ADAPTER_KEY]: disabledAdapter, [CHAIN.METIS]: { - fetch: fetch, + fetch, start: 1661900400, }, }, diff --git a/dexs/joe-v2.1/index.ts b/dexs/joe-v2.1/index.ts index 064290a219..5859561aa1 100644 --- a/dexs/joe-v2.1/index.ts +++ b/dexs/joe-v2.1/index.ts @@ -1,26 +1,7 @@ -import { SimpleAdapter } from "../../adapters/types"; +import { 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 { - amountInX: number; - amountInY: number; -} const event_swap = 'event Swap(address indexed sender,address indexed to,uint24 id,bytes32 amountsIn,bytes32 amountsOut,uint24 volatilityAccumulator,bytes32 totalFees,bytes32 protocolFees)'; -const topic0 = '0xad7d6f97abf51ce18e17a38f4d70e975be9c0708474987bb3e26ad21bd93ca70'; - -const contract_interface = new ethers.Interface([ - event_swap -]); type TPool = { [c: string]: string[]; @@ -66,86 +47,38 @@ const pools: TPool = { ] } -const graph = (chain: Chain) => { - return async (timestamp: number) => { - const fromTimestamp = timestamp - 60 * 60 * 24 - const toTimestamp = timestamp - const lpTokens = pools[chain] - const [underlyingToken0, underlyingToken1] = await Promise.all( - ['address:getTokenX', 'address:getTokenY'].map((abi: string) => - sdk.api2.abi.multiCall({ - abi, - calls: lpTokens, - chain: chain - }) - ) - ); - - const tokens0 = underlyingToken0; - const tokens1 = underlyingToken1; - const fromBlock = (await getBlock(fromTimestamp, chain, {})); - const toBlock = (await getBlock(toTimestamp, chain, {})); - - const logs: ILog[][] = (await Promise.all(lpTokens.map((address: string) => sdk.getEventLogs({ - target: address, - toBlock: toBlock, - fromBlock: fromBlock, - chain: chain, - topics: [topic0] - })))) as ILog[][]; +const fetch: any = async (timestamp: number, _, { api, chain, getLogs, createBalances, }: FetchOptions) => { + const dailyVolume = createBalances(); + const lpTokens = pools[chain] + const [tokens0, tokens1] = await Promise.all( + ['address:getTokenX', 'address:getTokenY'].map((abi: string) => + api.multiCall({ abi, calls: lpTokens, }) ) + ); - const rawCoins = [...tokens0, ...tokens1].map((e: string) => `${chain}:${e}`); - const coins = [...new Set(rawCoins)] - const prices = await getPrices(coins, timestamp); + const logs: any[][] = (await getLogs({ + targets: lpTokens, + eventAbi: event_swap, + flatten: false, + })) - - const untrackVolumes: number[] = lpTokens.map((_: string, index: number) => { - const token0Decimals = prices[`${chain}:${tokens0[index]}`]?.decimals || 0 - const token1Decimals = prices[`${chain}:${tokens1[index]}`]?.decimals || 0 - const log: IAmount[] = logs[index] - .map((e: ILog) => { return { ...e } }) - .map((p: ILog) => { - const value = contract_interface.parseLog(p); - const amountInX = Number('0x' + '0'.repeat(32) + value!.args.amountsIn.replace('0x', '').slice(0, 32)) / 10 ** token1Decimals - const amountInY = Number('0x' + '0'.repeat(32) + value!.args.amountsIn.replace('0x', '').slice(32, 64)) / 10 ** token0Decimals - return { - amountInX, - amountInY, - } as IAmount - }) as IAmount[]; - - const token0Price = (prices[`${chain}:${tokens0[index]}`]?.price || 0); - const token1Price = (prices[`${chain}:${tokens1[index]}`]?.price || 0); - const totalAmountInX = log - .reduce((a: number, b: IAmount) => Number(b.amountInX) + a, 0) * token1Price; - const totalAmountInY = log - .reduce((a: number, b: IAmount) => Number(b.amountInY) + a, 0) * token0Price; - const untrackAmountUSD = (totalAmountInX + totalAmountInY); // counted only we have price data - return untrackAmountUSD; - }); - const dailyVolume = untrackVolumes.reduce((a: number, b: number) => a + b, 0); - return { - dailyVolume: `${dailyVolume}`, - timestamp, - }; - } + logs.map((log: any, index: number) => { + const token0 = tokens0[index]; + const token1 = tokens1[index]; + log.forEach((i: any) => { + const amountInX = Number('0x' + '0'.repeat(32) + i.amountsIn.replace('0x', '').slice(0, 32)) + const amountInY = Number('0x' + '0'.repeat(32) + i.amountsIn.replace('0x', '').slice(32, 64)) + dailyVolume.add(token0, amountInY); + dailyVolume.add(token1, amountInX); + }) + }); + return { dailyVolume, timestamp, }; } - const adapter: SimpleAdapter = { adapter: { - [CHAIN.ARBITRUM]: { - fetch: graph(CHAIN.ARBITRUM), - start: 1682121600, - }, - [CHAIN.BSC]: { - fetch: graph(CHAIN.BSC), - start: 1681084800, - }, - [CHAIN.AVAX]: { - fetch: graph(CHAIN.AVAX), - start: 1682467200, - }, + [CHAIN.ARBITRUM]: { fetch, start: 1682121600, }, + [CHAIN.BSC]: { fetch, start: 1681084800, }, + [CHAIN.AVAX]: { fetch, start: 1682467200, }, } }; diff --git a/dexs/synthetix/index.ts b/dexs/synthetix/index.ts index 1e7dcdd910..4e37455e31 100644 --- a/dexs/synthetix/index.ts +++ b/dexs/synthetix/index.ts @@ -1,19 +1,9 @@ -import { FetchResultVolume, SimpleAdapter } from "../../adapters/types"; +import { FetchOptions, FetchResultVolume, SimpleAdapter } from "../../adapters/types"; import { CHAIN } from "../../helpers/chains"; -import * as sdk from "@defillama/sdk"; -import { getBlock } from "../../helpers/getBlock"; -import { ethers } from "ethers"; - -const topics0_modified_positions = '0xc0d933baa356386a245ade48f9a9c59db4612af2b5b9c17de5b451c628760f43'; -const topics0_postions_liq = '0x8e83cfbf9c95216dce50909e376c0dcc3e23129a3aa1edd5013fa8b41648f883'; const event_modified_positions = 'event PositionModified(uint indexed id,address indexed account,uint margin,int size,int tradeSize,uint lastPrice,uint fundingIndex,uint fee,int skew)'; const event_postions_liq = 'event PositionLiquidated(uint id,address account,address liquidator,int size,uint price,uint flaggerFee,uint liquidatorFee,uint stakersFee)'; -const contract_interface = new ethers.Interface([ - event_modified_positions, - event_postions_liq -]); const contracts: string[] = [ '0x5374761526175B59f1E583246E20639909E189cE', '0xF9DD29D2Fd9B38Cd90E390C797F1B7E0523f43A9', @@ -59,54 +49,22 @@ const contracts: string[] = [ '0x6110DF298B411a46d6edce72f5CAca9Ad826C1De', ] -interface ILog { - data: string; - transactionHash: string; - topics: string[]; - address: string; -} - -const fetchVolume = async (timestamp: number): 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 fetchVolume: any = async (timestamp: number, _, { getLogs, }: FetchOptions): Promise => { + let dailyVolume = 0 + const logs_modify: any[] = await getLogs({ targets: contracts, eventAbi: event_modified_positions, }) + const logs_liq: any[] = await getLogs({ targets: contracts, eventAbi: event_postions_liq, }) + logs_modify.forEach((log: any) => { + let value = Number(log.tradeSize) * Number(log.lastPrice) / 1e36 + if (value < 0) value *= -1 + dailyVolume += value + }) + logs_liq.forEach((log: any) => { + let value = Number(log.size) * Number(log.price) / 1e36 + if (value < 0) value *= -1 + dailyVolume += value + }) - const logs_modify: ILog[] = (await Promise.all(contracts.map((address: string) => sdk.getEventLogs({ - target: address, - toBlock: toBlock, - fromBlock: fromBlock, - chain: CHAIN.OPTIMISM, - topics: [topics0_modified_positions] - })))).flat(); - const contract_active: string[] = [...new Set(logs_modify.map((e: ILog) => e.address))] - const logs_liq: ILog[] = (await Promise.all(contract_active.map((address: string) => sdk.getEventLogs({ - target: address, - toBlock: toBlock, - fromBlock: fromBlock, - chain: CHAIN.OPTIMISM, - topics: [topics0_postions_liq] - })))).flat(); - - const tradeVolume = logs_modify.map((e: ILog) => { - const value = contract_interface.parseLog(e) - const tradeSize = Number(value!.args.tradeSize.toString().replace('-', '')) / 10 ** 18; - const lastPrice = Number(value!.args.lastPrice.toString().replace('-', '')) / 10 ** 18; - return (tradeSize * lastPrice); - }).filter((e: number) => !isNaN(e)).reduce((a: number, b: number) => a + b, 0); - - const liqVolume = logs_liq.map((e: ILog) => { - const value = contract_interface.parseLog(e) - const tradeSize = Number(value!.args.size.toString().replace('-', '')) / 10 ** 18; - const lastPrice = Number(value!.args.price.toString().replace('-', '')) / 10 ** 18; - return (tradeSize * lastPrice); - }).filter((e: number) => !isNaN(e)).reduce((a: number, b: number) => a + b, 0); - const dailyVolume = tradeVolume + liqVolume; - return { - dailyVolume: `${dailyVolume}`, - timestamp - } + return { dailyVolume, timestamp } } const adapter: SimpleAdapter = { adapter: { diff --git a/dexs/velocore-v2/index.ts b/dexs/velocore-v2/index.ts index 1e8df8757b..d0ae815131 100644 --- a/dexs/velocore-v2/index.ts +++ b/dexs/velocore-v2/index.ts @@ -1,52 +1,23 @@ -import { SimpleAdapter } from "../../adapters/types"; +import { FetchOptions, SimpleAdapter } from "../../adapters/types"; import { CHAIN } from "../../helpers/chains"; -import { ethers } from "ethers"; -import * as sdk from "@defillama/sdk"; -import { getBlock } from "../../helpers/getBlock"; -import { getPrices } from "../../utils/prices"; -interface ILog { - data: string; - transactionHash: string; - topics: string[]; -} - -const abs = (a: number) => a < 0 ? -a : a; -const fetch = async (timestamp: number) => { - let abi = ["event Swap(address indexed pool, address indexed user, bytes32[] tokenRef, int128[] delta)"]; - let iface = new ethers.Interface(abi); - const volume: { [addr: string]: number } = ((await sdk.getEventLogs({ - target: "0x1d0188c4B276A09366D05d6Be06aF61a73bC7535", - fromBlock: await getBlock(timestamp - 60 * 60 * 24, CHAIN.LINEA, {}), - toBlock: await getBlock(timestamp, CHAIN.LINEA, {}), - chain: CHAIN.LINEA, - topics: ["0xbaec78ca3218aba6fc32d82b79acdd1a47663d7b8da46e0c00947206d08f2071"] - })) as any as ILog[]).map((i) => { - const e = iface.parseLog(i)!.args; - let volume: { [addr: string]: number } = {}; - for (let i = 0; i < e.tokenRef.length; i++) { - if (e.tokenRef[i].slice(2 + 24).toLowerCase() == e.pool.slice(2).toLowerCase()) { - // this is lp deposit/withdrawal, not swap - return {}; - } - - volume['0x' + e.tokenRef[i].slice(2 + 24)] = (volume['0x' + e.tokenRef[i].slice(2 + 24)] ?? 0) + abs(Number(e.delta[i])) - } - volume["0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f"] = volume["0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"]; // WETH - delete volume["0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"]; - return volume; - }).reduce((a, b) => { - for (let i in b) { - a[i] = (a[i] ?? 0) + (b[i]); - } - return a; - }, {}) - let prices = await getPrices(Object.keys(volume).map((i) => `${CHAIN.LINEA}:${i}`), timestamp); - const dailyVolume = Object.keys(volume).map((addr) => (prices[`${CHAIN.LINEA}:${addr}`]?.price * volume[addr] / 10 ** prices[`${CHAIN.LINEA}:${addr}`]?.decimals) || 0).reduce((a, b) => a + b, 0) / 2; - return { - dailyVolume: `${dailyVolume}`, - timestamp, - }; +const fetch: any = async (timestamp: number, _, { getLogs, createBalances, }: FetchOptions) => { + const dailyVolume = createBalances() + let eventAbi = "event Swap(address indexed pool, address indexed user, bytes32[] tokenRef, int128[] delta)" + const logs = await getLogs({ target: "0x1d0188c4B276A09366D05d6Be06aF61a73bC7535", eventAbi, }) + logs.forEach((log: any) => { + const pool = log.pool.toLowerCase() + const hasPool = log.tokenRef.some((val: string) => '0x' + val.slice(2 + 24).toLowerCase() === pool) + // this is lp deposit/withdrawal, not swap + if (hasPool) return; + log.tokenRef.forEach((val: string, i: number) => { + const token = '0x' + val.slice(2 + 24).toLowerCase() + const volume = Number(log.delta[i]) + if (volume < 0) return; + dailyVolume.add(token, volume) + }) + }) + return { dailyVolume, timestamp, }; } const adapter: SimpleAdapter = { diff --git a/dexs/y2k/index.ts b/dexs/y2k/index.ts index aa08d87ea2..5ad933623f 100644 --- a/dexs/y2k/index.ts +++ b/dexs/y2k/index.ts @@ -8,7 +8,7 @@ const adapter: Adapter = { breakdown: { v1: { [CHAIN.ARBITRUM]: { - fetch: v1Fetch(CHAIN.ARBITRUM), + fetch: v1Fetch, start: 1667088000, }, }, diff --git a/dexs/y2k/utils.ts b/dexs/y2k/utils.ts index 6006826f69..eaa4c7bc4e 100644 --- a/dexs/y2k/utils.ts +++ b/dexs/y2k/utils.ts @@ -1,51 +1,7 @@ -import { CHAIN } from "../../helpers/chains"; import * as sdk from "@defillama/sdk"; -import { getPrices } from "../../utils/prices"; -import { ethers } from "ethers"; - -const treasury = "0x5c84cf4d91dc0acde638363ec804792bb2108258"; -const topic0_transfer = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"; -const topic0_deposit = "0xdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7"; - -const event_transfer = "event Transfer (address indexed from, address indexed to, uint256 amount)"; const event_deposit = "event Deposit (address indexed user, address indexed receiver, uint256 id, uint256 assets)"; -export interface ITx { - topics: string[]; - data: string; - transactionHash: string; -} - -const transfer_interface = new ethers.Interface([event_transfer]); -const deposit_interface = new ethers.Interface([event_deposit]); - -export const getDeposits = async ( - token: string, - vaults: string[], - fromBlock: number, - toBlock: number, - timestamp: number -): Promise => { - const coins: string[] = [`${CHAIN.ARBITRUM}:${token}`]; - const prices = await getPrices(coins, timestamp); - const price = prices[`${CHAIN.ARBITRUM}:${token}`].price; - const decimals = prices[`${CHAIN.ARBITRUM}:${token}`].decimals; - - let totalDeposits = 0; - for (const vault of vaults) { - const logs_deposit: ITx[] = ( - await sdk.getEventLogs({ - target: vault, - fromBlock: fromBlock, - toBlock: toBlock, - topics: [topic0_deposit], - chain: CHAIN.ARBITRUM, - }) - ) as ITx[]; - - const deposits = logs_deposit.map((e) => deposit_interface.parseLog(e)!.args); - const deposit = deposits.reduce((a, b) => a + Number(b.assets), 0); - totalDeposits += (Number(deposit) / 10 ** decimals) * price; - } - return totalDeposits; -}; +export const getDeposits = async (token: string, vaults: string[], getLogs: any, balances: sdk.Balances,) => { + const logs_deposit = await getLogs({ targets: vaults, eventAbi: event_deposit, }) + logs_deposit.forEach((log: any) => balances.add(token, log.amount)) +} \ No newline at end of file diff --git a/dexs/y2k/y2k-finance-v2.ts b/dexs/y2k/y2k-finance-v2.ts index 6781360edb..e9201c95bf 100644 --- a/dexs/y2k/y2k-finance-v2.ts +++ b/dexs/y2k/y2k-finance-v2.ts @@ -1,63 +1,32 @@ -import { FetchResultVolume } from "../../adapters/types"; -import { CHAIN } from "../../helpers/chains"; +import { FetchOptions, FetchResultVolume } from "../../adapters/types"; import * as sdk from "@defillama/sdk"; -import { getBlock } from "../../helpers/getBlock"; -import { ethers } from "ethers"; -import { getDeposits, ITx } from "./utils"; -const tokens = [ - "0x912ce59144191c1204e64559fe8253a0e49e6548", // ARB - "0x82af49447d8a07e3bd95bd0d56f35241523fbab1", // WETH -]; - -const controller_address = "0xC0655f3dace795cc48ea1E2e7BC012c1eec912dC"; const factory = "0xC3179AC01b7D68aeD4f27a19510ffe2bfb78Ab3e"; -const topic0_market_create = "0xe8066e93c2c1e100c0c76002a546075b7c6b53025db53708875180c81afda250"; -const topic0 = "0x4b66c73cef2a561fd3c21c2af17630b43dddcff66e6803219be3989857b29e80"; const event_market_create = "event MarketCreated (uint256 indexed marketId, address premium, address collateral, address underlyingAsset, address token, string name, uint256 strike, address controller)"; +const event_deposit = "event Deposit (address indexed user, address indexed receiver, uint256 id, uint256 assets)"; -const contract_interface = new ethers.Interface([event_market_create]); - -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 logs_market_create: ITx[] = ( - await sdk.getEventLogs({ - target: factory, - fromBlock: 96059531, - toBlock: toBlock, - topics: [topic0_market_create], - chain: CHAIN.ARBITRUM, - }) - ) as ITx[]; - - const tokenToVaults: {[key: string]: string[]} = {} - const market_create = logs_market_create.map((e) => contract_interface.parseLog(e)!.args); - const underlyings: string[] = []; - market_create.forEach((e: any) => { - underlyings.push(e.underlyingAsset); - if (!tokenToVaults[e.underlyingAsset]) { - tokenToVaults[e.underlyingAsset] = []; - } - tokenToVaults[e.underlyingAsset].push(e.premium); - tokenToVaults[e.underlyingAsset].push(e.collateral); +const fetch: any = async (timestamp: number, _, { getLogs, createBalances, }: FetchOptions): Promise => { + const dailyVolume = createBalances() + const logs_market_create = await getLogs({ + target: factory, + fromBlock: 96059531, + eventAbi: event_market_create, + cacheInCloud: true, + }) + const premiums = logs_market_create.map((e) => e.premium); + const collaterals = logs_market_create.map((e) => e.collateral); + let tokens = logs_market_create.map((e) => e.underlyingAsset); + tokens = tokens.concat(tokens) + const markets = premiums.concat(collaterals); + const logs = await getLogs({ targets: markets, eventAbi: event_deposit, flatten: false, }) + logs.forEach((logs: any, index: number) => { + logs.forEach((log: any) => dailyVolume.add(tokens[index], log.deposit)) }) - const tokens: string[] = [...new Set(underlyings)]; - let dailyVolume = 0; - for (const token of tokens) { - dailyVolume += await getDeposits(token, tokenToVaults[token], fromBlock, toBlock, timestamp); - } - return { - dailyVolume: `${dailyVolume}`, - timestamp, - }; + return { dailyVolume, timestamp, }; }; export default fetch; diff --git a/dexs/y2k/y2k-finance.ts b/dexs/y2k/y2k-finance.ts index 7b6b1ad54e..97146d70c4 100644 --- a/dexs/y2k/y2k-finance.ts +++ b/dexs/y2k/y2k-finance.ts @@ -1,53 +1,21 @@ -import { FetchResultVolume } from "../../adapters/types"; -import * as sdk from "@defillama/sdk"; -import { getBlock } from "../../helpers/getBlock"; -import { Chain } from "@defillama/sdk/build/general"; -import { getDeposits } from "./utils"; +import { FetchOptions, FetchResultVolume } from "../../adapters/types"; const vault_factory = "0x984e0eb8fb687afa53fc8b33e12e04967560e092"; const WETH = "0x82af49447d8a07e3bd95bd0d56f35241523fbab1"; +const event_deposit = "event Deposit (address indexed user, address indexed receiver, uint256 id, uint256 assets)"; const abis: any = { "getVaults": "function getVaults(uint256 index) view returns (address[] vaults)", "marketIndex": "uint256:marketIndex" }; -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 fetch: any = async (timestamp: number, _, { api, getLogs, createBalances, }: FetchOptions): Promise => { + const vaults = (await api.fetchList({ lengthAbi: abis.marketIndex, itemAbi: abis.getVaults, target: vault_factory })).flat() + const dailyVolume = createBalances() + const logs_deposit = await getLogs({ targets: vaults, eventAbi: event_deposit, }) + logs_deposit.forEach((log: any) => dailyVolume.add(WETH, log.amount)) - const poolLength = ( - await sdk.api2.abi.call({ - target: vault_factory, - chain: chain, - abi: abis.marketIndex, - }) - ); - - const vaultRes = await sdk.api2.abi.multiCall({ - abi: abis.getVaults, - calls: Array.from(Array(Number(poolLength)).keys()).map((i: any) => ({ - target: vault_factory, - params: i, - })), - chain: chain, - }); - - const vaults = vaultRes - - .flat() - .map((e: string) => e.toLowerCase()); - - const dailyVolume = await getDeposits(WETH, vaults, fromBlock, toBlock, timestamp); - - return { - dailyVolume: `${dailyVolume}`, - timestamp, - }; - }; + return { dailyVolume, timestamp, }; }; export default fetch; diff --git a/fees/0x0dex.ts b/fees/0x0dex.ts index 8489cb8d22..2f76d4b7e0 100644 --- a/fees/0x0dex.ts +++ b/fees/0x0dex.ts @@ -1,15 +1,5 @@ -import { Adapter, FetchResult } from "../adapters/types"; +import { Adapter, FetchOptions, FetchResult } from "../adapters/types"; import { ETHEREUM } from "../helpers/chains"; -import * as sdk from "@defillama/sdk"; -import { getBlock } from "../helpers/getBlock"; -import { CHAIN } from "../helpers/chains"; -import { ethers } from "ethers"; - -interface IDeposit { - sender: string; - depositAmount: string; - blockNumber: number; -} const OxOPoolETHAddress = "0x3d18AD735f949fEbD59BBfcB5864ee0157607616"; const OxOToken = "0x5a3e6A77ba2f983eC0d371ea3B475F8Bc0811AD5"; @@ -17,77 +7,29 @@ const fee = 0.009; const discount = 0.0045; // Deposit Event -const targetTopic = "0x90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15"; const discountThreshold = 1000000 * (9 ** 18); -async function calcFees(calcData: IDeposit[], chain: CHAIN) { - let fees = 0; - for (var i = 0; i < calcData.length; i++) { - let c = calcData[i]; - - let { output: balance } = await sdk.api.erc20.balanceOf({ - target: OxOToken, - owner: c.sender, - block: c.blockNumber, - chain: chain - }); - - if (parseInt(balance) >= discountThreshold) { - fees += Number(c.depositAmount) * discount; - } else { - fees += Number(c.depositAmount) * fee; - } - } - - return fees; -} - -async function getDepositTXs( - fromBlock: number, - toBlock: number, - chain: CHAIN -): Promise { - const iface = new ethers.Interface([ - "event Deposit (address, uint256 tokenAmount, uint256 ringIndex)" - ]); - - let calcData: IDeposit[] = (await sdk.getEventLogs({ +const fetch: any = async (timestamp: number, _: any, { getLogs, api }: FetchOptions): Promise => { + const logs = await getLogs({ target: OxOPoolETHAddress, - toBlock: toBlock, - fromBlock: fromBlock, - chain: chain, - topics: [targetTopic] - })).map((e: any) => { - const decoded = iface.decodeEventLog("Deposit", e.data); - const sender = decoded[0]; - const depositAmount = decoded.tokenAmount; - return { - sender: sender, - depositAmount: depositAmount, - blockNumber: e.blockNumber - } + eventAbi: "event Deposit (address sender, uint256 tokenAmount, uint256 ringIndex)" }) - - return calcData; -} - - -const fetch = async (timestamp: number): Promise => { - const chain = CHAIN.ETHEREUM; - const fromTimestamp = timestamp - 60 * 60 * 24; - const toTimestamp = timestamp; - const fromBlock = (await getBlock(fromTimestamp, chain, {})); - const toBlock = (await getBlock(toTimestamp, chain, {})); - - let dailyCalcData = await getDepositTXs(fromBlock, toBlock, chain); - let dailyFees = (await calcFees(dailyCalcData, chain)) / 1e18; + const senders = logs.map((log: any) => log.sender); + const balances = await api.multiCall({ abi: 'erc20:balanceOf', calls: senders, target: OxOToken }) + let dailyFees = 0; + logs.forEach((log: any, i: number) => { + const isDiscounted = Number(balances[i]) > discountThreshold + const ratio = isDiscounted ? discount : fee; + dailyFees += Number(log.tokenAmount) * ratio; + }) + dailyFees /= 1e18; return { - timestamp: timestamp, - dailyFees: dailyFees.toString(), + timestamp, + dailyFees, // 100% of the revenue going to holders, hence, fees = revenue, fees = holdersRevenue - dailyHoldersRevenue: dailyFees.toString(), - dailyProtocolRevenue: dailyFees.toString() + dailyHoldersRevenue: dailyFees, + dailyProtocolRevenue: dailyFees }; }; diff --git a/fees/allbridge-core.ts b/fees/allbridge-core.ts index 1c8e251a8d..38573a351a 100644 --- a/fees/allbridge-core.ts +++ b/fees/allbridge-core.ts @@ -1,10 +1,6 @@ import { Chain } from "@defillama/sdk/build/general"; -import { FetchResultFees, SimpleAdapter } from "../adapters/types"; +import { FetchOptions, SimpleAdapter } from "../adapters/types"; import { CHAIN } from "../helpers/chains"; -import { getBlock } from "../helpers/getBlock"; -import { ethers } from "ethers"; -import * as sdk from "@defillama/sdk"; -import { getPrices } from "../utils/prices"; import { httpGet } from "../utils/fetchURL"; type TChainAddress = { @@ -39,118 +35,67 @@ const lpTokenAddresses: TChainAddress = { ] } -const topic0_swap_fromUSD = '0xfc1df7b9ba72a13350b8a4e0f094e232eebded9edd179950e74a852a0f405112'; -const topic0_swap_toUSD = '0xa930da1d3f27a25892307dd59cec52dd9b881661a0f20364757f83a0da2f6873'; const event_swap_fromUSD = 'event SwappedFromVUsd(address recipient,address token,uint256 vUsdAmount,uint256 amount,uint256 fee)'; const event_swap_toUSD = 'event SwappedToVUsd(address sender,address token,uint256 amount,uint256 vUsdAmount,uint256 fee)'; -const contract_interface = new ethers.Interface([ - event_swap_fromUSD, - event_swap_toUSD -]); +const fetchFees = async ({ getLogs, createBalances, chain, api }: FetchOptions): Promise => { + const balances = createBalances(); + const pools = lpTokenAddresses[chain] + const logs_fromUSD = await getLogs({ targets: pools, eventAbi: event_swap_fromUSD, flatten: false, }) + const logs_toUSD = await getLogs({ targets: pools, eventAbi: event_swap_toUSD, flatten: false, }) + const tokens = await api.multiCall({ abi: "address:token", calls: pools }); -const abi_token = "address:token" -const fetchFees = async (chain: Chain, 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_fromUSD = (await Promise.all(lpTokenAddresses[chain].map(async (lpTokenAddress: string) => { - return sdk.getEventLogs({ - target: lpTokenAddress, - toBlock: toBlock, - fromBlock: fromBlock, - chain: chain, - topics: [topic0_swap_fromUSD] - }) - }))).flat(); - const logs_toUSD = (await Promise.all(lpTokenAddresses[chain].map(async (lpTokenAddress: string) => { - return sdk.getEventLogs({ - target: lpTokenAddress, - toBlock: toBlock, - fromBlock: fromBlock, - chain: chain, - topics: [topic0_swap_toUSD] - }) - }))).flat(); + logs_fromUSD.forEach(addLogs) + logs_toUSD.forEach(addLogs) - const lptokens = await sdk.api2.abi.multiCall({ - abi: abi_token, - calls: lpTokenAddresses[chain].map((address: string) => ({ - target: address - })), - chain: chain - }); - const tokens = lptokens; - const prices = await getPrices(tokens.map((e: any) => `${chain}:${e}`), timestamp); - const logs = logs_fromUSD.concat(logs_toUSD); - return logs.map((log: any) => { - const parsedLog = contract_interface.parseLog(log); - const index = lpTokenAddresses[chain].indexOf(log.address); - const tokenAdd = tokens[index]; - const price = prices[`${chain}:${tokenAdd}`].price; - let decimals = prices[`${chain}:${tokenAdd}`].decimals; - return Number(parsedLog!.args.fee) / 10 ** decimals * price; - }).reduce((a: number, b: number) => a + b, 0); + function addLogs(logs: any, index: number) { + const token = tokens[index] + logs.forEach((log: any) => balances.add(token, log.fee)) + } + return balances.getUSDValue(); }; -const fetchFeesTron = async (chain: Chain, timestamp: number): Promise => { - const toTimestamp = timestamp; - const fromTimestamp = timestamp - 60 * 60 * 24 +const fetchFeesTron = async ({ chain, createBalances, toTimestamp, fromTimestamp, api, }: FetchOptions): Promise => { + const balances = createBalances(); + const pools = lpTokenAddresses[chain] const minBlockTimestampMs = fromTimestamp * 1000; const maxBlockTimestampMs = toTimestamp * 1000; - const logs_fromUSD = (await Promise.all(lpTokenAddresses[chain].map(async (lpTokenAddress: string) => { + const logs_fromUSD = (await Promise.all(pools.map(async (lpTokenAddress: string) => { return getTronLogs(lpTokenAddress, 'SwappedFromVUsd', minBlockTimestampMs, maxBlockTimestampMs); - }))).flat(); - const logs_toUSD = (await Promise.all(lpTokenAddresses[chain].map(async (lpTokenAddress: string) => { + }))) + const logs_toUSD = (await Promise.all(pools.map(async (lpTokenAddress: string) => { return getTronLogs(lpTokenAddress, 'SwappedToVUsd', minBlockTimestampMs, maxBlockTimestampMs); - }))).flat(); - const logs = logs_fromUSD.concat(logs_toUSD); + }))) + const tokens = await api.multiCall({ abi: "address:token", calls: pools }); - const lptokens = await sdk.api2.abi.multiCall({ - abi: abi_token, - calls: lpTokenAddresses[chain].map((address: string) => ({ - target: address - })), - chain: chain - }); - const tokens = lptokens; - const prices = await getPrices(tokens.map((e: any) => `${chain}:${e}`), timestamp); + logs_fromUSD.forEach(addLogs) + logs_toUSD.forEach(addLogs) - return logs.map((log: any) => { - const index = lpTokenAddresses[chain].indexOf(log.contract_address); - const tokenAdd = tokens[index]; - const price = prices[`${chain}:${tokenAdd}`].price; - let decimals = prices[`${chain}:${tokenAdd}`].decimals; - return Number(log.result.fee) / 10 ** decimals * price; - }).reduce((a: number, b: number) => a + b, 0); + function addLogs(logs: any, index: number) { + const token = tokens[index] + logs.forEach((log: any) => balances.add(token, log.result.fee)) + } + return balances.getUSDValue() }; const tronRpc = `https://api.trongrid.io` const getTronLogs = async (address: string, eventName: string, minBlockTimestamp: number, maxBlockTimestamp: number) => { const url = `${tronRpc}/v1/contracts/${address}/events?event_name=${eventName}&min_block_timestamp=${minBlockTimestamp}&max_block_timestamp=${maxBlockTimestamp}&limit=200`; const res = await httpGet(url); + console.log(res.data) return res.data; } -const fetch = (chain: Chain) => { - return async (timestamp: number): Promise => { - let fees = 0; - if (chain === CHAIN.TRON) { - fees = await fetchFeesTron(chain, timestamp); - } else { - fees = await fetchFees(chain, timestamp); - } - const dailyFees = fees; - const dailyRevenue = dailyFees * 0.2; - const dailySupplySideRevenue = dailyFees * 0.8; - return { - dailyFees: dailyFees.toString(), - dailyRevenue: dailyRevenue.toString(), - dailySupplySideRevenue: dailySupplySideRevenue.toString(), - timestamp, - }; +const fetch: any = async (timestamp: number, _: any, options: FetchOptions) => { + let dailyFees = await (options.chain === CHAIN.TRON ? fetchFeesTron(options) : fetchFees(options)); + const dailyRevenue = dailyFees * 0.2; + const dailySupplySideRevenue = dailyFees * 0.8; + return { + dailyFees, + dailyRevenue: dailyRevenue, + dailySupplySideRevenue: dailySupplySideRevenue, + timestamp, }; }; @@ -165,37 +110,37 @@ const meta = { const adapters: SimpleAdapter = { adapter: { [CHAIN.ETHEREUM]: { - fetch: fetch(CHAIN.ETHEREUM), + fetch, start: 1684022400, meta, }, [CHAIN.BSC]: { - fetch: fetch(CHAIN.BSC), + fetch, start: 1684022400, meta, }, [CHAIN.POLYGON]: { - fetch: fetch(CHAIN.POLYGON), + fetch, start: 1684022400, meta, }, [CHAIN.ARBITRUM]: { - fetch: fetch(CHAIN.ARBITRUM), + fetch, start: 1687838400, meta, }, [CHAIN.AVAX]: { - fetch: fetch(CHAIN.AVAX), + fetch, start: 1698030000, meta, }, [CHAIN.OPTIMISM]: { - fetch: fetch(CHAIN.OPTIMISM), + fetch, start: 1702868400, meta, }, [CHAIN.TRON]: { - fetch: fetch(CHAIN.TRON), + fetch, start: 1685109600, meta, }, diff --git a/fees/basepaint.ts b/fees/basepaint.ts index f8025043d5..ce8a774a0a 100644 --- a/fees/basepaint.ts +++ b/fees/basepaint.ts @@ -1,62 +1,29 @@ -import { FetchResultFees, SimpleAdapter } from "../adapters/types" +import { FetchOptions, FetchResultFees, SimpleAdapter } from "../adapters/types" import { CHAIN } from "../helpers/chains" -import { getBlock } from "../helpers/getBlock" -import { ethers } from "ethers" -import { getPrices } from "../utils/prices" -import * as sdk from "@defillama/sdk" -const topic_0 = '0x1033721d007e6103a21cb6edd862fc6eb6a601285ee27d595c4d9f9e597a1837' const contract = '0xBa5e05cb26b78eDa3A2f8e3b3814726305dcAc83' -const event = 'event ArtistsEarned(uint256 indexed day,uint256 amount)'; +const eventAbi = 'event ArtistsEarned(uint256 indexed day,uint256 amount)'; const protocol_fees = 10; // 10% fees +const ethAddress = "0x0000000000000000000000000000000000000000"; -const contract_interface = new ethers.Interface([ +const fetch: any = async (timestamp: number, _: any, { getLogs, createBalances, }: FetchOptions): Promise => { + const logs = await getLogs({ target: contract, eventAbi }) + const dailyFees = createBalances() + const dailyRevenue = createBalances() + const amounts = logs.map((e: any) => e.amount) + dailyFees.add(ethAddress, amounts) + dailyFees.resizeBy(1 / 0.9) // 90% of the fees go to the artists + dailyRevenue.addBalances(dailyFees) + dailyRevenue.resizeBy(protocol_fees / 100) // 10% of the fees go to the protocol -]) -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.BASE, {})); - const toBlock = (await getBlock(toTimestamp, CHAIN.BASE, {})); - const logs = (await sdk.getEventLogs({ - target: contract, - topic: topic_0, - toBlock: toBlock, - fromBlock: fromBlock, - chain: CHAIN.BASE, - topics: [topic_0] - })) as ILog[]; - - const artic_fees = logs.map((e: ILog) => { - const amount = Number(e.data) / 10 ** 18; - return amount; - }); - - const artic_fees_amount = artic_fees.reduce((a: number, b: number) => a + b, 0); - const ethAddress = "ethereum:0x0000000000000000000000000000000000000000"; - const ethPrice = (await getPrices([ethAddress], timestamp))[ethAddress].price; - - const dailyFees = (artic_fees_amount / ((100 - 10) / 100)) * ethPrice; - const dailyRevenue = dailyFees * (protocol_fees / 100); - - return { - dailyFees: `${dailyFees}`, - dailyRevenue: `${dailyRevenue}`, - timestamp - } + return { dailyFees, dailyRevenue, timestamp } } const adapterFees: SimpleAdapter = { adapter: { [CHAIN.BASE]: { - fetch: fetchFees, + fetch, start: async () => 1691625600, } } diff --git a/fees/beethoven-x.ts b/fees/beethoven-x.ts index 86450b805d..1be148312d 100644 --- a/fees/beethoven-x.ts +++ b/fees/beethoven-x.ts @@ -1,199 +1,54 @@ import { Chain } from "@defillama/sdk/build/general"; -import { getBlock } from "../helpers/getBlock"; -import { FetchResultFees, SimpleAdapter } from "../adapters/types"; +import { FetchOptions, FetchResultFees, SimpleAdapter } from "../adapters/types"; import { CHAIN } from "../helpers/chains"; -import * as sdk from "@defillama/sdk"; -import { ethers } from 'ethers' -import BigNumber from "bignumber.js"; -import { getPrices } from "../utils/prices"; type TAddress = { [s: string | Chain]: string; } -const vualtAddress: TAddress = { +const vaultAddresses: TAddress = { [CHAIN.OPTIMISM]: "0xba12222222228d8ba445958a75a0704d566bf2c8", [CHAIN.FANTOM]: "0x20dd72ed959b6147912c2e529f0a0c651c33c9ce", } -interface ILogs { - address: string; - topics: string[]; - data: string; - blockNumber: string; - transactionHash: string; - transactionIndex: string; - blockHash: string; - logIndex: string; - removed: boolean; -} -const topic0_pools_balance_change = "0xe5ce249087ce04f05a957192435400fd97868dba0e6a4b4c049abf8af80dae78" -const topic0_flash_bot = "0x0d7d75e01ab95780d3cd1c8ec0dd6c2ce19e3a20427eec8bf53283b6fb8e95f0" -const topic0_swap = "0x2170c741c41531aec20e7c107c24eecfdd15e69c9bb0a8dd37b1840b9e0b207b"; - const event_pools_balance_change = "event PoolBalanceChanged(bytes32 indexed poolId,address indexed liquidityProvider,address[] tokens,int256[] deltas,uint256[] protocolFeeAmounts)" const event_flash_bot = "event FlashLoan(address indexed recipient,address indexed token,uint256 amount,uint256 feeAmount)" const event_swap = "event Swap(bytes32 indexed poolId,address indexed tokenIn,address indexed tokenOut,uint256 amountIn,uint256 amountOut)" -const contract_interface = new ethers.Interface([ - event_pools_balance_change, - event_flash_bot, - event_swap -]) - const abis = { getPool: "function getPool(bytes32 poolId) view returns (address, uint8)", getSwapFeePercentage: "uint256:getSwapFeePercentage" } -interface IBalanceChange { - tokens: string[]; - protocolFeeAmounts: BigNumber[]; -} - -interface ISwap { - poolId: string; - tokenIn: string; - tokenOut: string; - amountIn: number; - amountOut: number; -} - -interface SwapFees { - amountIdUSD: number; - amountOutUSD: number; - fee: number; -} - -const fetchFees = (chain: Chain) => { - return async (timestamp: number): Promise => { - const toTimestamp = timestamp - const fromTimestamp = timestamp - 60 * 60 * 24 - const toBlock = await getBlock(toTimestamp, chain, {}) - const fromBlock = await getBlock(fromTimestamp, chain, {}) - - const logs_balance: ILogs[] = (await sdk.getEventLogs({ - target: vualtAddress[chain], - fromBlock, - toBlock, - topics: [topic0_pools_balance_change], - chain: chain, - })) as ILogs[] - - const rawDataBalanceChange: IBalanceChange[] = logs_balance.map((a: ILogs) => { - const value = contract_interface.parseLog(a) - return { - tokens: value!.args.tokens, - protocolFeeAmounts: value!.args.protocolFeeAmounts - } - }); - const logs_flash_bot: ILogs[] = (await sdk.getEventLogs({ - target: vualtAddress[chain], - fromBlock, - toBlock, - topics: [topic0_flash_bot], - chain: chain, - })) as ILogs[] - - const logs_swap: ILogs[] = (await sdk.getEventLogs({ - target: vualtAddress[chain], - fromBlock, - toBlock, - topics: [topic0_swap], - chain: chain, - })) as ILogs[] - - const swapRaw: ISwap[] = logs_swap.map((a: ILogs) => { - const value = contract_interface.parseLog(a) - return { - poolId: value!.args.poolId, - tokenIn: value!.args.tokenIn, - tokenOut: value!.args.tokenOut, - amountIn: Number(value!.args.amountIn), - amountOut: Number(value!.args.amountOut), - } as ISwap - }); - const poolIds = [...new Set(swapRaw.map((a: ISwap) => a.poolId))] - const pools = (await sdk.api2.abi.multiCall({ - abi: abis.getPool, - calls: poolIds.map((a: string) => ({ - target: vualtAddress[chain], - params: [a] - })), - chain: chain, - })) - .map((a: any) => a[0]); - - const swapFees = (await sdk.api2.abi.multiCall({ - abi: abis.getSwapFeePercentage, - calls: pools.map((a: string) => ({ - target: a, - })), - chain: chain, - })); - - - const rawDataFlashBot: IBalanceChange[] = logs_flash_bot.map((a: ILogs) => { - const value = contract_interface.parseLog(a) - return { - tokens: [value!.args.token], - protocolFeeAmounts: [value!.args.feeAmount] - } - }); - - const coins = [...new Set([...rawDataBalanceChange.flatMap((a: IBalanceChange) => a.tokens), ...rawDataFlashBot.flatMap((a: IBalanceChange) => a.tokens), ...swapRaw.flatMap((a: ISwap) => [a.tokenIn, a.tokenOut])])] - .map((a: string) => `${chain}:${a.toLowerCase()}`) - const prices = await getPrices(coins, timestamp) - - const dailyFee = [...rawDataBalanceChange, ...rawDataFlashBot].map((a: IBalanceChange) => { - return a.tokens.map((b: string, i: number) => { - const price = prices[`${chain}:${b.toLowerCase()}`]?.price || 0; - const decimals = prices[`${chain}:${b.toLowerCase()}`]?.decimals || 0; - if (!price || !decimals) return 0; - const amount = Number(a.protocolFeeAmounts[i].toString()) / 10 ** decimals; - return amount * price; - }).reduce((a: number, b: number) => a + b, 0); - }).flat().reduce((a: number, b: number) => a + b, 0); - - const dailySwapFees: SwapFees[] = swapRaw.map((a: ISwap) => { - const priceIn = prices[`${chain}:${a.tokenIn.toLowerCase()}`]?.price || 0; - const decimalsIn = prices[`${chain}:${a.tokenIn.toLowerCase()}`]?.decimals || 0; - const priceOut = prices[`${chain}:${a.tokenOut.toLowerCase()}`]?.price || 0; - const decimalsOut = prices[`${chain}:${a.tokenOut.toLowerCase()}`]?.decimals || 0; - const amountIn = a.amountIn / 10 ** decimalsIn; - const amountOut = a.amountOut / 10 ** decimalsOut; - const amountIdUSD = (amountIn * priceIn) - const amountOutUSD = (amountOut * priceOut) - const indexPool = poolIds.indexOf(a.poolId); - const fee = (Number(swapFees[indexPool] || 0) / 1e18); - return { - amountIdUSD, - amountOutUSD, - fee - } as SwapFees - }); - const dailySwapFeesUSD = dailySwapFees.reduce((a: number, b: any) => a + b.fee * b.amountIdUSD, 0); - - const dailyFees = dailyFee + dailySwapFeesUSD; - const dailyRevenue = (dailyFees) * (25 / 100); - const dailySupplySideRevenue = dailyFees - dailyRevenue; - return { - dailyFees: `${dailyFees}`, - dailyRevenue: `${dailyRevenue}`, - dailySupplySideRevenue: `${dailySupplySideRevenue}`, - timestamp, - } - } +const fetch: any = async (timestamp: number, _: any, { getLogs, createBalances, chain, api, }: FetchOptions): Promise => { + const dailyFees = createBalances() + const dailyRevenue = createBalances() + const dailySupplySideRevenue = createBalances() + const vault = vaultAddresses[chain] + const logs_balance = await getLogs({ target: vault, eventAbi: event_pools_balance_change, }) + const logs_flash_bot = await getLogs({ target: vault, eventAbi: event_flash_bot, }) + const logs_swap = await getLogs({ target: vault, eventAbi: event_swap, }) + logs_balance.forEach((log: any) => dailyFees.add(log.tokens, log.protocolFeeAmounts)) + logs_flash_bot.forEach((log: any) => dailyFees.add(log.token, log.feeAmount)) + const poolIds = [...new Set(logs_swap.map((a: any) => a.poolId))] + const pools = (await api.multiCall({ abi: abis.getPool, calls: poolIds, target: vault })).map(i => i[0]) + const swapFees = await api.multiCall({ abi: abis.getSwapFeePercentage, calls: pools }) + logs_swap.forEach((log: any) => { + const index = poolIds.indexOf(log.poolId) + if (index === -1) return; + const fee = swapFees[index] / 1e18 + dailyFees.add(log.tokenOut, Number(log.amountOut) * fee) + }) + + dailyRevenue.addBalances(dailyFees) + dailySupplySideRevenue.addBalances(dailyFees) + dailyRevenue.resizeBy(0.25) + dailySupplySideRevenue.resizeBy(0.75) + return { dailyFees, dailyRevenue, dailySupplySideRevenue, timestamp, } } const adapters: SimpleAdapter = { adapter: { - [CHAIN.OPTIMISM]: { - fetch: fetchFees(CHAIN.OPTIMISM), - start: 1672531200 - }, - [CHAIN.FANTOM]: { - fetch: fetchFees(CHAIN.FANTOM), - start: 1672531200 - } + [CHAIN.OPTIMISM]: { fetch, start: 1672531200 }, + [CHAIN.FANTOM]: { fetch, start: 1672531200 } } } export default adapters diff --git a/fees/benqi-lending.ts b/fees/benqi-lending.ts index bfc9ae7b41..3c459a6667 100644 --- a/fees/benqi-lending.ts +++ b/fees/benqi-lending.ts @@ -1,205 +1,14 @@ -import { Adapter, ChainBlocks, FetchResultFees } from "../adapters/types" +import { Adapter, } from "../adapters/types" import { CHAIN } from "../helpers/chains"; -import { getBlock } from "../helpers/getBlock"; -import * as sdk from "@defillama/sdk"; -import { ethers, BigNumberish} from "ethers"; -import { getPrices } from "../utils/prices"; - - -interface IPrices { - [address: string]: { - decimals: number; - price: number; - symbol: string; - timestamp: number; - }; -} - -interface IContext { - currentTimestamp: number; - startTimestamp: number; - endTimestamp: number; - startBlock: number; - endBlock: number; - markets: string[]; - underlyings: string[]; - reserveFactors: string[]; - prices: IPrices; -} -interface IAccrueInterestLog { - market: string; - cashPrior: BigNumberish; - interestAccumulated: BigNumberish; - borrowIndexNew: BigNumberish; - totalBorrowsNew: BigNumberish; -} - -interface ITx { - address: string; - data: string; - topics: string[]; - transactionHash: string; -} +import { getFeesExport } from "../helpers/compoundV2"; const unitroller = "0x486Af39519B4Dc9a7fCcd318217352830E8AD9b4"; -const comptrollerABI = { - getAllMarkets: "function getAllMarkets() external view returns (address[])", -}; - -const topic0_accue_interest = '0x4dec04e750ca11537cabcd8a9eab06494de08da3735bc8871cd41250e190bc04'; - -const tokenABI = { - underlying: "function underlying() external view returns (address)", - accrueInterest:"event AccrueInterest(uint256 cashPrior,uint256 interestAccumulated,uint256 borrowIndex,uint256 totalBorrows)", - reserveFactorMantissa: "function reserveFactorMantissa() external view returns (uint256)", -}; - -const contract_interface = new ethers.Interface(Object.values(tokenABI)); - -const fetch = async (timestamp: number): Promise => { - const context = await getContext(timestamp, {}); - const { dailyProtocolFees, dailyProtocolRevenue } = await getDailyProtocolFees(context); - const dailySupplySideRevenue = (dailyProtocolFees - dailyProtocolRevenue); - return { - timestamp, - dailyFees: dailyProtocolFees.toString(), - dailyRevenue: dailyProtocolRevenue.toString(), - dailyHoldersRevenue: dailyProtocolRevenue.toString(), - dailySupplySideRevenue: `${dailySupplySideRevenue}` - } -} - -const getAllMarkets = async ( - unitroller: string, - chain: CHAIN -): Promise => { - return ( - await sdk.api2.abi.call({ - target: unitroller, - abi: comptrollerABI.getAllMarkets, - chain: chain, - }) - ); -}; - -const getContext = async (timestamp: number, _: ChainBlocks): Promise => { - const fromTimestamp = timestamp - 60 * 60 * 24 - const toTimestamp = timestamp - const fromBlock = (await getBlock(fromTimestamp, CHAIN.AVAX, {})); - const toBlock = (await getBlock(toTimestamp, CHAIN.AVAX, {})); - - const allMarketAddressess = await getAllMarkets(unitroller, CHAIN.AVAX); - const { underlyings, reserveFactors } = await getMarketDetails(allMarketAddressess,CHAIN.AVAX); - - const prices = await getPrices( - [ - ...underlyings.filter((e: string) => e).map((x: string) => `${CHAIN.AVAX}:${x.toLowerCase()}`), - ], - timestamp - ); - - return { - currentTimestamp: timestamp, - startTimestamp: fromTimestamp, - endTimestamp: toTimestamp, - startBlock: fromBlock, - endBlock: toBlock, - markets: allMarketAddressess, - underlyings, - reserveFactors, - prices, - }; -}; - -const getMarketDetails = async (markets: string[], chain: CHAIN): Promise<{underlyings: string[], reserveFactors:string[]}> => { - const underlyings = await sdk.api2.abi.multiCall({ - calls: markets.map((market: string) => ({ - target: market, - })), - abi: tokenABI.underlying, - chain: chain, - permitFailure: true, - }); - - const reserveFactors = await sdk.api2.abi.multiCall({ - calls: markets.map((market: string) => ({ - target: market, - })), - abi: tokenABI.reserveFactorMantissa, - chain: chain, - permitFailure: true, - }); - const _underlyings = underlyings; - _underlyings[0] = '0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7'; - return { - underlyings: _underlyings, - reserveFactors: reserveFactors, - }; -}; - - -const getDailyProtocolFees = async ({ - markets, - underlyings, - reserveFactors, - prices, - startBlock, - endBlock, -}: IContext) => { - let dailyProtocolFees = 0; - let dailyProtocolRevenue = 0; - const logs: ITx[] = (await Promise.all( - markets.map((address: string) => sdk.getEventLogs({ - target: address, - toBlock: endBlock, - fromBlock: startBlock, - chain: CHAIN.AVAX, - topics: [topic0_accue_interest] - })))).flat(); - - const raw_data: IAccrueInterestLog[] = logs.map((e: ITx) => { - const x = contract_interface.parseLog(e); - return { - market: e.address, - cashPrior: x!.args.cashPrior, - interestAccumulated: x!.args.interestAccumulated, - borrowIndexNew: x!.args.borrowIndex, - totalBorrowsNew: x!.args.totalBorrows, - } - }); - - raw_data.forEach((log: IAccrueInterestLog) => { - const marketIndex = markets.findIndex((e: string) => e.toLowerCase() === log.market.toLowerCase()); - const underlying = underlyings[marketIndex].toLowerCase(); - const price = prices[`${CHAIN.AVAX}:${underlying?.toLowerCase()}`]; - - const interestTokens = +ethers.formatUnits( - log.interestAccumulated, - price?.decimals || 0 - ); - const reserveFactor = +ethers.formatUnits( - reserveFactors[marketIndex], - 18 - ); - const interestUSD = interestTokens * price?.price || 0; - - dailyProtocolFees += interestUSD; - dailyProtocolRevenue += interestUSD * reserveFactor; - }); - - return { - dailyProtocolFees, - dailyProtocolRevenue, - }; -}; - const adapter: Adapter = { adapter: { [CHAIN.AVAX]: { - fetch: fetch, + fetch: getFeesExport(unitroller), start: 1664582400, - // runAtCurrTime: true, }, }, }; diff --git a/fees/morpho-compound.ts b/fees/morpho-compound.ts index ceb7ee5277..de79af0762 100644 --- a/fees/morpho-compound.ts +++ b/fees/morpho-compound.ts @@ -1,202 +1,13 @@ -import { Adapter, ChainBlocks, FetchResultFees } from "../adapters/types" +import { Adapter, } from "../adapters/types" import { CHAIN } from "../helpers/chains"; -import { getBlock } from "../helpers/getBlock"; -import * as sdk from "@defillama/sdk"; -import { ethers, BigNumberish } from "ethers"; -import { getPrices } from "../utils/prices"; - - -interface IPrices { - [address: string]: { - decimals: number; - price: number; - symbol: string; - timestamp: number; - }; -} - -interface IContext { - currentTimestamp: number; - startTimestamp: number; - endTimestamp: number; - startBlock: number; - endBlock: number; - markets: string[]; - underlyings: string[]; - reserveFactors: string[]; - prices: IPrices; -} -interface IAccrueInterestLog { - market: string; - cashPrior: BigNumberish; - interestAccumulated: BigNumberish; - borrowIndexNew: BigNumberish; - totalBorrowsNew: BigNumberish; -} - -interface ITx { - address: string; - data: string; - topics: string[]; - transactionHash: string; -} +import { getFeesExport } from "../helpers/compoundV2"; const unitroller = "0x930f1b46e1d081ec1524efd95752be3ece51ef67"; -const comptrollerABI = { - getAllMarkets: "function getAllMarkets() external view returns (address[])", -}; - -const topic0_accue_interest = '0x4dec04e750ca11537cabcd8a9eab06494de08da3735bc8871cd41250e190bc04'; - -const tokenABI = { - underlying: "function underlying() external view returns (address)", - accrueInterest:"event AccrueInterest(uint256 cashPrior,uint256 interestAccumulated,uint256 borrowIndex,uint256 totalBorrows)", - reserveFactorMantissa: "function reserveFactorMantissa() external view returns (uint256)", -}; - -const contract_interface = new ethers.Interface(Object.values(tokenABI)); - -const fetch = async (timestamp: number): Promise => { - const context = await getContext(timestamp, {}); - const { dailyProtocolFees, dailyProtocolRevenue } = await getDailyProtocolFees(context); - const dailySupplySideRevenue = (dailyProtocolFees - dailyProtocolRevenue); - return { - timestamp, - dailyFees: dailyProtocolFees.toString(), - dailyRevenue: dailyProtocolRevenue.toString(), - dailyHoldersRevenue: dailyProtocolRevenue.toString(), - dailySupplySideRevenue: `${dailySupplySideRevenue}` - } -} - -const getAllMarkets = async ( - unitroller: string, - chain: CHAIN -): Promise => { - return ( - await sdk.api2.abi.call({ - target: unitroller, - abi: comptrollerABI.getAllMarkets, - chain: chain, - }) - ); -}; - -const getContext = async (timestamp: number, _: ChainBlocks): 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 allMarketAddressess = await getAllMarkets(unitroller, CHAIN.ETHEREUM); - const { underlyings, reserveFactors } = await getMarketDetails(allMarketAddressess,CHAIN.ETHEREUM); - - const prices = await getPrices( - [ - ...underlyings.filter((e: string) => e).map((x: string) => `${CHAIN.ETHEREUM}:${x.toLowerCase()}`), - ], - timestamp - ); - - return { - currentTimestamp: timestamp, - startTimestamp: fromTimestamp, - endTimestamp: toTimestamp, - startBlock: fromBlock, - endBlock: toBlock, - markets: allMarketAddressess, - underlyings, - reserveFactors, - prices, - }; -}; - -const getMarketDetails = async (markets: string[], chain: CHAIN): Promise<{underlyings: string[], reserveFactors:string[]}> => { - const underlyings = await sdk.api2.abi.multiCall({ - calls: markets.map((market: string) => ({ - target: market, - })), - abi: tokenABI.underlying, - chain: chain, - permitFailure: true, - }); - - const reserveFactors = await sdk.api2.abi.multiCall({ - calls: markets.map((market: string) => ({ - target: market, - })), - abi: tokenABI.reserveFactorMantissa, - chain: chain, - permitFailure: true, - }); - const _underlyings = underlyings; - return { - underlyings: _underlyings, - reserveFactors: reserveFactors, - }; -}; - - -const getDailyProtocolFees = async ({ - markets, - underlyings, - reserveFactors, - prices, - startBlock, - endBlock, -}: IContext) => { - let dailyProtocolFees = 0; - let dailyProtocolRevenue = 0; - const logs: ITx[] = (await Promise.all( - markets.map((address: string) => sdk.getEventLogs({ - target: address, - toBlock: endBlock, - fromBlock: startBlock, - chain: CHAIN.ETHEREUM, - topics: [topic0_accue_interest] - })))).flat(); - - const raw_data: IAccrueInterestLog[] = logs.map((e: ITx) => { - const x = contract_interface.parseLog(e); - return { - market: e.address, - cashPrior: x!.args.cashPrior, - interestAccumulated: x!.args.interestAccumulated, - borrowIndexNew: x!.args.borrowIndex, - totalBorrowsNew: x!.args.totalBorrows, - } - }); - - raw_data.forEach((log: IAccrueInterestLog) => { - const marketIndex = markets.findIndex((e: string) => e === log.market); - const underlying = underlyings[marketIndex].toLowerCase(); - const price = prices[`${CHAIN.ETHEREUM}:${underlying?.toLowerCase()}`]; - - const interestTokens = +ethers.formatUnits( - log.interestAccumulated, - price.decimals - ); - const reserveFactor = +ethers.formatUnits( - reserveFactors[marketIndex], - 18 - ); - const interestUSD = interestTokens * price.price; - - dailyProtocolFees += interestUSD; - dailyProtocolRevenue += interestUSD * reserveFactor; - }); - - return { - dailyProtocolFees, - dailyProtocolRevenue, - }; -}; - const adapter: Adapter = { adapter: { [CHAIN.ETHEREUM]: { - fetch: fetch, + fetch: getFeesExport(unitroller), start: 1697932800, runAtCurrTime: true, }, diff --git a/fees/shoebillFinance-v2/_abi.ts b/fees/shoebillFinance-v2/_abi.ts deleted file mode 100644 index ec22008591..0000000000 --- a/fees/shoebillFinance-v2/_abi.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ethers } from "ethers"; - -const comptrollerABI = { - getAllMarkets: "function getAllMarkets() external view returns (address[])", -}; -const comptrollerInterface = new ethers.Interface( - Object.values(comptrollerABI) -); -const CTokenABI = { - underlying: "function underlying() external view returns (address)", - accrueInterest:"event AccrueInterest(uint256 cashPrior,uint256 interestAccumulated,uint256 borrowIndex,uint256 totalBorrows)", - reserveFactorMantissa: - "function reserveFactorMantissa() external view returns (uint256)", -}; -const cTokenInterface = new ethers.Interface(Object.values(CTokenABI)); - - - -export { - comptrollerABI, - comptrollerInterface, - CTokenABI, - cTokenInterface, -}; diff --git a/fees/shoebillFinance-v2/_types.ts b/fees/shoebillFinance-v2/_types.ts deleted file mode 100644 index 597f5ff396..0000000000 --- a/fees/shoebillFinance-v2/_types.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { BigNumberish } from "ethers"; -import { CHAIN } from "../../helpers/chains"; - -interface IPrices { - [address: string]: { - decimals: number; - price: number; - symbol: string; - timestamp: number; - }; -} - -interface IContext { - currentTimestamp: number; - startTimestamp: number; - endTimestamp: number; - startBlock: number; - endBlock: number; - markets: string[]; - underlyings: string[]; - reserveFactors: string[]; - prices: IPrices; - chain: CHAIN; -} - -interface IAccrueInterestLog { - market: string; - cashPrior: BigNumberish; - interestAccumulated: BigNumberish; - borrowIndexNew: BigNumberish; - totalBorrowsNew: BigNumberish; -} - -export { IPrices, IContext, IAccrueInterestLog }; diff --git a/fees/shoebillFinance-v2/helpers.ts b/fees/shoebillFinance-v2/helpers.ts deleted file mode 100644 index f29331ed3f..0000000000 --- a/fees/shoebillFinance-v2/helpers.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { comptrollerABI, CTokenABI } from "./_abi"; -import * as sdk from "@defillama/sdk"; - -const getAllMarkets = async (unitroller: string, api: sdk.ChainApi,): Promise => { - return (api.call({ target: unitroller, abi: comptrollerABI.getAllMarkets, })); -} - -const getAllMarketsMulti = async (unitrollers: string[], api: sdk.ChainApi,): Promise => { - return (await api.multiCall({ calls: unitrollers, abi: comptrollerABI.getAllMarkets, })).flat(); -} - -const getMarketDetails = async (markets: string[], api: sdk.ChainApi,) => { - const underlyings = await api.multiCall({ calls: markets, abi: CTokenABI.underlying, permitFailure: true, }); - const reserveFactors = await api.multiCall({ calls: markets, abi: CTokenABI.reserveFactorMantissa, }); - return { underlyings, reserveFactors, }; -} - -export { getAllMarkets, getMarketDetails, getAllMarketsMulti }; diff --git a/fees/shoebillFinance-v2/index.ts b/fees/shoebillFinance-v2/index.ts index 2feef9a0c3..a67d31ac05 100644 --- a/fees/shoebillFinance-v2/index.ts +++ b/fees/shoebillFinance-v2/index.ts @@ -1,6 +1,6 @@ import { Adapter, ChainBlocks, FetchOptions, FetchResultFees } from "../../adapters/types"; import { CHAIN } from "../../helpers/chains"; -import { getAllMarketsMulti, getMarketDetails, } from "./helpers"; +import { getFees } from "../../helpers/compoundV2"; const unitrollers = { [CHAIN.MANTA]: [ @@ -12,40 +12,13 @@ const unitrollers = { ] } -type IMapToken = { - [key: string]: string; -}; -const baseToken: IMapToken = { - [CHAIN.MANTA]: '0x0dc808adce2099a9f62aa87d9670745aba741746', - [CHAIN.WEMIX]: '0x7D72b22a74A216Af4a002a1095C8C707d6eC1C5f' -} - -const fetch: any = async (timestamp: number, chainBlocks: ChainBlocks, { api, chain, createBalances, getLogs, }: FetchOptions): Promise => { - - const markets = await getAllMarketsMulti(unitrollers[chain], api); - const { underlyings, reserveFactors } = await getMarketDetails(markets, api); - - let dailyFees = createBalances() - let dailyRevenue = createBalances() - const logs: any[] = (await getLogs({ - targets: markets, - flatten: false, - eventAbi: "event AccrueInterest(uint256 cashPrior,uint256 interestAccumulated,uint256 borrowIndex,uint256 totalBorrows)" - })).map((log: any, index: number) => { - return log.map((i: any) => ({ - ...i, - interestAccumulated: Number(i.interestAccumulated), - marketIndex: index, - })); - }).flat() - - logs.forEach((log: any) => { - const marketIndex = log.marketIndex; - const underlying = underlyings[marketIndex] ?? baseToken[chain] - dailyFees.add(underlying, log.interestAccumulated); - dailyRevenue.add(underlying, log.interestAccumulated * Number(reserveFactors[marketIndex]) / 1e18); - }) - +const fetch: any = async (timestamp: number, chainBlocks: ChainBlocks, options: FetchOptions): Promise => { + const { chain, createBalances, } = options + const dailyFees = createBalances(); + const dailyRevenue = createBalances(); + for (const market of unitrollers[chain]) { + await getFees(market, options, { dailyFees, dailyRevenue, abis: { reserveFactor: "uint256:reserveFactorMantissa", } }); + } return { timestamp, dailyFees, dailyRevenue, dailyHoldersRevenue: dailyRevenue, }; }; diff --git a/fees/sonne-finance/_abi.ts b/fees/sonne-finance/_abi.ts deleted file mode 100644 index a86d738f8a..0000000000 --- a/fees/sonne-finance/_abi.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ethers } from "ethers"; - -const comptrollerABI = { - getAllMarkets: "function getAllMarkets() external view returns (address[])", -}; -const comptrollerInterface = new ethers.Interface( - Object.values(comptrollerABI) -); -const CTokenABI = { - underlying: "function underlying() external view returns (address)", - accrueInterest:"event AccrueInterest(uint256 cashPrior,uint256 interestAccumulated,uint256 borrowIndex,uint256 totalBorrows)", - reserveFactorMantissa: - "function reserveFactorMantissa() external view returns (uint256)", -}; -const cTokenInterface = new ethers.Interface(Object.values(CTokenABI)); - -const veloGaugeAbi = { - earned: - "function earned(address token, address account) external view returns (uint256)", - lastEarn: - "function lastEarn(address token, address account) external view returns (uint256)", -}; -const veloGaugeInterface = new ethers.Interface( - Object.values(veloGaugeAbi) -); - -export { - comptrollerABI, - comptrollerInterface, - CTokenABI, - cTokenInterface, - veloGaugeAbi, - veloGaugeInterface, -}; diff --git a/fees/sonne-finance/_types.ts b/fees/sonne-finance/_types.ts deleted file mode 100644 index d270b01ba8..0000000000 --- a/fees/sonne-finance/_types.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { BigNumberish } from "ethers"; - -interface IPrices { - [address: string]: { - decimals: number; - price: number; - symbol: string; - timestamp: number; - }; -} - -interface IContext { - markets: string[]; - underlyings: string[]; - reserveFactors: string[]; -} - -interface IAccrueInterestLog { - market: string; - cashPrior: BigNumberish; - interestAccumulated: BigNumberish; - borrowIndexNew: BigNumberish; - totalBorrowsNew: BigNumberish; -} - -export { IPrices, IContext, IAccrueInterestLog }; diff --git a/fees/sonne-finance/helpers.ts b/fees/sonne-finance/helpers.ts index a3c513054f..a4a2cd3923 100644 --- a/fees/sonne-finance/helpers.ts +++ b/fees/sonne-finance/helpers.ts @@ -1,19 +1,3 @@ -import { comptrollerABI, CTokenABI, veloGaugeAbi } from "./_abi"; - -const getAllMarkets = async (unitroller: string, api: any): Promise => { - return api.call({ target: unitroller, abi: comptrollerABI.getAllMarkets, }) -}; - -const getMarketDetails = async (markets: string[], api: any) => { - const underlyings = await api.multiCall({ calls: markets, abi: CTokenABI.underlying, }); - const reserveFactors = await api.multiCall({ calls: markets, abi: CTokenABI.reserveFactorMantissa, }); - - return { - underlyings: underlyings, - reserveFactors: reserveFactors, - }; -}; - const getVeloGaugeDetails = async ( gauge: string, token: string, @@ -22,12 +6,12 @@ const getVeloGaugeDetails = async ( ) => { const lastEarn = await api.call({ target: gauge, - abi: veloGaugeAbi.lastEarn, + abi: "function lastEarn(address token, address account) external view returns (uint256)", params: [token, account], }); const earned = await api.call({ target: gauge, - abi: veloGaugeAbi.earned, + abi: "function earned(address token, address account) external view returns (uint256)", params: [token, account], }); @@ -37,4 +21,4 @@ const getVeloGaugeDetails = async ( }; }; -export { getAllMarkets, getMarketDetails, getVeloGaugeDetails }; +export { getVeloGaugeDetails }; diff --git a/fees/sonne-finance/index.ts b/fees/sonne-finance/index.ts index b805e603b9..f880a1d78d 100644 --- a/fees/sonne-finance/index.ts +++ b/fees/sonne-finance/index.ts @@ -1,58 +1,15 @@ import { Adapter, ChainBlocks, FetchOptions, FetchResultFees } from "../../adapters/types"; import { CHAIN } from "../../helpers/chains"; import { - getAllMarkets, - getMarketDetails, getVeloGaugeDetails, } from "./helpers"; -import { CTokenABI } from "./_abi"; -import { IAccrueInterestLog, IContext } from "./_types"; +import { getFees } from "../../helpers/compoundV2"; const unitroller = "0x60CF091cD3f50420d50fD7f707414d0DF4751C58"; const veloGauge = "0x3786d4419d6b4a902607ceb2bb319bb336735df8"; const veloToken = "0x3c8b650257cfb5f272f799f5e2b4e65093a11a05"; const veVeloHolder = "0x17063ad4e83b0aba4ca0f3fc3a9794e807a00ed7"; -const getContext = async ({ api }: FetchOptions): Promise => { - const allMarketAddressess = await getAllMarkets(unitroller, api); - const { underlyings, reserveFactors } = await getMarketDetails(allMarketAddressess, api); - - return { - markets: allMarketAddressess, - underlyings, - reserveFactors, - }; -}; - -const getDailyProtocolFees = async ({ - markets, - underlyings, - reserveFactors, -}: IContext, { getLogs, createBalances, }: FetchOptions) => { - let dailyFees = createBalances(); - let dailyRevenue = createBalances(); - const logs: IAccrueInterestLog[] = (await getLogs({ - targets: markets, - eventAbi: CTokenABI.accrueInterest, - flatten: false, - })).map((log: any, index: number) => { - return log.map((i: any) => ({ - ...i, - interestAccumulated: Number(i.interestAccumulated), - marketIndex: index, - })); - }).flat() - - logs.forEach((log: any) => { - const marketIndex = log.marketIndex; - const underlying = underlyings[marketIndex].toLowerCase(); - dailyFees.add(underlying, log.interestAccumulated); - dailyRevenue.add(underlying, log.interestAccumulated * Number(reserveFactors[marketIndex]) / 1e18); - }); - - return { dailyFees, dailyRevenue, }; -}; - const getDailyVeloRewards = async ({ api, fromTimestamp, toTimestamp, createBalances }: FetchOptions) => { const balances = createBalances(); const { lastEarn, earned } = await getVeloGaugeDetails(veloGauge, veloToken, veVeloHolder, api,); @@ -65,8 +22,7 @@ const getDailyVeloRewards = async ({ api, fromTimestamp, toTimestamp, createBala }; const fetch = async (timestamp: number, chainBlocks: ChainBlocks, options: FetchOptions): Promise => { - const context = await getContext(options); - const { dailyFees, dailyRevenue } = await getDailyProtocolFees(context, options); + const { dailyFees, dailyRevenue } = await getFees(unitroller, options, {}); const dailyHoldersRevenue = await getDailyVeloRewards(options) dailyHoldersRevenue.addBalances(dailyRevenue) diff --git a/fees/venus-finance.ts b/fees/venus-finance.ts index 8bfe7fc132..90eb6a8ccb 100644 --- a/fees/venus-finance.ts +++ b/fees/venus-finance.ts @@ -1,204 +1,14 @@ -import { Adapter, ChainBlocks, FetchResultFees } from "../adapters/types" +import { Adapter, } from "../adapters/types" import { CHAIN } from "../helpers/chains"; -import { getBlock } from "../helpers/getBlock"; -import * as sdk from "@defillama/sdk"; -import { ethers, BigNumberish } from "ethers"; -import { getPrices } from "../utils/prices"; - - -interface IPrices { - [address: string]: { - decimals: number; - price: number; - symbol: string; - timestamp: number; - }; -} - -interface IContext { - currentTimestamp: number; - startTimestamp: number; - endTimestamp: number; - startBlock: number; - endBlock: number; - markets: string[]; - underlyings: string[]; - reserveFactors: string[]; - prices: IPrices; -} -interface IAccrueInterestLog { - market: string; - cashPrior: BigNumberish; - interestAccumulated: BigNumberish; - borrowIndexNew: BigNumberish; - totalBorrowsNew: BigNumberish; -} - -interface ITx { - address: string; - data: string; - topics: string[]; - transactionHash: string; -} +import { getFeesExport } from "../helpers/compoundV2"; const unitroller = "0xfD36E2c2a6789Db23113685031d7F16329158384"; -const comptrollerABI = { - getAllMarkets: "function getAllMarkets() external view returns (address[])", -}; - -const topic0_accue_interest = '0x4dec04e750ca11537cabcd8a9eab06494de08da3735bc8871cd41250e190bc04'; - -const tokenABI = { - underlying: "function underlying() external view returns (address)", - accrueInterest:"event AccrueInterest(uint256 cashPrior,uint256 interestAccumulated,uint256 borrowIndex,uint256 totalBorrows)", - reserveFactorMantissa: "function reserveFactorMantissa() external view returns (uint256)", -}; - -const contract_interface = new ethers.Interface(Object.values(tokenABI)); - -const fetch = async (timestamp: number): Promise => { - const context = await getContext(timestamp, {}); - const { dailyProtocolFees, dailyProtocolRevenue } = await getDailyProtocolFees(context); - const dailySupplySideRevenue = (dailyProtocolFees - dailyProtocolRevenue); - return { - timestamp, - dailyFees: dailyProtocolFees.toString(), - dailyRevenue: dailyProtocolRevenue.toString(), - dailyHoldersRevenue: dailyProtocolRevenue.toString(), - dailySupplySideRevenue: `${dailySupplySideRevenue}` - } -} - -const getAllMarkets = async ( - unitroller: string, - chain: CHAIN -): Promise => { - return ( - await sdk.api2.abi.call({ - target: unitroller, - abi: comptrollerABI.getAllMarkets, - chain: chain, - }) - ); -}; - -const getContext = async (timestamp: number, _: ChainBlocks): Promise => { - const fromTimestamp = timestamp - 60 * 60 * 24 - const toTimestamp = timestamp - const fromBlock = (await getBlock(fromTimestamp, CHAIN.BSC, {})); - const toBlock = (await getBlock(toTimestamp, CHAIN.BSC, {})); - const allMarketAddressess = await getAllMarkets(unitroller, CHAIN.BSC); - const { underlyings, reserveFactors } = await getMarketDetails(allMarketAddressess,CHAIN.BSC); - - const prices = await getPrices( - [ - ...underlyings.filter((e: string) => e).map((x: string) => `${CHAIN.BSC}:${x.toLowerCase()}`), - ], - timestamp - ); - - return { - currentTimestamp: timestamp, - startTimestamp: fromTimestamp, - endTimestamp: toTimestamp, - startBlock: fromBlock, - endBlock: toBlock, - markets: allMarketAddressess, - underlyings, - reserveFactors, - prices, - }; -}; - -const getMarketDetails = async (markets: string[], chain: CHAIN): Promise<{underlyings: string[], reserveFactors:string[]}> => { - const underlyings = await sdk.api2.abi.multiCall({ - calls: markets.map((market: string) => ({ - target: market, - })), - abi: tokenABI.underlying, - chain: chain, - permitFailure: true, - }); - - const reserveFactors = await sdk.api2.abi.multiCall({ - calls: markets.map((market: string) => ({ - target: market, - })), - abi: tokenABI.reserveFactorMantissa, - chain: chain, - permitFailure: true, - }); - const _underlyings = underlyings; - _underlyings[5] = '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c'; - return { - underlyings: _underlyings, - reserveFactors: reserveFactors, - }; -}; - - -const getDailyProtocolFees = async ({ - markets, - underlyings, - reserveFactors, - prices, - startBlock, - endBlock, -}: IContext) => { - let dailyProtocolFees = 0; - let dailyProtocolRevenue = 0; - const logs: ITx[] = (await Promise.all( - markets.map((address: string) => sdk.getEventLogs({ - target: address, - toBlock: endBlock, - fromBlock: startBlock, - chain: CHAIN.BSC, - topics: [topic0_accue_interest] - })))).flat(); - - const raw_data: IAccrueInterestLog[] = logs.map((e: ITx) => { - const x = contract_interface.parseLog(e); - return { - market: e.address, - cashPrior: x!.args.cashPrior, - interestAccumulated: x!.args.interestAccumulated, - borrowIndexNew: x!.args.borrowIndex, - totalBorrowsNew: x!.args.totalBorrows, - } - }); - - raw_data.forEach((log: IAccrueInterestLog) => { - const marketIndex = markets.findIndex((e: string) => e.toLowerCase() === log.market.toLowerCase()); - const underlying = underlyings[marketIndex].toLowerCase(); - const price = prices[`${CHAIN.BSC}:${underlying?.toLowerCase()}`]; - - const interestTokens = +ethers.formatUnits( - log.interestAccumulated, - price?.decimals || 0 - ); - const reserveFactor = +ethers.formatUnits( - reserveFactors[marketIndex], - 18 - ); - const interestUSD = interestTokens * price?.price || 0 - - dailyProtocolFees += interestUSD; - dailyProtocolRevenue += interestUSD * reserveFactor; - }); - - return { - dailyProtocolFees, - dailyProtocolRevenue, - }; -}; - const adapter: Adapter = { adapter: { [CHAIN.BSC]: { - fetch: fetch, + fetch: getFeesExport(unitroller), start: 1691798400, - // runAtCurrTime: true, }, }, }; diff --git a/helpers/compoundV2.ts b/helpers/compoundV2.ts new file mode 100644 index 0000000000..566eaf7e0b --- /dev/null +++ b/helpers/compoundV2.ts @@ -0,0 +1,61 @@ +import { Fetch, FetchOptions } from "../adapters/types"; +import * as sdk from "@defillama/sdk"; + +const comptrollerABI = { + underlying: "address:underlying", + getAllMarkets: "address[]:getAllMarkets", + accrueInterest: "event AccrueInterest(uint256 cashPrior,uint256 interestAccumulated,uint256 borrowIndex,uint256 totalBorrows)", + reserveFactor: "uint256:reserveFactorMantissa", +}; + +export async function getFees(market: string, { createBalances, api, getLogs, }: FetchOptions, { + dailyFees, + dailyRevenue, + abis = {}, +}: { + dailyFees?: sdk.Balances, + dailyRevenue?: sdk.Balances, + abis?: any +}) { + if (!dailyFees) dailyFees = createBalances() + if (!dailyRevenue) dailyRevenue = createBalances() + const markets = await api.call({ target: market, abi: comptrollerABI.getAllMarkets, }) + const underlyings = await api.multiCall({ calls: markets, abi: comptrollerABI.underlying, permitFailure: true, }); + underlyings.forEach((underlying, index) => { + if (!underlying) underlyings[index] = '0x0000000000000000000000000000000000000000' + }) + const reserveFactors = await api.multiCall({ calls: markets, abi: abis.reserveFactor ?? comptrollerABI.reserveFactor, }); + const logs: any[] = (await getLogs({ + targets: markets, + flatten: false, + eventAbi: comptrollerABI.accrueInterest, + })).map((log: any, index: number) => { + return log.map((i: any) => ({ + ...i, + interestAccumulated: Number(i.interestAccumulated), + marketIndex: index, + })); + }).flat() + + logs.forEach((log: any) => { + const marketIndex = log.marketIndex; + const underlying = underlyings[marketIndex] + dailyFees!.add(underlying, log.interestAccumulated); + dailyRevenue!.add(underlying, log.interestAccumulated * Number(reserveFactors[marketIndex]) / 1e18); + }) + + return { dailyFees, dailyRevenue } +} + +export function getFeesExport(market: string) { + return (async (timestamp: number, _: any, options: FetchOptions) => { + const { dailyFees, dailyRevenue } = await getFees(market, options, {}) + const dailyHoldersRevenue = dailyRevenue + const dailySupplySideRevenue = options.createBalances() + dailySupplySideRevenue.addBalances(dailyFees) + Object.entries(dailyRevenue.getBalances()).forEach(([token, balance]) => { + dailySupplySideRevenue.addTokenVannila(token, Number(balance) * -1) + }) + return { timestamp, dailyFees, dailyRevenue, dailyHoldersRevenue, dailySupplySideRevenue } + }) as Fetch +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e6e7713564..ad36f31deb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -802,9 +802,9 @@ } }, "node_modules/@defillama/sdk": { - "version": "5.0.26", - "resolved": "https://registry.npmjs.org/@defillama/sdk/-/sdk-5.0.26.tgz", - "integrity": "sha512-zttsd9q17OYJxHMBobMbi/QiUBUaCNWdUWTtwzF72JZNS7hJv/54T/7nT6CtAtrwqyBa/gg1Xf8d2t7puIfNNw==", + "version": "5.0.28", + "resolved": "https://registry.npmjs.org/@defillama/sdk/-/sdk-5.0.28.tgz", + "integrity": "sha512-TGtUXZVgDOwQBzEuMQ2uru7H1NYFzw4iGL4JYO1JgTX7fJRzczTyCoQATUhqSzgQRZN9NC0/eScL/+9TsLMhvg==", "dependencies": { "@aws-sdk/client-s3": "^3.400.0", "@supercharge/promise-pool": "^2.1.0",