@strkfarm/sdk 2.0.0-dev.4 → 2.0.0-dev.6

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.
@@ -1,15 +1,43 @@
1
1
  import { ContractAddr, Web3Number } from "@/dataTypes";
2
2
  import { IConfig, Protocols, TokenInfo } from "@/interfaces";
3
3
  import { PricerBase } from "@/modules/pricerBase";
4
- import { BaseAdapter, BaseAdapterConfig, SupportedPosition, PositionInfo, PositionAPY, APYType, ManageCall, AdapterLeafType, GenerateCallFn, DepositParams, WithdrawParams, PositionAmount } from "./baseAdapter";
5
- import { SIMPLE_SANITIZER, SIMPLE_SANITIZER_V2, toBigInt, VESU_SINGLETON, VESU_V2_MODIFY_POSITION_SANITIZER } from "./adapter-utils";
4
+ import {
5
+ BaseAdapter,
6
+ BaseAdapterConfig,
7
+ SupportedPosition,
8
+ PositionInfo,
9
+ PositionAPY,
10
+ APYType,
11
+ ManageCall,
12
+ AdapterLeafType,
13
+ GenerateCallFn,
14
+ DepositParams,
15
+ WithdrawParams,
16
+ PositionAmount,
17
+ } from "./baseAdapter";
18
+ import {
19
+ SIMPLE_SANITIZER,
20
+ SIMPLE_SANITIZER_V2,
21
+ toBigInt,
22
+ VESU_SINGLETON,
23
+ VESU_V2_MODIFY_POSITION_SANITIZER,
24
+ } from "./adapter-utils";
6
25
  import { hash, uint256, Contract, CairoCustomEnum, num } from "starknet";
7
- import { VesuAdapter, VesuMultiplyCallParams, VesuModifyDelegationCallParams, getVesuSingletonAddress, VesuPools, Swap, IncreaseLeverParams, DecreaseLeverParams } from "./vesu-adapter";
26
+ import {
27
+ VesuAdapter,
28
+ VesuMultiplyCallParams,
29
+ VesuModifyDelegationCallParams,
30
+ getVesuSingletonAddress,
31
+ VesuPools,
32
+ Swap,
33
+ IncreaseLeverParams,
34
+ DecreaseLeverParams,
35
+ } from "./vesu-adapter";
8
36
  import { logger } from "@/utils";
9
37
  import { WALLET_ADDRESS } from "../vesu-extended-strategy/utils/constants";
10
- import VesuMultiplyAbi from '@/data/vesu-multiple.abi.json';
11
- import VesuSingletonAbi from '../../data/vesu-singleton.abi.json';
12
- import VesuPoolV2Abi from '@/data/vesu-pool-v2.abi.json';
38
+ import VesuMultiplyAbi from "@/data/vesu-multiple.abi.json";
39
+ import VesuSingletonAbi from "../../data/vesu-singleton.abi.json";
40
+ import VesuPoolV2Abi from "@/data/vesu-pool-v2.abi.json";
13
41
  import { EkuboQuoter, TokenMarketData } from "@/modules";
14
42
  import { calculateDebtReductionAmountForWithdrawal } from "../vesu-extended-strategy/utils/helper";
15
43
  import { HealthFactorMath } from "@/utils/health-factor-math";
@@ -24,7 +52,10 @@ export interface VesuMultiplyAdapterConfig extends BaseAdapterConfig {
24
52
  quoteAmountToFetchPrice: Web3Number;
25
53
  }
26
54
 
27
- export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawParams> {
55
+ export class VesuMultiplyAdapter extends BaseAdapter<
56
+ DepositParams,
57
+ WithdrawParams
58
+ > {
28
59
  readonly config: VesuMultiplyAdapterConfig;
29
60
  readonly vesuAdapter: VesuAdapter;
30
61
  readonly tokenMarketData: TokenMarketData;
@@ -37,15 +68,27 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
37
68
  collateral: config.collateral,
38
69
  debt: config.debt,
39
70
  vaultAllocator: config.vaultAllocator,
40
- id: ''
71
+ id: "",
41
72
  });
42
- this.tokenMarketData = new TokenMarketData(this.config.pricer, this.config.networkConfig);
73
+ this.tokenMarketData = new TokenMarketData(
74
+ this.config.pricer,
75
+ this.config.networkConfig
76
+ );
43
77
  }
44
78
 
45
- protected async getAPY(supportedPosition: SupportedPosition): Promise<PositionAPY> {
79
+ protected async getAPY(
80
+ supportedPosition: SupportedPosition
81
+ ): Promise<PositionAPY> {
46
82
  const CACHE_KEY = `apy_${this.config.poolId.address}_${supportedPosition.asset.symbol}`;
47
83
  const cacheData = this.getCache<PositionAPY>(CACHE_KEY);
48
- console.log(`${VesuMultiplyAdapter.name}::getAPY cacheData: ${JSON.stringify(cacheData)}`, this.vesuAdapter.config.poolId.shortString(), this.vesuAdapter.config.collateral.symbol, this.vesuAdapter.config.debt.symbol);
84
+ console.log(
85
+ `${VesuMultiplyAdapter.name}::getAPY cacheData: ${JSON.stringify(
86
+ cacheData
87
+ )}`,
88
+ this.vesuAdapter.config.poolId.shortString(),
89
+ this.vesuAdapter.config.collateral.symbol,
90
+ this.vesuAdapter.config.debt.symbol
91
+ );
49
92
  if (cacheData) {
50
93
  return cacheData;
51
94
  }
@@ -53,24 +96,30 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
53
96
  // Get Vesu pools to find APY for the asset
54
97
  const allVesuPools = await VesuAdapter.getVesuPools();
55
98
  const asset = supportedPosition.asset;
56
- const pool = allVesuPools.pools.find(p => this.vesuAdapter.config.poolId.eqString(num.getHexString(p.id)));
99
+ const pool = allVesuPools.pools.find((p) =>
100
+ this.vesuAdapter.config.poolId.eqString(num.getHexString(p.id))
101
+ );
57
102
  if (!pool) {
58
- logger.warn(`VesuMultiplyAdapter: Pool not found for token ${asset.symbol}`);
103
+ logger.warn(
104
+ `VesuMultiplyAdapter: Pool not found for token ${asset.symbol}`
105
+ );
59
106
  return {
60
107
  apy: 0,
61
- type: APYType.BASE
108
+ type: APYType.BASE,
62
109
  };
63
110
  }
64
111
  // Find the asset stats for our token
65
- const assetStats = pool.assets.find((a: any) =>
66
- a.symbol.toLowerCase() === asset.symbol.toLowerCase()
112
+ const assetStats = pool.assets.find(
113
+ (a: any) => a.symbol.toLowerCase() === asset.symbol.toLowerCase()
67
114
  )?.stats;
68
115
 
69
116
  if (!assetStats) {
70
- logger.warn(`VesuMultiplyAdapter: Asset stats not found for token ${asset.symbol}`);
117
+ logger.warn(
118
+ `VesuMultiplyAdapter: Asset stats not found for token ${asset.symbol}`
119
+ );
71
120
  return {
72
121
  apy: 0,
73
- type: APYType.BASE
122
+ type: APYType.BASE,
74
123
  };
75
124
  }
76
125
  // Get appropriate APY based on position type
@@ -79,15 +128,21 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
79
128
  // For debt positions, use borrow APY
80
129
  apy = Number(assetStats.borrowApr?.value || 0) / 1e18;
81
130
 
82
- // todo
131
+ // todo
83
132
  // Account for rewards on debt token
84
133
  } else {
85
134
  // For collateral positions, use supply APY
86
135
  const isAssetBTC = asset.symbol.toLowerCase().includes("btc");
87
- const baseAPY = Number(isAssetBTC ? assetStats.btcFiSupplyApr?.value + assetStats.supplyApy?.value : assetStats.supplyApy?.value || 0) / 1e18;
136
+ const baseAPY =
137
+ Number(
138
+ isAssetBTC
139
+ ? assetStats.btcFiSupplyApr?.value + assetStats.supplyApy?.value
140
+ : assetStats.supplyApy?.value || 0
141
+ ) / 1e18;
88
142
 
89
143
  // account for reward yield (like STRK rewards)
90
- const rewardAPY = Number(assetStats.defiSpringSupplyApr?.value || "0") / 1e18;
144
+ const rewardAPY =
145
+ Number(assetStats.defiSpringSupplyApr?.value || "0") / 1e18;
91
146
 
92
147
  // account for base yield of LST
93
148
  const isSupported = this.tokenMarketData.isAPYSupported(asset);
@@ -99,13 +154,16 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
99
154
  }
100
155
  const result = {
101
156
  apy,
102
- type: supportedPosition.isDebt ? APYType.BASE : APYType.BASE
157
+ type: supportedPosition.isDebt ? APYType.BASE : APYType.BASE,
103
158
  };
104
159
 
105
160
  this.setCache(CACHE_KEY, result, 300000); // Cache for 5 minutes
106
161
  return result;
107
162
  } catch (error) {
108
- logger.error(`VesuMultiplyAdapter: Error getting APY for ${supportedPosition.asset.symbol}:`, error);
163
+ logger.error(
164
+ `VesuMultiplyAdapter: Error getting APY for ${supportedPosition.asset.symbol}:`,
165
+ error
166
+ );
109
167
  // return {
110
168
  // apy: 0,
111
169
  // type: APYType.BASE
@@ -114,7 +172,9 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
114
172
  }
115
173
  }
116
174
 
