From 324065372ee5ec4967b4efdef9895280ea4c5f58 Mon Sep 17 00:00:00 2001 From: blueMoonWriter Date: Tue, 8 Oct 2024 09:42:20 +0800 Subject: [PATCH 1/6] add core reward --- fees/solv-finance/index.ts | 428 +++++++++++++++++++++++++------------ 1 file changed, 286 insertions(+), 142 deletions(-) diff --git a/fees/solv-finance/index.ts b/fees/solv-finance/index.ts index c17ff9145c..3a4dd06014 100644 --- a/fees/solv-finance/index.ts +++ b/fees/solv-finance/index.ts @@ -6,146 +6,174 @@ import { addTokensReceived } from "../../helpers/token"; import { httpGet } from "../../utils/fetchURL"; import { gql, request } from "graphql-request"; import { getPrices } from "../../utils/prices"; -import { BigNumber } from "bignumber.js" +import { BigNumber } from "bignumber.js"; import { Balances } from "@defillama/sdk"; - -const feesConfig = "https://raw.githubusercontent.com/solv-finance-dev/slov-protocol-defillama/main/solv-fees.json"; -const graphUrl = "https://raw.githubusercontent.com/solv-finance-dev/slov-protocol-defillama/refs/heads/main/solv-graph.json"; +import * as sdk from "@defillama/sdk"; +const feesConfig = + "https://raw.githubusercontent.com/solv-finance-dev/slov-protocol-defillama/main/solv-fees.json"; +const graphUrl = + "https://raw.githubusercontent.com/solv-finance-dev/slov-protocol-defillama/refs/heads/main/solv-graph.json"; const yields = 0.2; const chains: { - [chain: Chain]: { deployedAt: number }; + [chain: Chain]: { deployedAt: number }; } = { - [CHAIN.ETHEREUM]: { - deployedAt: 1726531200, - }, - [CHAIN.BSC]: { - deployedAt: 1726531200, - }, - [CHAIN.ARBITRUM]: { - deployedAt: 1726531200, - }, - [CHAIN.MANTLE]: { - deployedAt: 1726531200, - }, - [CHAIN.MERLIN]: { - deployedAt: 1726531200, - }, - [CHAIN.CORE]: { - deployedAt: 1726531200, - }, + [CHAIN.ETHEREUM]: { + deployedAt: 1726531200, + }, + [CHAIN.BSC]: { + deployedAt: 1726531200, + }, + [CHAIN.ARBITRUM]: { + deployedAt: 1726531200, + }, + [CHAIN.MANTLE]: { + deployedAt: 1726531200, + }, + [CHAIN.MERLIN]: { + deployedAt: 1726531200, + }, + [CHAIN.CORE]: { + deployedAt: 1726531200, + }, }; const fetch: FetchV2 = async (options) => { - const contracts: { - [chain: Chain]: { - [protocolFees: string]: { address: string[]; token: string[]; deployedAt: number }; - } - } = await httpGet(feesConfig); - - if (!contracts[options.chain]) { - return { - timestamp: new Date().getTime(), - }; - } - - const dailyFees = options.createBalances(); - const protocolFees = await protocol(options, contracts); - dailyFees.addBalances(protocolFees); + const contracts: { + [chain: Chain]: { + [protocolFees: string]: { + address: string[]; + token: string[]; + deployedAt: number; + }; + }; + } = await httpGet(feesConfig); - const poolFees = await pool(options, contracts); - dailyFees.addBalances(poolFees); + if (!contracts[options.chain]) { return { - dailyFees, - dailyRevenue: dailyFees.clone(yields) - } + timestamp: new Date().getTime(), + }; + } + + const dailyFees = options.createBalances(); + const protocolFees = await protocol(options, contracts); + dailyFees.addBalances(protocolFees); + + const poolFees = await pool(options, contracts); + dailyFees.addBalances(poolFees); + + const nativeTokenFees = await nativeToken(options, contracts); + dailyFees.addBalances(nativeTokenFees); + return { + dailyFees, + dailyRevenue: dailyFees.clone(yields), + }; }; -async function protocol(options: FetchOptions, contracts: any): Promise { - if (!contracts[options.chain]["protocolFees"]) { - return options.createBalances(); - } - const dailyFees = await addTokensReceived({ - options, - targets: contracts[options.chain]["protocolFees"].address, - tokens: contracts[options.chain]["protocolFees"].token, - }); +async function protocol( + options: FetchOptions, + contracts: any +): Promise { + if (!contracts[options.chain]["protocolFees"]) { + return options.createBalances(); + } + const dailyFees = await addTokensReceived({ + options, + targets: contracts[options.chain]["protocolFees"].address, + tokens: contracts[options.chain]["protocolFees"].token, + }); - return dailyFees; + return dailyFees; } async function pool(options: FetchOptions, contracts: any): Promise { - if (!contracts[options.chain]["poolFees"]) { - return options.createBalances(); + if (!contracts[options.chain]["poolFees"]) { + return options.createBalances(); + } + + const pools = await getGraphData( + contracts[options.chain]["poolFees"], + options.chain + ); + const shareConcretes = await concrete(pools, options); + + const fromTimestamp = getTimestampAtStartOfDayUTC(options.fromTimestamp); + const toTimestamp = getTimestampAtStartOfDayUTC(options.toTimestamp); + + const yesterdayNavs = await options.fromApi.multiCall({ + abi: "function getSubscribeNav(bytes32 poolId_, uint256 time_) view returns (uint256 nav_, uint256 navTime_)", + calls: pools.map((pool: { navOracle: string; poolId: string }) => ({ + target: pool.navOracle, + params: [pool.poolId, fromTimestamp], + })), + }); + + const todayNavs = await options.toApi.multiCall({ + abi: "function getSubscribeNav(bytes32 poolId_, uint256 time_) view returns (uint256 nav_, uint256 navTime_)", + calls: pools.map((pool: { navOracle: string; poolId: string }) => ({ + target: pool.navOracle, + params: [pool.poolId, toTimestamp], + })), + }); + + const poolBaseInfos = await options.api.multiCall({ + abi: `function slotBaseInfo(uint256 slot_) view returns (tuple(address issuer, address currency, uint64 valueDate, uint64 maturity, uint64 createTime, bool transferable, bool isValid))`, + calls: pools.map( + (index: { + contractAddress: string | number; + openFundShareSlot: any; + }) => ({ + target: shareConcretes[index.contractAddress], + params: [index.openFundShareSlot], + }) + ), + }); + + const shareTotalValues = await options.api.multiCall({ + abi: "function slotTotalValue(uint256) view returns (uint256)", + calls: pools.map( + (index: { + contractAddress: string | number; + openFundShareSlot: any; + }) => ({ + target: shareConcretes[index.contractAddress], + params: [index.openFundShareSlot], + }) + ), + }); + + const dailyFees = options.createBalances(); + for (let i = 0; i < pools.length; i++) { + const poolNavIncrease = todayNavs[i].nav_ - yesterdayNavs[i].nav_; + const poolBaseInfo = poolBaseInfos[i]; + const shareTotalValue = shareTotalValues[i]; + + if (poolNavIncrease <= 0) { + continue; } - const pools = await getGraphData(contracts[options.chain]["poolFees"], options.chain); - const shareConcretes = await concrete(pools, options); - - const fromTimestamp = getTimestampAtStartOfDayUTC(options.fromTimestamp); - const toTimestamp = getTimestampAtStartOfDayUTC(options.toTimestamp); - - const yesterdayNavs = await options.fromApi.multiCall({ - abi: 'function getSubscribeNav(bytes32 poolId_, uint256 time_) view returns (uint256 nav_, uint256 navTime_)', - calls: pools.map((pool: { navOracle: string; poolId: string }) => ({ - target: pool.navOracle, - params: [pool.poolId, fromTimestamp], - })), - }); - - const todayNavs = await options.toApi.multiCall({ - abi: 'function getSubscribeNav(bytes32 poolId_, uint256 time_) view returns (uint256 nav_, uint256 navTime_)', - calls: pools.map((pool: { navOracle: string; poolId: string }) => ({ - target: pool.navOracle, - params: [pool.poolId, toTimestamp], - })), - }); - - const poolBaseInfos = await options.api.multiCall({ - abi: `function slotBaseInfo(uint256 slot_) view returns (tuple(address issuer, address currency, uint64 valueDate, uint64 maturity, uint64 createTime, bool transferable, bool isValid))`, - calls: pools.map((index: { contractAddress: string | number; openFundShareSlot: any; }) => ({ - target: shareConcretes[index.contractAddress], - params: [index.openFundShareSlot] - })), - }); - - const shareTotalValues = await options.api.multiCall({ - abi: 'function slotTotalValue(uint256) view returns (uint256)', - calls: pools.map((index: { contractAddress: string | number; openFundShareSlot: any; }) => ({ - target: shareConcretes[index.contractAddress], - params: [index.openFundShareSlot] - })), - }); - - const dailyFees = options.createBalances(); - for (let i = 0; i < pools.length; i++) { - const poolNavIncrease = todayNavs[i].nav_ - yesterdayNavs[i].nav_; - const poolBaseInfo = poolBaseInfos[i]; - const shareTotalValue = shareTotalValues[i]; - - if (poolNavIncrease <= 0) { - continue; - } - if (shareTotalValue == 0) { - continue; - } - - const token = `${options.chain}:${poolBaseInfo.currency}`; - // PoolFee = (ShareTotalValue / 10^(ShareDecimals)) * (PoolNavIncrease / 10^(PoolTokenDecimals)) * 10^(PoolTokenDecimals) - const poolFee = BigNumber(shareTotalValue) - .dividedBy(BigNumber(10).pow(18)) - .times(BigNumber(poolNavIncrease)); - dailyFees.addBalances({ [token]: poolFee.toNumber() }); + if (shareTotalValue == 0) { + continue; } - return dailyFees; + const token = `${options.chain}:${poolBaseInfo.currency}`; + // PoolFee = (ShareTotalValue / 10^(ShareDecimals)) * (PoolNavIncrease / 10^(PoolTokenDecimals)) * 10^(PoolTokenDecimals) + const poolFee = BigNumber(shareTotalValue) + .dividedBy(BigNumber(10).pow(18)) + .times(BigNumber(poolNavIncrease)); + dailyFees.addBalances({ [token]: poolFee.toNumber() }); + } + + return dailyFees; } async function getGraphData(poolId: string[], chain: Chain) { - const graphUrlList: { - [chain: Chain]: string; - } = (await httpGet(graphUrl)) - const query = gql`{ - poolOrderInfos(first: 1000 where:{poolId_in: ${JSON.stringify(poolId)}}) { + const graphUrlList: { + [chain: Chain]: string; + } = await httpGet(graphUrl); + const query = gql`{ + poolOrderInfos(first: 1000 where:{poolId_in: ${JSON.stringify( + poolId + )}}) { marketContractAddress contractAddress navOracle @@ -154,45 +182,161 @@ async function getGraphData(poolId: string[], chain: Chain) { openFundShareSlot } }`; - let response: any; - if (graphUrlList[chain]) { - response = (await request(graphUrlList[chain], query)).poolOrderInfos; + let response: any; + if (graphUrlList[chain]) { + response = (await request(graphUrlList[chain], query)).poolOrderInfos; + } + + return response; +} + +async function concrete(slots: any[], options: FetchOptions): Promise { + var slotsList: any[] = []; + var only = {}; + for (var i = 0; i < slots.length; i++) { + if (!only[slots[i].contractAddress]) { + slotsList.push(slots[i]); + only[slots[i].contractAddress] = true; } + } - return response; + const concreteLists = await options.api.multiCall({ + calls: slotsList.map((index) => index.contractAddress), + abi: "address:concrete", + }); + + let concretes = {}; + for (var k = 0; k < concreteLists.length; k++) { + concretes[slotsList[k].contractAddress] = concreteLists[k]; + } + + return concretes; } +interface IBalanceChange { + block: number; + amount: BigNumber; +} +async function nativeToken( + options: FetchOptions, + contracts: any +): Promise { + if (!contracts[options.chain]["nativeTokenFees"]) { + return options.createBalances(); + } -async function concrete(slots: any[], options: FetchOptions): Promise { - var slotsList: any[] = []; - var only = {}; - for (var i = 0; i < slots.length; i++) { - if (!only[slots[i].contractAddress]) { - slotsList.push(slots[i]); - only[slots[i].contractAddress] = true; - } + const fromBlockHeight = await options.getFromBlock(); + const toBlockHeight = await options.getToBlock(); + + const feeAmount = await getNativeTokenDepositAmount( + contracts[options.chain]["nativeTokenFees"].address, + fromBlockHeight, + toBlockHeight, + options.chain + ); + const fees = options.createBalances(); + fees.addGasToken(feeAmount.toString(10)); + return fees; +} + +async function getNativeTokenDepositAmount( + targetAddress: string, + fromBlock: number, + toBlock: number, + chain: string +): Promise { + const balanceChanges = await foundNativeTokenTransfer( + targetAddress, + fromBlock, + toBlock, + chain + ); + let balance = BigNumber(0); + for (const balChangeInfo of balanceChanges) { + if (balChangeInfo.amount.isPositive()) { + balance = balance.plus(balChangeInfo.amount); } + } + return balance; +} + +async function foundNativeTokenTransfer( + targetAddress: string, + fromBlock: number, + toBlock: number, + chain: string +): Promise { + const logPrefix = `${fromBlock}_${toBlock}`; - const concreteLists = await options.api.multiCall({ - calls: slotsList.map((index) => index.contractAddress), - abi: 'address:concrete', - }) + if (fromBlock > toBlock) { + throw new Error(`${fromBlock} greater than ${toBlock}`); + } - let concretes = {}; - for (var k = 0; k < concreteLists.length; k++) { - concretes[slotsList[k].contractAddress] = concreteLists[k]; + if (fromBlock === toBlock) { + const [preAmount, afterAmount] = await Promise.all([ + getBalance(targetAddress, fromBlock - 1, chain), + getBalance(targetAddress, fromBlock, chain), + ]); + if (preAmount.isEqualTo(afterAmount)) { + return []; + } else { + return [{ block: fromBlock, amount: afterAmount.minus(preAmount) }]; } + } + const [fromAmount, toAmount] = await Promise.all([ + getBalance(targetAddress, fromBlock - 1, chain), + getBalance(targetAddress, toBlock, chain), + ]); + if (!toAmount.isEqualTo(fromAmount)) { + const middleBlock = Math.floor((fromBlock + toBlock) / 2); + const leftResults = await foundNativeTokenTransfer( + targetAddress, + fromBlock, + middleBlock, + chain + ); + const rightResults = await foundNativeTokenTransfer( + targetAddress, + middleBlock + 1, + toBlock, + chain + ); - return concretes; + return [leftResults, rightResults].flat(); + } else { + return []; + } +} + +async function getBalance( + address: string, + block: number, + chain: string +): Promise { + let retryCount = 0; + while (retryCount < 3) { + try { + const provider = sdk.getProvider(chain, true); + const amount = (await provider.getBalance( + address, + block + )) as any as string; + return BigNumber(amount, 10); + } catch (err) { + retryCount++; + console.log(block, err); + } + } + throw new Error(`retry max ${block}`); } const adapter: SimpleAdapter = { adapter: {}, version: 2 }; Object.keys(chains).forEach((chain: Chain) => { - adapter.adapter[chain] = { - fetch, - start: chains[chain].deployedAt, - }; + adapter.adapter[chain] = { + fetch, + start: chains[chain].deployedAt, + }; }); export default adapter; From 7e1e14920e0ad5bd75e5d992a611580e863d0a44 Mon Sep 17 00:00:00 2001 From: buchaoqun Date: Thu, 10 Oct 2024 14:14:31 +0800 Subject: [PATCH 2/6] del console log --- fees/solv-finance/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/fees/solv-finance/index.ts b/fees/solv-finance/index.ts index 3a4dd06014..7426d19d82 100644 --- a/fees/solv-finance/index.ts +++ b/fees/solv-finance/index.ts @@ -324,7 +324,6 @@ async function getBalance( return BigNumber(amount, 10); } catch (err) { retryCount++; - console.log(block, err); } } throw new Error(`retry max ${block}`); From 826caffae60759c794092494a3746a12b782addf Mon Sep 17 00:00:00 2001 From: buchaoqun Date: Thu, 24 Oct 2024 17:19:45 +0800 Subject: [PATCH 3/6] add network scroll add revenues --- fees/solv-finance/index.ts | 52 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/fees/solv-finance/index.ts b/fees/solv-finance/index.ts index 5a4003a548..79831aba73 100644 --- a/fees/solv-finance/index.ts +++ b/fees/solv-finance/index.ts @@ -32,6 +32,9 @@ const chains: { [CHAIN.CORE]: { deployedAt: 1726531200, }, + [CHAIN.SCROLL]: { + deployedAt: 1726531200, + }, }; const fetch: FetchV2 = async (options) => { @@ -58,12 +61,57 @@ const fetch: FetchV2 = async (options) => { const nativeTokenFees = await nativeToken(options, contracts); dailyFees.addBalances(nativeTokenFees); + + const dailyRevenue = options.createBalances(); + const receivedRevenues = await revenues(options, contracts); + dailyRevenue.addBalances(receivedRevenues); + + dailyRevenue.addBalances(dailyFees.clone(yields)); + return { dailyFees, - dailyRevenue: dailyFees.clone(yields), + dailyRevenue, }; }; + +async function revenues(options: FetchOptions, contracts: any): Promise { + const dailyRevenues = options.createBalances(); + + const receivedRevenue = await receivedRevenues(options, contracts); + dailyRevenues.addBalances(receivedRevenue); + + const nativeTokenRevenue = await nativeTokenRevenues(options, contracts); + dailyRevenues.addBalances(nativeTokenRevenue); + + return dailyRevenues; +} + +async function receivedRevenues(options: FetchOptions, contracts: any): Promise { + const receivedRevenueConfig = contracts[options.chain]?.receivedRevenue; + if (!receivedRevenueConfig) { + return options.createBalances(); + } + + return addTokensReceived({ + options, + targets: receivedRevenueConfig.address, + tokens: receivedRevenueConfig.token, + }); +} + +async function nativeTokenRevenues(options: FetchOptions, contracts: any): Promise { + const nativeTokenConfig = contracts[options.chain]?.nativeTokenRevenue; + if (!nativeTokenConfig) { + return options.createBalances(); + } + + return addGasTokensReceived({ + multisig: nativeTokenConfig.address, + options, + }); +} + async function protocol( options: FetchOptions, contracts: any @@ -210,7 +258,7 @@ async function nativeToken( return options.createBalances(); } const multisig = contracts[options.chain]["nativeTokenFees"].address; - return addGasTokensReceived({ multisig, options }) + return addGasTokensReceived({ multisig, options }) } const adapter: SimpleAdapter = { adapter: {}, version: 2 }; From 349c96326e11cf257c0eb5eecabe64d006acf491 Mon Sep 17 00:00:00 2001 From: buchaoqun Date: Mon, 28 Oct 2024 11:55:23 +0800 Subject: [PATCH 4/6] add solana network fees and revenue --- fees/solv-finance/index.ts | 69 ++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 18 deletions(-) diff --git a/fees/solv-finance/index.ts b/fees/solv-finance/index.ts index 79831aba73..49f49f143f 100644 --- a/fees/solv-finance/index.ts +++ b/fees/solv-finance/index.ts @@ -1,7 +1,7 @@ import { Chain } from "@defillama/sdk/build/general"; import { CHAIN } from "../../helpers/chains"; import { FetchOptions, FetchV2, SimpleAdapter } from "../../adapters/types"; -import { addGasTokensReceived, addTokensReceived } from "../../helpers/token"; +import { addGasTokensReceived, addTokensReceived, getSolanaReceived } from "../../helpers/token"; import { request } from "graphql-request"; import { Balances } from "@defillama/sdk"; import { getConfig } from "../../helpers/cache"; @@ -53,28 +53,21 @@ const fetch: FetchV2 = async (options) => { const dailyFees = options.createBalances(); - const protocolFees = await protocol(options, contracts); - dailyFees.addBalances(protocolFees); - - const poolFees = await pool(options, contracts); - dailyFees.addBalances(poolFees); - - const nativeTokenFees = await nativeToken(options, contracts); - dailyFees.addBalances(nativeTokenFees); + const feeRevenue = await feeRevenues(options, contracts); + dailyFees.addBalances(feeRevenue); const dailyRevenue = options.createBalances(); const receivedRevenues = await revenues(options, contracts); dailyRevenue.addBalances(receivedRevenues); dailyRevenue.addBalances(dailyFees.clone(yields)); - + return { dailyFees, dailyRevenue, }; }; - async function revenues(options: FetchOptions, contracts: any): Promise { const dailyRevenues = options.createBalances(); @@ -84,34 +77,65 @@ async function revenues(options: FetchOptions, contracts: any): Promise { const receivedRevenueConfig = contracts[options.chain]?.receivedRevenue; if (!receivedRevenueConfig) { - return options.createBalances(); + return options.createBalances(); } return addTokensReceived({ - options, - targets: receivedRevenueConfig.address, - tokens: receivedRevenueConfig.token, + options, + targets: receivedRevenueConfig.address, + tokens: receivedRevenueConfig.token, }); } async function nativeTokenRevenues(options: FetchOptions, contracts: any): Promise { const nativeTokenConfig = contracts[options.chain]?.nativeTokenRevenue; if (!nativeTokenConfig) { - return options.createBalances(); + return options.createBalances(); } return addGasTokensReceived({ - multisig: nativeTokenConfig.address, - options, + multisig: nativeTokenConfig.address, + options, }); } +async function solanaRevenues(options: FetchOptions, contracts: any): Promise { + const solanaRevenueConfig = contracts[options.chain]?.solanaRevenue; + if (!solanaRevenueConfig) { + return options.createBalances(); + } + + return await getSolanaReceived({ options, targets: solanaRevenueConfig }); +} + + +async function feeRevenues(options: FetchOptions, contracts: any): Promise { + const dailyFees = options.createBalances(); + + const protocolFees = await protocol(options, contracts); + dailyFees.addBalances(protocolFees); + + const poolFees = await pool(options, contracts); + dailyFees.addBalances(poolFees); + + const nativeTokenFees = await nativeToken(options, contracts); + dailyFees.addBalances(nativeTokenFees); + + const solanaFees = await solanas(options, contracts); + dailyFees.addBalances(solanaFees); + + return dailyFees; +} + async function protocol( options: FetchOptions, contracts: any @@ -261,6 +285,15 @@ async function nativeToken( return addGasTokensReceived({ multisig, options }) } +async function solanas(options: FetchOptions, contracts: any): Promise { + const solanaFeesConfig = contracts[options.chain]?.solanaFees; + if (!solanaFeesConfig) { + return options.createBalances(); + } + + return await getSolanaReceived({ options, targets: solanaFeesConfig }); +} + const adapter: SimpleAdapter = { adapter: {}, version: 2 }; Object.keys(chains).forEach((chain: Chain) => { From 94e772b25ad4e51503a2b50d5ac7ed04d4a98572 Mon Sep 17 00:00:00 2001 From: buchaoqun Date: Mon, 28 Oct 2024 14:06:13 +0800 Subject: [PATCH 5/6] add solana chain --- fees/solv-finance/index.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fees/solv-finance/index.ts b/fees/solv-finance/index.ts index 49f49f143f..11938b7b05 100644 --- a/fees/solv-finance/index.ts +++ b/fees/solv-finance/index.ts @@ -35,6 +35,9 @@ const chains: { [CHAIN.SCROLL]: { deployedAt: 1726531200, }, + [CHAIN.SOLANA]: { + deployedAt: 1726531200, + }, }; const fetch: FetchV2 = async (options) => { From d0a7692046fb2479e2b13df7e3581e9d613eaa5a Mon Sep 17 00:00:00 2001 From: buchaoqun Date: Fri, 22 Nov 2024 17:18:42 +0800 Subject: [PATCH 6/6] add pure revenues --- fees/solv-finance/index.ts | 146 ++++++++++++++----------------------- 1 file changed, 54 insertions(+), 92 deletions(-) diff --git a/fees/solv-finance/index.ts b/fees/solv-finance/index.ts index 11938b7b05..bd639cec46 100644 --- a/fees/solv-finance/index.ts +++ b/fees/solv-finance/index.ts @@ -6,38 +6,20 @@ import { request } from "graphql-request"; import { Balances } from "@defillama/sdk"; import { getConfig } from "../../helpers/cache"; const feesConfig = - "https://raw.githubusercontent.com/solv-finance-dev/slov-protocol-defillama/main/solv-fees.json"; + "https://raw.githubusercontent.com/solv-finance/solv-protocol-defillama/main/solv-fees.json"; const graphUrl = - "https://raw.githubusercontent.com/solv-finance-dev/slov-protocol-defillama/refs/heads/main/solv-graph.json"; + "https://raw.githubusercontent.com/solv-finance/solv-protocol-defillama/refs/heads/main/solv-graph.json"; const yields = 0.2; -const chains: { - [chain: Chain]: { deployedAt: number }; -} = { - [CHAIN.ETHEREUM]: { - deployedAt: 1726531200, - }, - [CHAIN.BSC]: { - deployedAt: 1726531200, - }, - [CHAIN.ARBITRUM]: { - deployedAt: 1726531200, - }, - [CHAIN.MANTLE]: { - deployedAt: 1726531200, - }, - [CHAIN.MERLIN]: { - deployedAt: 1726531200, - }, - [CHAIN.CORE]: { - deployedAt: 1726531200, - }, - [CHAIN.SCROLL]: { - deployedAt: 1726531200, - }, - [CHAIN.SOLANA]: { - deployedAt: 1726531200, - }, +const chains: { [chain: Chain]: { deployedAt: number } } = { + [CHAIN.ETHEREUM]: { deployedAt: 1726531200 }, + [CHAIN.BSC]: { deployedAt: 1726531200 }, + [CHAIN.ARBITRUM]: { deployedAt: 1726531200 }, + [CHAIN.MANTLE]: { deployedAt: 1726531200 }, + [CHAIN.MERLIN]: { deployedAt: 1726531200 }, + [CHAIN.CORE]: { deployedAt: 1726531200 }, + [CHAIN.SCROLL]: { deployedAt: 1726531200 }, + [CHAIN.SOLANA]: { deployedAt: 1726531200 }, }; const fetch: FetchV2 = async (options) => { @@ -55,111 +37,90 @@ const fetch: FetchV2 = async (options) => { return {} - const dailyFees = options.createBalances(); - const feeRevenue = await feeRevenues(options, contracts); - dailyFees.addBalances(feeRevenue); - - const dailyRevenue = options.createBalances(); - const receivedRevenues = await revenues(options, contracts); - dailyRevenue.addBalances(receivedRevenues); + const dailyFees = await feeRevenues(options, contracts); + const dailyRevenue = await revenues(options, contracts); + const pureRevenueBalances = await pureRevenues(options, contracts); dailyRevenue.addBalances(dailyFees.clone(yields)); + dailyFees.addBalances(pureRevenueBalances); + dailyRevenue.addBalances(pureRevenueBalances); + return { dailyFees, dailyRevenue, }; }; +async function pureRevenues(options: FetchOptions, contracts: any): Promise { + const pureRevenues = options.createBalances(); + + const receivedPureRevenue = await received(options, contracts, "receivedPureRevenue"); + pureRevenues.addBalances(receivedPureRevenue); + + const nativeTokenPureRevenue = await nativeToken(options, contracts, "nativeTokenPureRevenue"); + pureRevenues.addBalances(nativeTokenPureRevenue); + + return pureRevenues; +} + async function revenues(options: FetchOptions, contracts: any): Promise { const dailyRevenues = options.createBalances(); - const receivedRevenue = await receivedRevenues(options, contracts); + const receivedRevenue = await received(options, contracts, "receivedRevenue"); dailyRevenues.addBalances(receivedRevenue); - const nativeTokenRevenue = await nativeTokenRevenues(options, contracts); + const nativeTokenRevenue = await nativeToken(options, contracts, "nativeTokenRevenue"); dailyRevenues.addBalances(nativeTokenRevenue); - const solanaRevenue = await solanaRevenues(options, contracts); + const solanaRevenue = await solanas(options, contracts, "solanaRevenue"); dailyRevenues.addBalances(solanaRevenue); return dailyRevenues; } -async function receivedRevenues(options: FetchOptions, contracts: any): Promise { - const receivedRevenueConfig = contracts[options.chain]?.receivedRevenue; - if (!receivedRevenueConfig) { - return options.createBalances(); - } - - return addTokensReceived({ - options, - targets: receivedRevenueConfig.address, - tokens: receivedRevenueConfig.token, - }); -} - -async function nativeTokenRevenues(options: FetchOptions, contracts: any): Promise { - const nativeTokenConfig = contracts[options.chain]?.nativeTokenRevenue; - if (!nativeTokenConfig) { - return options.createBalances(); - } - - return addGasTokensReceived({ - multisig: nativeTokenConfig.address, - options, - }); -} - -async function solanaRevenues(options: FetchOptions, contracts: any): Promise { - const solanaRevenueConfig = contracts[options.chain]?.solanaRevenue; - if (!solanaRevenueConfig) { - return options.createBalances(); - } - - return await getSolanaReceived({ options, targets: solanaRevenueConfig }); -} - - async function feeRevenues(options: FetchOptions, contracts: any): Promise { const dailyFees = options.createBalances(); - const protocolFees = await protocol(options, contracts); + const protocolFees = await received(options, contracts, "protocolFees"); dailyFees.addBalances(protocolFees); - const poolFees = await pool(options, contracts); + const poolFees = await pool(options, contracts, "poolFees"); dailyFees.addBalances(poolFees); - const nativeTokenFees = await nativeToken(options, contracts); + const nativeTokenFees = await nativeToken(options, contracts, "nativeTokenFees"); dailyFees.addBalances(nativeTokenFees); - const solanaFees = await solanas(options, contracts); + const solanaFees = await solanas(options, contracts, "solanaFees"); dailyFees.addBalances(solanaFees); return dailyFees; } -async function protocol( +async function received( options: FetchOptions, - contracts: any + contracts: any, + configKey: string ): Promise { - if (!contracts[options.chain]["protocolFees"]) { + const protocolConfig = contracts[options.chain]?.[configKey]; + if (!protocolConfig) { return options.createBalances(); } return addTokensReceived({ options, - targets: contracts[options.chain]["protocolFees"].address, - tokens: contracts[options.chain]["protocolFees"].token, + targets: protocolConfig.address, + tokens: protocolConfig.token, }); } -async function pool(options: FetchOptions, contracts: any): Promise { - if (!contracts[options.chain]["poolFees"]) { +async function pool(options: FetchOptions, contracts: any, configKey: string): Promise { + const poolConfig = contracts[options.chain]?.[configKey]; + if (!poolConfig) { return options.createBalances(); } const pools = await getGraphData( - contracts[options.chain]["poolFees"], + poolConfig, options.chain ); const shareConcretes = await concrete(pools, options); @@ -279,17 +240,18 @@ async function concrete(slots: any[], options: FetchOptions): Promise { async function nativeToken( options: FetchOptions, - contracts: any + contracts: any, configKey: string ): Promise { - if (!contracts[options.chain]["nativeTokenFees"]) { + const nativeTokenConfig = contracts[options.chain]?.[configKey]; + if (!nativeTokenConfig) { return options.createBalances(); } - const multisig = contracts[options.chain]["nativeTokenFees"].address; + const multisig = nativeTokenConfig.address; return addGasTokensReceived({ multisig, options }) } -async function solanas(options: FetchOptions, contracts: any): Promise { - const solanaFeesConfig = contracts[options.chain]?.solanaFees; +async function solanas(options: FetchOptions, contracts: any, configKey: string): Promise { + const solanaFeesConfig = contracts[options.chain]?.[configKey]; if (!solanaFeesConfig) { return options.createBalances(); } @@ -306,4 +268,4 @@ Object.keys(chains).forEach((chain: Chain) => { }; }); -export default adapter; +export default adapter; \ No newline at end of file