@defisaver/positions-sdk 2.1.146 → 2.1.147-spark-ltv0-fallback-dev

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.
@@ -19,6 +19,19 @@ export declare const sparkGetEmodeMutableProps: ({ eModeCategory, eModeCategorie
19
19
  liquidationRatio: string;
20
20
  collateralFactor: string;
21
21
  };
22
+ /**
23
+ * @description Per-asset effective LTV and liquidation threshold (LLTV) for the user, eMode-aware.
24
+ * Mirrors SparkRatioHelper._getUserAccountDataWithLtvZeroFallback: unlike Aave v3 (eMode ltv-zero
25
+ * bitmap), Spark's LTV-0 state lives on the RESERVE config (asset offboarding zeroes the reserve ltv),
26
+ * so a zeroed reserve keeps `ltv` 0 even inside the active eMode category, while its `lltv` stays the
27
+ * eMode liquidation threshold there (liquidations only consider LLTV). The returned `ltv` is identical
28
+ * to sparkGetEmodeMutableProps().collateralFactor whenever the reserve ltv is non-zero, so a ratio
29
+ * built on this matches the regular safety ratio whenever no collateral is LTV-0.
30
+ */
31
+ export declare const sparkGetUserReserveLtvAndLltv: ({ eModeCategory, eModeCategoriesData, assetsData, }: SparkHelperCommon, _asset: string) => {
32
+ ltv: string;
33
+ lltv: string;
34
+ };
22
35
  export declare const sparkGetAggregatedPositionData: ({ usedAssets, eModeCategory, eModeCategoriesData, assetsData, selectedMarket, network, ...rest }: SparkHelperCommon) => SparkAggregatedPositionData;
23
36
  export declare const getApyAfterValuesEstimation: (selectedMarket: SparkMarketData, actions: [{
24
37
  action: string;
@@ -23,7 +23,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
23
23
  return (mod && mod.__esModule) ? mod : { "default": mod };
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.getApyAfterValuesEstimation = exports.sparkGetAggregatedPositionData = exports.sparkGetEmodeMutableProps = exports.sparkGetSuppliableAsCollAssets = exports.sparkGetSuppliableAssets = exports.sparkGetCollSuppliedAssets = exports.sparkIsInIsolationMode = void 0;
26
+ exports.getApyAfterValuesEstimation = exports.sparkGetAggregatedPositionData = exports.sparkGetUserReserveLtvAndLltv = exports.sparkGetEmodeMutableProps = exports.sparkGetSuppliableAsCollAssets = exports.sparkGetSuppliableAssets = exports.sparkGetCollSuppliedAssets = exports.sparkIsInIsolationMode = void 0;
27
27
  const decimal_js_1 = __importDefault(require("decimal.js"));
28
28
  const tokens_1 = require("@defisaver/tokens");
29
29
  const moneymarket_1 = require("../../moneymarket");
@@ -68,6 +68,37 @@ const sparkGetEmodeMutableProps = ({ eModeCategory, eModeCategoriesData, assetsD
68
68
  return ({ liquidationRatio, collateralFactor });
69
69
  };
70
70
  exports.sparkGetEmodeMutableProps = sparkGetEmodeMutableProps;
71
+ /**
72
+ * @description Offset subtracted from the liquidation threshold (LLTV) when crediting LTV-0 collateral
73
+ * in the safety-ratio fallback. Matches SparkView.getSafetyRatioWithLtvZeroFallback ('LLTV - 5%').
74
+ * Values are fractions (e.g. 0.8), so 5% === 0.05.
75
+ */
76
+ const LTV_ZERO_FALLBACK_LLTV_OFFSET = '0.05';
77
+ /**
78
+ * @description Per-asset effective LTV and liquidation threshold (LLTV) for the user, eMode-aware.
79
+ * Mirrors SparkRatioHelper._getUserAccountDataWithLtvZeroFallback: unlike Aave v3 (eMode ltv-zero
80
+ * bitmap), Spark's LTV-0 state lives on the RESERVE config (asset offboarding zeroes the reserve ltv),
81
+ * so a zeroed reserve keeps `ltv` 0 even inside the active eMode category, while its `lltv` stays the
82
+ * eMode liquidation threshold there (liquidations only consider LLTV). The returned `ltv` is identical
83
+ * to sparkGetEmodeMutableProps().collateralFactor whenever the reserve ltv is non-zero, so a ratio
84
+ * built on this matches the regular safety ratio whenever no collateral is LTV-0.
85
+ */
86
+ const sparkGetUserReserveLtvAndLltv = ({ eModeCategory, eModeCategoriesData, assetsData, }, _asset) => {
87
+ const asset = (0, utils_1.getNativeAssetFromWrapped)(_asset);
88
+ const assetData = assetsData[asset];
89
+ const eModeCategoryData = eModeCategoriesData === null || eModeCategoriesData === void 0 ? void 0 : eModeCategoriesData[eModeCategory];
90
+ if (eModeCategory === 0
91
+ || !eModeCategoryData
92
+ || !eModeCategoryData.collateralAssets.includes(asset)
93
+ || new decimal_js_1.default(eModeCategoryData.collateralFactor || 0).eq(0)) {
94
+ return { ltv: assetData.collateralFactor, lltv: assetData.liquidationRatio };
95
+ }
96
+ // In the active eMode category the fallback trigger is still the reserve-level ltv (the contract
97
+ // checks the reserve config's ltv), so an offboarded asset must not pick up the category-wide eMode ltv.
98
+ const ltv = new decimal_js_1.default(assetData.collateralFactor || 0).eq(0) ? '0' : eModeCategoryData.collateralFactor;
99
+ return { ltv, lltv: eModeCategoryData.liquidationRatio };
100
+ };
101
+ exports.sparkGetUserReserveLtvAndLltv = sparkGetUserReserveLtvAndLltv;
71
102
  const sparkGetAggregatedPositionData = (_a) => {
72
103
  var { usedAssets, eModeCategory, eModeCategoriesData, assetsData, selectedMarket, network } = _a, rest = __rest(_a, ["usedAssets", "eModeCategory", "eModeCategoriesData", "assetsData", "selectedMarket", "network"]);
73
104
  const data = Object.assign({ usedAssets, eModeCategory, eModeCategoriesData, assetsData, selectedMarket, network }, rest);
@@ -81,6 +112,17 @@ const sparkGetAggregatedPositionData = (_a) => {
81
112
  payload.leftToBorrowUsd = leftToBorrowUsd.lte('0') ? '0' : leftToBorrowUsd.toString();
82
113
  payload.ratio = +payload.suppliedUsd ? new decimal_js_1.default(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
83
114
  payload.collRatio = +payload.suppliedUsd ? new decimal_js_1.default(payload.suppliedCollateralUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
115
+ // Safety ratio as evaluated by the automation bots: LTV-0 collateral is credited at (LLTV - 5%)
116
+ // instead of 0 (SparkView.getSafetyRatioWithLtvZeroFallback). Equals `ratio` when no collateral
117
+ // is LTV-0. Computed off-chain here so it is available for after-value simulations too.
118
+ payload.borrowLimitWithLtvZeroFallbackUsd = (0, moneymarket_1.getAssetsTotal)(usedAssets, ({ isSupplied, collateral }) => isSupplied && collateral, ({ symbol, suppliedUsd }) => {
119
+ const { ltv, lltv } = (0, exports.sparkGetUserReserveLtvAndLltv)(data, symbol);
120
+ const effectiveLtv = new decimal_js_1.default(ltv).eq(0)
121
+ ? decimal_js_1.default.max(0, new decimal_js_1.default(lltv).sub(LTV_ZERO_FALLBACK_LLTV_OFFSET))
122
+ : new decimal_js_1.default(ltv);
123
+ return new decimal_js_1.default(suppliedUsd).mul(effectiveLtv);
124
+ });
125
+ payload.safetyRatioWithLtvZeroFallback = +payload.suppliedUsd ? new decimal_js_1.default(payload.borrowLimitWithLtvZeroFallbackUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
84
126
  const { netApy, incentiveUsd, totalInterestUsd } = (0, staking_1.calculateNetApy)({ usedAssets, assetsData });
85
127
  payload.netApy = netApy;
86
128
  payload.incentiveUsd = incentiveUsd;
@@ -32,8 +32,9 @@ const getLiquityV2ViewContract = (provider, network, isLegacy) => {
32
32
  const _getLiquityV2MarketData = (provider, network, selectedMarket) => __awaiter(void 0, void 0, void 0, function* () {
33
33
  var _a;
34
34
  const { marketAddress, debtToken, collateralToken, isLegacy, } = selectedMarket;
35
- const viewContract = getLiquityV2ViewContract(provider, network, isLegacy);
36
- const data = yield viewContract.read.getMarketData([marketAddress]);
35
+ const data = isLegacy
36
+ ? yield (0, contracts_1.LiquityV2LegacyViewContractViem)(provider, network).read.getMarketData([marketAddress])
37
+ : (yield (0, contracts_1.LiquityV2ViewContractViem)(provider, network).simulate.getMarketData([marketAddress])).result;
37
38
  const hintHelperAddress = data.hintHelpers;
38
39
  const troveNFTAddress = data.troveNFT;
39
40
  const borrowerOperationsAddress = data.borrowerOperations;
@@ -285,11 +286,15 @@ const _getDebtInFrontForInterestRateLiquityV2 = (markets_2, selectedMarket_1, pr
285
286
  const getDebtInFrontForInterestRateLiquityV2 = (markets_2, selectedMarket_1, provider_1, network_1, isLegacy_1, interestRate_1, ...args_1) => __awaiter(void 0, [markets_2, selectedMarket_1, provider_1, network_1, isLegacy_1, interestRate_1, ...args_1], void 0, function* (markets, selectedMarket, provider, network, isLegacy, interestRate, debtInFrontBeingMoved = '0') { return _getDebtInFrontForInterestRateLiquityV2(markets, selectedMarket, (0, viem_1.getViemProvider)(provider, network), network, isLegacy, interestRate, debtInFrontBeingMoved); });
286
287
  exports.getDebtInFrontForInterestRateLiquityV2 = getDebtInFrontForInterestRateLiquityV2;
287
288
  const _getLiquityV2TroveData = (provider_1, network_1, _a, ...args_1) => __awaiter(void 0, [provider_1, network_1, _a, ...args_1], void 0, function* (provider, network, { selectedMarket, assetsData, troveId, allMarketsData, }, fetchDebtInFront = true) {
288
- const viewContract = getLiquityV2ViewContract(provider, network, selectedMarket.isLegacy);
289
289
  const { minCollRatio, batchCollRatio } = allMarketsData[selectedMarket.value].marketData;
290
290
  const { collateralToken, marketAddress, debtToken } = selectedMarket;
291
+ const troveInfoPromise = selectedMarket.isLegacy
292
+ ? (0, contracts_1.LiquityV2LegacyViewContractViem)(provider, network).read.getTroveInfo([marketAddress, BigInt(troveId)])
293
+ : (0, contracts_1.LiquityV2ViewContractViem)(provider, network).simulate
294
+ .getTroveInfo([marketAddress, BigInt(troveId)])
295
+ .then(({ result }) => result);
291
296
  const [_data, debtInFront] = yield Promise.all([
292
- viewContract.read.getTroveInfo([marketAddress, BigInt(troveId)]),
297
+ troveInfoPromise,
293
298
  fetchDebtInFront ? getDebtInFrontLiquityV2(allMarketsData, selectedMarket.value, provider, network, selectedMarket.isLegacy, troveId) : Promise.resolve('0'),
294
299
  ]);
295
300
  const data = Object.assign(Object.assign({}, _data), { TCRatio: _data.TCRatio.toString() === utils_1.MAXUINT ? '0' : _data.TCRatio.toString() });
@@ -85,6 +85,8 @@ export interface SparkAggregatedPositionData {
85
85
  leftToBorrowUsd: string;
86
86
  ratio: string;
87
87
  collRatio: string;
88
+ borrowLimitWithLtvZeroFallbackUsd: string;
89
+ safetyRatioWithLtvZeroFallback: string;
88
90
  netApy: string;
89
91
  incentiveUsd: string;
90
92
  totalInterestUsd: string;
@@ -104,6 +106,7 @@ export interface SparkPositionData extends MMPositionData {
104
106
  ratio: string;
105
107
  minRatio: string;
106
108
  collRatio: string;
109
+ safetyRatioWithLtvZeroFallback?: string;
107
110
  suppliedUsd: string;
108
111
  borrowedUsd: string;
109
112
  borrowLimitUsd: string;