117
- protected async getPosition(supportedPosition: SupportedPosition): Promise<PositionAmount> {
175
+ protected async getPosition(
176
+ supportedPosition: SupportedPosition
177
+ ): Promise<PositionAmount> {
118
178
  const CACHE_KEY = `position_${this.config.poolId.address}_${supportedPosition.asset.symbol}`;
119
179
  const cacheData = this.getCache<PositionAmount>(CACHE_KEY);
120
180
  if (cacheData) {
@@ -125,19 +185,23 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
125
185
  // Use VesuAdapter to get positions
126
186
  this.vesuAdapter.networkConfig = this.config.networkConfig;
127
187
  this.vesuAdapter.pricer = this.config.pricer;
128
-
129
- const positions = await this.vesuAdapter.getPositions(this.config.networkConfig);
130
-
188
+
189
+ const positions = await this.vesuAdapter.getPositions(
190
+ this.config.networkConfig
191
+ );
192
+
131
193
  // Find the position for our asset
132
- let position = positions.find(p =>
194
+ let position = positions.find((p) =>
133
195
  p.token.address.eq(supportedPosition.asset.address)
134
196
  );
135
197
 
136
198
  if (!position) {
137
- logger.warn(`VesuMultiplyAdapter: Position not found for token ${supportedPosition.asset.symbol}`);
199
+ logger.warn(
200
+ `VesuMultiplyAdapter: Position not found for token ${supportedPosition.asset.symbol}`
201
+ );
138
202
  return {
139
- amount: new Web3Number('0', supportedPosition.asset.decimals),
140
- remarks: "Position not found"
203
+ amount: new Web3Number("0", supportedPosition.asset.decimals),
204
+ remarks: "Position not found",
141
205
  };
142
206
  }
143
207
 
@@ -149,7 +213,10 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
149
213
  this.setCache(CACHE_KEY, position, 60000); // Cache for 1 minute
150
214
  return position;
151
215
  } catch (error) {
152
- logger.error(`VesuMultiplyAdapter: Error getting position for ${supportedPosition.asset.symbol}:`, error);
216
+ logger.error(
217
+ `VesuMultiplyAdapter: Error getting position for ${supportedPosition.asset.symbol}:`,
218
+ error
219
+ );
153
220
  // return new Web3Number('0', supportedPosition.asset.decimals);
154
221
  throw error;
155
222
  }
@@ -157,7 +224,10 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
157
224
 
158
225
  async maxBorrowableAPY(): Promise<number> {
159
226
  // get collateral APY
160
- const collateralAPY = await this.getAPY({ asset: this.config.collateral, isDebt: false });
227
+ const collateralAPY = await this.getAPY({
228
+ asset: this.config.collateral,
229
+ isDebt: false,
230
+ });
161
231
  const apy = collateralAPY.apy * 0.8;
162
232
  return apy;
163
233
  }
@@ -170,58 +240,92 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
170
240
  // Get current positions
171
241
  this.vesuAdapter.networkConfig = this.config.networkConfig;
172
242
  this.vesuAdapter.pricer = this.config.pricer;
173
-
174
- const positions = await this.vesuAdapter.getPositions(this.config.networkConfig);
175
- const collateralPosition = positions.find(p => p.token.address.eq(collateral.address));
176
- const debtPosition = positions.find(p => p.token.address.eq(debt.address));
243
+
244
+ const positions = await this.vesuAdapter.getPositions(
245
+ this.config.networkConfig
246
+ );
247
+ const collateralPosition = positions.find((p) =>
248
+ p.token.address.eq(collateral.address)
249
+ );
250
+ const debtPosition = positions.find((p) =>
251
+ p.token.address.eq(debt.address)
252
+ );
177
253
 
178
254
  if (!collateralPosition || !debtPosition) {
179
- throw new Error('Could not find current positions');
255
+ throw new Error("Could not find current positions");
180
256
  }
181
257
 
182
258
  // Calculate max borrowable amount
183
259
  const maxBorrowableAPY = await this.maxBorrowableAPY();
184
- const maxBorrowable = await this.vesuAdapter.getMaxBorrowableByInterestRate(
185
- this.config.networkConfig,
186
- debt,
187
- maxBorrowableAPY
260
+ const maxBorrowable =
261
+ await this.vesuAdapter.getMaxBorrowableByInterestRate(
262
+ this.config.networkConfig,
263
+ debt,
264
+ maxBorrowableAPY
265
+ );
266
+ logger.verbose(
267
+ `VesuMultiplyAdapter: Max borrowable: ${maxBorrowable.toNumber()}`
268
+ );
269
+ const debtCap = await this.vesuAdapter.getDebtCap(
270
+ this.config.networkConfig
188
271
  );
189
- logger.verbose(`VesuMultiplyAdapter: Max borrowable: ${maxBorrowable.toNumber()}`);
190
- const debtCap = await this.vesuAdapter.getDebtCap(this.config.networkConfig);
191
272
  logger.verbose(`VesuMultiplyAdapter: Debt cap: ${debtCap.toNumber()}`);
192
273
  const actualMaxBorrowable = maxBorrowable.minimum(debtCap);
193
- logger.verbose(`VesuMultiplyAdapter: Actual max borrowable: ${actualMaxBorrowable.toNumber()}`);
274
+ logger.verbose(
275
+ `VesuMultiplyAdapter: Actual max borrowable: ${actualMaxBorrowable.toNumber()}`
276
+ );
194
277
 
195
278
  // Calculate max collateral that can be deposited based on LTV
196
- const maxLTV = await this.vesuAdapter.getLTVConfig(this.config.networkConfig);
197
- const collateralPrice = await this.config.pricer.getPrice(collateral.symbol);
279
+ const maxLTV = await this.vesuAdapter.getLTVConfig(
280
+ this.config.networkConfig
281
+ );
282
+ const collateralPrice = await this.config.pricer.getPrice(
283
+ collateral.symbol
284
+ );
198
285
  if (collateralPrice.price === 0) {
199
- throw new Error('Collateral price is 0');
286
+ throw new Error("Collateral price is 0");
200
287
  }
201
288
  const debtPrice = await this.config.pricer.getPrice(debt.symbol);
202
289
  if (debtPrice.price === 0) {
203
- throw new Error('Debt price is 0');
290
+ throw new Error("Debt price is 0");
204
291
  }
205
- const maxCollateralFromDebt = HealthFactorMath.getMinCollateralRequiredOnLooping(
206
- actualMaxBorrowable,
207
- debtPrice.price,
208
- this.config.targetHealthFactor,
209
- maxLTV,
210
- collateralPrice.price,
211
- collateral
212
- )
292
+ const maxCollateralFromDebt =
293
+ HealthFactorMath.getMinCollateralRequiredOnLooping(
294
+ actualMaxBorrowable,
295
+ debtPrice.price,
296
+ this.config.targetHealthFactor,
297
+ maxLTV,
298
+ collateralPrice.price,
299
+ collateral
300
+ );
213
301
 
214
- const maxDepositAmount = amount ? amount.minimum(maxCollateralFromDebt) : maxCollateralFromDebt;
302
+ const maxDepositAmount = amount
303
+ ? amount.minimum(maxCollateralFromDebt)
304
+ : maxCollateralFromDebt;
215
305
  const usdValue = await this.getUSDValue(collateral, maxDepositAmount);
216
- logger.verbose(`VesuMultiplyAdapter: Max deposit::USD value: ${usdValue}, amount: ${maxDepositAmount.toNumber()}`);
217
- const apys = await Promise.all([this.getAPY({ asset: collateral, isDebt: false }), this.getAPY({ asset: debt, isDebt: true })]);
218
- logger.verbose(`VesuMultiplyAdapter: Apys: ${apys[0].apy}, ${apys[1].apy}`);
306
+ logger.verbose(
307
+ `VesuMultiplyAdapter: Max deposit::USD value: ${usdValue}, amount: ${maxDepositAmount.toNumber()}`
308
+ );
309
+ const apys = await Promise.all([
310
+ this.getAPY({ asset: collateral, isDebt: false }),
311
+ this.getAPY({ asset: debt, isDebt: true }),
312
+ ]);
313
+ logger.verbose(
314
+ `VesuMultiplyAdapter: Apys: ${apys[0].apy}, ${apys[1].apy}`
315
+ );
219
316
 
220
317
  const borrowAmountUSD = actualMaxBorrowable.multipliedBy(debtPrice.price);
221
- logger.verbose(`VesuMultiplyAdapter: Borrow amount: ${actualMaxBorrowable.toNumber()}, borrow amount USD: ${borrowAmountUSD.toNumber()}`);
318
+ logger.verbose(
319
+ `VesuMultiplyAdapter: Borrow amount: ${actualMaxBorrowable.toNumber()}, borrow amount USD: ${borrowAmountUSD.toNumber()}`
320
+ );
222
321
  const netCollateralUSD = usdValue + borrowAmountUSD.toNumber();
223
- const netAPY = (apys[0].apy * netCollateralUSD + apys[1].apy * borrowAmountUSD.toNumber()) / (usdValue);
224
- logger.verbose(`VesuMultiplyAdapter: Max deposit amount: ${maxDepositAmount.toNumber()}, netAPY: ${netAPY}`);
322
+ const netAPY =
323
+ (apys[0].apy * netCollateralUSD +
324
+ apys[1].apy * borrowAmountUSD.toNumber()) /
325
+ usdValue;
326
+ logger.verbose(
327
+ `VesuMultiplyAdapter: Max deposit amount: ${maxDepositAmount.toNumber()}, netAPY: ${netAPY}`
328
+ );
225
329
  return {
226
330
  tokenInfo: collateral,
227
331
  amount: maxDepositAmount,
@@ -229,12 +333,15 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
229
333
  remarks: "Max deposit based on available debt capacity",
230
334
  apy: {
231
335
  apy: netAPY,
232
- type: APYType.BASE
336
+ type: APYType.BASE,
233
337
  },
234
- protocol: this.protocol
338
+ protocol: this.protocol,
235
339
  };
236
340
  } catch (error) {
237
- logger.error(`VesuMultiplyAdapter: Error calculating max deposit:`, error);
341
+ logger.error(
342
+ `VesuMultiplyAdapter: Error calculating max deposit:`,
343
+ error
344
+ );
238
345
  throw error;
239
346
  }
240
347
  }
@@ -247,28 +354,50 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
247
354
  // Calculate how much can be withdrawn without affecting health factor too much
248
355
  this.vesuAdapter.networkConfig = this.config.networkConfig;
249
356
  this.vesuAdapter.pricer = this.config.pricer;
250
-
251
- const positions = await this.vesuAdapter.getPositions(this.config.networkConfig);
252
- const collateralPosition = positions.find(p => p.token.address.eq(collateral.address));
253
- const debtPosition = positions.find(p => p.token.address.eq(this.config.debt.address));
357
+
358
+ const positions = await this.vesuAdapter.getPositions(
359
+ this.config.networkConfig
360
+ );
361
+ const collateralPosition = positions.find((p) =>
362
+ p.token.address.eq(collateral.address)
363
+ );
364
+ const debtPosition = positions.find((p) =>
365
+ p.token.address.eq(this.config.debt.address)
366
+ );
254
367
 
255
368
  if (!collateralPosition || !debtPosition) {
256
- throw new Error('Could not find current positions');
369
+ throw new Error("Could not find current positions");
257
370
  }
258
371
 
259
372
  // Calculate max withdrawable (conservative approach)
260
- const collateralPrice = collateralPosition.usdValue / collateralPosition.amount.toNumber();
373
+ const collateralPrice =
374
+ collateralPosition.usdValue / collateralPosition.amount.toNumber();
261
375
  const debtInCollateral = debtPosition.usdValue / collateralPrice;
262
376
  const maxWithdrawable = collateralPosition.amount.minus(debtInCollateral);
263
377
 
264
- const result = maxWithdrawable.greaterThan(0) ? maxWithdrawable : new Web3Number('0', collateral.decimals);
378
+ const result = maxWithdrawable.greaterThan(0)
379
+ ? maxWithdrawable
380
+ : new Web3Number("0", collateral.decimals);
265
381
  const usdValue = await this.getUSDValue(collateral, result);
266
382
  const debtUSD = debtPosition.usdValue;
267
- logger.verbose(`VesuMultiplyAdapter: Debt USD: ${debtUSD}, collateral USD: ${usdValue}`);
268
- const apys = await Promise.all([this.getAPY({ asset: collateral, isDebt: false }), this.getAPY({ asset: debt, isDebt: true })]);
269
- logger.verbose(`VesuMultiplyAdapter: Apys: ${apys[0].apy}, ${apys[1].apy}`);
270
- const netAPY = (usdValue - debtUSD) > 0 ? (apys[0].apy * usdValue + apys[1].apy * debtUSD) / (usdValue - debtUSD) : 0;
271
- logger.verbose(`VesuMultiplyAdapter: Max withdraw amount: ${result.toNumber()}, netAPY: ${netAPY}`);
383
+ logger.verbose(
384
+ `VesuMultiplyAdapter: Debt USD: ${debtUSD}, collateral USD: ${usdValue}`
385
+ );
386
+ const apys = await Promise.all([
387
+ this.getAPY({ asset: collateral, isDebt: false }),
388
+ this.getAPY({ asset: debt, isDebt: true }),
389
+ ]);
390
+ logger.verbose(
391
+ `VesuMultiplyAdapter: Apys: ${apys[0].apy}, ${apys[1].apy}`
392
+ );
393
+ const netAPY =
394
+ usdValue - debtUSD > 0
395
+ ? (apys[0].apy * usdValue + apys[1].apy * debtUSD) /
396
+ (usdValue - debtUSD)
397
+ : 0;
398
+ logger.verbose(
399
+ `VesuMultiplyAdapter: Max withdraw amount: ${result.toNumber()}, netAPY: ${netAPY}`
400
+ );
272
401
  return {
273
402
  tokenInfo: collateral,
274
403
  amount: result,
@@ -276,58 +405,71 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
276
405
  remarks: "Max withdraw based on health factor",
277
406
  apy: {
278
407
  apy: netAPY,
279
- type: APYType.BASE
408
+ type: APYType.BASE,
280
409
  },
281
- protocol: this.protocol
410
+ protocol: this.protocol,
282
411
  };
283
412
  } catch (error) {
284
- logger.error(`VesuMultiplyAdapter: Error calculating max withdraw:`, error);
413
+ logger.error(
414
+ `VesuMultiplyAdapter: Error calculating max withdraw:`,
415
+ error
416
+ );
285
417
  throw error;
286
418
  }
287
419
  }
