@defisaver/positions-sdk 1.0.30 → 1.0.32-dev-1

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.
@@ -115,6 +115,7 @@ const aaveAnyGetAggregatedPositionData = (_a) => {
115
115
  usedAssets,
116
116
  assetsData,
117
117
  isMorpho: (0, exports.isMorphoAave)({ selectedMarket }),
118
+ isAave: true,
118
119
  });
119
120
  payload.netApy = netApy;
120
121
  payload.incentiveUsd = incentiveUsd;
@@ -10,7 +10,7 @@ export declare const getLiquityV2UserTroveIds: (web3: Web3, network: NetworkNumb
10
10
  }>;
11
11
  export declare const getDebtInFrontForSingleMarketLiquityV2: (viewContract: any, marketAddress: EthAddress, troveId: string, accumulatedSum?: string, iterations?: number) => Promise<string>;
12
12
  export declare const getDebtInFrontForInterestRateSingleMarketLiquityV2: (viewContract: any, marketAddress: EthAddress, interestRate: string, troveId?: string, accumulatedSum?: string, iterations?: number) => Promise<string>;
13
- export declare const getAllMarketsUnbackedDebts: (markets: Record<LiquityV2Versions, LiquityV2MarketData>, web3: Web3, network: NetworkNumber) => Promise<Record<LiquityV2Versions, string>>;
13
+ export declare const getAllMarketsUnbackedDebts: (markets: Record<LiquityV2Versions, LiquityV2MarketData>, isLegacy: boolean, web3: Web3, network: NetworkNumber) => Promise<Record<LiquityV2Versions, string>>;
14
14
  export declare const calculateDebtInFrontLiquityV2: (markets: Record<LiquityV2Versions, LiquityV2MarketData>, selectedMarket: LiquityV2Versions, allMarketsUnbackedDebts: Record<LiquityV2Versions, string>, interestRateDebtInFront: string) => string;
15
15
  export declare const getDebtInFrontLiquityV2: (markets: Record<LiquityV2Versions, LiquityV2MarketData>, selectedMarket: LiquityV2Versions, web3: Web3, network: NetworkNumber, viewContract: any, troveId: string) => Promise<string>;
16
16
  /**
@@ -174,10 +174,12 @@ const getUnbackedDebtForSingleMarket = (totalBorrowed, web3, network, stabilityP
174
174
  const totalBoldDepositsInEth = (0, tokens_1.assetAmountInEth)(totalBoldDeposits);
175
175
  return decimal_js_1.default.max(new decimal_js_1.default(totalBorrowed).sub(totalBoldDepositsInEth), 0).toString();
176
176
  });
177
- const getAllMarketsUnbackedDebts = (markets, web3, network) => __awaiter(void 0, void 0, void 0, function* () {
177
+ const getAllMarketsUnbackedDebts = (markets, isLegacy, web3, network) => __awaiter(void 0, void 0, void 0, function* () {
178
178
  const allMarketsUnbackedDebt = yield Promise.all(Object.entries(markets).map(([version, market]) => __awaiter(void 0, void 0, void 0, function* () {
179
179
  const { assetsData, marketData } = market;
180
- const { debtToken } = (0, markets_1.LiquityV2Markets)(network)[version];
180
+ const { debtToken, isLegacy: isLegacyMarket } = (0, markets_1.LiquityV2Markets)(network)[version];
181
+ if (isLegacyMarket !== isLegacy)
182
+ return [version, '0'];
181
183
  const unbackedDebt = yield getUnbackedDebtForSingleMarket(assetsData[debtToken].totalBorrow, web3, network, marketData.stabilityPoolAddress);
182
184
  return [version, unbackedDebt];
183
185
  })));
@@ -186,10 +188,12 @@ const getAllMarketsUnbackedDebts = (markets, web3, network) => __awaiter(void 0,
186
188
  exports.getAllMarketsUnbackedDebts = getAllMarketsUnbackedDebts;
187
189
  const calculateDebtInFrontLiquityV2 = (markets, selectedMarket, allMarketsUnbackedDebts, interestRateDebtInFront) => {
188
190
  const selectedMarketUnbackedDebt = new decimal_js_1.default(allMarketsUnbackedDebts[selectedMarket]);
191
+ const { isLegacy } = (0, markets_1.LiquityV2Markets)(common_1.NetworkNumber.Eth)[selectedMarket];
189
192
  if (selectedMarketUnbackedDebt.eq(0))
190
- return 'N/A';
193
+ return interestRateDebtInFront;
191
194
  const amountBeingReedemedOnEachMarket = Object.entries(markets).map(([version, market]) => {
192
- if (version === selectedMarket)
195
+ const { isLegacy: isLegacyMarket } = (0, markets_1.LiquityV2Markets)(common_1.NetworkNumber.Eth)[version];
196
+ if (version === selectedMarket && isLegacyMarket !== isLegacy)
193
197
  return new decimal_js_1.default(interestRateDebtInFront);
194
198
  const { assetsData } = market;
195
199
  const { debtToken } = (0, markets_1.LiquityV2Markets)(common_1.NetworkNumber.Eth)[version];
@@ -202,7 +206,8 @@ const calculateDebtInFrontLiquityV2 = (markets, selectedMarket, allMarketsUnback
202
206
  };
203
207
  exports.calculateDebtInFrontLiquityV2 = calculateDebtInFrontLiquityV2;
204
208
  const getDebtInFrontLiquityV2 = (markets, selectedMarket, web3, network, viewContract, troveId) => __awaiter(void 0, void 0, void 0, function* () {
205
- const allMarketsUnbackedDebts = yield (0, exports.getAllMarketsUnbackedDebts)(markets, web3, network);
209
+ const { isLegacy } = (0, markets_1.LiquityV2Markets)(common_1.NetworkNumber.Eth)[selectedMarket];
210
+ const allMarketsUnbackedDebts = yield (0, exports.getAllMarketsUnbackedDebts)(markets, isLegacy, web3, network);
206
211
  const interestRateDebtInFront = yield (0, exports.getDebtInFrontForSingleMarketLiquityV2)(viewContract, (0, markets_1.LiquityV2Markets)(network)[selectedMarket].marketAddress, troveId);
207
212
  return (0, exports.calculateDebtInFrontLiquityV2)(markets, selectedMarket, allMarketsUnbackedDebts, interestRateDebtInFront.toString());
208
213
  });
@@ -217,7 +222,8 @@ exports.getDebtInFrontLiquityV2 = getDebtInFrontLiquityV2;
217
222
  * @param debtInFrontBeingMoved - amound of debt being repositioned if interest rate is being increased (prevents including it as debt in front)
218
223
  */
