@defisaver/positions-sdk 2.1.166 → 2.1.168-stable-pair-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.
- package/cjs/aaveV2/index.js +8 -29
- package/cjs/aaveV3/index.js +2 -31
- package/cjs/aaveV4/index.d.ts +25 -0
- package/cjs/aaveV4/index.js +4 -1
- package/cjs/compoundV2/index.d.ts +1 -1
- package/cjs/compoundV2/index.js +2 -2
- package/cjs/curveUsd/index.d.ts +1 -1
- package/cjs/curveUsd/index.js +6 -1
- package/cjs/fluid/index.js +13 -12
- package/cjs/helpers/aaveBalances.d.ts +5 -0
- package/cjs/helpers/aaveBalances.js +51 -0
- package/cjs/helpers/aaveV4Helpers/index.js +11 -1
- package/cjs/helpers/fluidBalances.d.ts +6 -0
- package/cjs/helpers/fluidBalances.js +36 -0
- package/cjs/liquityV2/index.d.ts +8 -0
- package/cjs/liquityV2/index.js +3 -3
- package/cjs/llamaLend/index.d.ts +1 -1
- package/cjs/llamaLend/index.js +6 -1
- package/cjs/markets/morphoBlue/index.d.ts +0 -2
- package/cjs/markets/morphoBlue/index.js +3 -20
- package/cjs/moneymarket/moneymarketCommonService.js +12 -2
- package/cjs/morphoMidnight/index.d.ts +1 -1
- package/cjs/morphoMidnight/index.js +6 -1
- package/cjs/portfolio/index.d.ts +1 -0
- package/cjs/portfolio/index.js +3 -0
- package/cjs/portfolio/lendingSummaries.d.ts +7 -0
- package/cjs/portfolio/lendingSummaries.js +262 -0
- package/cjs/portfolio/lendingSummaryTransport.d.ts +8 -0
- package/cjs/portfolio/lendingSummaryTransport.js +109 -0
- package/cjs/spark/index.js +2 -31
- package/cjs/types/common.d.ts +1 -0
- package/cjs/types/common.js +1 -0
- package/cjs/types/index.d.ts +1 -0
- package/cjs/types/index.js +1 -0
- package/cjs/types/lendingSummary.d.ts +34 -0
- package/cjs/types/lendingSummary.js +2 -0
- package/cjs/types/morphoBlue.d.ts +0 -1
- package/cjs/types/morphoBlue.js +0 -1
- package/esm/aaveV2/index.js +11 -32
- package/esm/aaveV3/index.js +3 -32
- package/esm/aaveV4/index.d.ts +25 -0
- package/esm/aaveV4/index.js +3 -1
- package/esm/compoundV2/index.d.ts +1 -1
- package/esm/compoundV2/index.js +2 -2
- package/esm/curveUsd/index.d.ts +1 -1
- package/esm/curveUsd/index.js +6 -1
- package/esm/fluid/index.js +13 -12
- package/esm/helpers/aaveBalances.d.ts +5 -0
- package/esm/helpers/aaveBalances.js +45 -0
- package/esm/helpers/aaveV4Helpers/index.js +11 -1
- package/esm/helpers/fluidBalances.d.ts +6 -0
- package/esm/helpers/fluidBalances.js +28 -0
- package/esm/liquityV2/index.d.ts +8 -0
- package/esm/liquityV2/index.js +1 -1
- package/esm/llamaLend/index.d.ts +1 -1
- package/esm/llamaLend/index.js +6 -1
- package/esm/markets/morphoBlue/index.d.ts +0 -2
- package/esm/markets/morphoBlue/index.js +0 -16
- package/esm/moneymarket/moneymarketCommonService.js +12 -2
- package/esm/morphoMidnight/index.d.ts +1 -1
- package/esm/morphoMidnight/index.js +6 -1
- package/esm/portfolio/index.d.ts +1 -0
- package/esm/portfolio/index.js +1 -0
- package/esm/portfolio/lendingSummaries.d.ts +7 -0
- package/esm/portfolio/lendingSummaries.js +256 -0
- package/esm/portfolio/lendingSummaryTransport.d.ts +8 -0
- package/esm/portfolio/lendingSummaryTransport.js +104 -0
- package/esm/spark/index.js +4 -33
- package/esm/types/common.d.ts +1 -0
- package/esm/types/common.js +1 -0
- package/esm/types/index.d.ts +1 -0
- package/esm/types/index.js +1 -0
- package/esm/types/lendingSummary.d.ts +34 -0
- package/esm/types/lendingSummary.js +1 -0
- package/esm/types/morphoBlue.d.ts +0 -1
- package/esm/types/morphoBlue.js +0 -1
- package/package.json +1 -1
- package/src/aaveV2/index.ts +8 -48
- package/src/aaveV3/index.ts +2 -48
- package/src/aaveV4/index.ts +6 -1
- package/src/compoundV2/index.ts +2 -2
- package/src/curveUsd/index.ts +6 -1
- package/src/fluid/index.ts +13 -12
- package/src/helpers/aaveBalances.ts +41 -0
- package/src/helpers/aaveV4Helpers/index.ts +12 -1
- package/src/helpers/fluidBalances.ts +34 -0
- package/src/liquityV2/index.ts +1 -1
- package/src/llamaLend/index.ts +6 -1
- package/src/markets/morphoBlue/index.ts +0 -16
- package/src/moneymarket/moneymarketCommonService.ts +13 -2
- package/src/morphoMidnight/index.ts +6 -1
- package/src/portfolio/index.ts +2 -0
- package/src/portfolio/lendingSummaries.ts +216 -0
- package/src/portfolio/lendingSummaryTransport.ts +84 -0
- package/src/spark/index.ts +3 -49
- package/src/types/common.ts +1 -0
- package/src/types/index.ts +2 -1
- package/src/types/lendingSummary.ts +41 -0
- package/src/types/morphoBlue.ts +0 -1
package/src/aaveV3/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { assetAmountInEth, assetAmountInWei, getAssetInfo } from '@defisaver/tokens';
|
|
2
2
|
import { Client } from 'viem';
|
|
3
3
|
import Dec from 'decimal.js';
|
|
4
|
+
import { getAaveLikeBalances } from '../helpers/aaveBalances';
|
|
4
5
|
import {
|
|
5
6
|
AaveIncentiveDataProviderV3ContractViem,
|
|
6
7
|
AaveIncentivesControllerViem,
|
|
@@ -17,7 +18,6 @@ import {
|
|
|
17
18
|
isEnabledOnBitmap,
|
|
18
19
|
isLayer2Network,
|
|
19
20
|
wethToEth,
|
|
20
|
-
wethToEthByAddress,
|
|
21
21
|
} from '../services/utils';
|
|
22
22
|
import { getStakingApy, STAKING_ASSETS } from '../staking';
|
|
23
23
|
import {
|
|
@@ -384,53 +384,7 @@ export const EMPTY_AAVE_DATA = {
|
|
|
384
384
|
};
|
|
385
385
|
|
|
386
386
|
export const _getAaveV3AccountBalances = async (provider: Client, network: NetworkNumber, block: Blockish, addressMapping: boolean, address: EthAddress): Promise<PositionBalances> => {
|
|
387
|
-
|
|
388
|
-
collateral: {},
|
|
389
|
-
debt: {},
|
|
390
|
-
};
|
|
391
|
-
|
|
392
|
-
if (!address) {
|
|
393
|
-
return balances;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
const loanInfoContract = AaveV3ViewContractViem(provider, network, block);
|
|
397
|
-
|
|
398
|
-
const market = AAVE_V3(network);
|
|
399
|
-
const marketAddress = market.providerAddress;
|
|
400
|
-
// @ts-ignore
|
|
401
|
-
const protocolDataProviderContract = createViemContractFromConfigFunc(market.protocolData, market.protocolDataAddress)(provider, network);
|
|
402
|
-
|
|
403
|
-
// @ts-ignore
|
|
404
|
-
const reserveTokens = await protocolDataProviderContract.read.getAllReservesTokens(setViemBlockNumber(block)) as { symbol: string, tokenAddress: EthAddress }[];
|
|
405
|
-
const symbols = reserveTokens.map(({ symbol }: { symbol: string }) => symbol);
|
|
406
|
-
const _addresses = reserveTokens.map(({ tokenAddress }: { tokenAddress: EthAddress }) => tokenAddress);
|
|
407
|
-
|
|
408
|
-
// split addresses in half to avoid gas limit by multicall
|
|
409
|
-
const middleAddressIndex = Math.floor(_addresses.length / 2);
|
|
410
|
-
|
|
411
|
-
const [tokenBalances1, tokenBalances2] = await Promise.all([
|
|
412
|
-
loanInfoContract.read.getTokenBalances([marketAddress, address, _addresses.slice(0, middleAddressIndex)], setViemBlockNumber(block)),
|
|
413
|
-
loanInfoContract.read.getTokenBalances([marketAddress, address, _addresses.slice(middleAddressIndex, _addresses.length)], setViemBlockNumber(block)),
|
|
414
|
-
]);
|
|
415
|
-
|
|
416
|
-
const loanInfo = [...tokenBalances1, ...tokenBalances2];
|
|
417
|
-
|
|
418
|
-
loanInfo.forEach((tokenInfo: any, i: number) => {
|
|
419
|
-
const asset = wethToEth(symbols[i]);
|
|
420
|
-
const assetAddr = wethToEthByAddress(_addresses[i], network).toLowerCase();
|
|
421
|
-
|
|
422
|
-
balances = {
|
|
423
|
-
collateral: {
|
|
424
|
-
...balances.collateral,
|
|
425
|
-
[addressMapping ? assetAddr : asset]: tokenInfo.balance.toString(),
|
|
426
|
-
},
|
|
427
|
-
debt: {
|
|
428
|
-
...balances.debt,
|
|
429
|
-
[addressMapping ? assetAddr : asset]: new Dec(tokenInfo.borrowsStable.toString()).add(tokenInfo.borrowsVariable.toString()).toString(),
|
|
430
|
-
},
|
|
431
|
-
};
|
|
432
|
-
});
|
|
433
|
-
|
|
387
|
+
const balances = await getAaveLikeBalances(provider, network, block, addressMapping, address, AAVE_V3(network), 'AaveV3View');
|
|
434
388
|
return balances;
|
|
435
389
|
};
|
|
436
390
|
|
package/src/aaveV4/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Client } from 'viem';
|
|
2
2
|
import Dec from 'decimal.js';
|
|
3
3
|
import { assetAmountInEth, assetAmountInWei, getAssetInfoByAddress } from '@defisaver/tokens';
|
|
4
|
-
import { getViemProvider } from '../services/viem';
|
|
4
|
+
import { getViemProvider, setViemBlockNumber } from '../services/viem';
|
|
5
5
|
import {
|
|
6
6
|
AaveV4AccountData,
|
|
7
7
|
AaveV4HubAssetOnChainData,
|
|
@@ -275,6 +275,11 @@ export async function _getAaveV4AccountData(provider: Client, network: NetworkNu
|
|
|
275
275
|
};
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
+
/** Shared raw read; no spoke metadata or market enrichment. */
|
|
279
|
+
export const _getAaveV4LoanBalances = (provider: Client, network: NetworkNumber, block: Blockish, address: EthAddress, spoke: EthAddress) => (
|
|
280
|
+
AaveV4ViewContractViem(provider, network, block).read.getLoanData([spoke, address], setViemBlockNumber(block))
|
|
281
|
+
);
|
|
282
|
+
|
|
278
283
|
/**
|
|
279
284
|
* Lightweight existence check for Loan Shifter / UI discovery.
|
|
280
285
|
* Reads only `getLoanData(spoke, user)` and returns whether any reserve has
|
package/src/compoundV2/index.ts
CHANGED
|
@@ -116,7 +116,7 @@ const getAllMarketAddresses = async (provider: Client, network: NetworkNumber, b
|
|
|
116
116
|
};
|
|
117
117
|
|
|
118
118
|
|
|
119
|
-
export const _getCompoundV2AccountBalances = async (provider: Client, network: NetworkNumber, block: Blockish, addressMapping: boolean, address: EthAddress): Promise<PositionBalances> => {
|
|
119
|
+
export const _getCompoundV2AccountBalances = async (provider: Client, network: NetworkNumber, block: Blockish, addressMapping: boolean, address: EthAddress, tokens?: EthAddress[]): Promise<PositionBalances> => {
|
|
120
120
|
let balances: PositionBalances = {
|
|
121
121
|
collateral: {},
|
|
122
122
|
debt: {},
|
|
@@ -126,7 +126,7 @@ export const _getCompoundV2AccountBalances = async (provider: Client, network: N
|
|
|
126
126
|
return balances;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
const assets = await getAllMarketAddresses(provider, network, block);
|
|
129
|
+
const assets = tokens || await getAllMarketAddresses(provider, network, block);
|
|
130
130
|
const assetInfo = assets.map(a => getAssetInfoByAddress(a, network));
|
|
131
131
|
const loanInfoContract = CompoundLoanInfoContractViem(provider, network, block);
|
|
132
132
|
const loanInfo = await loanInfoContract.read.getTokenBalances([address, assets], setViemBlockNumber(block));
|
package/src/curveUsd/index.ts
CHANGED
|
@@ -128,7 +128,7 @@ const getStatusForUser = (bandRange: string[], activeBand: string, crvUSDSupplie
|
|
|
128
128
|
return CrvUSDStatus.Nonexistant;
|
|
129
129
|
};
|
|
130
130
|
|
|
131
|
-
export const _getCrvUsdAccountBalances = async (provider: Client, network: NetworkNumber, block: Blockish, addressMapping: boolean, address: EthAddress, controllerAddress: EthAddress): Promise<PositionBalances> => {
|
|
131
|
+
export const _getCrvUsdAccountBalances = async (provider: Client, network: NetworkNumber, block: Blockish, addressMapping: boolean, address: EthAddress, controllerAddress: EthAddress, includeDeposited = false): Promise<PositionBalances> => {
|
|
132
132
|
let balances: PositionBalances = {
|
|
133
133
|
collateral: {},
|
|
134
134
|
debt: {},
|
|
@@ -152,6 +152,11 @@ export const _getCrvUsdAccountBalances = async (provider: Client, network: Netwo
|
|
|
152
152
|
},
|
|
153
153
|
};
|
|
154
154
|
|
|
155
|
+
if (includeDeposited) {
|
|
156
|
+
balances.deposited = {
|
|
157
|
+
[addressMapping ? getAssetInfo(wethToEth(selectedMarket.baseAsset), network).address.toLowerCase() : wethToEth(selectedMarket.baseAsset)]: data.curveUsdCollateralAmount.toString(),
|
|
158
|
+
};
|
|
159
|
+
}
|
|
155
160
|
return balances;
|
|
156
161
|
};
|
|
157
162
|
|
package/src/fluid/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
assetAmountInEth, AssetData, getAssetInfo, getAssetInfoByAddress,
|
|
4
4
|
} from '@defisaver/tokens';
|
|
5
5
|
import { Client, PublicClient } from 'viem';
|
|
6
|
+
import { fluidTokenAmount } from '../helpers/fluidBalances';
|
|
6
7
|
import {
|
|
7
8
|
EthAddress, EthereumProvider, IncentiveKind, NetworkNumber,
|
|
8
9
|
} from '../types/common';
|
|
@@ -1178,8 +1179,8 @@ const parseT1UserData = (userPositionData: FluidUserPositionStructOutputStruct,
|
|
|
1178
1179
|
const debtAsset = getAssetInfo(marketData.debtAsset0);
|
|
1179
1180
|
|
|
1180
1181
|
// for T2 and T4 - this is the number of shares
|
|
1181
|
-
const supplied =
|
|
1182
|
-
const borrowed =
|
|
1182
|
+
const supplied = fluidTokenAmount(userPositionData.supply, collAsset.decimals);
|
|
1183
|
+
const borrowed = fluidTokenAmount(userPositionData.borrow, debtAsset.decimals);
|
|
1183
1184
|
|
|
1184
1185
|
const collUsedAsset: FluidUsedAsset = {
|
|
1185
1186
|
...EMPTY_USED_ASSET,
|
|
@@ -1234,10 +1235,10 @@ const parseT2UserData = (userPositionData: FluidUserPositionStructOutputStruct,
|
|
|
1234
1235
|
const debtAsset = getAssetInfo(marketData.debtAsset0);
|
|
1235
1236
|
|
|
1236
1237
|
const supplyShares = getEthAmountForDecimals(userPositionData.supply.toString(), 18); // this is supplied in coll shares
|
|
1237
|
-
const borrowed =
|
|
1238
|
+
const borrowed = fluidTokenAmount(userPositionData.borrow, debtAsset.decimals); // this is actual token borrow
|
|
1238
1239
|
|
|
1239
|
-
const supplied0 =
|
|
1240
|
-
const supplied1 =
|
|
1240
|
+
const supplied0 = fluidTokenAmount(userPositionData.supply, collAsset0.decimals, assetsData[collAsset0.symbol].tokenPerSupplyShare!);
|
|
1241
|
+
const supplied1 = fluidTokenAmount(userPositionData.supply, collAsset1.decimals, assetsData[collAsset1.symbol].tokenPerSupplyShare!);
|
|
1241
1242
|
|
|
1242
1243
|
const collUsedAsset0: Partial<FluidUsedAsset> = {
|
|
1243
1244
|
symbol: collAsset0.symbol,
|
|
@@ -1302,11 +1303,11 @@ const parseT3UserData = (userPositionData: FluidUserPositionStructOutputStruct,
|
|
|
1302
1303
|
const debtAsset0 = getAssetInfo(marketData.debtAsset0);
|
|
1303
1304
|
const debtAsset1 = getAssetInfo(marketData.debtAsset1);
|
|
1304
1305
|
|
|
1305
|
-
const supplied =
|
|
1306
|
+
const supplied = fluidTokenAmount(userPositionData.supply, collAsset.decimals); // this is actual token supply
|
|
1306
1307
|
const borrowShares = getEthAmountForDecimals(userPositionData.borrow.toString(), 18); // this is actual token borrow
|
|
1307
1308
|
|
|
1308
|
-
const borrowed0 =
|
|
1309
|
-
const borrowed1 =
|
|
1309
|
+
const borrowed0 = fluidTokenAmount(userPositionData.borrow, debtAsset0.decimals, assetsData[debtAsset0.symbol].tokenPerBorrowShare!);
|
|
1310
|
+
const borrowed1 = fluidTokenAmount(userPositionData.borrow, debtAsset1.decimals, assetsData[debtAsset1.symbol].tokenPerBorrowShare!);
|
|
1310
1311
|
|
|
1311
1312
|
const collUsedAsset: Partial<FluidUsedAsset> = {
|
|
1312
1313
|
symbol: collAsset.symbol,
|
|
@@ -1374,11 +1375,11 @@ const parseT4UserData = (userPositionData: FluidUserPositionStructOutputStruct,
|
|
|
1374
1375
|
const supplyShares = getEthAmountForDecimals(userPositionData.supply.toString(), 18); // this is actual token supply
|
|
1375
1376
|
const borrowShares = getEthAmountForDecimals(userPositionData.borrow.toString(), 18); // this is actual token borrow
|
|
1376
1377
|
|
|
1377
|
-
const supplied0 =
|
|
1378
|
-
const supplied1 =
|
|
1378
|
+
const supplied0 = fluidTokenAmount(userPositionData.supply, collAsset0.decimals, assetsData[collAsset0.symbol].tokenPerSupplyShare!);
|
|
1379
|
+
const supplied1 = fluidTokenAmount(userPositionData.supply, collAsset1.decimals, assetsData[collAsset1.symbol].tokenPerSupplyShare!);
|
|
1379
1380
|
|
|
1380
|
-
const borrowed0 =
|
|
1381
|
-
const borrowed1 =
|
|
1381
|
+
const borrowed0 = fluidTokenAmount(userPositionData.borrow, debtAsset0.decimals, assetsData[debtAsset0.symbol].tokenPerBorrowShare!);
|
|
1382
|
+
const borrowed1 = fluidTokenAmount(userPositionData.borrow, debtAsset1.decimals, assetsData[debtAsset1.symbol].tokenPerBorrowShare!);
|
|
1382
1383
|
|
|
1383
1384
|
const collUsedAsset0: Partial<FluidUsedAsset> = {
|
|
1384
1385
|
symbol: collAsset0.symbol,
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import Dec from 'decimal.js';
|
|
2
|
+
import { getAssetInfoByAddress } from '@defisaver/tokens';
|
|
3
|
+
import { Client } from 'viem';
|
|
4
|
+
import { AaveMarketInfo, SparkMarketData } from '../types';
|
|
5
|
+
import {
|
|
6
|
+
Blockish, EthAddress, NetworkNumber, PositionBalances,
|
|
7
|
+
} from '../types/common';
|
|
8
|
+
import { createViemContractFromConfigFunc } from '../contracts';
|
|
9
|
+
import { setViemBlockNumber } from '../services/viem';
|
|
10
|
+
import { wethToEth, wethToEthByAddress } from '../services/utils';
|
|
11
|
+
|
|
12
|
+
/** Raw token balances shared by Aave/Spark getters and lending previews. */
|
|
13
|
+
export async function getAaveLikeBalances(
|
|
14
|
+
client: Client, network: NetworkNumber, block: Blockish, addressMapping: boolean,
|
|
15
|
+
address: EthAddress, market: Pick<AaveMarketInfo | SparkMarketData, 'providerAddress' | 'protocolData' | 'protocolDataAddress'>,
|
|
16
|
+
view: 'AaveLoanInfoV2' | 'AaveV3View' | 'SparkView', tokens?: EthAddress[],
|
|
17
|
+
): Promise<PositionBalances> {
|
|
18
|
+
const balances: PositionBalances = { collateral: {}, debt: {} };
|
|
19
|
+
if (!address) return balances;
|
|
20
|
+
let reserves: { tokenAddress: EthAddress; symbol: string }[];
|
|
21
|
+
if (tokens) reserves = tokens.map(tokenAddress => ({ tokenAddress, symbol: getAssetInfoByAddress(tokenAddress, network).symbol }));
|
|
22
|
+
else {
|
|
23
|
+
if (!market.protocolData) throw new Error('Missing protocol data provider');
|
|
24
|
+
reserves = [...await createViemContractFromConfigFunc(market.protocolData, market.protocolDataAddress as EthAddress)(client, network)
|
|
25
|
+
.read.getAllReservesTokens(setViemBlockNumber(block))];
|
|
26
|
+
}
|
|
27
|
+
const addresses = reserves.map(token => token.tokenAddress);
|
|
28
|
+
const contract = createViemContractFromConfigFunc(view)(client, network, block);
|
|
29
|
+
const middle = tokens ? Math.ceil(addresses.length / 2) : Math.floor(addresses.length / 2);
|
|
30
|
+
// Preserve legacy V2 single-call and V3/Spark two-call behavior.
|
|
31
|
+
const parts = !tokens && view === 'AaveLoanInfoV2' ? [addresses] : [addresses.slice(0, middle), addresses.slice(middle)];
|
|
32
|
+
const data = (await Promise.all((tokens ? parts.filter(part => part.length) : parts)
|
|
33
|
+
.map(part => contract.read.getTokenBalances([market.providerAddress, address, part], setViemBlockNumber(block))))).flat();
|
|
34
|
+
data.forEach((token, i) => {
|
|
35
|
+
// The views leave token.token unset; input order identifies the reserve.
|
|
36
|
+
const key = addressMapping ? wethToEthByAddress(reserves[i].tokenAddress, network).toLowerCase() : wethToEth(reserves[i].symbol);
|
|
37
|
+
balances.collateral![key] = token.balance.toString();
|
|
38
|
+
balances.debt![key] = new Dec(token.borrowsStable.toString()).add(token.borrowsVariable.toString()).toString();
|
|
39
|
+
});
|
|
40
|
+
return balances;
|
|
41
|
+
}
|
|
@@ -198,13 +198,17 @@ export const isLeveragedPosAaveV4 = (usedAssets: AaveV4UsedReserveAssets, dustLi
|
|
|
198
198
|
let supplyUnstable = 0;
|
|
199
199
|
let longAsset = '';
|
|
200
200
|
let shortAsset = '';
|
|
201
|
+
let stableCollAsset = '';
|
|
201
202
|
Object.values(usedAssets).forEach(({
|
|
202
203
|
symbol, suppliedUsd, borrowedUsd, collateral, reserveId,
|
|
203
204
|
}) => {
|
|
204
205
|
const spokeAsset = `${symbol}-${reserveId}`;
|
|
205
206
|
const isSupplied = (+suppliedUsd) > dustLimit; // ignore dust like <limit leftover supply
|
|
206
207
|
const isBorrowed = (+borrowedUsd) > dustLimit; // ignore dust like <limit leftover supply
|
|
207
|
-
if (isSupplied && STABLE_ASSETS.includes(symbol) && collateral)
|
|
208
|
+
if (isSupplied && STABLE_ASSETS.includes(symbol) && collateral) {
|
|
209
|
+
supplyStable += 1;
|
|
210
|
+
stableCollAsset = spokeAsset;
|
|
211
|
+
}
|
|
208
212
|
if (isBorrowed && STABLE_ASSETS.includes(symbol)) borrowStable += 1;
|
|
209
213
|
if (isBorrowed && !STABLE_ASSETS.includes(symbol)) {
|
|
210
214
|
borrowUnstable += 1;
|
|
@@ -218,6 +222,7 @@ export const isLeveragedPosAaveV4 = (usedAssets: AaveV4UsedReserveAssets, dustLi
|
|
|
218
222
|
const isLong = borrowStable > 0 && borrowUnstable === 0 && supplyUnstable === 1 && supplyStable === 0;
|
|
219
223
|
const isShort = supplyStable > 0 && supplyUnstable === 0 && borrowUnstable === 1 && borrowStable === 0;
|
|
220
224
|
const isVolatilePair = supplyUnstable === 1 && borrowUnstable === 1 && supplyStable === 0 && borrowStable === 0;
|
|
225
|
+
const isStablePair = supplyStable === 1 && borrowStable === 1 && supplyUnstable === 0 && borrowUnstable === 0;
|
|
221
226
|
if (isLong) {
|
|
222
227
|
return {
|
|
223
228
|
leveragedType: LeverageType.Long,
|
|
@@ -236,6 +241,12 @@ export const isLeveragedPosAaveV4 = (usedAssets: AaveV4UsedReserveAssets, dustLi
|
|
|
236
241
|
leveragedAsset: longAsset,
|
|
237
242
|
};
|
|
238
243
|
}
|
|
244
|
+
if (isStablePair) {
|
|
245
|
+
return {
|
|
246
|
+
leveragedType: LeverageType.StablePair,
|
|
247
|
+
leveragedAsset: stableCollAsset,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
239
250
|
return {
|
|
240
251
|
leveragedType: LeverageType.None,
|
|
241
252
|
leveragedAsset: '',
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import Dec from 'decimal.js';
|
|
2
|
+
import { getAssetInfoByAddress } from '@defisaver/tokens';
|
|
3
|
+
import { FluidUserPositionStructOutputStruct, FluidVaultDataStructOutputStruct } from '../types';
|
|
4
|
+
import { NetworkNumber, PositionBalances } from '../types/common';
|
|
5
|
+
|
|
6
|
+
/** Convert raw tokens, or raw 18-decimal shares with a human-readable token/share ratio. */
|
|
7
|
+
export const fluidTokenAmount = (amount: bigint, decimals: number, perShare?: string): string => (
|
|
8
|
+
new Dec(amount.toString()).div(new Dec(10).pow(perShare === undefined ? decimals : 18)).mul(perShare ?? 1).toString()
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
/** The same token/share conversion used by the full Fluid user parsers, without prices or yield. */
|
|
12
|
+
export function parseFluidBalances(position: FluidUserPositionStructOutputStruct, vault: FluidVaultDataStructOutputStruct, network: NetworkNumber): PositionBalances {
|
|
13
|
+
const type = Number(vault.vaultType);
|
|
14
|
+
if (![10000, 20000, 30000, 40000].includes(type)) throw new Error('Unsupported Fluid vault');
|
|
15
|
+
const side = (amount: bigint, tokens: string[], ratios: bigint[] | undefined) => {
|
|
16
|
+
const balances: Record<string, string> = {};
|
|
17
|
+
tokens.forEach((address, i) => {
|
|
18
|
+
const token = getAssetInfoByAddress(address, network);
|
|
19
|
+
if (!Number.isFinite(token.decimals) || !token.symbol) throw new Error('Fluid token metadata unavailable');
|
|
20
|
+
const perShare = ratios ? fluidTokenAmount(ratios[i], token.decimals) : undefined;
|
|
21
|
+
const value = fluidTokenAmount(amount, token.decimals, perShare);
|
|
22
|
+
balances[token.symbol] = new Dec(balances[token.symbol] || 0).add(value).toString();
|
|
23
|
+
});
|
|
24
|
+
return balances;
|
|
25
|
+
};
|
|
26
|
+
const smartSupply = type === 20000 || type === 40000;
|
|
27
|
+
const smartDebt = type === 30000 || type === 40000;
|
|
28
|
+
return {
|
|
29
|
+
collateral: side(position.supply, smartSupply ? [vault.supplyToken0, vault.supplyToken1] : [vault.supplyToken0],
|
|
30
|
+
smartSupply ? [vault.dexSupplyData.token0PerSupplyShare, vault.dexSupplyData.token1PerSupplyShare] : undefined),
|
|
31
|
+
debt: side(position.borrow, smartDebt ? [vault.borrowToken0, vault.borrowToken1] : [vault.borrowToken0],
|
|
32
|
+
smartDebt ? [vault.dexBorrowData.token0PerBorrowShare, vault.dexBorrowData.token1PerBorrowShare] : undefined),
|
|
33
|
+
};
|
|
34
|
+
}
|
package/src/liquityV2/index.ts
CHANGED
|
@@ -152,7 +152,7 @@ const getUserTroves = async (
|
|
|
152
152
|
return getUserTroves(provider, network, isLegacy, account, marketAddress, newStartIndex, newStartIndex + 100, existingTroves);
|
|
153
153
|
};
|
|
154
154
|
|
|
155
|
-
const nftContractCreationBlockMapping = {
|
|
155
|
+
export const nftContractCreationBlockMapping = {
|
|
156
156
|
[LiquityV2Versions.LiquityV2Eth]: 22516079,
|
|
157
157
|
[LiquityV2Versions.LiquityV2WstEth]: 22516099,
|
|
158
158
|
[LiquityV2Versions.LiquityV2REth]: 22516118,
|
package/src/llamaLend/index.ts
CHANGED
|
@@ -168,7 +168,7 @@ const getStatusForUser = (bandRange: string[], activeBand: string, debtSupplied:
|
|
|
168
168
|
return LlamaLendStatus.Nonexistant;
|
|
169
169
|
};
|
|
170
170
|
|
|
171
|
-
export const _getLlamaLendAccountBalances = async (provider: Client, network: NetworkNumber, block: Blockish, addressMapping: boolean, address: EthAddress, controllerAddress: EthAddress): Promise<PositionBalances> => {
|
|
171
|
+
export const _getLlamaLendAccountBalances = async (provider: Client, network: NetworkNumber, block: Blockish, addressMapping: boolean, address: EthAddress, controllerAddress: EthAddress, includeDeposited = false): Promise<PositionBalances> => {
|
|
172
172
|
let balances: PositionBalances = {
|
|
173
173
|
collateral: {},
|
|
174
174
|
debt: {},
|
|
@@ -192,6 +192,11 @@ export const _getLlamaLendAccountBalances = async (provider: Client, network: Ne
|
|
|
192
192
|
},
|
|
193
193
|
};
|
|
194
194
|
|
|
195
|
+
if (includeDeposited) {
|
|
196
|
+
balances.deposited = {
|
|
197
|
+
[addressMapping ? getAssetInfo(wethToEth(selectedMarket.baseAsset), network).address.toLowerCase() : wethToEth(selectedMarket.baseAsset)]: data.debtTokenCollateralAmount.toString(),
|
|
198
|
+
};
|
|
199
|
+
}
|
|
195
200
|
return balances;
|
|
196
201
|
};
|
|
197
202
|
|
|
@@ -712,21 +712,6 @@ export const MORPHO_BLUE_SWBTC_WBTC_945 = (networkId: NetworkNumber = NetworkNum
|
|
|
712
712
|
marketId: '0x514efda728a646dcafe4fdc9afe4ea214709e110ac1b2b78185ae00c1782cc82',
|
|
713
713
|
protocolName: 'morpho-blue',
|
|
714
714
|
});
|
|
715
|
-
export const MORPHO_BLUE_OSETH_ETH_860 = (networkId: NetworkNumber = NetworkNumber.Eth): MorphoBlueMarketData => ({
|
|
716
|
-
chainIds: [NetworkNumber.Eth],
|
|
717
|
-
label: 'Morpho Blue',
|
|
718
|
-
shortLabel: 'osETH/ETH',
|
|
719
|
-
value: MorphoBlueVersions.MorphoBlueOsEthEth_860,
|
|
720
|
-
url: 'osethweth-d5211d0e',
|
|
721
|
-
loanToken: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
|
|
722
|
-
collateralToken: '0xf1C9acDc66974dFB6dEcB12aA385b9cD01190E38',
|
|
723
|
-
oracle: '0x224F2F1333b45E34fFCfC3bD01cE43C73A914498',
|
|
724
|
-
oracleType: MorphoBlueOracleType.MARKET_RATE,
|
|
725
|
-
irm: '0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC',
|
|
726
|
-
lltv: 0.86,
|
|
727
|
-
marketId: '0xd5211d0e3f4a30d5c98653d988585792bb7812221f04801be73a44ceecb11e89',
|
|
728
|
-
protocolName: 'morpho-blue',
|
|
729
|
-
});
|
|
730
715
|
export const MORPHO_BLUE_WOETH_ETH_860 = (networkId: NetworkNumber = NetworkNumber.Eth): MorphoBlueMarketData => ({
|
|
731
716
|
chainIds: [NetworkNumber.Eth],
|
|
732
717
|
label: 'Morpho Blue',
|
|
@@ -1878,7 +1863,6 @@ export const MorphoBlueMarkets = (networkId: NetworkNumber) => ({
|
|
|
1878
1863
|
[MorphoBlueVersions.MorphoBlueRsEthEth_945]: MORPHO_BLUE_RSETH_ETH_945(networkId),
|
|
1879
1864
|
[MorphoBlueVersions.MorphoBlueRswEthEth_945]: MORPHO_BLUE_RSWETH_ETH_945(networkId),
|
|
1880
1865
|
[MorphoBlueVersions.MorphoBlueWeEthEth_860]: MORPHO_BLUE_WEETH_ETH_860(networkId),
|
|
1881
|
-
[MorphoBlueVersions.MorphoBlueOsEthEth_860]: MORPHO_BLUE_OSETH_ETH_860(networkId),
|
|
1882
1866
|
[MorphoBlueVersions.MorphoBlueWoEthEth_860]: MORPHO_BLUE_WOETH_ETH_860(networkId),
|
|
1883
1867
|
[MorphoBlueVersions.MorphoBluePTweETHUSDA_860]: MORPHO_BLUE_PTWEETH_USDA_860(networkId),
|
|
1884
1868
|
[MorphoBlueVersions.MorphoBlueSwBTCWBTC_945]: MORPHO_BLUE_SWBTC_WBTC_945(networkId),
|
|
@@ -13,7 +13,7 @@ export const calcShortLiqPrice = (assetPrice: string, borrowedUsd: string, borro
|
|
|
13
13
|
|
|
14
14
|
export const calcLeverageLiqPrice = (leverageType: LeverageType, assetPrice: string, borrowedUsd: string, borrowLimitUsd: string) => {
|
|
15
15
|
if (leverageType === LeverageType.Short || leverageType === LeverageType.VolatilePairReverse) return calcShortLiqPrice(assetPrice, borrowedUsd, borrowLimitUsd);
|
|
16
|
-
if (leverageType === LeverageType.Long || leverageType === LeverageType.VolatilePair) return calcLongLiqPrice(assetPrice, borrowedUsd, borrowLimitUsd);
|
|
16
|
+
if (leverageType === LeverageType.Long || leverageType === LeverageType.VolatilePair || leverageType === LeverageType.StablePair) return calcLongLiqPrice(assetPrice, borrowedUsd, borrowLimitUsd);
|
|
17
17
|
console.error('invalid leverageType', leverageType);
|
|
18
18
|
return '0';
|
|
19
19
|
};
|
|
@@ -37,12 +37,16 @@ export const isLeveragedPos = (usedAssets: MMUsedAssets, dustLimit = 5) => {
|
|
|
37
37
|
let supplyUnstable = 0;
|
|
38
38
|
let longAsset = '';
|
|
39
39
|
let shortAsset = '';
|
|
40
|
+
let stableCollAsset = '';
|
|
40
41
|
Object.values(usedAssets).forEach(({
|
|
41
42
|
symbol, suppliedUsd, borrowedUsd, collateral,
|
|
42
43
|
}) => {
|
|
43
44
|
const isSupplied = (+suppliedUsd) > dustLimit; // ignore dust like <limit leftover supply
|
|
44
45
|
const isBorrowed = (+borrowedUsd) > dustLimit; // ignore dust like <limit leftover supply
|
|
45
|
-
if (isSupplied && STABLE_ASSETS.includes(symbol) && collateral)
|
|
46
|
+
if (isSupplied && STABLE_ASSETS.includes(symbol) && collateral) {
|
|
47
|
+
supplyStable += 1;
|
|
48
|
+
stableCollAsset = symbol;
|
|
49
|
+
}
|
|
46
50
|
if (isBorrowed && STABLE_ASSETS.includes(symbol)) borrowStable += 1;
|
|
47
51
|
if (isBorrowed && !STABLE_ASSETS.includes(symbol)) {
|
|
48
52
|
borrowUnstable += 1;
|
|
@@ -56,6 +60,7 @@ export const isLeveragedPos = (usedAssets: MMUsedAssets, dustLimit = 5) => {
|
|
|
56
60
|
const isLong = borrowStable > 0 && borrowUnstable === 0 && supplyUnstable === 1 && supplyStable === 0;
|
|
57
61
|
const isShort = supplyStable > 0 && supplyUnstable === 0 && borrowUnstable === 1 && borrowStable === 0;
|
|
58
62
|
const isVolatilePair = supplyUnstable === 1 && borrowUnstable === 1 && supplyStable === 0 && borrowStable === 0;
|
|
63
|
+
const isStablePair = supplyStable === 1 && borrowStable === 1 && supplyUnstable === 0 && borrowUnstable === 0;
|
|
59
64
|
if (isLong) {
|
|
60
65
|
return {
|
|
61
66
|
leveragedType: LeverageType.Long,
|
|
@@ -74,6 +79,12 @@ export const isLeveragedPos = (usedAssets: MMUsedAssets, dustLimit = 5) => {
|
|
|
74
79
|
leveragedAsset: longAsset,
|
|
75
80
|
};
|
|
76
81
|
}
|
|
82
|
+
if (isStablePair) {
|
|
83
|
+
return {
|
|
84
|
+
leveragedType: LeverageType.StablePair,
|
|
85
|
+
leveragedAsset: stableCollAsset,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
77
88
|
return {
|
|
78
89
|
leveragedType: LeverageType.None,
|
|
79
90
|
leveragedAsset: '',
|
|
@@ -222,7 +222,7 @@ export async function getMorphoMidnightAccountData(provider: EthereumProvider, n
|
|
|
222
222
|
return _getMorphoMidnightAccountData(getViemProvider(provider, network), network, account, selectedMarket, marketInfo);
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
-
export const _getMorphoMidnightAccountBalances = async (provider: Client, network: NetworkNumber, block: Blockish, addressMapping: boolean, address: EthAddress, selectedMarket: MorphoMidnightMarketData): Promise<PositionBalances> => {
|
|
225
|
+
export const _getMorphoMidnightAccountBalances = async (provider: Client, network: NetworkNumber, block: Blockish, addressMapping: boolean, address: EthAddress, selectedMarket: MorphoMidnightMarketData, includeCredit = false): Promise<PositionBalances> => {
|
|
226
226
|
const balances: PositionBalances = { collateral: {}, debt: {} };
|
|
227
227
|
if (!address) return balances;
|
|
228
228
|
|
|
@@ -244,6 +244,11 @@ export const _getMorphoMidnightAccountBalances = async (provider: Client, networ
|
|
|
244
244
|
});
|
|
245
245
|
balances.collateral = collateral;
|
|
246
246
|
|
|
247
|
+
if (includeCredit) {
|
|
248
|
+
balances.deposited = {
|
|
249
|
+
[addressMapping ? loanTokenInfo.address.toLowerCase() : wethToEth(loanTokenInfo.symbol)]: assetAmountInEth(positionInfo.credit.toString(), wethToEth(loanTokenInfo.symbol)),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
247
252
|
return balances;
|
|
248
253
|
};
|
|
249
254
|
|