288
420
 
289
421
  protected _getDepositLeaf(): {
290
- target: ContractAddr,
291
- method: string,
292
- packedArguments: bigint[],
293
- sanitizer: ContractAddr,
294
- id: string
422
+ target: ContractAddr;
423
+ method: string;
424
+ packedArguments: bigint[];
425
+ sanitizer: ContractAddr;
426
+ id: string;
295
427
  }[] {
296
428
  const collateral = this.config.collateral;
297
429
  const debt = this.config.debt;
298
- const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(this.config.poolId);
299
- const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
430
+ const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
431
+ this.config.poolId
432
+ );
433
+ const vesuMultiply = isV2
434
+ ? this.vesuAdapter.VESU_MULTIPLY
435
+ : this.vesuAdapter.VESU_MULTIPLY_V1;
300
436
 
301
437
  return [
302
438
  // Approval step for collateral
303
439
  {
304
440
  target: collateral.address,
305
- method: 'approve',
441
+ method: "approve",
306
442
  packedArguments: [
307
443
  vesuMultiply.toBigInt(), // spender
308
444
  ],
309
445
  sanitizer: SIMPLE_SANITIZER,
310
446
  // amc = approve multiply collateral
311
- id: `amc_${this.config.poolId.shortString()}_${collateral.symbol}_${debt.symbol}`
447
+ id: `amc_${this.config.poolId.shortString()}_${collateral.symbol}_${
448
+ debt.symbol
449
+ }`,
312
450
  },
313
451
  // Switch delegation on
314
452
  {
315
453
  target: vesuSingleton,
316
- method: 'modify_delegation',
317
- packedArguments: isV2 ? [
318
- vesuMultiply.toBigInt(), // delegatee
319
- ] : [
320
- this.config.poolId.toBigInt(),
321
- vesuMultiply.toBigInt(), // delegatee
322
- ],
454
+ method: "modify_delegation",
455
+ packedArguments: isV2
456
+ ? [
457
+ vesuMultiply.toBigInt(), // delegatee
458
+ ]
459
+ : [
460
+ this.config.poolId.toBigInt(),
461
+ vesuMultiply.toBigInt(), // delegatee
462
+ ],
323
463
  sanitizer: isV2 ? SIMPLE_SANITIZER_V2 : SIMPLE_SANITIZER,
324
464
  // sd1 = switch delegation on
325
- id: `sd1_${this.config.poolId.shortString()}_${collateral.symbol}_${debt.symbol}`
465
+ id: `sd1_${this.config.poolId.shortString()}_${collateral.symbol}_${
466
+ debt.symbol
467
+ }`,
326
468
  },
327
469
  // Vesu multiply call
328
470
  {
329
471
  target: vesuMultiply,
330
- method: 'modify_lever',
472
+ method: "modify_lever",
331
473
  packedArguments: [
332
474
  this.config.poolId.toBigInt(),
333
475
  collateral.address.toBigInt(),
@@ -336,34 +478,44 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
336
478
  ],
337
479
  sanitizer: SIMPLE_SANITIZER_V2,
338
480
  // vm = vesu multiply
339
- id: `vm_${this.config.poolId.shortString()}_${collateral.symbol}_${debt.symbol}`
481
+ id: `vm_${this.config.poolId.shortString()}_${collateral.symbol}_${
482
+ debt.symbol
483
+ }`,
340
484
  },
341
485
  // Switch delegation off
342
486
  {
343
487
  target: vesuSingleton,
344
- method: 'modify_delegation',
345
- packedArguments: isV2 ? [
346
- vesuMultiply.toBigInt(), // delegatee
347
- ] : [
348
- this.config.poolId.toBigInt(),
349
- vesuMultiply.toBigInt(), // delegatee
350
- ],
488
+ method: "modify_delegation",
489
+ packedArguments: isV2
490
+ ? [
491
+ vesuMultiply.toBigInt(), // delegatee
492
+ ]
493
+ : [
494
+ this.config.poolId.toBigInt(),
495
+ vesuMultiply.toBigInt(), // delegatee
496
+ ],
351
497
  sanitizer: isV2 ? SIMPLE_SANITIZER_V2 : SIMPLE_SANITIZER,
352
498
  // sd2 = switch delegation off
353
- id: `sd2_${this.config.poolId.shortString()}_${collateral.symbol}_${debt.symbol}`
354
- }
499
+ id: `sd2_${this.config.poolId.shortString()}_${collateral.symbol}_${
500
+ debt.symbol
501
+ }`,
502
+ },
355
503
  ];
356
504
  }
357
505
 
358
506
  protected _getWithdrawLeaf(): {
359
- target: ContractAddr,
360
- method: string,
361
- packedArguments: bigint[],
362
- sanitizer: ContractAddr,
363
- id: string
507
+ target: ContractAddr;
508
+ method: string;
509
+ packedArguments: bigint[];
510
+ sanitizer: ContractAddr;
511
+ id: string;
364
512
  }[] {
365
- const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(this.config.poolId);
366
- const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
513
+ const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
514
+ this.config.poolId
515
+ );
516
+ const vesuMultiply = isV2
517
+ ? this.vesuAdapter.VESU_MULTIPLY
518
+ : this.vesuAdapter.VESU_MULTIPLY_V1;
367
519
  const collateral = this.config.collateral;
368
520
  const debt = this.config.debt;
369
521
 
@@ -371,21 +523,25 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
371
523
  // Switch delegation on
372
524
  {
373
525
  target: vesuSingleton,
374
- method: 'modify_delegation',
375
- packedArguments: isV2 ? [
376
- vesuMultiply.toBigInt(), // delegatee
377
- ] : [
378
- this.config.poolId.toBigInt(),
379
- vesuMultiply.toBigInt(), // delegatee
380
- ],
526
+ method: "modify_delegation",
527
+ packedArguments: isV2
528
+ ? [
529
+ vesuMultiply.toBigInt(), // delegatee
530
+ ]
531
+ : [
532
+ this.config.poolId.toBigInt(),
533
+ vesuMultiply.toBigInt(), // delegatee
534
+ ],
381
535
  sanitizer: isV2 ? SIMPLE_SANITIZER_V2 : SIMPLE_SANITIZER,
382
536
  // sdow = switch delegation on withdraw
383
- id: `sdow_${this.config.poolId.shortString()}_${collateral.symbol}_${debt.symbol}`
537
+ id: `sdow_${this.config.poolId.shortString()}_${collateral.symbol}_${
538
+ debt.symbol
539
+ }`,
384
540
  },
