@strkfarm/sdk 1.1.9 → 1.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/global.ts CHANGED
@@ -122,6 +122,16 @@ const defaultTokens: TokenInfo[] = [{
122
122
  symbol: 'xtBTC',
123
123
  logo: 'https://assets.strkfarm.com/integrations/tokens/xtbtc.svg',
124
124
  address: ContractAddr.from('0x43a35c1425a0125ef8c171f1a75c6f31ef8648edcc8324b55ce1917db3f9b91'),
125
+ decimals: 18,
126
+ coingeckId: undefined,
127
+ displayDecimals: 6,
128
+ priceProxySymbol: 'WBTC',
129
+ priceCheckAmount: 0.0001, // 112000 * 0.0001 = $11.2
130
+ }, {
131
+ name: 'xLBTC',
132
+ symbol: 'xLBTC',
133
+ logo: 'https://assets.strkfarm.com/integrations/tokens/xlbtc.svg',
134
+ address: ContractAddr.from('0x036834a40984312f7f7de8d31e3f6305b325389eaeea5b1c0664b2fb936461a4'),
125
135
  decimals: 8,
126
136
  coingeckId: undefined,
127
137
  displayDecimals: 6,
@@ -96,7 +96,8 @@ export interface IStrategyMetadata<T> {
96
96
  points?: {multiplier: number, logo: string, toolTip?: string}[];
97
97
  docs?: string;
98
98
  investmentSteps: string[];
99
- curator?: { name: string, logo: string }
99
+ curator?: { name: string, logo: string },
100
+ isPreview?: boolean
100
101
  }
101
102
 
102
103
  export interface IInvestmentFlow {
@@ -4,4 +4,5 @@ export * from './zkLend';
4
4
  export * from './pricer-from-api';
5
5
  export * from './erc20';
6
6
  export * from './avnu';
7
- export * from './ekubo-quoter';
7
+ export * from './ekubo-quoter';
8
+ export * from './pricer-lst';
@@ -42,7 +42,7 @@ export class PricerFromApi extends PricerBase {
42
42
 
43
43
  async getPriceFromMyAPI(tokenSymbol: string) {
44
44
  logger.verbose(`getPrice from redis: ${tokenSymbol}`);
45
- const endpoint = 'https://app.troves.fi'
45
+ const endpoint = 'https://cache-server-t2me.onrender.com'
46
46
  const url = `${endpoint}/api/price/${tokenSymbol}`;
47
47
  const priceInfoRes = await fetch(url);
48
48
  const priceInfo = await priceInfoRes.json();
@@ -0,0 +1,66 @@
1
+ import { FatalError, PriceInfo, Pricer, Web3Number } from "@/index.browser";
2
+ import { PricerBase } from "./pricerBase";
3
+ import { IConfig, TokenInfo } from "@/interfaces";
4
+ import { logger } from "@/utils";
5
+ import axios from "axios";
6
+
7
+ export class PricerLST extends Pricer {
8
+ private tokenMaps: {lst: TokenInfo, underlying: TokenInfo}[];
9
+ protected EKUBO_API = 'https://quoter-mainnet-api.ekubo.org/{{AMOUNT}}/{{TOKEN_ADDRESS}}/{{UNDERLYING_ADDRESS}}'; // e.g. xSTRK/STRK
10
+
11
+ constructor(config: IConfig, tokenMaps: {lst: TokenInfo, underlying: TokenInfo}[]) {
12
+ const refreshInterval = 5000;
13
+ const staleTime = 60000;
14
+ const allTokens = tokenMaps.map(map => [map.lst, map.underlying]).flat();
15
+ super(config, allTokens, refreshInterval, staleTime);
16
+ this.tokenMaps = tokenMaps;
17
+ }
18
+
19
+ isUnderlying(token: TokenInfo): boolean {
20
+ return this.tokenMaps.some(map => map.underlying.address.eq(token.address));
21
+ }
22
+
23
+ getUnderlying(token: TokenInfo): TokenInfo {
24
+ return this.tokenMaps.find(map => map.lst.address.eq(token.address))!.underlying;
25
+ }
26
+
27
+ async _getPrice(token: TokenInfo, defaultMethod = 'all'): Promise<number> {
28
+ if (this.isUnderlying(token)) {
29
+ return 1; // underlying is always 1 relative to LST
30
+ }
31
+
32
+ const methodToUse: string = this.methodToUse[token.symbol] || defaultMethod; // default start with coinbase
33
+ logger.verbose(`Fetching price of ${token.symbol} using ${methodToUse}`);
34
+ try {
35
+ const result = await this._getPriceEkubo(token, new Web3Number(token.priceCheckAmount ? token.priceCheckAmount : 1, token.decimals));
36
+ this.methodToUse[token.symbol] = 'Ekubo';
37
+ return result;
38
+ } catch (error: any) {
39
+ console.warn(`Ekubo: price err [${token.symbol}]: `, error.message);
40
+ console.warn(`Ekubo: price err [${token.symbol}]: `, Object.keys(error));
41
+ // do nothing, try next
42
+ }
43
+
44
+ throw new FatalError(`Price not found for ${token.symbol}`);
45
+ }
46
+
47
+ async _getPriceEkubo(token: TokenInfo, amountIn = new Web3Number(1, token.decimals), retry = 0): Promise<number> {
48
+ const underlying = this.getUnderlying(token);
49
+ const url = this.EKUBO_API
50
+ .replace("{{TOKEN_ADDRESS}}", token.address.toString())
51
+ .replace("{{AMOUNT}}", amountIn.toWei())
52
+ .replace("{{UNDERLYING_ADDRESS}}", underlying.address.toString());
53
+ const result = await axios.get(url);
54
+ const data: any = result.data;
55
+ const multiplier = 1 / amountIn.toNumber();
56
+ const outputUnderlying = Number(Web3Number.fromWei(data.total_calculated, underlying.decimals).toFixed(6)) * multiplier;
57
+ logger.verbose(`Ekubo: ${token.symbol} -> ${underlying.symbol}: ${outputUnderlying}, retry: ${retry}`);
58
+ if (outputUnderlying === 0 && retry < 3) {
59
+ // try again with a higher amount
60
+ const amountIn = new Web3Number(100, token.decimals); // 100 unit of token
61
+ return await this._getPriceEkubo(token, amountIn, retry + 1);
62
+ }
63
+
64
+ return outputUnderlying;
65
+ }
66
+ }
@@ -21,7 +21,7 @@ export class Pricer extends PricerBase {
21
21
 
22
22
  // code populates this map during runtime to determine which method to use for a given token
23
23
  // The method set will be the first one to try after first attempt
24
- private methodToUse: {[tokenSymbol: string]: 'Ekubo' | 'Coinbase' | 'Coinmarketcap'} = {};
24
+ protected methodToUse: {[tokenSymbol: string]: 'Ekubo' | 'Coinbase' | 'Coinmarketcap'} = {};
25
25
 
26
26
  /**
27
27
  * TOKENA and TOKENB are the two token names to get price of TokenA in terms of TokenB
@@ -1809,6 +1809,29 @@ const lstStrategies: IStrategyMetadata<CLVaultStrategySettings>[] = [
1809
1809
  contractDetails: [],
1810
1810
  investmentSteps: []
1811
1811
  },
1812
+ {
1813
+ ...xSTRKSTRK,
1814
+ name: "Ekubo xLBTC/LBTC",
1815
+ description: <></>,
1816
+ address: ContractAddr.from(
1817
+ "0x315a614603b1f702e466aedcbcb1ad97a77eb1192b8bd077e5154d4f2ee4fab"
1818
+ ),
1819
+ launchBlock: 2344809,
1820
+ // must be same order as poolKey token0 and token1
1821
+ depositTokens: [
1822
+ Global.getDefaultTokens().find((t) => t.symbol === "LBTC")!,
1823
+ Global.getDefaultTokens().find((t) => t.symbol === "xLBTC")!,
1824
+ ],
1825
+ additionalInfo: {
1826
+ ...xSTRKSTRK.additionalInfo,
1827
+ quoteAsset: Global.getDefaultTokens().find((t) => t.symbol === "LBTC")!,
1828
+ lstContract: Global.getDefaultTokens().find((t) => t.symbol === "xLBTC")!.address,
1829
+ },
1830
+ faqs: getLSTFAQs("xLBTC"),
1831
+ points: [],
1832
+ contractDetails: [],
1833
+ investmentSteps: []
1834
+ }
1812
1835
  ];
1813
1836
 
1814
1837
  const ETHUSDCRe7Strategy: IStrategyMetadata<CLVaultStrategySettings> = {
@@ -6,7 +6,7 @@ import { Global } from "@/global";
6
6
  import { ApproveCallParams, CommonAdapter, ManageCall, Swap, VesuAdapter, VesuModifyDelegationCallParams, VesuMultiplyCallParams, VesuPools } from "./universal-adapters";
7
7
  import { AVNU_MIDDLEWARE } from "./universal-adapters/adapter-utils";
8
8
  import { LiquidationRiskLevel, SmartContractRiskLevel, TechnicalRiskLevel } from "@/interfaces/risks";
9
- import { EkuboQuoter, ERC20 } from "@/modules";
9
+ import { EkuboQuoter, ERC20, PricerLST } from "@/modules";
10
10
  import { assert, logger } from "@/utils";
11
11
  import { SingleTokenInfo } from "./base-strategy";
12
12
  import { Call, Contract, uint256 } from "starknet";
@@ -17,7 +17,7 @@ export class UniversalLstMultiplierStrategy extends UniversalStrategy<UniversalS
17
17
 
18
18
  private quoteAmountToFetchPrice = new Web3Number(1, 18);
19
19
 
20
- constructor(config: IConfig, pricer: PricerBase, metadata: IStrategyMetadata<UniversalStrategySettings>) {
20
+ constructor(config: IConfig, pricer: PricerLST, metadata: IStrategyMetadata<UniversalStrategySettings>) {
21
21
  super(config, pricer, metadata);
22
22
 
23
23
  const STRKToken = Global.getDefaultTokens().find(token => token.symbol === 'STRK')!;
@@ -42,9 +42,9 @@ export class UniversalLstMultiplierStrategy extends UniversalStrategy<UniversalS
42
42
 
43
43
  // not applicable for this strategy
44
44
  // No rewards on collateral or borrowing of LST assets
45
- protected async getRewardsAUM(prevAum: Web3Number): Promise<Web3Number> {
46
- return Web3Number.fromWei("0", this.asset().decimals);
47
- }
45
+ // protected async getRewardsAUM(prevAum: Web3Number): Promise<Web3Number> {
46
+ // return Web3Number.fromWei("0", this.asset().decimals);
47
+ // }
48
48
 
49
49
  async getLSTDexPrice() {
50
50
  const ekuboQuoter = new EkuboQuoter(this.config);
@@ -82,12 +82,16 @@ export class UniversalLstMultiplierStrategy extends UniversalStrategy<UniversalS
82
82
  logger.debug(`${this.getTag()}::getVesuMultiplyCall existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
83
83
  existingDebtInfo: ${JSON.stringify(existingDebtInfo)}, collateralisation: ${JSON.stringify(collateralisation)}`);
84
84
 
85
+ // - Prices as seen by Vesu contracts, ideal for HF math
85
86
  // Price 1 is ok as fallback bcz that would relatively price the
86
87
  // collateral and debt as equal.
87
88
  const collateralPrice = collateralisation[0].usdValue > 0 ? collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() : 1;
88
89
  const debtPrice = collateralisation[1].usdValue > 0 ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() : 1;
89
90
  logger.debug(`${this.getTag()}::getVesuMultiplyCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
90
91
 
92
+ // - Prices as seen by actual swap price
93
+ const dexPrice = await this.getLSTDexPrice();
94
+
91
95
  // compute optimal amount of collateral and debt post addition/removal
92
96
  // target hf = collateral * collateralPrice * ltv / debt * debtPrice
93
97
  // assuming X to be the usd amount of debt borrowed or repaied (negative).
@@ -97,11 +101,10 @@ export class UniversalLstMultiplierStrategy extends UniversalStrategy<UniversalS
97
101
  // => X = (((collateral + legDepositAmount) * collateralPrice * ltv) - (debt * debtPrice * target hf)) / (target hf - ltv)
98
102
  const addedCollateral = params.leg1DepositAmount
99
103
  .multipliedBy(params.isDeposit ? 1 : -1)
100
- const DEXPrice = await this.getLSTDexPrice();
101
104
  logger.verbose(`${this.getTag()}::getVesuMultiplyCall addedCollateral: ${addedCollateral}`);
102
105
  const numeratorPart1 = (existingCollateralInfo.amount.plus((addedCollateral))).multipliedBy(collateralPrice).multipliedBy(legLTV);
103
106
  const numeratorPart2 = existingDebtInfo.amount.multipliedBy(debtPrice).multipliedBy(this.metadata.additionalInfo.targetHealthFactor);
104
- const denominatorPart = this.metadata.additionalInfo.targetHealthFactor - (legLTV / DEXPrice);
107
+ const denominatorPart = this.metadata.additionalInfo.targetHealthFactor - (legLTV / dexPrice);
105
108
  const x_debt_usd = numeratorPart1.minus(numeratorPart2).dividedBy(denominatorPart);
106
109
  logger.verbose(`${this.getTag()}::getVesuMultiplyCall x_debt_usd: ${x_debt_usd}`);
107
110
  logger.debug(`${this.getTag()}::getVesuMultiplyCall numeratorPart1: ${numeratorPart1}, numeratorPart2: ${numeratorPart2}, denominatorPart: ${denominatorPart}`);
@@ -121,6 +124,7 @@ export class UniversalLstMultiplierStrategy extends UniversalStrategy<UniversalS
121
124
  return this.getModifyLeverCall({
122
125
  marginAmount,
123
126
  debtAmount,
127
+ lstDexPriceInUnderlying: dexPrice,
124
128
  isIncrease: debtAmount.greaterThan(0)
125
129
  });
126
130
  }
@@ -152,6 +156,7 @@ export class UniversalLstMultiplierStrategy extends UniversalStrategy<UniversalS
152
156
  async getModifyLeverCall(params: {
153
157
  marginAmount: Web3Number, // >0 during deposit
154
158
  debtAmount: Web3Number,
159
+ lstDexPriceInUnderlying: number,
155
160
  isIncrease: boolean
156
161
  }): Promise<Call[]> {
157
162
  assert(!params.marginAmount.isZero() || !params.debtAmount.isZero(), 'Deposit/debt must be non-0');
@@ -175,13 +180,12 @@ export class UniversalLstMultiplierStrategy extends UniversalStrategy<UniversalS
175
180
  manageCalls.push(manageCall1);
176
181
  }
177
182
 
183
+ const lstDexPriceInUnderlying = params.lstDexPriceInUnderlying;
178
184
  const ekuboQuoter = new EkuboQuoter(this.config);
179
185
 
180
186
  // compute quotes for margin swap
181
- const lstPrice = await this.getLSTExchangeRate();
182
187
  const marginSwap: Swap[] = [];
183
188
 
184
-
185
189
  // compute quotes for lever swap
186
190
  const MAX_SLIPPAGE = 0.01;
187
191
  // when increasing, debt is swapped to collateral (LST)
@@ -196,8 +200,8 @@ export class UniversalLstMultiplierStrategy extends UniversalStrategy<UniversalS
196
200
  );
197
201
  assert(leverSwapQuote.price_impact < MAX_SLIPPAGE, 'getIncreaseLeverCall: Price impact is too high [Debt swap]');
198
202
  const leverSwap = ekuboQuoter.getVesuMultiplyQuote(leverSwapQuote, fromToken, toToken);
199
- const minExpectedDebt = params.debtAmount.dividedBy(lstPrice).multipliedBy(1 - MAX_SLIPPAGE); // used for increase
200
- const maxUsedCollateral = params.debtAmount.abs().dividedBy(lstPrice).multipliedBy(1 + MAX_SLIPPAGE); // +ve for exact amount out, used for decrease
203
+ const minExpectedDebt = params.debtAmount.dividedBy(lstDexPriceInUnderlying).multipliedBy(1 - MAX_SLIPPAGE); // used for increase
204
+ const maxUsedCollateral = params.debtAmount.abs().dividedBy(lstDexPriceInUnderlying).multipliedBy(1 + MAX_SLIPPAGE); // +ve for exact amount out, used for decrease
201
205
 
202
206
  const STEP2_ID = LST_MULTIPLIER_MANAGE_IDS.SWITCH_DELEGATION_ON;
203
207
  const manage2Info = this.getProofs<VesuModifyDelegationCallParams>(STEP2_ID);
@@ -416,6 +420,54 @@ const hyperxSTRK: UniversalStrategySettings = {
416
420
  minHealthFactor: 1.05
417
421
  }
418
422
 
423
+ const hyperxWBTC: UniversalStrategySettings = {
424
+ vaultAddress: ContractAddr.from('0x2da9d0f96a46b453f55604313785dc866424240b1c6811d13bef594343db818'),
425
+ manager: ContractAddr.from('0x75866db44c81e6986f06035206ee9c7d15833ddb22d6a22c016cfb5c866a491'),
426
+ vaultAllocator: ContractAddr.from('0x57b5c1bb457b5e840a2714ae53ada87d77be2f3fd33a59b4fe709ef20c020c1'),
427
+ redeemRequestNFT: ContractAddr.from('0x7a5dc288325456f05e70e9616e16bc02ffbe448f4b89f80b47c0970b989c7c'),
428
+ aumOracle: ContractAddr.from(''),
429
+ leafAdapters: [],
430
+ adapters: [],
431
+ targetHealthFactor: 1.1,
432
+ minHealthFactor: 1.05
433
+ }
434
+
435
+ const hyperxtBTC: UniversalStrategySettings = {
436
+ vaultAddress: ContractAddr.from('0x47d5f68477e5637ce0e56436c6b5eee5a354e6828995dae106b11a48679328'),
437
+ manager: ContractAddr.from('0xc4cc3e08029a0ae076f5fdfca70575abb78d23c5cd1c49a957f7e697885401'),
438
+ vaultAllocator: ContractAddr.from('0x50bbd4fe69f841ecb13b2619fe50ebfa4e8944671b5d0ebf7868fd80c61b31e'),
439
+ redeemRequestNFT: ContractAddr.from('0xeac9032f02057779816e38a6cb9185d12d86b3aacc9949b96b36de359c1e3'),
440
+ aumOracle: ContractAddr.from(''),
441
+ leafAdapters: [],
442
+ adapters: [],
443
+ targetHealthFactor: 1.1,
444
+ minHealthFactor: 1.05
445
+ }
446
+
447
+ const hyperxsBTC: UniversalStrategySettings = {
448
+ vaultAddress: ContractAddr.from('0x437ef1e7d0f100b2e070b7a65cafec0b2be31b0290776da8b4112f5473d8d9'),
449
+ manager: ContractAddr.from('0xc9ac023090625b0be3f6532ca353f086746f9c09f939dbc1b2613f09e5f821'),
450
+ vaultAllocator: ContractAddr.from('0x60c2d856936b975459a5b4eb28b8672d91f757bd76cebb6241f8d670185dc01'),
451
+ redeemRequestNFT: ContractAddr.from('0x429e8ee8bc7ecd1ade72630d350a2e0f10f9a2507c45f188ba17fe8f2ab4cf3'),
452
+ aumOracle: ContractAddr.from(''),
453
+ leafAdapters: [],
454
+ adapters: [],
455
+ targetHealthFactor: 1.1,
456
+ minHealthFactor: 1.05
457
+ }
458
+
459
+ const hyperxLBTC: UniversalStrategySettings = {
460
+ vaultAddress: ContractAddr.from('0x38e96a301428d204ab4553799aa386a0f14a5ef9b30a5830be1814e4fb8da1c'),
461
+ manager: ContractAddr.from('0x18d376446d9df1f783e17aff1f21bac3d97aa3ba378e367742cdd744468ad35'),
462
+ vaultAllocator: ContractAddr.from('0x3e98774ca0508505ba6d7f17d95ec391648f44f947b0d211241464a4f5b9b20'),
463
+ redeemRequestNFT: ContractAddr.from('0x268017b4c8b2117ca0136d9a77e3666db44b143447566f0746ca0b1c9ab1e72'),
464
+ aumOracle: ContractAddr.from('0x521a3f339c65e918e0d8a065b14baef1ea25676bb7fca1e0238ac47e20d7755'),
465
+ leafAdapters: [],
466
+ adapters: [],
467
+ targetHealthFactor: 1.1,
468
+ minHealthFactor: 1.05
469
+ }
470
+
419
471
  function getInvestmentSteps(lstSymbol: string, underlyingSymbol: string) {
420
472
  return [
421
473
  `Deposit ${underlyingSymbol} into the vault`,
@@ -427,7 +479,7 @@ function getInvestmentSteps(lstSymbol: string, underlyingSymbol: string) {
427
479
  ]
428
480
  }
429
481
 
430
- function getStrategySettings(lstSymbol: string, underlyingSymbol: string, addresses: UniversalStrategySettings): IStrategyMetadata<UniversalStrategySettings> {
482
+ function getStrategySettings(lstSymbol: string, underlyingSymbol: string, addresses: UniversalStrategySettings, isPreview: boolean = false): IStrategyMetadata<UniversalStrategySettings> {
431
483
  return {
432
484
  name: `Hyper ${lstSymbol}`,
433
485
  description: getDescription(lstSymbol),
@@ -448,10 +500,15 @@ function getStrategySettings(lstSymbol: string, underlyingSymbol: string, addres
448
500
  contractDetails: getContractDetails(addresses),
449
501
  faqs: getFAQs(lstSymbol, underlyingSymbol),
450
502
  investmentSteps: getInvestmentSteps(lstSymbol, underlyingSymbol),
503
+ isPreview: isPreview
451
504
  }
452
505
  }
453
506
 
454
507
  export const HyperLSTStrategies: IStrategyMetadata<UniversalStrategySettings>[] =
455
508
  [
456
- getStrategySettings('xSTRK', 'STRK', hyperxSTRK),
509
+ getStrategySettings('xSTRK', 'STRK', hyperxSTRK, false),
510
+ getStrategySettings('xWBTC', 'WBTC', hyperxWBTC, true),
511
+ getStrategySettings('xtBTC', 'tBTC', hyperxtBTC, true),
512
+ getStrategySettings('xsBTC', 'solvBTC', hyperxsBTC, true),
513
+ getStrategySettings('xLBTC', 'LBTC', hyperxLBTC, true),
457
514
  ]
@@ -203,6 +203,14 @@ export class UniversalStrategy<
203
203
  * @returns {Promise<number>} The weighted average APY across all pools
204
204
  */
205
205
  async netAPY(): Promise<{ net: number, splits: { apy: number, id: string }[] }> {
206
+ if (this.metadata.isPreview) {
207
+ return { net: 0, splits: [{
208
+ apy: 0, id: 'base'
209
+ }, {
210
+ apy: 0, id: 'defispring'
211
+ }] };
212
+ }
213
+
206
214
  const prevAUM = await this.getPrevAUM();
207
215
 
208
216
  // get Vesu pools, positions and APYs
@@ -302,20 +310,20 @@ export class UniversalStrategy<
302
310
  const underlying = this.asset();
303
311
  let vesuAum = Web3Number.fromWei("0", underlying.decimals);
304
312
 
313
+ let tokenUnderlyingPrice = await this.pricer.getPrice(this.asset().symbol);
314
+
305
315
  // handle collateral
306
316
  if (legAUM[0].token.address.eq(underlying.address)) {
307
317
  vesuAum = vesuAum.plus(legAUM[0].amount);
308
318
  } else {
309
- const tokenPrice = await this.pricer.getPrice(legAUM[1].token.symbol);
310
- vesuAum = vesuAum.plus(legAUM[1].usdValue / tokenPrice.price);
319
+ vesuAum = vesuAum.plus(legAUM[1].usdValue / tokenUnderlyingPrice.price);
311
320
  }
312
321
 
313
322
  // handle debt
314
323
  if (legAUM[1].token.address.eq(underlying.address)) {
315
324
  vesuAum = vesuAum.minus(legAUM[1].amount);
316
325
  } else {
317
- const tokenPrice = await this.pricer.getPrice(legAUM[1].token.symbol);
318
- vesuAum = vesuAum.minus(legAUM[1].usdValue / tokenPrice.price);
326
+ vesuAum = vesuAum.minus(legAUM[1].usdValue / tokenUnderlyingPrice.price);
319
327
  };
320
328
 
321
329
  logger.verbose(`${this.getTag()} Vesu AUM: ${vesuAum}, legCollateral: ${legAUM[0].amount.toNumber()}, legDebt: ${legAUM[1].amount.toNumber()}`);