@defisaver/positions-sdk 2.1.161 → 2.1.163

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 (128) hide show
  1. package/cjs/aaveV2/index.js +2 -0
  2. package/cjs/aaveV3/index.js +7 -1
  3. package/cjs/curveUsd/index.d.ts +5 -2
  4. package/cjs/curveUsd/index.js +30 -15
  5. package/cjs/fluid/index.d.ts +5 -0
  6. package/cjs/fluid/index.js +36 -1
  7. package/cjs/helpers/aaveHelpers/index.d.ts +9 -1
  8. package/cjs/helpers/aaveHelpers/index.js +26 -6
  9. package/cjs/helpers/aaveV4Helpers/index.js +1 -0
  10. package/cjs/helpers/compoundHelpers/index.js +2 -0
  11. package/cjs/helpers/curveUsdHelpers/index.d.ts +3 -1
  12. package/cjs/helpers/curveUsdHelpers/index.js +15 -2
  13. package/cjs/helpers/fluidHelpers/index.js +1 -0
  14. package/cjs/helpers/liquityV2Helpers/index.js +1 -0
  15. package/cjs/helpers/llamaLendHelpers/index.js +1 -0
  16. package/cjs/helpers/makerHelpers/index.d.ts +1 -1
  17. package/cjs/helpers/makerHelpers/index.js +2 -2
  18. package/cjs/helpers/morphoBlueHelpers/index.js +2 -0
  19. package/cjs/helpers/morphoMidnightHelpers/index.js +2 -0
  20. package/cjs/helpers/sparkHelpers/index.js +1 -0
  21. package/cjs/liquity/index.js +15 -2
  22. package/cjs/maker/index.d.ts +7 -2
  23. package/cjs/maker/index.js +44 -12
  24. package/cjs/markets/index.d.ts +1 -0
  25. package/cjs/markets/index.js +3 -1
  26. package/cjs/markets/maker/index.d.ts +1 -0
  27. package/cjs/markets/maker/index.js +13 -0
  28. package/cjs/moneymarket/moneymarketCommonService.d.ts +9 -0
  29. package/cjs/moneymarket/moneymarketCommonService.js +13 -1
  30. package/cjs/portfolio/index.d.ts +5 -1
  31. package/cjs/portfolio/index.js +282 -16
  32. package/cjs/spark/index.js +1 -0
  33. package/cjs/staking/staking.d.ts +20 -0
  34. package/cjs/staking/staking.js +19 -1
  35. package/cjs/types/aave.d.ts +3 -0
  36. package/cjs/types/aaveV4.d.ts +1 -0
  37. package/cjs/types/compound.d.ts +2 -0
  38. package/cjs/types/curveUsd.d.ts +6 -0
  39. package/cjs/types/fluid.d.ts +1 -0
  40. package/cjs/types/liquity.d.ts +4 -0
  41. package/cjs/types/liquityV2.d.ts +2 -0
  42. package/cjs/types/maker.d.ts +4 -0
  43. package/cjs/types/morphoBlue.d.ts +2 -0
  44. package/cjs/types/morphoMidnight.d.ts +1 -0
  45. package/cjs/types/portfolio.d.ts +26 -10
  46. package/cjs/types/spark.d.ts +2 -0
  47. package/esm/aaveV2/index.js +2 -0
  48. package/esm/aaveV3/index.js +7 -1
  49. package/esm/curveUsd/index.d.ts +5 -2
  50. package/esm/curveUsd/index.js +30 -15
  51. package/esm/fluid/index.d.ts +5 -0
  52. package/esm/fluid/index.js +33 -0
  53. package/esm/helpers/aaveHelpers/index.d.ts +9 -1
  54. package/esm/helpers/aaveHelpers/index.js +23 -5
  55. package/esm/helpers/aaveV4Helpers/index.js +1 -0
  56. package/esm/helpers/compoundHelpers/index.js +2 -0
  57. package/esm/helpers/curveUsdHelpers/index.d.ts +3 -1
  58. package/esm/helpers/curveUsdHelpers/index.js +16 -3
  59. package/esm/helpers/fluidHelpers/index.js +1 -0
  60. package/esm/helpers/liquityV2Helpers/index.js +1 -0
  61. package/esm/helpers/llamaLendHelpers/index.js +2 -1
  62. package/esm/helpers/makerHelpers/index.d.ts +1 -1
  63. package/esm/helpers/makerHelpers/index.js +2 -2
  64. package/esm/helpers/morphoBlueHelpers/index.js +2 -0
  65. package/esm/helpers/morphoMidnightHelpers/index.js +2 -0
  66. package/esm/helpers/sparkHelpers/index.js +1 -0
  67. package/esm/liquity/index.js +16 -3
  68. package/esm/maker/index.d.ts +7 -2
  69. package/esm/maker/index.js +44 -14
  70. package/esm/markets/index.d.ts +1 -0
  71. package/esm/markets/index.js +1 -0
  72. package/esm/markets/maker/index.d.ts +1 -0
  73. package/esm/markets/maker/index.js +10 -0
  74. package/esm/moneymarket/moneymarketCommonService.d.ts +9 -0
  75. package/esm/moneymarket/moneymarketCommonService.js +11 -0
  76. package/esm/portfolio/index.d.ts +5 -1
  77. package/esm/portfolio/index.js +284 -19
  78. package/esm/spark/index.js +1 -0
  79. package/esm/staking/staking.d.ts +20 -0
  80. package/esm/staking/staking.js +17 -0
  81. package/esm/types/aave.d.ts +3 -0
  82. package/esm/types/aaveV4.d.ts +1 -0
  83. package/esm/types/compound.d.ts +2 -0
  84. package/esm/types/curveUsd.d.ts +6 -0
  85. package/esm/types/fluid.d.ts +1 -0
  86. package/esm/types/liquity.d.ts +4 -0
  87. package/esm/types/liquityV2.d.ts +2 -0
  88. package/esm/types/maker.d.ts +4 -0
  89. package/esm/types/morphoBlue.d.ts +2 -0
  90. package/esm/types/morphoMidnight.d.ts +1 -0
  91. package/esm/types/portfolio.d.ts +26 -10
  92. package/esm/types/spark.d.ts +2 -0
  93. package/package.json +1 -1
  94. package/src/aaveV2/index.ts +2 -0
  95. package/src/aaveV3/index.ts +6 -1
  96. package/src/curveUsd/index.ts +33 -16
  97. package/src/fluid/index.ts +40 -0
  98. package/src/helpers/aaveHelpers/index.ts +27 -7
  99. package/src/helpers/aaveV4Helpers/index.ts +1 -0
  100. package/src/helpers/compoundHelpers/index.ts +2 -0
  101. package/src/helpers/curveUsdHelpers/index.ts +23 -3
  102. package/src/helpers/fluidHelpers/index.ts +1 -0
  103. package/src/helpers/liquityV2Helpers/index.ts +1 -0
  104. package/src/helpers/llamaLendHelpers/index.ts +2 -1
  105. package/src/helpers/makerHelpers/index.ts +2 -1
  106. package/src/helpers/morphoBlueHelpers/index.ts +2 -0
  107. package/src/helpers/morphoMidnightHelpers/index.ts +2 -0
  108. package/src/helpers/sparkHelpers/index.ts +1 -0
  109. package/src/liquity/index.ts +17 -3
  110. package/src/maker/index.ts +77 -30
  111. package/src/markets/index.ts +2 -1
  112. package/src/markets/maker/index.ts +10 -0
  113. package/src/moneymarket/moneymarketCommonService.ts +15 -0
  114. package/src/portfolio/index.ts +260 -5
  115. package/src/spark/index.ts +1 -0
  116. package/src/staking/staking.ts +28 -0
  117. package/src/types/aave.ts +4 -0
  118. package/src/types/aaveV4.ts +1 -0
  119. package/src/types/compound.ts +2 -0
  120. package/src/types/curveUsd.ts +7 -0
  121. package/src/types/fluid.ts +1 -0
  122. package/src/types/liquity.ts +6 -0
  123. package/src/types/liquityV2.ts +2 -0
  124. package/src/types/maker.ts +6 -0
  125. package/src/types/morphoBlue.ts +2 -0
  126. package/src/types/morphoMidnight.ts +1 -0
  127. package/src/types/portfolio.ts +31 -12
  128. package/src/types/spark.ts +2 -0
