@gearbox-protocol/sdk 14.12.0-next.65 → 14.12.0-next.67

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 (249) hide show
  1. package/dist/cjs/common-utils/index.js +2 -2
  2. package/dist/cjs/common-utils/utils/apy/calculate-safe-borrow-rate.js +3 -3
  3. package/dist/cjs/common-utils/utils/assets-math.js +7 -7
  4. package/dist/cjs/common-utils/utils/creditAccount/calc-health-factor.js +2 -2
  5. package/dist/cjs/common-utils/utils/creditAccount/debt.js +2 -2
  6. package/dist/cjs/common-utils/utils/creditAccount/quota-utils.js +5 -5
  7. package/dist/cjs/common-utils/utils/index.js +2 -2
  8. package/dist/cjs/common-utils/utils/strategies/leverage/calculate-max-leverage-factor.js +2 -2
  9. package/dist/cjs/common-utils/utils/strategies/leverage/calculate-max-strategy-debt.js +5 -5
  10. package/dist/cjs/common-utils/utils/strategies/strategy-info/calculate-total-points.js +2 -2
  11. package/dist/cjs/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.js +2 -2
  12. package/dist/cjs/common-utils/utils/validation/validate-open-account-pool-status.js +4 -4
  13. package/dist/cjs/dev/index.js +2 -1
  14. package/dist/cjs/dev/kycUtils.js +1 -1
  15. package/dist/cjs/dev/midasUtils.js +104 -0
  16. package/dist/cjs/model/history.js +28 -0
  17. package/dist/cjs/model/history.schema.js +84 -0
  18. package/dist/cjs/model/index.js +64 -0
  19. package/dist/cjs/model/liquidations.js +23 -0
  20. package/dist/cjs/model/liquidations.schema.js +91 -0
  21. package/dist/cjs/model/opportunities.js +55 -0
  22. package/dist/cjs/model/opportunities.schema.js +220 -0
  23. package/dist/cjs/model/package.json +1 -0
  24. package/dist/cjs/model/positions.js +1 -0
  25. package/dist/cjs/model/primitives.js +1 -0
  26. package/dist/cjs/model/primitives.schema.js +85 -0
  27. package/dist/cjs/new-sdk/AbstractNamespace.js +158 -0
  28. package/dist/cjs/new-sdk/GearboxSDK.js +122 -0
  29. package/dist/cjs/new-sdk/index.js +11 -0
  30. package/dist/cjs/new-sdk/opportunities/OpportunitiesNamespace.js +122 -0
  31. package/dist/cjs/new-sdk/opportunities/index.js +4 -0
  32. package/dist/cjs/new-sdk/opportunities/types.js +1 -0
  33. package/dist/cjs/new-sdk/package.json +1 -0
  34. package/dist/cjs/new-sdk/types.js +22 -0
  35. package/dist/cjs/new-sdk/utils/history.js +1 -0
  36. package/dist/cjs/new-sdk/utils/index.js +2 -0
  37. package/dist/cjs/offchain/GearboxAPI.js +33 -0
  38. package/dist/cjs/offchain/index.js +8 -0
  39. package/dist/cjs/offchain/opportunities/OffchainOpportunities.js +97 -0
  40. package/dist/cjs/offchain/opportunities/index.js +4 -0
  41. package/dist/cjs/offchain/package.json +1 -0
  42. package/dist/cjs/offchain/types.js +1 -0
  43. package/dist/cjs/preview/preview/buildDelayedPreview.js +5 -5
  44. package/dist/cjs/rewards/rewards/api.js +2 -2
  45. package/dist/cjs/rewards/rewards/extra-apy.js +2 -2
  46. package/dist/cjs/sdk/MultichainSDK.js +18 -2
  47. package/dist/cjs/sdk/OnchainSDK.js +8 -1
  48. package/dist/cjs/sdk/accounts/index.js +2 -0
  49. package/dist/cjs/sdk/accounts/liquidations/LiquidationsService.js +150 -106
  50. package/dist/cjs/sdk/accounts/liquidations/MultichainLiquidationsService.js +32 -38
  51. package/dist/cjs/sdk/accounts/liquidations/constants.js +13 -0
  52. package/dist/cjs/sdk/accounts/liquidations/index.js +2 -0
  53. package/dist/cjs/sdk/base/MultichainConstruct.js +80 -0
  54. package/dist/cjs/sdk/base/TokensMeta.js +51 -0
  55. package/dist/cjs/sdk/base/index.js +2 -0
  56. package/dist/cjs/sdk/chain/chains.js +76 -0
  57. package/dist/cjs/sdk/chain/index.js +4 -0
  58. package/dist/cjs/sdk/core/errors.js +13 -0
  59. package/dist/cjs/sdk/core/index.js +2 -1
  60. package/dist/cjs/sdk/index.js +25 -1
  61. package/dist/cjs/sdk/market/MarketConfiguratorContract.js +14 -0
  62. package/dist/cjs/sdk/market/MarketSuite.js +163 -0
  63. package/dist/cjs/sdk/market/credit/CreditManagerV310Contract.js +26 -0
  64. package/dist/cjs/sdk/market/credit/CreditSuite.js +102 -0
  65. package/dist/cjs/sdk/market/math.js +104 -0
  66. package/dist/cjs/sdk/market/oracle/PriceOracleBaseContract.js +52 -0
  67. package/dist/cjs/sdk/market/pool/LinearInterestRateModelContract.js +30 -0
  68. package/dist/cjs/sdk/market/pool/PoolQuotaKeeperV310Contract.js +26 -0
  69. package/dist/cjs/sdk/market/pool/PoolSuite.js +28 -0
  70. package/dist/cjs/sdk/market/pool/PoolV310Contract.js +27 -0
  71. package/dist/cjs/sdk/market/pool/math.js +44 -0
  72. package/dist/cjs/sdk/market/pricefeeds/AbstractPriceFeed.js +17 -0
  73. package/dist/cjs/sdk/opportunities/MultichainOpportunitiesService.js +60 -0
  74. package/dist/cjs/sdk/opportunities/OpportunitiesService.js +103 -0
  75. package/dist/cjs/sdk/opportunities/index.js +12 -0
  76. package/dist/cjs/sdk/types/multichain.js +1 -0
  77. package/dist/cjs/{common-utils → sdk}/utils/bigint-math.js +11 -11
  78. package/dist/cjs/sdk/utils/index.js +3 -0
  79. package/dist/cjs/sdk/utils/zod.js +12 -0
  80. package/dist/esm/common-utils/index.js +1 -1
  81. package/dist/esm/common-utils/utils/apy/calculate-safe-borrow-rate.js +1 -1
  82. package/dist/esm/common-utils/utils/assets-math.js +1 -1
  83. package/dist/esm/common-utils/utils/creditAccount/calc-health-factor.js +1 -1
  84. package/dist/esm/common-utils/utils/creditAccount/debt.js +1 -1
  85. package/dist/esm/common-utils/utils/creditAccount/quota-utils.js +1 -1
  86. package/dist/esm/common-utils/utils/index.js +1 -1
  87. package/dist/esm/common-utils/utils/strategies/leverage/calculate-max-leverage-factor.js +1 -1
  88. package/dist/esm/common-utils/utils/strategies/leverage/calculate-max-strategy-debt.js +1 -1
  89. package/dist/esm/common-utils/utils/strategies/strategy-info/calculate-total-points.js +1 -1
  90. package/dist/esm/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.js +1 -1
  91. package/dist/esm/common-utils/utils/validation/validate-open-account-pool-status.js +1 -1
  92. package/dist/esm/dev/AccountOpener.js +1 -1
  93. package/dist/esm/dev/index.js +3 -3
  94. package/dist/esm/dev/kycUtils.js +1 -1
  95. package/dist/esm/dev/midasUtils.js +105 -2
  96. package/dist/esm/dev/withdrawalUtils.js +1 -1
  97. package/dist/esm/model/history.js +26 -0
  98. package/dist/esm/model/history.schema.js +76 -0
  99. package/dist/esm/model/index.js +9 -0
  100. package/dist/esm/model/liquidations.js +22 -0
  101. package/dist/esm/model/liquidations.schema.js +83 -0
  102. package/dist/esm/model/opportunities.js +51 -0
  103. package/dist/esm/model/opportunities.schema.js +198 -0
  104. package/dist/esm/model/package.json +1 -0
  105. package/dist/esm/model/positions.js +1 -0
  106. package/dist/esm/model/primitives.js +1 -0
  107. package/dist/esm/model/primitives.schema.js +75 -0
  108. package/dist/esm/new-sdk/AbstractNamespace.js +157 -0
  109. package/dist/esm/new-sdk/GearboxSDK.js +121 -0
  110. package/dist/esm/new-sdk/index.js +7 -0
  111. package/dist/esm/new-sdk/opportunities/OpportunitiesNamespace.js +121 -0
  112. package/dist/esm/new-sdk/opportunities/index.js +3 -0
  113. package/dist/esm/new-sdk/opportunities/types.js +1 -0
  114. package/dist/esm/new-sdk/package.json +1 -0
  115. package/dist/esm/new-sdk/types.js +21 -0
  116. package/dist/esm/new-sdk/utils/history.js +1 -0
  117. package/dist/esm/new-sdk/utils/index.js +2 -0
  118. package/dist/esm/offchain/GearboxAPI.js +32 -0
  119. package/dist/esm/offchain/index.js +5 -0
  120. package/dist/esm/offchain/opportunities/OffchainOpportunities.js +95 -0
  121. package/dist/esm/offchain/opportunities/index.js +2 -0
  122. package/dist/esm/offchain/package.json +1 -0
  123. package/dist/esm/offchain/types.js +1 -0
  124. package/dist/esm/preview/preview/buildDelayedPreview.js +1 -1
  125. package/dist/esm/preview/simulate/simulatePoolOperation.js +1 -1
  126. package/dist/esm/preview/trace/extractTransfers.js +1 -1
  127. package/dist/esm/rewards/rewards/api.js +1 -1
  128. package/dist/esm/rewards/rewards/extra-apy.js +1 -1
  129. package/dist/esm/sdk/MultichainSDK.js +18 -2
  130. package/dist/esm/sdk/OnchainSDK.js +8 -1
  131. package/dist/esm/sdk/accounts/CreditAccountsServiceV310.js +2 -2
  132. package/dist/esm/sdk/accounts/index.js +2 -2
  133. package/dist/esm/sdk/accounts/liquidations/LiquidationsService.js +153 -109
  134. package/dist/esm/sdk/accounts/liquidations/MultichainLiquidationsService.js +32 -38
  135. package/dist/esm/sdk/accounts/liquidations/constants.js +12 -1
  136. package/dist/esm/sdk/accounts/liquidations/index.js +2 -2
  137. package/dist/esm/sdk/accounts/withdrawal-compressor/RedemptionLoggerV310Contract.js +1 -1
  138. package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV310Contract.js +1 -1
  139. package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV311Contract.js +1 -1
  140. package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.js +1 -1
  141. package/dist/esm/sdk/base/MultichainConstruct.js +79 -0
  142. package/dist/esm/sdk/base/TokensMeta.js +53 -2
  143. package/dist/esm/sdk/base/index.js +2 -1
  144. package/dist/esm/sdk/chain/chains.js +74 -2
  145. package/dist/esm/sdk/chain/detectNetwork.js +1 -1
  146. package/dist/esm/sdk/chain/index.js +2 -2
  147. package/dist/esm/sdk/core/createAddressProvider.js +1 -1
  148. package/dist/esm/sdk/core/errors.js +13 -1
  149. package/dist/esm/sdk/core/index.js +2 -2
  150. package/dist/esm/sdk/index.js +11 -5
  151. package/dist/esm/sdk/market/MarketConfiguratorContract.js +14 -0
  152. package/dist/esm/sdk/market/MarketSuite.js +163 -0
  153. package/dist/esm/sdk/market/credit/CreditFacadeV310BaseContract.js +1 -1
  154. package/dist/esm/sdk/market/credit/CreditManagerV310Contract.js +26 -0
  155. package/dist/esm/sdk/market/credit/CreditSuite.js +102 -0
  156. package/dist/esm/sdk/market/math.js +98 -0
  157. package/dist/esm/sdk/market/oracle/PriceOracleBaseContract.js +52 -0
  158. package/dist/esm/sdk/market/pool/LinearInterestRateModelContract.js +30 -0
  159. package/dist/esm/sdk/market/pool/PoolQuotaKeeperV310Contract.js +26 -0
  160. package/dist/esm/sdk/market/pool/PoolSuite.js +28 -0
  161. package/dist/esm/sdk/market/pool/PoolV310Contract.js +28 -1
  162. package/dist/esm/sdk/market/pool/math.js +41 -0
  163. package/dist/esm/sdk/market/pricefeeds/AbstractPriceFeed.js +17 -0
  164. package/dist/esm/sdk/market/zapper/IETHZapperContract.js +1 -1
  165. package/dist/esm/sdk/market/zapper/ZapperContract.js +1 -1
  166. package/dist/esm/sdk/opportunities/MultichainOpportunitiesService.js +59 -0
  167. package/dist/esm/sdk/opportunities/OpportunitiesService.js +102 -0
  168. package/dist/esm/sdk/opportunities/index.js +4 -0
  169. package/dist/esm/sdk/pools/PoolService.js +1 -1
  170. package/dist/esm/sdk/types/multichain.js +1 -0
  171. package/dist/esm/{common-utils → sdk}/utils/bigint-math.js +11 -11
  172. package/dist/esm/sdk/utils/index.js +3 -2
  173. package/dist/esm/sdk/utils/viem/simulateWithPriceUpdates.js +1 -1
  174. package/dist/esm/sdk/utils/zod.js +13 -2
  175. package/dist/types/common-utils/index.d.ts +1 -1
  176. package/dist/types/common-utils/utils/index.d.ts +1 -1
  177. package/dist/types/dev/index.d.ts +2 -2
  178. package/dist/types/dev/midasUtils.d.ts +31 -2
  179. package/dist/types/model/history.d.ts +105 -0
  180. package/dist/types/model/history.schema.d.ts +66 -0
  181. package/dist/types/model/index.d.ts +9 -0
  182. package/dist/types/model/liquidations.d.ts +230 -0
  183. package/dist/types/model/liquidations.schema.d.ts +292 -0
  184. package/dist/types/model/opportunities.d.ts +543 -0
  185. package/dist/types/model/opportunities.schema.d.ts +1066 -0
  186. package/dist/types/model/positions.d.ts +11 -0
  187. package/dist/types/model/primitives.d.ts +193 -0
  188. package/dist/types/model/primitives.schema.d.ts +81 -0
  189. package/dist/types/new-sdk/AbstractNamespace.d.ts +119 -0
  190. package/dist/types/new-sdk/GearboxSDK.d.ts +78 -0
  191. package/dist/types/new-sdk/index.d.ts +9 -0
  192. package/dist/types/new-sdk/opportunities/OpportunitiesNamespace.d.ts +69 -0
  193. package/dist/types/new-sdk/opportunities/index.d.ts +3 -0
  194. package/dist/types/new-sdk/opportunities/types.d.ts +66 -0
  195. package/dist/types/new-sdk/types.d.ts +149 -0
  196. package/dist/types/new-sdk/utils/history.d.ts +44 -0
  197. package/dist/types/new-sdk/utils/index.d.ts +2 -0
  198. package/dist/types/offchain/GearboxAPI.d.ts +31 -0
  199. package/dist/types/offchain/index.d.ts +5 -0
  200. package/dist/types/offchain/opportunities/OffchainOpportunities.d.ts +69 -0
  201. package/dist/types/offchain/opportunities/index.d.ts +2 -0
  202. package/dist/types/offchain/types.d.ts +50 -0
  203. package/dist/types/sdk/MultichainSDK.d.ts +15 -2
  204. package/dist/types/sdk/OnchainSDK.d.ts +9 -3
  205. package/dist/types/sdk/accounts/index.d.ts +3 -3
  206. package/dist/types/sdk/accounts/liquidations/LiquidationsService.d.ts +24 -16
  207. package/dist/types/sdk/accounts/liquidations/MultichainLiquidationsService.d.ts +26 -20
  208. package/dist/types/sdk/accounts/liquidations/constants.d.ts +12 -1
  209. package/dist/types/sdk/accounts/liquidations/index.d.ts +3 -3
  210. package/dist/types/sdk/accounts/liquidations/types.d.ts +34 -309
  211. package/dist/types/sdk/base/MultichainConstruct.d.ts +57 -0
  212. package/dist/types/sdk/base/TokensMeta.d.ts +26 -0
  213. package/dist/types/sdk/base/index.d.ts +2 -1
  214. package/dist/types/sdk/chain/chains.d.ts +68 -1
  215. package/dist/types/sdk/chain/index.d.ts +2 -2
  216. package/dist/types/sdk/core/errors.d.ts +10 -1
  217. package/dist/types/sdk/core/index.d.ts +2 -2
  218. package/dist/types/sdk/index.d.ts +15 -8
  219. package/dist/types/sdk/market/MarketConfiguratorContract.d.ts +9 -0
  220. package/dist/types/sdk/market/MarketSuite.d.ts +109 -1
  221. package/dist/types/sdk/market/credit/CreditManagerV310Contract.d.ts +14 -0
  222. package/dist/types/sdk/market/credit/CreditSuite.d.ts +47 -0
  223. package/dist/types/sdk/market/credit/types.d.ts +22 -0
  224. package/dist/types/sdk/market/index.d.ts +2 -2
  225. package/dist/types/sdk/market/math.d.ts +74 -0
  226. package/dist/types/sdk/market/oracle/PriceOracleBaseContract.d.ts +23 -0
  227. package/dist/types/sdk/market/oracle/types.d.ts +46 -0
  228. package/dist/types/sdk/market/pool/LinearInterestRateModelContract.d.ts +12 -0
  229. package/dist/types/sdk/market/pool/PoolQuotaKeeperV310Contract.d.ts +22 -1
  230. package/dist/types/sdk/market/pool/PoolSuite.d.ts +23 -0
  231. package/dist/types/sdk/market/pool/PoolV310Contract.d.ts +18 -0
  232. package/dist/types/sdk/market/pool/math.d.ts +57 -0
  233. package/dist/types/sdk/market/pool/types.d.ts +23 -0
  234. package/dist/types/sdk/market/pricefeeds/AbstractPriceFeed.d.ts +6 -0
  235. package/dist/types/sdk/market/pricefeeds/types.d.ts +10 -0
  236. package/dist/types/sdk/opportunities/MultichainOpportunitiesService.d.ts +40 -0
  237. package/dist/types/sdk/opportunities/OpportunitiesService.d.ts +47 -0
  238. package/dist/types/sdk/opportunities/index.d.ts +4 -0
  239. package/dist/types/sdk/types/index.d.ts +2 -1
  240. package/dist/types/sdk/types/multichain.d.ts +65 -0
  241. package/dist/types/sdk/types/state.d.ts +1 -1
  242. package/dist/types/sdk/types/transactions.d.ts +3 -0
  243. package/dist/types/{common-utils → sdk}/utils/bigint-math.d.ts +7 -11
  244. package/dist/types/sdk/utils/index.d.ts +3 -2
  245. package/dist/types/sdk/utils/zod.d.ts +6 -2
  246. package/package.json +16 -1
  247. package/dist/cjs/sdk/accounts/liquidations/helpers.js +0 -201
  248. package/dist/esm/sdk/accounts/liquidations/helpers.js +0 -192
  249. package/dist/types/sdk/accounts/liquidations/helpers.d.ts +0 -140