385
541
  // Vesu multiply call
386
542
  {
387
543
  target: vesuMultiply,
388
- method: 'modify_lever',
544
+ method: "modify_lever",
389
545
  packedArguments: [
390
546
  this.config.poolId.toBigInt(),
391
547
  this.config.collateral.address.toBigInt(),
@@ -394,59 +550,85 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
394
550
  ],
395
551
  sanitizer: isV2 ? SIMPLE_SANITIZER_V2 : SIMPLE_SANITIZER,
396
552
  // vmw = vesu multiply withdraw
397
- id: `vmw_${this.config.poolId.shortString()}_${collateral.symbol}_${debt.symbol}`
553
+ id: `vmw_${this.config.poolId.shortString()}_${collateral.symbol}_${
554
+ debt.symbol
555
+ }`,
398
556
  },
399
557
  // Switch delegation off
400
558
  {
401
559
  target: vesuSingleton,
402
- method: 'modify_delegation',
403
- packedArguments: isV2 ? [
404
- vesuMultiply.toBigInt(), // delegatee
405
- ] : [
406
- this.config.poolId.toBigInt(),
407
- vesuMultiply.toBigInt(), // delegatee
408
- ],
560
+ method: "modify_delegation",
561
+ packedArguments: isV2
562
+ ? [
563
+ vesuMultiply.toBigInt(), // delegatee
564
+ ]
565
+ : [
566
+ this.config.poolId.toBigInt(),
567
+ vesuMultiply.toBigInt(), // delegatee
568
+ ],
409
569
  sanitizer: isV2 ? SIMPLE_SANITIZER_V2 : SIMPLE_SANITIZER,
410
570
  // sdofw = switch delegation off withdraw
411
- id: `sdofw_${this.config.poolId.shortString()}_${collateral.symbol}_${debt.symbol}`
412
- }
571
+ id: `sdofw_${this.config.poolId.shortString()}_${collateral.symbol}_${
572
+ debt.symbol
573
+ }`,
574
+ },
413
575
  ];
414
576
  }
415
577
 
416
578
  getDepositAdapter(): AdapterLeafType<DepositParams> {
417
579
  const leafConfigs = this._getDepositLeaf();
418
- const leaves = leafConfigs.map(config => {
580
+ const leaves = leafConfigs.map((config) => {
419
581
  const { target, method, packedArguments, sanitizer, id } = config;
420
- const leaf = this.constructSimpleLeafData({
421
- id: id,
422
- target,
423
- method,
424
- packedArguments
425
- }, sanitizer);
582
+ const leaf = this.constructSimpleLeafData(
583
+ {
584
+ id: id,
585
+ target,
586
+ method,
587
+ packedArguments,
588
+ },
589
+ sanitizer
590
+ );
426
591
  return leaf;
427
592
  });
428
- return { leaves, callConstructor: this.getDepositCall.bind(this) as unknown as GenerateCallFn<DepositParams> };
593
+ return {
594
+ leaves,
595
+ callConstructor: this.getDepositCall.bind(
596
+ this
597
+ ) as unknown as GenerateCallFn<DepositParams>,
598
+ };
429
599
  }
430
600
 
431
601
  getWithdrawAdapter(): AdapterLeafType<WithdrawParams> {
432
602
  const leafConfigs = this._getWithdrawLeaf();
433
- const leaves = leafConfigs.map(config => {
603
+ const leaves = leafConfigs.map((config) => {
434
604
  const { target, method, packedArguments, sanitizer, id } = config;
435
- const leaf = this.constructSimpleLeafData({
436
- id: id,
437
- target,
438
- method,
439
- packedArguments
440
- }, sanitizer);
605
+ const leaf = this.constructSimpleLeafData(
606
+ {
607
+ id: id,
608
+ target,
609
+ method,
610
+ packedArguments,
611
+ },
612
+ sanitizer
613
+ );
441
614
  return leaf;
442
615
  });
443
- return { leaves, callConstructor: this.getWithdrawCall.bind(this) as unknown as GenerateCallFn<WithdrawParams> };
616
+ return {
617
+ leaves,
618
+ callConstructor: this.getWithdrawCall.bind(
619
+ this
620
+ ) as unknown as GenerateCallFn<WithdrawParams>,
621
+ };
444
622
  }
445
623
 
446
624
  async getDepositCall(params: DepositParams): Promise<ManageCall[]> {
447
625
  const collateral = this.config.collateral;
448
- const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(this.config.poolId);
449
- const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
626
+ const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
627
+ this.config.poolId
628
+ );
629
+ const vesuMultiply = isV2
630
+ ? this.vesuAdapter.VESU_MULTIPLY
631
+ : this.vesuAdapter.VESU_MULTIPLY_V1;
450
632
 
451
633
  const uint256MarginAmount = uint256.bnToUint256(params.amount.toWei());
452
634
 
@@ -456,61 +638,69 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
456
638
  sanitizer: SIMPLE_SANITIZER,
457
639
  call: {
458
640
  contractAddress: collateral.address,
459
- selector: hash.getSelectorFromName('approve'),
641
+ selector: hash.getSelectorFromName("approve"),
460
642
  calldata: [
461
643
  vesuMultiply.toBigInt(), // spender
462
644
  toBigInt(uint256MarginAmount.low.toString()), // amount low
463
645
  toBigInt(uint256MarginAmount.high.toString()), // amount high
464
- ]
465
- }
646
+ ],
647
+ },
466
648
  },
467
649
  // Switch delegation on
468
650
  {
469
651
  sanitizer: isV2 ? SIMPLE_SANITIZER_V2 : SIMPLE_SANITIZER,
470
652
  call: {
471
653
  contractAddress: vesuSingleton,
472
- selector: hash.getSelectorFromName('modify_delegation'),
473
- calldata: isV2 ? [
474
- vesuMultiply.toBigInt(), // delegatee
475
- BigInt(1), // delegation: true
476
- ] : [
477
- this.config.poolId.toBigInt(),
478
- vesuMultiply.toBigInt(), // delegatee
479
- BigInt(1), // delegation: true
480
- ]
481
- }
654
+ selector: hash.getSelectorFromName("modify_delegation"),
655
+ calldata: isV2
656
+ ? [
657
+ vesuMultiply.toBigInt(), // delegatee
658
+ BigInt(1), // delegation: true
659
+ ]
660
+ : [
661
+ this.config.poolId.toBigInt(),
662
+ vesuMultiply.toBigInt(), // delegatee
663
+ BigInt(1), // delegation: true
664
+ ],
665
+ },
482
666
  },
483
667
  // Vesu multiply call
484
668
  {
485
669
  sanitizer: SIMPLE_SANITIZER_V2,
486
670
  call: {
487
671
  contractAddress: vesuMultiply,
488
- selector: hash.getSelectorFromName('modify_lever'),
489
- calldata: await this.getMultiplyCallCalldata(params, true)
490
- }
672
+ selector: hash.getSelectorFromName("modify_lever"),
673
+ calldata: await this.getMultiplyCallCalldata(params, true),
674
+ },
491
675
  },
492
676
  // Switch delegation off
493
677
  {
494
678
  sanitizer: isV2 ? SIMPLE_SANITIZER_V2 : SIMPLE_SANITIZER,
495
679
  call: {
496
680
  contractAddress: vesuSingleton,
497
- selector: hash.getSelectorFromName('modify_delegation'),
498
- calldata: isV2 ? [
499
- vesuMultiply.toBigInt(), // delegatee
500
- BigInt(0), // delegation: false
501
- ] : [
502
- this.config.poolId.toBigInt(),
503
- vesuMultiply.toBigInt(), // delegatee
504
- BigInt(0), // delegation: false
505
- ]
506
- }
507
- }
681
+ selector: hash.getSelectorFromName("modify_delegation"),
682
+ calldata: isV2
683
+ ? [
684
+ vesuMultiply.toBigInt(), // delegatee
685
+ BigInt(0), // delegation: false
686
+ ]
687
+ : [
688
+ this.config.poolId.toBigInt(),
689
+ vesuMultiply.toBigInt(), // delegatee
690
+ BigInt(0), // delegation: false
691
+ ],
692
+ },
693
+ },
508
694
  ];
509
695
  }
510
696
 
511
697
  async getWithdrawCall(params: WithdrawParams): Promise<ManageCall[]> {
512
- const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(this.config.poolId);
513
- const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
698
+ const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
699
+ this.config.poolId
700
+ );
701
+ const vesuMultiply = isV2
702
+ ? this.vesuAdapter.VESU_MULTIPLY
703
+ : this.vesuAdapter.VESU_MULTIPLY_V1;
514
704
 
515
705
  return [
516
706
  // Switch delegation on
@@ -518,118 +708,191 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
518
708
  sanitizer: isV2 ? SIMPLE_SANITIZER_V2 : SIMPLE_SANITIZER,
519
709
  call: {
520
710
  contractAddress: vesuSingleton,
521
- selector: hash.getSelectorFromName('modify_delegation'),
522
- calldata: isV2 ? [
523
- vesuMultiply.toBigInt(), // delegatee
524
- BigInt(1), // delegation: true
525
- ] : [
526
- this.config.poolId.toBigInt(),
527
- vesuMultiply.toBigInt(), // delegatee
528
- BigInt(1), // delegation: true
529
- ]
530
- }
711
+ selector: hash.getSelectorFromName("modify_delegation"),
712
+ calldata: isV2
713
+ ? [
714
+ vesuMultiply.toBigInt(), // delegatee
715
+ BigInt(1), // delegation: true
716
+ ]
717
+ : [
718
+ this.config.poolId.toBigInt(),
719
+ vesuMultiply.toBigInt(), // delegatee
720
+ BigInt(1), // delegation: true
721
+ ],
722
+ },
531
723
  },
532
724
  // Vesu multiply call
