@defisaver/positions-sdk 2.1.4 → 2.1.6-dev-debt-in-front

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 (96) hide show
  1. package/.mocharc.json +4 -4
  2. package/.nvmrc +1 -1
  3. package/CLAUDE.md +32 -0
  4. package/README.md +64 -64
  5. package/cjs/curveUsd/index.js +2 -1
  6. package/cjs/fluid/index.js +2 -1
  7. package/cjs/helpers/morphoBlueHelpers/index.js +66 -66
  8. package/cjs/liquityV2/index.d.ts +2 -0
  9. package/cjs/liquityV2/index.js +52 -9
  10. package/cjs/types/curveUsd.d.ts +2 -0
  11. package/esm/curveUsd/index.js +2 -1
  12. package/esm/fluid/index.js +2 -1
  13. package/esm/helpers/morphoBlueHelpers/index.js +66 -66
  14. package/esm/liquityV2/index.d.ts +2 -0
  15. package/esm/liquityV2/index.js +48 -7
  16. package/esm/types/curveUsd.d.ts +2 -0
  17. package/package.json +47 -47
  18. package/src/aaveV2/index.ts +240 -240
  19. package/src/aaveV3/index.ts +614 -614
  20. package/src/aaveV3/merit.ts +94 -94
  21. package/src/aaveV3/merkl.ts +74 -74
  22. package/src/claiming/aaveV3.ts +154 -154
  23. package/src/claiming/compV3.ts +22 -22
  24. package/src/claiming/index.ts +12 -12
  25. package/src/claiming/king.ts +66 -66
  26. package/src/claiming/morphoBlue.ts +118 -118
  27. package/src/claiming/spark.ts +225 -225
  28. package/src/compoundV2/index.ts +244 -244
  29. package/src/compoundV3/index.ts +274 -274
  30. package/src/config/contracts.ts +1228 -1228
  31. package/src/constants/index.ts +10 -10
  32. package/src/contracts.ts +120 -120
  33. package/src/curveUsd/index.ts +254 -250
  34. package/src/eulerV2/index.ts +324 -324
  35. package/src/exchange/index.ts +25 -25
  36. package/src/fluid/index.ts +1638 -1638
  37. package/src/helpers/aaveHelpers/index.ts +185 -185
  38. package/src/helpers/compoundHelpers/index.ts +283 -283
  39. package/src/helpers/curveUsdHelpers/index.ts +40 -40
  40. package/src/helpers/eulerHelpers/index.ts +222 -222
  41. package/src/helpers/fluidHelpers/index.ts +326 -326
  42. package/src/helpers/index.ts +10 -10
  43. package/src/helpers/liquityV2Helpers/index.ts +82 -82
  44. package/src/helpers/llamaLendHelpers/index.ts +53 -53
  45. package/src/helpers/makerHelpers/index.ts +52 -52
  46. package/src/helpers/morphoBlueHelpers/index.ts +396 -396
  47. package/src/helpers/sparkHelpers/index.ts +155 -155
  48. package/src/index.ts +47 -47
  49. package/src/liquity/index.ts +159 -159
  50. package/src/liquityV2/index.ts +703 -657
  51. package/src/llamaLend/index.ts +305 -305
  52. package/src/maker/index.ts +223 -223
  53. package/src/markets/aave/index.ts +116 -116
  54. package/src/markets/aave/marketAssets.ts +49 -49
  55. package/src/markets/compound/index.ts +227 -227
  56. package/src/markets/compound/marketsAssets.ts +90 -90
  57. package/src/markets/curveUsd/index.ts +69 -69
  58. package/src/markets/euler/index.ts +26 -26
  59. package/src/markets/fluid/index.ts +2456 -2456
  60. package/src/markets/index.ts +25 -25
  61. package/src/markets/liquityV2/index.ts +102 -102
  62. package/src/markets/llamaLend/contractAddresses.ts +141 -141
  63. package/src/markets/llamaLend/index.ts +235 -235
  64. package/src/markets/morphoBlue/index.ts +895 -895
  65. package/src/markets/spark/index.ts +29 -29
  66. package/src/markets/spark/marketAssets.ts +11 -11
  67. package/src/moneymarket/moneymarketCommonService.ts +80 -80
  68. package/src/morphoBlue/index.ts +274 -274
  69. package/src/portfolio/index.ts +570 -570
  70. package/src/services/priceService.ts +159 -159
  71. package/src/services/utils.ts +99 -99
  72. package/src/services/viem.ts +32 -32
  73. package/src/setup.ts +8 -8
  74. package/src/spark/index.ts +445 -445
  75. package/src/staking/eligibility.ts +59 -59
  76. package/src/staking/index.ts +1 -1
  77. package/src/staking/staking.ts +170 -170
  78. package/src/types/aave.ts +189 -189
  79. package/src/types/claiming.ts +109 -109
  80. package/src/types/common.ts +105 -105
  81. package/src/types/compound.ts +136 -136
  82. package/src/types/curveUsd.ts +123 -121
  83. package/src/types/euler.ts +175 -175
  84. package/src/types/fluid.ts +448 -448
  85. package/src/types/index.ts +13 -13
  86. package/src/types/liquity.ts +30 -30
  87. package/src/types/liquityV2.ts +126 -126
  88. package/src/types/llamaLend.ts +159 -159
  89. package/src/types/maker.ts +63 -63
  90. package/src/types/merit.ts +1 -1
  91. package/src/types/merkl.ts +70 -70
  92. package/src/types/morphoBlue.ts +194 -194
  93. package/src/types/portfolio.ts +60 -60
  94. package/src/types/spark.ts +135 -135
  95. package/src/umbrella/index.ts +69 -69
  96. package/src/umbrella/umbrellaUtils.ts +29 -29
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/CLAUDE.md ADDED
@@ -0,0 +1,32 @@
1
+ # DeFiSaver Positions SDK
2
+
3
+ TypeScript SDK for DeFi positions tracking and management.
4
+
5
+ ## Commands
6
+
7
+ ```bash
8
+ # Development
9
+ npm run dev # Watch mode compilation
10
+ npm run build # Lint and build both CJS and ESM
11
+ npm run build:cjs # Build CommonJS
12
+ npm run build:esm # Build ES modules
13
+
14
+ # Linting
15
+ npm run lint # Lint and fix
16
+ npm run lint-check # Lint without fixing
17
+
18
+ # Testing
19
+ npm run test # Run all tests
20
+ npm run test-single # Run single test (use --name=filename)
21
+ npm run test:debugger # Run tests with debugger
22
+
23
+ # Versioning
24
+ npm run version-bump # Commit and bump patch version
25
+ ```
26
+
27
+ ## Project Structure
28
+
29
+ - `src/` - TypeScript source code
30
+ - `tests/` - Test files
31
+ - `esm/` - ES module build output
32
+ - `cjs/` - CommonJS build output
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
@@ -143,6 +143,7 @@ const _getCurveUsdUserData = (provider, network, address, selectedMarket, active
143
143
  const collSuppliedUsd = new decimal_js_1.default(collSupplied).mul(collPrice).toString();
144
144
  const crvUSDSupplied = (0, tokens_1.assetAmountInEth)(data.curveUsdCollateralAmount.toString(), debtAsset);
145
145
  const debtBorrowed = (0, tokens_1.assetAmountInEth)(data.debtAmount.toString(), debtAsset);
146
+ const collRatio = data.loanExists ? new decimal_js_1.default(collSuppliedUsd).div(debtBorrowed).toString() : '0';
146
147
  const usedAssets = data.loanExists ? {
147
148
  [collAsset]: {
148
149
  isSupplied: true,
@@ -173,7 +174,7 @@ const _getCurveUsdUserData = (provider, network, address, selectedMarket, active
173
174
  const _userBands = data.loanExists ? (yield getAndFormatBands(provider, network, selectedMarket, data.bandRange[0].toString(), data.bandRange[1].toString())) : [];
174
175
  const status = data.loanExists ? getStatusForUser(data.bandRange.map(b => b.toString()), activeBand, crvUSDSupplied, collSupplied, healthPercent) : types_1.CrvUSDStatus.Nonexistant;
175
176
  const userBands = _userBands.map((band, index) => (Object.assign(Object.assign({}, band), { userDebtAmount: (0, tokens_1.assetAmountInEth)(data.usersBands[0][index].toString(), debtAsset), userCollAmount: (0, tokens_1.assetAmountInEth)(data.usersBands[1][index].toString(), collAsset) }))).sort((a, b) => parseInt(b.id, 10) - parseInt(a.id, 10));
176
- return Object.assign(Object.assign(Object.assign(Object.assign({}, data), { debtAmount: (0, tokens_1.assetAmountInEth)(data.debtAmount.toString(), debtAsset), health,
177
+ return Object.assign(Object.assign(Object.assign(Object.assign({}, data), { collRatio, collateralPrice: collPrice, debtAmount: (0, tokens_1.assetAmountInEth)(data.debtAmount.toString(), debtAsset), health,
177
178
  healthPercent,
178
179
  priceHigh,
179
180
  priceLow, liquidationDiscount: (0, tokens_1.assetAmountInEth)(data.liquidationDiscount.toString()), numOfBands: data.N.toString(), usedAssets,
@@ -98,6 +98,7 @@ const getChainLinkPricesForTokens = (tokens, network, client) => __awaiter(void
98
98
  const btcPriceChainlink = new decimal_js_1.default(results[1].result).div(1e8).toString();
99
99
  let offset = 2; // wstETH and weETH has 3 calls, while others have only 1, so we need to keep track. First 2 are static calls for eth and btc prices
100
100
  return noDuplicateTokens.reduce((acc, token, i) => {
101
+ var _a;
101
102
  const assetInfo = (0, tokens_1.getAssetInfoByAddress)(token, network);
102
103
  switch (assetInfo.symbol) {
103
104
  case 'USDA':
@@ -142,7 +143,7 @@ const getChainLinkPricesForTokens = (tokens, network, client) => __awaiter(void
142
143
  }
143
144
  default:
144
145
  // @ts-ignore
145
- if (results[i + offset].result[1]) {
146
+ if ((_a = results[i + offset].result) === null || _a === void 0 ? void 0 : _a[1]) {
146
147
  // @ts-ignore
147
148
  acc[token] = new decimal_js_1.default(results[i + offset].result[1].toString()).div(1e8).toString();
148
149
  }
@@ -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
@@ -23,6 +23,8 @@ export declare const getLiquityV2UserTroveIds: (provider: EthereumProvider, netw
23
23
  }[];
24
24
  nextFreeTroveIndex: string;
25
25
  }>;
26
+ export declare const calculateDebtInFrontLiquityV2: (markets: Record<LiquityV2Versions, LiquityV2MarketData>, selectedMarket: LiquityV2Versions, allMarketsUnbackedDebts: Record<LiquityV2Versions, string>, interestRateDebtInFront: string) => string;
27
+ export declare const getDebtInFrontForInterestRateIncludingNewDebtLiquityV2: (newDebt: string, markets: Record<LiquityV2Versions, LiquityV2MarketData>, selectedMarket: LiquityV2Versions, provider: Client, network: NetworkNumber, interestRate: string) => Promise<string>;
26
28
  export declare const getDebtInFrontForInterestRateLiquityV2: (markets: Record<LiquityV2Versions, LiquityV2MarketData>, selectedMarket: LiquityV2Versions, provider: EthereumProvider, network: NetworkNumber, isLegacy: boolean, interestRate: string, debtInFrontBeingMoved?: string) => Promise<string>;
27
29
  export declare const _getLiquityV2TroveData: (provider: Client, network: NetworkNumber, { selectedMarket, assetsData, troveId, allMarketsData, }: {
28
30
  selectedMarket: LiquityV2MarketInfo;
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.getLiquitySAndYBold = exports.getLiquityV2Staking = exports.getLiquityV2ClaimableCollateral = exports.getLiquityV2TroveData = exports._getLiquityV2TroveData = exports.getDebtInFrontForInterestRateLiquityV2 = exports.getLiquityV2UserTroveIds = exports._getLiquityV2UserTroveIds = exports.getLiquityV2MarketData = exports._getLiquityV2MarketData = void 0;
15
+ exports.getLiquitySAndYBold = exports.getLiquityV2Staking = exports.getLiquityV2ClaimableCollateral = exports.getLiquityV2TroveData = exports._getLiquityV2TroveData = exports.getDebtInFrontForInterestRateLiquityV2 = exports.getDebtInFrontForInterestRateIncludingNewDebtLiquityV2 = exports.calculateDebtInFrontLiquityV2 = exports.getLiquityV2UserTroveIds = exports._getLiquityV2UserTroveIds = exports.getLiquityV2MarketData = exports._getLiquityV2MarketData = void 0;
16
16
  const decimal_js_1 = __importDefault(require("decimal.js"));
17
17
  const tokens_1 = require("@defisaver/tokens");
18
18
  const contracts_1 = require("../contracts");
@@ -201,11 +201,39 @@ const getAllMarketsUnbackedDebts = (markets, isLegacy, provider, network) => __a
201
201
  return Object.fromEntries(allMarketsUnbackedDebt);
202
202
  });
203
203
  const calculateDebtInFrontLiquityV2 = (markets, selectedMarket, allMarketsUnbackedDebts, interestRateDebtInFront) => {
204
+ // Sanity check to avoid division by 0. Very unlikely to ever happen.
205
+ const selectedMarketTotalBorrow = new decimal_js_1.default(markets[selectedMarket].assetsData[(0, markets_1.LiquityV2Markets)(common_1.NetworkNumber.Eth)[selectedMarket].debtToken].totalBorrow);
206
+ if (selectedMarketTotalBorrow.eq(0))
207
+ return new decimal_js_1.default(0).toString();
204
208
  const selectedMarketUnbackedDebt = new decimal_js_1.default(allMarketsUnbackedDebts[selectedMarket]);
205
209
  const { isLegacy } = (0, markets_1.LiquityV2Markets)(common_1.NetworkNumber.Eth)[selectedMarket];
206
- if (selectedMarketUnbackedDebt.eq(0))
207
- return interestRateDebtInFront;
208
- const amountBeingReedemedOnEachMarket = Object.entries(markets).map(([version, market]) => {
210
+ const totalUnbackedDebt = Object.values(allMarketsUnbackedDebts).reduce((acc, val) => acc.plus(new decimal_js_1.default(val)), new decimal_js_1.default(0));
211
+ // When totalUnbackedDebt is 0, redemptions will be proportional with the branch size and not to unbacked debt.
212
+ // When unbacked debt is 0 for branch, next redemption call won't touch that branch, so in order to estimate total debt in front we will:
213
+ // - First add up all the unbacked debt from other branches, as that will be the only debt that will be redeemed on the fist redemption call
214
+ // - Perform split the same way as we would do when totalUnbackedDebt == 0, this would represent the second call to the redemption function
215
+ if (selectedMarketUnbackedDebt.eq(0)) {
216
+ // Special case if the branch debt in front is 0, it means that all debt in front is unbacked debt from other branches.
217
+ if (new decimal_js_1.default(interestRateDebtInFront).eq(0))
218
+ return totalUnbackedDebt.toString();
219
+ // Then calculate how much of that estimated amount would go to each branch
220
+ // Second redemption call - calculate proportional redemption based on updated total debt
221
+ const amountBeingRedeemedOnEachMarketByTotalBorrow = Object.entries(markets).map(([version, market]) => {
222
+ const { isLegacy: isLegacyMarket } = (0, markets_1.LiquityV2Markets)(common_1.NetworkNumber.Eth)[version];
223
+ if (version === selectedMarket && isLegacyMarket !== isLegacy)
224
+ return new decimal_js_1.default(interestRateDebtInFront);
225
+ const { assetsData } = market;
226
+ const { debtToken } = (0, markets_1.LiquityV2Markets)(common_1.NetworkNumber.Eth)[version];
227
+ // For other markets, subtract their unbacked debt as it will be cleared in first redemption call
228
+ const marketUnbackedDebt = new decimal_js_1.default(allMarketsUnbackedDebts[version]);
229
+ const totalBorrow = new decimal_js_1.default(assetsData[debtToken].totalBorrow).sub(marketUnbackedDebt);
230
+ const amountToRedeem = new decimal_js_1.default(interestRateDebtInFront).mul(totalBorrow).div(selectedMarketTotalBorrow);
231
+ return decimal_js_1.default.min(amountToRedeem, totalBorrow);
232
+ });
233
+ const redemptionAmount = amountBeingRedeemedOnEachMarketByTotalBorrow.reduce((acc, val) => acc.plus(val), new decimal_js_1.default(0));
234
+ return totalUnbackedDebt.plus(redemptionAmount).toString();
235
+ }
236
+ const amountBeingRedeemedOnEachMarketByUnbackedDebt = Object.entries(markets).map(([version, market]) => {
209
237
  const { isLegacy: isLegacyMarket } = (0, markets_1.LiquityV2Markets)(common_1.NetworkNumber.Eth)[version];
210
238
  if (version === selectedMarket && isLegacyMarket !== isLegacy)
211
239
  return new decimal_js_1.default(interestRateDebtInFront);
@@ -213,16 +241,31 @@ const calculateDebtInFrontLiquityV2 = (markets, selectedMarket, allMarketsUnback
213
241
  const { debtToken } = (0, markets_1.LiquityV2Markets)(common_1.NetworkNumber.Eth)[version];
214
242
  const unbackedDebt = new decimal_js_1.default(allMarketsUnbackedDebts[version]);
215
243
  const totalBorrow = new decimal_js_1.default(assetsData[debtToken].totalBorrow);
216
- const amountToReedem = new decimal_js_1.default(interestRateDebtInFront).mul(unbackedDebt).div(selectedMarketUnbackedDebt);
217
- return decimal_js_1.default.min(amountToReedem, totalBorrow);
244
+ const amountToRedeem = new decimal_js_1.default(interestRateDebtInFront).mul(unbackedDebt).div(selectedMarketUnbackedDebt);
245
+ return decimal_js_1.default.min(amountToRedeem, totalBorrow);
218
246
  });
219
- return amountBeingReedemedOnEachMarket.reduce((acc, val) => acc.plus(val), new decimal_js_1.default(0)).toString();
247
+ return amountBeingRedeemedOnEachMarketByUnbackedDebt.reduce((acc, val) => acc.plus(val), new decimal_js_1.default(0)).toString();
220
248
  };
249
+ exports.calculateDebtInFrontLiquityV2 = calculateDebtInFrontLiquityV2;
250
+ // @dev The amount redeemed on each branch depends on the unbacked debt of every branch (the difference between total borrow and stability pool deposits).
251
+ // When new debt is generated on the selected market, the unbacked debt will increase, resulting in a higher redemption amount on that branch.
252
+ // This function accepts the new debt that's about to be generated (e.g., trove creation) and estimates the debt in front based on the new state.
253
+ const getDebtInFrontForInterestRateIncludingNewDebtLiquityV2 = (newDebt, markets, selectedMarket, provider, network, interestRate) => __awaiter(void 0, void 0, void 0, function* () {
254
+ const marketsWithNewDebt = structuredClone(markets);
255
+ const selectedMarketDebtToken = (0, markets_1.LiquityV2Markets)(network)[selectedMarket].debtToken;
256
+ const currentTotalBorrow = new decimal_js_1.default(marketsWithNewDebt[selectedMarket].assetsData[selectedMarketDebtToken].totalBorrow);
257
+ marketsWithNewDebt[selectedMarket].assetsData[selectedMarketDebtToken].totalBorrow = currentTotalBorrow.add(newDebt).toString();
258
+ const { isLegacy } = (0, markets_1.LiquityV2Markets)(common_1.NetworkNumber.Eth)[selectedMarket];
259
+ const allMarketsUnbackedDebts = yield getAllMarketsUnbackedDebts(marketsWithNewDebt, isLegacy, provider, network);
260
+ const interestRateDebtInFront = new decimal_js_1.default(yield getDebtInFrontForInterestRateSingleMarketLiquityV2(provider, network, isLegacy, (0, markets_1.LiquityV2Markets)(network)[selectedMarket].marketAddress, interestRate));
261
+ return (0, exports.calculateDebtInFrontLiquityV2)(marketsWithNewDebt, selectedMarket, allMarketsUnbackedDebts, interestRateDebtInFront.toString());
262
+ });
263
+ exports.getDebtInFrontForInterestRateIncludingNewDebtLiquityV2 = getDebtInFrontForInterestRateIncludingNewDebtLiquityV2;
221
264
  const getDebtInFrontLiquityV2 = (markets, selectedMarket, provider, network, viewContract, troveId) => __awaiter(void 0, void 0, void 0, function* () {
222
265
  const { isLegacy } = (0, markets_1.LiquityV2Markets)(common_1.NetworkNumber.Eth)[selectedMarket];
223
266
  const allMarketsUnbackedDebts = yield getAllMarketsUnbackedDebts(markets, isLegacy, provider, network);
224
267
  const interestRateDebtInFront = yield getDebtInFrontForSingleMarketLiquityV2(provider, network, isLegacy, (0, markets_1.LiquityV2Markets)(network)[selectedMarket].marketAddress, troveId);
225
- return calculateDebtInFrontLiquityV2(markets, selectedMarket, allMarketsUnbackedDebts, interestRateDebtInFront.toString());
268
+ return (0, exports.calculateDebtInFrontLiquityV2)(markets, selectedMarket, allMarketsUnbackedDebts, interestRateDebtInFront.toString());
226
269
  });
227
270
  /**
228
271
  * @param markets
@@ -237,7 +280,7 @@ const _getDebtInFrontForInterestRateLiquityV2 = (markets_2, selectedMarket_1, pr
237
280
  const allMarketsUnbackedDebts = yield getAllMarketsUnbackedDebts(markets, isLegacy, provider, network);
238
281
  const interestRateDebtInFront = new decimal_js_1.default(yield getDebtInFrontForInterestRateSingleMarketLiquityV2(provider, network, isLegacy, (0, markets_1.LiquityV2Markets)(network)[selectedMarket].marketAddress, interestRate))
239
282
  .sub(debtInFrontBeingMoved);
240
- return calculateDebtInFrontLiquityV2(markets, selectedMarket, allMarketsUnbackedDebts, interestRateDebtInFront.toString());
283
+ return (0, exports.calculateDebtInFrontLiquityV2)(markets, selectedMarket, allMarketsUnbackedDebts, interestRateDebtInFront.toString());
241
284
  });
242
285
  const getDebtInFrontForInterestRateLiquityV2 = (markets_2, selectedMarket_1, provider_1, network_1, isLegacy_1, interestRate_1, ...args_1) => __awaiter(void 0, [markets_2, selectedMarket_1, provider_1, network_1, isLegacy_1, interestRate_1, ...args_1], void 0, function* (markets, selectedMarket, provider, network, isLegacy, interestRate, debtInFrontBeingMoved = '0') { return _getDebtInFrontForInterestRateLiquityV2(markets, selectedMarket, (0, viem_1.getViemProvider)(provider, network), network, isLegacy, interestRate, debtInFrontBeingMoved); });
243
286
  exports.getDebtInFrontForInterestRateLiquityV2 = getDebtInFrontForInterestRateLiquityV2;
@@ -109,4 +109,6 @@ export interface CrvUSDUserData {
109
109
  userBands: UserBandData[];
110
110
  loanExists: boolean;
111
111
  borrowRate?: string;
112
+ collateralPrice: string;
113
+ collRatio: string;
112
114
  }
@@ -133,6 +133,7 @@ export const _getCurveUsdUserData = (provider, network, address, selectedMarket,
133
133
  const collSuppliedUsd = new Dec(collSupplied).mul(collPrice).toString();
134
134
  const crvUSDSupplied = assetAmountInEth(data.curveUsdCollateralAmount.toString(), debtAsset);
135
135
  const debtBorrowed = assetAmountInEth(data.debtAmount.toString(), debtAsset);
136
+ const collRatio = data.loanExists ? new Dec(collSuppliedUsd).div(debtBorrowed).toString() : '0';
136
137
  const usedAssets = data.loanExists ? {
137
138
  [collAsset]: {
138
139
  isSupplied: true,
@@ -163,7 +164,7 @@ export const _getCurveUsdUserData = (provider, network, address, selectedMarket,
163
164
  const _userBands = data.loanExists ? (yield getAndFormatBands(provider, network, selectedMarket, data.bandRange[0].toString(), data.bandRange[1].toString())) : [];
164
165
  const status = data.loanExists ? getStatusForUser(data.bandRange.map(b => b.toString()), activeBand, crvUSDSupplied, collSupplied, healthPercent) : CrvUSDStatus.Nonexistant;
165
166
  const userBands = _userBands.map((band, index) => (Object.assign(Object.assign({}, band), { userDebtAmount: assetAmountInEth(data.usersBands[0][index].toString(), debtAsset), userCollAmount: assetAmountInEth(data.usersBands[1][index].toString(), collAsset) }))).sort((a, b) => parseInt(b.id, 10) - parseInt(a.id, 10));
166
- return Object.assign(Object.assign(Object.assign(Object.assign({}, data), { debtAmount: assetAmountInEth(data.debtAmount.toString(), debtAsset), health,
167
+ return Object.assign(Object.assign(Object.assign(Object.assign({}, data), { collRatio, collateralPrice: collPrice, debtAmount: assetAmountInEth(data.debtAmount.toString(), debtAsset), health,
167
168
  healthPercent,
168
169
  priceHigh,
169
170
  priceLow, liquidationDiscount: assetAmountInEth(data.liquidationDiscount.toString()), numOfBands: data.N.toString(), usedAssets,
@@ -92,6 +92,7 @@ const getChainLinkPricesForTokens = (tokens, network, client) => __awaiter(void
92
92
  const btcPriceChainlink = new Dec(results[1].result).div(1e8).toString();
93
93
  let offset = 2; // wstETH and weETH has 3 calls, while others have only 1, so we need to keep track. First 2 are static calls for eth and btc prices
94
94
  return noDuplicateTokens.reduce((acc, token, i) => {
95
+ var _a;
95
96
  const assetInfo = getAssetInfoByAddress(token, network);
96
97
  switch (assetInfo.symbol) {
97
98
  case 'USDA':
@@ -136,7 +137,7 @@ const getChainLinkPricesForTokens = (tokens, network, client) => __awaiter(void
136
137
  }
137
138
  default:
138
139
  // @ts-ignore
139
- if (results[i + offset].result[1]) {
140
+ if ((_a = results[i + offset].result) === null || _a === void 0 ? void 0 : _a[1]) {
140
141
  // @ts-ignore
141
142
  acc[token] = new Dec(results[i + offset].result[1].toString()).div(1e8).toString();
142
143
  }
@@ -118,73 +118,73 @@ export const getApyAfterValuesEstimation = (selectedMarket, actions, provider, n
118
118
  return { borrowRate, supplyRate };
119
119
  });
120
120
  const API_URL = 'https://blue-api.morpho.org/graphql';
121
- const MARKET_QUERY = `
122
- query MarketByUniqueKey($uniqueKey: String!, $chainId: Int!) {
123
- marketByUniqueKey(uniqueKey: $uniqueKey, chainId: $chainId) {
124
- reallocatableLiquidityAssets
125
- targetBorrowUtilization
126
- loanAsset {
127
- address
128
- decimals
129
- priceUsd
130
- }
131
- state {
132
- liquidityAssets
133
- borrowAssets
134
- supplyAssets
135
- }
136
- publicAllocatorSharedLiquidity {
137
- assets
138
- vault {
139
- address
140
- name
141
- }
142
- allocationMarket {
143
- uniqueKey
144
- loanAsset {
145
- address
146
- }
147
- collateralAsset {
148
- address
149
- }
150
- irmAddress
151
- oracle {
152
- address
153
- }
154
- lltv
155
- }
156
- }
157
- loanAsset {
158
- address
159
- }
160
- collateralAsset {
161
- address
162
- }
163
- oracle {
164
- address
165
- }
166
- irmAddress
167
- lltv
168
- }
169
- }
121
+ const MARKET_QUERY = `
122
+ query MarketByUniqueKey($uniqueKey: String!, $chainId: Int!) {
123
+ marketByUniqueKey(uniqueKey: $uniqueKey, chainId: $chainId) {
124
+ reallocatableLiquidityAssets
125
+ targetBorrowUtilization
126
+ loanAsset {
127
+ address
128
+ decimals
129
+ priceUsd
130
+ }
131
+ state {
132
+ liquidityAssets
133
+ borrowAssets
134
+ supplyAssets
135
+ }
136
+ publicAllocatorSharedLiquidity {
137
+ assets
138
+ vault {
139
+ address
140
+ name
141
+ }
142
+ allocationMarket {
143
+ uniqueKey
144
+ loanAsset {
145
+ address
146
+ }
147
+ collateralAsset {
148
+ address
149
+ }
150
+ irmAddress
151
+ oracle {
152
+ address
153
+ }
154
+ lltv
155
+ }
156
+ }
157
+ loanAsset {
158
+ address
159
+ }
160
+ collateralAsset {
161
+ address
162
+ }
163
+ oracle {
164
+ address
165
+ }
166
+ irmAddress
167
+ lltv
168
+ }
169
+ }
170
170
  `;
171
- const REWARDS_QUERY = `
172
- query MarketByUniqueKey($uniqueKey: String!, $chainId: Int!) {
173
- marketByUniqueKey(uniqueKey: $uniqueKey, chainId: $chainId) {
174
- uniqueKey
175
- state {
176
- rewards {
177
- amountPerSuppliedToken
178
- supplyApr
179
- amountPerBorrowedToken
180
- borrowApr
181
- asset {
182
- address
183
- }
184
- }
185
- }
186
- }
187
- }
171
+ const REWARDS_QUERY = `
172
+ query MarketByUniqueKey($uniqueKey: String!, $chainId: Int!) {
173
+ marketByUniqueKey(uniqueKey: $uniqueKey, chainId: $chainId) {
174
+ uniqueKey
175
+ state {
176
+ rewards {
177
+ amountPerSuppliedToken
178
+ supplyApr
179
+ amountPerBorrowedToken
180
+ borrowApr
181
+ asset {
182
+ address
183
+ }
184
+ }
185
+ }
186
+ }
187
+ }
188
188
  `;
189
189
  /**
190
190
  * Get reallocatable liquidity to a given market and target borrow utilization