219
224
  const getDebtInFrontForInterestRateLiquityV2 = (markets, selectedMarket, web3, network, viewContract, interestRate, debtInFrontBeingMoved = '0') => __awaiter(void 0, void 0, void 0, function* () {
220
- const allMarketsUnbackedDebts = yield (0, exports.getAllMarketsUnbackedDebts)(markets, web3, network);
225
+ const { isLegacy } = (0, markets_1.LiquityV2Markets)(common_1.NetworkNumber.Eth)[selectedMarket];
226
+ const allMarketsUnbackedDebts = yield (0, exports.getAllMarketsUnbackedDebts)(markets, isLegacy, web3, network);
221
227
  const interestRateDebtInFront = new decimal_js_1.default(yield (0, exports.getDebtInFrontForInterestRateSingleMarketLiquityV2)(viewContract, (0, markets_1.LiquityV2Markets)(network)[selectedMarket].marketAddress, interestRate))
222
228
  .sub(debtInFrontBeingMoved);
223
229
  return (0, exports.calculateDebtInFrontLiquityV2)(markets, selectedMarket, allMarketsUnbackedDebts, interestRateDebtInFront.toString());
@@ -17,7 +17,7 @@ const multicall = (calls, web3, network = common_1.NetworkNumber.Eth, blockNumbe
17
17
  const multicallContract = (0, contracts_1.UniMulticallContract)(web3, network);
18
18
  const formattedCalls = calls.map((call) => {
19
19
  const callData = web3.eth.abi.encodeFunctionCall(call.abiItem, call.params);
20
- return { callData, target: call.target || '0x0', gasLimit: call.gasLimit || 1500000 };
20
+ return { callData, target: call.target || '0x0', gasLimit: call.gasLimit || 1800000 };
21
21
  });
22
22
  const callResult = yield multicallContract.methods.multicall(formattedCalls.filter(item => item.target !== '0x0')).call({}, blockNumber);
23
23
  let formattedResult = [];
@@ -4,10 +4,15 @@ import { MMAssetsData, MMUsedAssets } from '../types/common';
4
4
  export declare const STAKING_ASSETS: string[];
5
5
  export declare const getStakingApy: ((asset: string, web3: Web3, blockNumber?: 'latest' | number, fromBlock?: number | undefined) => Promise<string>) & memoize.Memoized<(asset: string, web3: Web3, blockNumber?: 'latest' | number, fromBlock?: number | undefined) => Promise<string>>;
6
6
  export declare const calculateInterestEarned: (principal: string, interest: string, type: string, apy?: boolean) => number;
7
- export declare const calculateNetApy: ({ usedAssets, assetsData, isMorpho }: {
7
+ export declare const isEligibleForEthenaUSDeRewards: (usedAssets: MMUsedAssets) => {
8
+ isEligible: boolean;
9
+ eligibleUSDAmount: string;
10
+ };
11
+ export declare const calculateNetApy: ({ usedAssets, assetsData, isMorpho, isAave, }: {
8
12
  usedAssets: MMUsedAssets;
9
13
  assetsData: MMAssetsData;
10
14
  isMorpho?: boolean | undefined;
15
+ isAave?: boolean | undefined;
11
16
  }) => {
12
17
  netApy: string;
13
18
  totalInterestUsd: string;
@@ -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.getStETHByWstETHMultiple = exports.getStETHByWstETH = exports.getWstETHByStETH = exports.calculateNetApy = exports.calculateInterestEarned = exports.getStakingApy = exports.STAKING_ASSETS = void 0;
15
+ exports.getStETHByWstETHMultiple = exports.getStETHByWstETH = exports.getWstETHByStETH = exports.calculateNetApy = exports.isEligibleForEthenaUSDeRewards = exports.calculateInterestEarned = exports.getStakingApy = exports.STAKING_ASSETS = void 0;
16
16
  const decimal_js_1 = __importDefault(require("decimal.js"));
17
17
  const memoizee_1 = __importDefault(require("memoizee"));
18
18
  const contracts_1 = require("../contracts");
@@ -177,7 +177,41 @@ const calculateInterestEarned = (principal, interest, type, apy = false) => {
177
177
  return (+principal * (Math.pow(((1 + (+interest / 100) / constants_1.BLOCKS_IN_A_YEAR)), (constants_1.BLOCKS_IN_A_YEAR * interval)))) - +principal; // eslint-disable-line
178
178
  };
179
179
  exports.calculateInterestEarned = calculateInterestEarned;
180
- const calculateNetApy = ({ usedAssets, assetsData, isMorpho = false }) => {
180
+ const USDE_REWARD_APY = '12';
181
+ const isEligibleForEthenaUSDeRewards = (usedAssets) => {
182
+ var _a, _b;
183
+ const USDeUSDAmountSupplied = ((_a = usedAssets.USDe) === null || _a === void 0 ? void 0 : _a.suppliedUsd) || '0';
184
+ const sUSDeUSDAmountSupplied = ((_b = usedAssets.sUSDe) === null || _b === void 0 ? void 0 : _b.suppliedUsd) || '0';
185
+ const anythingElseSupplied = Object.values(usedAssets).some((asset) => asset.symbol !== 'USDe' && asset.symbol !== 'sUSDe' && asset.isSupplied);
186
+ if (anythingElseSupplied)
187
+ return { isEligible: false, eligibleUSDAmount: '0' };
188
+ const totalAmountSupplied = new decimal_js_1.default(USDeUSDAmountSupplied).add(sUSDeUSDAmountSupplied).toString();
189
+ const percentageInUSDe = new decimal_js_1.default(USDeUSDAmountSupplied).div(totalAmountSupplied).toNumber();
190
+ if (percentageInUSDe < 0.45 || percentageInUSDe > 0.55)
191
+ return { isEligible: false, eligibleUSDAmount: '0' }; // 45% - 55% of total amount supplied must be in USDe
192
+ const percentageInSUSDe = new decimal_js_1.default(sUSDeUSDAmountSupplied).div(totalAmountSupplied).toNumber();
193
+ if (percentageInSUSDe < 0.45 || percentageInSUSDe > 0.55)
194
+ return { isEligible: false, eligibleUSDAmount: '0' }; // 45% - 55% of total amount supplied must be in sUSDe
195
+ const allowedBorrowAssets = ['USDC', 'USDT', 'USDS'];
196
+ const anythingBorrowedNotAllowed = Object.values(usedAssets).some((asset) => asset.isBorrowed && !allowedBorrowAssets.includes(asset.symbol));
197
+ if (anythingBorrowedNotAllowed)
198
+ return { isEligible: false, eligibleUSDAmount: '0' };
199
+ const totalAmountBorrowed = Object.values(usedAssets).reduce((acc, asset) => {
200
+ if (asset.isBorrowed) {
201
+ return acc.add(asset.borrowedUsd);
202
+ }
203
+ return acc;
204
+ }, new decimal_js_1.default(0)).toString();
205
+ const borrowPercentage = new decimal_js_1.default(totalAmountBorrowed).div(totalAmountSupplied).toNumber();
206
+ if (borrowPercentage < 0.5)
207
+ return { isEligible: false, eligibleUSDAmount: '0' }; // must be looped at least once
208
+ const halfAmountSupplied = new decimal_js_1.default(totalAmountSupplied).div(2).toString();
209
+ const USDeAmountEligibleForRewards = decimal_js_1.default.min(USDeUSDAmountSupplied, halfAmountSupplied).toString(); // rewards are given to amount of USDe supplied up to half of total amount supplied
210
+ return { isEligible: true, eligibleUSDAmount: USDeAmountEligibleForRewards };
211
+ };
212
+ exports.isEligibleForEthenaUSDeRewards = isEligibleForEthenaUSDeRewards;
213
+ const calculateNetApy = ({ usedAssets, assetsData, isMorpho = false, isAave = false, }) => {
214
+ const { isEligible, eligibleUSDAmount } = isAave ? (0, exports.isEligibleForEthenaUSDeRewards)(usedAssets) : { isEligible: true, eligibleUSDAmount: '0' };
181
215
  const sumValues = Object.values(usedAssets).reduce((_acc, usedAsset) => {
182
216
  const acc = Object.assign({}, _acc);
183
217
  const assetData = assetsData[usedAsset.symbol];
@@ -194,6 +228,10 @@ const calculateNetApy = ({ usedAssets, assetsData, isMorpho = false }) => {
194
228
  const incentiveInterest = (0, exports.calculateInterestEarned)(amount, assetData.incentiveSupplyApy, 'year', true);
195
229
  acc.incentiveUsd = new decimal_js_1.default(acc.incentiveUsd).add(incentiveInterest).toString();
196
230
  }
231
+ if (usedAsset.symbol === 'USDe' && isEligible) {
232
+ const incentiveInterest = (0, exports.calculateInterestEarned)(eligibleUSDAmount, USDE_REWARD_APY, 'year', true);
233
+ acc.incentiveUsd = new decimal_js_1.default(acc.incentiveUsd).add(incentiveInterest).toString();
234
+ }
197
235
  }
198
236
  if (usedAsset.isBorrowed) {
199
237
  const amount = usedAsset.borrowedUsd;
@@ -98,6 +98,7 @@ export const aaveAnyGetAggregatedPositionData = (_a) => {
98
98
  usedAssets,
99
99
  assetsData,
100
100
  isMorpho: isMorphoAave({ selectedMarket }),
101
+ isAave: true,
101
102
  });
102
103
  payload.netApy = netApy;
103
104
  payload.incentiveUsd = incentiveUsd;
@@ -10,7 +10,7 @@ export declare const getLiquityV2UserTroveIds: (web3: Web3, network: NetworkNumb
10
10
  }>;
11
11
  export declare const getDebtInFrontForSingleMarketLiquityV2: (viewContract: any, marketAddress: EthAddress, troveId: string, accumulatedSum?: string, iterations?: number) => Promise<string>;
12
12
  export declare const getDebtInFrontForInterestRateSingleMarketLiquityV2: (viewContract: any, marketAddress: EthAddress, interestRate: string, troveId?: string, accumulatedSum?: string, iterations?: number) => Promise<string>;
13
- export declare const getAllMarketsUnbackedDebts: (markets: Record<LiquityV2Versions, LiquityV2MarketData>, web3: Web3, network: NetworkNumber) => Promise<Record<LiquityV2Versions, string>>;
13
+ export declare const getAllMarketsUnbackedDebts: (markets: Record<LiquityV2Versions, LiquityV2MarketData>, isLegacy: boolean, web3: Web3, network: NetworkNumber) => Promise<Record<LiquityV2Versions, string>>;
14
14
  export declare const calculateDebtInFrontLiquityV2: (markets: Record<LiquityV2Versions, LiquityV2MarketData>, selectedMarket: LiquityV2Versions, allMarketsUnbackedDebts: Record<LiquityV2Versions, string>, interestRateDebtInFront: string) => string;
15
15
  export declare const getDebtInFrontLiquityV2: (markets: Record<LiquityV2Versions, LiquityV2MarketData>, selectedMarket: LiquityV2Versions, web3: Web3, network: NetworkNumber, viewContract: any, troveId: string) => Promise<string>;
16
16
  /**
@@ -164,10 +164,12 @@ const getUnbackedDebtForSingleMarket = (totalBorrowed, web3, network, stabilityP
164
164
  const totalBoldDepositsInEth = assetAmountInEth(totalBoldDeposits);
165
165
  return Dec.max(new Dec(totalBorrowed).sub(totalBoldDepositsInEth), 0).toString();
166
166
  });
167
- export const getAllMarketsUnbackedDebts = (markets, web3, network) => __awaiter(void 0, void 0, void 0, function* () {
167
+ export const getAllMarketsUnbackedDebts = (markets, isLegacy, web3, network) => __awaiter(void 0, void 0, void 0, function* () {
168
168
  const allMarketsUnbackedDebt = yield Promise.all(Object.entries(markets).map(([version, market]) => __awaiter(void 0, void 0, void 0, function* () {
169
169
  const { assetsData, marketData } = market;
170
- const { debtToken } = LiquityV2Markets(network)[version];
170
+ const { debtToken, isLegacy: isLegacyMarket } = LiquityV2Markets(network)[version];
171
+ if (isLegacyMarket !== isLegacy)
172
+ return [version, '0'];
171
173
  const unbackedDebt = yield getUnbackedDebtForSingleMarket(assetsData[debtToken].totalBorrow, web3, network, marketData.stabilityPoolAddress);
172
174
  return [version, unbackedDebt];
173
175
  })));
@@ -175,10 +177,12 @@ export const getAllMarketsUnbackedDebts = (markets, web3, network) => __awaiter(
175
177
  });
176
178
  export const calculateDebtInFrontLiquityV2 = (markets, selectedMarket, allMarketsUnbackedDebts, interestRateDebtInFront) => {
177
179
  const selectedMarketUnbackedDebt = new Dec(allMarketsUnbackedDebts[selectedMarket]);
180
+ const { isLegacy } = LiquityV2Markets(NetworkNumber.Eth)[selectedMarket];
178
181
  if (selectedMarketUnbackedDebt.eq(0))
179
- return 'N/A';
182
+ return interestRateDebtInFront;
180
183
  const amountBeingReedemedOnEachMarket = Object.entries(markets).map(([version, market]) => {
181
- if (version === selectedMarket)
184
+ const { isLegacy: isLegacyMarket } = LiquityV2Markets(NetworkNumber.Eth)[version];
185
+ if (version === selectedMarket && isLegacyMarket !== isLegacy)
182
186
  return new Dec(interestRateDebtInFront);
183
187
  const { assetsData } = market;
184
188
  const { debtToken } = LiquityV2Markets(NetworkNumber.Eth)[version];
@@ -190,7 +194,8 @@ export const calculateDebtInFrontLiquityV2 = (markets, selectedMarket, allMarket
190
194
  return amountBeingReedemedOnEachMarket.reduce((acc, val) => acc.plus(val), new Dec(0)).toString();
191
195
  };
192
196
  export const getDebtInFrontLiquityV2 = (markets, selectedMarket, web3, network, viewContract, troveId) => __awaiter(void 0, void 0, void 0, function* () {
193
- const allMarketsUnbackedDebts = yield getAllMarketsUnbackedDebts(markets, web3, network);
197
+ const { isLegacy } = LiquityV2Markets(NetworkNumber.Eth)[selectedMarket];
198
+ const allMarketsUnbackedDebts = yield getAllMarketsUnbackedDebts(markets, isLegacy, web3, network);
194
199
  const interestRateDebtInFront = yield getDebtInFrontForSingleMarketLiquityV2(viewContract, LiquityV2Markets(network)[selectedMarket].marketAddress, troveId);
195
200
  return calculateDebtInFrontLiquityV2(markets, selectedMarket, allMarketsUnbackedDebts, interestRateDebtInFront.toString());
196
201
  });
@@ -204,7 +209,8 @@ export const getDebtInFrontLiquityV2 = (markets, selectedMarket, web3, network,
204
209
  * @param debtInFrontBeingMoved - amound of debt being repositioned if interest rate is being increased (prevents including it as debt in front)
205
210
  */
206
211
  export const getDebtInFrontForInterestRateLiquityV2 = (markets, selectedMarket, web3, network, viewContract, interestRate, debtInFrontBeingMoved = '0') => __awaiter(void 0, void 0, void 0, function* () {
207
- const allMarketsUnbackedDebts = yield getAllMarketsUnbackedDebts(markets, web3, network);
212
+ const { isLegacy } = LiquityV2Markets(NetworkNumber.Eth)[selectedMarket];
213
+ const allMarketsUnbackedDebts = yield getAllMarketsUnbackedDebts(markets, isLegacy, web3, network);
208
214
  const interestRateDebtInFront = new Dec(yield getDebtInFrontForInterestRateSingleMarketLiquityV2(viewContract, LiquityV2Markets(network)[selectedMarket].marketAddress, interestRate))
209
215
  .sub(debtInFrontBeingMoved);
210
216
  return calculateDebtInFrontLiquityV2(markets, selectedMarket, allMarketsUnbackedDebts, interestRateDebtInFront.toString());
@@ -14,7 +14,7 @@ export const multicall = (calls, web3, network = NetworkNumber.Eth, blockNumber
14
14
  const multicallContract = UniMulticallContract(web3, network);
15
15
  const formattedCalls = calls.map((call) => {
16
16
  const callData = web3.eth.abi.encodeFunctionCall(call.abiItem, call.params);
17
- return { callData, target: call.target || '0x0', gasLimit: call.gasLimit || 1500000 };
17
+ return { callData, target: call.target || '0x0', gasLimit: call.gasLimit || 1800000 };
18
18
  });
19
19
  const callResult = yield multicallContract.methods.multicall(formattedCalls.filter(item => item.target !== '0x0')).call({}, blockNumber);
20
20
  let formattedResult = [];
@@ -4,10 +4,15 @@ import { MMAssetsData, MMUsedAssets } from '../types/common';
4
4
  export declare const STAKING_ASSETS: string[];
5
5
  export declare const getStakingApy: ((asset: string, web3: Web3, blockNumber?: 'latest' | number, fromBlock?: number | undefined) => Promise<string>) & memoize.Memoized<(asset: string, web3: Web3, blockNumber?: 'latest' | number, fromBlock?: number | undefined) => Promise<string>>;
6
6
  export declare const calculateInterestEarned: (principal: string, interest: string, type: string, apy?: boolean) => number;
7
- export declare const calculateNetApy: ({ usedAssets, assetsData, isMorpho }: {
7
+ export declare const isEligibleForEthenaUSDeRewards: (usedAssets: MMUsedAssets) => {
8
+ isEligible: boolean;
9
+ eligibleUSDAmount: string;
10
+ };
11
+ export declare const calculateNetApy: ({ usedAssets, assetsData, isMorpho, isAave, }: {
8
12
  usedAssets: MMUsedAssets;
9
13
  assetsData: MMAssetsData;
10
14
  isMorpho?: boolean | undefined;
15
+ isAave?: boolean | undefined;
11
16
  }) => {
12
17
  netApy: string;
13
18
  totalInterestUsd: string;
@@ -170,7 +170,40 @@ export const calculateInterestEarned = (principal, interest, type, apy = false)
170
170
  }
171
171
  return (+principal * (Math.pow(((1 + (+interest / 100) / BLOCKS_IN_A_YEAR)), (BLOCKS_IN_A_YEAR * interval)))) - +principal; // eslint-disable-line
172
172
  };
173
- export const calculateNetApy = ({ usedAssets, assetsData, isMorpho = false }) => {
173
+ const USDE_REWARD_APY = '12';
174
+ export const isEligibleForEthenaUSDeRewards = (usedAssets) => {
175
+ var _a, _b;
176
+ const USDeUSDAmountSupplied = ((_a = usedAssets.USDe) === null || _a === void 0 ? void 0 : _a.suppliedUsd) || '0';
177
+ const sUSDeUSDAmountSupplied = ((_b = usedAssets.sUSDe) === null || _b === void 0 ? void 0 : _b.suppliedUsd) || '0';
178
+ const anythingElseSupplied = Object.values(usedAssets).some((asset) => asset.symbol !== 'USDe' && asset.symbol !== 'sUSDe' && asset.isSupplied);
179
+ if (anythingElseSupplied)
180
+ return { isEligible: false, eligibleUSDAmount: '0' };
181
+ const totalAmountSupplied = new Dec(USDeUSDAmountSupplied).add(sUSDeUSDAmountSupplied).toString();
182
+ const percentageInUSDe = new Dec(USDeUSDAmountSupplied).div(totalAmountSupplied).toNumber();
183
+ if (percentageInUSDe < 0.45 || percentageInUSDe > 0.55)
184
+ return { isEligible: false, eligibleUSDAmount: '0' }; // 45% - 55% of total amount supplied must be in USDe
185
+ const percentageInSUSDe = new Dec(sUSDeUSDAmountSupplied).div(totalAmountSupplied).toNumber();
186
+ if (percentageInSUSDe < 0.45 || percentageInSUSDe > 0.55)
187
+ return { isEligible: false, eligibleUSDAmount: '0' }; // 45% - 55% of total amount supplied must be in sUSDe
188
+ const allowedBorrowAssets = ['USDC', 'USDT', 'USDS'];
189
+ const anythingBorrowedNotAllowed = Object.values(usedAssets).some((asset) => asset.isBorrowed && !allowedBorrowAssets.includes(asset.symbol));
190
+ if (anythingBorrowedNotAllowed)
191
+ return { isEligible: false, eligibleUSDAmount: '0' };
192
+ const totalAmountBorrowed = Object.values(usedAssets).reduce((acc, asset) => {
193
+ if (asset.isBorrowed) {
194
+ return acc.add(asset.borrowedUsd);
195
+ }
196
+ return acc;
197
+ }, new Dec(0)).toString();
198
+ const borrowPercentage = new Dec(totalAmountBorrowed).div(totalAmountSupplied).toNumber();
199
+ if (borrowPercentage < 0.5)
200
+ return { isEligible: false, eligibleUSDAmount: '0' }; // must be looped at least once
201
+ const halfAmountSupplied = new Dec(totalAmountSupplied).div(2).toString();
202
+ const USDeAmountEligibleForRewards = Dec.min(USDeUSDAmountSupplied, halfAmountSupplied).toString(); // rewards are given to amount of USDe supplied up to half of total amount supplied
203
+ return { isEligible: true, eligibleUSDAmount: USDeAmountEligibleForRewards };
204
+ };
205
+ export const calculateNetApy = ({ usedAssets, assetsData, isMorpho = false, isAave = false, }) => {
206
+ const { isEligible, eligibleUSDAmount } = isAave ? isEligibleForEthenaUSDeRewards(usedAssets) : { isEligible: true, eligibleUSDAmount: '0' };
174
207
  const sumValues = Object.values(usedAssets).reduce((_acc, usedAsset) => {
175
208
  const acc = Object.assign({}, _acc);
176
209
  const assetData = assetsData[usedAsset.symbol];
@@ -187,6 +220,10 @@ export const calculateNetApy = ({ usedAssets, assetsData, isMorpho = false }) =>
187
220
  const incentiveInterest = calculateInterestEarned(amount, assetData.incentiveSupplyApy, 'year', true);
188
221
  acc.incentiveUsd = new Dec(acc.incentiveUsd).add(incentiveInterest).toString();
189
222
  }
223
+ if (usedAsset.symbol === 'USDe' && isEligible) {
224
+ const incentiveInterest = calculateInterestEarned(eligibleUSDAmount, USDE_REWARD_APY, 'year', true);
225
+ acc.incentiveUsd = new Dec(acc.incentiveUsd).add(incentiveInterest).toString();
226
+ }
190
227
  }
191
228
  if (usedAsset.isBorrowed) {
192
229
  const amount = usedAsset.borrowedUsd;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defisaver/positions-sdk",
3
- "version": "1.0.30",
3
+ "version": "1.0.32-dev-1",
4
4
  "description": "",
5
5
  "main": "./cjs/index.js",
6
6
  "module": "./esm/index.js",
@@ -129,6 +129,7 @@ export const aaveAnyGetAggregatedPositionData = ({
129
129
  usedAssets,
130
130
  assetsData,
131
131
  isMorpho: isMorphoAave({ selectedMarket }),
132
+ isAave: true,
132
133
  });
133
134
  payload.netApy = netApy;
134
135
  payload.incentiveUsd = incentiveUsd;
@@ -188,10 +188,11 @@ const getUnbackedDebtForSingleMarket = async (totalBorrowed: string, web3: Web3,
188
188
  return Dec.max(new Dec(totalBorrowed).sub(totalBoldDepositsInEth), 0).toString();
189
189
  };
190
190
 
191
- export const getAllMarketsUnbackedDebts = async (markets: Record<LiquityV2Versions, LiquityV2MarketData>, web3: Web3, network: NetworkNumber): Promise<Record<LiquityV2Versions, string>> => {
191
+ export const getAllMarketsUnbackedDebts = async (markets: Record<LiquityV2Versions, LiquityV2MarketData>, isLegacy: boolean, web3: Web3, network: NetworkNumber): Promise<Record<LiquityV2Versions, string>> => {
192
192
  const allMarketsUnbackedDebt = await Promise.all(Object.entries(markets).map(async ([version, market]) => {
193
193
  const { assetsData, marketData } = market;
194
- const { debtToken } = LiquityV2Markets(network)[version as LiquityV2Versions];
194
+ const { debtToken, isLegacy: isLegacyMarket } = LiquityV2Markets(network)[version as LiquityV2Versions];
195
+ if (isLegacyMarket !== isLegacy) return [version, '0'];
195
196
  const unbackedDebt = await getUnbackedDebtForSingleMarket(assetsData[debtToken].totalBorrow, web3, network, marketData.stabilityPoolAddress);
196
197
  return [version, unbackedDebt];
197
198
  }));
@@ -201,10 +202,12 @@ export const getAllMarketsUnbackedDebts = async (markets: Record<LiquityV2Versio
201
202
 
202
203
  export const calculateDebtInFrontLiquityV2 = (markets: Record<LiquityV2Versions, LiquityV2MarketData>, selectedMarket: LiquityV2Versions, allMarketsUnbackedDebts: Record<LiquityV2Versions, string>, interestRateDebtInFront: string): string => {
203
204
  const selectedMarketUnbackedDebt = new Dec(allMarketsUnbackedDebts[selectedMarket]);
204
- if (selectedMarketUnbackedDebt.eq(0)) return 'N/A';
205
+ const { isLegacy } = LiquityV2Markets(NetworkNumber.Eth)[selectedMarket];
206
+ if (selectedMarketUnbackedDebt.eq(0)) return interestRateDebtInFront;
205
207
 
206
208
  const amountBeingReedemedOnEachMarket = Object.entries(markets).map(([version, market]) => {
207
- if (version === selectedMarket) return new Dec(interestRateDebtInFront);
209
+ const { isLegacy: isLegacyMarket } = LiquityV2Markets(NetworkNumber.Eth)[version as LiquityV2Versions];
210
+ if (version === selectedMarket && isLegacyMarket !== isLegacy) return new Dec(interestRateDebtInFront);
208
211
  const { assetsData } = market;
209
212
  const { debtToken } = LiquityV2Markets(NetworkNumber.Eth)[version as LiquityV2Versions];
210
213
  const unbackedDebt = new Dec(allMarketsUnbackedDebts[version as LiquityV2Versions]);
@@ -217,7 +220,8 @@ export const calculateDebtInFrontLiquityV2 = (markets: Record<LiquityV2Versions,
217
220
  };
218
221
 
219
222
  export const getDebtInFrontLiquityV2 = async (markets: Record<LiquityV2Versions, LiquityV2MarketData>, selectedMarket: LiquityV2Versions, web3: Web3, network: NetworkNumber, viewContract: any, troveId: string) => {
220
- const allMarketsUnbackedDebts = await getAllMarketsUnbackedDebts(markets, web3, network);
223
+ const { isLegacy } = LiquityV2Markets(NetworkNumber.Eth)[selectedMarket];
224
+ const allMarketsUnbackedDebts = await getAllMarketsUnbackedDebts(markets, isLegacy, web3, network);
221
225
  const interestRateDebtInFront = await getDebtInFrontForSingleMarketLiquityV2(viewContract, LiquityV2Markets(network)[selectedMarket].marketAddress, troveId);
222
226
 
223
227
  return calculateDebtInFrontLiquityV2(markets, selectedMarket, allMarketsUnbackedDebts, interestRateDebtInFront.toString());
@@ -233,7 +237,8 @@ export const getDebtInFrontLiquityV2 = async (markets: Record<LiquityV2Versions,
233
237
  * @param debtInFrontBeingMoved - amound of debt being repositioned if interest rate is being increased (prevents including it as debt in front)
234
238
  */
235
239
  export const getDebtInFrontForInterestRateLiquityV2 = async (markets: Record<LiquityV2Versions, LiquityV2MarketData>, selectedMarket: LiquityV2Versions, web3: Web3, network: NetworkNumber, viewContract: any, interestRate: string, debtInFrontBeingMoved: string = '0') => {
236
- const allMarketsUnbackedDebts = await getAllMarketsUnbackedDebts(markets, web3, network);
240
+ const { isLegacy } = LiquityV2Markets(NetworkNumber.Eth)[selectedMarket];
241
+ const allMarketsUnbackedDebts = await getAllMarketsUnbackedDebts(markets, isLegacy, web3, network);
237
242
  const interestRateDebtInFront = new Dec(await getDebtInFrontForInterestRateSingleMarketLiquityV2(viewContract, LiquityV2Markets(network)[selectedMarket].marketAddress, interestRate))
238
243
  .sub(debtInFrontBeingMoved);
239
244
 
@@ -7,7 +7,7 @@ export const multicall = async (calls: any[], web3: Web3, network: NetworkNumber
7
7
  const multicallContract = UniMulticallContract(web3, network);
8
8
  const formattedCalls = calls.map((call) => {
9
9
  const callData = web3.eth.abi.encodeFunctionCall(call.abiItem, call.params);
10
- return { callData, target: call.target || '0x0', gasLimit: call.gasLimit || 1500000 };
10
+ return { callData, target: call.target || '0x0', gasLimit: call.gasLimit || 1800000 };
11
11
  });
12
12
  const callResult = await multicallContract.methods.multicall(formattedCalls.filter(item => item.target !== '0x0')).call({}, blockNumber);
13
13
 
@@ -155,7 +155,43 @@ export const calculateInterestEarned = (principal: string, interest: string, typ
155
155
  return (+principal * (((1 + (+interest / 100) / BLOCKS_IN_A_YEAR)) ** (BLOCKS_IN_A_YEAR * interval))) - +principal; // eslint-disable-line
156
156
  };
157
157
 
158
- export const calculateNetApy = ({ usedAssets, assetsData, isMorpho = false }: { usedAssets: MMUsedAssets, assetsData: MMAssetsData, isMorpho?: boolean }) => {
158
+ const USDE_REWARD_APY = '12';
159
+
160
+ export const isEligibleForEthenaUSDeRewards = (usedAssets: MMUsedAssets) => {
161
+ const USDeUSDAmountSupplied = usedAssets.USDe?.suppliedUsd || '0';
162
+ const sUSDeUSDAmountSupplied = usedAssets.sUSDe?.suppliedUsd || '0';
163
+ const anythingElseSupplied = Object.values(usedAssets).some((asset) => asset.symbol !== 'USDe' && asset.symbol !== 'sUSDe' && asset.isSupplied);
164
+ if (anythingElseSupplied) return { isEligible: false, eligibleUSDAmount: '0' };
165
+ const totalAmountSupplied = new Dec(USDeUSDAmountSupplied).add(sUSDeUSDAmountSupplied).toString();
166
+ const percentageInUSDe = new Dec(USDeUSDAmountSupplied).div(totalAmountSupplied).toNumber();
167
+ if (percentageInUSDe < 0.45 || percentageInUSDe > 0.55) return { isEligible: false, eligibleUSDAmount: '0' }; // 45% - 55% of total amount supplied must be in USDe
168
+ const percentageInSUSDe = new Dec(sUSDeUSDAmountSupplied).div(totalAmountSupplied).toNumber();
169
+ if (percentageInSUSDe < 0.45 || percentageInSUSDe > 0.55) return { isEligible: false, eligibleUSDAmount: '0' }; // 45% - 55% of total amount supplied must be in sUSDe
170
+
171
+ const allowedBorrowAssets = ['USDC', 'USDT', 'USDS'];
172
+ const anythingBorrowedNotAllowed = Object.values(usedAssets).some((asset) => asset.isBorrowed && !allowedBorrowAssets.includes(asset.symbol));
173
+ if (anythingBorrowedNotAllowed) return { isEligible: false, eligibleUSDAmount: '0' };
174
+
175
+ const totalAmountBorrowed = Object.values(usedAssets).reduce((acc, asset) => {
176
+ if (asset.isBorrowed) {
177
+ return acc.add(asset.borrowedUsd);
178
+ }
179
+ return acc;
180
+ }, new Dec(0)).toString();
181
+
182
+ const borrowPercentage = new Dec(totalAmountBorrowed).div(totalAmountSupplied).toNumber();
183
+ if (borrowPercentage < 0.5) return { isEligible: false, eligibleUSDAmount: '0' }; // must be looped at least once
184
+
185
+ const halfAmountSupplied = new Dec(totalAmountSupplied).div(2).toString();
186
+ const USDeAmountEligibleForRewards = Dec.min(USDeUSDAmountSupplied, halfAmountSupplied).toString(); // rewards are given to amount of USDe supplied up to half of total amount supplied
187
+
188
+ return { isEligible: true, eligibleUSDAmount: USDeAmountEligibleForRewards };
189
+ };
190
+
191
+ export const calculateNetApy = ({
192
+ usedAssets, assetsData, isMorpho = false, isAave = false,
193
+ }: { usedAssets: MMUsedAssets, assetsData: MMAssetsData, isMorpho?: boolean, isAave?: boolean }) => {
194
+ const { isEligible, eligibleUSDAmount } = isAave ? isEligibleForEthenaUSDeRewards(usedAssets) : { isEligible: true, eligibleUSDAmount: '0' };
159
195
  const sumValues = Object.values(usedAssets).reduce((_acc, usedAsset) => {
160
196
  const acc = { ..._acc };
161
197
  const assetData = assetsData[usedAsset.symbol];
@@ -173,6 +209,11 @@ export const calculateNetApy = ({ usedAssets, assetsData, isMorpho = false }: {
173
209
  const incentiveInterest = calculateInterestEarned(amount, assetData.incentiveSupplyApy, 'year', true);
174
210
  acc.incentiveUsd = new Dec(acc.incentiveUsd).add(incentiveInterest).toString();
175
211
  }
212
+
213
+ if (usedAsset.symbol === 'USDe' && isEligible) {
214
+ const incentiveInterest = calculateInterestEarned(eligibleUSDAmount, USDE_REWARD_APY, 'year', true);
215
+ acc.incentiveUsd = new Dec(acc.incentiveUsd).add(incentiveInterest).toString();
216
+ }
176
217
  }
177
218
 
178
219
  if (usedAsset.isBorrowed) {