@gearbox-protocol/sdk 13.3.3 → 13.4.0-beta.2

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 (89) hide show
  1. package/dist/cjs/permissionless/utils/price-update/get-price-update-tx.js +3 -15
  2. package/dist/cjs/sdk/GearboxSDK.js +135 -20
  3. package/dist/cjs/sdk/accounts/AbstractCreditAccountsService.js +196 -340
  4. package/dist/cjs/sdk/accounts/CreditAccountsServiceV310.js +30 -35
  5. package/dist/cjs/sdk/accounts/multicall-utils.js +91 -0
  6. package/dist/cjs/sdk/base/BaseContract.js +26 -6
  7. package/dist/cjs/sdk/base/ChainContractsRegister.js +39 -2
  8. package/dist/cjs/sdk/base/Construct.js +15 -3
  9. package/dist/cjs/sdk/base/TokensMeta.js +23 -0
  10. package/dist/cjs/sdk/constants/address-provider.js +0 -22
  11. package/dist/cjs/sdk/core/AbstractAddressProviderContract.js +15 -0
  12. package/dist/cjs/sdk/market/MarketRegister.js +74 -3
  13. package/dist/cjs/sdk/market/credit/CreditFacadeV310Contract.js +6 -0
  14. package/dist/cjs/sdk/market/oracle/PriceOracleBaseContract.js +31 -50
  15. package/dist/cjs/sdk/market/pricefeeds/PriceFeedRef.js +16 -0
  16. package/dist/cjs/sdk/market/pricefeeds/PriceFeedsRegister.js +55 -12
  17. package/dist/cjs/sdk/options.js +30 -24
  18. package/dist/cjs/sdk/plugins/BasePlugin.js +24 -0
  19. package/dist/cjs/sdk/pools/AbstractPoolService.js +6 -0
  20. package/dist/cjs/sdk/router/AbstractRouterContract.js +4 -1
  21. package/dist/cjs/sdk/router/RouterV310Contract.js +20 -15
  22. package/dist/cjs/sdk/utils/AddressMap.js +53 -17
  23. package/dist/cjs/sdk/utils/AddressSet.js +9 -0
  24. package/dist/esm/permissionless/utils/price-update/get-price-update-tx.js +6 -20
  25. package/dist/esm/sdk/GearboxSDK.js +135 -20
  26. package/dist/esm/sdk/accounts/AbstractCreditAccountsService.js +204 -342
  27. package/dist/esm/sdk/accounts/CreditAccountsServiceV310.js +30 -35
  28. package/dist/esm/sdk/accounts/multicall-utils.js +69 -0
  29. package/dist/esm/sdk/base/BaseContract.js +26 -6
  30. package/dist/esm/sdk/base/ChainContractsRegister.js +39 -2
  31. package/dist/esm/sdk/base/Construct.js +15 -3
  32. package/dist/esm/sdk/base/TokensMeta.js +23 -0
  33. package/dist/esm/sdk/constants/address-provider.js +0 -21
  34. package/dist/esm/sdk/core/AbstractAddressProviderContract.js +15 -0
  35. package/dist/esm/sdk/market/MarketRegister.js +74 -3
  36. package/dist/esm/sdk/market/credit/CreditFacadeV310Contract.js +6 -0
  37. package/dist/esm/sdk/market/oracle/PriceOracleBaseContract.js +31 -50
  38. package/dist/esm/sdk/market/pricefeeds/PriceFeedRef.js +16 -0
  39. package/dist/esm/sdk/market/pricefeeds/PriceFeedsRegister.js +55 -12
  40. package/dist/esm/sdk/options.js +30 -24
  41. package/dist/esm/sdk/plugins/BasePlugin.js +24 -0
  42. package/dist/esm/sdk/pools/AbstractPoolService.js +6 -0
  43. package/dist/esm/sdk/router/AbstractRouterContract.js +4 -1
  44. package/dist/esm/sdk/router/RouterV310Contract.js +20 -15
  45. package/dist/esm/sdk/utils/AddressMap.js +53 -17
  46. package/dist/esm/sdk/utils/AddressSet.js +9 -0
  47. package/dist/types/permissionless/bindings/price-feed-store.d.ts +1 -2
  48. package/dist/types/permissionless/bindings/types.d.ts +0 -4
  49. package/dist/types/permissionless/utils/price-update/get-price-update-tx.d.ts +1 -3
  50. package/dist/types/sdk/GearboxSDK.d.ts +236 -34
  51. package/dist/types/sdk/accounts/AbstractCreditAccountsService.d.ts +92 -147
  52. package/dist/types/sdk/accounts/CreditAccountsServiceV310.d.ts +14 -5
  53. package/dist/types/sdk/accounts/multicall-utils.d.ts +39 -0
  54. package/dist/types/sdk/accounts/types.d.ts +237 -40
  55. package/dist/types/sdk/base/BaseContract.d.ts +67 -6
  56. package/dist/types/sdk/base/ChainContractsRegister.d.ts +51 -2
  57. package/dist/types/sdk/base/Construct.d.ts +31 -0
  58. package/dist/types/sdk/base/PlaceholderContract.d.ts +3 -0
  59. package/dist/types/sdk/base/SDKConstruct.d.ts +10 -0
  60. package/dist/types/sdk/base/TokensMeta.d.ts +59 -2
  61. package/dist/types/sdk/base/types.d.ts +185 -25
  62. package/dist/types/sdk/chain/chains.d.ts +78 -18
  63. package/dist/types/sdk/chain/detectNetwork.d.ts +7 -0
  64. package/dist/types/sdk/constants/address-provider.d.ts +4 -3
  65. package/dist/types/sdk/core/AbstractAddressProviderContract.d.ts +23 -0
  66. package/dist/types/sdk/core/types.d.ts +46 -0
  67. package/dist/types/sdk/market/MarketRegister.d.ts +81 -0
  68. package/dist/types/sdk/market/adapters/PlaceholderAdapterContracts.d.ts +3 -0
  69. package/dist/types/sdk/market/credit/CreditFacadeV310Contract.d.ts +1 -0
  70. package/dist/types/sdk/market/oracle/PriceOracleBaseContract.d.ts +40 -50
  71. package/dist/types/sdk/market/oracle/types.d.ts +78 -59
  72. package/dist/types/sdk/market/pricefeeds/AbstractLPPriceFeed.d.ts +3 -0
  73. package/dist/types/sdk/market/pricefeeds/AbstractPriceFeed.d.ts +3 -0
  74. package/dist/types/sdk/market/pricefeeds/PriceFeedRef.d.ts +22 -2
  75. package/dist/types/sdk/market/pricefeeds/PriceFeedsRegister.d.ts +80 -16
  76. package/dist/types/sdk/market/pricefeeds/getRawPriceUpdates.d.ts +2 -2
  77. package/dist/types/sdk/market/pricefeeds/types.d.ts +75 -11
  78. package/dist/types/sdk/options.d.ts +13 -4
  79. package/dist/types/sdk/plugins/BasePlugin.d.ts +39 -0
  80. package/dist/types/sdk/plugins/types.d.ts +73 -43
  81. package/dist/types/sdk/pools/AbstractPoolService.d.ts +12 -0
  82. package/dist/types/sdk/pools/types.d.ts +75 -6
  83. package/dist/types/sdk/router/AbstractRouterContract.d.ts +21 -2
  84. package/dist/types/sdk/router/RouterV310Contract.d.ts +27 -15
  85. package/dist/types/sdk/router/types.d.ts +47 -70
  86. package/dist/types/sdk/types/state.d.ts +32 -3
  87. package/dist/types/sdk/utils/AddressMap.d.ts +61 -17
  88. package/dist/types/sdk/utils/AddressSet.d.ts +15 -0
  89. package/package.json +4 -2