533
725
  {
534
726
  sanitizer: isV2 ? SIMPLE_SANITIZER_V2 : SIMPLE_SANITIZER,
535
727
  call: {
536
728
  contractAddress: vesuMultiply,
537
- selector: hash.getSelectorFromName('modify_lever'),
538
- calldata: await this.getWithdrawalCalldata(params)
539
- }
729
+ selector: hash.getSelectorFromName("modify_lever"),
730
+ calldata: await this.getWithdrawalCalldata(params),
731
+ },
540
732
  },
541
733
  // Switch delegation off
542
734
  {
543
735
  sanitizer: isV2 ? SIMPLE_SANITIZER_V2 : SIMPLE_SANITIZER,
544
736
  call: {
545
737
  contractAddress: vesuSingleton,
546
- selector: hash.getSelectorFromName('modify_delegation'),
547
- calldata: isV2 ? [
548
- vesuMultiply.toBigInt(), // delegatee
549
- BigInt(0), // delegation: false
550
- ] : [
551
- this.config.poolId.toBigInt(),
552
- vesuMultiply.toBigInt(), // delegatee
553
- BigInt(0), // delegation: false
554
- ]
555
- }
556
- }
738
+ selector: hash.getSelectorFromName("modify_delegation"),
739
+ calldata: isV2
740
+ ? [
741
+ vesuMultiply.toBigInt(), // delegatee
742
+ BigInt(0), // delegation: false
743
+ ]
744
+ : [
745
+ this.config.poolId.toBigInt(),
746
+ vesuMultiply.toBigInt(), // delegatee
747
+ BigInt(0), // delegation: false
748
+ ],
749
+ },
750
+ },
557
751
  ];
558
752
  }
559
753
 
