11import * as sdk from "@defillama/sdk" ;
22import { BaseAdapter , FetchOptions , IStartTimestamp , SimpleAdapter } from "../../adapters/types" ;
33import { ABI , EulerConfigs , MorphoConfigs } from "./configs" ;
4- import { METRIC } from "../metrics" ;
4+
5+ const METRICS = {
6+ // use this label for all yield sources if breakdownFees was not set
7+ AssetYields : 'Assets Yields' ,
8+
9+ // set
10+ OtherAssetYields : 'Other Asset Yields' ,
11+ OtherAssetYieldsToSuppliers : 'Other Asset Yields Distributed To Supliers' ,
12+ OtherAssetYieldsToCurator : 'Other Asset Yields To Curator' ,
13+ MorphoYields : 'Morpho Yields' ,
14+ MorphoYieldsToSuppliers : 'Morpho Yields Distributed To Supliers' ,
15+ MorphoPerformanceFee : 'Morpho Performance Fees' ,
16+ MorphoManagementFee : 'Morpho Performance Fees' ,
17+ EulerYields : 'Euler Yields' ,
18+ EulerYieldsToSuppliers : 'Euler Yields Distributed To Supliers' ,
19+ EulerPerformanceFee : 'Euler Performance Fees' ,
20+ }
521
622export interface CuratorConfig {
723 methodology ?: any ;
8-
24+ breakdownFees ?: boolean ;
925 vaults : {
1026 // chain =>
1127 [ key : string ] : {
@@ -24,9 +40,9 @@ export interface CuratorConfig {
2440}
2541
2642interface Balances {
27- dailyFees : sdk . Balances ,
28- dailyRevenue : sdk . Balances ,
29- dailySupplySideRevenue ? : sdk . Balances
43+ dailyFees : sdk . Balances ;
44+ dailyRevenue : sdk . Balances ;
45+ dailySupplySideRevenue : sdk . Balances ;
3046}
3147
3248interface VaultERC4626Info {
@@ -188,7 +204,7 @@ async function getVaultERC4626Info(options: FetchOptions, vaults: Array<string>,
188204 return vaultInfo ;
189205}
190206
191- async function getMorphoVaultFee ( options : FetchOptions , balances : Balances , vaults : Array < string > ) {
207+ async function getMorphoVaultFee ( options : FetchOptions , balances : Balances , vaults : Array < string > , breakdownFees ?: boolean ) {
192208 const vaultInfo = await getVaultERC4626Info ( options , vaults , true )
193209 const vaultFeeRates = await options . api . multiCall ( {
194210 abi : ABI . morpho . fee ,
@@ -199,25 +215,30 @@ async function getMorphoVaultFee(options: FetchOptions, balances: Balances, vaul
199215 for ( let i = 0 ; i < vaultInfo . length ; i ++ ) {
200216 const growthRate = vaultInfo [ i ] . rateAfter - vaultInfo [ i ] . rateBefore
201217
202- if ( growthRate > 0 ) {
203- const vaultFeeRate = BigInt ( vaultFeeRates [ i ] ? vaultFeeRates [ i ] : 0 )
204-
205- // morpho vault include fee directly to vault shares
206- // it mean that vault fees were added from vault token shares
218+ const vaultFeeRate = BigInt ( vaultFeeRates [ i ] ? vaultFeeRates [ i ] : 0 )
207219
208- // interest earned and distributed to vault deposited including fees
209- const interestEarnedIncludingFees = vaultInfo [ i ] . balance * growthRate / BigInt ( 10 ** 18 )
210-
211- // interest earned by vault curator
212- const interestFee = interestEarnedIncludingFees * vaultFeeRate / BigInt ( 1e18 )
220+ // morpho vault include fee directly to vault shares
221+ // it mean that vault fees were added from vault token shares
213222
214- balances . dailyFees . add ( vaultInfo [ i ] . asset , interestEarnedIncludingFees , METRIC . ASSETS_YIELDS )
215- balances . dailyRevenue . add ( vaultInfo [ i ] . asset , interestFee , METRIC . ASSETS_YIELDS )
223+ // interest earned and distributed to vault deposited including fees
224+ const interestEarnedIncludingFees = vaultInfo [ i ] . balance * growthRate / BigInt ( 10 ** 18 )
225+
226+ // interest earned by vault curator
227+ const interestFee = interestEarnedIncludingFees * vaultFeeRate / BigInt ( 1e18 )
228+
229+ if ( breakdownFees ) {
230+ balances . dailyFees . add ( vaultInfo [ i ] . asset , interestEarnedIncludingFees , METRICS . MorphoYields )
231+ balances . dailyRevenue . add ( vaultInfo [ i ] . asset , interestFee , METRICS . MorphoPerformanceFee )
232+ balances . dailySupplySideRevenue . add ( vaultInfo [ i ] . asset , interestEarnedIncludingFees - interestFee , METRICS . MorphoYieldsToSuppliers )
233+ } else {
234+ balances . dailyFees . add ( vaultInfo [ i ] . asset , interestEarnedIncludingFees , METRICS . AssetYields )
235+ balances . dailyRevenue . add ( vaultInfo [ i ] . asset , interestFee , METRICS . AssetYields )
236+ balances . dailySupplySideRevenue . add ( vaultInfo [ i ] . asset , interestEarnedIncludingFees - interestFee , METRICS . AssetYields )
216237 }
217238 }
218239}
219240
220- export async function getEulerVaultFee ( options : FetchOptions , balances : Balances , vaults : Array < string > ) {
241+ export async function getEulerVaultFee ( options : FetchOptions , balances : Balances , vaults : Array < string > , breakdownFees ?: boolean ) {
221242 const vaultInfo = await getVaultERC4626Info ( options , vaults )
222243 const vaultFeeRates = await options . api . multiCall ( {
223244 abi : ABI . euler . interestFee ,
@@ -228,32 +249,36 @@ export async function getEulerVaultFee(options: FetchOptions, balances: Balances
228249 for ( let i = 0 ; i < vaultInfo . length ; i ++ ) {
229250 const growthRate = vaultInfo [ i ] . rateAfter - vaultInfo [ i ] . rateBefore
230251
231- if ( growthRate > 0 ) {
232- const vaultFeeRate = BigInt ( vaultFeeRates [ i ] ? vaultFeeRates [ i ] : 0 )
233-
234- // euler vault subtract fee directly from interest when collecting
235- // it mean that vault fees were remove from vault token shares
252+ const vaultFeeRate = BigInt ( vaultFeeRates [ i ] ? vaultFeeRates [ i ] : 0 )
236253
237- // interest earned and distributed to vault deposited after fees
238- const interestEarned = vaultInfo [ i ] . balance * growthRate / BigInt ( 1e18 )
239-
240- // interest earned and distributed to vault deposited and vault curator before fees
241- let interestEarnedBeforeFee = interestEarned
242- if ( vaultFeeRate < BigInt ( 1e4 ) ) {
243- interestEarnedBeforeFee = interestEarned * BigInt ( 1e4 ) / ( BigInt ( 1e4 ) - vaultFeeRate )
244- }
254+ // euler vault subtract fee directly from interest when collecting
255+ // it mean that vault fees were remove from vault token shares
245256
246- // interest earned by vault curator
247- const interestFee = interestEarnedBeforeFee - interestEarned
257+ // interest earned and distributed to vault deposited after fees
258+ const interestEarned = vaultInfo [ i ] . balance * growthRate / BigInt ( 1e18 )
259+
260+ // interest earned and distributed to vault deposited and vault curator before fees
261+ let interestEarnedBeforeFee = interestEarned
262+ if ( vaultFeeRate < BigInt ( 1e4 ) ) {
263+ interestEarnedBeforeFee = interestEarned * BigInt ( 1e4 ) / ( BigInt ( 1e4 ) - vaultFeeRate )
264+ }
248265
249- balances . dailyFees . add ( vaultInfo [ i ] . asset , interestEarnedBeforeFee , METRIC . ASSETS_YIELDS )
250- balances . dailyRevenue . add ( vaultInfo [ i ] . asset , interestFee , METRIC . ASSETS_YIELDS )
251- if ( balances . dailySupplySideRevenue ) balances . dailySupplySideRevenue . add ( vaultInfo [ i ] . asset , interestEarnedBeforeFee - interestFee , METRIC . ASSETS_YIELDS )
266+ // interest earned by vault curator
267+ const interestFee = interestEarnedBeforeFee - interestEarned
268+
269+ if ( breakdownFees ) {
270+ balances . dailyFees . add ( vaultInfo [ i ] . asset , interestEarnedBeforeFee , METRICS . EulerYields )
271+ balances . dailyRevenue . add ( vaultInfo [ i ] . asset , interestFee , METRICS . EulerPerformanceFee )
272+ balances . dailySupplySideRevenue . add ( vaultInfo [ i ] . asset , interestEarnedBeforeFee - interestFee , METRICS . EulerYieldsToSuppliers )
273+ } else {
274+ balances . dailyFees . add ( vaultInfo [ i ] . asset , interestEarnedBeforeFee , METRICS . AssetYields )
275+ balances . dailyRevenue . add ( vaultInfo [ i ] . asset , interestFee , METRICS . AssetYields )
276+ balances . dailySupplySideRevenue . add ( vaultInfo [ i ] . asset , interestEarnedBeforeFee - interestFee , METRICS . AssetYields )
252277 }
253278 }
254279}
255280
256- async function getMorphoVaultV2Fee ( options : FetchOptions , balances : Balances , vaults : Array < string > ) {
281+ async function getMorphoVaultV2Fee ( options : FetchOptions , balances : Balances , vaults : Array < string > , breakdownFees ?: boolean ) {
257282 const vaultInfo = await getVaultERC4626Info ( options , vaults , true )
258283 const vaultPerformanceFeeRates = await options . api . multiCall ( {
259284 abi : ABI . morpho . performanceFee ,
@@ -269,27 +294,32 @@ async function getMorphoVaultV2Fee(options: FetchOptions, balances: Balances, va
269294 for ( let i = 0 ; i < vaultInfo . length ; i ++ ) {
270295 const growthRate = vaultInfo [ i ] . rateAfter - vaultInfo [ i ] . rateBefore
271296
297+ const vaultPerformanceFeeRate = BigInt ( vaultPerformanceFeeRates [ i ] ? vaultPerformanceFeeRates [ i ] : 0 )
298+ const vaultManagementFeeRate = BigInt ( vaultManagementFeeRates [ i ] ? vaultManagementFeeRates [ i ] : 0 )
272299
273- if ( growthRate > 0 ) {
274- const vaultPerformanceFeeRate = BigInt ( vaultPerformanceFeeRates [ i ] ? vaultPerformanceFeeRates [ i ] : 0 )
275- const vaultManagementFeeRate = BigInt ( vaultManagementFeeRates [ i ] ? vaultManagementFeeRates [ i ] : 0 )
276-
277- // morpho vault include fee directly to vault shares
278- // it mean that vault fees were added from vault token shares
300+ // morpho vault include fee directly to vault shares
301+ // it mean that vault fees were added from vault token shares
279302
280- // interest earned and distributed to vault deposited including fees
281- const interestEarnedIncludingFees = vaultInfo [ i ] . balance * growthRate / BigInt ( 10 ** 18 )
282-
283- // interest earned by vault curator - performance fee
284- const interestPerformanceFee = interestEarnedIncludingFees * vaultPerformanceFeeRate / BigInt ( 1e18 )
285-
286- // interest earned by vault curator - management fee
287- const timeElapsed = options . toTimestamp - options . fromTimestamp
288- const interestManagementFee = interestEarnedIncludingFees * vaultManagementFeeRate * BigInt ( timeElapsed ) / BigInt ( 1e18 )
289-
290- balances . dailyFees . add ( vaultInfo [ i ] . asset , interestEarnedIncludingFees , METRIC . ASSETS_YIELDS )
291- balances . dailyRevenue . add ( vaultInfo [ i ] . asset , interestPerformanceFee , METRIC . ASSETS_YIELDS )
292- balances . dailyRevenue . add ( vaultInfo [ i ] . asset , interestManagementFee , METRIC . ASSETS_YIELDS )
303+ // interest earned and distributed to vault deposited including fees
304+ const interestEarnedIncludingFees = vaultInfo [ i ] . balance * growthRate / BigInt ( 10 ** 18 )
305+
306+ // interest earned by vault curator - performance fee
307+ const interestPerformanceFee = interestEarnedIncludingFees * vaultPerformanceFeeRate / BigInt ( 1e18 )
308+
309+ // interest earned by vault curator - management fee
310+ const timeElapsed = options . toTimestamp - options . fromTimestamp
311+ const interestManagementFee = interestEarnedIncludingFees * vaultManagementFeeRate * BigInt ( timeElapsed ) / BigInt ( 1e18 )
312+
313+ if ( breakdownFees ) {
314+ balances . dailyFees . add ( vaultInfo [ i ] . asset , interestEarnedIncludingFees , METRICS . MorphoYields )
315+ balances . dailyRevenue . add ( vaultInfo [ i ] . asset , interestPerformanceFee , METRICS . MorphoManagementFee )
316+ balances . dailyRevenue . add ( vaultInfo [ i ] . asset , interestManagementFee , METRICS . MorphoManagementFee )
317+ balances . dailySupplySideRevenue . add ( vaultInfo [ i ] . asset , interestEarnedIncludingFees - interestPerformanceFee - interestManagementFee , METRICS . MorphoYieldsToSuppliers )
318+ } else {
319+ balances . dailyFees . add ( vaultInfo [ i ] . asset , interestEarnedIncludingFees , METRICS . AssetYields )
320+ balances . dailyRevenue . add ( vaultInfo [ i ] . asset , interestPerformanceFee , METRICS . AssetYields )
321+ balances . dailyRevenue . add ( vaultInfo [ i ] . asset , interestManagementFee , METRICS . AssetYields )
322+ balances . dailySupplySideRevenue . add ( vaultInfo [ i ] . asset , interestEarnedIncludingFees - interestPerformanceFee - interestManagementFee , METRICS . AssetYields )
293323 }
294324 }
295325}
@@ -303,13 +333,14 @@ export function getCuratorExport(curatorConfig: CuratorConfig): SimpleAdapter {
303333 }
304334 const breakdownMethodology = {
305335 Fees : {
306- [ METRIC . ASSETS_YIELDS ] : 'Interest yields generated from deposited assets in all curated vaults, including both curator fees and depositor yields' ,
336+ [ METRICS . AssetYields ] : 'Interest yields generated from deposited assets in all curated vaults, including both curator fees and depositor yields' ,
337+ [ METRICS . MorphoYields ] : 'Interest yields generated from deposited assets in all curated vaults, including both curator fees and depositor yields' ,
307338 } ,
308339 Revenue : {
309- [ METRIC . ASSETS_YIELDS ] : 'Portion of interest yields retained by vault curators as management and performance fees' ,
340+ [ METRICS . AssetYields ] : 'Portion of interest yields retained by vault curators as management and performance fees' ,
310341 } ,
311342 SupplySideRevenue : {
312- [ METRIC . ASSETS_YIELDS ] : 'Portion of interest yields distributed to vault depositors/investors after curator fees are deducted' ,
343+ [ METRICS . AssetYields ] : 'Portion of interest yields distributed to vault depositors/investors after curator fees are deducted' ,
313344 } ,
314345 }
315346 const exportObject : BaseAdapter = { }
@@ -319,6 +350,7 @@ export function getCuratorExport(curatorConfig: CuratorConfig): SimpleAdapter {
319350 fetch : ( async ( options : FetchOptions ) => {
320351 let dailyFees = options . createBalances ( )
321352 let dailyRevenue = options . createBalances ( )
353+ let dailySupplySideRevenue = options . createBalances ( )
322354
323355 // morpho meta vaults
324356 const morphoVaults = await getMorphoVaults ( options , vaults . morpho , vaults . morphoVaultOwners ) ;
@@ -329,20 +361,15 @@ export function getCuratorExport(curatorConfig: CuratorConfig): SimpleAdapter {
329361 const eulerVaults = await getEulerVaults ( options , vaults . euler , vaults . eulerVaultOwners ) ;
330362
331363 if ( morphoVaults . length > 0 ) {
332- await getMorphoVaultFee ( options , { dailyFees, dailyRevenue } , morphoVaults )
364+ await getMorphoVaultFee ( options , { dailyFees, dailyRevenue, dailySupplySideRevenue } , morphoVaults , curatorConfig . breakdownFees )
333365 }
334366 if ( morphoVaultsV2 . length > 0 ) {
335- await getMorphoVaultV2Fee ( options , { dailyFees, dailyRevenue } , morphoVaultsV2 )
367+ await getMorphoVaultV2Fee ( options , { dailyFees, dailyRevenue, dailySupplySideRevenue } , morphoVaultsV2 , curatorConfig . breakdownFees )
336368 }
337369 if ( eulerVaults . length > 0 ) {
338- await getEulerVaultFee ( options , { dailyFees, dailyRevenue } , eulerVaults )
370+ await getEulerVaultFee ( options , { dailyFees, dailyRevenue, dailySupplySideRevenue } , eulerVaults , curatorConfig . breakdownFees )
339371 }
340372
341- const dailySupplySideRevenue = options . createBalances ( )
342- const tempBalance = dailyFees . clone ( )
343- tempBalance . subtract ( dailyRevenue )
344- dailySupplySideRevenue . addBalances ( tempBalance , METRIC . ASSETS_YIELDS )
345-
346373 return {
347374 dailyFees,
348375 dailyRevenue,
@@ -359,6 +386,7 @@ export function getCuratorExport(curatorConfig: CuratorConfig): SimpleAdapter {
359386 methodology,
360387 breakdownMethodology,
361388 adapter : exportObject ,
389+ allowNegativeValue : true , // we allow negative fees for vaults because vaults can make yields or make loss too
362390 }
363391}
364392
0 commit comments