@@ -1,11 +1,15 @@
1
1
  import { iCreditManagerV310Abi } from "../../../abi/310/generated.js";
2
2
  import { AddressMap } from "../../utils/AddressMap.js";
3
+ import { PERCENTAGE_FACTOR } from "../../constants/math.js";
4
+ import "../../constants/index.js";
3
5
  import { fmtBinaryMask, percentFmt } from "../../utils/formatter.js";
4
6
  import "../../utils/index.js";
5
7
  import { BaseContract } from "../../base/BaseContract.js";
6
8
  import "../../base/index.js";
7
9
  import { createAdapter } from "../adapters/createAdapter.js";
8
10
  import "../adapters/index.js";
11
+ import { maxLeverage } from "../math.js";
12
+ import { isAddressEqual } from "viem";
9
13
  //#region src/sdk/market/credit/CreditManagerV310Contract.ts
10
14
  const abi = iCreditManagerV310Abi;
11
15
  var CreditManagerV310Contract = class extends BaseContract {
@@ -59,6 +63,28 @@ var CreditManagerV310Contract = class extends BaseContract {
59
63
  get collateralTokens() {
60
64
  return this.liquidationThresholds.keys();
61
65
  }
66
+ /**
67
+ * {@inheritDoc ICreditManagerContract.leverageableCollaterals}
68
+ */
69
+ get leverageableCollaterals() {
70
+ return this.collateralTokens.filter((token) => {
71
+ if (isAddressEqual(token, this.underlying)) return false;
72
+ const lt = this.liquidationThresholds.get(token);
73
+ return !!lt && lt > 0 && lt < Number(10000n);
74
+ });
75
+ }
76
+ /**
77
+ * {@inheritDoc ICreditManagerContract.maxLeverage}
78
+ */
79
+ maxLeverage(collateral) {
80
+ return maxLeverage(this.liquidationThresholds.mustGet(collateral));
81
+ }
82
+ /**
83
+ * {@inheritDoc ICreditManagerContract.liquidationPremium}
84
+ */
85
+ get liquidationPremium() {
86
+ return Number(PERCENTAGE_FACTOR) - this.liquidationDiscount;
87
+ }
62
88
  processLog(log) {
63
89
  switch (log.eventName) {
64
90
  case "SetCreditConfigurator": this.dirty = true;
@@ -1,5 +1,10 @@
1
+ import { BigIntMath } from "../../utils/bigint-math.js";
2
+ import { isSunsetStrategy } from "../../chain/chains.js";
3
+ import "../../constants/math.js";
4
+ import "../../constants/index.js";
1
5
  import { SDKConstruct } from "../../base/SDKConstruct.js";
2
6
  import "../../base/index.js";
7
+ import { additionalBorrowApyBps, borrowApyBps, utilizationBps } from "../math.js";
3
8
  import createCreditConfigurator from "./createCreditConfigurator.js";
4
9
  import createCreditFacade from "./createCreditFacade.js";
5
10
  import createCreditManager from "./createCreditManager.js";
@@ -98,6 +103,103 @@ var CreditSuite = class extends SDKConstruct {
98
103
  return this.creditFacade.expirable && this.creditFacade.expirationDate > 0 && this.creditFacade.expirationDate < this.sdk.timestamp;
99
104
  }
100
105
  /**
106
+ * Moment the facade expires, after which positions can no longer be opened
107
+ * and open ones become liquidatable, or `null` when it is not expirable.
108
+ *
109
+ * @remarks
110
+ * The facade stores `0` for a non-expirable suite, which as a timestamp
111
+ * would read as 1970 rather than as "never".
112
+ */
113
+ get expirationDate() {
114
+ const { expirationDate } = this.creditFacade;
115
+ return expirationDate > 0 ? expirationDate : null;
116
+ }
117
+ /**
118
+ * Whether this suite can be used right now. A paused pool blocks borrowing,
119
+ * so the suite is unusable even when its own facade is live.
120
+ */
121
+ get isPaused() {
122
+ return this.creditFacade.isPaused || this.market.pool.isPaused;
123
+ }
124
+ /**
125
+ * Collateral tokens a leveraged position can be built around in this suite:
126
+ * the ones the credit manager can lever up, narrowed to those the market
127
+ * still accepts quota for.
128
+ */
129
+ get strategyCollaterals() {
130
+ const { pqk } = this.market.pool;
131
+ return this.creditManager.leverageableCollaterals.filter((token) => pqk.hasActiveQuota(token));
132
+ }
133
+ /**
134
+ * Largest debt a single new position can take on right now: the tightest of
135
+ * this manager's remaining debt limit, the pool's free liquidity and the
136
+ * facade's per-account maximum.
137
+ */
138
+ get maxBorrowAmount() {
139
+ const { pool } = this.market.pool;
140
+ const debtParams = pool.creditManagerDebtParams.get(this.creditManager.address);
141
+ return BigIntMath.min(debtParams?.available ?? 115792089237316195423570985008687907853269984665640564039457584007913129639935n, pool.availableLiquidity, this.creditFacade.maxDebt);
142
+ }
143
+ /**
144
+ * Describes a leveraged position built on one collateral token as the shared
145
+ * read model does.
146
+ *
147
+ * @param collateral - Target collateral of the position.
148
+ * @param totalSupply - Summed worth of the credit accounts backing it, which
149
+ * only a credit-account query can establish. Defaults to zero, so a caller
150
+ * that does not care about size can omit it.
151
+ * @throws If the credit manager does not value the collateral.
152
+ */
153
+ strategyOpportunity(collateral, totalSupply_) {
154
+ const totalSupply = totalSupply_ ?? {
155
+ value: 0n,
156
+ valueUsd: 0
157
+ };
158
+ const { market, creditManager: cm } = this;
159
+ const { pool } = market.pool;
160
+ const oracle = market.priceOracle;
161
+ const liquidationThreshold = cm.liquidationThresholds.mustGet(collateral);
162
+ const maxLeverage = cm.maxLeverage(collateral);
163
+ const borrowed = pool.creditManagerDebtParams.get(cm.address)?.borrowed ?? 0n;
164
+ return {
165
+ kind: "strategy",
166
+ chainId: this.chainId,
167
+ creditManager: cm.address,
168
+ targetCollateral: this.tokensMeta.mustGetToken(collateral),
169
+ title: `${this.tokensMeta.symbol(collateral)} / ${market.underlyingToken.symbol}`,
170
+ curator: market.curator,
171
+ underlyingToken: market.underlyingToken,
172
+ totalSupply,
173
+ totalBorrow: oracle.toAmount(pool.underlying, borrowed),
174
+ utilization: utilizationBps(borrowed, totalSupply.value),
175
+ collateralTokens: market.collateralTokens,
176
+ paused: this.isPaused,
177
+ rwa: market.rwa,
178
+ sunset: isSunsetStrategy(cm.address, collateral, this.sdk.networkType),
179
+ liquidationThreshold,
180
+ liquidationPremium: cm.liquidationPremium,
181
+ liquidationFee: cm.feeLiquidation,
182
+ expirationDate: this.expirationDate,
183
+ borrowApy: borrowApyBps(pool.baseInterestRate, cm.feeInterest),
184
+ additionalBorrowApy: additionalBorrowApyBps(market.pool.pqk.quotaRate(collateral), maxLeverage),
185
+ maxBorrowAmount: oracle.toAmount(pool.underlying, this.maxBorrowAmount),
186
+ maxLeverage
187
+ };
188
+ }
189
+ /**
190
+ * {@link strategyOpportunity} plus the data only its detail screen needs.
191
+ *
192
+ * @param collateral - Target collateral of the position.
193
+ * @param totalSupply - Summed worth of the credit accounts backing it.
194
+ */
195
+ strategyOpportunityDetail(collateral, totalSupply) {
196
+ return {
197
+ ...this.strategyOpportunity(collateral, totalSupply),
198
+ rateCurve: this.market.pool.rateCurve,
199
+ priceFeeds: this.market.priceFeedSummary(collateral)
200
+ };
201
+ }
202
+ /**
101
203
  * Whether the facade, manager, or configurator has observed logs that require
102
204
  * a credit-suite resync.
103
205
  */
@@ -0,0 +1,98 @@
1
+ import { PERCENTAGE_FACTOR, PRICE_DECIMALS, RAY } from "../constants/math.js";
2
+ //#region src/sdk/market/math.ts
3
+ /**
4
+ * Conversions between the units the protocol stores and the basis points the
5
+ * read model exposes.
6
+ *
7
+ * These live here rather than inside the service so that the on-chain adapter,
8
+ * the merger and any future consumer of the read model share one definition of
9
+ * every derived value.
10
+ **/
11
+ const FULL = Number(PERCENTAGE_FACTOR);
12
+ /**
13
+ * Converts a ray-scaled rate (`10 ** 27` = 100%) to basis points, truncating
14
+ * towards zero.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * rayToBps(50_000_000_000_000_000_000_000_000n) // 500, i.e. 5%
19
+ * ```
20
+ **/
21
+ function rayToBps(ray) {
22
+ return Number(ray * PERCENTAGE_FACTOR / RAY);
23
+ }
24
+ /**
25
+ * Converts a USD value in the oracle's 8-decimal fixed point to a float.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * usdToNumber(150_050_000_000n) // 1500.5
30
+ * ```
31
+ **/
32
+ function usdToNumber(usd) {
33
+ return Number(usd) / Number(PRICE_DECIMALS);
34
+ }
35
+ /**
36
+ * Share of capital currently borrowed, in basis points. Returns `0` when there
37
+ * is nothing to borrow from, and never exceeds 100%.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * utilizationBps(750n, 1000n) // 7500, i.e. 75%
42
+ * ```
43
+ **/
44
+ function utilizationBps(borrowed, total) {
45
+ if (total <= 0n || borrowed <= 0n) return 0;
46
+ const utilization = Number(borrowed * PERCENTAGE_FACTOR / total);
47
+ return Math.min(utilization, FULL);
48
+ }
49
+ /**
50
+ * Annual cost of debt for a credit manager, in basis points: the pool's base
51
+ * rate plus the protocol's cut of the accrued interest.
52
+ *
53
+ * @param baseInterestRate - Pool base rate in ray.
54
+ * @param feeInterest - Credit manager interest fee in basis points.
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * // 5% base rate, 50% interest fee
59
+ * borrowApyBps(50_000_000_000_000_000_000_000_000n, 5000) // 750, i.e. 7.5%
60
+ * ```
61
+ **/
62
+ function borrowApyBps(baseInterestRate, feeInterest) {
63
+ return rayToBps(baseInterestRate * (PERCENTAGE_FACTOR + BigInt(feeInterest)) / PERCENTAGE_FACTOR);
64
+ }
65
+ /**
66
+ * Highest leverage a liquidation threshold allows: `1 / (1 - lt)`.
67
+ *
68
+ * A threshold of 100% or more would allow unbounded leverage; such tokens are
69
+ * not strategies and are filtered out before this is called, so the guard here
70
+ * only exists to keep the function total.
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * maxLeverage(9000) // 10
75
+ * maxLeverage(8000) // 5
76
+ * ```
77
+ **/
78
+ function maxLeverage(liquidationThreshold) {
79
+ const equity = FULL - liquidationThreshold;
80
+ return equity > 0 ? FULL / equity : Number.POSITIVE_INFINITY;
81
+ }
82
+ /**
83
+ * Annual quota cost scaled to the debt a maximally leveraged position carries,
84
+ * in basis points. Every unit of own capital carries `maxLeverage - 1` units of
85
+ * debt, and the quota is paid on the whole quoted position.
86
+ *
87
+ * @example
88
+ * ```ts
89
+ * // 2.5% quota rate at 5x leverage
90
+ * additionalBorrowApyBps(250, 5) // 1000, i.e. 10%
91
+ * ```
92
+ **/
93
+ function additionalBorrowApyBps(quotaRate, leverage) {
94
+ if (!Number.isFinite(leverage)) return 0;
95
+ return Math.round(quotaRate * Math.max(leverage - 1, 0));
96
+ }
97
+ //#endregion
98
+ export { additionalBorrowApyBps, borrowApyBps, maxLeverage, rayToBps, usdToNumber, utilizationBps };
@@ -6,6 +6,7 @@ import { formatBN } from "../../utils/formatter.js";
6
6
  import "../../utils/index.js";
7
7
  import { BaseContract } from "../../base/BaseContract.js";
8
8
  import "../../base/index.js";
9
+ import { usdToNumber } from "../math.js";
9
10
  import { PriceFeedRef } from "../pricefeeds/PriceFeedRef.js";
10
11
  import { priceFeedCompressorAbi } from "../../../abi/compressors/priceFeedCompressor.js";
11
12
  import "../pricefeeds/index.js";
@@ -103,6 +104,57 @@ var PriceOracleBaseContract = class extends BaseContract {
103
104
  return amount * 10n ** BigInt(this.tokensMeta.decimals(to)) / price;
104
105
  }
105
106
  /**
107
+ * {@inheritDoc IPriceOracleContract.safeUsdValue}
108
+ **/
109
+ safeUsdValue(token, amount) {
110
+ try {
111
+ return usdToNumber(this.convertToUSD(token, amount));
112
+ } catch (e) {
113
+ this.logger?.debug(`cannot price ${this.labelAddress(token)}: ${e}`);
114
+ return null;
115
+ }
116
+ }
117
+ /**
118
+ * {@inheritDoc IPriceOracleContract.toAmount}
119
+ **/
120
+ toAmount = (token, value) => {
121
+ return {
122
+ value,
123
+ valueUsd: this.safeUsdValue(token, value)
124
+ };
125
+ };
126
+ /**
127
+ * {@inheritDoc IPriceOracleContract.toTokenAmount}
128
+ **/
129
+ toTokenAmount = (token, value) => {
130
+ return {
131
+ token: this.tokensMeta.mustGetToken(token),
132
+ ...this.toAmount(token, value)
133
+ };
134
+ };
135
+ /**
136
+ * {@inheritDoc IPriceOracleContract.priceFeedData}
137
+ **/
138
+ priceFeedData(token) {
139
+ const ref = this.mainPriceFeeds.get(token);
140
+ if (!ref) throw new Error(`no main price feed for ${this.labelAddress(token)} in oracle ${this.labelAddress(this.address)}`);
141
+ return ref.priceFeed.describe();
142
+ }
143
+ /**
144
+ * {@inheritDoc IPriceOracleContract.priceFeedSummary}
145
+ **/
146
+ priceFeedSummary(underlying, collateral) {
147
+ const collateralUnit = 10n ** BigInt(this.tokensMeta.decimals(collateral));
148
+ const underlyingUnit = 10n ** BigInt(this.tokensMeta.decimals(underlying));
149
+ return {
150
+ underlyingPriceInUsd: usdToNumber(this.mainPrice(underlying)),
151
+ collateralPriceInUsd: usdToNumber(this.mainPrice(collateral)),
152
+ collateralPriceInUnderlying: Number(this.convert(collateral, underlying, collateralUnit)) / Number(underlyingUnit),
153
+ underlyingFeed: this.priceFeedData(underlying),
154
+ collateralFeed: this.priceFeedData(collateral)
155
+ };
156
+ }
157
+ /**
106
158
  * {@inheritDoc IPriceOracleContract.priceFeeds}
107
159
  **/
108
160
  get priceFeeds() {
@@ -3,6 +3,7 @@ import "../../utils/index.js";
3
3
  import { BaseContract } from "../../base/BaseContract.js";
4
4
  import "../../base/index.js";
5
5
  import { iLinearInterestRateModelV310Abi } from "../../../abi/310/iLinearInterestRateModelV310.js";
6
+ import { borrowRateAtUtilization, rateCurveUtilizations, supplyRateAtUtilization } from "./math.js";
6
7
  import { decodeAbiParameters } from "viem";
7
8
  //#region src/sdk/market/pool/LinearInterestRateModelContract.ts
8
9
  const abi = iLinearInterestRateModelV310Abi;
@@ -58,6 +59,35 @@ var LinearInterestRateModelContract = class extends BaseContract {
58
59
  this.Rslope3 = Rslope3;
59
60
  this.isBorrowingMoreU2Forbidden = isBorrowingMoreU2Forbidden;
60
61
  }
62
+ /**
63
+ * The model's own parameters, gathered for the rate math.
64
+ */
65
+ get params() {
66
+ return {
67
+ U1: this.U1,
68
+ U2: this.U2,
69
+ Rbase: this.Rbase,
70
+ Rslope1: this.Rslope1,
71
+ Rslope2: this.Rslope2,
72
+ Rslope3: this.Rslope3,
73
+ isBorrowingMoreU2Forbidden: this.isBorrowingMoreU2Forbidden
74
+ };
75
+ }
76
+ /**
77
+ * The model evaluated into chart-ready points, so that no consumer has to
78
+ * reimplement it.
79
+ */
80
+ rateCurve() {
81
+ const { params } = this;
82
+ return {
83
+ points: rateCurveUtilizations(params).map((utilization) => ({
84
+ utilization,
85
+ supplyApy: supplyRateAtUtilization(utilization, params),
86
+ borrowApy: borrowRateAtUtilization(utilization, params)
87
+ })),
88
+ borrowingLimitUtilization: params.isBorrowingMoreU2Forbidden ? params.U2 : null
89
+ };
90
+ }
61
91
  stateHuman(raw) {
62
92
  return {
63
93
  ...super.stateHuman(raw),
@@ -20,6 +20,32 @@ var PoolQuotaKeeperV310Contract = class extends BaseContract {
20
20
  return [q.token, q];
21
21
  }), "quotas");
22
22
  }
23
+ /**
24
+ * Whether the market still accepts quota for a token: a token whose quota is
25
+ * inactive or whose limit is exhausted can no longer back a new position.
26
+ *
27
+ * @param token - Token address.
28
+ */
29
+ hasActiveQuota(token) {
30
+ const quota = this.quotas.get(token);
31
+ return !!quota?.isActive && quota.limit > 0n;
32
+ }
33
+ /**
34
+ * Every token the market still accepts quota for, see
35
+ * {@link hasActiveQuota}.
36
+ */
37
+ get activeQuotaTokens() {
38
+ return this.quotas.keys().filter((token) => this.hasActiveQuota(token));
39
+ }
40
+ /**
41
+ * Annual quota rate paid on a quoted token, in basis points, or `0` when the
42
+ * market does not quote it.
43
+ *
44
+ * @param token - Quoted token address.
45
+ */
46
+ quotaRate(token) {
47
+ return this.quotas.get(token)?.rate ?? 0;
48
+ }
23
49
  stateHuman(raw = true) {
24
50
  return {
25
51
  ...super.stateHuman(raw),
@@ -99,6 +99,34 @@ var PoolSuite = class extends SDKConstruct {
99
99
  return this.pool.underlying;
100
100
  }
101
101
  /**
102
+ * {@inheritDoc IPoolContract.unwrappedUnderlying}
103
+ */
104
+ get unwrappedUnderlying() {
105
+ return this.pool.unwrappedUnderlying;
106
+ }
107
+ /**
108
+ * {@inheritDoc IPoolContract.utilization}
109
+ */
110
+ get utilization() {
111
+ return this.pool.utilization;
112
+ }
113
+ /**
114
+ * Whether the pool is paused, which blocks borrowing across every connected
115
+ * credit suite.
116
+ */
117
+ get isPaused() {
118
+ return this.pool.isPaused;
119
+ }
120
+ /**
121
+ * Interest rate curve of the pool's rate model.
122
+ *
123
+ * @throws If the market uses an interest-rate model that is not linear, and
124
+ * therefore has no curve the SDK can evaluate.
125
+ */
126
+ get rateCurve() {
127
+ return this.linearModel.rateCurve();
128
+ }
129
+ /**
102
130
  * RWA factory associated with the pool's underlying, undefined for non-RWA markets.
103
131
  */
104
132
  get rwaFactory() {
@@ -1,10 +1,13 @@
1
+ import { iPausableAbi } from "../../../abi/iPausable.js";
1
2
  import { iPoolV310Abi } from "../../../abi/310/generated.js";
2
3
  import { AddressMap } from "../../utils/AddressMap.js";
4
+ import { RAY } from "../../constants/math.js";
5
+ import "../../constants/index.js";
3
6
  import { formatBN, formatBNvalue, percentFmt } from "../../utils/formatter.js";
4
7
  import "../../utils/index.js";
5
8
  import { BaseContract } from "../../base/BaseContract.js";
6
9
  import "../../base/index.js";
7
- import { iPausableAbi } from "../../../abi/iPausable.js";
10
+ import { utilizationBps } from "../math.js";
8
11
  //#region src/sdk/market/pool/PoolV310Contract.ts
9
12
  const abi = [...iPoolV310Abi, ...iPausableAbi];
10
13
  var PoolV310Contract = class extends BaseContract {
@@ -31,6 +34,30 @@ var PoolV310Contract = class extends BaseContract {
31
34
  const meta = this.#sdk.tokensMeta.mustGet(this.underlying);
32
35
  if (this.#sdk.tokensMeta.isRWAUnderlying(meta)) return this.#sdk.mustGetContract(meta.rwaFactory);
33
36
  }
37
+ /**
38
+ * {@inheritDoc IPoolContract.borrowed}
39
+ */
40
+ get borrowed() {
41
+ return this.expectedLiquidity > this.availableLiquidity ? this.expectedLiquidity - this.availableLiquidity : 0n;
42
+ }
43
+ /**
44
+ * {@inheritDoc IPoolContract.totalAssets}
45
+ */
46
+ get totalAssets() {
47
+ return this.totalSupply * this.dieselRate / RAY;
48
+ }
49
+ /**
50
+ * {@inheritDoc IPoolContract.utilization}
51
+ */
52
+ get utilization() {
53
+ return utilizationBps(this.borrowed, this.expectedLiquidity);
54
+ }
55
+ /**
56
+ * {@inheritDoc IPoolContract.unwrappedUnderlying}
57
+ */
58
+ get unwrappedUnderlying() {
59
+ return this.tokensMeta.unwrapRWA(this.underlying);
60
+ }
34
61
  stateHuman(raw = true) {
35
62
  return {
36
63
  ...super.stateHuman(raw),
@@ -0,0 +1,41 @@
1
+ import { PERCENTAGE_FACTOR } from "../../constants/math.js";
2
+ //#region src/sdk/market/pool/math.ts
3
+ const FULL = Number(PERCENTAGE_FACTOR);
4
+ /**
5
+ * Base rate borrowers pay at a given utilization, in basis points, following
6
+ * the linear interest rate model's three segments.
7
+ *
8
+ * The result excludes the per-credit-manager interest fee: the model belongs to
9
+ * the pool, and every credit manager of a market can charge a different one.
10
+ **/
11
+ function borrowRateAtUtilization(utilization, params) {
12
+ const { U1, U2, Rbase, Rslope1, Rslope2, Rslope3 } = params;
13
+ const u = Math.min(Math.max(utilization, 0), FULL);
14
+ if (u <= 0) return Rbase;
15
+ if (u <= U1) return Math.round(Rbase + Rslope1 * u / U1);
16
+ if (u <= U2) return Math.round(Rbase + Rslope1 + Rslope2 * (u - U1) / Math.max(U2 - U1, 1));
17
+ return Math.round(Rbase + Rslope1 + Rslope2 + Rslope3 * (u - U2) / Math.max(FULL - U2, 1));
18
+ }
19
+ /**
20
+ * Rate depositors earn at a given utilization, in basis points: the interest
21
+ * borrowers pay, spread over the pool's whole liquidity.
22
+ **/
23
+ function supplyRateAtUtilization(utilization, params) {
24
+ const u = Math.min(Math.max(utilization, 0), FULL);
25
+ return Math.round(borrowRateAtUtilization(u, params) * u / FULL);
26
+ }
27
+ /**
28
+ * Utilizations the rate curve is sampled at: a fixed grid plus both kinks of
29
+ * the model, so the borrow leg is exact and the supply leg — which is
30
+ * quadratic between kinks — is smooth.
31
+ **/
32
+ function rateCurveUtilizations(params) {
33
+ const step = FULL / 20;
34
+ const grid = /* @__PURE__ */ new Set();
35
+ for (let u = 0; u <= FULL; u += step) grid.add(u);
36
+ grid.add(params.U1);
37
+ grid.add(params.U2);
38
+ return [...grid].filter((u) => u >= 0 && u <= FULL).sort((a, b) => a - b);
39
+ }
40
+ //#endregion
41
+ export { borrowRateAtUtilization, rateCurveUtilizations, supplyRateAtUtilization };
@@ -88,6 +88,23 @@ var AbstractPriceFeedContract = class extends BaseContract {
88
88
  const underlying = this.underlyingPriceFeeds.flatMap((f) => f.priceFeed.updatableDependencies());
89
89
  return isUpdatablePriceFeed(this) ? [this, ...underlying] : underlying;
90
90
  }
91
+ /**
92
+ * {@inheritDoc IPriceFeedContract.describe}
93
+ */
94
+ describe() {
95
+ let dependencies = [];
96
+ try {
97
+ dependencies = this.underlyingPriceFeeds.map((ref) => ref.priceFeed.describe());
98
+ } catch {
99
+ dependencies = [];
100
+ }
101
+ return {
102
+ name: this.name,
103
+ type: this.contractType,
104
+ feedAddress: this.address,
105
+ dependencies
106
+ };
107
+ }
91
108
  };
92
109
  //#endregion
93
110
  export { AbstractPriceFeedContract, PartialPriceFeedInitError };
@@ -1,5 +1,5 @@
1
- import { ZapperContract } from "./ZapperContract.js";
2
1
  import { iethZapperAbi } from "../../../abi/iETHZapper.js";
2
+ import { ZapperContract } from "./ZapperContract.js";
3
3
  //#region src/sdk/market/zapper/IETHZapperContract.ts
4
4
  const abi = iethZapperAbi;
5
5
  var IETHZapperContract = class extends ZapperContract {
@@ -1,6 +1,6 @@
1
+ import { iZapperAbi } from "../../../abi/iZapper.js";
1
2
  import { BaseContract } from "../../base/BaseContract.js";
2
3
  import "../../base/index.js";
3
- import { iZapperAbi } from "../../../abi/iZapper.js";
4
4
  import { UnsupportedZapperFunctionError } from "./errors.js";
5
5
  //#region src/sdk/market/zapper/ZapperContract.ts
6
6
  /**
@@ -0,0 +1,59 @@
1
+ import { getNetworkType } from "../chain/chains.js";
2
+ import { MultichainConstruct } from "../base/MultichainConstruct.js";
3
+ import "../base/index.js";
4
+ //#region src/sdk/opportunities/MultichainOpportunitiesService.ts
5
+ /**
6
+ * Cross-chain counterpart of {@link OpportunitiesService}.
7
+ *
8
+ * Fans out over every chain configured in {@link MultichainSDK}. A chain that
9
+ * fails is logged and skipped so one dead RPC does not empty the list; its
10
+ * failure is reported in {@link MultichainResult.meta}.
11
+ *
12
+ * Detail reads need no fan-out: an opportunity key names its chain.
13
+ *
14
+ * @typeParam Plugins - Map of attached plugin types.
15
+ **/
16
+ var MultichainOpportunitiesService = class extends MultichainConstruct {
17
+ /**
18
+ * Opportunities of all queried chains, see {@link OpportunitiesService.list}.
19
+ *
20
+ * A filter that names chains narrows the fan-out itself, so chains whose rows
21
+ * would be discarded are never queried and never appear in the meta.
22
+ **/
23
+ async list(filter) {
24
+ return this.queryChains({
25
+ networks: this.#networksOf(filter),
26
+ label: "list opportunities",
27
+ run: (sdk) => sdk.opportunities.list(filter)
28
+ });
29
+ }
30
+ /**
31
+ * {@inheritDoc OpportunitiesService.getPool}
32
+ **/
33
+ async getPool(key) {
34
+ return this.sdk.chain(key.chainId).opportunities.getPool(key);
35
+ }
36
+ /**
37
+ * {@inheritDoc OpportunitiesService.getStrategy}
38
+ **/
39
+ async getStrategy(key) {
40
+ return this.sdk.chain(key.chainId).opportunities.getStrategy(key);
41
+ }
42
+ /**
43
+ * Chains named by the filter, or `undefined` to query all of them. Chain ids
44
+ * the SDK does not support are dropped here rather than reported as failures:
45
+ * a filter naming them is a narrowing, not a request.
46
+ **/
47
+ #networksOf(filter) {
48
+ if (!filter?.chainIds) return;
49
+ const networks = [];
50
+ for (const chainId of filter.chainIds) try {
51
+ networks.push(getNetworkType(chainId));
52
+ } catch {
53
+ this.sdk.logger?.debug(`ignoring unsupported chain ${chainId} in opportunities filter`);
54
+ }
55
+ return networks;
56
+ }
57
+ };
58
+ //#endregion
59
+ export { MultichainOpportunitiesService };