@strkfarm/sdk 1.2.0 → 2.0.0-dca.1

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 (42) hide show
  1. package/dist/cli.js +9 -5
  2. package/dist/cli.mjs +9 -5
  3. package/dist/index.browser.global.js +65510 -38933
  4. package/dist/index.browser.mjs +5218 -1908
  5. package/dist/index.d.ts +478 -33
  6. package/dist/index.js +5499 -2156
  7. package/dist/index.mjs +5441 -2129
  8. package/package.json +4 -1
  9. package/src/data/ekubo-price-fethcer.abi.json +265 -0
  10. package/src/data/yoloVault.abi.json +777 -0
  11. package/src/dataTypes/_bignumber.ts +5 -0
  12. package/src/dataTypes/bignumber.browser.ts +5 -0
  13. package/src/dataTypes/bignumber.node.ts +5 -0
  14. package/src/dataTypes/index.ts +3 -2
  15. package/src/dataTypes/mynumber.ts +141 -0
  16. package/src/global.ts +42 -0
  17. package/src/index.browser.ts +2 -1
  18. package/src/interfaces/common.tsx +168 -2
  19. package/src/modules/apollo-client-config.ts +28 -0
  20. package/src/modules/avnu.ts +1 -1
  21. package/src/modules/ekubo-pricer.ts +79 -0
  22. package/src/modules/erc20.ts +18 -2
  23. package/src/modules/pragma.ts +23 -8
  24. package/src/modules/pricer-from-api.ts +150 -14
  25. package/src/modules/pricer.ts +2 -1
  26. package/src/modules/pricerBase.ts +2 -1
  27. package/src/node/pricer-redis.ts +2 -1
  28. package/src/strategies/base-strategy.ts +81 -2
  29. package/src/strategies/ekubo-cl-vault.tsx +686 -316
  30. package/src/strategies/factory.ts +159 -0
  31. package/src/strategies/index.ts +5 -1
  32. package/src/strategies/registry.ts +239 -0
  33. package/src/strategies/sensei.ts +361 -13
  34. package/src/strategies/types.ts +4 -0
  35. package/src/strategies/universal-adapters/vesu-adapter.ts +48 -27
  36. package/src/strategies/universal-lst-muliplier-strategy.tsx +1396 -462
  37. package/src/strategies/universal-strategy.tsx +287 -129
  38. package/src/strategies/vesu-rebalance.tsx +242 -146
  39. package/src/strategies/yoloVault.ts +463 -0
  40. package/src/utils/index.ts +1 -1
  41. package/src/utils/logger.node.ts +11 -4
  42. package/src/utils/strategy-utils.ts +61 -0
@@ -1,7 +1,7 @@
1
- import { getNoRiskTags, highlightTextWithLinks, IConfig, IProtocol, IStrategyMetadata, RiskFactor, RiskType, TokenInfo } from "@/interfaces";
1
+ import { getNoRiskTags, highlightTextWithLinks, IConfig, IProtocol, IStrategyMetadata, RiskFactor, RiskType, StrategyTag, TokenInfo, AuditStatus, SourceCodeType, AccessControlType, InstantWithdrawalVault, StrategyLiveStatus, VaultType } from "@/interfaces";
2
2
  import { BaseStrategy, SingleActionAmount, SingleTokenInfo } from "./base-strategy";
3
3
  import { ContractAddr, Web3Number } from "@/dataTypes";
4
- import { Call, Contract, uint256 } from "starknet";
4
+ import { Call, Contract, num, uint256, BlockIdentifier } from "starknet";
5
5
  import SenseiABI from "@/data/sensei.abi.json";
6
6
  import { getTrovesEndpoint, logger } from "@/utils";
7
7
  import { Global } from "@/global";
@@ -9,6 +9,10 @@ import { QuoteRequest } from "@avnu/avnu-sdk";
9
9
  import { PricerBase } from "@/modules/pricerBase";
10
10
  import ERC20ABI from "@/data/erc20.abi.json";
11
11
  import { AvnuWrapper } from "@/modules";
