@defisaver/positions-sdk 2.0.0 → 2.0.4

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 (84) hide show
  1. package/.mocharc.json +4 -4
  2. package/.nvmrc +1 -1
  3. package/README.md +64 -64
  4. package/cjs/fluid/index.js +2 -1
  5. package/cjs/helpers/compoundHelpers/index.js +2 -2
  6. package/cjs/helpers/morphoBlueHelpers/index.js +156 -139
  7. package/cjs/markets/aave/marketAssets.js +1 -1
  8. package/cjs/services/utils.d.ts +1 -0
  9. package/cjs/services/utils.js +2 -1
  10. package/cjs/staking/staking.js +43 -23
  11. package/cjs/types/compound.d.ts +2 -0
  12. package/esm/fluid/index.js +3 -2
  13. package/esm/helpers/compoundHelpers/index.js +2 -2
  14. package/esm/helpers/morphoBlueHelpers/index.js +157 -140
  15. package/esm/markets/aave/marketAssets.js +1 -1
  16. package/esm/services/utils.d.ts +1 -0
  17. package/esm/services/utils.js +1 -0
  18. package/esm/staking/staking.js +43 -23
  19. package/esm/types/compound.d.ts +2 -0
  20. package/package.json +47 -47
  21. package/src/aaveV2/index.ts +236 -236
  22. package/src/aaveV3/index.ts +489 -489
  23. package/src/compoundV2/index.ts +240 -240
  24. package/src/compoundV3/index.ts +270 -270
  25. package/src/config/contracts.ts +1082 -1082
  26. package/src/constants/index.ts +6 -6
  27. package/src/contracts.ts +107 -107
  28. package/src/curveUsd/index.ts +250 -250
  29. package/src/eulerV2/index.ts +314 -314
  30. package/src/exchange/index.ts +25 -25
  31. package/src/fluid/index.ts +1568 -1564
  32. package/src/helpers/aaveHelpers/index.ts +170 -170
  33. package/src/helpers/compoundHelpers/index.ts +261 -250
  34. package/src/helpers/curveUsdHelpers/index.ts +40 -40
  35. package/src/helpers/eulerHelpers/index.ts +259 -259
  36. package/src/helpers/fluidHelpers/index.ts +324 -324
  37. package/src/helpers/index.ts +10 -10
  38. package/src/helpers/liquityV2Helpers/index.ts +80 -80
  39. package/src/helpers/llamaLendHelpers/index.ts +53 -53
  40. package/src/helpers/makerHelpers/index.ts +52 -52
  41. package/src/helpers/morphoBlueHelpers/index.ts +390 -375
  42. package/src/helpers/sparkHelpers/index.ts +155 -155
  43. package/src/index.ts +45 -45
  44. package/src/liquity/index.ts +104 -104
  45. package/src/liquityV2/index.ts +408 -408
  46. package/src/llamaLend/index.ts +296 -296
  47. package/src/maker/index.ts +223 -223
  48. package/src/markets/aave/index.ts +116 -116
  49. package/src/markets/aave/marketAssets.ts +44 -44
  50. package/src/markets/compound/index.ts +216 -216
  51. package/src/markets/compound/marketsAssets.ts +83 -83
  52. package/src/markets/curveUsd/index.ts +69 -69
  53. package/src/markets/euler/index.ts +26 -26
  54. package/src/markets/fluid/index.ts +2456 -2456
  55. package/src/markets/index.ts +25 -25
  56. package/src/markets/liquityV2/index.ts +102 -102
  57. package/src/markets/llamaLend/contractAddresses.ts +141 -141
  58. package/src/markets/llamaLend/index.ts +235 -235
  59. package/src/markets/morphoBlue/index.ts +895 -895
  60. package/src/markets/spark/index.ts +29 -29
  61. package/src/markets/spark/marketAssets.ts +10 -10
  62. package/src/moneymarket/moneymarketCommonService.ts +80 -80
  63. package/src/morphoBlue/index.ts +222 -222
  64. package/src/portfolio/index.ts +285 -285
  65. package/src/services/priceService.ts +159 -159
  66. package/src/services/utils.ts +64 -62
  67. package/src/services/viem.ts +30 -30
  68. package/src/setup.ts +8 -8
  69. package/src/spark/index.ts +456 -456
  70. package/src/staking/staking.ts +192 -173
  71. package/src/types/aave.ts +194 -194
  72. package/src/types/common.ts +87 -87
  73. package/src/types/compound.ts +136 -134
  74. package/src/types/curveUsd.ts +121 -121
  75. package/src/types/euler.ts +174 -174
  76. package/src/types/fluid.ts +450 -450
  77. package/src/types/index.ts +11 -11
  78. package/src/types/liquity.ts +30 -30
  79. package/src/types/liquityV2.ts +126 -126
  80. package/src/types/llamaLend.ts +157 -157
  81. package/src/types/maker.ts +63 -63
  82. package/src/types/morphoBlue.ts +194 -194
  83. package/src/types/portfolio.ts +60 -60
  84. package/src/types/spark.ts +137 -137
