@strkfarm/sdk 2.0.0-dev.3 → 2.0.0-dev.31

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.
Files changed (75) hide show
  1. package/dist/cli.js +190 -36
  2. package/dist/cli.mjs +188 -34
  3. package/dist/index.browser.global.js +78475 -45620
  4. package/dist/index.browser.mjs +19580 -9901
  5. package/dist/index.d.ts +3763 -1424
  6. package/dist/index.js +20977 -11063
  7. package/dist/index.mjs +20945 -11087
  8. package/package.json +1 -1
  9. package/src/data/avnu.abi.json +840 -0
  10. package/src/data/ekubo-price-fethcer.abi.json +265 -0
  11. package/src/dataTypes/_bignumber.ts +13 -4
  12. package/src/dataTypes/bignumber.browser.ts +6 -1
  13. package/src/dataTypes/bignumber.node.ts +5 -1
  14. package/src/dataTypes/index.ts +3 -2
  15. package/src/dataTypes/mynumber.ts +141 -0
  16. package/src/global.ts +76 -41
  17. package/src/index.browser.ts +2 -1
  18. package/src/interfaces/common.tsx +175 -3
  19. package/src/modules/ExtendedWrapperSDk/types.ts +28 -5
  20. package/src/modules/ExtendedWrapperSDk/wrapper.ts +275 -59
  21. package/src/modules/apollo-client-config.ts +28 -0
  22. package/src/modules/avnu.ts +4 -4
  23. package/src/modules/ekubo-pricer.ts +79 -0
  24. package/src/modules/ekubo-quoter.ts +48 -30
  25. package/src/modules/erc20.ts +17 -0
  26. package/src/modules/harvests.ts +43 -29
  27. package/src/modules/pragma.ts +23 -8
  28. package/src/modules/pricer-from-api.ts +156 -15
  29. package/src/modules/pricer-lst.ts +1 -1
  30. package/src/modules/pricer.ts +40 -4
  31. package/src/modules/pricerBase.ts +2 -1
  32. package/src/node/deployer.ts +36 -1
  33. package/src/node/pricer-redis.ts +2 -1
  34. package/src/strategies/base-strategy.ts +78 -10
  35. package/src/strategies/ekubo-cl-vault.tsx +906 -347
  36. package/src/strategies/factory.ts +159 -0
  37. package/src/strategies/index.ts +7 -1
  38. package/src/strategies/registry.ts +239 -0
  39. package/src/strategies/sensei.ts +335 -7
  40. package/src/strategies/svk-strategy.ts +97 -27
  41. package/src/strategies/types.ts +4 -0
  42. package/src/strategies/universal-adapters/adapter-utils.ts +2 -1
  43. package/src/strategies/universal-adapters/avnu-adapter.ts +180 -265
  44. package/src/strategies/universal-adapters/baseAdapter.ts +263 -251
  45. package/src/strategies/universal-adapters/common-adapter.ts +206 -203
  46. package/src/strategies/universal-adapters/extended-adapter.ts +490 -316
  47. package/src/strategies/universal-adapters/index.ts +11 -8
  48. package/src/strategies/universal-adapters/svk-troves-adapter.ts +364 -0
  49. package/src/strategies/universal-adapters/token-transfer-adapter.ts +200 -0
  50. package/src/strategies/universal-adapters/usdc<>usdce-adapter.ts +200 -0
  51. package/src/strategies/universal-adapters/vesu-adapter.ts +120 -82
  52. package/src/strategies/universal-adapters/vesu-modify-position-adapter.ts +476 -0
  53. package/src/strategies/universal-adapters/vesu-multiply-adapter.ts +1067 -704
  54. package/src/strategies/universal-adapters/vesu-position-common.ts +251 -0
  55. package/src/strategies/universal-adapters/vesu-supply-only-adapter.ts +18 -3
  56. package/src/strategies/universal-lst-muliplier-strategy.tsx +397 -204
  57. package/src/strategies/universal-strategy.tsx +1426 -1173
  58. package/src/strategies/vesu-extended-strategy/services/executionService.ts +2233 -0
  59. package/src/strategies/vesu-extended-strategy/services/extended-vesu-state-manager.ts +4087 -0
  60. package/src/strategies/vesu-extended-strategy/services/ltv-imbalance-rebalance-math.ts +783 -0
  61. package/src/strategies/vesu-extended-strategy/services/operationService.ts +38 -16
  62. package/src/strategies/vesu-extended-strategy/types/transaction-metadata.ts +88 -0
  63. package/src/strategies/vesu-extended-strategy/utils/config.runtime.ts +1 -0
  64. package/src/strategies/vesu-extended-strategy/utils/constants.ts +5 -6
  65. package/src/strategies/vesu-extended-strategy/utils/helper.ts +259 -103
  66. package/src/strategies/vesu-extended-strategy/vesu-extended-strategy.tsx +688 -817
  67. package/src/strategies/vesu-rebalance.tsx +255 -152
  68. package/src/utils/cacheClass.ts +11 -2
  69. package/src/utils/health-factor-math.ts +4 -1
  70. package/src/utils/index.ts +3 -1
  71. package/src/utils/logger.browser.ts +22 -4
  72. package/src/utils/logger.node.ts +259 -24
  73. package/src/utils/starknet-call-parser.ts +1036 -0
  74. package/src/utils/strategy-utils.ts +61 -0
  75. package/src/strategies/universal-adapters/unused-balance-adapter.ts +0 -109