12
+ import { gql } from "@apollo/client";
13
+ import apolloClient from "@/modules/apollo-client";
14
+ import { VesuAdapter, VesuPools } from "./universal-adapters/vesu-adapter";
15
+ import { LSTAPRService } from "@/modules/lst-apr";
12
16
 
13
17
  export interface SenseiVaultSettings {
14
18
  mainToken: TokenInfo;
@@ -37,17 +41,27 @@ export class SenseiVault extends BaseStrategy<
37
41
  }
38
42
  }
39
43
 
40
- async getUserTVL(user: ContractAddr): Promise<SingleTokenInfo> {
44
+ async getUserTVL(user: ContractAddr, blockIdentifier: BlockIdentifier = "latest"): Promise<SingleTokenInfo> {
41
45
  const result: any = await this.contract.call(
42
46
  "describe_position",
43
47
  [user.address],
48
+ {
49
+ blockIdentifier,
50
+ }
44
51
  );
45
52
  const amount = Web3Number.fromWei(
46
53
  uint256.uint256ToBN(result[1].estimated_size).toString(),
47
54
  this.metadata.depositTokens[0].decimals,
48
55
  )
56
+
57
+ // Convert blockIdentifier to block number for pricer if it's a number
58
+ const blockNumber = typeof blockIdentifier === 'number' || typeof blockIdentifier === 'bigint'
59
+ ? Number(blockIdentifier)
60
+ : undefined;
61
+
49
62
  const price = await this.pricer.getPrice(
50
63
  this.metadata.depositTokens[0].symbol,
64
+ blockNumber
51
65
  );
52
66
  return {
53
67
  usdValue: Number(amount.toFixed(6)) * price.price,
@@ -144,23 +158,42 @@ export class SenseiVault extends BaseStrategy<
144
158
  throw new Error('No positions found');
145
159
  }
146
160
 
147
- const collateralXSTRK = Web3Number.fromWei(
161
+ let collateralXSTRK = Web3Number.fromWei(
148
162
  data.data[0].collateral.value,
149
163
  data.data[0].collateral.decimals,
150
164
  );
151
- const collateralUSDValue = Web3Number.fromWei(
165
+ let collateralUSDValue = Web3Number.fromWei(
152
166
  data.data[0].collateral.usdPrice.value,
153
167
  data.data[0].collateral.usdPrice.decimals,
154
168
  );
155
- const debtSTRK = Web3Number.fromWei(
169
+ let debtSTRK = Web3Number.fromWei(
156
170
  data.data[0].debt.value,
157
171
  data.data[0].debt.decimals,
158
172
  );
159
- const debtUSDValue = Web3Number.fromWei(
173
+ let debtUSDValue = Web3Number.fromWei(
160
174
  data.data[0].debt.usdPrice.value,
161
175
  data.data[0].debt.usdPrice.decimals,
162
176
  );
163
177
 
178
+ if (data.data[1]) {
179
+ collateralXSTRK = collateralXSTRK.plus(Web3Number.fromWei(
180
+ data.data[1].collateral.value,
181
+ data.data[1].collateral.decimals,
182
+ ));
183
+ collateralUSDValue = collateralUSDValue.plus(Web3Number.fromWei(
184
+ data.data[1].collateral.usdPrice.value,
185
+ data.data[1].collateral.usdPrice.decimals,
186
+ ));
187
+ debtSTRK = debtSTRK.plus(Web3Number.fromWei(
188
+ data.data[1].debt.value,
189
+ data.data[1].debt.decimals,
190
+ ));
191
+ debtUSDValue = debtUSDValue.plus(Web3Number.fromWei(
192
+ data.data[1].debt.usdPrice.value,
193
+ data.data[1].debt.usdPrice.decimals,
194
+ ));
195
+ }
196
+
164
197
  const xSTRKPrice = await this.getSecondaryTokenPriceRelativeToMain();
165
198
  const collateralInSTRK =
166
199
  Number(collateralXSTRK.toFixed(6)) * xSTRKPrice;
@@ -189,10 +222,11 @@ export class SenseiVault extends BaseStrategy<
189
222
  const existingCacheData = this.getCache<number>(CACHE_KEY);
190
223
  if (existingCacheData) return existingCacheData;
191
224
 
225
+ let AMOUNT = 100;
192
226
  const params: QuoteRequest = {
193
227
  sellTokenAddress: this.metadata.additionalInfo.secondaryToken.address.address,
194
228
  buyTokenAddress: this.metadata.additionalInfo.mainToken.address.address,
195
- sellAmount: BigInt(new Web3Number('1', 18).toWei()),
229
+ sellAmount: BigInt(new Web3Number(AMOUNT.toString(), 18).toWei()),
196
230
  takerAddress: this.address.address,
197
231
  };
198
232
  logger.verbose('getSecondaryTokenPriceRelativeToMain [1]', params);
@@ -212,7 +246,7 @@ export class SenseiVault extends BaseStrategy<
212
246
  Web3Number.fromWei(firstQuote.buyAmount.toString(), 18).toFixed(
213
247
  6,
214
248
  ),
215
- );
249
+ ) / AMOUNT;
216
250
  logger.verbose('getSecondaryTokenPriceRelativeToMain [2]', price);
217
251
  this.setCache(CACHE_KEY, price); // cache for 1 min
218
252
  return price;
@@ -223,6 +257,268 @@ export class SenseiVault extends BaseStrategy<
223
257
  logger.verbose('getSettings', settings);
224
258
  return settings;
225
259
  };
260
+
261
+ /**
262
+ * Calculate lifetime earnings for a user
263
+ * Not yet implemented for Sensei Vault strategy
264
+ */
265
+ getLifetimeEarnings(
266
+ userTVL: SingleTokenInfo,
267
+ investmentFlows: Array<{ amount: string; type: string; timestamp: number; tx_hash: string }>
268
+ ): any {
269
+ throw new Error("getLifetimeEarnings is not implemented yet for this strategy");
270
+ }
271
+
272
+ async netAPY(): Promise<number> {
273
+ try {
274
+ // Fetch Vesu pools and select the Re7 xSTRK pool
275
+ const { pools } = await VesuAdapter.getVesuPools();
276
+ const re7PoolId = VesuPools.Re7xSTRK;
277
+ const pool = pools.find((p: any) =>
278
+ ContractAddr.from(num.getHexString(p.id)).eq(re7PoolId),
279
+ );
280
+
281
+ if (!pool) {
282
+ logger.warn(`${SenseiVault.name}::netAPY - Re7 xSTRK pool not found`);
283
+ return 0;
284
+ }
285
+
286
+ const mainSymbol = this.metadata.additionalInfo.mainToken.symbol.toLowerCase(); // STRK
287
+ const secondarySymbol =
288
+ this.metadata.additionalInfo.secondaryToken.symbol.toLowerCase(); // xSTRK
289
+
290
+ const collateralAssetStats = pool.assets.find(
291
+ (a: any) => String(a.symbol).toLowerCase() === secondarySymbol,
292
+ )?.stats;
293
+ const debtAssetStats = pool.assets.find(
294
+ (a: any) => String(a.symbol).toLowerCase() === mainSymbol,
295
+ )?.stats;
296
+
297
+ if (!collateralAssetStats || !debtAssetStats) {
298
+ logger.warn(
299
+ `${SenseiVault.name}::netAPY - Missing collateral/debt stats on Vesu pool`,
300
+ );
301
+ return 0;
302
+ }
303
+
304
+ // Base xSTRK lending APY from Vesu
305
+ const xstrkSupplyAPY =
306
+ Number(collateralAssetStats.supplyApy?.value || 0) / 1e18;
307
+
308
+ // STRK rewards APR on xSTRK collateral from Vesu
309
+ const strkRewardsAPR = collateralAssetStats.defiSpringSupplyApr
310
+ ? Number(collateralAssetStats.defiSpringSupplyApr.value || 0) / 1e18
311
+ : 0;
312
+
313
+ // STRK borrow APY from Vesu
314
+ const borrowAPY =
315
+ Number(debtAssetStats.borrowApr?.value || 0) / 1e18;
316
+
317
+ // LST APR for xSTRK from Endur (based on underlying STRK asset)
318
+ const lstAPY = await LSTAPRService.getLSTAPR(
319
+ this.metadata.additionalInfo.mainToken.address,
320
+ );
321
+
322
+ // Collateral APY = Vesu xSTRK supply + Endur xSTRK APR + STRK rewards
323
+ const collateralAPY = xstrkSupplyAPY + lstAPY + strkRewardsAPR;
324
+
325
+ const feeFactor = this.metadata.additionalInfo.feeBps / 10000; // convert bps to decimal
326
+ const feeAdjustedColAPY =
327
+ collateralAPY - strkRewardsAPR * feeFactor;
328
+
329
+ // Position info (collateral & debt in USD terms)
330
+ const { collateralUSDValue, debtUSDValue } =
331
+ await this.getPositionInfo();
332
+
333
+ const collateralUSD = Number(collateralUSDValue.toFixed(6));
334
+ const debtUSD = Number(debtUSDValue.toFixed(6));
335
+
336
+ // Compute expected leverage using the same math as app-side strategy
337
+ const targetHf = this.metadata.additionalInfo.targetHfBps / 10000;
338
+ const xSTRKPrice = await this.getSecondaryTokenPriceRelativeToMain();
339
+ const denominator = targetHf * xSTRKPrice - 0.87;
340
+ if (denominator <= 0) {
341
+ logger.warn(
342
+ `${SenseiVault.name}::netAPY - Invalid denominator in leverage calc`,
343
+ );
344
+ return 0;
345
+ }
346
+ const borrowedSTRK = (0.87 * xSTRKPrice) / denominator;
347
+ const expectedLeverage = 1 + borrowedSTRK;
348
+ if (!Number.isFinite(expectedLeverage) || expectedLeverage <= 0) {
349
+ logger.warn(
350
+ `${SenseiVault.name}::netAPY - Non-positive or invalid expectedLeverage`,
351
+ );
352
+ return 0;
353
+ }
354
+
355
+ const payoff =
356
+ collateralUSD * feeAdjustedColAPY - debtUSD * borrowAPY;
357
+ const investment = collateralUSD - debtUSD;
358
+
359
+ if (investment === 0) {
360
+ return 0;
361
+ }
362
+
363
+ const netAPY = payoff / investment;
364
+ return Number.isFinite(netAPY) ? netAPY : 0;
365
+ } catch (error) {
366
+ logger.error(`${SenseiVault.name}::netAPY - Error`, error);
367
+ return 0;
368
+ }
369
+ }
370
+
371
+ /**
372
+ * Calculates user realized APY based on position growth accounting for deposits and withdrawals.
373
+ * Returns the APY as a number.
374
+ * Not implemented for Sensei Strategy yet.
375
+ */
376
+ async getUserRealizedAPY(
377
+ blockIdentifier: BlockIdentifier = "latest",
378
+ sinceBlocks = 600000
379
+ ): Promise<number> {
380
+ throw new Error("getUserRealizedAPY not implemented yet for Sensei strategy");
381
+
382
+ /*
383
+ logger.verbose(
384
+ `${SenseiVault.name}: getUserRealizedAPY => starting with userAddress=${userAddress.address}, blockIdentifier=${blockIdentifier}, sinceBlocks=${sinceBlocks}`
385
+ );
386
+
387
+ // Determine current block number
388
+ let blockNow =
389
+ typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint"
390
+ ? Number(blockIdentifier)
391
+ : (await this.config.provider.getBlockLatestAccepted()).block_number;
392
+
393
+ // Look back window, but never before launch block
394
+ const blockBefore = Math.max(
395
+ blockNow - sinceBlocks,
396
+ this.metadata.launchBlock
397
+ );
398
+
399
+ logger.verbose(
400
+ `${SenseiVault.name}: getUserRealizedAPY => blockNow=${blockNow}, blockBefore=${blockBefore}`
401
+ );
402
+
403
+ // Get current estimated size
404
+ const currentResult: any = await this.contract.call(
405
+ "describe_position",
406
+ [userAddress.address],
407
+ {
408
+ blockIdentifier,
409
+ }
410
+ );
411
+ const currentEstimatedSize = Web3Number.fromWei(
412
+ uint256.uint256ToBN(currentResult[1].estimated_size).toString(),
413
+ this.metadata.depositTokens[0].decimals,
414
+ );
415
+
416
+ // Get previous estimated size
417
+ const previousResult: any = await this.contract.call(
418
+ "describe_position",
419
+ [userAddress.address],
420
+ {
421
+ blockIdentifier: blockBefore,
422
+ }
423
+ );
424
+ const previousEstimatedSize = Web3Number.fromWei(
425
+ uint256.uint256ToBN(previousResult[1].estimated_size).toString(),
426
+ this.metadata.depositTokens[0].decimals,
427
+ );
428
+
429
+ logger.verbose(
430
+ `${SenseiVault.name}: getUserRealizedAPY => currentEstimatedSize=${currentEstimatedSize.toString()}, previousEstimatedSize=${previousEstimatedSize.toString()}`
431
+ );
432
+
433
+ // Query GraphQL for deposits and withdrawals between blockBefore and blockNow
434
+ let newDeposits = Web3Number.fromWei("0", this.metadata.depositTokens[0].decimals);
435
+ let newWithdrawals = Web3Number.fromWei("0", this.metadata.depositTokens[0].decimals);
436
+
437
+ try {
438
+ const { data } = await apolloClient.query({
439
+ query: gql`
440
+ query Query($where: Investment_flowsWhereInput) {
441
+ findManyInvestment_flows(where: $where) {
442
+ block_number
443
+ amount
444
+ type
445
+ }
446
+ }
447
+ `,
448
+ variables: {
449
+ where: {
450
+ contract: {
451
+ equals: this.address.address.toLowerCase(),
452
+ },
453
+ owner: {
454
+ equals: userAddress.address.toLowerCase(),
455
+ },
456
+ block_number: {
457
+ gte: blockBefore,
458
+ lte: blockNow,
459
+ },
460
+ },
461
+ },
462
+ fetchPolicy: 'no-cache',
463
+ });
464
+
465
+ // Sum deposits and withdrawals
466
+ for (const flow of data.findManyInvestment_flows) {
467
+ const amount = Web3Number.fromWei(
468
+ flow.amount,
469
+ this.metadata.depositTokens[0].decimals
470
+ );
471
+ if (flow.type === 'deposit') {
472
+ newDeposits = newDeposits.plus(amount);
473
+ } else if (flow.type === 'withdraw') {
474
+ newWithdrawals = newWithdrawals.plus(amount);
475
+ }
476
+ }
477
+
478
+ logger.verbose(
479
+ `${SenseiVault.name}: getUserRealizedAPY => newDeposits=${newDeposits.toString()}, newWithdrawals=${newWithdrawals.toString()}`
480
+ );
481
+ } catch (error) {
482
+ logger.verbose(
483
+ `${SenseiVault.name}: getUserRealizedAPY => Error querying GraphQL, continuing with zero deposits/withdrawals:`,
484
+ error
485
+ );
486
+ // Continue with zero deposits/withdrawals if GraphQL query fails
487
+ }
488
+
489
+ // Calculate growth: Current estimated size - new deposits + new withdrawals - previous estimated size
490
+ const growth = currentEstimatedSize
491
+ .minus(newDeposits)
492
+ .plus(newWithdrawals)
493
+ .minus(previousEstimatedSize);
494
+
495
+ logger.verbose(
496
+ `${SenseiVault.name}: getUserRealizedAPY => growth=${growth.toString()}`
497
+ );
498
+
499
+ // Handle edge case where previous position is zero
500
+ if (previousEstimatedSize.isZero() || previousEstimatedSize.lte(0)) {
501
+ logger.verbose(
502
+ `${SenseiVault.name}: getUserRealizedAPY => Previous position is zero, returning 0`
503
+ );
504
+ return 0;
505
+ }
506
+
507
+ // Calculate actual block difference (in case limited by launch block)
508
+ const actualBlockDiff = blockNow - blockBefore;
509
+
510
+ // Calculate APY: 100 * 365/n * growth / previousEstimatedSize
511
+ // where n is the number of blocks (sinceBlocks or actual block difference)
512
+ const growthRatio = growth.dividedBy(previousEstimatedSize);
513
+ const apy = Number(growthRatio) * 100 * 365 / actualBlockDiff;
514
+
515
+ logger.verbose(
516
+ `${SenseiVault.name}: getUserRealizedAPY => actualBlockDiff=${actualBlockDiff}, growthRatio=${Number(growthRatio)}, apy=${apy}`
517
+ );
518
+
519
+ return apy;
520
+ */
521
+ }
226
522
 
227
523
  }
228
524
 
@@ -289,9 +585,10 @@ const FAQS = [
289
585
  export const SenseiStrategies: IStrategyMetadata<SenseiVaultSettings>[] =
290
586
  [
291
587
  {
588
+ id: "xstrk_sensei",
292
589
  name: "xSTRK Sensei",
293
590
  description: highlightTextWithLinks(
294
- senseiDescription.replaceAll('{{token1}}', 'STRK').replaceAll('{{token2}}', 'xSTRK'),
591
+ senseiDescription.replace('{{token1}}', 'STRK').replace('{{token2}}', 'xSTRK'),
295
592
  [{
296
593
  highlight: "Endur",
297
594
  link: "https://endur.fi"
@@ -308,11 +605,37 @@ export const SenseiStrategies: IStrategyMetadata<SenseiVaultSettings>[] =
308
605
  ),
309
606
  launchBlock: 1053811,
310
607
  type: "Other",
608
+ curator: {
609
+ name: "Unwrap Labs",
610
+ logo: "https://assets.troves.fi/integrations/unwraplabs/white.png"
611
+ },
612
+ vaultType: {
613
+ type: VaultType.LOOPING,
614
+ description: "Creates leveraged looping position on xSTRK by borrowing STRK to increase yield"
615
+ },
311
616
  depositTokens: [
312
617
  Global.getDefaultTokens().find((t) => t.symbol === "STRK")!
313
618
  ],
314
619
  protocols: [endurProtocol, vesuProtocol],
315
- maxTVL: new Web3Number("1500000", 18),
620
+ settings: {
621
+ maxTVL: new Web3Number("1500000", 18),
622
+ alerts: [
623
+ {
624
+ type: "info",
625
+ text: "Depeg-risk: If xSTRK price on DEXes deviates from expected price, you may lose money or may have to wait for the price to recover.",
626
+ tab: "all"
627
+ }
628
+ ],
629
+ liveStatus: StrategyLiveStatus.ACTIVE,
630
+ isPaused: false,
631
+ isInMaintenance: false,
632
+ isAudited: false,
633
+ isInstantWithdrawal: true,
634
+ isTransactionHistDisabled: true,
635
+ quoteToken: Global.getDefaultTokens().find(
636
+ (t) => t.symbol === "STRK"
637
+ )!
638
+ },
316
639
  risk: {
317
640
  riskFactor: _riskFactor,
318
641
  netRisk:
@@ -335,6 +658,31 @@ export const SenseiStrategies: IStrategyMetadata<SenseiVaultSettings>[] =
335
658
  "Buy more xSTRK with borrowed STRK",
336
659
  "Repeat the process to loop your position",
337
660
  "Claim DeFi spring (STRK) rewards weekly and reinvest",
338
- ]
661
+ ],
662
+ tags: [StrategyTag.LEVERED],
663
+ security: {
664
+ auditStatus: AuditStatus.AUDITED,
665
+ sourceCode: {
666
+ type: SourceCodeType.CLOSED_SOURCE,
667
+ contractLink: "https://github.com/trovesfi/troves-contracts",
668
+ },
669
+ accessControl: {
670
+ type: AccessControlType.STANDARD_ACCOUNT,
671
+ addresses: [ContractAddr.from("0x0")],
672
+ timeLock: "2 Days",
673
+ },
674
+ },
675
+ redemptionInfo: {
676
+ instantWithdrawalVault: InstantWithdrawalVault.YES,
677
+ redemptionsInfo: [],
678
+ alerts: [],
679
+ },
680
+ usualTimeToEarnings: "2 weeks",
681
+ usualTimeToEarningsDescription: "Strategy returns depend on LST price on DEXes. Even though the true price of LST on Endur increases continuously, the DEX price may lag sometimes, and historically is seen to rebase at least once every 2 hours. This is when you realise your earnings.",
682
+ points: [{
683
+ multiplier: 4,
684
+ logo: 'https://endur.fi/favicon.ico',
685
+ toolTip: "This strategy holds xSTRK. Earn 3-4x Endur points on your xSTRK due to the leverage. Points can be found on endur.fi.",
686
+ }]
339
687
  },
340
- ];
688
+ ];
@@ -0,0 +1,4 @@
1
+ export enum LSTPriceType {
2
+ ENDUR_PRICE = 'ENDUR_PRICE',
3
+ AVNU_PRICE = 'AVNU_PRICE'
4
+ }
@@ -234,6 +234,25 @@ export const VesuPools = {
234
234
  Re7xSTRK: ContractAddr.from('0x052fb52363939c3aa848f8f4ac28f0a51379f8d1b971d8444de25fbd77d8f161'),
235
235
  Re7xBTC: ContractAddr.from('0x3a8416bf20d036df5b1cf3447630a2e1cb04685f6b0c3a70ed7fb1473548ecf'),
236
236
  Prime: ContractAddr.from('0x451fe483d5921a2919ddd81d0de6696669bccdacd859f72a4fba7656b97c3b5'),
237
+ Re7STRK: ContractAddr.from('0x01fcdacc1d8184eca7b472b5acbaf1500cec9d5683ca95fede8128b46c8f9cc2'),
238
+ }
239
+
240
+ export const VesuPoolMetadata = {
241
+ [VesuPools.Genesis.address]: {
242
+ name: 'Genesis',
243
+ },
244
+ [VesuPools.Re7xSTRK.address]: {
245
+ name: 'Re7 xSTRK',
246
+ },
247
+ [VesuPools.Re7xBTC.address]: {
248
+ name: 'Re7 xBTC',
249
+ },
250
+ [VesuPools.Prime.address]: {
251
+ name: 'Prime',
252
+ },
253
+ [VesuPools.Re7STRK.address]: {
254
+ name: 'Re7 STRK',
255
+ },
237
256
  }
238
257
 
239
258
  export const extensionMap: {[key: string]: ContractAddr} = {};
@@ -418,14 +437,14 @@ export class VesuAdapter extends BaseAdapter {
418
437
  }
419
438
  }
420
439
 
421
- getVesuModifyDelegationAdapter = (id: string): LeafAdapterFn<VesuModifyDelegationCallParams> => {
440
+ getVesuModifyDelegationAdapter = (id: string, delegatee: ContractAddr): LeafAdapterFn<VesuModifyDelegationCallParams> => {
422
441
  return () => {
423
442
  const { addr: VESU_SINGLETON, isV2 } = getVesuSingletonAddress(this.config.poolId);
424
443
  const packedArguments: bigint[] = isV2 ? [
425
- toBigInt(this.VESU_MULTIPLY.toString()), // v2
444
+ toBigInt(delegatee.toString()), // v2
426
445
  ] : [
427
446
  this.config.poolId.toBigInt(),
428
- toBigInt(this.VESU_MULTIPLY_V1.toString()), // v1
447
+ toBigInt(delegatee.toString()), // v1
429
448
  ];
430
449
  const output = this.constructSimpleLeafData({
431
450
  id: id,
@@ -434,29 +453,31 @@ export class VesuAdapter extends BaseAdapter {
434
453
  packedArguments
435
454
  }, isV2 ? SIMPLE_SANITIZER_V2 : SIMPLE_SANITIZER_VESU_V1_DELEGATIONS);
436
455
 
437
- return { leaf: output, callConstructor: this.getVesuModifyDelegationCall.bind(this) };
456
+ return { leaf: output, callConstructor: this.getVesuModifyDelegationCall(delegatee).bind(this) };
438
457
  }
439
458
  }
440
459
 
441
- getVesuModifyDelegationCall = (params: VesuModifyDelegationCallParams): ManageCall => {
442
- const VESU_SINGLETON = getVesuSingletonAddress(this.config.poolId).addr;
443
- const { contract, isV2 } = this.getVesuSingletonContract(getMainnetConfig(), this.config.poolId);
444
- const call = contract.populate('modify_delegation', isV2 ? {
445
- delegatee: this.VESU_MULTIPLY.toBigInt(),
446
- delegation: params.delegation,
447
- } : {
448
- pool_id: this.config.poolId.toBigInt(),
449
- delegatee: this.VESU_MULTIPLY_V1.toBigInt(),
450
- delegation: params.delegation,
451
- });
452
- return {
453
- sanitizer: isV2 ? SIMPLE_SANITIZER_V2 : SIMPLE_SANITIZER_VESU_V1_DELEGATIONS,
454
- call: {
455
- contractAddress: VESU_SINGLETON,
456
- selector: hash.getSelectorFromName('modify_delegation'),
457
- calldata: [
458
- ...call.calldata as bigint[]
459
- ]
460
+ getVesuModifyDelegationCall = (delegatee: ContractAddr) => {
461
+ return (params: VesuModifyDelegationCallParams) => {
462
+ const VESU_SINGLETON = getVesuSingletonAddress(this.config.poolId).addr;
463
+ const { contract, isV2 } = this.getVesuSingletonContract(getMainnetConfig(), this.config.poolId);
464
+ const call = contract.populate('modify_delegation', isV2 ? {
465
+ delegatee: delegatee.toBigInt(),
466
+ delegation: params.delegation,
467
+ } : {
468
+ pool_id: this.config.poolId.toBigInt(),
469
+ delegatee: delegatee.toBigInt(),
470
+ delegation: params.delegation,
471
+ });
472
+ return {
473
+ sanitizer: isV2 ? SIMPLE_SANITIZER_V2 : SIMPLE_SANITIZER_VESU_V1_DELEGATIONS,
474
+ call: {
475
+ contractAddress: VESU_SINGLETON,
476
+ selector: hash.getSelectorFromName('modify_delegation'),
477
+ calldata: [
478
+ ...call.calldata as bigint[]
479
+ ]
480
+ }
460
481
  }
461
482
  }
462
483
  }
@@ -654,12 +675,12 @@ export class VesuAdapter extends BaseAdapter {
654
675
  amount: collateralAmount,
655
676
  token: this.config.collateral,
656
677
  usdValue: collateralAmount.multipliedBy(token1Price.price).toNumber(),
657
- remarks: "Collateral"
678
+ remarks: `Collateral - ${VesuPoolMetadata[this.config.poolId.address].name} pool`
658
679
  }, {
659
680
  amount: debtAmount,
660
681
  token: this.config.debt,
661
682
  usdValue: debtAmount.multipliedBy(token2Price.price).toNumber(),
662
- remarks: "Debt"
683
+ remarks: `Debt - ${VesuPoolMetadata[this.config.poolId.address].name} pool`
663
684
  }];
664
685
  this.setCache(CACHE_KEY, value, 60000); // ttl: 1min
665
686
  return value;
@@ -747,7 +768,7 @@ export class VesuAdapter extends BaseAdapter {
747
768
  let pools: any[] = [];
748
769
  try {
749
770
  const data = await getAPIUsingHeadlessBrowser(
750
- `${ENDPOINTS.VESU_BASE_STAGING}/pools`
771
+ `${ENDPOINTS.VESU_BASE}/pools`
751
772
  );
752
773
  pools = data.data;
753
774
 
@@ -893,4 +914,4 @@ export class VesuAdapter extends BaseAdapter {
893
914
  }
894
915
  throw new Error('Max utilization not found');
895
916
  }
896
- }
917
+ }