From 2c22f5ecb1ab434ace3250ec92367bc7fadc4a8d Mon Sep 17 00:00:00 2001 From: Prasenjit Kaninde <31060173+prasenjit-26@users.noreply.github.com> Date: Thu, 23 Nov 2023 16:02:50 +0530 Subject: [PATCH] sdk adapter for chimpexchange --- dexs/chimpexchange/index.ts | 77 +++++++++++++++++++++ fees/chimpexchange.ts | 130 ++++++++++++++++++++++++++++++++++++ 2 files changed, 207 insertions(+) create mode 100644 dexs/chimpexchange/index.ts create mode 100644 fees/chimpexchange.ts diff --git a/dexs/chimpexchange/index.ts b/dexs/chimpexchange/index.ts new file mode 100644 index 0000000000..7591ced545 --- /dev/null +++ b/dexs/chimpexchange/index.ts @@ -0,0 +1,77 @@ +import { Chain } from "@defillama/sdk/build/general"; +import request, { gql } from "graphql-request"; +import { + SimpleAdapter, + ChainEndpoints, + FetchResultVolume, +} from "../../adapters/types"; +import { CHAIN } from "../../helpers/chains"; +import { getStartTimestamp } from "../../helpers/getStartTimestamp"; +import { getTimestampAtStartOfDayUTC } from "../../utils/date"; + +const endpoints: ChainEndpoints = { + [CHAIN.LINEA]: + "https://graph-query.linea.build/subgraphs/name/Chimp-Exchange/chimp-exchange-subgraph", +}; + +interface IPool { + id: string; + swapVolume: string; +} +interface IPoolSnapshot { + today: IPool[]; + yesterday: IPool[]; +} + +const graphs = (chain: Chain) => { + return async (timestamp: number): Promise => { + const startTimestamp = getTimestampAtStartOfDayUTC(timestamp); + const fromTimestamp = startTimestamp - 60 * 60 * 24; + const toTimestamp = startTimestamp; + const graphQuery = gql`query fees { + today:poolSnapshots(where: {timestamp:${toTimestamp}}, orderBy:swapFees, orderDirection: desc) { + id + swapVolume + } + yesterday:poolSnapshots(where: {timestamp:${fromTimestamp}}, orderBy:swapFees, orderDirection: desc) { + id + swapVolume + } + }`; + // const blackList = ['0x93d199263632a4ef4bb438f1feb99e57b4b5f0bd0000000000000000000005c2'] + const graphRes: IPoolSnapshot = await request(endpoints[chain], graphQuery); + const dailyVolume = graphRes["today"] + .map((p: IPool) => { + const yesterdayValue = Number( + graphRes.yesterday.find( + (e: IPool) => e.id.split("-")[0] === p.id.split("-")[0] + )?.swapVolume || "0" + ); + if (yesterdayValue === 0) return 0; + return Number(p.swapVolume) - yesterdayValue; + }) + .filter((e) => e < 100_000_000) + .reduce((a: number, b: number) => a + b, 0); + + return { + dailyVolume: `${dailyVolume}`, + timestamp, + }; + }; +}; + +const adapter: SimpleAdapter = { + adapter: { + [CHAIN.LINEA]: { + fetch: graphs(CHAIN.LINEA), + start: getStartTimestamp({ + endpoints, + chain: CHAIN.LINEA, + dailyDataField: `balancerSnapshots`, + dateField: "timestamp", + volumeField: "totalSwapVolume", + }), + }, + }, +}; +export default adapter; diff --git a/fees/chimpexchange.ts b/fees/chimpexchange.ts new file mode 100644 index 0000000000..68038584c0 --- /dev/null +++ b/fees/chimpexchange.ts @@ -0,0 +1,130 @@ +import { Adapter } from "../adapters/types"; +import { CHAIN } from "../helpers/chains"; +import { request, gql } from "graphql-request"; +import type { ChainEndpoints } from "../adapters/types"; +import { Chain } from "@defillama/sdk/build/general"; +import BigNumber from "bignumber.js"; +import { getTimestampAtStartOfDayUTC } from "../utils/date"; + +const endpoints = { + [CHAIN.LINEA]: + "https://graph-query.linea.build/subgraphs/name/Chimp-Exchange/chimp-exchange-subgraph", +}; + +interface IPool { + id: string; + swapFees: string; + protocolFee: string; +} + +interface IPoolSnapshot { + today: IPool[]; + yesterday: IPool[]; + tenPcFeeChange: { + totalSwapFee: string; + timestamp: number; + }; + fiftyPcFeeChange: { + totalSwapFee: string; + timestamp: number; + }; +} + +const graphs = (graphUrls: ChainEndpoints) => { + return (chain: Chain) => { + return async (timestamp: number) => { + const startTimestamp = getTimestampAtStartOfDayUTC(timestamp); + const fromTimestamp = startTimestamp - 60 * 60 * 24; + const toTimestamp = startTimestamp; + const graphQuery = gql`query fees { + today:poolSnapshots(where: {timestamp:${toTimestamp}}, orderBy:swapFees, orderDirection: desc) { + id + swapFees + protocolFee + } + yesterday:poolSnapshots(where: {timestamp:${fromTimestamp}}, orderBy:swapFees, orderDirection: desc) { + id + swapFees + protocolFee + } + }`; + const graphRes: IPoolSnapshot = await request( + graphUrls[chain], + graphQuery + ); + const dailyFee = graphRes["today"] + .map((e: IPool) => { + const yesterdayValue = new BigNumber( + graphRes["yesterday"].find( + (p: IPool) => p.id.split("-")[0] === e.id.split("-")[0] + )?.swapFees || 0 + ); + console.log("yesterdayValue", yesterdayValue.toNumber()); + if (yesterdayValue.toNumber() === 0) return new BigNumber("0"); + return new BigNumber(e.swapFees).minus(yesterdayValue); + }) + .filter((e) => new BigNumber(e).toNumber() < 10000) + .reduce((a: BigNumber, b: BigNumber) => a.plus(b), new BigNumber("0")); + + const currentTotalSwapFees = graphRes["today"] + .map((e: IPool) => new BigNumber(e.swapFees)) + .reduce((a: BigNumber, b: BigNumber) => a.plus(b), new BigNumber("0")); + const dailyRevenue = "0"; + const totalRevenue = "0"; + + const dailyProtocolFee = graphRes["today"] + .map((e: IPool) => { + const yesterdayValue = new BigNumber( + graphRes["yesterday"].find( + (p: IPool) => p.id.split("-")[0] === e.id.split("-")[0] + )?.protocolFee || 0 + ); + if (yesterdayValue.toNumber() === 0) return new BigNumber("0"); + return new BigNumber(e.protocolFee).minus(yesterdayValue); + }) + .filter((e) => new BigNumber(e).toNumber() < 10000) + .reduce((a: BigNumber, b: BigNumber) => a.plus(b), new BigNumber("0")); + + return { + timestamp, + totalUserFees: currentTotalSwapFees.toString(), + dailyUserFees: dailyFee.toString(), + totalFees: currentTotalSwapFees.toString(), + dailyFees: dailyFee.toString(), + totalRevenue: dailyProtocolFee.toString(), // balancer v2 subgraph does not flash loan fees yet + dailyRevenue: dailyProtocolFee.toString(), // balancer v2 subgraph does not flash loan fees yet + totalProtocolRevenue: totalRevenue.toString(), + dailyProtocolRevenue: dailyRevenue.toString(), + totalSupplySideRevenue: currentTotalSwapFees + .minus(totalRevenue.toString()) + .toString(), + dailySupplySideRevenue: new BigNumber(dailyFee.toString()) + .minus(dailyRevenue.toString()) + .toString(), + }; + }; + }; +}; + +const methodology = { + UserFees: "Trading fees paid by users, ranging from 0.0001% to 10%", + Fees: "All trading fees collected (doesn't include withdrawal and flash loan fees)", + Revenue: "Protocol revenue from all fees collected", + ProtocolRevenue: "Set to 10% of collected fees by a governance vote", + SupplySideRevenue: + "A small percentage of the trade paid by traders to pool LPs, set by the pool creator or dynamically optimized by Gauntlet", +}; + +const adapter: Adapter = { + adapter: { + [CHAIN.LINEA]: { + fetch: graphs(endpoints)(CHAIN.LINEA), + start: async () => 605519, + meta: { + methodology, + }, + }, + }, +}; + +export default adapter;