@defisaver/positions-sdk 2.1.162 → 2.1.164

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 (120) hide show
  1. package/cjs/aaveV2/index.js +2 -0
  2. package/cjs/curveUsd/index.d.ts +5 -2
  3. package/cjs/curveUsd/index.js +30 -15
  4. package/cjs/fluid/index.d.ts +5 -0
  5. package/cjs/fluid/index.js +36 -1
  6. package/cjs/helpers/aaveHelpers/index.js +3 -0
  7. package/cjs/helpers/aaveV4Helpers/index.js +1 -0
  8. package/cjs/helpers/compoundHelpers/index.js +2 -0
  9. package/cjs/helpers/curveUsdHelpers/index.d.ts +3 -1
  10. package/cjs/helpers/curveUsdHelpers/index.js +15 -2
  11. package/cjs/helpers/fluidHelpers/index.js +1 -0
  12. package/cjs/helpers/liquityV2Helpers/index.js +1 -0
  13. package/cjs/helpers/llamaLendHelpers/index.js +1 -0
  14. package/cjs/helpers/makerHelpers/index.d.ts +1 -1
  15. package/cjs/helpers/makerHelpers/index.js +2 -2
  16. package/cjs/helpers/morphoBlueHelpers/index.js +2 -0
  17. package/cjs/helpers/morphoMidnightHelpers/index.js +2 -0
  18. package/cjs/helpers/sparkHelpers/index.js +1 -0
  19. package/cjs/liquity/index.js +15 -2
  20. package/cjs/maker/index.d.ts +7 -2
  21. package/cjs/maker/index.js +44 -12
  22. package/cjs/markets/index.d.ts +1 -0
  23. package/cjs/markets/index.js +3 -1
  24. package/cjs/markets/maker/index.d.ts +1 -0
  25. package/cjs/markets/maker/index.js +13 -0
  26. package/cjs/moneymarket/moneymarketCommonService.d.ts +9 -0
  27. package/cjs/moneymarket/moneymarketCommonService.js +13 -1
  28. package/cjs/portfolio/index.d.ts +5 -1
  29. package/cjs/portfolio/index.js +282 -16
  30. package/cjs/staking/staking.d.ts +20 -0
  31. package/cjs/staking/staking.js +19 -1
  32. package/cjs/types/aave.d.ts +2 -0
  33. package/cjs/types/aaveV4.d.ts +1 -0
  34. package/cjs/types/compound.d.ts +2 -0
  35. package/cjs/types/curveUsd.d.ts +6 -0
  36. package/cjs/types/fluid.d.ts +1 -0
  37. package/cjs/types/liquity.d.ts +4 -0
  38. package/cjs/types/liquityV2.d.ts +2 -0
  39. package/cjs/types/maker.d.ts +4 -0
  40. package/cjs/types/morphoBlue.d.ts +2 -0
  41. package/cjs/types/morphoMidnight.d.ts +1 -0
  42. package/cjs/types/portfolio.d.ts +26 -10
  43. package/cjs/types/spark.d.ts +2 -0
  44. package/esm/aaveV2/index.js +2 -0
  45. package/esm/curveUsd/index.d.ts +5 -2
  46. package/esm/curveUsd/index.js +30 -15
  47. package/esm/fluid/index.d.ts +5 -0
  48. package/esm/fluid/index.js +33 -0
  49. package/esm/helpers/aaveHelpers/index.js +3 -0
  50. package/esm/helpers/aaveV4Helpers/index.js +1 -0
  51. package/esm/helpers/compoundHelpers/index.js +2 -0
  52. package/esm/helpers/curveUsdHelpers/index.d.ts +3 -1
  53. package/esm/helpers/curveUsdHelpers/index.js +16 -3
  54. package/esm/helpers/fluidHelpers/index.js +1 -0
  55. package/esm/helpers/liquityV2Helpers/index.js +1 -0
  56. package/esm/helpers/llamaLendHelpers/index.js +2 -1
  57. package/esm/helpers/makerHelpers/index.d.ts +1 -1
  58. package/esm/helpers/makerHelpers/index.js +2 -2
  59. package/esm/helpers/morphoBlueHelpers/index.js +2 -0
  60. package/esm/helpers/morphoMidnightHelpers/index.js +2 -0
  61. package/esm/helpers/sparkHelpers/index.js +1 -0
  62. package/esm/liquity/index.js +16 -3
  63. package/esm/maker/index.d.ts +7 -2
  64. package/esm/maker/index.js +44 -14
  65. package/esm/markets/index.d.ts +1 -0
  66. package/esm/markets/index.js +1 -0
  67. package/esm/markets/maker/index.d.ts +1 -0
  68. package/esm/markets/maker/index.js +10 -0
  69. package/esm/moneymarket/moneymarketCommonService.d.ts +9 -0
  70. package/esm/moneymarket/moneymarketCommonService.js +11 -0
  71. package/esm/portfolio/index.d.ts +5 -1
  72. package/esm/portfolio/index.js +284 -19
  73. package/esm/staking/staking.d.ts +20 -0
  74. package/esm/staking/staking.js +17 -0
  75. package/esm/types/aave.d.ts +2 -0
  76. package/esm/types/aaveV4.d.ts +1 -0
  77. package/esm/types/compound.d.ts +2 -0
  78. package/esm/types/curveUsd.d.ts +6 -0
  79. package/esm/types/fluid.d.ts +1 -0
  80. package/esm/types/liquity.d.ts +4 -0
  81. package/esm/types/liquityV2.d.ts +2 -0
  82. package/esm/types/maker.d.ts +4 -0
  83. package/esm/types/morphoBlue.d.ts +2 -0
  84. package/esm/types/morphoMidnight.d.ts +1 -0
  85. package/esm/types/portfolio.d.ts +26 -10
  86. package/esm/types/spark.d.ts +2 -0
  87. package/package.json +1 -1
  88. package/src/aaveV2/index.ts +2 -0
  89. package/src/curveUsd/index.ts +33 -16
  90. package/src/fluid/index.ts +40 -0
  91. package/src/helpers/aaveHelpers/index.ts +3 -0
  92. package/src/helpers/aaveV4Helpers/index.ts +1 -0
  93. package/src/helpers/compoundHelpers/index.ts +2 -0
  94. package/src/helpers/curveUsdHelpers/index.ts +23 -3
  95. package/src/helpers/fluidHelpers/index.ts +1 -0
  96. package/src/helpers/liquityV2Helpers/index.ts +1 -0
  97. package/src/helpers/llamaLendHelpers/index.ts +2 -1
  98. package/src/helpers/makerHelpers/index.ts +2 -1
  99. package/src/helpers/morphoBlueHelpers/index.ts +2 -0
  100. package/src/helpers/morphoMidnightHelpers/index.ts +2 -0
  101. package/src/helpers/sparkHelpers/index.ts +1 -0
  102. package/src/liquity/index.ts +17 -3
  103. package/src/maker/index.ts +77 -30
  104. package/src/markets/index.ts +2 -1
  105. package/src/markets/maker/index.ts +10 -0
  106. package/src/moneymarket/moneymarketCommonService.ts +15 -0
  107. package/src/portfolio/index.ts +262 -5
  108. package/src/staking/staking.ts +28 -0
  109. package/src/types/aave.ts +3 -0
  110. package/src/types/aaveV4.ts +1 -0
  111. package/src/types/compound.ts +2 -0
  112. package/src/types/curveUsd.ts +7 -0
  113. package/src/types/fluid.ts +1 -0
  114. package/src/types/liquity.ts +6 -0
  115. package/src/types/liquityV2.ts +2 -0
  116. package/src/types/maker.ts +6 -0
  117. package/src/types/morphoBlue.ts +2 -0
  118. package/src/types/morphoMidnight.ts +1 -0
  119. package/src/types/portfolio.ts +31 -12
  120. package/src/types/spark.ts +2 -0