@@ -32,9 +32,11 @@ var import_iBaseRewardPool = require("../../abi/iBaseRewardPool.js");
32
32
  var import_base = require("../base/index.js");
33
33
  var import_chains = require("../chain/chains.js");
34
34
  var import_constants = require("../constants/index.js");
35
+ var import_market = require("../market/index.js");
35
36
  var import_router = require("../router/index.js");
36
37
  var import_utils = require("../utils/index.js");
37
38
  var import_viem2 = require("../utils/viem/index.js");
39
+ var import_multicall_utils = require("./multicall-utils.js");
38
40
  const COMPRESSORS = {
39
41
  [import_chains.chains.Mainnet.id]: "0x36F3d0Bb73CBC2E94fE24dF0f26a689409cF9023",
40
42
  [import_chains.chains.Monad.id]: "0x36F3d0Bb73CBC2E94fE24dF0f26a689409cF9023"
@@ -57,12 +59,8 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
57
59
  );
58
60
  }
59
61
  /**
60
- * Returns single credit account data, or undefined if it's not found
61
- * Performs all necessary price feed updates under the hood
62
- * @param account
63
- * @param blockNumber
64
- * @returns
65
- */
62
+ * {@inheritDoc ICreditAccountsService.getCreditAccountData}
63
+ **/
66
64
  async getCreditAccountData(account, blockNumber) {
67
65
  let raw;
68
66
  try {
@@ -81,10 +79,7 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
81
79
  if (raw.success) {
82
80
  return raw;
83
81
  }
84
- const { txs: priceUpdateTxs } = await this.getUpdateForAccount({
85
- creditManager: raw.creditManager,
86
- creditAccount: raw
87
- });
82
+ const { txs: priceUpdateTxs } = await this.getUpdateForAccount(raw);
88
83
  const [cad] = await (0, import_viem2.simulateWithPriceUpdates)(this.client, {
89
84
  priceUpdates: priceUpdateTxs,
90
85
  contracts: [
@@ -101,13 +96,8 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
101
96
  return cad;
102
97
  }
103
98
  /**
104
- * Methods to get all credit accounts with some optional filtering
105
- * Performs all necessary price feed updates under the hood
106
- *
107
- * @param options
108
- * @param blockNumber
109
- * @returns returned credit accounts are sorted by health factor in ascending order
110
- */
99
+ * {@inheritDoc ICreditAccountsService.getCreditAccounts}
100
+ **/
111
101
  async getCreditAccounts(options, blockNumber) {
112
102
  const {
113
103
  creditManager,
@@ -160,11 +150,8 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
160
150
  return allCAs.sort((a, b) => Number(a.healthFactor - b.healthFactor));
161
151
  }
162
152
  /**
163
- * Method to get all claimable rewards for credit account (ex. stkUSDS SKY rewards)
164
- Assosiates rewards by adapter + stakedPhantomToken
165
- * @param {Address} creditAccount - address of credit account to get rewards for
166
- * @returns {Array<Rewards>} list of {@link Rewards} that can be claimed
167
- */
153
+ * {@inheritDoc ICreditAccountsService.getRewards}
154
+ **/
168
155
  async getRewards(creditAccount) {
169
156
  const rewards = await this.client.readContract({
170
157
  abi: import_rewardsCompressor.rewardsCompressorAbi,
@@ -204,11 +191,8 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
204
191
  return Object.values(r);
205
192
  }
206
193
  /**
207
- * Method to get all connected bots for credit account
208
- * @param {Array<AccountToCheck>} accountsToCheck - list of credit accounts
209
- and their credit managers to check connected bots on
210
- * @returns call result of getConnectedBots for each credit account
211
- */
194
+ * {@inheritDoc ICreditAccountsService.getConnectedBots}
195
+ **/
212
196
  async getConnectedBots(accountsToCheck, legacyMigrationBot, additionalBots) {
213
197
  const allResp = await this.client.multicall({
214
198
  contracts: [
@@ -312,10 +296,8 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
312
296
  return void 0;
313
297
  }
314
298
  /**
315
- * Generates transaction to liquidate credit account
316
- * @param props - {@link FullyLiquidateProps}
317
- * @returns
318
- */
299
+ * {@inheritDoc ICreditAccountsService.fullyLiquidate}
300
+ **/
319
301
  async fullyLiquidate(props) {
320
302
  const {
321
303
  account,
@@ -334,12 +316,12 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
334
316
  keepAssets,
335
317
  debtOnly
336
318
  });
337
- const priceUpdates = await this.getPriceUpdatesForFacade({
338
- creditManager: account.creditManager,
339
- creditAccount: account,
340
- ignoreReservePrices
341
- });
342
- const calls = [...priceUpdates, ...routerCloseResult.calls];
319
+ const calls = await this.prependPriceUpdates(
320
+ account.creditManager,
321
+ routerCloseResult.calls,
322
+ account,
323
+ { ignoreReservePrices }
324
+ );
343
325
  let lossPolicyData;
344
326
  if (applyLossPolicy) {
345
327
  const market = this.sdk.marketRegister.findByCreditManager(
@@ -365,21 +347,8 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
365
347
  };
366
348
  }
367
349
  /**
368
- * Closes credit account or closes credit account and keeps it open with zero debt.
369
- - Ca is closed in the following order: price update -> close path to swap all tokens into underlying ->
370
- -> disable quotas of exiting tokens -> decrease debt -> disable exiting tokens tokens -> withdraw underlying tokenz
371
- * @param {CloseOptions} operation - {@link CloseOptions}: close or zeroDebt
372
- * @param {RouterCASlice} creditAccount - minimal credit account data {@link RouterCASlice} on which operation is performed
373
- * @param {Array<Address>} assetsToWithdraw - tokens to withdraw from credit account.
374
- For credit account closing this is the underlying token, because during the closure,
375
- all tokens on account are swapped into the underlying,
376
- and only the underlying token will remain on the credit account
377
- * @param {Address} to - Wallet address to withdraw underlying to
378
- * @param {number} slippage - Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
379
- * @default 50n
380
- * @param {RouterCloseResult | undefined} closePath - result of findBestClosePath method from router; if omited, calls marketRegister.findCreditManager {@link RouterCloseResult}
381
- * @returns All necessary data to execute the transaction (call, credit facade)
382
- */
350
+ * {@inheritDoc ICreditAccountsService.closeCreditAccount}
351
+ **/
383
352
  async closeCreditAccount({
384
353
  operation,
385
354
  assetsToWithdraw,
@@ -394,12 +363,7 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
394
363
  creditManager: cm.creditManager,
395
364
  slippage
396
365
  });
397
- const priceUpdates = await this.getPriceUpdatesForFacade({
398
- creditManager: ca.creditManager,
399
- creditAccount: ca
400
- });
401
- const calls = [
402
- ...operation === "close" ? [] : priceUpdates,
366
+ const operationCalls = [
403
367
  ...routerCloseResult.calls,
404
368
  ...this.prepareDisableQuotas(ca),
405
369
  ...this.prepareDecreaseDebt(ca),
@@ -407,17 +371,13 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
407
371
  (t) => this.prepareWithdrawToken(ca.creditFacade, t, import_constants.MAX_UINT256, to)
408
372
  )
409
373
  ];
374
+ const calls = operation === "close" ? operationCalls : await this.prependPriceUpdates(ca.creditManager, operationCalls, ca);
410
375
  const tx = operation === "close" ? cm.creditFacade.closeCreditAccount(ca.creditAccount, calls) : cm.creditFacade.multicall(ca.creditAccount, calls);
411
376
  return { tx, calls, routerCloseResult, creditFacade: cm.creditFacade };
412
377
  }
413
378
  /**
414
- * Updates quota of credit account.
415
- - CA quota updated in the following order: price update -> update quotas
416
- * @param {RouterCASlice} creditAccount - minimal credit account data {@link RouterCASlice} on which operation is performed
417
- * @param {Array<Asset>} averageQuota - average quota for desired tokens {@link Asset}
418
- * @param {Array<Asset>} minQuota - minimum quota for desired tokens {@link Asset}
419
- * @returns All necessary data to execute the transaction (call, credit facade)
420
- */
379
+ * {@inheritDoc ICreditAccountsService.updateQuotas}
380
+ **/
421
381
  async updateQuotas({
422
382
  minQuota,
423
383
  averageQuota,
@@ -426,31 +386,21 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
426
386
  const cm = this.sdk.marketRegister.findCreditManager(
427
387
  creditAccount.creditManager
428
388
  );
429
- const priceUpdates = await this.getPriceUpdatesForFacade({
430
- creditManager: creditAccount.creditManager,
389
+ const operationCalls = this.prepareUpdateQuotas(
390
+ creditAccount.creditFacade,
391
+ { minQuota, averageQuota }
392
+ );
393
+ const calls = await this.prependPriceUpdates(
394
+ creditAccount.creditManager,
395
+ operationCalls,
431
396
  creditAccount
432
- });
433
- const calls = [
434
- ...priceUpdates,
435
- ...this.prepareUpdateQuotas(creditAccount.creditFacade, {
436
- minQuota,
437
- averageQuota
438
- })
439
- ];
397
+ );
440
398
  const tx = cm.creditFacade.multicall(creditAccount.creditAccount, calls);
441
399
  return { tx, calls, creditFacade: cm.creditFacade };
442
400
  }
443
401
  /**
444
- * Adds a single collateral to credit account and updates quotas
445
- - Collateral is added in the following order: price update -> add collateral (with permit) -> update quotas
446
- * @param {RouterCASlice} creditAccount - minimal credit account data {@link RouterCASlice} on which operation is performed
447
- * @param {Array<Asset>} averageQuota - average quota for desired token {@link Asset}
448
- * @param {Array<Asset>} minQuota - minimum quota for desired token {@link Asset}
449
- * @param {Asset} asset - asset to add as collateral {@link Asset}
450
- * @param {PermitResult | undefined} permits - permits of collateral asset if it is permittable {@link PermitResult}
451
- * @param {bigint} ethAmount - native token amount to attach to tx
452
- * @returns All necessary data to execute the transaction (call, credit facade)
453
- */
402
+ * {@inheritDoc ICreditAccountsService.addCollateral}
403
+ **/
454
404
  async addCollateral({
455
405
  creditAccount,
456
406
  asset,
@@ -462,13 +412,7 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
462
412
  const cm = this.sdk.marketRegister.findCreditManager(
463
413
  creditAccount.creditManager
464
414
  );
465
- const priceUpdatesCalls = await this.getPriceUpdatesForFacade({
466
- creditManager: creditAccount.creditManager,
467
- creditAccount,
468
- desiredQuotas: averageQuota
469
- });
470
- const calls = [
471
- ...priceUpdatesCalls,
415
+ const operationCalls = [
472
416
  ...this.prepareAddCollateral(
473
417
  creditAccount.creditFacade,
474
418
  [asset],
@@ -479,20 +423,18 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
479
423
  averageQuota
480
424
  })
481
425
  ];
426
+ const calls = await this.prependPriceUpdates(
427
+ creditAccount.creditManager,
428
+ operationCalls,
429
+ creditAccount
430
+ );
482
431
  const tx = cm.creditFacade.multicall(creditAccount.creditAccount, calls);
483
432
  tx.value = ethAmount.toString(10);
484
433
  return { tx, calls, creditFacade: cm.creditFacade };
485
434
  }
486
435
  /**
487
- * Increases or decreases debt of credit account; debt decrease uses token ON CREDIT ACCOUNT
488
- - Debt is changed in the following order: price update -> (enables underlying if it was disabled) -> change debt
489
- * @param {RouterCASlice} creditAccount - minimal credit account data {@link RouterCASlice} on which operation is performed
490
- * @param {bigint} amount - amount to change debt by;
491
- 0 - prohibited value;
492
- negative value for debt decrease;
493
- positive value for debt increase.
494
- * @returns All necessary data to execute the transaction (call, credit facade)
495
- */
436
+ * {@inheritDoc ICreditAccountsService.changeDebt}
437
+ **/
496
438
  async changeDebt({
497
439
  creditAccount,
498
440
  amount,
@@ -506,10 +448,6 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
506
448
  const cm = this.sdk.marketRegister.findCreditManager(
507
449
  creditAccount.creditManager
508
450
  );
509
- const priceUpdatesCalls = await this.getPriceUpdatesForFacade({
510
- creditManager: creditAccount.creditManager,
511
- creditAccount
512
- });
513
451
  const addCollateralCalls = addCollateral && isDecrease ? this.prepareAddCollateral(
514
452
  creditAccount.creditFacade,
515
453
  [
@@ -520,23 +458,21 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
520
458
  ],
521
459
  {}
522
460
  ) : [];
523
- const calls = [
524
- ...priceUpdatesCalls,
461
+ const operationCalls = [
525
462
  ...addCollateralCalls,
526
463
  this.#prepareChangeDebt(creditAccount.creditFacade, change, isDecrease)
527
464
  ];
465
+ const calls = await this.prependPriceUpdates(
466
+ creditAccount.creditManager,
467
+ operationCalls,
468
+ creditAccount
469
+ );
528
470
  const tx = cm.creditFacade.multicall(creditAccount.creditAccount, calls);
529
471
  return { tx, calls, creditFacade: cm.creditFacade };
530
472
  }
531
473
  /**
532
- * Executes swap specified by given calls, update quotas of affected tokens
533
- - Swap is executed in the following order: price update -> execute swap path -> update quotas
534
- * @param {RouterCASlice} creditAccount - minimal credit account data {@link RouterCASlice} on which operation is performed
535
- * @param {Array<Asset>} averageQuota - average quota for desired token {@link Asset}
536
- * @param {Array<Asset>} minQuota - minimum quota for desired token {@link Asset}
537
- * @param {Array<MultiCall>} calls - array of MultiCall from router methods getSingleSwap or getAllSwaps {@link MultiCall}
538
- * @returns All necessary data to execute the transaction (call, credit facade)
539
- */
474
+ * {@inheritDoc ICreditAccountsService.executeSwap}
475
+ **/
540
476
  async executeSwap({
541
477
  creditAccount,
542
478
  calls: swapCalls,
@@ -547,27 +483,24 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
547
483
  const cm = this.sdk.marketRegister.findCreditManager(
548
484
  creditAccount.creditManager
549
485
  );
550
- const priceUpdatesCalls = await this.getPriceUpdatesForFacade({
551
- creditManager: creditAccount.creditManager,
552
- creditAccount,
553
- desiredQuotas: averageQuota
554
- });
555
- const calls = [
556
- ...priceUpdatesCalls,
486
+ const operationCalls = [
557
487
  ...swapCalls,
558
488
  ...this.prepareUpdateQuotas(creditAccount.creditFacade, {
559
489
  minQuota,
560
490
  averageQuota
561
491
  })
562
492
  ];
493
+ const calls = await this.prependPriceUpdates(
494
+ creditAccount.creditManager,
495
+ operationCalls,
496
+ creditAccount
497
+ );
563
498
  const tx = cm.creditFacade.multicall(creditAccount.creditAccount, calls);
564
499
  return { tx, calls, creditFacade: cm.creditFacade };
565
500
  }
566
501
  /**
567
- * Preview delayed withdrawal for given token
568
- * @param props - {@link PreviewDelayedWithdrawalProps}
569
- * @returns
570
- */
502
+ * {@inheritDoc ICreditAccountsService.previewDelayedWithdrawal}
503
+ **/
571
504
  async previewDelayedWithdrawal({
572
505
  creditAccount,
573
506
  amount,
@@ -591,10 +524,8 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
591
524
  return resp;
592
525
  }
593
526
  /**
594
- * Get claimable and pending withdrawals of an account
595
- * @param props - {@link GetPendingWithdrawalsProps}
596
- * @returns
597
- */
527
+ * {@inheritDoc ICreditAccountsService.getPendingWithdrawals}
528
+ **/
598
529
  async getPendingWithdrawals({
599
530
  creditAccount
600
531
  }) {
@@ -620,11 +551,8 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
620
551
  return respResult;
621
552
  }
622
553
  /**
623
- * Start delayed withdrawal for given token
624
- - Withdrawal is executed in the following order: price update -> execute withdraw calls -> update quotas
625
- * @param props - {@link StartDelayedWithdrawalProps}
626
- * @returns
627
- */
554
+ * {@inheritDoc ICreditAccountsService.startDelayedWithdrawal}
555
+ **/
628
556
  async startDelayedWithdrawal({
629
557
  creditAccount,
630
558
  minQuota,
@@ -661,13 +589,7 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
661
589
  args: []
662
590
  })
663
591
  };
664
- const priceUpdatesCalls = await this.getPriceUpdatesForFacade({
665
- creditManager: creditAccount.creditManager,
666
- creditAccount,
667
- desiredQuotas: averageQuota
668
- });
669
- const calls = [
670
- ...priceUpdatesCalls,
592
+ const operationCalls = [
671
593
  storeExpectedBalances,
672
594
  ...preview.requestCalls,
673
595
  compareBalances,
@@ -676,15 +598,17 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
676
598
  averageQuota
677
599
  })
678
600
  ];
601
+ const calls = await this.prependPriceUpdates(
602
+ creditAccount.creditManager,
603
+ operationCalls,
604
+ creditAccount
605
+ );
679
606
  const tx = cm.creditFacade.multicall(creditAccount.creditAccount, calls);
680
607
  return { tx, calls, creditFacade: cm.creditFacade };
681
608
  }
682
609
  /**
683
- * Claim tokens with delayed withdrawal
684
- - Claim is executed in the following order: price update -> execute claim calls -> update quotas
685
- * @param props - {@link ClaimDelayedProps}
686
- * @returns
687
- */
610
+ * {@inheritDoc ICreditAccountsService.claimDelayed}
611
+ **/
688
612
  async claimDelayed({
689
613
  creditAccount,
690
614
  minQuota,
@@ -725,49 +649,27 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
725
649
  args: []
726
650
  })
727
651
  };
728
- const priceUpdatesCalls = zeroDebt ? [] : await this.getPriceUpdatesForFacade({
729
- creditManager: creditAccount.creditManager,
730
- creditAccount,
731
- desiredQuotas: averageQuota
732
- });
733
652
  const quotaCalls = zeroDebt ? [] : this.prepareUpdateQuotas(creditAccount.creditFacade, {
734
653
  minQuota,
735
654
  averageQuota
736
655
  });
737
- const calls = [
738
- ...priceUpdatesCalls,
656
+ const operationCalls = [
739
657
  storeExpectedBalances,
740
658
  ...claimableNow.claimCalls,
741
659
  compareBalances,
742
660
  ...quotaCalls
743
661
  ];
662
+ const calls = zeroDebt ? operationCalls : await this.prependPriceUpdates(
663
+ creditAccount.creditManager,
664
+ operationCalls,
665
+ creditAccount
666
+ );
744
667
  const tx = cm.creditFacade.multicall(creditAccount.creditAccount, calls);
745
668
  return { tx, calls, creditFacade: cm.creditFacade };
746
669
  }
747
670
  /**
748
- * Executes swap specified by given calls, update quotas of affected tokens
749
- - Open credit account is executed in the following order: price update -> increase debt -> add collateral ->
750
- -> update quotas -> (optionally: execute swap path for trading/strategy) ->
751
- -> (optionally: withdraw debt for lending)
752
- - Basic open credit account: price update -> increase debt -> add collateral -> update quotas
753
- - Lending: price update -> increase debt -> add collateral -> update quotas -> withdraw debt
754
- - Strategy/trading: price update -> increase debt -> add collateral -> update quotas -> execute swap path
755
- - In strategy is possible situation when collateral is added, but not swapped; the only swapped value in this case will be debt
756
- * @param {bigint} ethAmount - native token amount to attach to tx
757
- * @param {Address} creditManager - address of credit manager to open credit account on
758
- * @param {Array<Asset>} collateral - array of collateral which can be just directly added or swapped using the path {@link Asset}
759
- * @param {Record<Address, PermitResult>} permits - permits of collateral tokens (in any permittable token is present) {@link PermitResult}
760
- * @param {bigint} debt - debt to open credit account with
761
- * @param {boolean} withdrawDebt - flag to withdraw debt to wallet after opening credit account;
762
- used for borrowing functionality
763
- * @param {bigint} referralCode - referral code to open credit account with
764
- * @param {Address} to - wallet address to transfer credit account to\
765
- * @param {Array<MultiCall>} calls - array of MultiCall from router methods findOpenStrategyPath {@link MultiCall}.
766
- Used for trading and strategy functionality
767
- * @param {Array<Asset>} averageQuota - average quota for tokens after open {@link Asset}
768
- * @param {Array<Asset>} minQuota - minimum quota for tokens after open {@link Asset}
769
- * @returns All necessary data to execute the transaction (call, credit facade)
770
- */
671
+ * {@inheritDoc ICreditAccountsService.openCA}
672
+ **/
771
673
  async openCA({
772
674
  ethAmount,
773
675
  creditManager,
@@ -783,12 +685,7 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
783
685
  }) {
784
686
  const cmSuite = this.sdk.marketRegister.findCreditManager(creditManager);
785
687
  const cm = cmSuite.creditManager;
786
- const priceUpdatesCalls = await this.getPriceUpdatesForFacade({
787
- creditManager: cm.address,
788
- desiredQuotas: averageQuota
789
- });
790
- const calls = [
791
- ...priceUpdatesCalls,
688
+ const operationCalls = [
792
689
  this.#prepareIncreaseDebt(cm.creditFacade, debt),
793
690
  ...this.prepareAddCollateral(cm.creditFacade, collateral, permits),
794
691
  ...openPathCalls,
@@ -798,15 +695,14 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
798
695
  averageQuota
799
696
  })
800
697
  ];
698
+ const calls = await this.prependPriceUpdates(cm.address, operationCalls);
801
699
  const tx = cmSuite.creditFacade.openCreditAccount(to, calls, referralCode);
802
700
  tx.value = ethAmount.toString(10);
803
701
  return { calls, tx, creditFacade: cmSuite.creditFacade };
804
702
  }
805
703
  /**
806
- * Returns borrow rate with 4 digits precision (10000 = 100%)
807
- * @param ca
808
- * @returns
809
- */
704
+ * {@inheritDoc ICreditAccountsService.getBorrowRate}
705
+ **/
810
706
  getBorrowRate(ca) {
811
707
  const { creditManager } = this.sdk.marketRegister.findCreditManager(
812
708
  ca.creditManager
@@ -832,9 +728,8 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
832
728
  return r + qr;
833
729
  }
834
730
  /**
835
- * Returns optimal HF for partial liquidation with 4 digits precision (10000 = 100%)
836
- * @param ca
837
- */
731
+ * {@inheritDoc ICreditAccountsService.getOptimalHFForPartialLiquidation}
732
+ **/
838
733
  getOptimalHFForPartialLiquidation(ca) {
839
734
  const borrowRate = this.getBorrowRate(ca);
840
735
  return import_constants.PERCENTAGE_FACTOR + (borrowRate < 100n ? borrowRate : 100n);
@@ -883,112 +778,146 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
883
778
  return resp;
884
779
  }
885
780
  /**
886
- * Returns raw txs that are needed to update all price feeds so that all credit accounts (possibly from different markets) compute
781
+ * {@inheritDoc ICreditAccountsService.getOnDemandPriceUpdates}
782
+ **/
783
+ async getOnDemandPriceUpdates(account, ignoreReservePrices) {
784
+ const { creditManager, creditAccount } = account;
785
+ const cm = this.sdk.marketRegister.findCreditManager(creditManager);
786
+ const update = await this.getUpdateForAccount(account, ignoreReservePrices);
787
+ this.logger?.debug(
788
+ { account: creditAccount, manager: cm.name },
789
+ `getting on demand price updates from ${update.txs.length} txs`
790
+ );
791
+ return (0, import_market.getRawPriceUpdates)(update);
792
+ }
793
+ /**
794
+ * Analyzes a multicall array and prepends necessary on-demand price feed updates.
887
795
  *
888
- * This can be used by batch liquidator
889
- * @param accounts
890
- * @returns
796
+ * Deduplicates existing `onDemandPriceUpdates` calls
797
+ *
798
+ * @param creditManager - Address of the credit manager
799
+ * @param calls - The multicall array to prepend price updates to
800
+ * @param ca - Credit account slice, undefined when opening a new account
801
+ * @param options - Optional settings for price update generation
802
+ * @returns A new array with a single consolidated price update call prepended,
803
+ * followed by the non-price-update calls in their original order
891
804
  */
892
- async getUpdateForAccounts(accounts) {
893
- const tokensByPool = /* @__PURE__ */ new Map();
894
- const oracleByPool = /* @__PURE__ */ new Map();
895
- for (const acc of accounts) {
896
- const market = this.sdk.marketRegister.findByCreditManager(
897
- acc.creditManager
898
- );
899
- const pool = market.pool.pool.address;
900
- oracleByPool.set(pool, market.priceOracle);
901
- for (const t of acc.tokens) {
902
- if (t.balance > 10n) {
903
- const tokens = tokensByPool.get(pool) ?? /* @__PURE__ */ new Set();
805
+ async prependPriceUpdates(creditManager, calls, ca, options) {
806
+ const market = this.sdk.marketRegister.findByCreditManager(creditManager);
807
+ const cm = this.sdk.marketRegister.findCreditManager(creditManager).creditManager;
808
+ const { priceUpdates: existingUpdates, remainingCalls } = (0, import_multicall_utils.extractPriceUpdates)(calls);
809
+ const tokens = new import_utils.AddressSet([
810
+ cm.underlying,
811
+ // underlying - always included
812
+ ...(0, import_multicall_utils.extractQuotaTokens)(calls)
813
+ // tokens from `updateQuota` calls
814
+ ]);
815
+ if (ca) {
816
+ for (const t of ca.tokens) {
817
+ const isEnabled = (t.mask & ca.enabledTokensMask) !== 0n;
818
+ if (t.balance > 10n && isEnabled) {
904
819
  tokens.add(t.token);
905
- tokensByPool.set(pool, tokens);
906
820
  }
907
821
  }
908
822
  }
909
- const priceFeeds = [];
910
- for (const [pool, oracle] of oracleByPool.entries()) {
911
- const tokens = Array.from(tokensByPool.get(pool) ?? []);
912
- priceFeeds.push(...oracle.priceFeedsForTokens(tokens));
823
+ const ignoreReservePrices = options?.ignoreReservePrices;
824
+ const priceFeeds = market.priceOracle.priceFeedsForTokens(Array.from(tokens), {
825
+ main: true,
826
+ reserve: !ignoreReservePrices
827
+ });
828
+ const tStr = tokens.map((t) => this.labelAddress(t)).join(", ");
829
+ const remark = ignoreReservePrices ? " main" : "";
830
+ this.logger?.debug(
831
+ { account: ca?.creditAccount, manager: cm.name },
832
+ `prependPriceUpdates for ${tStr} from ${priceFeeds.length}${remark} price feeds`
833
+ );
834
+ const generatedUpdates = await this.sdk.priceFeeds.generatePriceFeedsUpdates(priceFeeds);
835
+ const merged = (0, import_multicall_utils.mergePriceUpdates)(existingUpdates, generatedUpdates);
836
+ if (merged.length === 0) {
837
+ return remainingCalls;
913
838
  }
914
- return this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(priceFeeds);
839
+ return [
840
+ {
841
+ target: cm.creditFacade,
842
+ callData: (0, import_viem.encodeFunctionData)({
843
+ abi: import_generated.iCreditFacadeMulticallV310Abi,
844
+ functionName: "onDemandPriceUpdates",
845
+ args: [merged]
846
+ })
847
+ },
848
+ ...remainingCalls
849
+ ];
915
850
  }
916
- async getUpdateForAccount(options) {
917
- const { creditManager, creditAccount, desiredQuotas, ignoreReservePrices } = options;
918
- const quotaRecord = desiredQuotas ? (0, import_router.assetsMap)(desiredQuotas) : desiredQuotas;
919
- const caBalancesRecord = creditAccount ? (0, import_router.assetsMap)(creditAccount.tokens) : creditAccount;
851
+ async getUpdateForAccount(account, ignoreReservePrices) {
852
+ const { creditManager, creditAccount, enabledTokensMask } = account;
920
853
  const market = this.sdk.marketRegister.findByCreditManager(creditManager);
921
854
  const cm = this.sdk.marketRegister.findCreditManager(creditManager).creditManager;
922
- const tokens = /* @__PURE__ */ new Set([(0, import_viem.getAddress)(cm.underlying)]);
923
- for (const t of cm.collateralTokens) {
924
- if (creditAccount && caBalancesRecord && quotaRecord) {
925
- const balanceAsset = caBalancesRecord.get(t);
926
- const balance = balanceAsset?.balance || 0n;
927
- const mask = balanceAsset?.mask || 0n;
928
- const isEnabled = (mask & creditAccount.enabledTokensMask) !== 0n;
929
- const quotaAsset = quotaRecord.get(t);
930
- const quotaBalance = quotaAsset?.balance || 0n;
931
- if (balance > 10n && isEnabled || quotaBalance > 0) {
932
- tokens.add((0, import_viem.getAddress)(t));
933
- }
934
- } else if (creditAccount && caBalancesRecord) {
935
- const balanceAsset = caBalancesRecord.get(t);
936
- const balance = balanceAsset?.balance || 0n;
937
- const mask = balanceAsset?.mask || 0n;
938
- const isEnabled = (mask & creditAccount.enabledTokensMask) !== 0n;
939
- if (balance > 10n && isEnabled) {
940
- tokens.add((0, import_viem.getAddress)(t));
941
- }
942
- } else if (quotaRecord) {
943
- const quotaAsset = quotaRecord.get(t);
944
- const quotaBalance = quotaAsset?.balance || 0n;
945
- if (quotaBalance > 0) {
946
- tokens.add((0, import_viem.getAddress)(t));
947
- }
855
+ const tokens = new import_utils.AddressSet([cm.underlying]);
856
+ for (const t of account.tokens) {
857
+ const isEnabled = (t.mask & enabledTokensMask) !== 0n;
858
+ if (t.balance > 10n && isEnabled) {
859
+ tokens.add(t.token);
948
860
  }
949
861
  }
950
862
  const priceFeeds = market.priceOracle.priceFeedsForTokens(Array.from(tokens), {
951
863
  main: true,
952
864
  reserve: !ignoreReservePrices
953
865
  });
954
- const tStr = Array.from(tokens).map((t) => this.labelAddress(t)).join(", ");
866
+ const tStr = tokens.map((t) => this.labelAddress(t)).join(", ");
955
867
  const remark = ignoreReservePrices ? " main" : "";
956
868
  this.logger?.debug(
957
- { account: creditAccount?.creditAccount, manager: cm.name },
869
+ { account: creditAccount, manager: cm.name },
958
870
  `generating price feed updates for ${tStr} from ${priceFeeds.length}${remark} price feeds`
959
871
  );
960
872
  return this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(priceFeeds);
961
873
  }
962
874
  /**
963
- * Returns account price updates that can be used in credit facade multicall or liquidator calls
964
- * @param options
965
- * @returns
875
+ * Executes a multicall on a credit account, automatically prepending
876
+ * necessary on-demand price feed updates.
877
+ *
878
+ * @param creditAccount - Credit account to execute multicall on
879
+ * @param calls - Array of multicall operations (price updates will be inferred)
880
+ * @param options - Optional settings for price update generation
881
+ * @returns Raw transaction ready to be signed and sent
966
882
  */
967
- async getOnDemandPriceUpdates(options) {
968
- const { creditManager, creditAccount } = options;
969
- const market = this.sdk.marketRegister.findByCreditManager(creditManager);
970
- const cm = this.sdk.marketRegister.findCreditManager(creditManager);
971
- const update = await this.getUpdateForAccount(options);
972
- this.logger?.debug(
973
- { account: creditAccount?.creditAccount, manager: cm.name },
974
- `getting on demand price updates from ${update.txs.length} txs`
883
+ async multicall(creditAccount, calls, options) {
884
+ const cm = this.sdk.marketRegister.findCreditManager(
885
+ creditAccount.creditManager
886
+ );
887
+ const callsWithPrices = await this.prependPriceUpdates(
888
+ creditAccount.creditManager,
889
+ calls,
890
+ creditAccount,
891
+ options
975
892
  );
976
- return market.priceOracle.onDemandPriceUpdates(
977
- cm.creditFacade.address,
978
- update
893
+ return cm.creditFacade.multicall(
894
+ creditAccount.creditAccount,
895
+ callsWithPrices
979
896
  );
980
897
  }
981
898
  /**
982
- * Returns price updates in format that is accepted by various credit facade methods (multicall, close/liquidate, etc...).
983
- * - If there are desiredQuotas and creditAccount update quotaBalance > 0 || (balance > 10n && isEnabled). Is used when account has both: balances and quota buys.
984
- * - If there is creditAccount update balance > 10n && isEnabled. Is used in credit account actions when quota is not being bought.
985
- * - If there is desiredQuotas update quotaBalance > 0. Is used on credit account opening, when quota is bought for the first time.
986
- * @param acc
987
- * @returns
899
+ * Executes a bot multicall on a credit account, automatically prepending
900
+ * necessary on-demand price feed updates.
901
+ *
902
+ * @param creditAccount - Credit account to execute bot multicall on
903
+ * @param calls - Array of multicall operations (price updates will be inferred)
904
+ * @param options - Optional settings for price update generation
905
+ * @returns Raw transaction ready to be signed and sent
988
906
  */
989
- async getPriceUpdatesForFacade(options) {
990
- const updates = await this.getOnDemandPriceUpdates(options);
991
- return updates.multicall;
907
+ async botMulticall(creditAccount, calls, options) {
908
+ const cm = this.sdk.marketRegister.findCreditManager(
909
+ creditAccount.creditManager
910
+ );
911
+ const callsWithPrices = await this.prependPriceUpdates(
912
+ creditAccount.creditManager,
913
+ calls,
914
+ creditAccount,
915
+ options
916
+ );
917
+ return cm.creditFacade.botMulticall(
918
+ creditAccount.creditAccount,
919
+ callsWithPrices
920
+ );
992
921
  }
993
922
  prepareDisableQuotas(ca) {
994
923
  const calls = [];
@@ -1110,79 +1039,6 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
1110
1039
  )[0];
1111
1040
  }
1112
1041
  }
1113
- const iMellowClaimerAdapterAbi = [
1114
- {
1115
- type: "function",
1116
- name: "getMultiVaultSubvaultIndices",
1117
- inputs: [{ name: "multiVault", type: "address", internalType: "address" }],
1118
- outputs: [
1119
- {
1120
- name: "subvaultIndices",
1121
- type: "uint256[]",
1122
- internalType: "uint256[]"
1123
- },
1124
- {
1125
- name: "withdrawalIndices",
1126
- type: "uint256[][]",
1127
- internalType: "uint256[][]"
1128
- }
1129
- ],
1130
- stateMutability: "view"
1131
- },
1132
- {
1133
- type: "function",
1134
- name: "getUserSubvaultIndices",
1135
- inputs: [
1136
- { name: "multiVault", type: "address", internalType: "address" },
1137
- { name: "user", type: "address", internalType: "address" }
1138
- ],
1139
- outputs: [
1140
- {
1141
- name: "subvaultIndices",
1142
- type: "uint256[]",
1143
- internalType: "uint256[]"
1144
- },
1145
- {
1146
- name: "withdrawalIndices",
1147
- type: "uint256[][]",
1148
- internalType: "uint256[][]"
1149
- }
1150
- ],
1151
- stateMutability: "view"
1152
- },
1153
- {
1154
- type: "function",
1155
- name: "multiAccept",
1156
- inputs: [
1157
- { name: "multiVault", type: "address", internalType: "address" },
1158
- {
1159
- name: "subvaultIndices",
1160
- type: "uint256[]",
1161
- internalType: "uint256[]"
1162
- },
1163
- { name: "indices", type: "uint256[][]", internalType: "uint256[][]" }
1164
- ],
1165
- outputs: [{ name: "", type: "bool", internalType: "bool" }],
1166
- stateMutability: "nonpayable"
1167
- },
1168
- {
1169
- type: "function",
1170
- name: "multiAcceptAndClaim",
1171
- inputs: [
1172
- { name: "multiVault", type: "address", internalType: "address" },
1173
- {
1174
- name: "subvaultIndices",
1175
- type: "uint256[]",
1176
- internalType: "uint256[]"
1177
- },
1178
- { name: "indices", type: "uint256[][]", internalType: "uint256[][]" },
1179
- { name: "", type: "address", internalType: "address" },
1180
- { name: "maxAssets", type: "uint256", internalType: "uint256" }
1181
- ],
1182
- outputs: [{ name: "", type: "bool", internalType: "bool" }],
1183
- stateMutability: "nonpayable"
1184
- }
1185
- ];
1186
1042
  // Annotate the CommonJS export names for ESM import in node:
1187
1043
  0 && (module.exports = {
1188
1044
  AbstractCreditAccountService,