@@ -0,0 +1,200 @@
1
+ import {
2
+ BaseAdapter,
3
+ DepositParams,
4
+ WithdrawParams,
5
+ BaseAdapterConfig,
6
+ } from "./baseAdapter";
7
+ import { toBigInt } from "./adapter-utils";
8
+ import { Protocols } from "@/interfaces";
9
+ import { SupportedPosition } from "./baseAdapter";
10
+ import { PositionAPY, APYType, PositionAmount } from "./baseAdapter";
11
+ import { Web3Number } from "@/dataTypes";
12
+ import { PositionInfo } from "./baseAdapter";
13
+ import { ManageCall } from "./baseAdapter";
14
+ import { ContractAddr } from "@/dataTypes";
15
+ import { AVNU_EXCHANGE } from "./adapter-utils";
16
+ import { hash, uint256 } from "starknet";
17
+ import { AVNU_EXCHANGE_FOR_LEGACY_USDC } from "./adapter-utils";
18
+ import { AVNU_LEGACY_SANITIZER } from "./adapter-utils";
19
+ import { assert, logger } from "@/utils";
20
+ import { ERC20 } from "@/modules";
21
+
22
+ export class UsdcToUsdceAdapter extends BaseAdapter<
23
+ DepositParams,
24
+ WithdrawParams
25
+ > {
26
+ readonly config: BaseAdapterConfig;
27
+
28
+ private _approveProofReadableId(usdcToUsdce: boolean): string {
29
+ const method = usdcToUsdce ? "swap_to_legacy" : "swap_to_new";
30
+ return `approve_${method}`;
31
+ }
32
+
33
+ private _swapProofReadableId(usdcToUsdce: boolean): string {
34
+ const method = usdcToUsdce ? "swap_to_legacy" : "swap_to_new";
35
+ const target = usdcToUsdce
36
+ ? this.config.supportedPositions[0].asset
37
+ : this.config.supportedPositions[1].asset;
38
+ return `${method}_${target.symbol}`;
39
+ }
40
+
41
+ private buildSwapLeafConfigs(usdcToUsdce: boolean): {
42
+ target: ContractAddr;
43
+ method: string;
44
+ packedArguments: bigint[];
45
+ sanitizer: ContractAddr;
46
+ id: string;
47
+ }[] {
48
+ const method = usdcToUsdce ? "swap_to_legacy" : "swap_to_new";
49
+ const target = usdcToUsdce
50
+ ? this.config.supportedPositions[0].asset
51
+ : this.config.supportedPositions[1].asset;
52
+ return [
53
+ {
54
+ target: target.address,
55
+ method: "approve",
56
+ packedArguments: [AVNU_EXCHANGE_FOR_LEGACY_USDC.toBigInt()],
57
+ id: this._approveProofReadableId(usdcToUsdce),
58
+ sanitizer: AVNU_LEGACY_SANITIZER,
59
+ },
60
+ {
61
+ target: AVNU_EXCHANGE_FOR_LEGACY_USDC,
62
+ method: method,
63
+ packedArguments: [],
64
+ id: this._swapProofReadableId(usdcToUsdce),
65
+ sanitizer: AVNU_LEGACY_SANITIZER,
66
+ },
67
+ ];
68
+ }
69
+
70
+ private async buildSwapCalls(
71
+ params: DepositParams | WithdrawParams,
72
+ usdcToUsdce: boolean,
73
+ ): Promise<ManageCall[]> {
74
+ const approveAmount = uint256.bnToUint256(params.amount.toWei());
75
+ const target = usdcToUsdce
76
+ ? this.config.supportedPositions[0].asset
77
+ : this.config.supportedPositions[1].asset;
78
+ const method = usdcToUsdce ? "swap_to_legacy" : "swap_to_new";
79
+ return [
80
+ {
81
+ proofReadableId: this._approveProofReadableId(usdcToUsdce),
82
+ sanitizer: AVNU_LEGACY_SANITIZER,
83
+ call: {
84
+ contractAddress: target.address,
85
+ selector: hash.getSelectorFromName("approve"),
86
+ calldata: [
87
+ AVNU_EXCHANGE_FOR_LEGACY_USDC.toBigInt(),
88
+ toBigInt(approveAmount.low.toString()),
89
+ toBigInt(approveAmount.high.toString()),
90
+ ],
91
+ },
92
+ },
93
+ {
94
+ proofReadableId: this._swapProofReadableId(usdcToUsdce),
95
+ sanitizer: AVNU_LEGACY_SANITIZER,
96
+ call: {
97
+ contractAddress: AVNU_EXCHANGE_FOR_LEGACY_USDC,
98
+ selector: hash.getSelectorFromName(method),
99
+ calldata: [
100
+ toBigInt(approveAmount.low.toString()), // amount low
101
+ toBigInt(approveAmount.high.toString()), // amount high
102
+ ],
103
+ },
104
+ },
105
+ ];
106
+ }
107
+
108
+ constructor(config: BaseAdapterConfig) {
109
+ super(config, UsdcToUsdceAdapter.name, Protocols.AVNU);
110
+ this.config = config as BaseAdapterConfig;
111
+ assert(this.config.supportedPositions.length === 2, "UsdcToUsdceAdapter must have 2 supported positions");
112
+ assert(this.config.supportedPositions[0].asset.symbol === "USDC", "UsdcToUsdceAdapter must have USDC as the first supported position");
113
+ assert(this.config.supportedPositions[1].asset.symbol === "USDC.e", "UsdcToUsdceAdapter must have USDCE as the second supported position");
114
+ }
115
+ //abstract means the method has no implementation in this class; instead, child classes must implement it.
116
+ protected async getAPY(
117
+ supportedPosition: SupportedPosition,
118
+ ): Promise<PositionAPY> {
119
+ return Promise.resolve({ apy: 0, type: APYType.BASE });
120
+ }
121
+
122
+ protected async getPosition(
123
+ supportedPosition: SupportedPosition,
124
+ ): Promise<PositionAmount | null> {
125
+ const toToken = this.config.supportedPositions[1].asset;
126
+ if (supportedPosition.asset.symbol != toToken.symbol) {
127
+ return null;
128
+ }
129
+ try {
130
+ // only measure balance of toToken, bcz from token usually gets trakced in unused balance or a previous avnu adapter
131
+ const balance = await new ERC20(this.config.networkConfig).balanceOf(
132
+ toToken.address,
133
+ this.config.vaultAllocator.address,
134
+ toToken.decimals,
135
+ );
136
+ return { amount: balance, remarks: `USDC.e unused balance (VA)` };
137
+ } catch (_e) {
138
+ logger.error(`${UsdcToUsdceAdapter.name}::getPosition: failed for ${toToken.symbol}`);
139
+ throw new Error(`${UsdcToUsdceAdapter.name}: failed to get balance for ${toToken.symbol}`);
140
+ }
141
+ }
142
+
143
+ async maxDeposit(amount?: Web3Number): Promise<PositionInfo> {
144
+ return Promise.resolve({
145
+ tokenInfo: this.config.baseToken,
146
+ amount: new Web3Number(0, 0),
147
+ usdValue: 0,
148
+ apy: { apy: 0, type: APYType.BASE },
149
+ protocol: Protocols.AVNU,
150
+ remarks: "",
151
+ });
152
+ }
153
+
154
+ async maxWithdraw(): Promise<PositionInfo> {
155
+ return Promise.resolve({
156
+ tokenInfo: this.config.baseToken,
157
+ amount: new Web3Number(0, 0),
158
+ usdValue: 0,
159
+ apy: { apy: 0, type: APYType.BASE },
160
+ protocol: Protocols.AVNU,
161
+ remarks: "",
162
+ });
163
+ }
164
+
165
+ protected _getDepositLeaf(): {
166
+ // considering deposit is converting usdc to usdce
167
+ target: ContractAddr;
168
+ method: string;
169
+ packedArguments: bigint[];
170
+ sanitizer: ContractAddr;
171
+ id: string;
172
+ }[] {
173
+ return this.buildSwapLeafConfigs(true);
174
+ }
175
+
176
+ protected _getWithdrawLeaf(): {
177
+ target: ContractAddr;
178
+ method: string;
179
+ packedArguments: bigint[];
180
+ sanitizer: ContractAddr;
181
+ id: string;
182
+ }[] {
183
+ return this.buildSwapLeafConfigs(false);
184
+ }
185
+
186
+ async getDepositCall(params: DepositParams): Promise<ManageCall[]> {
187
+ const calls = await this.buildSwapCalls(params, true);
188
+ return calls;
189
+ }
190
+
191
+ //Swap wbtc to usdc
192
+ async getWithdrawCall(params: WithdrawParams): Promise<ManageCall[]> {
193
+ const calls = await this.buildSwapCalls(params, false);
194
+ return calls;
195
+ }
196
+
197
+ async getHealthFactor(): Promise<number> {
198
+ return Promise.resolve(1);
199
+ }
200
+ }
@@ -16,6 +16,7 @@ import { EkuboPoolKey } from "../ekubo-cl-vault";
16
16
  import VesuPoolV2Abi from '@/data/vesu-pool-v2.abi.json';