package/.mocharc.json CHANGED
@@ -1,4 +1,4 @@
1
- {
2
- "require": "ts-node/register",
3
- "extension": ["ts"]
4
- }
1
+ {
2
+ "require": "ts-node/register",
3
+ "extension": ["ts"]
4
+ }
package/.nvmrc CHANGED
@@ -1 +1 @@
1
- v20.17.0
1
+ v20.17.0
package/README.md CHANGED
@@ -1,64 +1,64 @@
1
- # DeFi Saver Positions SDK
2
-
3
- Supported protocols:
4
- - [Maker](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/maker)
5
- - [Spark](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/spark)
6
- - [CrvUSD](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/curveUsd)
7
- - [Aave V2](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/aaveV2)
8
- - [Aave V3](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/aaveV3)
9
- - [Compound V2](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/compoundV2)
10
- - [Compound V3](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/compoundV3)
11
- - [Liquity](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/liquity)
12
-
13
- ## Setup
14
- Supported Node version is v10.
15
-
16
- - run `npm install` (first time)
17
- - run `npm run build`
18
-
19
- `build` command will generate contracts and build ejs and esm folders
20
-
21
- ## How to use
22
- [All available imports](https://github.com/defisaver/defisaver-positions-sdk/blob/main/src/index.ts)
23
-
24
- This is a Compound V3 example, and every other protocol is similar
25
- ```js
26
- import { compoundV3 } from '@defisaver/positions-sdk';
27
-
28
-
29
- // every protocol has market data and user data getters
30
- const {
31
- getCompoundV3MarketsData,
32
- getCompoundV3AccountData,
33
- } = compoundV3;
34
-
35
- const provider = 'Your RPC provider';
36
-
37
- const user = '0x123...';
38
-
39
- const { assetsData } = await getCompoundV3MarketsData(
40
- provider, // rpc for the network you are using (note: can be tenderly or any other testnet rpc)
41
- 1, // network
42
- selectedMarket, // market object like in /src/markets/compound/index.ts
43
- provider, // this must be mainnet rpc - used for getting prices onchain and calculating apys
44
- );
45
-
46
- const userData = await getCompoundV3AccountData(
47
- provider,
48
- 1, // network
49
- userAddress, // EOA or DSProxy
50
- '', // proxy address of the user, or just empty string if checking for EOA
51
- {
52
- selectedMarket, // market object as in /src/markets/compound/index.ts
53
- assetsData,
54
- }
55
- );
56
- ```
57
-
58
- More examples found [here](https://github.com/defisaver/defisaver-positions-sdk/tree/main/tests)
59
-
60
- ## Testing
61
-
62
- `npm run test` - Run all tests
63
-
64
- `npm run test-single --name=your_test_name` - Run single test for specified name e.g. for MyTest.js test name is MyTest
1
+ # DeFi Saver Positions SDK
2
+
3
+ Supported protocols:
4
+ - [Maker](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/maker)
5
+ - [Spark](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/spark)
6
+ - [CrvUSD](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/curveUsd)
7
+ - [Aave V2](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/aaveV2)
8
+ - [Aave V3](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/aaveV3)
9
+ - [Compound V2](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/compoundV2)
10
+ - [Compound V3](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/compoundV3)
11
+ - [Liquity](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/liquity)
12
+
13
+ ## Setup
14
+ Supported Node version is v10.
15
+
16
+ - run `npm install` (first time)
17
+ - run `npm run build`
18
+
19
+ `build` command will generate contracts and build ejs and esm folders
20
+
21
+ ## How to use
22
+ [All available imports](https://github.com/defisaver/defisaver-positions-sdk/blob/main/src/index.ts)
23
+
24
+ This is a Compound V3 example, and every other protocol is similar
25
+ ```js
26
+ import { compoundV3 } from '@defisaver/positions-sdk';
27
+
28
+
29
+ // every protocol has market data and user data getters
30
+ const {
31
+ getCompoundV3MarketsData,
32
+ getCompoundV3AccountData,
33
+ } = compoundV3;
34
+
35
+ const provider = 'Your RPC provider';
36
+
37
+ const user = '0x123...';
38
+
39
+ const { assetsData } = await getCompoundV3MarketsData(
40
+ provider, // rpc for the network you are using (note: can be tenderly or any other testnet rpc)
41
+ 1, // network
42
+ selectedMarket, // market object like in /src/markets/compound/index.ts
43
+ provider, // this must be mainnet rpc - used for getting prices onchain and calculating apys
44
+ );
45
+
46
+ const userData = await getCompoundV3AccountData(
47
+ provider,
48
+ 1, // network
49
+ userAddress, // EOA or DSProxy
50
+ '', // proxy address of the user, or just empty string if checking for EOA
51
+ {
52
+ selectedMarket, // market object as in /src/markets/compound/index.ts
53
+ assetsData,
54
+ }
55
+ );
56
+ ```
57
+
58
+ More examples found [here](https://github.com/defisaver/defisaver-positions-sdk/tree/main/tests)
59
+
60
+ ## Testing
61
+
62
+ `npm run test` - Run all tests
63
+
64
+ `npm run test-single --name=your_test_name` - Run single test for specified name e.g. for MyTest.js test name is MyTest
@@ -199,9 +199,10 @@ const getAdditionalMarketRateForDex = (token1PerShare, token0PerShare, incentive
199
199
  const getTradingApy = (poolAddress) => __awaiter(void 0, void 0, void 0, function* () {
200
200
  let res;
201
201
  try {
202
- res = yield fetch(`https://api.fluid.instadapp.io/v2/1/dexes/${poolAddress}/apy`, { signal: AbortSignal.timeout(2000) });
202
+ res = yield fetch(`https://api.fluid.instadapp.io/v2/1/dexes/${poolAddress}/apy`, { signal: AbortSignal.timeout(utils_1.DEFAULT_TIMEOUT) });
203
203
  }
204
204
  catch (e) {
205
+ console.error('External API Failure: Fluid Trading Apy');
205
206
  return '0';
206
207
  }
207
208
  if (!res.ok) {
@@ -38,7 +38,7 @@ const formatMarketData = (data, network, baseAssetPrice) => {
38
38
  const assetInfo = (0, tokens_1.getAssetInfoByAddress)(data.tokenAddr, network);
39
39
  const isWETH = assetInfo.symbol === 'WETH';
40
40
  const price = (0, utils_1.getEthAmountForDecimals)(data.price, 8);
41
- return (Object.assign(Object.assign({}, data), { priceInBaseAsset: (0, utils_1.getEthAmountForDecimals)(data.price, 8), price: new decimal_js_1.default(price).mul(baseAssetPrice).toString(), collateralFactor: (0, utils_1.getEthAmountForDecimals)(data.borrowCollateralFactor, 18), liquidationRatio: (0, utils_1.getEthAmountForDecimals)(data.liquidateCollateralFactor, 18), supplyCap: (0, utils_1.getEthAmountForDecimals)(data.supplyCap, assetInfo.decimals), totalSupply: (0, utils_1.getEthAmountForDecimals)(data.totalSupply, assetInfo.decimals), symbol: isWETH ? 'ETH' : assetInfo.symbol, supplyRate: '0', borrowRate: '0', canBeBorrowed: false, canBeSupplied: true }));
41
+ return (Object.assign(Object.assign({}, data), { borrowCollateralFactor: data.borrowCollateralFactor.toString(), liquidateCollateralFactor: data.liquidateCollateralFactor.toString(), liquidationFactor: data.liquidationFactor.toString(), supplyReserved: data.supplyReserved.toString(), priceInBaseAsset: (0, utils_1.getEthAmountForDecimals)(data.price, 8), price: new decimal_js_1.default(price).mul(baseAssetPrice).toString(), collateralFactor: (0, utils_1.getEthAmountForDecimals)(data.borrowCollateralFactor, 18), liquidationRatio: (0, utils_1.getEthAmountForDecimals)(data.liquidateCollateralFactor, 18), supplyCap: (0, utils_1.getEthAmountForDecimals)(data.supplyCap, assetInfo.decimals), totalSupply: (0, utils_1.getEthAmountForDecimals)(data.totalSupply, assetInfo.decimals), symbol: isWETH ? 'ETH' : assetInfo.symbol, supplyRate: '0', borrowRate: '0', canBeBorrowed: false, canBeSupplied: true }));
42
42
  };
43
43
  exports.formatMarketData = formatMarketData;
44
44
  // TODO: maybe not hardcode decimals
@@ -46,7 +46,7 @@ const formatBaseData = (data, network, baseAssetPrice) => {
46
46
  const assetInfo = (0, tokens_1.getAssetInfoByAddress)(data.tokenAddr, network);
47
47
  const totalSupply = (0, utils_1.getEthAmountForDecimals)(new decimal_js_1.default(data.totalSupply).mul(data.supplyIndex).toString(), 15 + assetInfo.decimals);
48
48
  const totalBorrow = (0, utils_1.getEthAmountForDecimals)(new decimal_js_1.default(data.totalBorrow).mul(data.borrowIndex).toString(), 15 + assetInfo.decimals);
49
- return (Object.assign(Object.assign({}, data), { supplyRate: (0, moneymarket_1.aprToApy)(new decimal_js_1.default(data.supplyRate).div(1e18).mul(constants_1.SECONDS_PER_YEAR).mul(100)
49
+ return (Object.assign(Object.assign({}, data), { baseBorrowMin: data.baseBorrowMin.toString(), baseTrackingBorrowRewardsSpeed: data.baseTrackingBorrowRewardsSpeed.toString(), baseTrackingSupplyRewardsSpeed: data.baseTrackingSupplyRewardsSpeed.toString(), borrowIndex: data.borrowIndex.toString(), supplyIndex: data.supplyIndex.toString(), trackingBorrowIndex: data.trackingBorrowIndex.toString(), trackingSupplyIndex: data.trackingSupplyIndex.toString(), supplyRate: (0, moneymarket_1.aprToApy)(new decimal_js_1.default(data.supplyRate).div(1e18).mul(constants_1.SECONDS_PER_YEAR).mul(100)
50
50
  .toString()), borrowRate: (0, moneymarket_1.aprToApy)(new decimal_js_1.default(data.borrowRate).div(1e18).mul(constants_1.SECONDS_PER_YEAR).mul(100)
51
51
  .toString()), utilization: (0, utils_1.getEthAmountForDecimals)(data.utilization, 16), // utilization is totalSupply/totalBorrow in 1e18, but we need % so when we mul with 100 it's 16 decimals
52
52
  totalSupply,
@@ -128,73 +128,73 @@ const getApyAfterValuesEstimation = (selectedMarket, actions, provider, network)
128
128
  });
129
129
  exports.getApyAfterValuesEstimation = getApyAfterValuesEstimation;
130
130
  const API_URL = 'https://blue-api.morpho.org/graphql';
131
- const MARKET_QUERY = `
132
- query MarketByUniqueKey($uniqueKey: String!, $chainId: Int!) {
133
- marketByUniqueKey(uniqueKey: $uniqueKey, chainId: $chainId) {
134
- reallocatableLiquidityAssets
135
- targetBorrowUtilization
136
- loanAsset {
137
- address
138
- decimals
139
- priceUsd
140
- }
141
- state {
142
- liquidityAssets
143
- borrowAssets
144
- supplyAssets
145
- }
146
- publicAllocatorSharedLiquidity {
147
- assets
148
- vault {
149
- address
150
- name
151
- }
152
- allocationMarket {
153
- uniqueKey
154
- loanAsset {
155
- address
156
- }
157
- collateralAsset {
158
- address
159
- }
160
- irmAddress
161
- oracle {
162
- address
163
- }
164
- lltv
165
- }
166
- }
167
- loanAsset {
168
- address
169
- }
170
- collateralAsset {
171
- address
172
- }
173
- oracle {
174
- address
175
- }
176
- irmAddress
177
- lltv
178
- }
179
- }
131
+ const MARKET_QUERY = `
132
+ query MarketByUniqueKey($uniqueKey: String!, $chainId: Int!) {
133
+ marketByUniqueKey(uniqueKey: $uniqueKey, chainId: $chainId) {
134
+ reallocatableLiquidityAssets
135
+ targetBorrowUtilization
136
+ loanAsset {
137
+ address
138
+ decimals
139
+ priceUsd
140
+ }
141
+ state {
142
+ liquidityAssets
143
+ borrowAssets
144
+ supplyAssets
145
+ }
146
+ publicAllocatorSharedLiquidity {
147
+ assets
148
+ vault {
149
+ address
150
+ name
151
+ }
152
+ allocationMarket {
153
+ uniqueKey
154
+ loanAsset {
155
+ address
156
+ }
157
+ collateralAsset {
158
+ address
159
+ }
160
+ irmAddress
161
+ oracle {
162
+ address
163
+ }
164
+ lltv
165
+ }
166
+ }
167
+ loanAsset {
168
+ address
169
+ }
170
+ collateralAsset {
171
+ address
172
+ }
173
+ oracle {
174
+ address
175
+ }
176
+ irmAddress
177
+ lltv
178
+ }
179
+ }
180
180
  `;
181
- const REWARDS_QUERY = `
182
- query MarketByUniqueKey($uniqueKey: String!, $chainId: Int!) {
183
- marketByUniqueKey(uniqueKey: $uniqueKey, chainId: $chainId) {
184
- uniqueKey
185
- state {
186
- rewards {
187
- amountPerSuppliedToken
188
- supplyApr
189
- amountPerBorrowedToken
190
- borrowApr
191
- asset {
192
- address
193
- }
194
- }
195
- }
196
- }
197
- }
181
+ const REWARDS_QUERY = `
182
+ query MarketByUniqueKey($uniqueKey: String!, $chainId: Int!) {
183
+ marketByUniqueKey(uniqueKey: $uniqueKey, chainId: $chainId) {
184
+ uniqueKey
185
+ state {
186
+ rewards {
187
+ amountPerSuppliedToken
188
+ supplyApr
189
+ amountPerBorrowedToken
190
+ borrowApr
191
+ asset {
192
+ address
193
+ }
194
+ }
195
+ }
196
+ }
197
+ }
198
198
  `;
199
199
  /**
200
200
  * Get reallocatable liquidity to a given market and target borrow utilization
@@ -204,19 +204,29 @@ const REWARDS_QUERY = `
204
204
  */
205
205
  const getReallocatableLiquidity = (marketId_1, ...args_1) => __awaiter(void 0, [marketId_1, ...args_1], void 0, function* (marketId, network = common_1.NetworkNumber.Eth) {
206
206
  var _a;
207
- const response = yield fetch(API_URL, {
208
- method: 'POST',
209
- headers: { 'Content-Type': 'application/json' },
210
- body: JSON.stringify({
211
- query: MARKET_QUERY,
212
- variables: { uniqueKey: marketId, chainId: network },
213
- }),
214
- });
215
- const data = yield response.json();
216
- const marketData = (_a = data === null || data === void 0 ? void 0 : data.data) === null || _a === void 0 ? void 0 : _a.marketByUniqueKey;
217
- if (!marketData)
218
- throw new Error('Market data not found');
219
- return { reallocatableLiquidity: marketData.reallocatableLiquidityAssets, targetBorrowUtilization: marketData.targetBorrowUtilization };
207
+ try {
208
+ const response = yield fetch(API_URL, {
209
+ method: 'POST',
210
+ headers: { 'Content-Type': 'application/json' },
211
+ body: JSON.stringify({
212
+ query: MARKET_QUERY,
213
+ variables: { uniqueKey: marketId, chainId: network },
214
+ }),
215
+ signal: AbortSignal.timeout(utils_1.DEFAULT_TIMEOUT),
216
+ });
217
+ const data = yield response.json();
218
+ const marketData = (_a = data === null || data === void 0 ? void 0 : data.data) === null || _a === void 0 ? void 0 : _a.marketByUniqueKey;
219
+ if (!marketData)
220
+ throw new Error('Market data not found');
221
+ return {
222
+ reallocatableLiquidity: marketData.reallocatableLiquidityAssets,
223
+ targetBorrowUtilization: marketData.targetBorrowUtilization,
224
+ };
225
+ }
226
+ catch (error) {
227
+ console.error('External API Failure: Morpho blue reallocatable liquidity', error);
228
+ throw new Error('Failed to fetch reallocatable liquidity');
229
+ }
220
230
  });
221
231
  exports.getReallocatableLiquidity = getReallocatableLiquidity;
222
232
  /**
@@ -257,71 +267,78 @@ exports.getLiquidityToAllocate = getLiquidityToAllocate;
257
267
  */
258
268
  const getReallocation = (market_1, assetsData_1, amountToBorrow_1, ...args_1) => __awaiter(void 0, [market_1, assetsData_1, amountToBorrow_1, ...args_1], void 0, function* (market, assetsData, amountToBorrow, network = common_1.NetworkNumber.Eth) {
259
269
  var _a, _b, _c;
260
- const { marketId, loanToken } = market;
261
- const response = yield fetch(API_URL, {
262
- method: 'POST',
263
- headers: { 'Content-Type': 'application/json' },
264
- body: JSON.stringify({
265
- query: MARKET_QUERY,
266
- variables: { uniqueKey: marketId, chainId: network },
267
- }),
268
- });
269
- const data = yield response.json();
270
- const marketData = (_a = data === null || data === void 0 ? void 0 : data.data) === null || _a === void 0 ? void 0 : _a.marketByUniqueKey;
271
- if (!marketData)
272
- throw new Error('Market data not found');
273
- const loanAssetInfo = (0, tokens_1.getAssetInfoByAddress)(loanToken, network);
274
- const { totalBorrow, totalSupply } = assetsData[loanAssetInfo.symbol] || { totalBorrow: '0', totalSupply: '0' };
275
- const totalBorrowWei = (0, tokens_1.assetAmountInWei)(totalBorrow, loanAssetInfo.symbol);
276
- const totalSupplyWei = (0, tokens_1.assetAmountInWei)(totalSupply, loanAssetInfo.symbol);
277
- const newTotalBorrowAssets = new decimal_js_1.default(totalBorrowWei).add(amountToBorrow).toString();
278
- const newUtil = new decimal_js_1.default(newTotalBorrowAssets).div(totalSupplyWei).toString();
279
- const newUtilScaled = new decimal_js_1.default(newUtil).mul(1e18).toString();
280
- if (new decimal_js_1.default(newUtilScaled).lt(marketData.targetBorrowUtilization))
281
- return { vaults: [], withdrawals: [] };
282
- const liquidityToAllocate = (0, exports.getLiquidityToAllocate)(amountToBorrow, totalBorrowWei, totalSupplyWei, marketData.targetBorrowUtilization, marketData.reallocatableLiquidityAssets);
283
- const vaultTotalAssets = marketData.publicAllocatorSharedLiquidity.reduce((acc, item) => {
284
- const vaultAddress = item.vault.address;
285
- acc[vaultAddress] = new decimal_js_1.default(acc[vaultAddress] || '0').add(item.assets).toString();
286
- return acc;
287
- }, {});
288
- const sortedVaults = Object.entries(vaultTotalAssets).sort(([, a], [, b]) => new decimal_js_1.default(b || '0').sub(a || '0').toNumber());
289
- const withdrawalsPerVault = {};
290
- let totalReallocated = '0';
291
- for (const [vaultAddress] of sortedVaults) {
292
- if (new decimal_js_1.default(totalReallocated).gte(liquidityToAllocate))
293
- break;
294
- const vaultAllocations = marketData.publicAllocatorSharedLiquidity.filter((item) => (0, utils_1.compareAddresses)(item.vault.address, vaultAddress));
295
- for (const item of vaultAllocations) {
270
+ try {
271
+ const { marketId, loanToken } = market;
272
+ const response = yield fetch(API_URL, {
273
+ method: 'POST',
274
+ headers: { 'Content-Type': 'application/json' },
275
+ body: JSON.stringify({
276
+ query: MARKET_QUERY,
277
+ variables: { uniqueKey: marketId, chainId: network },
278
+ }),
279
+ signal: AbortSignal.timeout(utils_1.DEFAULT_TIMEOUT),
280
+ });
281
+ const data = yield response.json();
282
+ const marketData = (_a = data === null || data === void 0 ? void 0 : data.data) === null || _a === void 0 ? void 0 : _a.marketByUniqueKey;
283
+ if (!marketData)
284
+ throw new Error('Market data not found');
285
+ const loanAssetInfo = (0, tokens_1.getAssetInfoByAddress)(loanToken, network);
286
+ const { totalBorrow, totalSupply } = assetsData[loanAssetInfo.symbol] || { totalBorrow: '0', totalSupply: '0' };
287
+ const totalBorrowWei = (0, tokens_1.assetAmountInWei)(totalBorrow, loanAssetInfo.symbol);
288
+ const totalSupplyWei = (0, tokens_1.assetAmountInWei)(totalSupply, loanAssetInfo.symbol);
289
+ const newTotalBorrowAssets = new decimal_js_1.default(totalBorrowWei).add(amountToBorrow).toString();
290
+ const newUtil = new decimal_js_1.default(newTotalBorrowAssets).div(totalSupplyWei).toString();
291
+ const newUtilScaled = new decimal_js_1.default(newUtil).mul(1e18).toString();
292
+ if (new decimal_js_1.default(newUtilScaled).lt(marketData.targetBorrowUtilization))
293
+ return { vaults: [], withdrawals: [] };
294
+ const liquidityToAllocate = (0, exports.getLiquidityToAllocate)(amountToBorrow, totalBorrowWei, totalSupplyWei, marketData.targetBorrowUtilization, marketData.reallocatableLiquidityAssets);
295
+ const vaultTotalAssets = marketData.publicAllocatorSharedLiquidity.reduce((acc, item) => {
296
+ const vaultAddress = item.vault.address;
297
+ acc[vaultAddress] = new decimal_js_1.default(acc[vaultAddress] || '0').add(item.assets).toString();
298
+ return acc;
299
+ }, {});
300
+ const sortedVaults = Object.entries(vaultTotalAssets).sort(([, a], [, b]) => new decimal_js_1.default(b || '0').sub(a || '0').toNumber());
301
+ const withdrawalsPerVault = {};
302
+ let totalReallocated = '0';
303
+ for (const [vaultAddress] of sortedVaults) {
296
304
  if (new decimal_js_1.default(totalReallocated).gte(liquidityToAllocate))
297
305
  break;
298
- const itemAmount = item.assets;
299
- const leftToAllocate = new decimal_js_1.default(liquidityToAllocate).sub(totalReallocated).toString();
300
- const amountToTake = new decimal_js_1.default(itemAmount).lt(leftToAllocate) ? itemAmount : leftToAllocate;
301
- totalReallocated = new decimal_js_1.default(totalReallocated).add(amountToTake).toString();
302
- const withdrawal = [
303
- [
304
- item.allocationMarket.loanAsset.address,
305
- (_b = item.allocationMarket.collateralAsset) === null || _b === void 0 ? void 0 : _b.address,
306
- (_c = item.allocationMarket.oracle) === null || _c === void 0 ? void 0 : _c.address,
307
- item.allocationMarket.irmAddress,
308
- item.allocationMarket.lltv,
309
- ],
310
- amountToTake.toString(),
311
- item.allocationMarket.uniqueKey,
312
- ];
313
- if (!withdrawalsPerVault[vaultAddress]) {
314
- withdrawalsPerVault[vaultAddress] = [];
306
+ const vaultAllocations = marketData.publicAllocatorSharedLiquidity.filter((item) => (0, utils_1.compareAddresses)(item.vault.address, vaultAddress));
307
+ for (const item of vaultAllocations) {
308
+ if (new decimal_js_1.default(totalReallocated).gte(liquidityToAllocate))
309
+ break;
310
+ const itemAmount = item.assets;
311
+ const leftToAllocate = new decimal_js_1.default(liquidityToAllocate).sub(totalReallocated).toString();
312
+ const amountToTake = new decimal_js_1.default(itemAmount).lt(leftToAllocate) ? itemAmount : leftToAllocate;
313
+ totalReallocated = new decimal_js_1.default(totalReallocated).add(amountToTake).toString();
314
+ const withdrawal = [
315
+ [
316
+ item.allocationMarket.loanAsset.address,
317
+ (_b = item.allocationMarket.collateralAsset) === null || _b === void 0 ? void 0 : _b.address,
318
+ (_c = item.allocationMarket.oracle) === null || _c === void 0 ? void 0 : _c.address,
319
+ item.allocationMarket.irmAddress,
320
+ item.allocationMarket.lltv,
321
+ ],
322
+ amountToTake.toString(),
323
+ item.allocationMarket.uniqueKey,
324
+ ];
325
+ if (!withdrawalsPerVault[vaultAddress]) {
326
+ withdrawalsPerVault[vaultAddress] = [];
327
+ }
328
+ withdrawalsPerVault[vaultAddress].push(withdrawal);
315
329
  }
316
- withdrawalsPerVault[vaultAddress].push(withdrawal);
317
330
  }
331
+ const vaults = Object.keys(withdrawalsPerVault);
332
+ const withdrawals = vaults.map((vaultAddress) => withdrawalsPerVault[vaultAddress].sort((a, b) => a[2].localeCompare(b[2])).map(w => [w[0], w[1]]));
333
+ return {
334
+ vaults,
335
+ withdrawals,
336
+ };
337
+ }
338
+ catch (error) {
339
+ console.error('External API Failure: Morpho blue reallocation', error);
340
+ throw new Error('Failed to fetch reallocation data');
318
341
  }
319
- const vaults = Object.keys(withdrawalsPerVault);
320
- const withdrawals = vaults.map((vaultAddress) => withdrawalsPerVault[vaultAddress].sort((a, b) => a[2].localeCompare(b[2])).map(w => [w[0], w[1]]));
321
- return {
322
- vaults,
323
- withdrawals,
324
- };
325
342
  });
326
343
  exports.getReallocation = getReallocation;
327
344
  const getRewardsForMarket = (marketId_1, ...args_1) => __awaiter(void 0, [marketId_1, ...args_1], void 0, function* (marketId, network = common_1.NetworkNumber.Eth) {
@@ -10,7 +10,7 @@ exports.aaveV1AssetsDefaultMarket = [
10
10
  exports.aaveV2AssetsDefaultMarket = ['USDT', 'WBTC', 'ETH', 'YFI', 'ZRX', 'UNI', 'AAVE', 'BAT', 'BUSD', 'DAI', 'ENJ', 'KNCL', 'LINK', 'MANA', 'MKR', 'REN', 'SNX', 'SUSD', 'TUSD', 'USDC', 'CRV', 'GUSD', 'BAL', 'xSUSHI', 'RENFIL', 'RAI', 'AMPL', 'USDP', 'DPI', 'FRAX', 'FEI', 'stETH', 'ENS', 'UST', 'CVX', '1INCH', 'LUSD'];
11
11
  exports.aaveV3AssetsDefaultMarketEth = [
12
12
  'ETH', 'wstETH', 'WBTC', 'USDC', 'DAI', 'LINK', 'AAVE', 'cbETH', 'USDT', 'rETH', 'LUSD', 'CRV', 'MKR', 'SNX', 'BAL', 'UNI', 'LDO', 'ENS', '1INCH', 'FRAX', 'GHO', 'RPL', 'sDAI', 'STG', 'KNC', 'FXS', 'crvUSD', 'PYUSD', 'weETH', 'osETH', 'USDe', 'ETHx', 'sUSDe', 'tBTC', 'cbBTC', 'USDS', 'rsETH', 'LBTC', 'eBTC', 'RLUSD', 'PT eUSDe May', 'PT sUSDe July', 'USDtb',
13
- 'eUSDe', 'PT USDe July', 'PT eUSDe Aug', 'EURC', 'FBTC', 'PT sUSDe Sep', 'PT USDe Sep',
13
+ 'eUSDe', 'PT USDe July', 'PT eUSDe Aug', 'EURC', 'FBTC', 'PT sUSDe Sep', 'PT USDe Sep', 'tETH', 'ezETH',
14
14
  ];
15
15
  exports.aaveV3AssetsDefaultMarketOpt = [
16
16
  'DAI', 'USDC.e', 'USDT', 'SUSD', 'AAVE', 'LINK', 'WBTC', 'ETH', 'OP', 'wstETH', 'LUSD', 'MAI', 'rETH', 'USDC',
@@ -24,3 +24,4 @@ export declare const isEnabledOnBitmap: (bitmap: number, assetId: number) => big
24
24
  export declare const MAXUINT: string;
25
25
  export declare const isMaxuint: (amount: string) => boolean;
26
26
  export declare const isMainnetNetwork: (network: NetworkNumber) => network is NetworkNumber.Eth;
27
+ export declare const DEFAULT_TIMEOUT = 2000;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.isMainnetNetwork = exports.isMaxuint = exports.MAXUINT = exports.isEnabledOnBitmap = exports.mapRange = exports.bytesToString = exports.ethToWethByAddress = exports.wethToEthByAddress = exports.handleWbtcLegacy = exports.getEthAmountForDecimals = exports.getWeiAmountForDecimals = exports.compareAddresses = exports.isAddress = exports.ADDRESS_REGEX = exports.getAbiItem = exports.wstEthToStEth = exports.stEthToWstEth = exports.wethToEth = exports.ethToWeth = exports.addToArrayIf = exports.addToObjectIf = exports.isLayer2Network = void 0;
6
+ exports.DEFAULT_TIMEOUT = exports.isMainnetNetwork = exports.isMaxuint = exports.MAXUINT = exports.isEnabledOnBitmap = exports.mapRange = exports.bytesToString = exports.ethToWethByAddress = exports.wethToEthByAddress = exports.handleWbtcLegacy = exports.getEthAmountForDecimals = exports.getWeiAmountForDecimals = exports.compareAddresses = exports.isAddress = exports.ADDRESS_REGEX = exports.getAbiItem = exports.wstEthToStEth = exports.stEthToWstEth = exports.wethToEth = exports.ethToWeth = exports.addToArrayIf = exports.addToObjectIf = exports.isLayer2Network = void 0;
7
7
  const decimal_js_1 = __importDefault(require("decimal.js"));
8
8
  const tokens_1 = require("@defisaver/tokens");
9
9
  const common_1 = require("../types/common");
@@ -63,3 +63,4 @@ const isMaxuint = (amount) => (0, exports.compareAddresses)(exports.MAXUINT, amo
63
63
  exports.isMaxuint = isMaxuint;
64
64
  const isMainnetNetwork = (network) => network === common_1.NetworkNumber.Eth;
65
65
  exports.isMainnetNetwork = isMainnetNetwork;
66
+ exports.DEFAULT_TIMEOUT = 2000; // 2 seconds
@@ -16,36 +16,56 @@ exports.calculateNetApy = exports.isEligibleForEthenaUSDeRewards = exports.calcu
16
16
  const decimal_js_1 = __importDefault(require("decimal.js"));
17
17
  const memoizee_1 = __importDefault(require("memoizee"));
18
18
  const constants_1 = require("../constants");
19
+ const utils_1 = require("../services/utils");
19
20
  const getSsrApy = () => __awaiter(void 0, void 0, void 0, function* () {
20
- const res = yield fetch('https://fe.defisaver.com/api/sky/data');
21
- const data = yield res.json();
22
- return new decimal_js_1.default(data.data.skyData[0].sky_savings_rate_apy).mul(100).toString();
21
+ try {
22
+ const res = yield fetch('https://fe.defisaver.com/api/sky/data', { signal: AbortSignal.timeout(utils_1.DEFAULT_TIMEOUT) });
23
+ const data = yield res.json();
24
+ return new decimal_js_1.default(data.data.skyData[0].sky_savings_rate_apy).mul(100).toString();
25
+ }
26
+ catch (e) {
27
+ console.error('External API Failure: Failed to fetch SSR APY from external API', e);
28
+ return '0';
29
+ }
23
30
  });
24
31
  const getSuperOETHApy = () => __awaiter(void 0, void 0, void 0, function* () {
25
- const res = yield fetch('https://origin.squids.live/origin-squid/graphql', {
26
- method: 'POST',
27
- headers: {
28
- 'Content-Type': 'application/json',
29
- },
30
- body: JSON.stringify({
31
- query: '\n query OTokenApy($chainId: Int!, $token: String!) {\n oTokenApies(\n limit: 1\n orderBy: timestamp_DESC\n where: {chainId_eq: $chainId, otoken_containsInsensitive: $token}\n ) {\n apy7DayAvg\n apy14DayAvg\n apy30DayAvg\n apr\n apy\n }\n}\n ',
32
- variables: {
33
- token: '0xdbfefd2e8460a6ee4955a68582f85708baea60a3',
34
- chainId: 8453,
32
+ try {
33
+ const res = yield fetch('https://origin.squids.live/origin-squid/graphql', {
34
+ method: 'POST',
35
+ headers: {
36
+ 'Content-Type': 'application/json',
35
37
  },
36
- }),
37
- });
38
- const data = yield res.json();
39
- return new decimal_js_1.default(data.data.oTokenApies[0].apy).mul(100).toString();
38
+ body: JSON.stringify({
39
+ query: '\n query OTokenApy($chainId: Int!, $token: String!) {\n oTokenApies(\n limit: 1\n orderBy: timestamp_DESC\n where: {chainId_eq: $chainId, otoken_containsInsensitive: $token}\n ) {\n apy7DayAvg\n apy14DayAvg\n apy30DayAvg\n apr\n apy\n }\n}\n ',
40
+ variables: {
41
+ token: '0xdbfefd2e8460a6ee4955a68582f85708baea60a3',
42
+ chainId: 8453,
43
+ },
44
+ }),
45
+ signal: AbortSignal.timeout(utils_1.DEFAULT_TIMEOUT),
46
+ });
47
+ const data = yield res.json();
48
+ return new decimal_js_1.default(data.data.oTokenApies[0].apy).mul(100).toString();
49
+ }
50
+ catch (e) {
51
+ console.error('External API Failure: Failed to fetch Super OETH APY from external API', e);
52
+ return '0';
53
+ }
40
54
  });
41
55
  const getApyFromDfsApi = (asset) => __awaiter(void 0, void 0, void 0, function* () {
42
- const res = yield fetch(`https://fe.defisaver.com/api/staking/apy?asset=${asset}`);
43
- if (!res.ok)
44
- throw new Error(`Failed to fetch APY for ${asset}`);
45
- const data = yield res.json();
46
- return String(data.apy);
56
+ try {
57
+ const res = yield fetch(`https://fe.defisaver.com/api/staking/apy?asset=${asset}`, { signal: AbortSignal.timeout(utils_1.DEFAULT_TIMEOUT) });
58
+ if (!res.ok)
59
+ throw new Error(`Failed to fetch APY for ${asset}`);
60
+ const data = yield res.json();
61
+ return String(data.apy);
62
+ }
63
+ catch (e) {
64
+ console.error(`External API Failure: Failed to fetch APY for ${asset} from DFS API`, e);
65
+ return '0';
66
+ }
47
67
  });
48
- exports.STAKING_ASSETS = ['cbETH', 'wstETH', 'cbETH', 'rETH', 'sDAI', 'weETH', 'sUSDe', 'osETH', 'ezETH', 'ETHx', 'rsETH', 'pufETH', 'wrsETH', 'wsuperOETHb', 'sUSDS', 'PT eUSDe May', 'PT sUSDe July', 'PT USDe July', 'PT eUSDe Aug', 'tETH', 'PT sUSDe Sep', 'PT USDe Sep'];
68
+ exports.STAKING_ASSETS = ['cbETH', 'wstETH', 'cbETH', 'rETH', 'sDAI', 'weETH', 'sUSDe', 'osETH', 'ezETH', 'ETHx', 'rsETH', 'pufETH', 'wrsETH', 'wsuperOETHb', 'sUSDS', 'tETH', 'PT sUSDe Sep', 'PT USDe Sep'];
49
69
  exports.getStakingApy = (0, memoizee_1.default)((asset) => __awaiter(void 0, void 0, void 0, function* () {
50
70
  try {
51
71
  if (asset === 'stETH' || asset === 'wstETH')
@@ -50,7 +50,9 @@ export interface CompoundV2AssetData extends CompoundAssetData {
50
50
  export interface CompoundV3AssetData extends CompoundAssetData {
51
51
  borrowCollateralFactor: string;
52
52
  liquidateCollateralFactor: string;
53
+ liquidationFactor: string;
53
54
  minDebt: string;
55
+ supplyReserved: string;
54
56
  liquidationRatio: string;
55
57
  supplyCap: string;
56
58
  priceInBaseAsset: string;