560
- private async getMultiplyCallCalldata(params: DepositParams | WithdrawParams, isDeposit: boolean): Promise<bigint[]> {
561
- logger.verbose(`${VesuMultiplyAdapter.name}::getMultiplyCallCalldata params: ${JSON.stringify(params)}, isDeposit: ${isDeposit}, collateral: ${this.config.collateral.symbol}, debt: ${this.config.debt.symbol}`);
754
+ private async getMultiplyCallCalldata(
755
+ params: DepositParams | WithdrawParams,
756
+ isDeposit: boolean
757
+ ): Promise<bigint[]> {
758
+ logger.verbose(
759
+ `${
760
+ VesuMultiplyAdapter.name
761
+ }::getMultiplyCallCalldata params: ${JSON.stringify(
762
+ params
763
+ )}, isDeposit: ${isDeposit}, collateral: ${
764
+ this.config.collateral.symbol
765
+ }, debt: ${this.config.debt.symbol}`
766
+ );
562
767
  const { isV2 } = getVesuSingletonAddress(this.config.poolId);
563
- const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
564
-
768
+ const vesuMultiply = isV2
769
+ ? this.vesuAdapter.VESU_MULTIPLY
770
+ : this.vesuAdapter.VESU_MULTIPLY_V1;
771
+
565
772
  // Create a temporary contract instance to populate the call
566
773
  const multiplyContract = new Contract({
567
- abi: VesuMultiplyAbi,
568
- address: vesuMultiply.address,
569
- providerOrAccount: this.config.networkConfig.provider
774
+ abi: VesuMultiplyAbi,
775
+ address: vesuMultiply.address,
776
+ providerOrAccount: this.config.networkConfig.provider,
570
777
  });
571
778
 
572
779
  // Configure swaps based on the operation
573
780
  let leverSwap: Swap[] = [];
574
781
  let leverSwapLimitAmount = Web3Number.fromWei(0, this.config.debt.decimals);
575
782
 
576
- const existingPositions = await this.vesuAdapter.getPositions(this.config.networkConfig);
577
- const collateralisation = await this.vesuAdapter.getCollateralization(this.config.networkConfig);
783
+ const existingPositions = await this.vesuAdapter.getPositions(
784
+ this.config.networkConfig
785
+ );
786
+ const collateralisation = await this.vesuAdapter.getCollateralization(
787
+ this.config.networkConfig
788
+ );
578
789
  const existingCollateralInfo = existingPositions[0];
579
790
  const existingDebtInfo = existingPositions[1];
580
791
  const isDexPriceRequired = existingDebtInfo.token.symbol !== "USDC";
581
- logger.debug(`${VesuMultiplyAdapter.name}::getVesuMultiplyCall existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
582
- existingDebtInfo: ${JSON.stringify(existingDebtInfo)}, collateralisation: ${JSON.stringify(collateralisation)}`);
792
+ logger.debug(`${
793
+ VesuMultiplyAdapter.name
794
+ }::getVesuMultiplyCall existingCollateralInfo: ${JSON.stringify(
795
+ existingCollateralInfo
796
+ )},
797
+ existingDebtInfo: ${JSON.stringify(
798
+ existingDebtInfo
799
+ )}, collateralisation: ${JSON.stringify(collateralisation)}`);
583
800
 
584
801
  // - Prices as seen by Vesu contracts, ideal for HF math
585
- // Price 1 is ok as fallback bcz that would relatively price the
802
+ // Price 1 is ok as fallback bcz that would relatively price the
586
803
  // collateral and debt as equal.
587
- const collateralPrice = collateralisation[0].usdValue > 0 ?
588
- collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() :
589
- (await this.config.pricer.getPrice(this.config.collateral.symbol)).price;
590
- const debtPrice = collateralisation[1].usdValue > 0 ?
591
- collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() :
592
- (await this.config.pricer.getPrice(this.config.debt.symbol)).price;
593
- logger.debug(`${VesuMultiplyAdapter.name}::getVesuMultiplyCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
594
-
595
- const legLTV = await this.vesuAdapter.getLTVConfig(this.config.networkConfig);
596
- const ekuboQuoter = new EkuboQuoter(this.config.networkConfig, this.config.pricer);
597
- const dexPrice = isDexPriceRequired ? await ekuboQuoter.getDexPrice(this.config.collateral, this.config.debt, this.config.quoteAmountToFetchPrice) : 1;
598
- logger.verbose(`${VesuMultiplyAdapter.name}::getVesuMultiplyCall dexPrice: ${dexPrice}, ltv: ${legLTV}`);
804
+ const collateralPrice =
805
+ collateralisation[0].usdValue > 0
806
+ ? collateralisation[0].usdValue /
807
+ existingCollateralInfo.amount.toNumber()
808
+ : (await this.config.pricer.getPrice(this.config.collateral.symbol))
809
+ .price;
810
+ const debtPrice =
811
+ collateralisation[1].usdValue > 0
812
+ ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber()
813
+ : (await this.config.pricer.getPrice(this.config.debt.symbol)).price;
814
+ logger.debug(
815
+ `${VesuMultiplyAdapter.name}::getVesuMultiplyCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`
816
+ );
817
+
818
+ const legLTV = await this.vesuAdapter.getLTVConfig(
819
+ this.config.networkConfig
820
+ );
821
+ const ekuboQuoter = new EkuboQuoter(
822
+ this.config.networkConfig,
823
+ this.config.pricer
824
+ );
825
+ const dexPrice = isDexPriceRequired
826
+ ? await ekuboQuoter.getDexPrice(
827
+ this.config.collateral,
828
+ this.config.debt,
829
+ this.config.quoteAmountToFetchPrice
830
+ )
831
+ : 1;
832
+ logger.verbose(
833
+ `${VesuMultiplyAdapter.name}::getVesuMultiplyCall dexPrice: ${dexPrice}, ltv: ${legLTV}`
834
+ );
599
835
 
600
836
  // compute optimal amount of collateral and debt post addition/removal
601
837
  // target hf = collateral * collateralPrice * ltv / debt * debtPrice
602
- // assuming X to be the usd amount of debt borrowed or repaied (negative).
838
+ // assuming X to be the usd amount of debt borrowed or repaied (negative).
603
839
  // target hf = (((collateral + legDepositAmount) * collateralPrice + X)) * ltv / (debt * debtPrice + X)
604
840
  // => X * target hf = (((collateral + legDepositAmount) * collateralPrice + X)) * ltv - (debt * debtPrice * target hf)
605
841
  // => X * (target hf - ltv)= ((collateral + legDepositAmount) * collateralPrice * ltv) - (debt * debtPrice * target hf)
606
842
  // => X = (((collateral + legDepositAmount) * collateralPrice * ltv) - (debt * debtPrice * target hf)) / (target hf - ltv)
607
843
 
608
- const addedCollateral = params.amount
609
- .multipliedBy(isDeposit ? 1 : -1)
610
- logger.verbose(`${VesuMultiplyAdapter.name}::getVesuMultiplyCall addedCollateral: ${addedCollateral}`);
611
- const numeratorPart1 = (existingCollateralInfo.amount.plus((addedCollateral))).multipliedBy(collateralPrice).multipliedBy(legLTV);
612
- logger.verbose(`${VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart1: ${numeratorPart1}`);
613
- const numeratorPart2 = existingDebtInfo.amount.multipliedBy(debtPrice).multipliedBy(this.config.targetHealthFactor);
614
- logger.verbose(`${VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart2: ${numeratorPart2}`);
615
- const denominatorPart = this.config.targetHealthFactor - (legLTV / dexPrice); // TODO Write reason for this. this dexPrice is some custom thing. this dexPrice is probably exchange rate (1 xWBTC in WBTC terms)
616
- logger.verbose(`${VesuMultiplyAdapter.name}::getVesuMultiplyCall denominatorPart: ${denominatorPart}`);
617
- const x_debt_usd = numeratorPart1.minus(numeratorPart2).dividedBy(denominatorPart);
618
- logger.verbose(`${VesuMultiplyAdapter.name}::getVesuMultiplyCall x_debt_usd: ${x_debt_usd}`);
619
- logger.debug(`${VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart1: ${numeratorPart1}, numeratorPart2: ${numeratorPart2}, denominatorPart: ${denominatorPart}`);
844
+ const addedCollateral = params.amount.multipliedBy(isDeposit ? 1 : -1);
845
+ logger.verbose(
846
+ `${VesuMultiplyAdapter.name}::getVesuMultiplyCall addedCollateral: ${addedCollateral}`
847
+ );
848
+ const numeratorPart1 = existingCollateralInfo.amount
849
+ .plus(addedCollateral)
850
+ .multipliedBy(collateralPrice)
851
+ .multipliedBy(legLTV);
852
+ logger.verbose(
853
+ `${VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart1: ${numeratorPart1}`
854
+ );
855
+ const numeratorPart2 = existingDebtInfo.amount
856
+ .multipliedBy(debtPrice)
857
+ .multipliedBy(this.config.targetHealthFactor);
858
+ logger.verbose(
859
+ `${VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart2: ${numeratorPart2}`
860
+ );
861
+ const denominatorPart = this.config.targetHealthFactor - legLTV / dexPrice; // TODO Write reason for this. this dexPrice is some custom thing. this dexPrice is probably exchange rate (1 xWBTC in WBTC terms)
862
+ logger.verbose(
863
+ `${VesuMultiplyAdapter.name}::getVesuMultiplyCall denominatorPart: ${denominatorPart}`
864
+ );
865
+ const x_debt_usd = numeratorPart1
866
+ .minus(numeratorPart2)
867
+ .dividedBy(denominatorPart);
868
+ logger.verbose(
869
+ `${VesuMultiplyAdapter.name}::getVesuMultiplyCall x_debt_usd: ${x_debt_usd}`
870
+ );
871
+ logger.debug(
872
+ `${VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart1: ${numeratorPart1}, numeratorPart2: ${numeratorPart2}, denominatorPart: ${denominatorPart}`
873
+ );
620
874
 
621
875
  // both in underlying
622
876
  // debtAmount in debt units
623
- let debtAmount = new Web3Number(x_debt_usd.dividedBy(debtPrice).toFixed(this.config.debt.decimals), this.config.debt.decimals);
877
+ let debtAmount = new Web3Number(
878
+ x_debt_usd.dividedBy(debtPrice).toFixed(this.config.debt.decimals),
879
+ this.config.debt.decimals
880
+ );
624
881
  const marginAmount = addedCollateral;
625
882
  const collateralToken = this.config.collateral;
626
883
  const debtToken = this.config.debt;
627
- const debtAmountInCollateralUnits = new Web3Number(debtAmount.multipliedBy(debtPrice).dividedBy(collateralPrice).multipliedBy(10 ** collateralToken.decimals).toFixed(0), collateralToken.decimals);
628
-
884
+ const debtAmountInCollateralUnits = new Web3Number(
885
+ debtAmount
886
+ .multipliedBy(debtPrice)
887
+ .dividedBy(collateralPrice)
888
+ .multipliedBy(10 ** collateralToken.decimals)
889
+ .toFixed(0),
890
+ collateralToken.decimals
891
+ );
892
+
629
893
  // increase multiply lever or not
630
894
  const isIncrease = debtAmount.greaterThanOrEqualTo(0);
631
895
 
632
-
633
896
  // due to directional limitations in multiply contract
634
897
  if (isIncrease && debtAmount.lessThan(0)) {
635
898
  // we are increasing lever but math says reduce debt
@@ -640,23 +903,37 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
640
903
  // - so just set debt 0
641
904
  debtAmount = Web3Number.fromWei(0, this.config.debt.decimals);
642
905
  }
643
- logger.verbose(`${VesuMultiplyAdapter.name}::getVesuMultiplyCall debtAmount: ${debtAmount}, marginAmount: ${marginAmount}`);
906
+ logger.verbose(
907
+ `${VesuMultiplyAdapter.name}::getVesuMultiplyCall debtAmount: ${debtAmount}, marginAmount: ${marginAmount}`
908
+ );
644
909
  if (!debtAmount.isZero()) {
645
910
  // Get swap quote for leverage operation
646
911
  // Determine swap direction based on operation type
647
-
648
- try {
912
+
913
+ try {
649
914
  const swapQuote = await ekuboQuoter.getQuote(
650
915
  collateralToken.address.address,
651
916
  debtToken.address.address,
652
- debtAmountInCollateralUnits.multipliedBy(-1)// negative for exact amount out
917
+ debtAmountInCollateralUnits.multipliedBy(-1) // negative for exact amount out
653
918
  );
654
-
919
+
655
920
  // todo add better slip checks
656
921
  // Check price impact
657
- if (swapQuote.price_impact < 0.01) { // 1% max price impact
922
+ if (swapQuote.price_impact < 0.01) {
923
+ // 1% max price impact
658
924
  // from and toToken param position reversed, to fetch the required quote and keep things generalised
659
- leverSwap = ekuboQuoter.getVesuMultiplyQuote(swapQuote, debtToken, collateralToken);
925
+
926
+ leverSwap = debtAmount.isNegative()
927
+ ? ekuboQuoter.getVesuMultiplyQuote(
928
+ swapQuote,
929
+ collateralToken,
930
+ debtToken
931
+ )
932
+ : ekuboQuoter.getVesuMultiplyQuote(
933
+ swapQuote,
934
+ debtToken,
935
+ collateralToken
936
+ );
660
937
  //console.log("leverSwap", leverSwap[-1].token_amount);
661
938
  //console.log(JSON.stringify(leverSwap));
662
939
  // Calculate limit amount with slippage protection
@@ -672,215 +949,309 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
672
949
  // For decrease: maximum amount of collateral used
673
950
  // from collateral token to debt token
674
951
  //leverSwapLimitAmount = await ekuboQuoter.getSwapLimitAmount(collateralToken, debtToken, debtAmountInCollateralUnits.multipliedBy(-1), MAX_SLIPPAGE);
675
- leverSwapLimitAmount = debtAmount.abs().multipliedBy(1 - MAX_SLIPPAGE);
952
+ leverSwapLimitAmount = debtAmount
953
+ .abs()
954
+ .multipliedBy(1 - MAX_SLIPPAGE);
676
955
  //console.log("anotherleverSwapLimitAmount", anotherleverSwapLimitAmount, leverSwapLimitAmount);
677
956
  } else {
678
- leverSwapLimitAmount = Web3Number.fromWei(0, this.config.debt.decimals);
957
+ leverSwapLimitAmount = Web3Number.fromWei(
958
+ 0,
959
+ this.config.debt.decimals
960
+ );
679
961
  }
680
962
  await new Promise((resolve) => setTimeout(resolve, 10000));
681
963
  //console.log("leverSwapLimitAmount", leverSwapLimitAmount);
682
964
  } else {
683
- throw new Error(`VesuMultiplyAdapter: Price impact too high (${swapQuote.price_impact}), skipping swap`);
965
+ throw new Error(
966
+ `VesuMultiplyAdapter: Price impact too high (${swapQuote.price_impact}), skipping swap`
967
+ );
684
968
  }
685
969
  } catch (error) {
686
- throw new Error(`VesuMultiplyAdapter: Failed to get swap quote: ${error}`);
970
+ throw new Error(
971
+ `VesuMultiplyAdapter: Failed to get swap quote: ${error}`
972
+ );
687
973
  }
688
974
  }
689
-
690
- const multiplyParams = await this.getLeverParams(isIncrease, params, leverSwap, leverSwapLimitAmount);
691
- const call = multiplyContract.populate('modify_lever', {
692
- modify_lever_params: this.formatMultiplyParams(isIncrease, multiplyParams)
975
+
976
+ const multiplyParams = await this.getLeverParams(
977
+ isIncrease,
978
+ params,
979
+ leverSwap,
980
+ leverSwapLimitAmount
981
+ );
982
+ const call = multiplyContract.populate("modify_lever", {
983
+ modify_lever_params: this.formatMultiplyParams(
984
+ isIncrease,
985
+ multiplyParams
986
+ ),
693
987
  });
694
988
 
695
989
  return call.calldata as bigint[];
696
990
  }
697
991
 
698
- private async getLeverParams(isIncrease: boolean, params: DepositParams | WithdrawParams, leverSwap: Swap[], leverSwapLimitAmount: Web3Number): Promise<IncreaseLeverParams | DecreaseLeverParams> {
699
- const multiplyParams: IncreaseLeverParams | DecreaseLeverParams = isIncrease ? {
700
- user: this.config.vaultAllocator,
701
- pool_id: this.config.poolId,
702
- collateral_asset: this.config.collateral.address,
703
- debt_asset: this.config.debt.address,
704
- recipient: this.config.vaultAllocator,
705
- add_margin: params.amount, // multiplied by collateral decimals in format
706
- margin_swap: [],
707
- margin_swap_limit_amount: Web3Number.fromWei(0, this.config.collateral.decimals),
708
- lever_swap: leverSwap,
709
- lever_swap_limit_amount: leverSwapLimitAmount
710
- } : {
711
- user: this.config.vaultAllocator,
712
- pool_id: this.config.poolId,
713
- collateral_asset: this.config.collateral.address,
714
- debt_asset: this.config.debt.address,
715
- recipient: this.config.vaultAllocator,
716
- sub_margin: params.amount,
717
- lever_swap: leverSwap,
718
- lever_swap_limit_amount: leverSwapLimitAmount,
719
- lever_swap_weights: [],
720
- withdraw_swap: [],
721
- withdraw_swap_limit_amount: Web3Number.fromWei(0, this.config.collateral.decimals),
722
- withdraw_swap_weights: [],
723
- close_position: false
724
- };
992
+ private async getLeverParams(
993
+ isIncrease: boolean,
994
+ params: DepositParams | WithdrawParams,
995
+ leverSwap: Swap[],
996
+ leverSwapLimitAmount: Web3Number
997
+ ): Promise<IncreaseLeverParams | DecreaseLeverParams> {
998
+ const multiplyParams: IncreaseLeverParams | DecreaseLeverParams = isIncrease
999
+ ? {
1000
+ user: this.config.vaultAllocator,
1001
+ pool_id: this.config.poolId,
1002
+ collateral_asset: this.config.collateral.address,
1003
+ debt_asset: this.config.debt.address,
1004
+ recipient: this.config.vaultAllocator,
1005
+ add_margin: params.amount, // multiplied by collateral decimals in format
1006
+ margin_swap: [],
1007
+ margin_swap_limit_amount: Web3Number.fromWei(
1008
+ 0,
1009
+ this.config.collateral.decimals
1010
+ ),
1011
+ lever_swap: leverSwap,
1012
+ lever_swap_limit_amount: leverSwapLimitAmount,
1013
+ }
1014
+ : {
1015
+ user: this.config.vaultAllocator,
1016
+ pool_id: this.config.poolId,
1017
+ collateral_asset: this.config.collateral.address,
1018
+ debt_asset: this.config.debt.address,
1019
+ recipient: this.config.vaultAllocator,
1020
+ sub_margin: params.amount,
1021
+ lever_swap: leverSwap,
1022
+ lever_swap_limit_amount: leverSwapLimitAmount,
1023
+ lever_swap_weights: [],
1024
+ withdraw_swap: [],
1025
+ withdraw_swap_limit_amount: Web3Number.fromWei(
1026
+ 0,
1027
+ this.config.collateral.decimals
1028
+ ),
1029
+ withdraw_swap_weights: [],
1030
+ close_position: false,
1031
+ };
725
1032
  return multiplyParams;
726
1033
  }
727
1034
 
728
- private async getWithdrawalCalldata(params: WithdrawParams): Promise<bigint[]> {
1035
+ private async getWithdrawalCalldata(
1036
+ params: WithdrawParams
1037
+ ): Promise<bigint[]> {
729
1038
  //params.amount must be in btc here
730
1039
  const { isV2 } = getVesuSingletonAddress(this.config.poolId);
731
- const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
1040
+ const vesuMultiply = isV2
1041
+ ? this.vesuAdapter.VESU_MULTIPLY
1042
+ : this.vesuAdapter.VESU_MULTIPLY_V1;
732
1043
  const multiplyContract = new Contract({
733
- abi: VesuMultiplyAbi,
734
- address: vesuMultiply.address,
735
- providerOrAccount: this.config.networkConfig.provider
1044
+ abi: VesuMultiplyAbi,
1045
+ address: vesuMultiply.address,
1046
+ providerOrAccount: this.config.networkConfig.provider,
736
1047
  });
737
1048
  let leverSwap: Swap[] = [];
738
1049
  let leverSwapLimitAmount = Web3Number.fromWei(0, this.config.debt.decimals);
739
- const existingPositions = await this.vesuAdapter.getPositions(this.config.networkConfig);
1050
+ const existingPositions = await this.vesuAdapter.getPositions(
1051
+ this.config.networkConfig
1052
+ );
740
1053
  const existingCollateralInfo = existingPositions[0];
741
1054
  const existingDebtInfo = existingPositions[1];
742
1055
  const collateralToken = this.config.collateral;
743
1056
  const debtToken = this.config.debt;
744
- const collateralPrice = await this.config.pricer.getPrice(collateralToken.symbol);
1057
+ const collateralPrice = await this.config.pricer.getPrice(
1058
+ collateralToken.symbol
1059
+ );
745
1060
  const debtPrice = await this.config.pricer.getPrice(debtToken.symbol);
746
1061
  // the debt amount is negative as we are reducing debt to withdraw
747
1062
  const { deltadebtAmountUnits: debtAmountToRepay } =
748
- calculateDebtReductionAmountForWithdrawal(
749
- existingDebtInfo.amount,
750
- existingCollateralInfo.amount,
751
- MAX_LIQUIDATION_RATIO,
752
- params.amount,
753
- collateralPrice.price,
754
- debtPrice.price,
755
- debtToken.decimals
756
- );
1063
+ calculateDebtReductionAmountForWithdrawal(
1064
+ existingDebtInfo.amount,
1065
+ existingCollateralInfo.amount,
1066
+ MAX_LIQUIDATION_RATIO,
1067
+ params.amount,
1068
+ collateralPrice.price,
1069
+ debtPrice.price,
1070
+ debtToken.decimals
1071
+ );
757
1072
  //console.log("debtAmountToRepay", debtAmountToRepay);
758
- if(!debtAmountToRepay) {
1073
+ if (!debtAmountToRepay) {
759
1074
  throw new Error("error calculating debt amount to repay");
760
1075
  }
761
- const ekuboQuoter = new EkuboQuoter(this.config.networkConfig, this.config.pricer);
762
- const debtInDebtUnits = new Web3Number(debtAmountToRepay, debtToken.decimals).dividedBy(debtPrice.price).multipliedBy(10 ** debtToken.decimals);
1076
+ const ekuboQuoter = new EkuboQuoter(
1077
+ this.config.networkConfig,
1078
+ this.config.pricer
1079
+ );
1080
+ const debtInDebtUnits = new Web3Number(
1081
+ debtAmountToRepay,
1082
+ debtToken.decimals
1083
+ )
1084
+ .dividedBy(debtPrice.price)
1085
+ .multipliedBy(10 ** debtToken.decimals);
763
1086
  const swapQuote = await ekuboQuoter.getQuote(
764
1087
  debtToken.address.address,
765
1088
  collateralToken.address.address,
766
1089
  debtInDebtUnits
767
- )
1090
+ );
768
1091
  const MAX_SLIPPAGE = 0.002; // 0.2% slippag
769
- if(swapQuote.price_impact < 0.0025) {
770
- leverSwap = ekuboQuoter.getVesuMultiplyQuote(swapQuote, collateralToken, debtToken);
1092
+ if (swapQuote.price_impact < 0.0025) {
1093
+ leverSwap = ekuboQuoter.getVesuMultiplyQuote(
1094
+ swapQuote,
1095
+ collateralToken,
1096
+ debtToken
1097
+ );
771
1098
  } else {
772
- logger.error(`VesuMultiplyAdapter: Price impact too high (${swapQuote.price_impact}), skipping swap`);
1099
+ logger.error(
1100
+ `VesuMultiplyAdapter: Price impact too high (${swapQuote.price_impact}), skipping swap`
1101
+ );
773
1102
  }
774
1103
 
775
- leverSwapLimitAmount = new Web3Number(debtAmountToRepay, debtToken.decimals).abs().multipliedBy(1 + MAX_SLIPPAGE);
1104
+ leverSwapLimitAmount = new Web3Number(debtAmountToRepay, debtToken.decimals)
1105
+ .abs()
1106
+ .multipliedBy(1 + MAX_SLIPPAGE);
776
1107
  //leverSwapLimitAmount = await ekuboQuoter.getSwapLimitAmount(debtToken, collateralToken, debtInCollateralUnits, MAX_SLIPPAGE);
777
- const multiplyParams = await this.getLeverParams(false, params, leverSwap, leverSwapLimitAmount);
778
- const call = multiplyContract.populate('modify_lever', {
779
- modify_lever_params: this.formatMultiplyParams(false, multiplyParams)
1108
+ const multiplyParams = await this.getLeverParams(
1109
+ false,
1110
+ params,
1111
+ leverSwap,
1112
+ leverSwapLimitAmount
1113
+ );
1114
+ const call = multiplyContract.populate("modify_lever", {
1115
+ modify_lever_params: this.formatMultiplyParams(false, multiplyParams),
780
1116
  });
781
1117
  return call.calldata as bigint[];
782
1118
  }
783
1119
 
784
- formatMultiplyParams(isIncrease: boolean, params: IncreaseLeverParams | DecreaseLeverParams) {
1120
+ formatMultiplyParams(
1121
+ isIncrease: boolean,
1122
+ params: IncreaseLeverParams | DecreaseLeverParams
1123
+ ) {
785
1124
  if (isIncrease) {
786
1125
  const _params = params as IncreaseLeverParams;
787
1126
  return {
788
- action: new CairoCustomEnum({ IncreaseLever: {
1127
+ action: new CairoCustomEnum({
1128
+ IncreaseLever: {
1129
+ pool_id: _params.pool_id.toBigInt(),
1130
+ collateral_asset: _params.collateral_asset.toBigInt(),
1131
+ debt_asset: _params.debt_asset.toBigInt(),
1132
+ user: _params.user.toBigInt(),
1133
+ add_margin: BigInt(_params.add_margin.toWei()),
1134
+ margin_swap: _params.margin_swap.map((swap) => ({
1135
+ route: swap.route.map((route) => ({
1136
+ pool_key: {
1137
+ token0: route.pool_key.token0.toBigInt(),
1138
+ token1: route.pool_key.token1.toBigInt(),
1139
+ fee: route.pool_key.fee,
1140
+ tick_spacing: route.pool_key.tick_spacing,
1141
+ extension: BigInt(
1142
+ num.hexToDecimalString(route.pool_key.extension)
1143
+ ),
1144
+ },
1145
+ sqrt_ratio_limit: uint256.bnToUint256(
1146
+ route.sqrt_ratio_limit.toWei()
1147
+ ),
1148
+ skip_ahead: BigInt(100),
1149
+ })),
1150
+ token_amount: {
1151
+ token: swap.token_amount.token.toBigInt(),
1152
+ amount: swap.token_amount.amount.toI129(),
1153
+ },
1154
+ })),
1155
+ margin_swap_limit_amount: BigInt(
1156
+ _params.margin_swap_limit_amount.toWei()
1157
+ ),
1158
+ lever_swap: _params.lever_swap.map((swap) => ({
1159
+ route: swap.route.map((route) => ({
1160
+ pool_key: {
1161
+ token0: route.pool_key.token0.toBigInt(),
1162
+ token1: route.pool_key.token1.toBigInt(),
1163
+ fee: route.pool_key.fee,
1164
+ tick_spacing: route.pool_key.tick_spacing,
1165
+ extension: BigInt(
1166
+ num.hexToDecimalString(route.pool_key.extension)
1167
+ ),
1168
+ },
1169
+ sqrt_ratio_limit: uint256.bnToUint256(
1170
+ route.sqrt_ratio_limit.toWei()
1171
+ ),
1172
+ skip_ahead: BigInt(0),
1173
+ })),
1174
+ token_amount: {
1175
+ token: swap.token_amount.token.toBigInt(),
1176
+ amount: swap.token_amount.amount.toI129(),
1177
+ },
1178
+ })),
1179
+ lever_swap_limit_amount: BigInt(
1180
+ _params.lever_swap_limit_amount.toWei()
1181
+ ),
1182
+ },
1183
+ }),
1184
+ };
1185
+ }
1186
+
1187
+ const _params = params as DecreaseLeverParams;
1188
+ return {
1189
+ action: new CairoCustomEnum({
1190
+ DecreaseLever: {
789
1191
  pool_id: _params.pool_id.toBigInt(),
790
1192
  collateral_asset: _params.collateral_asset.toBigInt(),
791
1193
  debt_asset: _params.debt_asset.toBigInt(),
792
1194
  user: _params.user.toBigInt(),
793
- add_margin: BigInt(_params.add_margin.toWei()),
794
- margin_swap: _params.margin_swap.map(swap => ({
795
- route: swap.route.map(route => ({
1195
+ sub_margin: BigInt(_params.sub_margin.toWei()),
1196
+ recipient: _params.recipient.toBigInt(),
1197
+ lever_swap: _params.lever_swap.map((swap) => ({
1198
+ route: swap.route.map((route) => ({
796
1199
  pool_key: {
797
1200
  token0: route.pool_key.token0.toBigInt(),
798
1201
  token1: route.pool_key.token1.toBigInt(),
799
1202
  fee: route.pool_key.fee,
800
1203
  tick_spacing: route.pool_key.tick_spacing,
801
- extension: BigInt(num.hexToDecimalString(route.pool_key.extension)),
1204
+ extension: ContractAddr.from(
1205
+ route.pool_key.extension
1206
+ ).toBigInt(),
802
1207
  },
803
- sqrt_ratio_limit: uint256.bnToUint256(route.sqrt_ratio_limit.toWei()),
804
- skip_ahead: BigInt(100)
1208
+ sqrt_ratio_limit: uint256.bnToUint256(
1209
+ route.sqrt_ratio_limit.toWei()
1210
+ ),
1211
+ skip_ahead: BigInt(route.skip_ahead.toWei()),
805
1212
  })),
806
1213
  token_amount: {
807
1214
  token: swap.token_amount.token.toBigInt(),
808
- amount: swap.token_amount.amount.toI129()
809
- }
1215
+ amount: swap.token_amount.amount.toI129(),
1216
+ },
810
1217
  })),
811
- margin_swap_limit_amount: BigInt(_params.margin_swap_limit_amount.toWei()),
812
- lever_swap: _params.lever_swap.map(swap => ({
813
- route: swap.route.map(route => ({
1218
+ lever_swap_limit_amount: BigInt(
1219
+ _params.lever_swap_limit_amount.toWei()
1220
+ ),
1221
+ lever_swap_weights: _params.lever_swap_weights.map((weight) =>
1222
+ BigInt(weight.toWei())
1223
+ ),
1224
+ withdraw_swap: _params.withdraw_swap.map((swap) => ({
1225
+ route: swap.route.map((route) => ({
814
1226
  pool_key: {
815
1227
  token0: route.pool_key.token0.toBigInt(),
816
1228
  token1: route.pool_key.token1.toBigInt(),
817
1229
  fee: route.pool_key.fee,
818
1230
  tick_spacing: route.pool_key.tick_spacing,
819
- extension: BigInt(num.hexToDecimalString(route.pool_key.extension)),
1231
+ extension: ContractAddr.from(
1232
+ route.pool_key.extension
1233
+ ).toBigInt(),
820
1234
  },
821
- sqrt_ratio_limit: uint256.bnToUint256(route.sqrt_ratio_limit.toWei()),
822
- skip_ahead: BigInt(0)
1235
+ sqrt_ratio_limit: uint256.bnToUint256(
1236
+ route.sqrt_ratio_limit.toWei()
1237
+ ),
1238
+ skip_ahead: BigInt(route.skip_ahead.toWei()),
823
1239
  })),
824
1240
  token_amount: {
825
1241
  token: swap.token_amount.token.toBigInt(),
826
- amount: swap.token_amount.amount.toI129()
827
- }
828
- })),
829
- lever_swap_limit_amount: BigInt(_params.lever_swap_limit_amount.toWei()),
830
- } }),
831
- }
832
- }
833
-
834
- const _params = params as DecreaseLeverParams;
835
- return {
836
- action: new CairoCustomEnum({ DecreaseLever: {
837
- pool_id: _params.pool_id.toBigInt(),
838
- collateral_asset: _params.collateral_asset.toBigInt(),
839
- debt_asset: _params.debt_asset.toBigInt(),
840
- user: _params.user.toBigInt(),
841
- sub_margin: BigInt(_params.sub_margin.toWei()),
842
- recipient: _params.recipient.toBigInt(),
843
- lever_swap: _params.lever_swap.map(swap => ({
844
- route: swap.route.map(route => ({
845
- pool_key: {
846
- token0: route.pool_key.token0.toBigInt(),
847
- token1: route.pool_key.token1.toBigInt(),
848
- fee: route.pool_key.fee,
849
- tick_spacing: route.pool_key.tick_spacing,
850
- extension: ContractAddr.from(route.pool_key.extension).toBigInt(),
851
- },
852
- sqrt_ratio_limit: uint256.bnToUint256(route.sqrt_ratio_limit.toWei()),
853
- skip_ahead: BigInt(route.skip_ahead.toWei())
854
- })),
855
- token_amount: {
856
- token: swap.token_amount.token.toBigInt(),
857
- amount: swap.token_amount.amount.toI129()
858
- }
859
- })),
860
- lever_swap_limit_amount: BigInt(_params.lever_swap_limit_amount.toWei()),
861
- lever_swap_weights: _params.lever_swap_weights.map(weight => BigInt(weight.toWei())),
862
- withdraw_swap: _params.withdraw_swap.map(swap => ({
863
- route: swap.route.map(route => ({
864
- pool_key: {
865
- token0: route.pool_key.token0.toBigInt(),
866
- token1: route.pool_key.token1.toBigInt(),
867
- fee: route.pool_key.fee,
868
- tick_spacing: route.pool_key.tick_spacing,
869
- extension: ContractAddr.from(route.pool_key.extension).toBigInt(),
1242
+ amount: swap.token_amount.amount.toI129(),
870
1243
  },
871
- sqrt_ratio_limit: uint256.bnToUint256(route.sqrt_ratio_limit.toWei()),
872
- skip_ahead: BigInt(route.skip_ahead.toWei())
873
1244
  })),
874
- token_amount: {
875
- token: swap.token_amount.token.toBigInt(),
876
- amount: swap.token_amount.amount.toI129()
877
- }
878
- })),
879
- withdraw_swap_limit_amount: BigInt(_params.withdraw_swap_limit_amount.toWei()),
880
- withdraw_swap_weights: _params.withdraw_swap_weights.map(weight => BigInt(weight.toWei())),
881
- close_position: _params.close_position,
882
- }}),
883
- }
1245
+ withdraw_swap_limit_amount: BigInt(
1246
+ _params.withdraw_swap_limit_amount.toWei()
1247
+ ),
1248
+ withdraw_swap_weights: _params.withdraw_swap_weights.map((weight) =>
1249
+ BigInt(weight.toWei())
1250
+ ),
1251
+ close_position: _params.close_position,
1252
+ },
1253
+ }),
1254
+ };
884
1255
  }
885
1256
 
886
1257
  async getHealthFactor(): Promise<number> {
@@ -890,15 +1261,19 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
890
1261
 
891
1262
  async getNetAPY(): Promise<number> {
892
1263
  const positions = await this.getPositions();
893
- logger.verbose(`${this.name}::getNetAPY: positions: ${JSON.stringify(positions)}`);
894
- const allZero = positions.every(p => p.usdValue === 0);
1264
+ logger.verbose(
1265
+ `${this.name}::getNetAPY: positions: ${JSON.stringify(positions)}`
1266
+ );
1267
+ const allZero = positions.every((p) => p.usdValue === 0);
895
1268
 
896
1269
  // in case of zero positions, apy will come zero/NaN
897
1270
  // bcz of net 0 zero weights
898
1271
  if (allZero) {
899
1272
  // use approx dummy usd values to compute netAPY
900
1273
  const collateralUSD = 1000;
901
- const maxLTV = await this.vesuAdapter.getLTVConfig(this.config.networkConfig);
1274
+ const maxLTV = await this.vesuAdapter.getLTVConfig(
1275
+ this.config.networkConfig
1276
+ );
902
1277
  const targetHF = this.config.targetHealthFactor;
903
1278
  const maxDebt = HealthFactorMath.getMaxDebtAmountOnLooping(
904
1279
  new Web3Number(collateralUSD, this.config.collateral.decimals),
@@ -907,17 +1282,22 @@ export class VesuMultiplyAdapter extends BaseAdapter<DepositParams, WithdrawPara
907
1282
  targetHF,
908
1283
  1, // assume price 1 for simplicity
909
1284
  this.config.debt
910
- )
1285
+ );
911
1286
 
912
1287
  // debt is also added to collateral bcz, we assume debt is swapped to collateral
913
1288
  const debtUSD = maxDebt.multipliedBy(1); // assume price 1 for simplicity
914
- const netAPY = (positions[0].apy.apy * (collateralUSD + debtUSD.toNumber()) + positions[1].apy.apy * debtUSD.toNumber()) / (collateralUSD);
1289
+ const netAPY =
1290
+ (positions[0].apy.apy * (collateralUSD + debtUSD.toNumber()) +
1291
+ positions[1].apy.apy * debtUSD.toNumber()) /
1292
+ collateralUSD;
915
1293
  return netAPY;
916
1294
  }
917
1295
 
918
1296
  // Return true APY
919
1297
  const netAmount = positions.reduce((acc, curr) => acc + curr.usdValue, 0);
920
- const netAPY = positions.reduce((acc, curr) => acc + curr.apy.apy * curr.usdValue, 0) / netAmount;
1298
+ const netAPY =
1299
+ positions.reduce((acc, curr) => acc + curr.apy.apy * curr.usdValue, 0) /
1300
+ netAmount;
921
1301
  logger.verbose(`${this.name}::getNetAPY: netAPY: ${netAPY}`);
922
1302
  return netAPY;
923
1303
  }