@@ -40,6 +40,7 @@ export interface EModeCategoryData {
40
40
  borrowAssets: string[];
41
41
  ltvzeroBitmap?: string;
42
42
  ltvZeroAssets: string[];
43
+ isolated: boolean;
43
44
  }
44
45
  export interface EModeCategoryDataMapping {
45
46
  enteringTerms: boolean[];
@@ -126,6 +127,7 @@ export interface AavePositionData extends MMPositionData {
126
127
  minRatio: string;
127
128
  collRatio: string;
128
129
  safetyRatioWithLtvZeroFallback?: string;
130
+ safetyRatio?: string;
129
131
  suppliedUsd: string;
130
132
  borrowedUsd: string;
131
133
  borrowLimitUsd: string;
@@ -159,6 +161,7 @@ export interface AaveV3AggregatedPositionData {
159
161
  collRatio: string;
160
162
  borrowLimitWithLtvZeroFallbackUsd: string;
161
163
  safetyRatioWithLtvZeroFallback: string;
164
+ safetyRatio: string;
162
165
  netApy: string;
163
166
  incentiveUsd: string;
164
167
  totalInterestUsd: string;
@@ -169,6 +169,7 @@ export interface AaveV4AggregatedPositionData {
169
169
  leftToBorrowUsd: string;
170
170
  ratio: string;
171
171
  collRatio: string;
172
+ safetyRatio: string;
172
173
  liqRatio: string;
173
174
  liqPercent: string;
174
175
  leveragedType: LeverageType;
@@ -96,6 +96,7 @@ export interface CompoundAggregatedPositionData {
96
96
  leftToBorrowUsd: string;
97
97
  ratio: string;
98
98
  collRatio: string;
99
+ safetyRatio: string;
99
100
  netApy: string;
100
101
  incentiveUsd: string;
101
102
  totalInterestUsd: string;
@@ -115,6 +116,7 @@ export interface CompoundAggregatedPositionData {
115
116
  export interface CompoundPositionData extends MMPositionData {
116
117
  ratio: string;
117
118
  minRatio: string;
119
+ safetyRatio?: string;
118
120
  suppliedUsd: string;
119
121
  borrowedUsd: string;
120
122
  borrowLimitUsd: string;
@@ -73,6 +73,9 @@ export interface CrvUSDAggregatedPositionData {
73
73
  collFactor: string;
74
74
  leveragedType: LeverageType;
75
75
  exposure: string;
76
+ netApy: string;
77
+ totalInterestUsd: string;
78
+ incentiveUsd: string;
76
79
  leveragedAsset?: string;
77
80
  liquidationPrice?: string;
78
81
  }
@@ -113,4 +116,7 @@ export interface CrvUSDUserData {
113
116
  collateralPrice: string;
114
117
  collRatio: string;
115
118
  exposure: string;
119
+ netApy: string;
120
+ totalInterestUsd: string;
121
+ incentiveUsd: string;
116
122
  }
@@ -323,6 +323,7 @@ export interface FluidAggregatedVaultData {
323
323
  merklBorrowIncentives: IncentiveData[];
324
324
  ratio: string;
325
325
  collRatio: string;
326
+ safetyRatio: string;
326
327
  minRatio: string;
327
328
  totalInterestUsd: string;
328
329
  leveragedType?: LeverageType;
@@ -24,7 +24,11 @@ export interface LiquityTroveInfo {
24
24
  totalETH: string;
25
25
  totalLUSD: string;
26
26
  minCollateralRatio: number;
27
+ safetyRatio: string;
27
28
  priceForRecovery: string;
28
29
  debtInFront: string;
29
30
  exposure: string;
31
+ netApy: string;
32
+ totalInterestUsd: string;
33
+ incentiveUsd: string;
30
34
  }
@@ -94,6 +94,7 @@ export interface LiquityV2AggregatedTroveData {
94
94
  liquidationPrice: string;
95
95
  ratio: string;
96
96
  collRatio: string;
97
+ safetyRatio: string;
97
98
  exposure: string;
98
99
  }
99
100
  export interface LiquityV2TroveData {
@@ -101,6 +102,7 @@ export interface LiquityV2TroveData {
101
102
  troveId: string;
102
103
  ratio: string;
103
104
  collRatio: string;
105
+ safetyRatio?: string;
104
106
  liqRatio: string;
105
107
  borrowLimitRatio: string;
106
108
  interestRate: string;
@@ -43,6 +43,7 @@ export interface CdpData {
43
43
  debtAssetMarketPrice: string;
44
44
  liquidationPrice: string;
45
45
  ratio: string;
46
+ safetyRatio: string;
46
47
  liqRatio: string;
47
48
  liqPercent: number;
48
49
  assetPrice: string;
@@ -58,4 +59,7 @@ export interface CdpData {
58
59
  liquidationFee: string;
59
60
  lastUpdated: number;
60
61
  exposure: string;
62
+ netApy: string;
63
+ totalInterestUsd: string;
64
+ incentiveUsd: string;
61
65
  }
@@ -185,6 +185,7 @@ export interface MorphoBlueAggregatedPositionData {
185
185
  totalInterestUsd: string;
186
186
  ltv: string;
187
187
  ratio: string;
188
+ safetyRatio: string;
188
189
  leveragedType: LeverageType;
189
190
  leveragedAsset?: string;
190
191
  currentVolatilePairRatio?: string;
@@ -207,6 +208,7 @@ export interface MorphoBluePositionData {
207
208
  totalInterestUsd: string;
208
209
  ltv: string;
209
210
  ratio: string;
211
+ safetyRatio?: string;
210
212
  leveragedType: LeverageType;
211
213
  leveragedAsset?: string;
212
214
  currentVolatilePairRatio?: string;
@@ -170,6 +170,7 @@ export interface MorphoMidnightAggregatedPositionData {
170
170
  ltv: string;
171
171
  ratio: string;
172
172
  healthRatio: string;
173
+ safetyRatio: string;
173
174
  leveragedType: LeverageType;
174
175
  leveragedAsset?: string;
175
176
  currentVolatilePairRatio?: string;
@@ -1,15 +1,16 @@
1
- import { AaveV2PositionData, AaveV3PositionData, AaveVersions } from './aave';
2
- import { AaveV4AccountData, AaveV4SpokesType } from './aaveV4';
1
+ import { AaveV2MarketData, AaveV2PositionData, AaveV3MarketData, AaveV3PositionData, AaveVersions } from './aave';
2
+ import { AaveV4AccountData, AaveV4SpokeData, AaveV4SpokesType } from './aaveV4';
3
3
  import { EthAddress } from './common';
4
- import { CompoundV2PositionData, CompoundV3PositionData, CompoundVersions } from './compound';
5
- import { CrvUSDUserData, CrvUSDVersions } from './curveUsd';
6
- import { FluidVaultData } from './fluid';
4
+ import { CompoundV2MarketsData, CompoundV2PositionData, CompoundV3MarketsData, CompoundV3PositionData, CompoundVersions } from './compound';
5
+ import { CrvUSDGlobalMarketData, CrvUSDUserData, CrvUSDVersions } from './curveUsd';
6
+ import { FluidMarketData, FluidVaultData } from './fluid';
7
7
  import { LiquityTroveInfo } from './liquity';
8
- import { LlamaLendUserData, LlamaLendVersionsType } from './llamaLend';
9
- import { CdpData } from './maker';
10
- import { MorphoBluePositionData, MorphoBlueVersions } from './morphoBlue';
11
- import { MorphoMidnightPositionData, MorphoMidnightVersions } from './morphoMidnight';
12
- import { SparkPositionData, SparkVersions } from './spark';
8
+ import { LiquityV2MarketData } from './liquityV2';
9
+ import { LlamaLendGlobalMarketData, LlamaLendUserData, LlamaLendVersionsType } from './llamaLend';
10
+ import { CdpData, IlkInfo } from './maker';
11
+ import { MorphoBlueMarketInfo, MorphoBluePositionData, MorphoBlueVersions } from './morphoBlue';
12
+ import { MorphoMidnightMarketInfo, MorphoMidnightPositionData, MorphoMidnightVersions } from './morphoMidnight';
13
+ import { SparkMarketsData, SparkPositionData, SparkVersions } from './spark';
13
14
  export interface PortfolioProtocolData<T> {
14
15
  error: string;
15
16
  data: T | null;
@@ -59,3 +60,18 @@ export interface PortfolioPositionsDataForAddress {
59
60
  export interface PortfolioPositionsData {
60
61
  [key: EthAddress]: PortfolioPositionsDataForAddress;
61
62
  }
63
+ export interface PortfolioMarketsData {
64
+ morphoMarketsData: Record<string, MorphoBlueMarketInfo>;
65
+ morphoMidnightMarketsData: Record<string, MorphoMidnightMarketInfo>;
66
+ compoundV3MarketsData: Record<string, CompoundV3MarketsData>;
67
+ sparkMarketsData: Record<string, SparkMarketsData>;
68
+ aaveV3MarketsData: Record<string, AaveV3MarketData>;
69
+ aaveV2MarketsData: Record<string, AaveV2MarketData>;
70
+ compoundV2MarketsData: Record<string, CompoundV2MarketsData>;
71
+ crvUsdMarketsData: Record<string, CrvUSDGlobalMarketData>;
72
+ llamaLendMarketsData: Record<string, LlamaLendGlobalMarketData>;
73
+ liquityV2MarketsData: Record<string, LiquityV2MarketData>;
74
+ aaveV4SpokesData: Record<string, AaveV4SpokeData>;
75
+ fluidMarketsData: Record<string, FluidMarketData>;
76
+ makerMarketsData: Record<string, IlkInfo>;
77
+ }
@@ -85,6 +85,7 @@ export interface SparkAggregatedPositionData {
85
85
  leftToBorrowUsd: string;
86
86
  ratio: string;
87
87
  collRatio: string;
88
+ safetyRatio: string;
88
89
  netApy: string;
89
90
  incentiveUsd: string;
90
91
  totalInterestUsd: string;
@@ -104,6 +105,7 @@ export interface SparkPositionData extends MMPositionData {
104
105
  ratio: string;
105
106
  minRatio: string;
106
107
  collRatio: string;
108
+ safetyRatio?: string;
107
109
  suppliedUsd: string;
108
110
  borrowedUsd: string;
109
111
  borrowLimitUsd: string;
@@ -167,6 +167,8 @@ export const _getAaveV2AccountData = (provider, network, address, assetsData, ma
167
167
  payload.collRatio = payload.borrowedUsd && payload.borrowedUsd !== '0'
168
168
  ? new Dec(payload.suppliedCollateralUsd).div(payload.borrowedUsd).mul(100).toString()
169
169
  : '0';
170
+ // Aave v2 has no LTV-0 fallback (AaveV3View only), so its safety ratio is the plain ratio.
171
+ payload.safetyRatio = payload.ratio;
170
172
  // Calculate borrow limits per asset
171
173
  Object.values(payload.usedAssets).forEach((item) => {
172
174
  if (item.isBorrowed) {
@@ -31,7 +31,10 @@ export const aaveV3EmodeCategoriesMapping = (extractedState, usedAssets) => {
31
31
  : !usedAssetsValues.filter(u => u.isBorrowed && !e.borrowAssets.includes(u.symbol)).length;
32
32
  const afterEnteringCategory = aaveAnyGetAggregatedPositionData(Object.assign(Object.assign({}, extractedState), { usedAssets, eModeCategory: e.id }));
33
33
  const willStayOverCollateralized = new Dec(afterEnteringCategory.ratio === 'NaN' ? '0' : afterEnteringCategory.ratio).eq(0) || new Dec(afterEnteringCategory.ratio).gt(afterEnteringCategory.liqPercent);
34
- const enteringTerms = [borrowingOnlyFromCategory, willStayOverCollateralized];
34
+ const collateralOnlyFromCategory = e.id === 0 || !e.isolated
35
+ ? true
36
+ : !usedAssetsValues.filter(u => u.isSupplied && u.collateral && !e.collateralAssets.includes(u.symbol)).length;
37
+ const enteringTerms = [borrowingOnlyFromCategory, willStayOverCollateralized, collateralOnlyFromCategory];
35
38
  categoriesMapping[e.id] = {
36
39
  enteringTerms,
37
40
  canEnterCategory: !enteringTerms.includes(false),
@@ -48,6 +51,7 @@ export const aaveV3EmodeCategoriesMapping = (extractedState, usedAssets) => {
48
51
  };
49
52
  export function _getAaveV3MarketData(provider_1, network_1, market_1) {
50
53
  return __awaiter(this, arguments, void 0, function* (provider, network, market, blockNumber = 'latest') {
54
+ var _a;
51
55
  const _addresses = market.assets.map(a => getAssetInfo(getWrappedNativeAssetFromUnwrapped(a), network).address);
52
56
  const loanInfoContract = AaveV3ViewContractViem(provider, network);
53
57
  const aaveIncentivesContract = AaveIncentiveDataProviderV3ContractViem(provider, network);
@@ -81,6 +85,7 @@ export function _getAaveV3MarketData(provider_1, network_1, market_1) {
81
85
  borrowableBitmap: eModesInfo[i].borrowableBitmap.toString(),
82
86
  collateralBitmap: eModesInfo[i].collateralBitmap.toString(),
83
87
  ltvzeroBitmap: eModesInfo[i].ltvzeroBitmap.toString(),
88
+ isolated: (_a = eModesInfo[i].isolated) !== null && _a !== void 0 ? _a : false,
84
89
  borrowAssets: [],
85
90
  collateralAssets: [],
86
91
  ltvZeroAssets: [],
@@ -296,6 +301,7 @@ export function _getAaveV3MarketData(provider_1, network_1, market_1) {
296
301
  collateralAssets: assetsData.map((a) => a.symbol),
297
302
  borrowAssets: assetsData.map((a) => a.symbol),
298
303
  ltvZeroAssets: [],
304
+ isolated: false,
299
305
  };
300
306
  return { assetsData: payload, eModeCategoriesData };
301
307
  });
@@ -5,6 +5,9 @@ export declare const _getCurveUsdGlobalData: (provider: Client, network: Network
5
5
  export declare const getCurveUsdGlobalData: (provider: EthereumProvider, network: NetworkNumber, selectedMarket: CrvUSDMarketData) => Promise<CrvUSDGlobalMarketData>;
6
6
  export declare const _getCrvUsdAccountBalances: (provider: Client, network: NetworkNumber, block: Blockish, addressMapping: boolean, address: EthAddress, controllerAddress: EthAddress) => Promise<PositionBalances>;
7
7
  export declare const getCrvUsdAccountBalances: (provider: EthereumProvider, network: NetworkNumber, block: Blockish, addressMapping: boolean, address: EthAddress, controllerAddress: EthAddress) => Promise<PositionBalances>;
8
- export declare const _getCurveUsdUserData: (provider: Client, network: NetworkNumber, address: EthAddress, selectedMarket: CrvUSDMarketData, activeBand: string) => Promise<CrvUSDUserData>;
9
- export declare const getCurveUsdUserData: (provider: EthereumProvider, network: NetworkNumber, address: EthAddress, selectedMarket: CrvUSDMarketData, activeBand: string) => Promise<CrvUSDUserData>;
8
+ /**
9
+ * @param borrowRate market borrow APY in % (`CrvUSDGlobalMarketData.borrowRate`); when omitted it is read from the view contract
10
+ */
11
+ export declare const _getCurveUsdUserData: (provider: Client, network: NetworkNumber, address: EthAddress, selectedMarket: CrvUSDMarketData, activeBand: string, borrowRate?: string) => Promise<CrvUSDUserData>;
12
+ export declare const getCurveUsdUserData: (provider: EthereumProvider, network: NetworkNumber, address: EthAddress, selectedMarket: CrvUSDMarketData, activeBand: string, borrowRate?: string) => Promise<CrvUSDUserData>;
10
13
  export declare const getCurveUsdFullPositionData: (provider: EthereumProvider, network: NetworkNumber, address: EthAddress, selectedMarket: CrvUSDMarketData) => Promise<CrvUSDUserData>;
@@ -16,6 +16,12 @@ import { getCrvUsdAggregatedData } from '../helpers/curveUsdHelpers';
16
16
  import { CrvUsdMarkets } from '../markets';
17
17
  import { wethToEth } from '../services/utils';
18
18
  import { getViemProvider, setViemBlockNumber } from '../services/viem';
19
+ import { getStakingApy, STAKING_ASSETS } from '../staking';
20
+ /** Converts a per-second AMM rate (wei, 18 decimals) into a yearly compounded borrow APY in %. */
21
+ const ammRateToBorrowApy = (rateWei) => {
22
+ const exponent = new Dec(assetAmountInEth(rateWei)).mul(365).mul(86400);
23
+ return new Dec(new Dec(2.718281828459).pow(exponent).minus(1)).mul(100).toString();
24
+ };
19
25
  const getAndFormatBands = (provider, network, selectedMarket, _minBand, _maxBand) => __awaiter(void 0, void 0, void 0, function* () {
20
26
  const contract = CrvUSDViewContractViem(provider, network);
21
27
  const minBand = parseInt(_minBand, 10);
@@ -65,14 +71,8 @@ export const _getCurveUsdGlobalData = (provider, network, selectedMarket) => __a
65
71
  // all prices are in 18 decimals
66
72
  const totalDebt = assetAmountInEth(data.totalDebt.toString(), debtAsset);
67
73
  const ammPrice = assetAmountInEth(data.ammPrice.toString(), debtAsset);
68
- const rate = assetAmountInEth(data.ammRate.toString());
69
- const futureRate = assetAmountInEth(data.monetaryPolicyRate.toString());
70
- const exponentRate = new Dec(rate).mul(365).mul(86400);
71
- const exponentFutureRate = new Dec(futureRate).mul(365).mul(86400);
72
- const borrowRate = new Dec(new Dec(2.718281828459).pow(exponentRate).minus(1)).mul(100)
73
- .toString();
74
- const futureBorrowRate = new Dec(new Dec(2.718281828459).pow(exponentFutureRate).minus(1)).mul(100)
75
- .toString();
74
+ const borrowRate = ammRateToBorrowApy(data.ammRate.toString());
75
+ const futureBorrowRate = ammRateToBorrowApy(data.monetaryPolicyRate.toString());
76
76
  const bandsData = yield getAndFormatBands(provider, network, selectedMarket, data.minBand.toString(), data.maxBand.toString());
77
77
  const leftToBorrow = new Dec(debtCeiling.toString()).minus(totalDebt).toString();
78
78
  const loanDiscount = assetAmountInEth(loanDiscountWei.toString(), debtAsset);
@@ -121,11 +121,20 @@ export const _getCrvUsdAccountBalances = (provider, network, block, addressMappi
121
121
  return balances;
122
122
  });
123
123
  export const getCrvUsdAccountBalances = (provider, network, block, addressMapping, address, controllerAddress) => __awaiter(void 0, void 0, void 0, function* () { return _getCrvUsdAccountBalances(getViemProvider(provider, network), network, block, addressMapping, address, controllerAddress); });
124
- export const _getCurveUsdUserData = (provider, network, address, selectedMarket, activeBand) => __awaiter(void 0, void 0, void 0, function* () {
124
+ /**
125
+ * @param borrowRate market borrow APY in % (`CrvUSDGlobalMarketData.borrowRate`); when omitted it is read from the view contract
126
+ */
127
+ export const _getCurveUsdUserData = (provider, network, address, selectedMarket, activeBand, borrowRate) => __awaiter(void 0, void 0, void 0, function* () {
125
128
  const contract = CrvUSDViewContractViem(provider, network);
126
- const data = yield contract.read.userData([selectedMarket.controllerAddress, address]);
127
129
  const collAsset = selectedMarket.collAsset;
128
130
  const debtAsset = selectedMarket.baseAsset;
131
+ const [data, collStakingApy, marketBorrowRate] = yield Promise.all([
132
+ contract.read.userData([selectedMarket.controllerAddress, address]),
133
+ STAKING_ASSETS.includes(collAsset) ? getStakingApy(collAsset) : Promise.resolve('0'),
134
+ borrowRate !== undefined
135
+ ? Promise.resolve(borrowRate)
136
+ : contract.read.globalData([selectedMarket.controllerAddress]).then((globalData) => ammRateToBorrowApy(globalData.ammRate.toString())),
137
+ ]);
129
138
  const health = assetAmountInEth(data.health.toString());
130
139
  const healthPercent = new Dec(health).mul(100).toString();
131
140
  const collPrice = assetAmountInEth(data.collateralPrice.toString(), debtAsset);
@@ -156,7 +165,7 @@ export const _getCurveUsdUserData = (provider, network, address, selectedMarket,
156
165
  isBorrowed: new Dec(debtBorrowed).gt('0'),
157
166
  symbol: 'crvUSD',
158
167
  price: '1',
159
- interestRate: '0',
168
+ interestRate: marketBorrowRate,
160
169
  },
161
170
  } : {};
162
171
  const priceHigh = assetAmountInEth(data.priceHigh.toString());
@@ -168,13 +177,19 @@ export const _getCurveUsdUserData = (provider, network, address, selectedMarket,
168
177
  healthPercent,
169
178
  priceHigh,
170
179
  priceLow, liquidationDiscount: assetAmountInEth(data.liquidationDiscount.toString()), numOfBands: data.N.toString(), usedAssets,
171
- status }), getCrvUsdAggregatedData({
172
- loanExists: data.loanExists, usedAssets, network: NetworkNumber.Eth, selectedMarket, numOfBands: data.N.toString(),
180
+ status, borrowRate: marketBorrowRate }), getCrvUsdAggregatedData({
181
+ loanExists: data.loanExists,
182
+ usedAssets,
183
+ network: NetworkNumber.Eth,
184
+ selectedMarket,
185
+ numOfBands: data.N.toString(),
186
+ borrowRate: marketBorrowRate,
187
+ collStakingApy,
173
188
  })), { userBands });
174
189
  });
175
- export const getCurveUsdUserData = (provider, network, address, selectedMarket, activeBand) => __awaiter(void 0, void 0, void 0, function* () { return _getCurveUsdUserData(getViemProvider(provider, network), network, address, selectedMarket, activeBand); });
190
+ export const getCurveUsdUserData = (provider, network, address, selectedMarket, activeBand, borrowRate) => __awaiter(void 0, void 0, void 0, function* () { return _getCurveUsdUserData(getViemProvider(provider, network), network, address, selectedMarket, activeBand, borrowRate); });
176
191
  export const getCurveUsdFullPositionData = (provider, network, address, selectedMarket) => __awaiter(void 0, void 0, void 0, function* () {
177
192
  const marketData = yield getCurveUsdGlobalData(provider, network, selectedMarket);
178
- const positionData = yield getCurveUsdUserData(provider, network, address, selectedMarket, marketData.activeBand);
193
+ const positionData = yield getCurveUsdUserData(provider, network, address, selectedMarket, marketData.activeBand, marketData.borrowRate);
179
194
  return positionData;
180
195
  });
@@ -133,6 +133,7 @@ export declare const _getUserPositions: (provider: PublicClient, network: Networ
133
133
  merklBorrowIncentives: import("../types").IncentiveData[];
134
134
  ratio: string;
135
135
  collRatio: string;
136
+ safetyRatio: string;
136
137
  minRatio: string;
137
138
  totalInterestUsd: string;
138
139
  leveragedType?: import("../types").LeverageType;
@@ -167,6 +168,7 @@ export declare const getUserPositions: (provider: EthereumProvider, network: Net
167
168
  merklBorrowIncentives: import("../types").IncentiveData[];
168
169
  ratio: string;
169
170
  collRatio: string;
171
+ safetyRatio: string;
170
172
  minRatio: string;
171
173
  totalInterestUsd: string;
172
174
  leveragedType?: import("../types").LeverageType;
@@ -201,6 +203,7 @@ export declare const _getUserPositionsPortfolio: (provider: PublicClient, networ
201
203
  merklBorrowIncentives: import("../types").IncentiveData[];
202
204
  ratio: string;
203
205
  collRatio: string;
206
+ safetyRatio: string;
204
207
  minRatio: string;
205
208
  totalInterestUsd: string;
206
209
  leveragedType?: import("../types").LeverageType;
@@ -221,3 +224,5 @@ export declare const _getUserPositionsPortfolio: (provider: PublicClient, networ
221
224
  nftId: string;
222
225
  } | undefined;
223
226
  }[]>;
227
+ export declare const _getAllFluidMarketDataPortfolio: (provider: PublicClient, network: NetworkNumber) => Promise<Record<string, FluidMarketData>>;
228
+ export declare const getAllFluidMarketDataPortfolio: (provider: EthereumProvider, network: NetworkNumber) => Promise<Record<string, FluidMarketData>>;
@@ -1381,3 +1381,36 @@ export const _getUserPositionsPortfolio = (provider, network, user) => __awaiter
1381
1381
  userData: userData[i],
1382
1382
  })).filter(md => md.marketData !== undefined);
1383
1383
  });
1384
+ export const _getAllFluidMarketDataPortfolio = (provider, network) => __awaiter(void 0, void 0, void 0, function* () {
1385
+ const versions = getFluidVersionsDataForNetwork(network);
1386
+ if (versions.length === 0)
1387
+ return {};
1388
+ const view = FluidViewContractViem(provider, network);
1389
+ const vaultsData = yield Promise.all(versions.map((version) => view.read.getVaultData([version.marketAddress])));
1390
+ const tokens = Array.from(new Set(vaultsData.map((vaultData) => {
1391
+ const vaultTokens = [getAssetInfoByAddress(vaultData.supplyToken0, network).symbol, getAssetInfoByAddress(vaultData.borrowToken0, network).symbol];
1392
+ if (vaultData.supplyToken1 && !compareAddresses(ZERO_ADDRESS, vaultData.supplyToken1))
1393
+ vaultTokens.push(getAssetInfoByAddress(vaultData.supplyToken1, network).symbol);
1394
+ if (vaultData.borrowToken1 && !compareAddresses(ZERO_ADDRESS, vaultData.borrowToken1))
1395
+ vaultTokens.push(getAssetInfoByAddress(vaultData.borrowToken1, network).symbol);
1396
+ return vaultTokens;
1397
+ }).flat()));
1398
+ // ETH and WBTC needed for other tokens prices
1399
+ if (!tokens.includes('ETH'))
1400
+ tokens.push('ETH');
1401
+ if (!tokens.includes('WBTC'))
1402
+ tokens.push('WBTC');
1403
+ const [tokenPrices, merklCampaigns] = yield Promise.all([
1404
+ getTokensPricesForPortfolio(tokens, provider, network),
1405
+ getFluidMerklCampaigns(network),
1406
+ ]);
1407
+ const parsedMarketsData = yield Promise.all(vaultsData.map((vaultData) => __awaiter(void 0, void 0, void 0, function* () { return parseMarketData(provider, vaultData, network, tokenPrices); })));
1408
+ const marketsData = {};
1409
+ parsedMarketsData.forEach((marketData, i) => {
1410
+ if (!marketData)
1411
+ return;
1412
+ marketsData[versions[i].value] = attachFluidMerklIncentives(marketData, merklCampaigns);
1413
+ });
1414
+ return marketsData;
1415
+ });
1416
+ export const getAllFluidMarketDataPortfolio = (provider, network) => __awaiter(void 0, void 0, void 0, function* () { return _getAllFluidMarketDataPortfolio(getViemProvider(provider, network, { batch: { multicall: true } }), network); });
@@ -1,4 +1,4 @@
1
- import { AaveHelperCommon, AaveMarketInfo, AaveV3AggregatedPositionData, AaveV3AssetsData, AaveV3UsedAsset, AaveV3UsedAssets, AaveVersions } from '../../types';
1
+ import { AaveHelperCommon, AaveMarketInfo, AaveV3AggregatedPositionData, AaveV3AssetsData, AaveV3UsedAsset, AaveV3UsedAssets, AaveVersions, EModeCategoriesData } from '../../types';
2
2
  import { EthereumProvider, NetworkNumber } from '../../types/common';
3
3
  export declare const AAVE_V3_MARKETS: AaveVersions[];
4
4
  export declare const isAaveV2: ({ selectedMarket }: {
@@ -15,6 +15,14 @@ export declare const aaveV3IsInSiloedMode: ({ usedAssets, assetsData }: {
15
15
  usedAssets: AaveV3UsedAssets;
16
16
  assetsData: AaveV3AssetsData;
17
17
  }) => boolean;
18
+ export declare const aaveV3IsEmodeIsolated: ({ eModeCategory, eModeCategoriesData }: {
19
+ eModeCategory: number;
20
+ eModeCategoriesData?: EModeCategoriesData;
21
+ }) => boolean;
22
+ export declare const aaveV3CanBeCollateralInEmode: ({ eModeCategory, eModeCategoriesData }: {
23
+ eModeCategory: number;
24
+ eModeCategoriesData?: EModeCategoriesData;
25
+ }, _asset: string) => boolean;
18
26
  export declare const aaveAnyGetCollSuppliedAssets: ({ usedAssets }: {
19
27
  usedAssets: AaveV3UsedAssets;
20
28
  }) => AaveV3UsedAsset[];
@@ -33,6 +33,12 @@ export const isAaveV2 = ({ selectedMarket }) => selectedMarket.value === AaveVer
33
33
  export const isAaveV3 = ({ selectedMarket }) => AAVE_V3_MARKETS.includes(selectedMarket.value);
34
34
  export const aaveV3IsInIsolationMode = ({ usedAssets, assetsData }) => Object.values(usedAssets).some(({ symbol, collateral }) => collateral && assetsData[symbol].isIsolated);
35
35
  export const aaveV3IsInSiloedMode = ({ usedAssets, assetsData }) => Object.values(usedAssets).some(({ symbol, debt }) => debt && assetsData[symbol].isSiloed);
36
+ export const aaveV3IsEmodeIsolated = ({ eModeCategory, eModeCategoriesData }) => { var _a; return eModeCategory !== 0 && !!((_a = eModeCategoriesData === null || eModeCategoriesData === void 0 ? void 0 : eModeCategoriesData[eModeCategory]) === null || _a === void 0 ? void 0 : _a.isolated); };
37
+ export const aaveV3CanBeCollateralInEmode = ({ eModeCategory, eModeCategoriesData }, _asset) => {
38
+ if (!aaveV3IsEmodeIsolated({ eModeCategory, eModeCategoriesData }))
39
+ return true;
40
+ return eModeCategoriesData[eModeCategory].collateralAssets.includes(getNativeAssetFromWrapped(_asset));
41
+ };
36
42
  export const aaveAnyGetCollSuppliedAssets = ({ usedAssets }) => Object.values(usedAssets)
37
43
  .filter(({ isSupplied, collateral }) => isSupplied && collateral);
38
44
  export const aaveAnyGetSuppliableAssets = (_a) => {
@@ -40,13 +46,16 @@ export const aaveAnyGetSuppliableAssets = (_a) => {
40
46
  const data = Object.assign({ usedAssets, eModeCategory, assetsData, selectedMarket, network }, rest);
41
47
  const collAccountAssets = aaveAnyGetCollSuppliedAssets(data);
42
48
  const marketAssets = Object.values(assetsData);
43
- if (collAccountAssets.length === 0 || !isAaveV3(data))
49
+ if (!isAaveV3(data))
44
50
  return marketAssets.filter(({ canBeSupplied }) => canBeSupplied).map(({ symbol }) => ({ symbol, canBeCollateral: true }));
51
+ const canBeCollateralInEmode = (symbol) => aaveV3CanBeCollateralInEmode(data, symbol);
52
+ if (collAccountAssets.length === 0)
53
+ return marketAssets.filter(({ canBeSupplied }) => canBeSupplied).map(({ symbol }) => ({ symbol, canBeCollateral: canBeCollateralInEmode(symbol) }));
45
54
  if (aaveV3IsInIsolationMode(data)) {
46
55
  const collAsset = collAccountAssets[0].symbol;
47
- return marketAssets.filter(d => d.canBeSupplied).map(({ symbol }) => ({ symbol, canBeCollateral: symbol === collAsset }));
56
+ return marketAssets.filter(d => d.canBeSupplied).map(({ symbol }) => ({ symbol, canBeCollateral: symbol === collAsset && canBeCollateralInEmode(symbol) }));
48
57
  }
49
- return marketAssets.filter(d => d.canBeSupplied).map(({ symbol, isIsolated }) => ({ symbol, canBeCollateral: !isIsolated }));
58
+ return marketAssets.filter(d => d.canBeSupplied).map(({ symbol, isIsolated }) => ({ symbol, canBeCollateral: !isIsolated && canBeCollateralInEmode(symbol) }));
50
59
  };
51
60
  export const aaveAnyGetSuppliableAsCollAssets = (_a) => {
52
61
  var { usedAssets, eModeCategory, assetsData, selectedMarket, network } = _a, rest = __rest(_a, ["usedAssets", "eModeCategory", "assetsData", "selectedMarket", "network"]);
@@ -56,12 +65,15 @@ export const aaveAnyGetEmodeMutableProps = ({ eModeCategory, eModeCategoriesData
56
65
  const asset = getNativeAssetFromWrapped(_asset);
57
66
  const assetData = assetsData[asset];
58
67
  const eModeCategoryData = (eModeCategoriesData === null || eModeCategoriesData === void 0 ? void 0 : eModeCategoriesData[eModeCategory]) || {
59
- collateralAssets: [], ltvZeroAssets: [], collateralFactor: '0', liquidationRatio: '0',
68
+ collateralAssets: [], ltvZeroAssets: [], collateralFactor: '0', liquidationRatio: '0', isolated: false,
60
69
  };
61
70
  if (eModeCategory === 0
62
71
  || !eModeCategoryData.collateralAssets.includes(asset)
63
72
  || new Dec(eModeCategoryData.collateralFactor || 0).eq(0)) {
64
73
  const { liquidationRatio, collateralFactor } = assetData;
74
+ if (eModeCategory !== 0 && eModeCategoryData.isolated && !eModeCategoryData.collateralAssets.includes(asset)) {
75
+ return ({ liquidationRatio, collateralFactor: '0' });
76
+ }
65
77
  return ({ liquidationRatio, collateralFactor });
66
78
  }
67
79
  if (eModeCategoryData.ltvZeroAssets.includes(asset))
@@ -96,7 +108,10 @@ export const aaveAnyGetUserReserveLtvAndLltv = ({ eModeCategory, eModeCategories
96
108
  || !eModeCategoryData
97
109
  || !eModeCategoryData.collateralAssets.includes(asset)
98
110
  || new Dec(eModeCategoryData.collateralFactor || 0).eq(0)) {
99
- return { ltv: assetData.collateralFactor, lltv: assetData.liquidationRatio };
111
+ const ltv = eModeCategory !== 0 && (eModeCategoryData === null || eModeCategoryData === void 0 ? void 0 : eModeCategoryData.isolated) && !eModeCategoryData.collateralAssets.includes(asset)
112
+ ? '0'
113
+ : assetData.collateralFactor;
114
+ return { ltv, lltv: assetData.liquidationRatio };
100
115
  }
101
116
  const ltv = eModeCategoryData.ltvZeroAssets.includes(asset) ? '0' : eModeCategoryData.collateralFactor;
102
117
  return { ltv, lltv: eModeCategoryData.liquidationRatio };
@@ -125,6 +140,9 @@ export const aaveAnyGetAggregatedPositionData = (_a) => {
125
140
  return new Dec(suppliedUsd).mul(effectiveLtv);
126
141
  });
127
142
  payload.safetyRatioWithLtvZeroFallback = +payload.suppliedUsd ? new Dec(payload.borrowLimitWithLtvZeroFallbackUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
143
+ // Normalised safety ratio (100 = liquidation on every protocol): the automation ratio above, falling back
144
+ // to the regular ratio when the fallback carries its '0' placeholder.
145
+ payload.safetyRatio = +payload.safetyRatioWithLtvZeroFallback ? payload.safetyRatioWithLtvZeroFallback : payload.ratio;
128
146
  payload.liqRatio = new Dec(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).toString();
129
147
  payload.liqPercent = new Dec(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).mul(100).toString();
130
148
  const { leveragedType, leveragedAsset } = isLeveragedPos(usedAssets);
@@ -208,6 +208,7 @@ export const aaveV4GetAggregatedPositionData = ({ usedAssets, assetsData, networ
208
208
  payload.ratio = +payload.suppliedUsd ? new Dec(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
209
209
  payload.minRatio = '100';
210
210
  payload.collRatio = +payload.suppliedUsd ? new Dec(payload.suppliedCollateralUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
211
+ payload.safetyRatio = payload.ratio;
211
212
  payload.liqRatio = new Dec(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).toString();
212
213
  payload.liqPercent = new Dec(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).mul(100).toString();
213
214
  const { leveragedType, leveragedAsset } = isLeveragedPosAaveV4(usedAssets);
@@ -93,6 +93,7 @@ export const getCompoundV2AggregatedData = (_a) => {
93
93
  payload.collRatio = payload.borrowedUsd && payload.borrowedUsd !== '0'
94
94
  ? new Dec(payload.suppliedCollateralUsd).div(payload.borrowedUsd).mul(100).toString()
95
95
  : '0';
96
+ payload.safetyRatio = payload.ratio;
96
97
  // Calculate borrow limits per asset
97
98
  Object.values(usedAssets).forEach((item) => {
98
99
  if (item.isBorrowed) {
@@ -134,6 +135,7 @@ export const getCompoundV3AggregatedData = (_a) => {
134
135
  payload.incentiveUsd = incentiveUsd;
135
136
  payload.totalInterestUsd = totalInterestUsd;
136
137
  payload.minRatio = '100';
138
+ payload.safetyRatio = payload.ratio;
137
139
  payload.liqRatio = new Dec(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).toString();
138
140
  payload.liqPercent = new Dec(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).mul(100).toString();
139
141
  payload.minDebt = assetsData[selectedMarket.baseAsset].minDebt;
@@ -1,9 +1,11 @@
1
1
  import { CrvUSDAggregatedPositionData, CrvUSDMarketData, CrvUSDUsedAssets } from '../../types';
2
2
  import { NetworkNumber } from '../../types/common';
3
- export declare const getCrvUsdAggregatedData: ({ loanExists, usedAssets, network, selectedMarket, numOfBands, ...rest }: {
3
+ export declare const getCrvUsdAggregatedData: ({ loanExists, usedAssets, network, selectedMarket, numOfBands, borrowRate, collStakingApy, ...rest }: {
4
4
  loanExists: boolean;
5
5
  usedAssets: CrvUSDUsedAssets;
6
6
  network: NetworkNumber;
7
7
  selectedMarket: CrvUSDMarketData;
8
8
  numOfBands: number | string;
9
+ borrowRate?: string;
10
+ collStakingApy?: string;
9
11
  }) => CrvUSDAggregatedPositionData;
@@ -10,11 +10,12 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  return t;
11
11
  };
12
12
  import Dec from 'decimal.js';
13
- import { calcLeverageLiqPrice, getAssetsTotal, getExposure, isLeveragedPos, } from '../../moneymarket';
13
+ import { calcLeverageLiqPrice, getAssetsTotal, getExposure, getSafetyRatioFromCollateralRatio, isLeveragedPos, } from '../../moneymarket';
14
14
  import { mapRange } from '../../services/utils';
15
+ import { calculateNetApyFromRates } from '../../staking';
15
16
  export const getCrvUsdAggregatedData = (_a) => {
16
- var _b;
17
- var { loanExists, usedAssets, network, selectedMarket, numOfBands } = _a, rest = __rest(_a, ["loanExists", "usedAssets", "network", "selectedMarket", "numOfBands"]);
17
+ var _b, _c;
18
+ var { loanExists, usedAssets, network, selectedMarket, numOfBands, borrowRate = '0', collStakingApy = '0' } = _a, rest = __rest(_a, ["loanExists", "usedAssets", "network", "selectedMarket", "numOfBands", "borrowRate", "collStakingApy"]);
18
19
  const payload = {};
19
20
  payload.supplied = getAssetsTotal(usedAssets, ({ isSupplied }) => isSupplied, ({ supplied }) => supplied); // this is wrong if we are in soft-liquidations
20
21
  payload.borrowed = getAssetsTotal(usedAssets, ({ isBorrowed }) => isBorrowed, ({ borrowed }) => borrowed);
@@ -28,6 +29,7 @@ export const getCrvUsdAggregatedData = (_a) => {
28
29
  : '0';
29
30
  // this is all approximation
30
31
  payload.minAllowedRatio = mapRange(numOfBands, 4, 50, 115, 140); // collateral ratio
32
+ payload.safetyRatio = loanExists ? getSafetyRatioFromCollateralRatio(payload.ratio, payload.minAllowedRatio) : '0';
31
33
  payload.collFactor = new Dec(1).div(payload.minAllowedRatio).mul(100).toString(); // collateral factor = 1 / collateral ratio
32
34
  // only take in consideration collAsset
33
35
  payload.borrowLimitUsd = ((_b = usedAssets === null || usedAssets === void 0 ? void 0 : usedAssets[selectedMarket.collAsset]) === null || _b === void 0 ? void 0 : _b.isSupplied)
@@ -41,5 +43,16 @@ export const getCrvUsdAggregatedData = (_a) => {
41
43
  payload.liquidationPrice = calcLeverageLiqPrice(leveragedType, usedAssets[selectedMarket.collAsset].price, payload.borrowedUsd, payload.borrowLimitUsd);
42
44
  }
43
45
  payload.exposure = getExposure(payload.borrowedUsd, payload.suppliedUsd);
46
+ // crvUSD debt accrues the market borrow rate. Collateral (including crvUSD held during soft liquidation) earns
47
+ // nothing from the protocol itself; only the native yield of staked collateral is counted, as an incentive.
48
+ const { netApy, totalInterestUsd, incentiveUsd } = calculateNetApyFromRates({
49
+ suppliedUsd: payload.suppliedUsd,
50
+ borrowedUsd: payload.borrowedUsd,
51
+ borrowRate,
52
+ incentives: [{ apy: collStakingApy, amountUsd: ((_c = usedAssets === null || usedAssets === void 0 ? void 0 : usedAssets[selectedMarket.collAsset]) === null || _c === void 0 ? void 0 : _c.suppliedUsd) || '0' }],
53
+ });
54
+ payload.netApy = netApy;
55
+ payload.totalInterestUsd = totalInterestUsd;
56
+ payload.incentiveUsd = incentiveUsd;
44
57
  return payload;
45
58
  };
@@ -78,6 +78,7 @@ export const getFluidAggregatedData = ({ usedAssets, assetsData, marketData, },
78
78
  payload.ratio = +payload.suppliedUsd ? new Dec(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
79
79
  payload.collRatio = +payload.suppliedUsd ? new Dec(payload.suppliedUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
80
80
  payload.minRatio = marketData.minRatio;
81
+ payload.safetyRatio = payload.ratio;
81
82
  const { leveragedType, leveragedAsset } = isLeveragedPos(usedAssets);
82
83
  payload.leveragedType = leveragedType;
83
84
  payload.liquidationPrice = '';
@@ -41,6 +41,7 @@ export const getLiquityV2AggregatedPositionData = ({ usedAssets, assetsData, min
41
41
  payload.leftToBorrowUsd = leftToBorrowUsd.lte('0') ? '0' : leftToBorrowUsd.toString();
42
42
  payload.ratio = (+payload.suppliedUsd && +payload.borrowedUsd) ? new Dec(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
43
43
  payload.collRatio = (+payload.suppliedUsd && +payload.borrowedUsd) ? new Dec(payload.suppliedUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
44
+ payload.safetyRatio = payload.ratio;
44
45
  const { netApy, incentiveUsd, totalInterestUsd } = calculateNetApyLiquityV2(usedAssets, assetsData, interestRate);
45
46
  payload.netApy = netApy;
46
47
  payload.incentiveUsd = incentiveUsd;