@defisaver/positions-sdk 2.1.168-stable-pair-dev → 2.1.169-portfolio-api-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/aaveV3/index.d.ts +2 -12
- package/cjs/aaveV3/sgho.d.ts +2 -16
- package/cjs/aaveV4/lend.d.ts +2 -43
- package/cjs/claiming/aaveV3.d.ts +2 -2
- package/cjs/claiming/ethena.d.ts +2 -1
- package/cjs/claiming/king.d.ts +2 -1
- package/cjs/claiming/spark.d.ts +2 -2
- package/cjs/fluid/index.d.ts +5 -49
- package/cjs/helpers/aaveV4Helpers/index.js +1 -11
- package/cjs/liquity/index.d.ts +2 -12
- package/cjs/liquityV2/index.d.ts +8 -23
- package/cjs/liquityV2/index.js +37 -19
- package/cjs/moneymarket/moneymarketCommonService.js +2 -12
- package/cjs/portfolio/index.d.ts +16 -8
- package/cjs/portfolio/index.js +458 -520
- package/cjs/portfolio/lendingProtocols.d.ts +184 -0
- package/cjs/portfolio/lendingProtocols.js +196 -0
- package/cjs/savings/index.d.ts +8 -2
- package/cjs/savings/index.js +33 -4
- package/cjs/types/aave.d.ts +98 -2
- package/cjs/types/aaveV4.d.ts +44 -0
- package/cjs/types/common.d.ts +0 -1
- package/cjs/types/common.js +0 -1
- package/cjs/types/compound.d.ts +26 -2
- package/cjs/types/curveUsd.d.ts +9 -1
- package/cjs/types/fluid.d.ts +13 -0
- package/cjs/types/index.d.ts +1 -0
- package/cjs/types/index.js +1 -0
- package/cjs/types/liquity.d.ts +12 -0
- package/cjs/types/liquityV2.d.ts +24 -0
- package/cjs/types/llamaLend.d.ts +12 -1
- package/cjs/types/morphoBlue.d.ts +2 -0
- package/cjs/types/portfolio.d.ts +125 -5
- package/cjs/types/savings/index.d.ts +9 -1
- package/cjs/types/spark.d.ts +21 -1
- package/cjs/umbrella/index.d.ts +2 -3
- package/esm/aaveV3/index.d.ts +2 -12
- package/esm/aaveV3/sgho.d.ts +2 -16
- package/esm/aaveV4/lend.d.ts +2 -43
- package/esm/claiming/aaveV3.d.ts +2 -2
- package/esm/claiming/aaveV3.js +1 -1
- package/esm/claiming/ethena.d.ts +2 -1
- package/esm/claiming/king.d.ts +2 -1
- package/esm/claiming/spark.d.ts +2 -2
- package/esm/claiming/spark.js +1 -1
- package/esm/fluid/index.d.ts +5 -49
- package/esm/helpers/aaveV4Helpers/index.js +1 -11
- package/esm/liquity/index.d.ts +2 -12
- package/esm/liquityV2/index.d.ts +8 -23
- package/esm/liquityV2/index.js +35 -18
- package/esm/moneymarket/moneymarketCommonService.js +2 -12
- package/esm/portfolio/index.d.ts +16 -8
- package/esm/portfolio/index.js +458 -522
- package/esm/portfolio/lendingProtocols.d.ts +184 -0
- package/esm/portfolio/lendingProtocols.js +189 -0
- package/esm/savings/index.d.ts +8 -2
- package/esm/savings/index.js +31 -3
- package/esm/types/aave.d.ts +98 -2
- package/esm/types/aaveV4.d.ts +44 -0
- package/esm/types/common.d.ts +0 -1
- package/esm/types/common.js +0 -1
- package/esm/types/compound.d.ts +26 -2
- package/esm/types/curveUsd.d.ts +9 -1
- package/esm/types/fluid.d.ts +13 -0
- package/esm/types/index.d.ts +1 -0
- package/esm/types/index.js +1 -0
- package/esm/types/liquity.d.ts +12 -0
- package/esm/types/liquityV2.d.ts +24 -0
- package/esm/types/llamaLend.d.ts +12 -1
- package/esm/types/morphoBlue.d.ts +2 -0
- package/esm/types/portfolio.d.ts +125 -5
- package/esm/types/savings/index.d.ts +9 -1
- package/esm/types/spark.d.ts +21 -1
- package/esm/umbrella/index.d.ts +2 -3
- package/package.json +1 -1
- package/src/aaveV3/index.ts +2 -1
- package/src/aaveV3/sgho.ts +2 -17
- package/src/aaveV4/lend.ts +2 -48
- package/src/claiming/aaveV3.ts +4 -2
- package/src/claiming/ethena.ts +5 -5
- package/src/claiming/king.ts +3 -3
- package/src/claiming/spark.ts +6 -4
- package/src/fluid/index.ts +4 -3
- package/src/helpers/aaveV4Helpers/index.ts +1 -12
- package/src/liquity/index.ts +2 -2
- package/src/liquityV2/index.ts +48 -22
- package/src/moneymarket/moneymarketCommonService.ts +2 -13
- package/src/portfolio/index.ts +306 -331
- package/src/portfolio/lendingProtocols.ts +281 -0
- package/src/savings/index.ts +41 -4
- package/src/types/aave.ts +104 -1
- package/src/types/aaveV4.ts +49 -0
- package/src/types/common.ts +0 -1
- package/src/types/compound.ts +38 -2
- package/src/types/curveUsd.ts +17 -1
- package/src/types/fluid.ts +14 -0
- package/src/types/index.ts +1 -0
- package/src/types/liquity.ts +13 -1
- package/src/types/liquityV2.ts +26 -1
- package/src/types/llamaLend.ts +19 -1
- package/src/types/morphoBlue.ts +3 -0
- package/src/types/portfolio.ts +151 -5
- package/src/types/savings/index.ts +12 -1
- package/src/types/spark.ts +25 -1
- package/src/umbrella/index.ts +2 -1
package/src/claiming/ethena.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { getAssetInfo } from '@defisaver/tokens';
|
|
|
2
2
|
import Dec from 'decimal.js';
|
|
3
3
|
import { getAddress } from 'viem';
|
|
4
4
|
import { EthAddress } from '../types/common';
|
|
5
|
-
import { ClaimType } from '../types/claiming';
|
|
5
|
+
import { ClaimType, EthenaAirdropClaimableToken } from '../types/claiming';
|
|
6
6
|
import { getEthAmountForDecimals } from '../services/utils';
|
|
7
7
|
|
|
8
8
|
export const fetchEthenaAirdropReward = async (address: EthAddress) => {
|
|
@@ -23,11 +23,11 @@ export const fetchEthenaAirdropReward = async (address: EthAddress) => {
|
|
|
23
23
|
}
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
-
export const fetchEthenaAirdropRewards = async (walletAddresses: EthAddress[]): Promise<Record<string,
|
|
26
|
+
export const fetchEthenaAirdropRewards = async (walletAddresses: EthAddress[]): Promise<Record<string, EthenaAirdropClaimableToken[]>> => {
|
|
27
27
|
const apiDataPromises = walletAddresses.map(address => fetchEthenaAirdropReward(address));
|
|
28
28
|
const apiDataArray = await Promise.all(apiDataPromises);
|
|
29
29
|
|
|
30
|
-
const results: Record<string,
|
|
30
|
+
const results: Record<string, EthenaAirdropClaimableToken[]> = {};
|
|
31
31
|
for (let i = 0; i < walletAddresses.length; i++) {
|
|
32
32
|
const walletAddress = walletAddresses[i];
|
|
33
33
|
const data = apiDataArray[i];
|
|
@@ -36,7 +36,7 @@ export const fetchEthenaAirdropRewards = async (walletAddresses: EthAddress[]):
|
|
|
36
36
|
continue;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
const processedRewards = [];
|
|
39
|
+
const processedRewards: EthenaAirdropClaimableToken[] = [];
|
|
40
40
|
const assetInfo = getAssetInfo('sENA');
|
|
41
41
|
|
|
42
42
|
const amount = getEthAmountForDecimals(data.events[0].awardAmount, assetInfo.decimals);
|
|
@@ -47,7 +47,7 @@ export const fetchEthenaAirdropRewards = async (walletAddresses: EthAddress[]):
|
|
|
47
47
|
underlyingSymbol: assetInfo.symbol,
|
|
48
48
|
amount,
|
|
49
49
|
claimType: ClaimType.ETHENA_AIRDROP,
|
|
50
|
-
tokenAddress: assetInfo.address,
|
|
50
|
+
tokenAddress: assetInfo.address as EthAddress,
|
|
51
51
|
walletAddress,
|
|
52
52
|
label: 'Ethena Airdrop',
|
|
53
53
|
});
|
package/src/claiming/king.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { assetAmountInEth } from '@defisaver/tokens';
|
|
|
3
3
|
import { Client } from 'viem';
|
|
4
4
|
import { UUPSViem } from '../contracts';
|
|
5
5
|
import { EthAddress, HexString, NetworkNumber } from '../types/common';
|
|
6
|
-
import { ClaimType } from '../types/claiming';
|
|
6
|
+
import { ClaimType, KingRewardsClaimableToken } from '../types/claiming';
|
|
7
7
|
|
|
8
8
|
export const fetchKingRewards = async (walletAddress: EthAddress) => {
|
|
9
9
|
try {
|
|
@@ -19,7 +19,7 @@ export const fetchKingRewards = async (walletAddress: EthAddress) => {
|
|
|
19
19
|
}
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
export const getKingRewards = async (provider: Client, network: NetworkNumber, walletAddresses: EthAddress[]) => {
|
|
22
|
+
export const getKingRewards = async (provider: Client, network: NetworkNumber, walletAddresses: EthAddress[]): Promise<Record<string, KingRewardsClaimableToken[]>> => {
|
|
23
23
|
// Fetch all API data in parallel (these are external API calls, can't be batched with multicall)
|
|
24
24
|
const apiDataPromises = walletAddresses.map(address => fetchKingRewards(address));
|
|
25
25
|
const apiDataArray = await Promise.all(apiDataPromises);
|
|
@@ -31,7 +31,7 @@ export const getKingRewards = async (provider: Client, network: NetworkNumber, w
|
|
|
31
31
|
const cumulativeResults = await Promise.all(cumulativePromises);
|
|
32
32
|
|
|
33
33
|
// Process results
|
|
34
|
-
const results: Record<string,
|
|
34
|
+
const results: Record<string, KingRewardsClaimableToken[]> = {};
|
|
35
35
|
|
|
36
36
|
for (let i = 0; i < walletAddresses.length; i++) {
|
|
37
37
|
const walletAddress = walletAddresses[i];
|
package/src/claiming/spark.ts
CHANGED
|
@@ -7,7 +7,9 @@ import {
|
|
|
7
7
|
SparkRewardsControllerViem,
|
|
8
8
|
} from '../contracts';
|
|
9
9
|
import { EthAddress, NetworkNumber } from '../types/common';
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
ClaimType, SparkAirdropClaimableToken, SparkAirdropType, SparkRewardsClaimableToken,
|
|
12
|
+
} from '../types/claiming';
|
|
11
13
|
import { compareAddresses, getEthAmountForDecimals } from '../services/utils';
|
|
12
14
|
|
|
13
15
|
const IGNITION_REWARDS = '0xCBA0C0a2a0B6Bb11233ec4EA85C5bFfea33e724d';
|
|
@@ -50,7 +52,7 @@ export const fetchSparkAirdropRewards = async (
|
|
|
50
52
|
provider: Client,
|
|
51
53
|
network: NetworkNumber,
|
|
52
54
|
walletAddresses: EthAddress[],
|
|
53
|
-
) => {
|
|
55
|
+
): Promise<Record<string, SparkAirdropClaimableToken[]>> => {
|
|
54
56
|
// Fetch all API data in parallel (these are external API calls, can't be batched with multicall)
|
|
55
57
|
const apiDataPromises = walletAddresses.map(address => fetchSpkAirdropRewards(address));
|
|
56
58
|
const apiDataArray = await Promise.all(apiDataPromises);
|
|
@@ -92,7 +94,7 @@ export const fetchSparkAirdropRewards = async (
|
|
|
92
94
|
const cumulativeClaimedAmounts = await getCumulativeClaimedSpkAirdrop(provider, network, contractCallsData);
|
|
93
95
|
|
|
94
96
|
// Process results
|
|
95
|
-
const results: Record<string,
|
|
97
|
+
const results: Record<string, SparkAirdropClaimableToken[]> = {};
|
|
96
98
|
let contractCallIndex = 0;
|
|
97
99
|
|
|
98
100
|
for (const { walletAddress, data } of allClaimData) {
|
|
@@ -101,7 +103,7 @@ export const fetchSparkAirdropRewards = async (
|
|
|
101
103
|
continue;
|
|
102
104
|
}
|
|
103
105
|
|
|
104
|
-
const processedRewards = [];
|
|
106
|
+
const processedRewards: SparkAirdropClaimableToken[] = [];
|
|
105
107
|
for (let i = 0; i < data.length; i++) {
|
|
106
108
|
const rewardInfo = data[i];
|
|
107
109
|
const assetInfo = getAssetInfoByAddress(rewardInfo.token_address);
|
package/src/fluid/index.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
FluidAggregatedVaultData,
|
|
12
12
|
FluidAssetData,
|
|
13
13
|
FluidAssetsData,
|
|
14
|
+
FluidEarnPositionData,
|
|
14
15
|
FluidFTokenDataStructOutput,
|
|
15
16
|
FluidMarketData,
|
|
16
17
|
FluidMarketInfo,
|
|
@@ -1598,7 +1599,7 @@ export const getFluidTokenData = async (
|
|
|
1598
1599
|
token: string,
|
|
1599
1600
|
) => _getFluidTokenData(getViemProvider(provider, network), network, token);
|
|
1600
1601
|
|
|
1601
|
-
const parseFDepositTokenData = (fTokenData: FluidFTokenDataStructOutput, userPosition: FluidUserEarnPositionStructOutput, apiData: any, fTokenAddress?: string) => {
|
|
1602
|
+
const parseFDepositTokenData = (fTokenData: FluidFTokenDataStructOutput, userPosition: FluidUserEarnPositionStructOutput, apiData: any, fTokenAddress?: string): FluidEarnPositionData => {
|
|
1602
1603
|
const decimals = fTokenData.decimals.toString();
|
|
1603
1604
|
const depositRate = new Dec(getEthAmountForDecimals(fTokenData.convertToShares.toString(), decimals)).toString();
|
|
1604
1605
|
const withdrawRate = new Dec(getEthAmountForDecimals(fTokenData.convertToAssets.toString(), decimals)).toString();
|
|
@@ -1646,7 +1647,7 @@ export const getFluidDepositData = async (
|
|
|
1646
1647
|
address: EthAddress,
|
|
1647
1648
|
) => _getFluidDepositData(getViemProvider(provider, network), network, token, address);
|
|
1648
1649
|
|
|
1649
|
-
export const _getAllUserEarnPositionsWithFTokens = async (provider: Client, network: NetworkNumber, user: EthAddress) => {
|
|
1650
|
+
export const _getAllUserEarnPositionsWithFTokens = async (provider: Client, network: NetworkNumber, user: EthAddress): Promise<FluidEarnPositionData[]> => {
|
|
1650
1651
|
const view = FluidViewContractViem(provider, network);
|
|
1651
1652
|
const [
|
|
1652
1653
|
[userPositions, fTokensData],
|
|
@@ -1665,7 +1666,7 @@ export const _getAllUserEarnPositionsWithFTokens = async (provider: Client, netw
|
|
|
1665
1666
|
rewardsData = await rewardsApiResponse.json();
|
|
1666
1667
|
}
|
|
1667
1668
|
|
|
1668
|
-
const parsedRes = fTokensData.reduce<
|
|
1669
|
+
const parsedRes = fTokensData.reduce<FluidEarnPositionData[]>((acc, fTokenData, i) => {
|
|
1669
1670
|
const userPosition = userPositions[i];
|
|
1670
1671
|
const deposited = userPosition?.underlyingAssets;
|
|
1671
1672
|
|
|
@@ -198,17 +198,13 @@ export const isLeveragedPosAaveV4 = (usedAssets: AaveV4UsedReserveAssets, dustLi
|
|
|
198
198
|
let supplyUnstable = 0;
|
|
199
199
|
let longAsset = '';
|
|
200
200
|
let shortAsset = '';
|
|
201
|
-
let stableCollAsset = '';
|
|
202
201
|
Object.values(usedAssets).forEach(({
|
|
203
202
|
symbol, suppliedUsd, borrowedUsd, collateral, reserveId,
|
|
204
203
|
}) => {
|
|
205
204
|
const spokeAsset = `${symbol}-${reserveId}`;
|
|
206
205
|
const isSupplied = (+suppliedUsd) > dustLimit; // ignore dust like <limit leftover supply
|
|
207
206
|
const isBorrowed = (+borrowedUsd) > dustLimit; // ignore dust like <limit leftover supply
|
|
208
|
-
if (isSupplied && STABLE_ASSETS.includes(symbol) && collateral)
|
|
209
|
-
supplyStable += 1;
|
|
210
|
-
stableCollAsset = spokeAsset;
|
|
211
|
-
}
|
|
207
|
+
if (isSupplied && STABLE_ASSETS.includes(symbol) && collateral) supplyStable += 1;
|
|
212
208
|
if (isBorrowed && STABLE_ASSETS.includes(symbol)) borrowStable += 1;
|
|
213
209
|
if (isBorrowed && !STABLE_ASSETS.includes(symbol)) {
|
|
214
210
|
borrowUnstable += 1;
|
|
@@ -222,7 +218,6 @@ export const isLeveragedPosAaveV4 = (usedAssets: AaveV4UsedReserveAssets, dustLi
|
|
|
222
218
|
const isLong = borrowStable > 0 && borrowUnstable === 0 && supplyUnstable === 1 && supplyStable === 0;
|
|
223
219
|
const isShort = supplyStable > 0 && supplyUnstable === 0 && borrowUnstable === 1 && borrowStable === 0;
|
|
224
220
|
const isVolatilePair = supplyUnstable === 1 && borrowUnstable === 1 && supplyStable === 0 && borrowStable === 0;
|
|
225
|
-
const isStablePair = supplyStable === 1 && borrowStable === 1 && supplyUnstable === 0 && borrowUnstable === 0;
|
|
226
221
|
if (isLong) {
|
|
227
222
|
return {
|
|
228
223
|
leveragedType: LeverageType.Long,
|
|
@@ -241,12 +236,6 @@ export const isLeveragedPosAaveV4 = (usedAssets: AaveV4UsedReserveAssets, dustLi
|
|
|
241
236
|
leveragedAsset: longAsset,
|
|
242
237
|
};
|
|
243
238
|
}
|
|
244
|
-
if (isStablePair) {
|
|
245
|
-
return {
|
|
246
|
-
leveragedType: LeverageType.StablePair,
|
|
247
|
-
leveragedAsset: stableCollAsset,
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
239
|
return {
|
|
251
240
|
leveragedType: LeverageType.None,
|
|
252
241
|
leveragedAsset: '',
|
package/src/liquity/index.ts
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
LiquityTroveManagerContractViem,
|
|
14
14
|
LiquityViewContractViem,
|
|
15
15
|
} from '../contracts';
|
|
16
|
-
import { LIQUITY_TROVE_STATUS_ENUM, LiquityTroveInfo } from '../types';
|
|
16
|
+
import { LIQUITY_TROVE_STATUS_ENUM, LiquityStakingData, LiquityTroveInfo } from '../types';
|
|
17
17
|
import { ZERO_ADDRESS } from '../constants';
|
|
18
18
|
import { getViemProvider, setViemBlockNumber } from '../services/viem';
|
|
19
19
|
import { getEthAmountForDecimals } from '../services/utils';
|
|
@@ -127,7 +127,7 @@ export const _getLiquityTroveInfo = async (provider: Client, network: NetworkNum
|
|
|
127
127
|
|
|
128
128
|
export const getLiquityTroveInfo = async (provider: EthereumProvider, network: NetworkNumber, address: EthAddress): Promise<LiquityTroveInfo> => _getLiquityTroveInfo(getViemProvider(provider, network, { batch: { multicall: true } }), network, address);
|
|
129
129
|
|
|
130
|
-
export const getLiquityStakingData = async (provider: Client, network: NetworkNumber, address: EthAddress) => {
|
|
130
|
+
export const getLiquityStakingData = async (provider: Client, network: NetworkNumber, address: EthAddress): Promise<LiquityStakingData> => {
|
|
131
131
|
const lqtyStakingView = LiquityLQTYStakingViem(provider, network);
|
|
132
132
|
const stabilityPoolView = LiquityStabilityPoolViem(provider, network);
|
|
133
133
|
const [
|
package/src/liquityV2/index.ts
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from '../types/common';
|
|
13
13
|
import {
|
|
14
14
|
LIQUITY_V2_TROVE_STATUS_ENUM,
|
|
15
|
-
LiquityV2AssetsData, LiquityV2MarketData, LiquityV2MarketInfo, LiquityV2TroveData, LiquityV2UsedAssets,
|
|
15
|
+
LiquityV2AssetsData, LiquityV2MarketData, LiquityV2MarketInfo, LiquityV2SBoldYBoldData, LiquityV2StakingData, LiquityV2TroveData, LiquityV2UsedAssets,
|
|
16
16
|
LiquityV2Versions,
|
|
17
17
|
} from '../types';
|
|
18
18
|
import { getStakingApy, STAKING_ASSETS } from '../staking';
|
|
@@ -162,31 +162,35 @@ export const nftContractCreationBlockMapping = {
|
|
|
162
162
|
[LiquityV2Versions.LiquityV2REthLegacy]: 21686257,
|
|
163
163
|
};
|
|
164
164
|
|
|
165
|
-
|
|
165
|
+
interface TroveTransfer {
|
|
166
|
+
from?: EthAddress,
|
|
167
|
+
to?: EthAddress,
|
|
168
|
+
tokenId: string,
|
|
169
|
+
blockNumber: number,
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** Every Transfer of a market's trove NFT since the contract was created (or, on a fork, in the last 1000 blocks). */
|
|
173
|
+
const getTroveTransfers = async (provider: PublicClient, network: NetworkNumber, troveNFTAddress: EthAddress, limitBlocksForEventFetching: boolean, market: LiquityV2Versions): Promise<TroveTransfer[]> => {
|
|
166
174
|
const nftContract = createViemContractFromConfigFunc('LiquityV2TroveNFT', troveNFTAddress)(provider, network);
|
|
167
175
|
const nftContractCreationBlock = nftContractCreationBlockMapping[market];
|
|
168
176
|
const currentBlock = +(await provider.getBlockNumber()).toString();
|
|
169
177
|
const _events = await nftContract.getEvents.Transfer({}, { fromBlock: limitBlocksForEventFetching ? BigInt(currentBlock - 1000) : BigInt(nftContractCreationBlock) });
|
|
170
|
-
|
|
178
|
+
return _events.map((event) => ({
|
|
171
179
|
from: event.args.from, to: event.args.to, tokenId: event.args.tokenId!.toString(), blockNumber: +(event.blockNumber.toString()),
|
|
172
180
|
}));
|
|
173
|
-
const userTransferredTroves = events.filter((event) => compareAddresses(event.to, account));
|
|
174
|
-
|
|
175
|
-
// check if the last know transfer address is the user
|
|
176
|
-
userTransferredTroves.forEach((event, index) => {
|
|
177
|
-
const otherTransfers = events.filter((e) => event.blockNumber < e.blockNumber && e.tokenId === event.tokenId);
|
|
178
|
-
// @ts-ignore
|
|
179
|
-
userTransferredTroves[index].invalid = !!otherTransfers.length;
|
|
180
|
-
});
|
|
181
|
-
// @ts-ignore
|
|
182
|
-
return userTransferredTroves.filter((event) => !event.invalid).map((event) => ({ troveId: event.tokenId }));
|
|
183
181
|
};
|
|
184
182
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
183
|
+
/** The troves transferred to an account that it still holds: no later transfer of the same trove. */
|
|
184
|
+
const getAccountTransferredTroves = (events: TroveTransfer[], account: EthAddress): { troveId: string }[] => events
|
|
185
|
+
.filter((event) => compareAddresses(event.to, account))
|
|
186
|
+
.filter((event) => !events.some((e) => event.blockNumber < e.blockNumber && e.tokenId === event.tokenId))
|
|
187
|
+
.map((event) => ({ troveId: event.tokenId }));
|
|
188
|
+
|
|
189
|
+
const getTransferredTroves = async (provider: PublicClient, network: NetworkNumber, troveNFTAddress: EthAddress, limitBlocksForEventFetching: boolean, market: LiquityV2Versions, account: EthAddress): Promise<{ troveId: string }[]> => (
|
|
190
|
+
getAccountTransferredTroves(await getTroveTransfers(provider, network, troveNFTAddress, limitBlocksForEventFetching, market), account));
|
|
191
|
+
|
|
192
|
+
/** The troves an account opened and still owns, then the ones transferred to it, each once. */
|
|
193
|
+
const mergeTroveIds = (userTroves: { troveId: string }[], userTransferredTroves: { troveId: string }[]): { troveId: string }[] => {
|
|
190
194
|
const troves = [...userTroves.map(({ troveId }) => ({ troveId })), ...userTransferredTroves];
|
|
191
195
|
const filteredTroves = troves.filter((value, index, self) => index === self.findIndex((t) => (
|
|
192
196
|
t.troveId === value.troveId
|
|
@@ -195,8 +199,30 @@ export const _getLiquityV2UserTroveIds = async (provider: PublicClient, network:
|
|
|
195
199
|
const troveIds = filteredTroves.map((trove) => trove.troveId);
|
|
196
200
|
const troveIdsSet = new Set(troveIds);
|
|
197
201
|
const troveIdsArray = Array.from(troveIdsSet);
|
|
198
|
-
|
|
199
|
-
|
|
202
|
+
return troveIdsArray.map((troveId) => troves.find((trove) => trove.troveId === troveId)) as { troveId: string }[];
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* The trove ids of several accounts in one market: the market's NFT transfers are read once for all of them, rather
|
|
207
|
+
* than once per account as _getLiquityV2UserTroveIds does.
|
|
208
|
+
*/
|
|
209
|
+
export const _getLiquityV2UsersTroveIds = async (provider: PublicClient, network: NetworkNumber, selectedMarket: LiquityV2MarketInfo, troveNFTAddress: EthAddress, limitBlocksForEventFetching: boolean, accounts: EthAddress[]): Promise<Record<EthAddress, string[]>> => {
|
|
210
|
+
const [userTroves, events] = await Promise.all([
|
|
211
|
+
Promise.all(accounts.map((account) => getUserTroves(provider, network, selectedMarket.isLegacy, account, selectedMarket.marketAddress))),
|
|
212
|
+
getTroveTransfers(provider, network, troveNFTAddress, limitBlocksForEventFetching, selectedMarket.value),
|
|
213
|
+
]);
|
|
214
|
+
return Object.fromEntries(accounts.map((account, i) => [
|
|
215
|
+
account,
|
|
216
|
+
mergeTroveIds(userTroves[i].troves, getAccountTransferredTroves(events, account)).map(({ troveId }) => troveId),
|
|
217
|
+
]));
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
export const _getLiquityV2UserTroveIds = async (provider: PublicClient, network: NetworkNumber, selectedMarket: LiquityV2MarketInfo, troveNFTAddress: EthAddress, limitBlocksForEventFetching: boolean, account: EthAddress): Promise<{ troves: { troveId: string }[], nextFreeTroveIndex: string }> => {
|
|
221
|
+
const [{ troves: userTroves, nextFreeTroveIndex }, userTransferredTroves] = await Promise.all([
|
|
222
|
+
getUserTroves(provider, network, selectedMarket.isLegacy, account, selectedMarket.marketAddress),
|
|
223
|
+
getTransferredTroves(provider, network, troveNFTAddress, limitBlocksForEventFetching, selectedMarket.value, account),
|
|
224
|
+
]);
|
|
225
|
+
return { troves: mergeTroveIds(userTroves, userTransferredTroves), nextFreeTroveIndex };
|
|
200
226
|
};
|
|
201
227
|
|
|
202
228
|
export const getLiquityV2UserTroveIds = async (
|
|
@@ -579,7 +605,7 @@ const calculateSPApy = (
|
|
|
579
605
|
return apy;
|
|
580
606
|
};
|
|
581
607
|
|
|
582
|
-
export const getLiquityV2Staking = async (provider: Client, network: NetworkNumber, market: LiquityV2Versions, user: EthAddress) => {
|
|
608
|
+
export const getLiquityV2Staking = async (provider: Client, network: NetworkNumber, market: LiquityV2Versions, user: EthAddress): Promise<LiquityV2StakingData> => {
|
|
583
609
|
const stabilityPoolView = createViemContractFromConfigFunc('LiquityV2StabilityPool', stabilityPoolAddrForMarket[market])(provider, network);
|
|
584
610
|
const activePoolView = createViemContractFromConfigFunc('LiquityV2ActivePool', activePoolAddrForMarket[market])(provider, network);
|
|
585
611
|
|
|
@@ -638,7 +664,7 @@ export const getLiquityV2Staking = async (provider: Client, network: NetworkNumb
|
|
|
638
664
|
};
|
|
639
665
|
};
|
|
640
666
|
|
|
641
|
-
export const getLiquitySAndYBold = async (provider: Client, network: NetworkNumber, markets: any, user: EthAddress) => {
|
|
667
|
+
export const getLiquitySAndYBold = async (provider: Client, network: NetworkNumber, markets: any, user: EthAddress): Promise<LiquityV2SBoldYBoldData> => {
|
|
642
668
|
const sBold = LiquityV2sBoldVaultViem(provider, network);
|
|
643
669
|
const yBold = createViemContractFromConfigFunc('Erc4626', '0x9F4330700a36B29952869fac9b33f45EEdd8A3d8')(provider, network);
|
|
644
670
|
const stYBold = createViemContractFromConfigFunc('Erc4626', '0x23346B04a7f55b8760E5860AA5A77383D63491cD')(provider, network);
|
|
@@ -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
|
|
16
|
+
if (leverageType === LeverageType.Long || leverageType === LeverageType.VolatilePair) return calcLongLiqPrice(assetPrice, borrowedUsd, borrowLimitUsd);
|
|
17
17
|
console.error('invalid leverageType', leverageType);
|
|
18
18
|
return '0';
|
|
19
19
|
};
|
|
@@ -37,16 +37,12 @@ export const isLeveragedPos = (usedAssets: MMUsedAssets, dustLimit = 5) => {
|
|
|
37
37
|
let supplyUnstable = 0;
|
|
38
38
|
let longAsset = '';
|
|
39
39
|
let shortAsset = '';
|
|
40
|
-
let stableCollAsset = '';
|
|
41
40
|
Object.values(usedAssets).forEach(({
|
|
42
41
|
symbol, suppliedUsd, borrowedUsd, collateral,
|
|
43
42
|
}) => {
|
|
44
43
|
const isSupplied = (+suppliedUsd) > dustLimit; // ignore dust like <limit leftover supply
|
|
45
44
|
const isBorrowed = (+borrowedUsd) > dustLimit; // ignore dust like <limit leftover supply
|
|
46
|
-
if (isSupplied && STABLE_ASSETS.includes(symbol) && collateral)
|
|
47
|
-
supplyStable += 1;
|
|
48
|
-
stableCollAsset = symbol;
|
|
49
|
-
}
|
|
45
|
+
if (isSupplied && STABLE_ASSETS.includes(symbol) && collateral) supplyStable += 1;
|
|
50
46
|
if (isBorrowed && STABLE_ASSETS.includes(symbol)) borrowStable += 1;
|
|
51
47
|
if (isBorrowed && !STABLE_ASSETS.includes(symbol)) {
|
|
52
48
|
borrowUnstable += 1;
|
|
@@ -60,7 +56,6 @@ export const isLeveragedPos = (usedAssets: MMUsedAssets, dustLimit = 5) => {
|
|
|
60
56
|
const isLong = borrowStable > 0 && borrowUnstable === 0 && supplyUnstable === 1 && supplyStable === 0;
|
|
61
57
|
const isShort = supplyStable > 0 && supplyUnstable === 0 && borrowUnstable === 1 && borrowStable === 0;
|
|
62
58
|
const isVolatilePair = supplyUnstable === 1 && borrowUnstable === 1 && supplyStable === 0 && borrowStable === 0;
|
|
63
|
-
const isStablePair = supplyStable === 1 && borrowStable === 1 && supplyUnstable === 0 && borrowUnstable === 0;
|
|
64
59
|
if (isLong) {
|
|
65
60
|
return {
|
|
66
61
|
leveragedType: LeverageType.Long,
|
|
@@ -79,12 +74,6 @@ export const isLeveragedPos = (usedAssets: MMUsedAssets, dustLimit = 5) => {
|
|
|
79
74
|
leveragedAsset: longAsset,
|
|
80
75
|
};
|
|
81
76
|
}
|
|
82
|
-
if (isStablePair) {
|
|
83
|
-
return {
|
|
84
|
-
leveragedType: LeverageType.StablePair,
|
|
85
|
-
leveragedAsset: stableCollAsset,
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
77
|
return {
|
|
89
78
|
leveragedType: LeverageType.None,
|
|
90
79
|
leveragedAsset: '',
|