@mento-protocol/mento-sdk 3.2.7 → 3.3.0-beta.0

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 (302) hide show
  1. package/dist/cache/routes.d.ts +13 -0
  2. package/dist/cache/routes.js +14588 -0
  3. package/dist/cache/tokens.d.ts +68 -0
  4. package/dist/cache/tokens.js +514 -0
  5. package/dist/core/abis/activePool.d.ts +2 -0
  6. package/dist/core/abis/activePool.js +14 -0
  7. package/dist/core/abis/addressesRegistry.d.ts +2 -0
  8. package/dist/core/abis/addressesRegistry.js +26 -0
  9. package/dist/core/abis/bipoolmanager.d.ts +34 -0
  10. package/dist/core/abis/bipoolmanager.js +72 -0
  11. package/dist/core/abis/borrowerOperations.d.ts +9 -0
  12. package/dist/core/abis/borrowerOperations.js +89 -0
  13. package/dist/core/abis/breakerbox.d.ts +13 -0
  14. package/dist/core/abis/breakerbox.js +8 -0
  15. package/dist/core/abis/broker.d.ts +2 -0
  16. package/dist/core/abis/broker.js +9 -0
  17. package/dist/core/abis/erc20.d.ts +9 -0
  18. package/dist/core/abis/erc20.js +21 -0
  19. package/dist/core/abis/fpmm.d.ts +270 -0
  20. package/dist/core/abis/fpmm.js +49 -0
  21. package/dist/core/abis/fpmmFactory.d.ts +85 -0
  22. package/dist/core/abis/fpmmFactory.js +26 -0
  23. package/dist/core/abis/hintHelpers.d.ts +2 -0
  24. package/dist/core/abis/hintHelpers.js +14 -0
  25. package/dist/core/abis/index.d.ts +22 -0
  26. package/dist/core/abis/index.js +38 -0
  27. package/dist/core/abis/liquidityStrategy.d.ts +132 -0
  28. package/dist/core/abis/liquidityStrategy.js +10 -0
  29. package/dist/core/abis/multiTroveGetter.d.ts +8 -0
  30. package/dist/core/abis/multiTroveGetter.js +15 -0
  31. package/dist/core/abis/priceFeed.d.ts +7 -0
  32. package/dist/core/abis/priceFeed.js +16 -0
  33. package/dist/core/abis/pricingmodule.d.ts +2 -0
  34. package/dist/core/abis/pricingmodule.js +6 -0
  35. package/dist/core/abis/reserve.d.ts +3 -0
  36. package/dist/core/abis/reserve.js +18 -0
  37. package/dist/core/abis/router.d.ts +521 -0
  38. package/dist/core/abis/router.js +45 -0
  39. package/dist/core/abis/sortedTroves.d.ts +2 -0
  40. package/dist/core/abis/sortedTroves.js +15 -0
  41. package/dist/core/abis/systemParams.d.ts +2 -0
  42. package/dist/core/abis/systemParams.js +14 -0
  43. package/dist/core/abis/troveManager.d.ts +2 -0
  44. package/dist/core/abis/troveManager.js +27 -0
  45. package/dist/core/abis/troveNFT.d.ts +2 -0
  46. package/dist/core/abis/troveNFT.js +9 -0
  47. package/dist/core/abis/virtualPool.d.ts +50 -0
  48. package/dist/core/abis/virtualPool.js +11 -0
  49. package/dist/core/abis/virtualPoolFactory.d.ts +59 -0
  50. package/dist/core/abis/virtualPoolFactory.js +17 -0
  51. package/dist/core/constants/addresses.d.ts +18 -0
  52. package/dist/core/constants/addresses.js +125 -0
  53. package/dist/core/constants/borrowConstants.d.ts +10 -0
  54. package/dist/core/constants/borrowConstants.js +16 -0
  55. package/dist/core/constants/borrowRegistries.d.ts +7 -0
  56. package/dist/core/constants/borrowRegistries.js +34 -0
  57. package/dist/core/constants/chainId.d.ts +8 -0
  58. package/dist/core/constants/chainId.js +12 -0
  59. package/dist/core/constants/contractNames.d.ts +21 -0
  60. package/dist/core/constants/contractNames.js +24 -0
  61. package/dist/core/constants/index.d.ts +6 -0
  62. package/dist/core/constants/index.js +22 -0
  63. package/dist/core/errors/base.d.ts +8 -0
  64. package/dist/core/errors/base.js +17 -0
  65. package/dist/core/errors/index.d.ts +4 -0
  66. package/dist/core/errors/index.js +20 -0
  67. package/dist/core/errors/oracle.d.ts +9 -0
  68. package/dist/core/errors/oracle.js +15 -0
  69. package/dist/core/errors/router.d.ts +14 -0
  70. package/dist/core/errors/router.js +24 -0
  71. package/dist/core/types/borrow.d.ts +87 -0
  72. package/dist/core/types/borrow.js +3 -0
  73. package/dist/core/types/contractAddresses.d.ts +42 -0
  74. package/dist/core/types/contractAddresses.js +3 -0
  75. package/dist/core/types/index.d.ts +10 -0
  76. package/dist/core/types/index.js +26 -0
  77. package/dist/core/types/liquidity.d.ts +194 -0
  78. package/dist/core/types/liquidity.js +3 -0
  79. package/dist/core/types/pool.d.ts +208 -0
  80. package/dist/core/types/pool.js +14 -0
  81. package/dist/core/types/provider.d.ts +45 -0
  82. package/dist/core/types/provider.js +3 -0
  83. package/dist/core/types/route.d.ts +62 -0
  84. package/dist/core/types/route.js +3 -0
  85. package/dist/core/types/token.d.ts +21 -0
  86. package/dist/core/types/token.js +3 -0
  87. package/dist/core/types/tradingLimits.d.ts +91 -0
  88. package/dist/core/types/tradingLimits.js +3 -0
  89. package/dist/core/types/tradingMode.d.ts +24 -0
  90. package/dist/core/types/tradingMode.js +31 -0
  91. package/dist/core/types/transaction.d.ts +45 -0
  92. package/dist/core/types/transaction.js +3 -0
  93. package/dist/esm/cache/routes.js +14583 -0
  94. package/dist/esm/cache/tokens.js +506 -0
  95. package/dist/esm/core/abis/activePool.js +10 -0
  96. package/dist/esm/core/abis/addressesRegistry.js +22 -0
  97. package/dist/esm/core/abis/bipoolmanager.js +68 -0
  98. package/dist/esm/core/abis/borrowerOperations.js +85 -0
  99. package/dist/esm/core/abis/breakerbox.js +4 -0
  100. package/dist/esm/core/abis/broker.js +5 -0
  101. package/dist/esm/core/abis/erc20.js +17 -0
  102. package/dist/esm/core/abis/fpmm.js +45 -0
  103. package/dist/esm/core/abis/fpmmFactory.js +22 -0
  104. package/dist/esm/core/abis/hintHelpers.js +10 -0
  105. package/dist/esm/core/abis/index.js +21 -0
  106. package/dist/esm/core/abis/liquidityStrategy.js +6 -0
  107. package/dist/esm/core/abis/multiTroveGetter.js +11 -0
  108. package/dist/esm/core/abis/priceFeed.js +12 -0
  109. package/dist/esm/core/abis/pricingmodule.js +2 -0
  110. package/dist/esm/core/abis/reserve.js +14 -0
  111. package/dist/esm/core/abis/router.js +41 -0
  112. package/dist/esm/core/abis/sortedTroves.js +11 -0
  113. package/dist/esm/core/abis/systemParams.js +10 -0
  114. package/dist/esm/core/abis/troveManager.js +23 -0
  115. package/dist/esm/core/abis/troveNFT.js +5 -0
  116. package/dist/esm/core/abis/virtualPool.js +7 -0
  117. package/dist/esm/core/abis/virtualPoolFactory.js +13 -0
  118. package/dist/esm/core/constants/addresses.js +119 -0
  119. package/dist/esm/core/constants/borrowConstants.js +12 -0
  120. package/dist/esm/core/constants/borrowRegistries.js +29 -0
  121. package/dist/esm/core/constants/chainId.js +8 -0
  122. package/dist/esm/core/constants/contractNames.js +20 -0
  123. package/dist/esm/core/constants/index.js +5 -0
  124. package/dist/esm/core/errors/base.js +12 -0
  125. package/dist/esm/core/errors/index.js +3 -0
  126. package/dist/esm/core/errors/oracle.js +10 -0
  127. package/dist/esm/core/errors/router.js +18 -0
  128. package/dist/esm/core/types/borrow.js +1 -0
  129. package/dist/esm/core/types/contractAddresses.js +1 -0
  130. package/dist/esm/core/types/index.js +9 -0
  131. package/dist/esm/core/types/liquidity.js +1 -0
  132. package/dist/esm/core/types/pool.js +10 -0
  133. package/dist/esm/core/types/provider.js +1 -0
  134. package/dist/esm/core/types/route.js +1 -0
  135. package/dist/esm/core/types/token.js +1 -0
  136. package/dist/esm/core/types/tradingLimits.js +1 -0
  137. package/dist/esm/core/types/tradingMode.js +26 -0
  138. package/dist/esm/core/types/transaction.js +1 -0
  139. package/dist/esm/index.js +139 -0
  140. package/dist/esm/package.json +1 -0
  141. package/dist/esm/services/borrow/BorrowService.js +455 -0
  142. package/dist/esm/services/borrow/borrowHelpers.js +3 -0
  143. package/dist/esm/services/borrow/borrowMath.js +127 -0
  144. package/dist/esm/services/borrow/index.js +3 -0
  145. package/dist/esm/services/borrow/internal/borrowApprovalService.js +48 -0
  146. package/dist/esm/services/borrow/internal/borrowContextStore.js +35 -0
  147. package/dist/esm/services/borrow/internal/borrowErc20.js +38 -0
  148. package/dist/esm/services/borrow/internal/borrowHints.js +27 -0
  149. package/dist/esm/services/borrow/internal/borrowPositionParser.js +82 -0
  150. package/dist/esm/services/borrow/internal/borrowReadService.js +271 -0
  151. package/dist/esm/services/borrow/internal/borrowRegistryReader.js +108 -0
  152. package/dist/esm/services/borrow/internal/borrowTransactionService.js +271 -0
  153. package/dist/esm/services/borrow/internal/borrowTypes.js +1 -0
  154. package/dist/esm/services/borrow/internal/borrowValidation.js +89 -0
  155. package/dist/esm/services/index.js +8 -0
  156. package/dist/esm/services/liquidity/LiquidityService.js +163 -0
  157. package/dist/esm/services/liquidity/basicLiquidity.js +162 -0
  158. package/dist/esm/services/liquidity/index.js +1 -0
  159. package/dist/esm/services/liquidity/liquidityHelpers.js +95 -0
  160. package/dist/esm/services/liquidity/rebalance.js +59 -0
  161. package/dist/esm/services/liquidity/zapHelpers.js +181 -0
  162. package/dist/esm/services/liquidity/zapIn.js +131 -0
  163. package/dist/esm/services/liquidity/zapOut.js +248 -0
  164. package/dist/esm/services/pools/PoolService.js +204 -0
  165. package/dist/esm/services/pools/index.js +1 -0
  166. package/dist/esm/services/pools/poolDetails.js +209 -0
  167. package/dist/esm/services/pools/poolDiscovery.js +112 -0
  168. package/dist/esm/services/pools/rebalancePreview.js +181 -0
  169. package/dist/esm/services/quotes/QuoteService.js +85 -0
  170. package/dist/esm/services/quotes/index.js +1 -0
  171. package/dist/esm/services/routes/RouteService.js +268 -0
  172. package/dist/esm/services/routes/index.js +1 -0
  173. package/dist/esm/services/swap/SwapService.js +247 -0
  174. package/dist/esm/services/swap/index.js +1 -0
  175. package/dist/esm/services/tokens/index.js +1 -0
  176. package/dist/esm/services/tokens/tokenService.js +285 -0
  177. package/dist/esm/services/trading/TradingLimitsService.js +154 -0
  178. package/dist/esm/services/trading/TradingService.js +222 -0
  179. package/dist/esm/services/trading/index.js +2 -0
  180. package/dist/esm/utils/chainConfig.js +122 -0
  181. package/dist/esm/utils/costUtils.js +56 -0
  182. package/dist/esm/utils/deadline.js +22 -0
  183. package/dist/esm/utils/index.js +9 -0
  184. package/dist/esm/utils/multicall.js +47 -0
  185. package/dist/esm/utils/pathEncoder.js +69 -0
  186. package/dist/esm/utils/rateFeed.js +23 -0
  187. package/dist/esm/utils/retry.js +24 -0
  188. package/dist/esm/utils/routeUtils.js +361 -0
  189. package/dist/esm/utils/routes.js +2 -0
  190. package/dist/esm/utils/sortUtils.js +33 -0
  191. package/dist/esm/utils/tokens.js +2 -0
  192. package/dist/esm/utils/tradingLimits.js +163 -0
  193. package/dist/esm/utils/validation.js +30 -0
  194. package/dist/index.d.ts +101 -0
  195. package/dist/index.js +158 -0
  196. package/dist/services/borrow/BorrowService.d.ts +381 -0
  197. package/dist/services/borrow/BorrowService.js +460 -0
  198. package/dist/services/borrow/borrowHelpers.d.ts +4 -0
  199. package/dist/services/borrow/borrowHelpers.js +13 -0
  200. package/dist/services/borrow/borrowMath.d.ts +21 -0
  201. package/dist/services/borrow/borrowMath.js +137 -0
  202. package/dist/services/borrow/index.d.ts +4 -0
  203. package/dist/services/borrow/index.js +20 -0
  204. package/dist/services/borrow/internal/borrowApprovalService.d.ts +14 -0
  205. package/dist/services/borrow/internal/borrowApprovalService.js +53 -0
  206. package/dist/services/borrow/internal/borrowContextStore.d.ts +11 -0
  207. package/dist/services/borrow/internal/borrowContextStore.js +40 -0
  208. package/dist/services/borrow/internal/borrowErc20.d.ts +5 -0
  209. package/dist/services/borrow/internal/borrowErc20.js +43 -0
  210. package/dist/services/borrow/internal/borrowHints.d.ts +7 -0
  211. package/dist/services/borrow/internal/borrowHints.js +31 -0
  212. package/dist/services/borrow/internal/borrowPositionParser.d.ts +4 -0
  213. package/dist/services/borrow/internal/borrowPositionParser.js +87 -0
  214. package/dist/services/borrow/internal/borrowReadService.d.ts +31 -0
  215. package/dist/services/borrow/internal/borrowReadService.js +276 -0
  216. package/dist/services/borrow/internal/borrowRegistryReader.d.ts +5 -0
  217. package/dist/services/borrow/internal/borrowRegistryReader.js +113 -0
  218. package/dist/services/borrow/internal/borrowTransactionService.d.ts +23 -0
  219. package/dist/services/borrow/internal/borrowTransactionService.js +276 -0
  220. package/dist/services/borrow/internal/borrowTypes.d.ts +15 -0
  221. package/dist/services/borrow/internal/borrowTypes.js +3 -0
  222. package/dist/services/borrow/internal/borrowValidation.d.ts +14 -0
  223. package/dist/services/borrow/internal/borrowValidation.js +104 -0
  224. package/dist/services/index.d.ts +9 -0
  225. package/dist/services/index.js +25 -0
  226. package/dist/services/liquidity/LiquidityService.d.ts +139 -0
  227. package/dist/services/liquidity/LiquidityService.js +168 -0
  228. package/dist/services/liquidity/basicLiquidity.d.ts +11 -0
  229. package/dist/services/liquidity/basicLiquidity.js +172 -0
  230. package/dist/services/liquidity/index.d.ts +2 -0
  231. package/dist/services/liquidity/index.js +18 -0
  232. package/dist/services/liquidity/liquidityHelpers.d.ts +19 -0
  233. package/dist/services/liquidity/liquidityHelpers.js +104 -0
  234. package/dist/services/liquidity/rebalance.d.ts +6 -0
  235. package/dist/services/liquidity/rebalance.js +64 -0
  236. package/dist/services/liquidity/zapHelpers.d.ts +100 -0
  237. package/dist/services/liquidity/zapHelpers.js +192 -0
  238. package/dist/services/liquidity/zapIn.d.ts +18 -0
  239. package/dist/services/liquidity/zapIn.js +138 -0
  240. package/dist/services/liquidity/zapOut.d.ts +9 -0
  241. package/dist/services/liquidity/zapOut.js +255 -0
  242. package/dist/services/pools/PoolService.d.ts +69 -0
  243. package/dist/services/pools/PoolService.js +209 -0
  244. package/dist/services/pools/index.d.ts +2 -0
  245. package/dist/services/pools/index.js +18 -0
  246. package/dist/services/pools/poolDetails.d.ts +13 -0
  247. package/dist/services/pools/poolDetails.js +216 -0
  248. package/dist/services/pools/poolDiscovery.d.ts +12 -0
  249. package/dist/services/pools/poolDiscovery.js +117 -0
  250. package/dist/services/pools/rebalancePreview.d.ts +5 -0
  251. package/dist/services/pools/rebalancePreview.js +186 -0
  252. package/dist/services/quotes/QuoteService.d.ts +51 -0
  253. package/dist/services/quotes/QuoteService.js +91 -0
  254. package/dist/services/quotes/index.d.ts +2 -0
  255. package/dist/services/quotes/index.js +18 -0
  256. package/dist/services/routes/RouteService.d.ts +117 -0
  257. package/dist/services/routes/RouteService.js +306 -0
  258. package/dist/services/routes/index.d.ts +2 -0
  259. package/dist/services/routes/index.js +18 -0
  260. package/dist/services/swap/SwapService.d.ts +198 -0
  261. package/dist/services/swap/SwapService.js +252 -0
  262. package/dist/services/swap/index.d.ts +2 -0
  263. package/dist/services/swap/index.js +18 -0
  264. package/dist/services/tokens/index.d.ts +2 -0
  265. package/dist/services/tokens/index.js +18 -0
  266. package/dist/services/tokens/tokenService.d.ts +55 -0
  267. package/dist/services/tokens/tokenService.js +290 -0
  268. package/dist/services/trading/TradingLimitsService.d.ts +38 -0
  269. package/dist/services/trading/TradingLimitsService.js +159 -0
  270. package/dist/services/trading/TradingService.d.ts +115 -0
  271. package/dist/services/trading/TradingService.js +227 -0
  272. package/dist/services/trading/index.d.ts +3 -0
  273. package/dist/services/trading/index.js +19 -0
  274. package/dist/utils/chainConfig.d.ts +16 -0
  275. package/dist/utils/chainConfig.js +127 -0
  276. package/dist/utils/costUtils.d.ts +12 -0
  277. package/dist/utils/costUtils.js +60 -0
  278. package/dist/utils/deadline.d.ts +21 -0
  279. package/dist/utils/deadline.js +26 -0
  280. package/dist/utils/index.d.ts +10 -0
  281. package/dist/utils/index.js +26 -0
  282. package/dist/utils/multicall.d.ts +30 -0
  283. package/dist/utils/multicall.js +52 -0
  284. package/dist/utils/pathEncoder.d.ts +34 -0
  285. package/dist/utils/pathEncoder.js +73 -0
  286. package/dist/utils/rateFeed.d.ts +18 -0
  287. package/dist/utils/rateFeed.js +27 -0
  288. package/dist/utils/retry.d.ts +12 -0
  289. package/dist/utils/retry.js +28 -0
  290. package/dist/utils/routeUtils.d.ts +295 -0
  291. package/dist/utils/routeUtils.js +371 -0
  292. package/dist/utils/routes.d.ts +3 -0
  293. package/dist/utils/routes.js +8 -0
  294. package/dist/utils/sortUtils.d.ts +24 -0
  295. package/dist/utils/sortUtils.js +39 -0
  296. package/dist/utils/tokens.d.ts +2 -0
  297. package/dist/utils/tokens.js +13 -0
  298. package/dist/utils/tradingLimits.d.ts +41 -0
  299. package/dist/utils/tradingLimits.js +171 -0
  300. package/dist/utils/validation.d.ts +19 -0
  301. package/dist/utils/validation.js +34 -0
  302. package/package.json +1 -1
