Skip to content

Commit

Permalink
Merge pull request #2443 from TomShear/refactor/toros-use-entry-exit-…
Browse files Browse the repository at this point in the history
…fees-events
  • Loading branch information
dtmkeng authored Feb 21, 2025
2 parents 9789bde + faab738 commit c2afa99
Showing 1 changed file with 54 additions and 49 deletions.
103 changes: 54 additions & 49 deletions fees/toros/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,31 @@
import { FetchOptions, SimpleAdapter } from "../../adapters/types";
import { CHAIN } from "../../helpers/chains";
import { GraphQLClient } from "graphql-request";
import { ZeroAddress } from "ethers";

const query = `
const queryManagerFeeMinteds = `
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, pool, manager, block }
}`

const queryEntryFeeMinteds = `
query entryFeeMinteds($manager: Bytes!, $startTimestamp: BigInt!, $endTimestamp: BigInt!, $first: Int!, $skip: Int!) {
entryFeeMinteds(
where: { managerAddress: $manager, time_gte: $startTimestamp, time_lte: $endTimestamp },
first: $first, skip: $skip, orderBy: time, orderDirection: desc
) { entryFeeAmount, tokenPrice }
}`

const queryExitFeeMinteds = `
query exitFeeMinteds($manager: Bytes!, $startTimestamp: BigInt!, $endTimestamp: BigInt!, $first: Int!, $skip: Int!) {
exitFeeMinteds(
where: { managerAddress: $manager, time_gte: $startTimestamp, time_lte: $endTimestamp },
first: $first, skip: $skip, orderBy: time, orderDirection: desc
) { exitFeeAmount, tokenPrice }
}`

// gql`
// query managerFeeMinteds($manager: Bytes!, $startTimestamp: BigInt!, $endTimestamp: BigInt!) {
// managerFeeMinteds(
Expand All @@ -36,26 +52,22 @@ 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", "0xf067575eb60c7587c11e867907aa7284833704d1"],
},
};

const fetchHistoricalFees = async (chainId: CHAIN, startTimestamp: number, endTimestamp: number) => {
const fetchHistoricalFees = async (chainId: CHAIN, query: string, dataField: string, startTimestamp: number, endTimestamp: number) => {
const { endpoint, torosManagerAddress} = CONFIG[chainId];

let allData = [];
Expand All @@ -72,7 +84,7 @@ const fetchHistoricalFees = async (chainId: CHAIN, startTimestamp: number, endTi
skip
});

const entries = data.managerFeeMinteds
const entries = data[dataField];
if (entries.length === 0) break;

allData = allData.concat(entries);
Expand All @@ -86,60 +98,53 @@ const fetchHistoricalFees = async (chainId: CHAIN, startTimestamp: number, endTi
return allData;
};

const getTransferLogs = async (getLogs, poolAddresss: string[]): Promise<any> => {
return await getLogs({
targets: poolAddresss,
topic: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
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;
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();
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) {
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 =>
const calculateManagerFees = (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;
const managerFeeUsd = managerFeeFormatted * tokenPriceFormatted;
return acc + managerFeeUsd;
}, 0);

const fetch = async ({ chain, getLogs, endTimestamp, startTimestamp }: FetchOptions) => {
const calculateEntryFees = (data: any): number =>
data.reduce((acc: number, item: any) => {
const entryFee = Number(item.entryFeeAmount);
const tokenPrice = Number(item.tokenPrice);
const entryFeeFormatted = entryFee / 1e18;
const tokenPriceFormatted = tokenPrice / 1e18;
const result = entryFeeFormatted * tokenPriceFormatted;
return acc + result;
}, 0);

const calculateExitFees = (data: any): number =>
data.reduce((acc: number, item: any) => {
const exitFee = Number(item.exitFeeAmount);
const tokenPrice = Number(item.tokenPrice);
const exitFeeFormatted = exitFee / 1e18;
const tokenPriceFormatted = tokenPrice / 1e18;
const result = exitFeeFormatted * tokenPriceFormatted;
return acc + result;
}, 0);

const fetch = async ({ chain, endTimestamp, startTimestamp }: FetchOptions) => {
const config = CONFIG[chain];
if (!config) throw new Error(`Unsupported chain: ${chain}`);

const dailyFees = await fetchHistoricalFees(chain as CHAIN, startTimestamp, endTimestamp);
await addEntryExitFees(dailyFees, chain as CHAIN, getLogs);
const dailyManagerFeesEvents = await fetchHistoricalFees(chain as CHAIN, queryManagerFeeMinteds, 'managerFeeMinteds', startTimestamp, endTimestamp);
const dailyEntryFeesEvents = await fetchHistoricalFees(chain as CHAIN, queryEntryFeeMinteds, 'entryFeeMinteds', startTimestamp, endTimestamp);
const dailyExitFeesEvents = await fetchHistoricalFees(chain as CHAIN, queryExitFeeMinteds, 'exitFeeMinteds', startTimestamp, endTimestamp);

const managerFees = calculateManagerFees(dailyManagerFeesEvents);
const entryFees = calculateEntryFees(dailyEntryFeesEvents);
const exitFees = calculateExitFees(dailyExitFeesEvents);

const dailyFees = managerFees + entryFees + exitFees;

return {
dailyFees: calculateFees(dailyFees),
dailyRevenue: calculateFees(dailyFees),
dailyFees: dailyFees,
dailyRevenue: dailyFees,
timestamp: endTimestamp,
};
}
Expand Down

0 comments on commit c2afa99

Please sign in to comment.