17
17
  import VesuExtensionAbi from '@/data/vesu-extension.abi.json';
18
18
  import { CacheClass } from "@/utils/cacheClass";
19
+ import { PricerFromApi } from "@/modules";
19
20
 
20
21
  interface VesuPoolsInfo { pools: any[]; isErrorPoolsAPI: boolean };
21
22
 
@@ -178,7 +179,7 @@ function getVesuMultiplyParams(isIncrease: boolean, params: IncreaseLeverParams
178
179
  }
179
180
  }
180
181
 
181
- const _params = params as DecreaseLeverParams;
182
+ const _params = params as DecreaseLeverParams;
182
183
  return {
183
184
  action: new CairoCustomEnum({ DecreaseLever: {
184
185
  pool_id: _params.pool_id.toBigInt(),
@@ -235,6 +236,29 @@ export const VesuPools = {
235
236
  Re7xSTRK: ContractAddr.from('0x052fb52363939c3aa848f8f4ac28f0a51379f8d1b971d8444de25fbd77d8f161'),
236
237
  Re7xBTC: ContractAddr.from('0x3a8416bf20d036df5b1cf3447630a2e1cb04685f6b0c3a70ed7fb1473548ecf'),
237
238
  Re7USDCPrime: ContractAddr.from('0x02eef0c13b10b487ea5916b54c0a7f98ec43fb3048f60fdeedaf5b08f6f88aaf'),
239
+ Prime: ContractAddr.from('0x451fe483d5921a2919ddd81d0de6696669bccdacd859f72a4fba7656b97c3b5'),
240
+ Re7STRK: ContractAddr.from('0x01fcdacc1d8184eca7b472b5acbaf1500cec9d5683ca95fede8128b46c8f9cc2'),
241
+ }
242
+
243
+ export const VesuPoolMetadata = {
244
+ [VesuPools.Genesis.address]: {
245
+ name: 'Genesis',
246
+ },
247
+ [VesuPools.Re7xSTRK.address]: {
248
+ name: 'Re7 xSTRK',
249
+ },
250
+ [VesuPools.Re7xBTC.address]: {
251
+ name: 'Re7 xBTC',
252
+ },
253
+ [VesuPools.Prime.address]: {
254
+ name: 'Prime',
255
+ },
256
+ [VesuPools.Re7STRK.address]: {
257
+ name: 'Re7 STRK',
258
+ },
259
+ [VesuPools.Re7USDCPrime.address]: {
260
+ name: 'Re7 USDC Prime',
261
+ },
238
262
  }
239
263
 
240
264
  export const extensionMap: {[key: string]: ContractAddr} = {};
@@ -251,6 +275,7 @@ export function getVesuSingletonAddress(vesuPool: ContractAddr) {
251
275
  export class VesuAdapter extends CacheClass {
252
276
  VESU_MULTIPLY_V1 = ContractAddr.from('0x3630f1f8e5b8f5c4c4ae9b6620f8a570ae55cddebc0276c37550e7c118edf67');
253
277
  VESU_MULTIPLY = ContractAddr.from('0x027fef272d0a9a3844767c851a64b36fe4f0115141d81134baade95d2b27b781');
278
+ VESU_WITHDRAW_SWAP_FIXED_MULTIPLIER = ContractAddr.from('0xd2b0006de39992e78d457b7607a606c00bd6b601e9d9a77a8e1870c5e19e73');
254
279
  config: VesuAdapterConfig;
255
280
  networkConfig: IConfig | undefined;
256
281
  pricer: PricerBase | undefined;
@@ -286,31 +311,31 @@ export class VesuAdapter extends CacheClass {
286
311
  // return { leaf: output, callConstructor: this.getModifyPositionCall.bind(this) };
287
312
  // }
288
313
 
289
- // static getDefaultModifyPositionCallParams(params: {
290
- // collateralAmount: Web3Number,
291
- // isAddCollateral: boolean,
292
- // debtAmount: Web3Number,
293
- // isBorrow: boolean
294
- // }) {
295
- // return {
296
- // collateralAmount: {
297
- // amount_type: VesuAmountType.Delta,
298
- // denomination: VesuAmountDenomination.Assets,
299
- // value: {
300
- // abs: params.collateralAmount,
301
- // is_negative: !params.isAddCollateral
302
- // }
303
- // },
304
- // debtAmount: {
305
- // amount_type: VesuAmountType.Delta,
306
- // denomination: VesuAmountDenomination.Assets,
307
- // value: {
308
- // abs: params.debtAmount,
309
- // is_negative: !params.isBorrow
310
- // }
311
- // }
312
- // }
313
- // }
314
+ static getDefaultModifyPositionCallParams(params: {
315
+ collateralAmount: Web3Number,
316
+ isAddCollateral: boolean,
317
+ debtAmount: Web3Number,
318
+ isBorrow: boolean
319
+ }) {
320
+ return {
321
+ collateralAmount: {
322
+ amount_type: VesuAmountType.Delta,
323
+ denomination: VesuAmountDenomination.Assets,
324
+ value: {
325
+ abs: params.collateralAmount,
326
+ is_negative: !params.isAddCollateral
327
+ }
328
+ },
329
+ debtAmount: {
330
+ amount_type: VesuAmountType.Delta,
331
+ denomination: VesuAmountDenomination.Assets,
332
+ value: {
333
+ abs: params.debtAmount,
334
+ is_negative: !params.isBorrow
335
+ }
336
+ }
337
+ }
338
+ }
314
339
 
315
340
  // getModifyPositionCall = (params: VesuModifyPositionCallParams): ManageCall => {
316
341
  // // pub pool_id: felt252,
@@ -439,29 +464,31 @@ export class VesuAdapter extends CacheClass {
439
464
  // }
440
465
  // }
441
466
 
442
- getVesuModifyDelegationCall = (params: VesuModifyDelegationCallParams): ManageCall => {
443
- const VESU_SINGLETON = getVesuSingletonAddress(this.config.poolId).addr;
444
- const { contract, isV2 } = this.getVesuSingletonContract(getMainnetConfig(), this.config.poolId);
445
- const call = contract.populate('modify_delegation', isV2 ? {
446
- delegatee: this.VESU_MULTIPLY.toBigInt(),
447
- delegation: params.delegation,
448
- } : {
449
- pool_id: this.config.poolId.toBigInt(),
450
- delegatee: this.VESU_MULTIPLY_V1.toBigInt(),
451
- delegation: params.delegation,
452
- });
453
- return {
454
- sanitizer: isV2 ? SIMPLE_SANITIZER_V2 : SIMPLE_SANITIZER_VESU_V1_DELEGATIONS,
455
- call: {
456
- contractAddress: VESU_SINGLETON,
457
- selector: hash.getSelectorFromName('modify_delegation'),
458
- calldata: [
459
- ...call.calldata as bigint[]
460
- ]
467
+ getVesuModifyDelegationCall = (delegatee: ContractAddr) => {
468
+ return (params: VesuModifyDelegationCallParams) => {
469
+ const VESU_SINGLETON = getVesuSingletonAddress(this.config.poolId).addr;
470
+ const { contract, isV2 } = this.getVesuSingletonContract(getMainnetConfig(), this.config.poolId);
471
+ const call = contract.populate('modify_delegation', isV2 ? {
472
+ delegatee: delegatee.toBigInt(),
473
+ delegation: params.delegation,
474
+ } : {
475
+ pool_id: this.config.poolId.toBigInt(),
476
+ delegatee: delegatee.toBigInt(),
477
+ delegation: params.delegation,
478
+ });
479
+ return {
480
+ sanitizer: isV2 ? SIMPLE_SANITIZER_V2 : SIMPLE_SANITIZER_VESU_V1_DELEGATIONS,
481
+ call: {
482
+ contractAddress: VESU_SINGLETON,
483
+ selector: hash.getSelectorFromName('modify_delegation'),
484
+ calldata: [
485
+ ...call.calldata as bigint[]
486
+ ]
487
+ }
461
488
  }
462
489
  }
463
490
  }
464
-
491
+
465
492
  // getDefispringRewardsAdapter = (id: string): () => AdapterLeafType<VesuDefiSpringRewardsCallParams> => {
466
493
  // return () => {
467
494
  // const packedArguments: bigint[] = [];
@@ -538,7 +565,7 @@ export class VesuAdapter extends CacheClass {
538
565
  }
539
566
  const output: any = await contract.call('pair_config', [this.config.collateral.address.address, this.config.debt.address.address]);
540
567
  logger.verbose(`${this.config.debt.symbol}::VesuAdapter::getDebtCap debt_cap: ${output.debt_cap.toString()}`);
541
-
568
+
542
569
  if (!isV2) {
543
570
  throw new Error('getDebtCap is not supported for v1');
544
571
  }
@@ -568,7 +595,7 @@ export class VesuAdapter extends CacheClass {
568
595
 
569
596
  }
570
597
  const _interestRateConfig: any = await interestRateConfigContract.call(
571
- 'interest_rate_config',
598
+ 'interest_rate_config',
572
599
  isV2 ? [this.config.debt.address.address] : [this.config.poolId.address, this.config.debt.address.address]
573
600
  );
574
601
  const interestRateConfig: InterestRateConfig = {
@@ -581,24 +608,25 @@ export class VesuAdapter extends CacheClass {
581
608
  min_full_utilization_rate: _interestRateConfig.min_full_utilization_rate,
582
609
  max_full_utilization_rate: _interestRateConfig.max_full_utilization_rate,
583
610
  };
584
-
611
+
585
612
  const _assetConfig: any = await contract.call(
586
- isV2 ? 'asset_config' : 'asset_config_unsafe',
613
+ isV2 ? 'asset_config' : 'asset_config_unsafe',
587
614
  isV2 ? [asset.address.address] : [this.config.poolId.address, asset.address.address]
588
615
  );
589
616
  const assetConfig = isV2 ? _assetConfig : _assetConfig['0'];
590
617
  const timeDelta = assetConfig.last_updated;
591
618
  const lastFullUtilizationRate = assetConfig.last_full_utilization_rate;
592
- const currentDebt = new Web3Number((Number(assetConfig.total_nominal_debt) / 1e18).toFixed(9), asset.decimals);
619
+ const debtSharePrice = Web3Number.fromWei(assetConfig.last_rate_accumulator, 18);
620
+ const currentDebt = (new Web3Number((Number(assetConfig.total_nominal_debt) / 1e18).toFixed(9), asset.decimals)).multipliedBy(debtSharePrice);
593
621
  const totalSupply = currentDebt.plus(Web3Number.fromWei(assetConfig.reserve, asset.decimals));
594
622
 
595
623
  const ratePerSecond = BigInt(Math.round(maxBorrowAPY / 365 / 24 / 60 / 60 * Number(SCALE)));
596
624
  const maxUtilisation = this.getMaxUtilizationGivenRatePerSecond(interestRateConfig, ratePerSecond, timeDelta, lastFullUtilizationRate);
597
625
  logger.verbose(`${asset.symbol}::VesuAdapter::getMaxBorrowableByInterestRate maxUtilisation: ${Number(maxUtilisation) / 1e18}, totalSupply: ${totalSupply.toString()}`);
598
-
626
+
599
627
  const maxDebtToHave = totalSupply.multipliedBy(Number(maxUtilisation) / 1e18);
600
628
  logger.verbose(`${asset.symbol}::VesuAdapter::getMaxBorrowableByInterestRate currentDebt: ${currentDebt.toString()}, maxDebtToHave: ${maxDebtToHave.toString()}`);
601
- return maxDebtToHave.minus(currentDebt);
629
+ return {maxDebtToHave: maxDebtToHave.minus(currentDebt), currentDebt: currentDebt, totalSupply: totalSupply};
602
630
  }
603
631
 
604
632
  async getLTVConfig(config: IConfig, blockNumber: BlockIdentifier = 'latest') {
@@ -620,7 +648,7 @@ export class VesuAdapter extends CacheClass {
620
648
  throw new Error('LTV is 0');
621
649
  }
622
650
  this.setCache(CACHE_KEY, ltv, 300000); // ttl: 5min
623
- return this.getCache<number>(CACHE_KEY) as number;
651
+ return ltv;
624
652
  }
625
653
 
626
654
  async getPositions(config: IConfig, blockNumber: BlockIdentifier = 'latest'): Promise<VaultPosition[]> {
@@ -628,40 +656,39 @@ export class VesuAdapter extends CacheClass {
628
656
  throw new Error('Pricer is not initialized');
629
657
  }
630
658
  // { '0': { collateral_shares: 0n, nominal_debt: 0n }, '1': 0n, '2': 0n }
631
- const CACHE_KEY = `positions_${blockNumber}_${this.config.poolId.shortString()}_${this.config.collateral.symbol}_${this.config.debt.symbol}`;
632
- const cacheData = this.getCache<VaultPosition[]>(CACHE_KEY);
633
- if (cacheData) {
634
- return cacheData;
635
- }
659
+ // const CACHE_KEY = `positions_${blockNumber}_${this.config.poolId.shortString()}_${this.config.collateral.symbol}_${this.config.debt.symbol}`;
660
+ // const cacheData = this.getCache<VaultPosition[]>(CACHE_KEY);
661
+ // if (cacheData) {
662
+ // return cacheData;
663
+ // }
636
664
 
637
665
  const { contract, isV2} = this.getVesuSingletonContract(config, this.config.poolId);
638
666
  const output: any = await contract
639
- .call(isV2 ? 'position' : 'position_unsafe', [...(isV2 ?
667
+ .call(isV2 ? 'position' : 'position_unsafe', [...(isV2 ?
640
668
  []: [this.config.poolId.address]), // exclude pool id in v2
641
669
  this.config.collateral.address.address,
642
670
  this.config.debt.address.address,
643
671
  this.config.vaultAllocator.address
644
672
  ], { blockIdentifier: blockNumber });
645
673
 
646
- console.log(output)
647
674
  const token1Price = await this.pricer.getPrice(this.config.collateral.symbol);
648
675
  const token2Price = await this.pricer.getPrice(this.config.debt.symbol);
649
676
  logger.verbose(`VesuAdapter::getPositions token1Price: ${token1Price.price}, token2Price: ${token2Price.price}`);
650
-
677
+
651
678
  const collateralAmount = Web3Number.fromWei(output['1'].toString(), this.config.collateral.decimals);
652
679
  const debtAmount = Web3Number.fromWei(output['2'].toString(), this.config.debt.decimals);
653
680
  const value = [{
654
681
  amount: collateralAmount,
655
682
  token: this.config.collateral,
656
683
  usdValue: collateralAmount.multipliedBy(token1Price.price).toNumber(),
657
- remarks: "Collateral"
684
+ remarks: `Collateral - ${VesuPoolMetadata[this.config.poolId.address].name} pool`
658
685
  }, {
659
686
  amount: debtAmount,
660
687
  token: this.config.debt,
661
688
  usdValue: debtAmount.multipliedBy(token2Price.price).toNumber(),
662
- remarks: "Debt"
689
+ remarks: `Debt - ${VesuPoolMetadata[this.config.poolId.address].name} pool`
663
690
  }];
664
- this.setCache(CACHE_KEY, value, 60000); // ttl: 1min
691
+ // this.setCache(CACHE_KEY, value, 60000); // ttl: 1min
665
692
  return value.map(v => ({ ...v, protocol: Protocols.VESU }));
666
693
  }
667
694
 
@@ -678,7 +705,7 @@ export class VesuAdapter extends CacheClass {
678
705
  const { contract, isV2 } = this.getVesuSingletonContract(config, this.config.poolId);
679
706
  const output: any = await contract
680
707
  .call(isV2 ? 'check_collateralization' : 'check_collateralization_unsafe', [
681
- ...(isV2 ?
708
+ ...(isV2 ?
682
709
  []: [this.config.poolId.address]), // exclude pool id in v2
683
710
  this.config.collateral.address.address,
684
711
  this.config.debt.address.address,
@@ -711,12 +738,23 @@ export class VesuAdapter extends CacheClass {
711
738
 
712
739
  const collateralTokenAmount = positions[0].amount;
713
740
  const collateralUSDAmount = collateralization[0].usdValue;
714
- const collateralPrice = collateralUSDAmount / collateralTokenAmount.toNumber();
741
+ let collateralPrice = collateralUSDAmount / collateralTokenAmount.toNumber();
715
742
 
716
743
  const debtTokenAmount = positions[1].amount;
717
744
  const debtUSDAmount = collateralization[1].usdValue;
718
- const debtPrice = debtUSDAmount / debtTokenAmount.toNumber();
719
-
745
+ let debtPrice = debtUSDAmount / debtTokenAmount.toNumber();
746
+ if (isNaN(collateralPrice)) {
747
+ const pricer = new PricerFromApi(this.networkConfig!, Global.getDefaultTokens())
748
+ collateralPrice = (await pricer.getPrice(this.config.collateral.priceProxySymbol || this.config.collateral.symbol)).price;
749
+ }
750
+ if (isNaN(debtPrice)) {
751
+ const pricer = new PricerFromApi(this.networkConfig!, Global.getDefaultTokens())
752
+ debtPrice = (await pricer.getPrice(this.config.debt.priceProxySymbol || this.config.debt.symbol)).price;
753
+ }
754
+ logger.verbose(`VesuAdapter::getAssetPrices collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
755
+ if (isNaN(collateralPrice) || isNaN(debtPrice) || collateralPrice == 0 || debtPrice == 0) {
756
+ throw new Error(`VesuAdapter::getAssetPrices collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
757
+ }
720
758
  return {
721
759
  collateralTokenAmount,
722
760
  collateralUSDAmount,
@@ -747,7 +785,7 @@ export class VesuAdapter extends CacheClass {
747
785
  let pools: any[] = [];
748
786
  try {
749
787
  const data = await getAPIUsingHeadlessBrowser(
750
- `${ENDPOINTS.VESU_BASE_STAGING}/pools`
788
+ `${ENDPOINTS.VESU_BASE}/pools`
751
789
  );
752
790
  pools = data.data;
753
791
 
@@ -792,11 +830,11 @@ export class VesuAdapter extends CacheClass {
792
830
  min_full_utilization_rate,
793
831
  max_full_utilization_rate,
794
832
  } = interestRateConfig;
795
-
833
+
796
834
  const halfLifeScaled = rate_half_life * SCALE;
797
-
835
+
798
836
  let nextFullUtilizationRate: bigint;
799
-
837
+
800
838
  if (utilization < min_target_utilization) {
801
839
  const utilizationDelta =
802
840
  ((min_target_utilization - utilization) * SCALE) / min_target_utilization;
@@ -811,7 +849,7 @@ export class VesuAdapter extends CacheClass {
811
849
  } else {
812
850
  nextFullUtilizationRate = fullUtilizationRate;
813
851
  }
814
-
852
+
815
853
  if (nextFullUtilizationRate > max_full_utilization_rate) {
816
854
  return max_full_utilization_rate;
817
855
  } else if (nextFullUtilizationRate < min_full_utilization_rate) {
@@ -831,26 +869,26 @@ export class VesuAdapter extends CacheClass {
831
869
  lastFullUtilizationRate: bigint
832
870
  ): { newRatePerSecond: bigint; nextFullUtilizationRate: bigint } {
833
871
  const scaledUtilization = utilization / UTILIZATION_SCALE_TO_SCALE;
834
-
872
+
835
873
  const {
836
874
  target_utilization,
837
875
  zero_utilization_rate,
838
876
  target_rate_percent,
839
877
  } = interestRateConfig;
840
-
878
+
841
879
  const nextFullUtilizationRate = this.fullUtilizationRate(
842
880
  interestRateConfig,
843
881
  timeDelta,
844
882
  scaledUtilization,
845
883
  lastFullUtilizationRate
846
884
  );
847
-
885
+
848
886
  const targetRate =
849
887
  (((nextFullUtilizationRate - zero_utilization_rate) * target_rate_percent) / SCALE) +
850
888
  zero_utilization_rate;
851
-
889
+
852
890
  let newRatePerSecond: bigint;
853
-
891
+
854
892
  if (scaledUtilization < target_utilization) {
855
893
  newRatePerSecond =
856
894
  zero_utilization_rate +
@@ -863,10 +901,10 @@ export class VesuAdapter extends CacheClass {
863
901
  (nextFullUtilizationRate - targetRate)) /
864
902
  (UTILIZATION_SCALE - target_utilization);
865
903
  }
866
-
904
+
867
905
  return { newRatePerSecond, nextFullUtilizationRate };
868
906
  }
869
-
907
+
870
908
  /**
871
909
  * Calculates utilization given a specific rate per second.
872
910
  * This is an inverse function of the piecewise interest rate formula above.
@@ -893,4 +931,4 @@ export class VesuAdapter extends CacheClass {
893
931
  }
894
932
  throw new Error('Max utilization not found');
895
933
  }
896
- }
934
+ }