@@ -0,0 +1,38 @@
1
+ import { encodeFunctionData } from 'viem';
2
+ import { ERC20_ABI } from '../../../core/abis';
3
+ import { validateAddress } from '../../../utils/validation';
4
+ const ZERO_VALUE = '0';
5
+ function requireBigInt(value, fieldName) {
6
+ if (typeof value !== 'bigint') {
7
+ throw new Error(`${fieldName} must be a bigint`);
8
+ }
9
+ if (value < 0n) {
10
+ throw new Error(`${fieldName} cannot be negative`);
11
+ }
12
+ return value;
13
+ }
14
+ export function buildErc20ApprovalParams(token, spender, amount) {
15
+ validateAddress(token, 'token');
16
+ validateAddress(spender, 'spender');
17
+ if (amount < 0n) {
18
+ throw new Error('Approval amount cannot be negative');
19
+ }
20
+ const data = encodeFunctionData({
21
+ abi: ERC20_ABI,
22
+ functionName: 'approve',
23
+ args: [spender, amount],
24
+ });
25
+ return { to: token, data, value: ZERO_VALUE };
26
+ }
27
+ export async function readErc20Allowance(publicClient, token, owner, spender) {
28
+ validateAddress(token, 'token');
29
+ validateAddress(owner, 'owner');
30
+ validateAddress(spender, 'spender');
31
+ const allowanceRaw = await publicClient.readContract({
32
+ address: token,
33
+ abi: ERC20_ABI,
34
+ functionName: 'allowance',
35
+ args: [owner, spender],
36
+ });
37
+ return requireBigInt(allowanceRaw, 'allowance');
38
+ }
@@ -0,0 +1,27 @@
1
+ import { HINT_HELPERS_ABI, SORTED_TROVES_ABI } from '../../../core/abis';
2
+ import { COLL_INDEX } from '../../../core/constants';
3
+ import { ceilSqrt, requireNonNegativeBigInt } from './borrowValidation';
4
+ export async function getTroveOperationHints(publicClient, ctx, interestRate) {
5
+ const annualInterestRate = requireNonNegativeBigInt(interestRate, 'interestRate');
6
+ const troveCount = (await publicClient.readContract({
7
+ address: ctx.addresses.sortedTroves,
8
+ abi: SORTED_TROVES_ABI,
9
+ functionName: 'getSize',
10
+ args: [],
11
+ }));
12
+ const sqrtCount = ceilSqrt(troveCount);
13
+ const numTrials = 10n * (sqrtCount > 0n ? sqrtCount : 1n);
14
+ const [approxHint] = (await publicClient.readContract({
15
+ address: ctx.addresses.hintHelpers,
16
+ abi: HINT_HELPERS_ABI,
17
+ functionName: 'getApproxHint',
18
+ args: [COLL_INDEX, annualInterestRate, numTrials, 42n],
19
+ }));
20
+ const [upperHint, lowerHint] = (await publicClient.readContract({
21
+ address: ctx.addresses.sortedTroves,
22
+ abi: SORTED_TROVES_ABI,
23
+ functionName: 'findInsertPosition',
24
+ args: [annualInterestRate, approxHint, approxHint],
25
+ }));
26
+ return { upper: upperHint, lower: lowerHint };
27
+ }
@@ -0,0 +1,82 @@
1
+ import { zeroAddress } from 'viem';
2
+ import { validateAddress } from '../../../utils/validation';
3
+ const MAX_SAFE_INTEGER_BIGINT = BigInt(Number.MAX_SAFE_INTEGER);
4
+ function requireAddress(value, fieldName) {
5
+ if (typeof value !== 'string') {
6
+ throw new Error(`${fieldName} must be a string address`);
7
+ }
8
+ validateAddress(value, fieldName);
9
+ return value;
10
+ }
11
+ function requireBigInt(value, fieldName) {
12
+ if (typeof value !== 'bigint') {
13
+ throw new Error(`${fieldName} must be a bigint`);
14
+ }
15
+ if (value < 0n) {
16
+ throw new Error(`${fieldName} cannot be negative`);
17
+ }
18
+ return value;
19
+ }
20
+ function requireNonNegativeInteger(value, fieldName) {
21
+ if (typeof value === 'bigint') {
22
+ if (value < 0n) {
23
+ throw new Error(`${fieldName} cannot be negative`);
24
+ }
25
+ if (value > MAX_SAFE_INTEGER_BIGINT) {
26
+ throw new Error(`${fieldName} exceeds Number.MAX_SAFE_INTEGER`);
27
+ }
28
+ return Number(value);
29
+ }
30
+ if (typeof value === 'number') {
31
+ if (!Number.isSafeInteger(value)) {
32
+ throw new Error(`${fieldName} must be a safe integer`);
33
+ }
34
+ if (value < 0) {
35
+ throw new Error(`${fieldName} cannot be negative`);
36
+ }
37
+ return value;
38
+ }
39
+ throw new Error(`${fieldName} must be a number or bigint`);
40
+ }
41
+ export function mapTroveStatus(statusNum) {
42
+ if (!Number.isSafeInteger(statusNum) || statusNum < 0) {
43
+ throw new Error(`Invalid trove status: ${statusNum}`);
44
+ }
45
+ switch (statusNum) {
46
+ case 0:
47
+ return 'nonExistent';
48
+ case 1:
49
+ return 'active';
50
+ case 2:
51
+ return 'closedByOwner';
52
+ case 3:
53
+ return 'closedByLiquidation';
54
+ case 4:
55
+ return 'zombie';
56
+ default:
57
+ throw new Error(`Unknown trove status: ${statusNum}`);
58
+ }
59
+ }
60
+ export function parseBorrowPosition(troveId, latestData, trovesData) {
61
+ if (typeof troveId !== 'string' || troveId.length === 0) {
62
+ throw new Error('troveId must be a non-empty string');
63
+ }
64
+ const latest = latestData;
65
+ const trove = trovesData;
66
+ const interestBatchManager = requireAddress(trove.interestBatchManager, 'trovesData.interestBatchManager');
67
+ return {
68
+ troveId,
69
+ collateral: requireBigInt(latest.entireColl, 'latestData.entireColl'),
70
+ debt: requireBigInt(latest.entireDebt, 'latestData.entireDebt'),
71
+ annualInterestRate: requireBigInt(latest.annualInterestRate, 'latestData.annualInterestRate'),
72
+ status: mapTroveStatus(requireNonNegativeInteger(trove.status, 'trovesData.status')),
73
+ interestBatchManager: interestBatchManager.toLowerCase() === zeroAddress ? null : interestBatchManager,
74
+ lastDebtUpdateTime: requireNonNegativeInteger(trove.lastDebtUpdateTime, 'trovesData.lastDebtUpdateTime'),
75
+ lastInterestRateAdjTime: requireNonNegativeInteger(latest.lastInterestRateAdjTime, 'latestData.lastInterestRateAdjTime'),
76
+ redistBoldDebtGain: requireBigInt(latest.redistBoldDebtGain, 'latestData.redistBoldDebtGain'),
77
+ redistCollGain: requireBigInt(latest.redistCollGain, 'latestData.redistCollGain'),
78
+ accruedInterest: requireBigInt(latest.accruedInterest, 'latestData.accruedInterest'),
79
+ recordedDebt: requireBigInt(latest.recordedDebt, 'latestData.recordedDebt'),
80
+ accruedBatchManagementFee: requireBigInt(latest.accruedBatchManagementFee, 'latestData.accruedBatchManagementFee'),
81
+ };
82
+ }
@@ -0,0 +1,271 @@
1
+ import { BORROWER_OPERATIONS_ABI, HINT_HELPERS_ABI, MULTI_TROVE_GETTER_ABI, PRICE_FEED_ABI, TROVE_MANAGER_ABI, TROVE_NFT_ABI, } from '../../../core/abis';
2
+ import { COLL_INDEX } from '../../../core/constants';
3
+ import { multicall } from '../../../utils/multicall';
4
+ import { parseBorrowPosition } from './borrowPositionParser';
5
+ import { deriveTroveId, formatTroveId, MAX_SAFE_INTEGER_BIGINT, parseTroveId, requireAddress, requireNonNegativeBigInt, } from './borrowValidation';
6
+ const TROVE_ID_BATCH_SIZE = 64;
7
+ const TROVE_OWNER_BATCH_SIZE = 64;
8
+ const TROVE_DETAIL_BATCH_SIZE = 64;
9
+ const OWNER_INDEX_PROBE_BATCH_SIZE = 64;
10
+ export class BorrowReadService {
11
+ constructor(publicClient) {
12
+ this.publicClient = publicClient;
13
+ }
14
+ async getTroveData(ctx, troveId) {
15
+ const parsedTroveId = parseTroveId(troveId);
16
+ const [latestData, trovesData] = await this.readContractsInChunks([
17
+ {
18
+ address: ctx.addresses.troveManager,
19
+ abi: TROVE_MANAGER_ABI,
20
+ functionName: 'getLatestTroveData',
21
+ args: [parsedTroveId],
22
+ },
23
+ {
24
+ address: ctx.addresses.troveManager,
25
+ abi: TROVE_MANAGER_ABI,
26
+ functionName: 'Troves',
27
+ args: [parsedTroveId],
28
+ },
29
+ ], 2);
30
+ return parseBorrowPosition(formatTroveId(parsedTroveId), latestData, trovesData);
31
+ }
32
+ async getUserTroves(ctx, owner) {
33
+ const ownerAddress = requireAddress(owner, 'owner');
34
+ const ownedTroveCount = await this.getOwnedTroveCount(ctx, ownerAddress);
35
+ if (ownedTroveCount === 0) {
36
+ return [];
37
+ }
38
+ const troveCount = (await this.publicClient.readContract({
39
+ address: ctx.addresses.troveManager,
40
+ abi: TROVE_MANAGER_ABI,
41
+ functionName: 'getTroveIdsCount',
42
+ args: [],
43
+ }));
44
+ if (troveCount === 0n) {
45
+ return [];
46
+ }
47
+ const troveIdContracts = [];
48
+ for (let i = 0n; i < troveCount; i++) {
49
+ troveIdContracts.push({
50
+ address: ctx.addresses.troveManager,
51
+ abi: TROVE_MANAGER_ABI,
52
+ functionName: 'getTroveFromTroveIdsArray',
53
+ args: [i],
54
+ });
55
+ }
56
+ const troveIds = (await this.readContractsInChunks(troveIdContracts, TROVE_ID_BATCH_SIZE)).map((troveId) => troveId);
57
+ const ownerContracts = troveIds.map((troveId) => ({
58
+ address: ctx.addresses.troveNFT,
59
+ abi: TROVE_NFT_ABI,
60
+ functionName: 'ownerOf',
61
+ args: [troveId],
62
+ }));
63
+ const troveOwners = await this.readContractsInChunks(ownerContracts, TROVE_OWNER_BATCH_SIZE);
64
+ const matchedTroveIds = troveIds.filter((troveId, index) => troveOwners[index].toLowerCase() === ownerAddress.toLowerCase());
65
+ if (matchedTroveIds.length === 0) {
66
+ return [];
67
+ }
68
+ const troveDetailContracts = matchedTroveIds.flatMap((troveId) => ([
69
+ {
70
+ address: ctx.addresses.troveManager,
71
+ abi: TROVE_MANAGER_ABI,
72
+ functionName: 'getLatestTroveData',
73
+ args: [troveId],
74
+ },
75
+ {
76
+ address: ctx.addresses.troveManager,
77
+ abi: TROVE_MANAGER_ABI,
78
+ functionName: 'Troves',
79
+ args: [troveId],
80
+ },
81
+ ]));
82
+ const detailResults = await this.readContractsInChunks(troveDetailContracts, TROVE_DETAIL_BATCH_SIZE * 2);
83
+ return matchedTroveIds.map((troveId, index) => {
84
+ const offset = index * 2;
85
+ return parseBorrowPosition(formatTroveId(troveId), detailResults[offset], detailResults[offset + 1]);
86
+ });
87
+ }
88
+ async getCollateralPrice(ctx) {
89
+ return (await this.publicClient.readContract({
90
+ address: ctx.addresses.priceFeed,
91
+ abi: PRICE_FEED_ABI,
92
+ functionName: 'fetchPrice',
93
+ args: [],
94
+ }));
95
+ }
96
+ async isSystemShutDown(ctx) {
97
+ return (await this.publicClient.readContract({
98
+ address: ctx.addresses.borrowerOperations,
99
+ abi: BORROWER_OPERATIONS_ABI,
100
+ functionName: 'hasBeenShutDown',
101
+ args: [],
102
+ }));
103
+ }
104
+ async getBranchStats(ctx) {
105
+ const [totalColl, totalDebt] = await Promise.all([
106
+ this.publicClient.readContract({
107
+ address: ctx.addresses.borrowerOperations,
108
+ abi: BORROWER_OPERATIONS_ABI,
109
+ functionName: 'getEntireBranchColl',
110
+ args: [],
111
+ }),
112
+ this.publicClient.readContract({
113
+ address: ctx.addresses.borrowerOperations,
114
+ abi: BORROWER_OPERATIONS_ABI,
115
+ functionName: 'getEntireBranchDebt',
116
+ args: [],
117
+ }),
118
+ ]);
119
+ return { totalColl: totalColl, totalDebt: totalDebt };
120
+ }
121
+ async getInterestRateBrackets(ctx) {
122
+ const result = (await this.publicClient.readContract({
123
+ address: ctx.addresses.multiTroveGetter,
124
+ abi: MULTI_TROVE_GETTER_ABI,
125
+ functionName: 'getDebtPerInterestRateAscending',
126
+ args: [COLL_INDEX, 0n, 500n],
127
+ }));
128
+ const entries = result[0] ?? [];
129
+ const grouped = new Map();
130
+ for (const item of entries) {
131
+ const rate = requireNonNegativeBigInt(item.interestRate, 'interestRate');
132
+ const debt = requireNonNegativeBigInt(item.debt, 'debt');
133
+ const key = rate.toString();
134
+ grouped.set(key, (grouped.get(key) ?? 0n) + debt);
135
+ }
136
+ return Array.from(grouped.entries())
137
+ .map(([rate, totalDebt]) => ({
138
+ rate: BigInt(rate),
139
+ totalDebt,
140
+ }))
141
+ .sort((a, b) => (a.rate < b.rate ? -1 : a.rate > b.rate ? 1 : 0));
142
+ }
143
+ async getAverageInterestRate(ctx) {
144
+ const brackets = await this.getInterestRateBrackets(ctx);
145
+ if (brackets.length === 0)
146
+ return 0n;
147
+ let weightedRateSum = 0n;
148
+ let totalDebt = 0n;
149
+ for (const bracket of brackets) {
150
+ weightedRateSum += bracket.rate * bracket.totalDebt;
151
+ totalDebt += bracket.totalDebt;
152
+ }
153
+ return totalDebt === 0n ? 0n : weightedRateSum / totalDebt;
154
+ }
155
+ async getBatchManagerInfo(ctx, address) {
156
+ const batchManagerAddress = requireAddress(address, 'address');
157
+ const exists = (await this.publicClient.readContract({
158
+ address: ctx.addresses.borrowerOperations,
159
+ abi: BORROWER_OPERATIONS_ABI,
160
+ functionName: 'checkBatchManagerExists',
161
+ args: [batchManagerAddress],
162
+ }));
163
+ if (!exists)
164
+ return null;
165
+ const manager = (await this.publicClient.readContract({
166
+ address: ctx.addresses.borrowerOperations,
167
+ abi: BORROWER_OPERATIONS_ABI,
168
+ functionName: 'getInterestBatchManager',
169
+ args: [batchManagerAddress],
170
+ }));
171
+ return {
172
+ minRate: requireNonNegativeBigInt(manager.minInterestRate, 'minInterestRate'),
173
+ maxRate: requireNonNegativeBigInt(manager.maxInterestRate, 'maxInterestRate'),
174
+ minChangePeriod: requireNonNegativeBigInt(manager.minInterestRateChangePeriod, 'minInterestRateChangePeriod'),
175
+ };
176
+ }
177
+ async predictOpenTroveUpfrontFee(ctx, amount, rate) {
178
+ const borrowedAmount = requireNonNegativeBigInt(amount, 'amount');
179
+ const annualInterestRate = requireNonNegativeBigInt(rate, 'rate');
180
+ return (await this.publicClient.readContract({
181
+ address: ctx.addresses.hintHelpers,
182
+ abi: HINT_HELPERS_ABI,
183
+ functionName: 'predictOpenTroveUpfrontFee',
184
+ args: [COLL_INDEX, borrowedAmount, annualInterestRate],
185
+ }));
186
+ }
187
+ async predictAdjustUpfrontFee(ctx, troveId, debtIncrease) {
188
+ const parsedTroveId = parseTroveId(troveId);
189
+ const debtIncreaseAmount = requireNonNegativeBigInt(debtIncrease, 'debtIncrease');
190
+ return (await this.publicClient.readContract({
191
+ address: ctx.addresses.hintHelpers,
192
+ abi: HINT_HELPERS_ABI,
193
+ functionName: 'predictAdjustTroveUpfrontFee',
194
+ args: [COLL_INDEX, parsedTroveId, debtIncreaseAmount],
195
+ }));
196
+ }
197
+ async predictAdjustInterestRateUpfrontFee(ctx, troveId, newRate) {
198
+ const parsedTroveId = parseTroveId(troveId);
199
+ const newAnnualInterestRate = requireNonNegativeBigInt(newRate, 'newRate');
200
+ return (await this.publicClient.readContract({
201
+ address: ctx.addresses.hintHelpers,
202
+ abi: HINT_HELPERS_ABI,
203
+ functionName: 'predictAdjustInterestRateUpfrontFee',
204
+ args: [COLL_INDEX, parsedTroveId, newAnnualInterestRate],
205
+ }));
206
+ }
207
+ async predictJoinBatchUpfrontFee(ctx, troveId, batchAddress) {
208
+ const parsedTroveId = parseTroveId(troveId);
209
+ const managerAddress = requireAddress(batchAddress, 'batchAddress');
210
+ return (await this.publicClient.readContract({
211
+ address: ctx.addresses.hintHelpers,
212
+ abi: HINT_HELPERS_ABI,
213
+ functionName: 'predictJoinBatchInterestRateUpfrontFee',
214
+ args: [COLL_INDEX, parsedTroveId, managerAddress],
215
+ }));
216
+ }
217
+ async getOwnedTroveCount(ctx, owner) {
218
+ const ownerAddress = requireAddress(owner, 'owner');
219
+ const ownerTroveCount = (await this.publicClient.readContract({
220
+ address: ctx.addresses.troveNFT,
221
+ abi: TROVE_NFT_ABI,
222
+ functionName: 'balanceOf',
223
+ args: [ownerAddress],
224
+ }));
225
+ if (ownerTroveCount > MAX_SAFE_INTEGER_BIGINT) {
226
+ throw new Error('Owner trove count exceeds Number.MAX_SAFE_INTEGER');
227
+ }
228
+ return Number(ownerTroveCount);
229
+ }
230
+ async findNextAvailableOwnerIndex(ctx, owner, opener) {
231
+ const ownerAddress = requireAddress(owner, 'owner');
232
+ const openerAddress = requireAddress(opener, 'opener');
233
+ let candidateIndex = await this.getOwnedTroveCount(ctx, ownerAddress);
234
+ while (candidateIndex <= Number.MAX_SAFE_INTEGER) {
235
+ const batchIndices = Array.from({ length: Math.min(OWNER_INDEX_PROBE_BATCH_SIZE, Number.MAX_SAFE_INTEGER - candidateIndex + 1) }, (_, offset) => candidateIndex + offset);
236
+ const statusContracts = batchIndices.map((ownerIndex) => ({
237
+ address: ctx.addresses.troveManager,
238
+ abi: TROVE_MANAGER_ABI,
239
+ functionName: 'getTroveStatus',
240
+ args: [deriveTroveId(openerAddress, ownerAddress, ownerIndex)],
241
+ }));
242
+ const statuses = await this.readContractsInChunks(statusContracts, OWNER_INDEX_PROBE_BATCH_SIZE);
243
+ const availableOffset = statuses.findIndex((status) => status === 0 || status === 0n);
244
+ if (availableOffset !== -1) {
245
+ return batchIndices[availableOffset];
246
+ }
247
+ candidateIndex += batchIndices.length;
248
+ }
249
+ throw new Error('Next available owner index exceeds Number.MAX_SAFE_INTEGER');
250
+ }
251
+ async getNextOwnerIndex(ctx, owner) {
252
+ return this.getOwnedTroveCount(ctx, owner);
253
+ }
254
+ async readContractsInChunks(contracts, chunkSize) {
255
+ if (contracts.length === 0) {
256
+ return [];
257
+ }
258
+ const results = [];
259
+ for (let index = 0; index < contracts.length; index += chunkSize) {
260
+ const chunk = contracts.slice(index, index + chunkSize);
261
+ const chunkResults = await multicall(this.publicClient, chunk, { allowFailure: false });
262
+ for (const result of chunkResults) {
263
+ if (result.status === 'failure') {
264
+ throw result.error;
265
+ }
266
+ results.push(result.result);
267
+ }
268
+ }
269
+ return results;
270
+ }
271
+ }
@@ -0,0 +1,108 @@
1
+ import { ADDRESSES_REGISTRY_ABI, BORROWER_OPERATIONS_ABI, SYSTEM_PARAMS_ABI, } from '../../../core/abis';
2
+ import { multicall } from '../../../utils/multicall';
3
+ import { validateAddress } from '../../../utils/validation';
4
+ function readNoArgsContract(publicClient, address, abi, functionName) {
5
+ const readContract = publicClient.readContract;
6
+ return readContract({ address, abi, functionName, args: [] });
7
+ }
8
+ async function readNoArgsContracts(publicClient, contracts) {
9
+ if (contracts.length === 0) {
10
+ return [];
11
+ }
12
+ const results = await multicall(publicClient, contracts.map((contract) => ({
13
+ ...contract,
14
+ abi: contract.abi,
15
+ args: [],
16
+ })), { allowFailure: false });
17
+ return results.map((result) => {
18
+ if (result.status === 'failure') {
19
+ throw result.error;
20
+ }
21
+ return result.result;
22
+ });
23
+ }
24
+ function requireAddress(value, fieldName) {
25
+ if (typeof value !== 'string') {
26
+ throw new Error(`${fieldName} must be a string address`);
27
+ }
28
+ validateAddress(value, fieldName);
29
+ return value;
30
+ }
31
+ function requireBigInt(value, fieldName) {
32
+ if (typeof value !== 'bigint') {
33
+ throw new Error(`${fieldName} must be a bigint`);
34
+ }
35
+ if (value < 0n) {
36
+ throw new Error(`${fieldName} cannot be negative`);
37
+ }
38
+ return value;
39
+ }
40
+ export async function resolveAddressesFromRegistry(publicClient, registryAddress) {
41
+ validateAddress(registryAddress, 'registryAddress');
42
+ const registry = registryAddress;
43
+ const [borrowerOperationsRaw, troveManagerRaw, sortedTrovesRaw, activePoolRaw, defaultPoolRaw, hintHelpersRaw, multiTroveGetterRaw, collTokenRaw, debtTokenRaw, troveNFTRaw, metadataNFTRaw, stabilityPoolRaw, priceFeedRaw, collSurplusPoolRaw, interestRouterRaw, collateralRegistryRaw, gasTokenRaw, gasPoolAddressRaw, liquidityStrategyRaw,] = await readNoArgsContracts(publicClient, [
44
+ { address: registry, abi: ADDRESSES_REGISTRY_ABI, functionName: 'borrowerOperations' },
45
+ { address: registry, abi: ADDRESSES_REGISTRY_ABI, functionName: 'troveManager' },
46
+ { address: registry, abi: ADDRESSES_REGISTRY_ABI, functionName: 'sortedTroves' },
47
+ { address: registry, abi: ADDRESSES_REGISTRY_ABI, functionName: 'activePool' },
48
+ { address: registry, abi: ADDRESSES_REGISTRY_ABI, functionName: 'defaultPool' },
49
+ { address: registry, abi: ADDRESSES_REGISTRY_ABI, functionName: 'hintHelpers' },
50
+ { address: registry, abi: ADDRESSES_REGISTRY_ABI, functionName: 'multiTroveGetter' },
51
+ { address: registry, abi: ADDRESSES_REGISTRY_ABI, functionName: 'collToken' },
52
+ { address: registry, abi: ADDRESSES_REGISTRY_ABI, functionName: 'boldToken' },
53
+ { address: registry, abi: ADDRESSES_REGISTRY_ABI, functionName: 'troveNFT' },
54
+ { address: registry, abi: ADDRESSES_REGISTRY_ABI, functionName: 'metadataNFT' },
55
+ { address: registry, abi: ADDRESSES_REGISTRY_ABI, functionName: 'stabilityPool' },
56
+ { address: registry, abi: ADDRESSES_REGISTRY_ABI, functionName: 'priceFeed' },
57
+ { address: registry, abi: ADDRESSES_REGISTRY_ABI, functionName: 'collSurplusPool' },
58
+ { address: registry, abi: ADDRESSES_REGISTRY_ABI, functionName: 'interestRouter' },
59
+ { address: registry, abi: ADDRESSES_REGISTRY_ABI, functionName: 'collateralRegistry' },
60
+ { address: registry, abi: ADDRESSES_REGISTRY_ABI, functionName: 'gasToken' },
61
+ { address: registry, abi: ADDRESSES_REGISTRY_ABI, functionName: 'gasPoolAddress' },
62
+ { address: registry, abi: ADDRESSES_REGISTRY_ABI, functionName: 'liquidityStrategy' },
63
+ ]);
64
+ return {
65
+ borrowerOperations: requireAddress(borrowerOperationsRaw, 'borrowerOperations'),
66
+ troveManager: requireAddress(troveManagerRaw, 'troveManager'),
67
+ sortedTroves: requireAddress(sortedTrovesRaw, 'sortedTroves'),
68
+ activePool: requireAddress(activePoolRaw, 'activePool'),
69
+ defaultPool: requireAddress(defaultPoolRaw, 'defaultPool'),
70
+ hintHelpers: requireAddress(hintHelpersRaw, 'hintHelpers'),
71
+ multiTroveGetter: requireAddress(multiTroveGetterRaw, 'multiTroveGetter'),
72
+ collToken: requireAddress(collTokenRaw, 'collToken'),
73
+ debtToken: requireAddress(debtTokenRaw, 'debtToken'),
74
+ troveNFT: requireAddress(troveNFTRaw, 'troveNFT'),
75
+ metadataNFT: requireAddress(metadataNFTRaw, 'metadataNFT'),
76
+ stabilityPool: requireAddress(stabilityPoolRaw, 'stabilityPool'),
77
+ priceFeed: requireAddress(priceFeedRaw, 'priceFeed'),
78
+ collSurplusPool: requireAddress(collSurplusPoolRaw, 'collSurplusPool'),
79
+ interestRouter: requireAddress(interestRouterRaw, 'interestRouter'),
80
+ collateralRegistry: requireAddress(collateralRegistryRaw, 'collateralRegistry'),
81
+ gasToken: requireAddress(gasTokenRaw, 'gasToken'),
82
+ gasPoolAddress: requireAddress(gasPoolAddressRaw, 'gasPoolAddress'),
83
+ liquidityStrategy: requireAddress(liquidityStrategyRaw, 'liquidityStrategy'),
84
+ };
85
+ }
86
+ export async function readSystemParams(publicClient, borrowerOperations) {
87
+ validateAddress(borrowerOperations, 'borrowerOperations');
88
+ const systemParamsAddressRaw = await readNoArgsContract(publicClient, borrowerOperations, BORROWER_OPERATIONS_ABI, 'systemParams');
89
+ const systemParamsAddress = requireAddress(systemParamsAddressRaw, 'systemParamsAddress');
90
+ const [ccrRaw, mcrRaw, scrRaw, bcrRaw, minDebtRaw, ethGasCompensationRaw, minAnnualInterestRateRaw,] = await readNoArgsContracts(publicClient, [
91
+ { address: systemParamsAddress, abi: SYSTEM_PARAMS_ABI, functionName: 'CCR' },
92
+ { address: systemParamsAddress, abi: SYSTEM_PARAMS_ABI, functionName: 'MCR' },
93
+ { address: systemParamsAddress, abi: SYSTEM_PARAMS_ABI, functionName: 'SCR' },
94
+ { address: systemParamsAddress, abi: SYSTEM_PARAMS_ABI, functionName: 'BCR' },
95
+ { address: systemParamsAddress, abi: SYSTEM_PARAMS_ABI, functionName: 'MIN_DEBT' },
96
+ { address: systemParamsAddress, abi: SYSTEM_PARAMS_ABI, functionName: 'ETH_GAS_COMPENSATION' },
97
+ { address: systemParamsAddress, abi: SYSTEM_PARAMS_ABI, functionName: 'MIN_ANNUAL_INTEREST_RATE' },
98
+ ]);
99
+ return {
100
+ mcr: requireBigInt(mcrRaw, 'MCR'),
101
+ ccr: requireBigInt(ccrRaw, 'CCR'),
102
+ scr: requireBigInt(scrRaw, 'SCR'),
103
+ bcr: requireBigInt(bcrRaw, 'BCR'),
104
+ minDebt: requireBigInt(minDebtRaw, 'MIN_DEBT'),
105
+ ethGasCompensation: requireBigInt(ethGasCompensationRaw, 'ETH_GAS_COMPENSATION'),
106
+ minAnnualInterestRate: requireBigInt(minAnnualInterestRateRaw, 'MIN_ANNUAL_INTEREST_RATE'),
107
+ };
108
+ }