@@ -177,6 +177,8 @@ const _getAaveV2AccountData = (provider, network, address, assetsData, market) =
177
177
  payload.collRatio = payload.borrowedUsd && payload.borrowedUsd !== '0'
178
178
  ? new decimal_js_1.default(payload.suppliedCollateralUsd).div(payload.borrowedUsd).mul(100).toString()
179
179
  : '0';
180
+ // Aave v2 has no LTV-0 fallback (AaveV3View only), so its safety ratio is the plain ratio.
181
+ payload.safetyRatio = payload.ratio;
180
182
  // Calculate borrow limits per asset
181
183
  Object.values(payload.usedAssets).forEach((item) => {
182
184
  if (item.isBorrowed) {
@@ -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>;
@@ -22,6 +22,12 @@ const curveUsdHelpers_1 = require("../helpers/curveUsdHelpers");
22
22
  const markets_1 = require("../markets");
23
23
  const utils_1 = require("../services/utils");
24
24
  const viem_1 = require("../services/viem");
25
+ const staking_1 = require("../staking");
26
+ /** Converts a per-second AMM rate (wei, 18 decimals) into a yearly compounded borrow APY in %. */
27
+ const ammRateToBorrowApy = (rateWei) => {
28
+ const exponent = new decimal_js_1.default((0, tokens_1.assetAmountInEth)(rateWei)).mul(365).mul(86400);
29
+ return new decimal_js_1.default(new decimal_js_1.default(2.718281828459).pow(exponent).minus(1)).mul(100).toString();
30
+ };
25
31
  const getAndFormatBands = (provider, network, selectedMarket, _minBand, _maxBand) => __awaiter(void 0, void 0, void 0, function* () {
26
32
  const contract = (0, contracts_1.CrvUSDViewContractViem)(provider, network);
27
33
  const minBand = parseInt(_minBand, 10);
@@ -71,14 +77,8 @@ const _getCurveUsdGlobalData = (provider, network, selectedMarket) => __awaiter(
71
77
  // all prices are in 18 decimals
72
78
  const totalDebt = (0, tokens_1.assetAmountInEth)(data.totalDebt.toString(), debtAsset);
73
79
  const ammPrice = (0, tokens_1.assetAmountInEth)(data.ammPrice.toString(), debtAsset);
74
- const rate = (0, tokens_1.assetAmountInEth)(data.ammRate.toString());
75
- const futureRate = (0, tokens_1.assetAmountInEth)(data.monetaryPolicyRate.toString());
76
- const exponentRate = new decimal_js_1.default(rate).mul(365).mul(86400);
77
- const exponentFutureRate = new decimal_js_1.default(futureRate).mul(365).mul(86400);
78
- const borrowRate = new decimal_js_1.default(new decimal_js_1.default(2.718281828459).pow(exponentRate).minus(1)).mul(100)
79
- .toString();
80
- const futureBorrowRate = new decimal_js_1.default(new decimal_js_1.default(2.718281828459).pow(exponentFutureRate).minus(1)).mul(100)
81
- .toString();
80
+ const borrowRate = ammRateToBorrowApy(data.ammRate.toString());
81
+ const futureBorrowRate = ammRateToBorrowApy(data.monetaryPolicyRate.toString());
82
82
  const bandsData = yield getAndFormatBands(provider, network, selectedMarket, data.minBand.toString(), data.maxBand.toString());
83
83
  const leftToBorrow = new decimal_js_1.default(debtCeiling.toString()).minus(totalDebt).toString();
84
84
  const loanDiscount = (0, tokens_1.assetAmountInEth)(loanDiscountWei.toString(), debtAsset);
@@ -131,11 +131,20 @@ const _getCrvUsdAccountBalances = (provider, network, block, addressMapping, add
131
131
  exports._getCrvUsdAccountBalances = _getCrvUsdAccountBalances;
132
132
  const getCrvUsdAccountBalances = (provider, network, block, addressMapping, address, controllerAddress) => __awaiter(void 0, void 0, void 0, function* () { return (0, exports._getCrvUsdAccountBalances)((0, viem_1.getViemProvider)(provider, network), network, block, addressMapping, address, controllerAddress); });
133
133
  exports.getCrvUsdAccountBalances = getCrvUsdAccountBalances;
134
- const _getCurveUsdUserData = (provider, network, address, selectedMarket, activeBand) => __awaiter(void 0, void 0, void 0, function* () {
134
+ /**
135
+ * @param borrowRate market borrow APY in % (`CrvUSDGlobalMarketData.borrowRate`); when omitted it is read from the view contract
136
+ */
137
+ const _getCurveUsdUserData = (provider, network, address, selectedMarket, activeBand, borrowRate) => __awaiter(void 0, void 0, void 0, function* () {
135
138
  const contract = (0, contracts_1.CrvUSDViewContractViem)(provider, network);
136
- const data = yield contract.read.userData([selectedMarket.controllerAddress, address]);
137
139
  const collAsset = selectedMarket.collAsset;
138
140
  const debtAsset = selectedMarket.baseAsset;
141
+ const [data, collStakingApy, marketBorrowRate] = yield Promise.all([
142
+ contract.read.userData([selectedMarket.controllerAddress, address]),
143
+ staking_1.STAKING_ASSETS.includes(collAsset) ? (0, staking_1.getStakingApy)(collAsset) : Promise.resolve('0'),
144
+ borrowRate !== undefined
145
+ ? Promise.resolve(borrowRate)
146
+ : contract.read.globalData([selectedMarket.controllerAddress]).then((globalData) => ammRateToBorrowApy(globalData.ammRate.toString())),
147
+ ]);
139
148
  const health = (0, tokens_1.assetAmountInEth)(data.health.toString());
140
149
  const healthPercent = new decimal_js_1.default(health).mul(100).toString();
141
150
  const collPrice = (0, tokens_1.assetAmountInEth)(data.collateralPrice.toString(), debtAsset);
@@ -166,7 +175,7 @@ const _getCurveUsdUserData = (provider, network, address, selectedMarket, active
166
175
  isBorrowed: new decimal_js_1.default(debtBorrowed).gt('0'),
167
176
  symbol: 'crvUSD',
168
177
  price: '1',
169
- interestRate: '0',
178
+ interestRate: marketBorrowRate,
170
179
  },
171
180
  } : {};
172
181
  const priceHigh = (0, tokens_1.assetAmountInEth)(data.priceHigh.toString());
@@ -178,16 +187,22 @@ const _getCurveUsdUserData = (provider, network, address, selectedMarket, active
178
187
  healthPercent,
179
188
  priceHigh,
180
189
  priceLow, liquidationDiscount: (0, tokens_1.assetAmountInEth)(data.liquidationDiscount.toString()), numOfBands: data.N.toString(), usedAssets,
181
- status }), (0, curveUsdHelpers_1.getCrvUsdAggregatedData)({
182
- loanExists: data.loanExists, usedAssets, network: common_1.NetworkNumber.Eth, selectedMarket, numOfBands: data.N.toString(),
190
+ status, borrowRate: marketBorrowRate }), (0, curveUsdHelpers_1.getCrvUsdAggregatedData)({
191
+ loanExists: data.loanExists,
192
+ usedAssets,
193
+ network: common_1.NetworkNumber.Eth,
194
+ selectedMarket,
195
+ numOfBands: data.N.toString(),
196
+ borrowRate: marketBorrowRate,
197
+ collStakingApy,
183
198
  })), { userBands });
184
199
  });
185
200
  exports._getCurveUsdUserData = _getCurveUsdUserData;
186
- const getCurveUsdUserData = (provider, network, address, selectedMarket, activeBand) => __awaiter(void 0, void 0, void 0, function* () { return (0, exports._getCurveUsdUserData)((0, viem_1.getViemProvider)(provider, network), network, address, selectedMarket, activeBand); });
201
+ const getCurveUsdUserData = (provider, network, address, selectedMarket, activeBand, borrowRate) => __awaiter(void 0, void 0, void 0, function* () { return (0, exports._getCurveUsdUserData)((0, viem_1.getViemProvider)(provider, network), network, address, selectedMarket, activeBand, borrowRate); });
187
202
  exports.getCurveUsdUserData = getCurveUsdUserData;
188
203
  const getCurveUsdFullPositionData = (provider, network, address, selectedMarket) => __awaiter(void 0, void 0, void 0, function* () {
189
204
  const marketData = yield (0, exports.getCurveUsdGlobalData)(provider, network, selectedMarket);
190
- const positionData = yield (0, exports.getCurveUsdUserData)(provider, network, address, selectedMarket, marketData.activeBand);
205
+ const positionData = yield (0, exports.getCurveUsdUserData)(provider, network, address, selectedMarket, marketData.activeBand, marketData.borrowRate);
191
206
  return positionData;
192
207
  });
193
208
  exports.getCurveUsdFullPositionData = getCurveUsdFullPositionData;
@@ -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>>;
@@ -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._getUserPositionsPortfolio = exports.getUserPositions = exports._getUserPositions = exports.getAllUserEarnPositionsWithFTokens = exports._getAllUserEarnPositionsWithFTokens = exports.getFluidDepositData = exports._getFluidDepositData = exports.getFluidTokenData = exports._getFluidTokenData = exports.getAllFluidMarketDataChunked = exports._getAllFluidMarketDataChunked = exports.getFluidPositionWithMarket = exports._getFluidPositionWithMarket = exports.getFluidPosition = exports._getFluidPosition = exports.getFluidVaultIdsForUser = exports._getFluidVaultIdsForUser = exports.getFluidMarketData = exports._getFluidMarketData = exports.EMPTY_FLUID_DATA = exports.EMPTY_USED_ASSET = exports.attachFluidMerklIncentives = exports.getFluidMerklCampaigns = exports.buildFluidMerklRewardMap = exports.FluidMerklOpportunityType = void 0;
15
+ exports.getAllFluidMarketDataPortfolio = exports._getAllFluidMarketDataPortfolio = exports._getUserPositionsPortfolio = exports.getUserPositions = exports._getUserPositions = exports.getAllUserEarnPositionsWithFTokens = exports._getAllUserEarnPositionsWithFTokens = exports.getFluidDepositData = exports._getFluidDepositData = exports.getFluidTokenData = exports._getFluidTokenData = exports.getAllFluidMarketDataChunked = exports._getAllFluidMarketDataChunked = exports.getFluidPositionWithMarket = exports._getFluidPositionWithMarket = exports.getFluidPosition = exports._getFluidPosition = exports.getFluidVaultIdsForUser = exports._getFluidVaultIdsForUser = exports.getFluidMarketData = exports._getFluidMarketData = exports.EMPTY_FLUID_DATA = exports.EMPTY_USED_ASSET = exports.attachFluidMerklIncentives = exports.getFluidMerklCampaigns = exports.buildFluidMerklRewardMap = exports.FluidMerklOpportunityType = void 0;
16
16
  const decimal_js_1 = __importDefault(require("decimal.js"));
17
17
  const tokens_1 = require("@defisaver/tokens");
18
18
  const common_1 = require("../types/common");
@@ -1410,3 +1410,38 @@ const _getUserPositionsPortfolio = (provider, network, user) => __awaiter(void 0
1410
1410
  })).filter(md => md.marketData !== undefined);
1411
1411
  });
1412
1412
  exports._getUserPositionsPortfolio = _getUserPositionsPortfolio;
1413
+ const _getAllFluidMarketDataPortfolio = (provider, network) => __awaiter(void 0, void 0, void 0, function* () {
1414
+ const versions = (0, markets_1.getFluidVersionsDataForNetwork)(network);
1415
+ if (versions.length === 0)
1416
+ return {};
1417
+ const view = (0, contracts_1.FluidViewContractViem)(provider, network);
1418
+ const vaultsData = yield Promise.all(versions.map((version) => view.read.getVaultData([version.marketAddress])));
1419
+ const tokens = Array.from(new Set(vaultsData.map((vaultData) => {
1420
+ const vaultTokens = [(0, tokens_1.getAssetInfoByAddress)(vaultData.supplyToken0, network).symbol, (0, tokens_1.getAssetInfoByAddress)(vaultData.borrowToken0, network).symbol];
1421
+ if (vaultData.supplyToken1 && !(0, utils_1.compareAddresses)(constants_1.ZERO_ADDRESS, vaultData.supplyToken1))
1422
+ vaultTokens.push((0, tokens_1.getAssetInfoByAddress)(vaultData.supplyToken1, network).symbol);
1423
+ if (vaultData.borrowToken1 && !(0, utils_1.compareAddresses)(constants_1.ZERO_ADDRESS, vaultData.borrowToken1))
1424
+ vaultTokens.push((0, tokens_1.getAssetInfoByAddress)(vaultData.borrowToken1, network).symbol);
1425
+ return vaultTokens;
1426
+ }).flat()));
1427
+ // ETH and WBTC needed for other tokens prices
1428
+ if (!tokens.includes('ETH'))
1429
+ tokens.push('ETH');
1430
+ if (!tokens.includes('WBTC'))
1431
+ tokens.push('WBTC');
1432
+ const [tokenPrices, merklCampaigns] = yield Promise.all([
1433
+ getTokensPricesForPortfolio(tokens, provider, network),
1434
+ (0, merkl_1.getFluidMerklCampaigns)(network),
1435
+ ]);
1436
+ const parsedMarketsData = yield Promise.all(vaultsData.map((vaultData) => __awaiter(void 0, void 0, void 0, function* () { return parseMarketData(provider, vaultData, network, tokenPrices); })));
1437
+ const marketsData = {};
1438
+ parsedMarketsData.forEach((marketData, i) => {
1439
+ if (!marketData)
1440
+ return;
1441
+ marketsData[versions[i].value] = (0, merkl_1.attachFluidMerklIncentives)(marketData, merklCampaigns);
1442
+ });
1443
+ return marketsData;
1444
+ });
1445
+ exports._getAllFluidMarketDataPortfolio = _getAllFluidMarketDataPortfolio;
1446
+ const getAllFluidMarketDataPortfolio = (provider, network) => __awaiter(void 0, void 0, void 0, function* () { return (0, exports._getAllFluidMarketDataPortfolio)((0, viem_1.getViemProvider)(provider, network, { batch: { multicall: true } }), network); });
1447
+ exports.getAllFluidMarketDataPortfolio = getAllFluidMarketDataPortfolio;
@@ -157,6 +157,9 @@ const aaveAnyGetAggregatedPositionData = (_a) => {
157
157
  return new decimal_js_1.default(suppliedUsd).mul(effectiveLtv);
158
158
  });
