From ec171f593219a6f54fceaa372ae41b95d9737230 Mon Sep 17 00:00:00 2001 From: artem Date: Thu, 17 Oct 2024 14:33:44 +0300 Subject: [PATCH 1/3] Add exit and entry fees --- fees/toros/index.ts | 60 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/fees/toros/index.ts b/fees/toros/index.ts index 82d8ab072d..29efdf631d 100644 --- a/fees/toros/index.ts +++ b/fees/toros/index.ts @@ -1,12 +1,14 @@ import { FetchOptions, SimpleAdapter } from "../../adapters/types"; import { CHAIN } from "../../helpers/chains"; import { GraphQLClient } from "graphql-request"; +import { ZeroAddress } from "ethers"; + const query = ` query managerFeeMinteds($manager: Bytes!, $startTimestamp: BigInt!, $endTimestamp: BigInt!, $first: Int!, $skip: Int!) { managerFeeMinteds( where: { manager: $manager, managerFee_not: 0, blockTimestamp_gte: $startTimestamp, blockTimestamp_lte: $endTimestamp }, first: $first, skip: $skip, orderBy: blockTimestamp, orderDirection: desc - ) { managerFee, tokenPriceAtFeeMint } + ) { managerFee, tokenPriceAtFeeMint, pool, manager, block } }` // gql` // query managerFeeMinteds($manager: Bytes!, $startTimestamp: BigInt!, $endTimestamp: BigInt!) { @@ -81,21 +83,53 @@ const fetchHistoricalFees = async (chainId: CHAIN, managerAddress: string, start return allData; }; -const calculateFees = (data: any): number => - data.reduce((acc: number, item: any) => { - const managerFee = Number(item.managerFee); - const tokenPrice = Number(item.tokenPriceAtFeeMint); - const managerFeeFormatted = managerFee / 1e18; - const tokenPriceFormatted = tokenPrice / 1e18; - const managerFeeUsd = managerFeeFormatted * tokenPriceFormatted; - return acc + managerFeeUsd; - }, 0); - -const fetch = async ({ chain, endTimestamp, startTimestamp }: FetchOptions) => { +const getTransferLogs = async (chain: string, getLogs, poolAddress: string, fromBlock: number, toBlock: number): Promise => { + return await getLogs({ + target: poolAddress, + topic: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', + fromBlock: fromBlock, + toBlock: toBlock, + eventAbi: 'event Transfer (address indexed from, address indexed to, uint256 value)', + onlyArgs: true, + }); +} + +async function addEntryExitFees(dailyFees: any[], chain: CHAIN, getLogs: any) { + for (const dailyFeesDto of dailyFees) { + const transferLogs = await getTransferLogs(chain.toString(), getLogs, dailyFeesDto.pool, +dailyFeesDto.block, +dailyFeesDto.block); + const exitEntryFeeLogs = transferLogs.filter(transfer => { + return (transfer.from.toLowerCase() === ZeroAddress + && transfer.to.toLowerCase() === dailyFeesDto.manager.toLowerCase() + && Number(transfer.value) !== Number(dailyFeesDto.managerFee)) + || (transfer.from.toLowerCase() === dailyFeesDto.pool.toLowerCase() + && transfer.to.toLowerCase() === dailyFeesDto.manager.toLowerCase() + && Number(transfer.value) !== Number(dailyFeesDto.managerFee)); + }); + + if (exitEntryFeeLogs !== null && exitEntryFeeLogs.length > 0) { + const exitEntryFeeFormatted = Number(exitEntryFeeLogs[0].value) / 1e18; + const tokenPriceFormatted = Number(dailyFeesDto.tokenPriceAtFeeMint) / 1e18; + dailyFeesDto.exitEntryFeeUsd = exitEntryFeeFormatted * tokenPriceFormatted; + } else dailyFeesDto.exitEntryFeeUsd = Number(0); + } +} + +const calculateFees = (dailyFees: any): number => + dailyFees.reduce((acc: number, dailyFeesDto: any) => { + const managerFee = Number(dailyFeesDto.managerFee); + const tokenPrice = Number(dailyFeesDto.tokenPriceAtFeeMint); + const managerFeeFormatted = managerFee / 1e18; + const tokenPriceFormatted = tokenPrice / 1e18; + const managerFeeUsd = managerFeeFormatted * tokenPriceFormatted + dailyFeesDto.exitEntryFeeUsd; + return acc + managerFeeUsd; + }, 0); + +const fetch = async ({ chain, getLogs, endTimestamp, startTimestamp }: FetchOptions) => { const config = CONFIG[chain]; if (!config) throw new Error(`Unsupported chain: ${chain}`); - const dailyFees = await fetchHistoricalFees(chain as CHAIN, config.torosManagerAddress, startTimestamp, endTimestamp) + const dailyFees = await fetchHistoricalFees(chain as CHAIN, config.torosManagerAddress, startTimestamp, endTimestamp); + await addEntryExitFees(dailyFees, chain as CHAIN, getLogs); return { dailyFees: calculateFees(dailyFees), From e899631b4909f44010b9e2d3fef544651c29b8a4 Mon Sep 17 00:00:00 2001 From: tomshear32 Date: Fri, 18 Oct 2024 02:37:48 +0300 Subject: [PATCH 2/3] Add fees from easyswapper addresses --- fees/toros/index.ts | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/fees/toros/index.ts b/fees/toros/index.ts index 29efdf631d..75d2819ab4 100644 --- a/fees/toros/index.ts +++ b/fees/toros/index.ts @@ -36,23 +36,27 @@ const CONFIG = { [CHAIN.OPTIMISM]: { endpoint: "https://api.studio.thegraph.com/query/48129/dhedge-v2-optimism/version/latest", torosManagerAddress: "0x813123a13d01d3f07d434673fdc89cbba523f14d", + easyswapperAddresses: ["0x3988513793bce39f0167064a9f7fc3617faf35ab", "0x2ed1bd7f66e47113672f3870308b5e867c5bb743"], }, [CHAIN.POLYGON]: { endpoint: "https://api.studio.thegraph.com/query/48129/dhedge-v2-polygon/version/latest", torosManagerAddress: "0x090e7fbd87a673ee3d0b6ccacf0e1d94fb90da59", + easyswapperAddresses: ["0xb2f1498983bf9c9442c35f772e6c1ade66a8dede", "0x45b90480d6f643de2f128db091a357c3c90399f2"], }, [CHAIN.ARBITRUM]: { endpoint: "https://api.studio.thegraph.com/query/48129/dhedge-v2-arbitrum/version/latest", torosManagerAddress: "0xfbd2b4216f422dc1eee1cff4fb64b726f099def5", + easyswapperAddresses: ["0x80b9411977c4ff8d618f2ac3f29f1e2d623c4d34", "0xa5679c4272a056bb83f039961fae7d99c48529f5"], }, [CHAIN.BASE]: { endpoint: "https://api.studio.thegraph.com/query/48129/dhedge-v2-base-mainnet/version/latest", torosManagerAddress: "0x5619ad05b0253a7e647bd2e4c01c7f40ceab0879", + easyswapperAddresses: ["0xe10ed1e5354eed0f7c9d2e16250ba8996c12db7a", "0xa907504d7a4c415b4e6e1d0866d96afe8202f0e5"], }, }; -const fetchHistoricalFees = async (chainId: CHAIN, managerAddress: string, startTimestamp: number, endTimestamp: number) => { - const { endpoint, } = CONFIG[chainId]; +const fetchHistoricalFees = async (chainId: CHAIN, startTimestamp: number, endTimestamp: number) => { + const { endpoint, torosManagerAddress} = CONFIG[chainId]; let allData = []; let skip = 0; @@ -61,7 +65,7 @@ const fetchHistoricalFees = async (chainId: CHAIN, managerAddress: string, start while (true) { try { const data = await new GraphQLClient(endpoint).request(query, { - manager: managerAddress, + manager: torosManagerAddress, startTimestamp: startTimestamp.toString(), endTimestamp: endTimestamp.toString(), first: batchSize, @@ -75,7 +79,6 @@ const fetchHistoricalFees = async (chainId: CHAIN, managerAddress: string, start skip += batchSize; if (entries.length < batchSize) break; - } catch (e) { throw new Error(`Error fetching data for chain ${chainId}: ${e.message}`); } @@ -87,23 +90,26 @@ const getTransferLogs = async (chain: string, getLogs, poolAddress: string, from return await getLogs({ target: poolAddress, topic: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', - fromBlock: fromBlock, - toBlock: toBlock, + fromBlock, + toBlock, eventAbi: 'event Transfer (address indexed from, address indexed to, uint256 value)', onlyArgs: true, }); } async function addEntryExitFees(dailyFees: any[], chain: CHAIN, getLogs: any) { + const easyswapperAddresses = CONFIG[chain].easyswapperAddresses; + for (const dailyFeesDto of dailyFees) { const transferLogs = await getTransferLogs(chain.toString(), getLogs, dailyFeesDto.pool, +dailyFeesDto.block, +dailyFeesDto.block); const exitEntryFeeLogs = transferLogs.filter(transfer => { - return (transfer.from.toLowerCase() === ZeroAddress - && transfer.to.toLowerCase() === dailyFeesDto.manager.toLowerCase() - && Number(transfer.value) !== Number(dailyFeesDto.managerFee)) - || (transfer.from.toLowerCase() === dailyFeesDto.pool.toLowerCase() - && transfer.to.toLowerCase() === dailyFeesDto.manager.toLowerCase() - && Number(transfer.value) !== Number(dailyFeesDto.managerFee)); + const from = transfer.from.toLowerCase(); + const to = transfer.to.toLowerCase(); + const isZeroAddressTransfer = from === ZeroAddress && to === dailyFeesDto.manager.toLowerCase(); + const isEasySwapperTransfer = easyswapperAddresses.includes(from) && to === dailyFeesDto.manager.toLowerCase(); + const isPoolTransfer = from === dailyFeesDto.pool.toLowerCase() && to === dailyFeesDto.manager.toLowerCase(); + const notManagerFeeTransfer = Number(transfer.value) !== Number(dailyFeesDto.managerFee); + return (isZeroAddressTransfer || isEasySwapperTransfer || isPoolTransfer) && notManagerFeeTransfer; }); if (exitEntryFeeLogs !== null && exitEntryFeeLogs.length > 0) { @@ -128,7 +134,7 @@ const fetch = async ({ chain, getLogs, endTimestamp, startTimestamp }: FetchOpti const config = CONFIG[chain]; if (!config) throw new Error(`Unsupported chain: ${chain}`); - const dailyFees = await fetchHistoricalFees(chain as CHAIN, config.torosManagerAddress, startTimestamp, endTimestamp); + const dailyFees = await fetchHistoricalFees(chain as CHAIN, startTimestamp, endTimestamp); await addEntryExitFees(dailyFees, chain as CHAIN, getLogs); return { From d9e862ca5a4f514fa43ba51a4307dc16a3d7390f Mon Sep 17 00:00:00 2001 From: 0xgnek <0xgnek@gmail.com> Date: Sun, 20 Oct 2024 13:50:16 +0000 Subject: [PATCH 3/3] fix get transfer --- fees/toros/index.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/fees/toros/index.ts b/fees/toros/index.ts index 75d2819ab4..b756aa83fb 100644 --- a/fees/toros/index.ts +++ b/fees/toros/index.ts @@ -86,22 +86,22 @@ const fetchHistoricalFees = async (chainId: CHAIN, startTimestamp: number, endTi return allData; }; -const getTransferLogs = async (chain: string, getLogs, poolAddress: string, fromBlock: number, toBlock: number): Promise => { +const getTransferLogs = async (getLogs, poolAddresss: string[]): Promise => { return await getLogs({ - target: poolAddress, + targets: poolAddresss, topic: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', - fromBlock, - toBlock, eventAbi: 'event Transfer (address indexed from, address indexed to, uint256 value)', onlyArgs: true, + flatten: false, }); } async function addEntryExitFees(dailyFees: any[], chain: CHAIN, getLogs: any) { const easyswapperAddresses = CONFIG[chain].easyswapperAddresses; - - for (const dailyFeesDto of dailyFees) { - const transferLogs = await getTransferLogs(chain.toString(), getLogs, dailyFeesDto.pool, +dailyFeesDto.block, +dailyFeesDto.block); + const poolAddresses = dailyFees.map(e => e.pool) + const _transferLogs = await getTransferLogs(getLogs, poolAddresses) + for (const [index,dailyFeesDto] of dailyFees.entries()) { + const transferLogs = _transferLogs[index]; const exitEntryFeeLogs = transferLogs.filter(transfer => { const from = transfer.from.toLowerCase(); const to = transfer.to.toLowerCase();