159
159
  payload.safetyRatioWithLtvZeroFallback = +payload.suppliedUsd ? new decimal_js_1.default(payload.borrowLimitWithLtvZeroFallbackUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
160
+ // Normalised safety ratio (100 = liquidation on every protocol): the automation ratio above, falling back
161
+ // to the regular ratio when the fallback carries its '0' placeholder.
162
+ payload.safetyRatio = +payload.safetyRatioWithLtvZeroFallback ? payload.safetyRatioWithLtvZeroFallback : payload.ratio;
160
163
  payload.liqRatio = new decimal_js_1.default(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).toString();
161
164
  payload.liqPercent = new decimal_js_1.default(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).mul(100).toString();
162
165
  const { leveragedType, leveragedAsset } = (0, moneymarket_1.isLeveragedPos)(usedAssets);
@@ -219,6 +219,7 @@ const aaveV4GetAggregatedPositionData = ({ usedAssets, assetsData, network, useU
219
219
  payload.ratio = +payload.suppliedUsd ? new decimal_js_1.default(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
220
220
  payload.minRatio = '100';
221
221
  payload.collRatio = +payload.suppliedUsd ? new decimal_js_1.default(payload.suppliedCollateralUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
222
+ payload.safetyRatio = payload.ratio;
222
223
  payload.liqRatio = new decimal_js_1.default(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).toString();
223
224
  payload.liqPercent = new decimal_js_1.default(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).mul(100).toString();
224
225
  const { leveragedType, leveragedAsset } = (0, exports.isLeveragedPosAaveV4)(usedAssets);
@@ -102,6 +102,7 @@ const getCompoundV2AggregatedData = (_a) => {
102
102
  payload.collRatio = payload.borrowedUsd && payload.borrowedUsd !== '0'
103
103
  ? new decimal_js_1.default(payload.suppliedCollateralUsd).div(payload.borrowedUsd).mul(100).toString()
104
104
  : '0';
105
+ payload.safetyRatio = payload.ratio;
105
106
  // Calculate borrow limits per asset
106
107
  Object.values(usedAssets).forEach((item) => {
107
108
  if (item.isBorrowed) {
@@ -144,6 +145,7 @@ const getCompoundV3AggregatedData = (_a) => {
144
145
  payload.incentiveUsd = incentiveUsd;
145
146
  payload.totalInterestUsd = totalInterestUsd;
146
147
  payload.minRatio = '100';
148
+ payload.safetyRatio = payload.ratio;
147
149
  payload.liqRatio = new decimal_js_1.default(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).toString();
148
150
  payload.liqPercent = new decimal_js_1.default(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).mul(100).toString();
149
151
  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;
@@ -18,9 +18,10 @@ exports.getCrvUsdAggregatedData = void 0;
18
18
  const decimal_js_1 = __importDefault(require("decimal.js"));
19
19
  const moneymarket_1 = require("../../moneymarket");
20
20
  const utils_1 = require("../../services/utils");
21
+ const staking_1 = require("../../staking");
21
22
  const getCrvUsdAggregatedData = (_a) => {
22
- var _b;
23
- var { loanExists, usedAssets, network, selectedMarket, numOfBands } = _a, rest = __rest(_a, ["loanExists", "usedAssets", "network", "selectedMarket", "numOfBands"]);
23
+ var _b, _c;
24
+ var { loanExists, usedAssets, network, selectedMarket, numOfBands, borrowRate = '0', collStakingApy = '0' } = _a, rest = __rest(_a, ["loanExists", "usedAssets", "network", "selectedMarket", "numOfBands", "borrowRate", "collStakingApy"]);
24
25
  const payload = {};
25
26
  payload.supplied = (0, moneymarket_1.getAssetsTotal)(usedAssets, ({ isSupplied }) => isSupplied, ({ supplied }) => supplied); // this is wrong if we are in soft-liquidations
26
27
  payload.borrowed = (0, moneymarket_1.getAssetsTotal)(usedAssets, ({ isBorrowed }) => isBorrowed, ({ borrowed }) => borrowed);
@@ -34,6 +35,7 @@ const getCrvUsdAggregatedData = (_a) => {
34
35
  : '0';
35
36
  // this is all approximation
36
37
  payload.minAllowedRatio = (0, utils_1.mapRange)(numOfBands, 4, 50, 115, 140); // collateral ratio
38
+ payload.safetyRatio = loanExists ? (0, moneymarket_1.getSafetyRatioFromCollateralRatio)(payload.ratio, payload.minAllowedRatio) : '0';
37
39
  payload.collFactor = new decimal_js_1.default(1).div(payload.minAllowedRatio).mul(100).toString(); // collateral factor = 1 / collateral ratio
38
40
  // only take in consideration collAsset
39
41
  payload.borrowLimitUsd = ((_b = usedAssets === null || usedAssets === void 0 ? void 0 : usedAssets[selectedMarket.collAsset]) === null || _b === void 0 ? void 0 : _b.isSupplied)
@@ -47,6 +49,17 @@ const getCrvUsdAggregatedData = (_a) => {
47
49
  payload.liquidationPrice = (0, moneymarket_1.calcLeverageLiqPrice)(leveragedType, usedAssets[selectedMarket.collAsset].price, payload.borrowedUsd, payload.borrowLimitUsd);
48
50
  }
49
51
  payload.exposure = (0, moneymarket_1.getExposure)(payload.borrowedUsd, payload.suppliedUsd);
52
+ // crvUSD debt accrues the market borrow rate. Collateral (including crvUSD held during soft liquidation) earns
53
+ // nothing from the protocol itself; only the native yield of staked collateral is counted, as an incentive.
54
+ const { netApy, totalInterestUsd, incentiveUsd } = (0, staking_1.calculateNetApyFromRates)({
55
+ suppliedUsd: payload.suppliedUsd,
56
+ borrowedUsd: payload.borrowedUsd,
57
+ borrowRate,
58
+ incentives: [{ apy: collStakingApy, amountUsd: ((_c = usedAssets === null || usedAssets === void 0 ? void 0 : usedAssets[selectedMarket.collAsset]) === null || _c === void 0 ? void 0 : _c.suppliedUsd) || '0' }],
59
+ });
60
+ payload.netApy = netApy;
61
+ payload.totalInterestUsd = totalInterestUsd;
62
+ payload.incentiveUsd = incentiveUsd;
50
63
  return payload;
51
64
  };
52
65
  exports.getCrvUsdAggregatedData = getCrvUsdAggregatedData;
@@ -85,6 +85,7 @@ const getFluidAggregatedData = ({ usedAssets, assetsData, marketData, }, supplyS
85
85
  payload.ratio = +payload.suppliedUsd ? new decimal_js_1.default(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
86
86
  payload.collRatio = +payload.suppliedUsd ? new decimal_js_1.default(payload.suppliedUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
87
87
  payload.minRatio = marketData.minRatio;
88
+ payload.safetyRatio = payload.ratio;
88
89
  const { leveragedType, leveragedAsset } = (0, moneymarket_1.isLeveragedPos)(usedAssets);
89
90
  payload.leveragedType = leveragedType;
90
91
  payload.liquidationPrice = '';
@@ -48,6 +48,7 @@ const getLiquityV2AggregatedPositionData = ({ usedAssets, assetsData, minCollRat
48
48
  payload.leftToBorrowUsd = leftToBorrowUsd.lte('0') ? '0' : leftToBorrowUsd.toString();
49
49
  payload.ratio = (+payload.suppliedUsd && +payload.borrowedUsd) ? new decimal_js_1.default(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
50
50
  payload.collRatio = (+payload.suppliedUsd && +payload.borrowedUsd) ? new decimal_js_1.default(payload.suppliedUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
51
+ payload.safetyRatio = payload.ratio;
51
52
  const { netApy, incentiveUsd, totalInterestUsd } = (0, exports.calculateNetApyLiquityV2)(usedAssets, assetsData, interestRate);
52
53
  payload.netApy = netApy;
53
54
  payload.incentiveUsd = incentiveUsd;
@@ -42,6 +42,7 @@ const getLlamaLendAggregatedData = (_a) => {
42
42
  : '0';
43
43
  // this is all approximation
44
44
  payload.minAllowedRatio = (0, utils_1.mapRange)(numOfBands, 4, 50, 115, 140); // collateral ratio
45
+ payload.safetyRatio = loanExists ? (0, moneymarket_1.getSafetyRatioFromCollateralRatio)(payload.ratio, payload.minAllowedRatio) : '0';
45
46
  payload.collFactor = new decimal_js_1.default(1).div(payload.minAllowedRatio).mul(100).toString(); // collateral factor = 1 / collateral ratio
46
47
  // only take in consideration collAsset
47
48
  payload.borrowLimitUsd = ((_b = usedAssets === null || usedAssets === void 0 ? void 0 : usedAssets[collAsset]) === null || _b === void 0 ? void 0 : _b.isSupplied)
@@ -1,4 +1,4 @@
1
- export declare const parseCollateralInfo: (ilk: string, _par: string, _mat: string, _art: string, _rate: string, _spot: string, _line: string, _duty: string, _futureRate: string, _chop: string) => {
1
+ export declare const parseCollateralInfo: (ilk: string, _par: string, _mat: string, _art: string, _rate: string, _spot: string, _line: string, _dust: string, _duty: string, _futureRate: string, _chop: string) => {
2
2
  ilkLabel: string;
3
3
  currentRate: string;
4
4
  futureRate: string;
@@ -7,14 +7,14 @@ exports.parseCollateralInfo = void 0;
7
7
  const decimal_js_1 = __importDefault(require("decimal.js"));
8
8
  const constants_1 = require("../../constants");
9
9
  const utils_1 = require("../../services/utils");
10
- const parseCollateralInfo = (ilk, _par, _mat, _art, _rate, _spot, _line, _duty, _futureRate, _chop) => {
10
+ const parseCollateralInfo = (ilk, _par, _mat, _art, _rate, _spot, _line, _dust, _duty, _futureRate, _chop) => {
11
11
  const par = new decimal_js_1.default(_par).div(1e27).toString();
12
12
  const mat = new decimal_js_1.default(_mat).div(1e27).toString();
13
13
  const art = new decimal_js_1.default(_art).toString();
14
14
  const rate = new decimal_js_1.default(_rate).toString();
15
15
  const spot = new decimal_js_1.default(_spot).div(1e27).toString();
16
16
  const line = new decimal_js_1.default(_line).div(1e45).toString();
17
- const dust = new decimal_js_1.default(_rate).div(1e45).toString();
17
+ const dust = new decimal_js_1.default(_dust).div(1e45).toString(); // Vat.ilks.dust, rad (1e45) -> DAI
18
18
  const duty = new decimal_js_1.default(_duty).toString();
19
19
  const futureRate = new decimal_js_1.default(_futureRate).toString();
20
20
  const chop = new decimal_js_1.default(_chop).div(1e18).toString();
@@ -46,6 +46,8 @@ const getMorphoBlueAggregatedPositionData = ({ usedAssets, assetsData, marketInf
46
46
  payload.ltv = new decimal_js_1.default(((_c = usedAssets[loanToken]) === null || _c === void 0 ? void 0 : _c.borrowed) || 0).div(oracle).div(((_d = usedAssets[collateralToken]) === null || _d === void 0 ? void 0 : _d.supplied) || 1).toString(); // default to 1 because can't div 0
47
47
  payload.ratio = new decimal_js_1.default(((_e = usedAssets[collateralToken]) === null || _e === void 0 ? void 0 : _e.supplied) || 0).mul(oracle).div(((_f = usedAssets[loanToken]) === null || _f === void 0 ? void 0 : _f.borrowed) || 1).mul(100)
48
48
  .toString();
49
+ // Borrow limit over debt, so 100 sits on the market's LLTV however low it is (`ratio` is the raw collateral ratio).
50
+ payload.safetyRatio = +payload.borrowedUsd > 0 ? new decimal_js_1.default(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
49
51
  const { leveragedType, leveragedAsset } = (0, moneymarket_1.isLeveragedPos)(usedAssets);
50
52
  payload.leveragedType = leveragedType;
51
53
  payload.liquidationPrice = '';
@@ -77,6 +77,8 @@ const getMorphoMidnightAggregatedPositionData = ({ usedAssets, assetsData, marke
77
77
  payload.ltv = new decimal_js_1.default(payload.suppliedCollateralUsd).eq(0) ? '0' : new decimal_js_1.default(payload.borrowedUsd).div(payload.suppliedCollateralUsd).toString();
78
78
  payload.ratio = new decimal_js_1.default(payload.borrowedUsd).eq(0) ? '0' : new decimal_js_1.default(payload.suppliedCollateralUsd).div(payload.borrowedUsd).mul(100).toString();
79
79
  payload.healthRatio = new decimal_js_1.default(payload.borrowedUsd).eq(0) ? 'Infinity' : new decimal_js_1.default(payload.liquidationLimitUsd).div(payload.borrowedUsd).toDP(4).toString();
80
+ // Borrow limit over debt, so 100 sits on the market's LLTV however low it is (`ratio` is the raw collateral ratio).
81
+ payload.safetyRatio = +payload.borrowedUsd > 0 ? new decimal_js_1.default(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
80
82
  const { leveragedType, leveragedAsset } = (0, moneymarket_1.isLeveragedPos)(usedAssets);
81
83
  payload.leveragedType = leveragedType;
82
84
  payload.liquidationPrice = '';
@@ -81,6 +81,7 @@ const sparkGetAggregatedPositionData = (_a) => {
81
81
  payload.leftToBorrowUsd = leftToBorrowUsd.lte('0') ? '0' : leftToBorrowUsd.toString();
82
82
  payload.ratio = +payload.suppliedUsd ? new decimal_js_1.default(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
83
83
  payload.collRatio = +payload.suppliedUsd ? new decimal_js_1.default(payload.suppliedCollateralUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
84
+ payload.safetyRatio = payload.ratio;
84
85
  const { netApy, incentiveUsd, totalInterestUsd } = (0, staking_1.calculateNetApy)({ usedAssets, assetsData });
85
86
  payload.netApy = netApy;
86
87
  payload.incentiveUsd = incentiveUsd;
@@ -22,6 +22,7 @@ const constants_1 = require("../constants");
22
22
  const viem_1 = require("../services/viem");
23
23
  const utils_1 = require("../services/utils");
24
24
  const moneymarket_1 = require("../moneymarket");
25
+ const staking_1 = require("../staking");
25
26
  exports.LIQUITY_NORMAL_MODE_RATIO = 110; // MCR
26
27
  exports.LIQUITY_RECOVERY_MODE_RATIO = 150; // CCR
27
28
  const _getLiquityAccountBalances = (provider, network, block, addressMapping, address) => __awaiter(void 0, void 0, void 0, function* () {
@@ -77,6 +78,14 @@ const _getLiquityTroveInfo = (provider, network, address) => __awaiter(void 0, v
77
78
  _getDebtInFront(viewContract, address),
78
79
  ]);
79
80
  const recoveryMode = troveInfo[6];
81
+ const minCollateralRatio = recoveryMode ? exports.LIQUITY_RECOVERY_MODE_RATIO : exports.LIQUITY_NORMAL_MODE_RATIO;
82
+ const collateral = (0, tokens_1.assetAmountInEth)(troveInfo[1].toString());
83
+ const debtInAsset = (0, tokens_1.assetAmountInEth)(troveInfo[2].toString());
84
+ const collateralUsd = new decimal_js_1.default(collateral).mul((0, tokens_1.assetAmountInEth)(assetPrice.toString())).toString();
85
+ const collRatio = +debtInAsset ? new decimal_js_1.default(collateralUsd).div(debtInAsset).mul(100).toString() : '0';
86
+ // LUSD debt is interest free (only a one-off borrowing fee on issuance) and ETH collateral earns no yield,
87
+ // so a trove's net APY is always 0. It is exposed for parity with the other protocols.
88
+ const { netApy, totalInterestUsd, incentiveUsd } = (0, staking_1.calculateNetApyFromRates)({ suppliedUsd: collateralUsd, borrowedUsd: debtInAsset });
80
89
  const payload = {
81
90
  troveStatus: types_1.LIQUITY_TROVE_STATUS_ENUM[+(troveInfo[0].toString())],
82
91
  collateral: (0, tokens_1.assetAmountInEth)(troveInfo[1].toString()),
@@ -89,10 +98,14 @@ const _getLiquityTroveInfo = (provider, network, address) => __awaiter(void 0, v
89
98
  totalETH: totalETH.toString(),
90
99
  totalLUSD: totalLUSD.toString(),
91
100
  debtInFront: debtInFront.toString(),
92
- minCollateralRatio: recoveryMode ? exports.LIQUITY_RECOVERY_MODE_RATIO : exports.LIQUITY_NORMAL_MODE_RATIO,
101
+ minCollateralRatio,
102
+ safetyRatio: (0, moneymarket_1.getSafetyRatioFromCollateralRatio)(collRatio, minCollateralRatio),
93
103
  priceForRecovery: new decimal_js_1.default(recoveryMode ? exports.LIQUITY_RECOVERY_MODE_RATIO : exports.LIQUITY_NORMAL_MODE_RATIO).mul(totalLUSD).div(totalETH).div(100)
94
104
  .toString(),
95
- exposure: (0, moneymarket_1.getExposure)((0, tokens_1.assetAmountInEth)(troveInfo[2].toString()), new decimal_js_1.default((0, tokens_1.assetAmountInEth)(troveInfo[1].toString())).mul(assetPrice).toString()),
105
+ exposure: (0, moneymarket_1.getExposure)(debtInAsset, collateralUsd),
106
+ netApy,
107
+ totalInterestUsd,
108
+ incentiveUsd,
96
109
  };
97
110
  return payload;
98
111
  });
@@ -1,9 +1,14 @@
1
1
  import { Client, PublicClient } from 'viem';
2
2
  import { Blockish, EthAddress, EthereumProvider, NetworkNumber, PositionBalances } from '../types/common';
3
- import { CdpData, CdpInfo } from '../types';
3
+ import { CdpData, CdpInfo, IlkInfo } from '../types';
4
4
  export declare const _getMakerAccountBalances: (provider: PublicClient, network: NetworkNumber, block: Blockish, addressMapping: boolean, cdpId: string, _managerAddress?: EthAddress) => Promise<PositionBalances>;
5
5
  export declare const getMakerAccountBalances: (provider: EthereumProvider, network: NetworkNumber, block: Blockish, addressMapping: boolean, cdpId: string, _managerAddress?: EthAddress) => Promise<PositionBalances>;
6
6
  export declare const _getUserCdps: (provider: Client, network: NetworkNumber, userAddress: EthAddress) => Promise<CdpInfo[]>;
7
7
  export declare const getUserCdps: (provider: EthereumProvider, network: NetworkNumber, userAddress: EthAddress) => Promise<CdpInfo[]>;
8
- export declare const _getMakerCdpData: (provider: Client, network: NetworkNumber, cdp: CdpInfo) => Promise<CdpData>;
8
+ export declare const _getMakerIlksData: (provider: Client, network: NetworkNumber, ilkLabels: string[]) => Promise<Record<string, IlkInfo>>;
9
+ export declare const getMakerIlksData: (provider: EthereumProvider, network: NetworkNumber, ilkLabels: string[]) => Promise<Record<string, IlkInfo>>;
10
+ /**
11
+ * @param ilkInfo optional precomputed ilk data (from `_getMakerIlksData`); when provided the per-ilk reads are skipped
12
+ */
13
+ export declare const _getMakerCdpData: (provider: Client, network: NetworkNumber, cdp: CdpInfo, ilkInfo?: IlkInfo) => Promise<CdpData>;
9
14
  export declare const getMakerCdpData: (provider: EthereumProvider, network: NetworkNumber, cdp: CdpInfo) => Promise<CdpData>;
@@ -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.getMakerCdpData = exports._getMakerCdpData = exports.getUserCdps = exports._getUserCdps = exports.getMakerAccountBalances = exports._getMakerAccountBalances = void 0;
15
+ exports.getMakerCdpData = exports._getMakerCdpData = exports.getMakerIlksData = exports._getMakerIlksData = exports.getUserCdps = exports._getUserCdps = exports.getMakerAccountBalances = exports._getMakerAccountBalances = 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");
@@ -21,6 +21,7 @@ const utils_1 = require("../services/utils");
21
21
  const makerHelpers_1 = require("../helpers/makerHelpers");
22
22
  const viem_1 = require("../services/viem");
23
23
  const moneymarket_1 = require("../moneymarket");
24
+ const staking_1 = require("../staking");
24
25
  const _getMakerAccountBalances = (provider, network, block, addressMapping, cdpId, _managerAddress) => __awaiter(void 0, void 0, void 0, function* () {
25
26
  let balances = {
26
27
  collateral: {},
@@ -44,7 +45,7 @@ const _getMakerAccountBalances = (provider, network, block, addressMapping, cdpI
44
45
  // [urn, owner, userAddr, ilk, collateral, debt]
45
46
  const cdpInfo = yield viewContract.read.getCdpInfo((needsIlk ? [managerAddress, cdpId, ilk] : [cdpId]), (0, viem_1.setViemBlockNumber)(block));
46
47
  cdpInfo.ilk = cdpInfo[3];
47
- const [par, [_, mat], [artGlobal, rate, spot, line], [duty], futureRate, chop,] = yield Promise.all([
48
+ const [par, [_, mat], [artGlobal, rate, spot, line, dust], [duty], futureRate, chop,] = yield Promise.all([
48
49
  spotterContract.read.par((0, viem_1.setViemBlockNumber)(block)),
49
50
  spotterContract.read.ilks(needsIlk ? [ilk] : [cdpInfo.ilk], (0, viem_1.setViemBlockNumber)(block)),
50
51
  vatContract.read.ilks(needsIlk ? [ilk] : [cdpInfo.ilk], (0, viem_1.setViemBlockNumber)(block)),
@@ -52,7 +53,7 @@ const _getMakerAccountBalances = (provider, network, block, addressMapping, cdpI
52
53
  jugContract.read.drip(needsIlk ? [ilk] : [cdpInfo.ilk], (0, viem_1.setViemBlockNumber)(block)),
53
54
  dogContract.read.chop(needsIlk ? [ilk] : [cdpInfo.ilk], (0, viem_1.setViemBlockNumber)(block)),
54
55
  ]);
55
- const ilkInfo = (0, makerHelpers_1.parseCollateralInfo)(needsIlk ? ilk : cdpInfo.ilk, par.toString(), mat.toString(), artGlobal.toString(), rate.toString(), spot.toString(), line.toString(), duty.toString(), futureRate.toString(), chop.toString());
56
+ const ilkInfo = (0, makerHelpers_1.parseCollateralInfo)(needsIlk ? ilk : cdpInfo.ilk, par.toString(), mat.toString(), artGlobal.toString(), rate.toString(), spot.toString(), line.toString(), dust.toString(), duty.toString(), futureRate.toString(), chop.toString());
56
57
  const collateral = cdpInfo[4];
57
58
  const debt = cdpInfo[5];
58
59
  const asset = (0, utils_1.wethToEth)((0, tokens_1.ilkToAsset)(needsIlk ? ilk : cdpInfo.ilk));
@@ -90,22 +91,40 @@ const _getUserCdps = (provider, network, userAddress) => __awaiter(void 0, void
90
91
  exports._getUserCdps = _getUserCdps;
91
92
  const getUserCdps = (provider, network, userAddress) => __awaiter(void 0, void 0, void 0, function* () { return (0, exports._getUserCdps)((0, viem_1.getViemProvider)(provider, network), network, userAddress); });
92
93
  exports.getUserCdps = getUserCdps;
93
- const _getMakerCdpData = (provider, network, cdp) => __awaiter(void 0, void 0, void 0, function* () {
94
+ const _getMakerIlksData = (provider, network, ilkLabels) => __awaiter(void 0, void 0, void 0, function* () {
94
95
  const vatContract = (0, contracts_1.McdVatContractViem)(provider, network);
95
96
  const spotterContract = (0, contracts_1.McdSpotterContractViem)(provider, network);
96
97
  const dogContract = (0, contracts_1.McdDogContractViem)(provider, network);
97
98
  const jugContract = (0, contracts_1.McdJugContractViem)(provider, network);
98
- const [[ink, art], coll, par, [_, mat], [artGlobal, rate, spot, line], [duty], futureRate, chop,] = yield Promise.all([
99
+ const par = yield spotterContract.read.par();
100
+ const ilksInfo = yield Promise.all(ilkLabels.map((ilkLabel) => __awaiter(void 0, void 0, void 0, function* () {
101
+ const ilk = (0, tokens_1.stringToBytes)(ilkLabel);
102
+ const [[_, mat], [artGlobal, rate, spot, line, dust], [duty], futureRate, chop,] = yield Promise.all([
103
+ spotterContract.read.ilks([ilk]),
104
+ vatContract.read.ilks([ilk]),
105
+ jugContract.read.ilks([ilk]),
106
+ jugContract.read.drip([ilk]),
107
+ dogContract.read.chop([ilk]),
108
+ ]);
109
+ return (0, makerHelpers_1.parseCollateralInfo)(ilk, par.toString(), mat.toString(), artGlobal.toString(), rate.toString(), spot.toString(), line.toString(), dust.toString(), duty.toString(), futureRate.toString(), chop.toString());
110
+ })));
111
+ return Object.fromEntries(ilksInfo.map((ilkInfo) => [ilkInfo.ilkLabel, ilkInfo]));
112
+ });
113
+ exports._getMakerIlksData = _getMakerIlksData;
114
+ const getMakerIlksData = (provider, network, ilkLabels) => __awaiter(void 0, void 0, void 0, function* () { return (0, exports._getMakerIlksData)((0, viem_1.getViemProvider)(provider, network, { batch: { multicall: true } }), network, ilkLabels); });
115
+ exports.getMakerIlksData = getMakerIlksData;
116
+ /**
117
+ * @param ilkInfo optional precomputed ilk data (from `_getMakerIlksData`); when provided the per-ilk reads are skipped
118
+ */
119
+ const _getMakerCdpData = (provider, network, cdp, ilkInfo) => __awaiter(void 0, void 0, void 0, function* () {
120
+ const vatContract = (0, contracts_1.McdVatContractViem)(provider, network);
121
+ const [[ink, art], coll, fetchedIlkInfo, collStakingApy,] = yield Promise.all([
99
122
  vatContract.read.urns([cdp.ilk, cdp.urn]),
100
123
  vatContract.read.gem([cdp.ilk, cdp.urn]),
101
- spotterContract.read.par(),
102
- spotterContract.read.ilks([cdp.ilk]),
103
- vatContract.read.ilks([cdp.ilk]),
104
- jugContract.read.ilks([cdp.ilk]),
105
- jugContract.read.drip([cdp.ilk]),
106
- dogContract.read.chop([cdp.ilk]),
124
+ ilkInfo || (0, exports._getMakerIlksData)(provider, network, [cdp.ilkLabel]).then((ilks) => ilks[cdp.ilkLabel]),
125
+ staking_1.STAKING_ASSETS.includes(cdp.asset) ? (0, staking_1.getStakingApy)(cdp.asset) : Promise.resolve('0'),
107
126
  ]);
108
- const collInfo = (0, makerHelpers_1.parseCollateralInfo)(cdp.ilk, par.toString(), mat.toString(), artGlobal.toString(), rate.toString(), spot.toString(), line.toString(), duty.toString(), futureRate.toString(), chop.toString());
127
+ const collInfo = fetchedIlkInfo;
109
128
  const collateral = (0, tokens_1.assetAmountInEth)(ink.toString(), `MCD-${cdp.asset}`);
110
129
  const collateralUsd = new decimal_js_1.default(collateral).mul(collInfo.assetPrice).toString();
111
130
  const debt = new decimal_js_1.default(art).times(collInfo.currentRate).div(1e27).floor()
@@ -117,7 +136,16 @@ const _getMakerCdpData = (provider, network, cdp) => __awaiter(void 0, void 0, v
117
136
  .toString();
118
137
  if (new decimal_js_1.default(debt).eq(0))
119
138
  ratio = '0';
139
+ const safetyRatio = (0, moneymarket_1.getSafetyRatioFromCollateralRatio)(ratio, collInfo.liqPercent);
120
140
  const debtTooLow = new decimal_js_1.default(debt).gt(0) && new decimal_js_1.default((0, tokens_1.assetAmountInEth)(debt, 'DAI')).lt(collInfo.minDebt);
141
+ // DAI debt accrues the ilk's stability fee. Collateral earns nothing inside the vault, except for the
142
+ // native yield of staked collateral (e.g. wstETH), which is tracked as an incentive.
143
+ const { netApy, totalInterestUsd, incentiveUsd } = (0, staking_1.calculateNetApyFromRates)({
144
+ suppliedUsd: collateralUsd,
145
+ borrowedUsd: (0, tokens_1.assetAmountInEth)(debt, 'DAI'),
146
+ borrowRate: collInfo.stabilityFee.toString(),
147
+ incentives: [{ apy: collStakingApy, amountUsd: collateralUsd }],
148
+ });
121
149
  return {
122
150
  owner: cdp.owner,
123
151
  id: cdp.id.toString(),
@@ -136,6 +164,7 @@ const _getMakerCdpData = (provider, network, cdp) => __awaiter(void 0, void 0, v
136
164
  debtAssetMarketPrice: '1',
137
165
  liquidationPrice,
138
166
  ratio,
167
+ safetyRatio,
139
168
  liqRatio: collInfo.liqRatio.toString(),
140
169
  liqPercent: parseFloat(collInfo.liqPercent.toString()),
141
170
  assetPrice: collInfo.assetPrice,
@@ -151,6 +180,9 @@ const _getMakerCdpData = (provider, network, cdp) => __awaiter(void 0, void 0, v
151
180
  liquidationFee: collInfo.liquidationFee,
152
181
  lastUpdated: Date.now(),
153
182
  exposure: (0, moneymarket_1.getExposure)((0, tokens_1.assetAmountInEth)(debt, 'DAI'), collateralUsd),
183
+ netApy,
184
+ totalInterestUsd,
185
+ incentiveUsd,
154
186
  };
155
187
  });
156
188
  exports._getMakerCdpData = _getMakerCdpData;
@@ -8,3 +8,4 @@ export { LlamaLendMarkets } from './llamaLend';
8
8
  export { LiquityV2Markets, findLiquityV2MarketByAddress } from './liquityV2';
9
9
  export { FluidMarkets, getFluidVersionsDataForNetwork, getFluidMarketInfoById, getFTokenAddress, getFluidMarketInfoByAddress, } from './fluid';
10
10
  export { AaveV4Spokes, findAaveV4SpokeByAddress } from './aaveV4';
11
+ export { MakerActiveIlks } from './maker';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.findAaveV4SpokeByAddress = exports.AaveV4Spokes = exports.getFluidMarketInfoByAddress = exports.getFTokenAddress = exports.getFluidMarketInfoById = exports.getFluidVersionsDataForNetwork = exports.FluidMarkets = exports.findLiquityV2MarketByAddress = exports.LiquityV2Markets = exports.LlamaLendMarkets = exports.morphoMidnightVisibleCollaterals = exports.morphoMidnightMarketCollateralParams = exports.isTenorMidnightMarket = exports.findMorphoMidnightMarket = exports.MorphoMidnightMarkets = exports.findMorphoBlueMarket = exports.MorphoBlueMarkets = exports.CrvUsdMarkets = exports.SparkMarkets = exports.v3USDTCollAssets = exports.v3USDCeCollAssets = exports.v3USDCCollAssets = exports.v3USDbCCollAssets = exports.v3ETHCollAssets = exports.compoundV2CollateralAssets = exports.CompoundMarkets = exports.getAaveV3MarketByMarketAddress = exports.aaveV3AssetsDefaultMarket = exports.aaveV2AssetsDefaultMarket = exports.aaveV1AssetsDefaultMarket = exports.AaveMarkets = void 0;
3
+ exports.MakerActiveIlks = exports.findAaveV4SpokeByAddress = exports.AaveV4Spokes = exports.getFluidMarketInfoByAddress = exports.getFTokenAddress = exports.getFluidMarketInfoById = exports.getFluidVersionsDataForNetwork = exports.FluidMarkets = exports.findLiquityV2MarketByAddress = exports.LiquityV2Markets = exports.LlamaLendMarkets = exports.morphoMidnightVisibleCollaterals = exports.morphoMidnightMarketCollateralParams = exports.isTenorMidnightMarket = exports.findMorphoMidnightMarket = exports.MorphoMidnightMarkets = exports.findMorphoBlueMarket = exports.MorphoBlueMarkets = exports.CrvUsdMarkets = exports.SparkMarkets = exports.v3USDTCollAssets = exports.v3USDCeCollAssets = exports.v3USDCCollAssets = exports.v3USDbCCollAssets = exports.v3ETHCollAssets = exports.compoundV2CollateralAssets = exports.CompoundMarkets = exports.getAaveV3MarketByMarketAddress = exports.aaveV3AssetsDefaultMarket = exports.aaveV2AssetsDefaultMarket = exports.aaveV1AssetsDefaultMarket = exports.AaveMarkets = void 0;
4
4
  var aave_1 = require("./aave");
5
5
  Object.defineProperty(exports, "AaveMarkets", { enumerable: true, get: function () { return aave_1.AaveMarkets; } });
6
6
  Object.defineProperty(exports, "aaveV1AssetsDefaultMarket", { enumerable: true, get: function () { return aave_1.aaveV1AssetsDefaultMarket; } });
@@ -42,3 +42,5 @@ Object.defineProperty(exports, "getFluidMarketInfoByAddress", { enumerable: true
42
42
  var aaveV4_1 = require("./aaveV4");
43
43
  Object.defineProperty(exports, "AaveV4Spokes", { enumerable: true, get: function () { return aaveV4_1.AaveV4Spokes; } });
44
44
  Object.defineProperty(exports, "findAaveV4SpokeByAddress", { enumerable: true, get: function () { return aaveV4_1.findAaveV4SpokeByAddress; } });
45
+ var maker_1 = require("./maker");
46
+ Object.defineProperty(exports, "MakerActiveIlks", { enumerable: true, get: function () { return maker_1.MakerActiveIlks; } });
@@ -0,0 +1 @@
1
+ export declare const MakerActiveIlks: string[];
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MakerActiveIlks = void 0;
4
+ exports.MakerActiveIlks = [
5
+ 'ETH-A',
6
+ 'ETH-B',
7
+ 'ETH-C',
8
+ 'WSTETH-A',
9
+ 'WSTETH-B',
10
+ 'WBTC-A',
11
+ 'WBTC-B',
12
+ 'WBTC-C',
13
+ ];
@@ -11,3 +11,12 @@ export declare const isLeveragedPos: (usedAssets: MMUsedAssets, dustLimit?: numb
11
11
  };
12
12
  export declare const aprToApy: (interest: string | number, frequency?: number) => string;
13
13
  export declare const getExposure: (borrowedUsd: string, suppliedUsd: string) => string;
14
+ /**
15
+ * A collateral ratio rebased so that 100 means "sitting exactly on the liquidation ratio": the scale the
16
+ * shared `safetyRatio` field assumes. Protocols that liquidate on a raw collateral ratio (Maker at the ilk's
17
+ * liquidation ratio, Liquity at 110%, crvUSD/LlamaLend at the band-derived minimum) pass through here.
18
+ *
19
+ * Yields '0' when the liquidation ratio isn't available (or is 0), the "no signal" value consumers already recognise.
20
+ * Mirrors `getSafetyRatioFromCollateralRatio` on the client.
21
+ */
22
+ export declare const getSafetyRatioFromCollateralRatio: (collateralRatio: string | number | undefined, liquidationRatio: string | number | undefined) => string;