@defisaver/positions-sdk 2.1.161-portfolio-api-1-dev → 2.1.161-portfolio-api-3-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 +2 -0
- package/cjs/aaveV3/index.d.ts +41 -12
- package/cjs/aaveV3/index.js +237 -2
- 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/curveUsd/index.d.ts +5 -2
- package/cjs/curveUsd/index.js +30 -15
- package/cjs/fluid/index.d.ts +10 -49
- package/cjs/fluid/index.js +36 -1
- package/cjs/helpers/aaveHelpers/index.d.ts +9 -1
- package/cjs/helpers/aaveHelpers/index.js +26 -6
- package/cjs/helpers/aaveV4Helpers/index.js +1 -0
- package/cjs/helpers/compoundHelpers/index.js +2 -0
- package/cjs/helpers/curveUsdHelpers/index.d.ts +3 -1
- package/cjs/helpers/curveUsdHelpers/index.js +15 -2
- package/cjs/helpers/fluidHelpers/index.js +1 -0
- package/cjs/helpers/liquityV2Helpers/index.js +1 -0
- package/cjs/helpers/llamaLendHelpers/index.js +1 -0
- package/cjs/helpers/makerHelpers/index.d.ts +1 -1
- package/cjs/helpers/makerHelpers/index.js +2 -2
- package/cjs/helpers/morphoBlueHelpers/index.js +2 -0
- package/cjs/helpers/morphoMidnightHelpers/index.js +2 -0
- package/cjs/helpers/sparkHelpers/index.js +1 -0
- package/cjs/liquity/index.d.ts +2 -12
- package/cjs/liquity/index.js +15 -2
- package/cjs/liquityV2/index.d.ts +8 -23
- package/cjs/liquityV2/index.js +37 -19
- package/cjs/maker/index.d.ts +7 -2
- package/cjs/maker/index.js +44 -12
- package/cjs/markets/index.d.ts +1 -0
- package/cjs/markets/index.js +3 -1
- package/cjs/markets/maker/index.d.ts +1 -0
- package/cjs/markets/maker/index.js +13 -0
- package/cjs/moneymarket/moneymarketCommonService.d.ts +9 -0
- package/cjs/moneymarket/moneymarketCommonService.js +13 -1
- package/cjs/portfolio/index.d.ts +17 -5
- package/cjs/portfolio/index.js +583 -381
- 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 +37 -5
- package/cjs/savings/morphoVaults/index.d.ts +1 -1
- package/cjs/savings/morphoVaults/index.js +56 -18
- package/cjs/savings/morphoVaults/options.d.ts +2 -0
- package/cjs/savings/morphoVaults/options.js +61 -1
- package/cjs/spark/index.js +1 -0
- package/cjs/staking/staking.d.ts +20 -0
- package/cjs/staking/staking.js +19 -1
- package/cjs/types/aave.d.ts +86 -0
- package/cjs/types/aaveV4.d.ts +45 -0
- package/cjs/types/compound.d.ts +2 -0
- package/cjs/types/curveUsd.d.ts +6 -0
- package/cjs/types/fluid.d.ts +14 -0
- package/cjs/types/index.d.ts +1 -0
- package/cjs/types/index.js +1 -0
- package/cjs/types/liquity.d.ts +16 -0
- package/cjs/types/liquityV2.d.ts +26 -0
- package/cjs/types/maker.d.ts +4 -0
- package/cjs/types/morphoBlue.d.ts +2 -0
- package/cjs/types/morphoMidnight.d.ts +1 -0
- package/cjs/types/portfolio.d.ts +127 -6
- package/cjs/types/savings/index.d.ts +9 -1
- package/cjs/types/savings/morphoVaults.d.ts +10 -2
- package/cjs/types/savings/morphoVaults.js +9 -1
- package/cjs/types/spark.d.ts +2 -0
- package/cjs/umbrella/index.d.ts +2 -3
- package/esm/aaveV2/index.js +2 -0
- package/esm/aaveV3/index.d.ts +41 -12
- package/esm/aaveV3/index.js +231 -2
- 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/curveUsd/index.d.ts +5 -2
- package/esm/curveUsd/index.js +30 -15
- package/esm/fluid/index.d.ts +10 -49
- package/esm/fluid/index.js +33 -0
- package/esm/helpers/aaveHelpers/index.d.ts +9 -1
- package/esm/helpers/aaveHelpers/index.js +23 -5
- package/esm/helpers/aaveV4Helpers/index.js +1 -0
- package/esm/helpers/compoundHelpers/index.js +2 -0
- package/esm/helpers/curveUsdHelpers/index.d.ts +3 -1
- package/esm/helpers/curveUsdHelpers/index.js +16 -3
- package/esm/helpers/fluidHelpers/index.js +1 -0
- package/esm/helpers/liquityV2Helpers/index.js +1 -0
- package/esm/helpers/llamaLendHelpers/index.js +2 -1
- package/esm/helpers/makerHelpers/index.d.ts +1 -1
- package/esm/helpers/makerHelpers/index.js +2 -2
- package/esm/helpers/morphoBlueHelpers/index.js +2 -0
- package/esm/helpers/morphoMidnightHelpers/index.js +2 -0
- package/esm/helpers/sparkHelpers/index.js +1 -0
- package/esm/liquity/index.d.ts +2 -12
- package/esm/liquity/index.js +16 -3
- package/esm/liquityV2/index.d.ts +8 -23
- package/esm/liquityV2/index.js +35 -18
- package/esm/maker/index.d.ts +7 -2
- package/esm/maker/index.js +44 -14
- package/esm/markets/index.d.ts +1 -0
- package/esm/markets/index.js +1 -0
- package/esm/markets/maker/index.d.ts +1 -0
- package/esm/markets/maker/index.js +10 -0
- package/esm/moneymarket/moneymarketCommonService.d.ts +9 -0
- package/esm/moneymarket/moneymarketCommonService.js +11 -0
- package/esm/portfolio/index.d.ts +17 -5
- package/esm/portfolio/index.js +584 -385
- 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 +35 -4
- package/esm/savings/morphoVaults/index.d.ts +1 -1
- package/esm/savings/morphoVaults/index.js +57 -19
- package/esm/savings/morphoVaults/options.d.ts +2 -0
- package/esm/savings/morphoVaults/options.js +61 -1
- package/esm/spark/index.js +1 -0
- package/esm/staking/staking.d.ts +20 -0
- package/esm/staking/staking.js +17 -0
- package/esm/types/aave.d.ts +86 -0
- package/esm/types/aaveV4.d.ts +45 -0
- package/esm/types/compound.d.ts +2 -0
- package/esm/types/curveUsd.d.ts +6 -0
- package/esm/types/fluid.d.ts +14 -0
- package/esm/types/index.d.ts +1 -0
- package/esm/types/index.js +1 -0
- package/esm/types/liquity.d.ts +16 -0
- package/esm/types/liquityV2.d.ts +26 -0
- package/esm/types/maker.d.ts +4 -0
- package/esm/types/morphoBlue.d.ts +2 -0
- package/esm/types/morphoMidnight.d.ts +1 -0
- package/esm/types/portfolio.d.ts +127 -6
- package/esm/types/savings/index.d.ts +9 -1
- package/esm/types/savings/morphoVaults.d.ts +10 -2
- package/esm/types/savings/morphoVaults.js +8 -0
- package/esm/types/spark.d.ts +2 -0
- package/esm/umbrella/index.d.ts +2 -3
- package/package.json +3 -2
- package/src/aaveV2/index.ts +2 -0
- package/src/aaveV3/index.ts +293 -2
- 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/curveUsd/index.ts +33 -16
- package/src/fluid/index.ts +44 -3
- package/src/helpers/aaveHelpers/index.ts +27 -7
- package/src/helpers/aaveV4Helpers/index.ts +1 -0
- package/src/helpers/compoundHelpers/index.ts +2 -0
- package/src/helpers/curveUsdHelpers/index.ts +23 -3
- package/src/helpers/fluidHelpers/index.ts +1 -0
- package/src/helpers/liquityV2Helpers/index.ts +1 -0
- package/src/helpers/llamaLendHelpers/index.ts +2 -1
- package/src/helpers/makerHelpers/index.ts +2 -1
- package/src/helpers/morphoBlueHelpers/index.ts +2 -0
- package/src/helpers/morphoMidnightHelpers/index.ts +2 -0
- package/src/helpers/sparkHelpers/index.ts +1 -0
- package/src/liquity/index.ts +19 -5
- package/src/liquityV2/index.ts +48 -22
- package/src/maker/index.ts +77 -30
- package/src/markets/index.ts +2 -1
- package/src/markets/maker/index.ts +10 -0
- package/src/moneymarket/moneymarketCommonService.ts +15 -0
- package/src/portfolio/index.ts +477 -248
- package/src/portfolio/lendingProtocols.ts +281 -0
- package/src/savings/index.ts +45 -5
- package/src/savings/morphoVaults/index.ts +73 -21
- package/src/savings/morphoVaults/options.ts +67 -1
- package/src/spark/index.ts +1 -0
- package/src/staking/staking.ts +28 -0
- package/src/types/aave.ts +90 -0
- package/src/types/aaveV4.ts +50 -0
- package/src/types/compound.ts +2 -0
- package/src/types/curveUsd.ts +7 -0
- package/src/types/fluid.ts +15 -0
- package/src/types/index.ts +2 -1
- package/src/types/liquity.ts +19 -1
- package/src/types/liquityV2.ts +28 -1
- package/src/types/maker.ts +6 -0
- package/src/types/morphoBlue.ts +2 -0
- package/src/types/morphoMidnight.ts +1 -0
- package/src/types/portfolio.ts +153 -7
- package/src/types/savings/index.ts +12 -1
- package/src/types/savings/morphoVaults.ts +11 -1
- package/src/types/spark.ts +2 -0
- package/src/umbrella/index.ts +2 -1
package/src/aaveV4/lend.ts
CHANGED
|
@@ -7,26 +7,9 @@ import {
|
|
|
7
7
|
EthereumProvider,
|
|
8
8
|
NetworkNumber,
|
|
9
9
|
} from '../types/common';
|
|
10
|
+
import { AaveV4TokenizationSpokeDataParsed } from '../types/aaveV4';
|
|
10
11
|
|
|
11
|
-
export
|
|
12
|
-
underlyingAsset: EthAddress;
|
|
13
|
-
assetId: string;
|
|
14
|
-
decimals: number;
|
|
15
|
-
spoke: EthAddress;
|
|
16
|
-
spokeActive: boolean;
|
|
17
|
-
spokeHalted: boolean;
|
|
18
|
-
spokeDepositCap: string;
|
|
19
|
-
spokeTotalAssets: string;
|
|
20
|
-
spokeTotalShares: string;
|
|
21
|
-
hub: EthAddress;
|
|
22
|
-
hubLiquidity: string;
|
|
23
|
-
hubDrawnRate: string;
|
|
24
|
-
convertToShares: string;
|
|
25
|
-
convertToAssets: string;
|
|
26
|
-
user: EthAddress;
|
|
27
|
-
userSuppliedAssets: string;
|
|
28
|
-
userSuppliedShares: string;
|
|
29
|
-
}
|
|
12
|
+
export type { AaveV4TokenizationSpokeData, AaveV4TokenizationSpokeDataParsed } from '../types/aaveV4';
|
|
30
13
|
|
|
31
14
|
export const AAVE_V4_TOKENIZED_SPOKES: Record<string, EthAddress> = {
|
|
32
15
|
EURC_CORE: '0x6D9e2Cdd61CaF69af99b275704B6e272C41c6718',
|
|
@@ -102,34 +85,6 @@ export const aaveV4GetTokenizedVaultAddress = (
|
|
|
102
85
|
return AAVE_V4_TOKENIZED_SPOKES[key];
|
|
103
86
|
};
|
|
104
87
|
|
|
105
|
-
/** Parsed tokenization spoke data with human-readable supplied amounts for display */
|
|
106
|
-
export interface AaveV4TokenizationSpokeDataParsed {
|
|
107
|
-
vaultAddress: EthAddress;
|
|
108
|
-
key: string | null;
|
|
109
|
-
symbol: string;
|
|
110
|
-
hubKey: string;
|
|
111
|
-
// ---- Spoke ----
|
|
112
|
-
spokeActive: boolean;
|
|
113
|
-
spokeHalted: boolean;
|
|
114
|
-
/** Deposit cap in asset units (wei string) */
|
|
115
|
-
spokeDepositCap: string;
|
|
116
|
-
/** Total assets currently in spoke in asset units (wei string) */
|
|
117
|
-
spokeTotalAssets: string;
|
|
118
|
-
// ---- Hub ----
|
|
119
|
-
/** Available hub liquidity in asset units (wei string) */
|
|
120
|
-
hubLiquidity: string;
|
|
121
|
-
/** The conversion rate from assets to shares expressed in asset units. */
|
|
122
|
-
convertToShares: string;
|
|
123
|
-
// ---- User ----
|
|
124
|
-
userSuppliedAssetsEth: string;
|
|
125
|
-
userSuppliedSharesEth: string;
|
|
126
|
-
userSuppliedAssets: string;
|
|
127
|
-
userSuppliedShares: string;
|
|
128
|
-
underlyingAsset: EthAddress;
|
|
129
|
-
spoke: EthAddress;
|
|
130
|
-
decimals: number;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
88
|
const AAVE_V4_TOKENIZED_SPOKE_ADDRESS_TO_KEY: Record<string, string> = Object.entries(
|
|
134
89
|
AAVE_V4_TOKENIZED_SPOKES,
|
|
135
90
|
).reduce((acc, [k, v]) => {
|
|
@@ -189,4 +144,3 @@ export async function getAaveV4TokenizationSpokesData(
|
|
|
189
144
|
}).filter(item => item != null);
|
|
190
145
|
}
|
|
191
146
|
|
|
192
|
-
|
package/src/claiming/aaveV3.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { Client } from 'viem';
|
|
2
2
|
import Dec from 'decimal.js';
|
|
3
3
|
import { EthAddress, NetworkNumber } from '../types';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
AaveRewardsClaimableToken, ClaimableToken, ClaimType, MerklRewardsClaimableToken,
|
|
6
|
+
} from '../types/claiming';
|
|
5
7
|
import {
|
|
6
8
|
AaveIncentiveDataProviderV3ContractViem,
|
|
7
9
|
AaveRewardsControllerViem,
|
|
@@ -37,7 +39,7 @@ export async function getUnclaimedRewardsForAllMarkets(
|
|
|
37
39
|
network: NetworkNumber,
|
|
38
40
|
walletAddress: EthAddress,
|
|
39
41
|
marketAddress: EthAddress,
|
|
40
|
-
): Promise<
|
|
42
|
+
): Promise<AaveRewardsClaimableToken[]> {
|
|
41
43
|
const contract = AaveIncentiveDataProviderV3ContractViem(provider, network);
|
|
42
44
|
const tokensData = await contract.read.getUserReservesIncentivesData([marketAddress, walletAddress]);
|
|
43
45
|
const allTokensDataArrays = tokensData.reduce((acc: any[], val) => {
|
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/curveUsd/index.ts
CHANGED
|
@@ -14,6 +14,13 @@ import { getCrvUsdAggregatedData } from '../helpers/curveUsdHelpers';
|
|
|
14
14
|
import { CrvUsdMarkets } from '../markets';
|
|
15
15
|
import { wethToEth } from '../services/utils';
|
|
16
16
|
import { getViemProvider, setViemBlockNumber } from '../services/viem';
|
|
17
|
+
import { getStakingApy, STAKING_ASSETS } from '../staking';
|
|
18
|
+
|
|
19
|
+
/** Converts a per-second AMM rate (wei, 18 decimals) into a yearly compounded borrow APY in %. */
|
|
20
|
+
const ammRateToBorrowApy = (rateWei: string) => {
|
|
21
|
+
const exponent = new Dec(assetAmountInEth(rateWei)).mul(365).mul(86400);
|
|
22
|
+
return new Dec(new Dec(2.718281828459).pow(exponent).minus(1)).mul(100).toString();
|
|
23
|
+
};
|
|
17
24
|
|
|
18
25
|
const getAndFormatBands = async (provider: Client, network: NetworkNumber, selectedMarket: CrvUSDMarketData, _minBand: string, _maxBand: string) => {
|
|
19
26
|
const contract = CrvUSDViewContractViem(provider, network);
|
|
@@ -69,15 +76,8 @@ export const _getCurveUsdGlobalData = async (provider: Client, network: NetworkN
|
|
|
69
76
|
const totalDebt = assetAmountInEth(data.totalDebt.toString(), debtAsset);
|
|
70
77
|
const ammPrice = assetAmountInEth(data.ammPrice.toString(), debtAsset);
|
|
71
78
|
|
|
72
|
-
const
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
const exponentRate = new Dec(rate).mul(365).mul(86400);
|
|
76
|
-
const exponentFutureRate = new Dec(futureRate).mul(365).mul(86400);
|
|
77
|
-
const borrowRate = new Dec(new Dec(2.718281828459).pow(exponentRate).minus(1)).mul(100)
|
|
78
|
-
.toString();
|
|
79
|
-
const futureBorrowRate = new Dec(new Dec(2.718281828459).pow(exponentFutureRate).minus(1)).mul(100)
|
|
80
|
-
.toString();
|
|
79
|
+
const borrowRate = ammRateToBorrowApy(data.ammRate.toString());
|
|
80
|
+
const futureBorrowRate = ammRateToBorrowApy(data.monetaryPolicyRate.toString());
|
|
81
81
|
|
|
82
82
|
const bandsData = await getAndFormatBands(provider, network, selectedMarket, data.minBand.toString(), data.maxBand.toString());
|
|
83
83
|
|
|
@@ -164,13 +164,22 @@ export const getCrvUsdAccountBalances = async (
|
|
|
164
164
|
controllerAddress: EthAddress,
|
|
165
165
|
): Promise<PositionBalances> => _getCrvUsdAccountBalances(getViemProvider(provider, network), network, block, addressMapping, address, controllerAddress);
|
|
166
166
|
|
|
167
|
-
|
|
167
|
+
/**
|
|
168
|
+
* @param borrowRate market borrow APY in % (`CrvUSDGlobalMarketData.borrowRate`); when omitted it is read from the view contract
|
|
169
|
+
*/
|
|
170
|
+
export const _getCurveUsdUserData = async (provider: Client, network: NetworkNumber, address: EthAddress, selectedMarket: CrvUSDMarketData, activeBand: string, borrowRate?: string): Promise<CrvUSDUserData> => {
|
|
168
171
|
const contract = CrvUSDViewContractViem(provider, network);
|
|
169
|
-
|
|
170
|
-
const data = await contract.read.userData([selectedMarket.controllerAddress, address]);
|
|
171
172
|
const collAsset = selectedMarket.collAsset;
|
|
172
173
|
const debtAsset = selectedMarket.baseAsset;
|
|
173
174
|
|
|
175
|
+
const [data, collStakingApy, marketBorrowRate] = await Promise.all([
|
|
176
|
+
contract.read.userData([selectedMarket.controllerAddress, address]),
|
|
177
|
+
STAKING_ASSETS.includes(collAsset) ? getStakingApy(collAsset) : Promise.resolve('0'),
|
|
178
|
+
borrowRate !== undefined
|
|
179
|
+
? Promise.resolve(borrowRate)
|
|
180
|
+
: contract.read.globalData([selectedMarket.controllerAddress]).then((globalData) => ammRateToBorrowApy(globalData.ammRate.toString())),
|
|
181
|
+
]);
|
|
182
|
+
|
|
174
183
|
const health = assetAmountInEth(data.health.toString());
|
|
175
184
|
const healthPercent = new Dec(health).mul(100).toString();
|
|
176
185
|
const collPrice = assetAmountInEth(data.collateralPrice.toString(), debtAsset);
|
|
@@ -202,7 +211,7 @@ export const _getCurveUsdUserData = async (provider: Client, network: NetworkNum
|
|
|
202
211
|
isBorrowed: new Dec(debtBorrowed).gt('0'),
|
|
203
212
|
symbol: 'crvUSD',
|
|
204
213
|
price: '1',
|
|
205
|
-
interestRate:
|
|
214
|
+
interestRate: marketBorrowRate,
|
|
206
215
|
},
|
|
207
216
|
} : {};
|
|
208
217
|
|
|
@@ -232,8 +241,15 @@ export const _getCurveUsdUserData = async (provider: Client, network: NetworkNum
|
|
|
232
241
|
numOfBands: data.N.toString(),
|
|
233
242
|
usedAssets,
|
|
234
243
|
status,
|
|
244
|
+
borrowRate: marketBorrowRate,
|
|
235
245
|
...getCrvUsdAggregatedData({
|
|
236
|
-
loanExists: data.loanExists,
|
|
246
|
+
loanExists: data.loanExists,
|
|
247
|
+
usedAssets,
|
|
248
|
+
network: NetworkNumber.Eth,
|
|
249
|
+
selectedMarket,
|
|
250
|
+
numOfBands: data.N.toString(),
|
|
251
|
+
borrowRate: marketBorrowRate,
|
|
252
|
+
collStakingApy,
|
|
237
253
|
}),
|
|
238
254
|
userBands,
|
|
239
255
|
};
|
|
@@ -245,10 +261,11 @@ export const getCurveUsdUserData = async (
|
|
|
245
261
|
address: EthAddress,
|
|
246
262
|
selectedMarket: CrvUSDMarketData,
|
|
247
263
|
activeBand: string,
|
|
248
|
-
|
|
264
|
+
borrowRate?: string,
|
|
265
|
+
): Promise<CrvUSDUserData> => _getCurveUsdUserData(getViemProvider(provider, network), network, address, selectedMarket, activeBand, borrowRate);
|
|
249
266
|
|
|
250
267
|
export const getCurveUsdFullPositionData = async (provider: EthereumProvider, network: NetworkNumber, address: EthAddress, selectedMarket: CrvUSDMarketData): Promise<CrvUSDUserData> => {
|
|
251
268
|
const marketData = await getCurveUsdGlobalData(provider, network, selectedMarket);
|
|
252
|
-
const positionData = await getCurveUsdUserData(provider, network, address, selectedMarket, marketData.activeBand);
|
|
269
|
+
const positionData = await getCurveUsdUserData(provider, network, address, selectedMarket, marketData.activeBand, marketData.borrowRate);
|
|
253
270
|
return positionData;
|
|
254
271
|
};
|
package/src/fluid/index.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
FluidAggregatedVaultData,
|
|
11
11
|
FluidAssetData,
|
|
12
12
|
FluidAssetsData,
|
|
13
|
+
FluidEarnPositionData,
|
|
13
14
|
FluidFTokenDataStructOutput,
|
|
14
15
|
FluidMarketData,
|
|
15
16
|
FluidMarketInfo,
|
|
@@ -1597,7 +1598,7 @@ export const getFluidTokenData = async (
|
|
|
1597
1598
|
token: string,
|
|
1598
1599
|
) => _getFluidTokenData(getViemProvider(provider, network), network, token);
|
|
1599
1600
|
|
|
1600
|
-
const parseFDepositTokenData = (fTokenData: FluidFTokenDataStructOutput, userPosition: FluidUserEarnPositionStructOutput, apiData: any, fTokenAddress?: string) => {
|
|
1601
|
+
const parseFDepositTokenData = (fTokenData: FluidFTokenDataStructOutput, userPosition: FluidUserEarnPositionStructOutput, apiData: any, fTokenAddress?: string): FluidEarnPositionData => {
|
|
1601
1602
|
const decimals = fTokenData.decimals.toString();
|
|
1602
1603
|
const depositRate = new Dec(getEthAmountForDecimals(fTokenData.convertToShares.toString(), decimals)).toString();
|
|
1603
1604
|
const withdrawRate = new Dec(getEthAmountForDecimals(fTokenData.convertToAssets.toString(), decimals)).toString();
|
|
@@ -1645,7 +1646,7 @@ export const getFluidDepositData = async (
|
|
|
1645
1646
|
address: EthAddress,
|
|
1646
1647
|
) => _getFluidDepositData(getViemProvider(provider, network), network, token, address);
|
|
1647
1648
|
|
|
1648
|
-
export const _getAllUserEarnPositionsWithFTokens = async (provider: Client, network: NetworkNumber, user: EthAddress) => {
|
|
1649
|
+
export const _getAllUserEarnPositionsWithFTokens = async (provider: Client, network: NetworkNumber, user: EthAddress): Promise<FluidEarnPositionData[]> => {
|
|
1649
1650
|
const view = FluidViewContractViem(provider, network);
|
|
1650
1651
|
const [
|
|
1651
1652
|
[userPositions, fTokensData],
|
|
@@ -1664,7 +1665,7 @@ export const _getAllUserEarnPositionsWithFTokens = async (provider: Client, netw
|
|
|
1664
1665
|
rewardsData = await rewardsApiResponse.json();
|
|
1665
1666
|
}
|
|
1666
1667
|
|
|
1667
|
-
const parsedRes = fTokensData.reduce<
|
|
1668
|
+
const parsedRes = fTokensData.reduce<FluidEarnPositionData[]>((acc, fTokenData, i) => {
|
|
1668
1669
|
const userPosition = userPositions[i];
|
|
1669
1670
|
const deposited = userPosition?.underlyingAssets;
|
|
1670
1671
|
|
|
@@ -1830,3 +1831,43 @@ export const _getUserPositionsPortfolio = async (provider: PublicClient, network
|
|
|
1830
1831
|
userData: userData[i],
|
|
1831
1832
|
})).filter(md => md.marketData !== undefined);
|
|
1832
1833
|
};
|
|
1834
|
+
|
|
1835
|
+
|
|
1836
|
+
export const _getAllFluidMarketDataPortfolio = async (provider: PublicClient, network: NetworkNumber): Promise<Record<string, FluidMarketData>> => {
|
|
1837
|
+
const versions = getFluidVersionsDataForNetwork(network);
|
|
1838
|
+
if (versions.length === 0) return {};
|
|
1839
|
+
|
|
1840
|
+
const view = FluidViewContractViem(provider, network);
|
|
1841
|
+
const vaultsData = await Promise.all(versions.map((version) => view.read.getVaultData([version.marketAddress])));
|
|
1842
|
+
|
|
1843
|
+
const tokens = Array.from(new Set(vaultsData.map((vaultData) => {
|
|
1844
|
+
const vaultTokens = [getAssetInfoByAddress(vaultData.supplyToken0, network).symbol, getAssetInfoByAddress(vaultData.borrowToken0, network).symbol];
|
|
1845
|
+
if (vaultData.supplyToken1 && !compareAddresses(ZERO_ADDRESS, vaultData.supplyToken1)) vaultTokens.push(getAssetInfoByAddress(vaultData.supplyToken1, network).symbol);
|
|
1846
|
+
if (vaultData.borrowToken1 && !compareAddresses(ZERO_ADDRESS, vaultData.borrowToken1)) vaultTokens.push(getAssetInfoByAddress(vaultData.borrowToken1, network).symbol);
|
|
1847
|
+
return vaultTokens;
|
|
1848
|
+
}).flat()));
|
|
1849
|
+
|
|
1850
|
+
// ETH and WBTC needed for other tokens prices
|
|
1851
|
+
if (!tokens.includes('ETH')) tokens.push('ETH');
|
|
1852
|
+
if (!tokens.includes('WBTC')) tokens.push('WBTC');
|
|
1853
|
+
|
|
1854
|
+
const [tokenPrices, merklCampaigns] = await Promise.all([
|
|
1855
|
+
getTokensPricesForPortfolio(tokens, provider, network),
|
|
1856
|
+
getFluidMerklCampaigns(network),
|
|
1857
|
+
]);
|
|
1858
|
+
|
|
1859
|
+
const parsedMarketsData = await Promise.all(vaultsData.map(async (vaultData) => parseMarketData(provider, vaultData, network, tokenPrices)));
|
|
1860
|
+
|
|
1861
|
+
const marketsData: Record<string, FluidMarketData> = {};
|
|
1862
|
+
parsedMarketsData.forEach((marketData, i) => {
|
|
1863
|
+
if (!marketData) return;
|
|
1864
|
+
marketsData[versions[i].value] = attachFluidMerklIncentives(marketData, merklCampaigns);
|
|
1865
|
+
});
|
|
1866
|
+
|
|
1867
|
+
return marketsData;
|
|
1868
|
+
};
|
|
1869
|
+
|
|
1870
|
+
export const getAllFluidMarketDataPortfolio = async (
|
|
1871
|
+
provider: EthereumProvider,
|
|
1872
|
+
network: NetworkNumber,
|
|
1873
|
+
): Promise<Record<string, FluidMarketData>> => _getAllFluidMarketDataPortfolio(getViemProvider(provider, network, { batch: { multicall: true } }), network);
|
|
@@ -2,7 +2,7 @@ import Dec from 'decimal.js';
|
|
|
2
2
|
import { assetAmountInWei, getAssetInfo, getAssetInfoByAddress } from '@defisaver/tokens';
|
|
3
3
|
import { Client } from 'viem';
|
|
4
4
|
import {
|
|
5
|
-
AaveAssetData, AaveHelperCommon, AaveMarketInfo, AaveV3AggregatedPositionData, AaveV3AssetsData, AaveV3UsedAsset, AaveV3UsedAssets, AaveVersions,
|
|
5
|
+
AaveAssetData, AaveHelperCommon, AaveMarketInfo, AaveV3AggregatedPositionData, AaveV3AssetsData, AaveV3UsedAsset, AaveV3UsedAssets, AaveVersions, EModeCategoriesData,
|
|
6
6
|
} from '../../types';
|
|
7
7
|
import { getNativeAssetFromWrapped, getWrappedNativeAssetFromUnwrapped } from '../../services/utils';
|
|
8
8
|
import {
|
|
@@ -24,6 +24,13 @@ export const isAaveV3 = ({ selectedMarket }: { selectedMarket: Partial<AaveMarke
|
|
|
24
24
|
export const aaveV3IsInIsolationMode = ({ usedAssets, assetsData }: { usedAssets: AaveV3UsedAssets, assetsData: AaveV3AssetsData }) => Object.values(usedAssets).some(({ symbol, collateral }) => collateral && assetsData[symbol].isIsolated);
|
|
25
25
|
export const aaveV3IsInSiloedMode = ({ usedAssets, assetsData }: { usedAssets: AaveV3UsedAssets, assetsData: AaveV3AssetsData }) => Object.values(usedAssets).some(({ symbol, debt }) => debt && assetsData[symbol].isSiloed);
|
|
26
26
|
|
|
27
|
+
export const aaveV3IsEmodeIsolated = ({ eModeCategory, eModeCategoriesData }: { eModeCategory: number, eModeCategoriesData?: EModeCategoriesData }) => eModeCategory !== 0 && !!eModeCategoriesData?.[eModeCategory]?.isolated;
|
|
28
|
+
|
|
29
|
+
export const aaveV3CanBeCollateralInEmode = ({ eModeCategory, eModeCategoriesData }: { eModeCategory: number, eModeCategoriesData?: EModeCategoriesData }, _asset: string) => {
|
|
30
|
+
if (!aaveV3IsEmodeIsolated({ eModeCategory, eModeCategoriesData })) return true;
|
|
31
|
+
return eModeCategoriesData![eModeCategory].collateralAssets.includes(getNativeAssetFromWrapped(_asset));
|
|
32
|
+
};
|
|
33
|
+
|
|
27
34
|
export const aaveAnyGetCollSuppliedAssets = ({ usedAssets }: { usedAssets: AaveV3UsedAssets }) => Object.values(usedAssets)
|
|
28
35
|
.filter(({ isSupplied, collateral }: { isSupplied: boolean, collateral: boolean }) => isSupplied && collateral);
|
|
29
36
|
|
|
@@ -37,14 +44,18 @@ export const aaveAnyGetSuppliableAssets = ({
|
|
|
37
44
|
const collAccountAssets = aaveAnyGetCollSuppliedAssets(data);
|
|
38
45
|
const marketAssets = Object.values(assetsData) as AaveAssetData[];
|
|
39
46
|
|
|
40
|
-
if (
|
|
47
|
+
if (!isAaveV3(data)) return marketAssets.filter(({ canBeSupplied }) => canBeSupplied).map(({ symbol }) => ({ symbol, canBeCollateral: true }));
|
|
48
|
+
|
|
49
|
+
const canBeCollateralInEmode = (symbol: string) => aaveV3CanBeCollateralInEmode(data, symbol);
|
|
50
|
+
|
|
51
|
+
if (collAccountAssets.length === 0) return marketAssets.filter(({ canBeSupplied }) => canBeSupplied).map(({ symbol }) => ({ symbol, canBeCollateral: canBeCollateralInEmode(symbol) }));
|
|
41
52
|
|
|
42
53
|
if (aaveV3IsInIsolationMode(data)) {
|
|
43
54
|
const collAsset = collAccountAssets[0].symbol;
|
|
44
|
-
return marketAssets.filter(d => d.canBeSupplied).map(({ symbol }) => ({ symbol, canBeCollateral: symbol === collAsset }));
|
|
55
|
+
return marketAssets.filter(d => d.canBeSupplied).map(({ symbol }) => ({ symbol, canBeCollateral: symbol === collAsset && canBeCollateralInEmode(symbol) }));
|
|
45
56
|
}
|
|
46
57
|
|
|
47
|
-
return marketAssets.filter(d => d.canBeSupplied).map(({ symbol, isIsolated }) => ({ symbol, canBeCollateral: !isIsolated }));
|
|
58
|
+
return marketAssets.filter(d => d.canBeSupplied).map(({ symbol, isIsolated }) => ({ symbol, canBeCollateral: !isIsolated && canBeCollateralInEmode(symbol) }));
|
|
48
59
|
};
|
|
49
60
|
|
|
50
61
|
export const aaveAnyGetSuppliableAsCollAssets = ({
|
|
@@ -62,8 +73,8 @@ export const aaveAnyGetEmodeMutableProps = (
|
|
|
62
73
|
const asset = getNativeAssetFromWrapped(_asset);
|
|
63
74
|
|
|
64
75
|
const assetData = assetsData[asset];
|
|
65
|
-
const eModeCategoryData: { collateralAssets: string[], collateralFactor: string, liquidationRatio: string, ltvZeroAssets: string[] } = eModeCategoriesData?.[eModeCategory] || {
|
|
66
|
-
collateralAssets: [], ltvZeroAssets: [], collateralFactor: '0', liquidationRatio: '0',
|
|
76
|
+
const eModeCategoryData: { collateralAssets: string[], collateralFactor: string, liquidationRatio: string, ltvZeroAssets: string[], isolated?: boolean } = eModeCategoriesData?.[eModeCategory] || {
|
|
77
|
+
collateralAssets: [], ltvZeroAssets: [], collateralFactor: '0', liquidationRatio: '0', isolated: false,
|
|
67
78
|
};
|
|
68
79
|
|
|
69
80
|
if (
|
|
@@ -72,6 +83,9 @@ export const aaveAnyGetEmodeMutableProps = (
|
|
|
72
83
|
|| new Dec(eModeCategoryData.collateralFactor || 0).eq(0)
|
|
73
84
|
) {
|
|
74
85
|
const { liquidationRatio, collateralFactor } = assetData;
|
|
86
|
+
if (eModeCategory !== 0 && eModeCategoryData.isolated && !eModeCategoryData.collateralAssets.includes(asset)) {
|
|
87
|
+
return ({ liquidationRatio, collateralFactor: '0' });
|
|
88
|
+
}
|
|
75
89
|
return ({ liquidationRatio, collateralFactor });
|
|
76
90
|
}
|
|
77
91
|
if (eModeCategoryData.ltvZeroAssets.includes(asset)) return ({ liquidationRatio: '0', collateralFactor: '0' });
|
|
@@ -118,7 +132,10 @@ export const aaveAnyGetUserReserveLtvAndLltv = (
|
|
|
118
132
|
|| !eModeCategoryData.collateralAssets.includes(asset)
|
|
119
133
|
|| new Dec(eModeCategoryData.collateralFactor || 0).eq(0)
|
|
120
134
|
) {
|
|
121
|
-
|
|
135
|
+
const ltv = eModeCategory !== 0 && eModeCategoryData?.isolated && !eModeCategoryData.collateralAssets.includes(asset)
|
|
136
|
+
? '0'
|
|
137
|
+
: assetData.collateralFactor;
|
|
138
|
+
return { ltv, lltv: assetData.liquidationRatio };
|
|
122
139
|
}
|
|
123
140
|
|
|
124
141
|
const ltv = eModeCategoryData.ltvZeroAssets.includes(asset) ? '0' : eModeCategoryData.collateralFactor;
|
|
@@ -169,6 +186,9 @@ export const aaveAnyGetAggregatedPositionData = ({
|
|
|
169
186
|
},
|
|
170
187
|
);
|
|
171
188
|
payload.safetyRatioWithLtvZeroFallback = +payload.suppliedUsd ? new Dec(payload.borrowLimitWithLtvZeroFallbackUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
|
|
189
|
+
// Normalised safety ratio (100 = liquidation on every protocol): the automation ratio above, falling back
|
|
190
|
+
// to the regular ratio when the fallback carries its '0' placeholder.
|
|
191
|
+
payload.safetyRatio = +payload.safetyRatioWithLtvZeroFallback ? payload.safetyRatioWithLtvZeroFallback : payload.ratio;
|
|
172
192
|
payload.liqRatio = new Dec(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).toString();
|
|
173
193
|
payload.liqPercent = new Dec(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).mul(100).toString();
|
|
174
194
|
const { leveragedType, leveragedAsset } = isLeveragedPos(usedAssets);
|
|
@@ -270,6 +270,7 @@ export const aaveV4GetAggregatedPositionData = ({
|
|
|
270
270
|
payload.ratio = +payload.suppliedUsd ? new Dec(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
|
|
271
271
|
payload.minRatio = '100';
|
|
272
272
|
payload.collRatio = +payload.suppliedUsd ? new Dec(payload.suppliedCollateralUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
|
|
273
|
+
payload.safetyRatio = payload.ratio;
|
|
273
274
|
payload.liqRatio = new Dec(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).toString();
|
|
274
275
|
payload.liqPercent = new Dec(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).mul(100).toString();
|
|
275
276
|
const { leveragedType, leveragedAsset } = isLeveragedPosAaveV4(usedAssets);
|
|
@@ -139,6 +139,7 @@ export const getCompoundV2AggregatedData = ({
|
|
|
139
139
|
payload.collRatio = payload.borrowedUsd && payload.borrowedUsd !== '0'
|
|
140
140
|
? new Dec(payload.suppliedCollateralUsd).div(payload.borrowedUsd).mul(100).toString()
|
|
141
141
|
: '0';
|
|
142
|
+
payload.safetyRatio = payload.ratio;
|
|
142
143
|
|
|
143
144
|
// Calculate borrow limits per asset
|
|
144
145
|
Object.values(usedAssets).forEach((item) => {
|
|
@@ -185,6 +186,7 @@ export const getCompoundV3AggregatedData = ({
|
|
|
185
186
|
payload.incentiveUsd = incentiveUsd;
|
|
186
187
|
payload.totalInterestUsd = totalInterestUsd;
|
|
187
188
|
payload.minRatio = '100';
|
|
189
|
+
payload.safetyRatio = payload.ratio;
|
|
188
190
|
payload.liqRatio = new Dec(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).toString();
|
|
189
191
|
payload.liqPercent = new Dec(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).mul(100).toString();
|
|
190
192
|
payload.minDebt = assetsData[selectedMarket.baseAsset].minDebt;
|
|
@@ -2,14 +2,21 @@ import Dec from 'decimal.js';
|
|
|
2
2
|
import { CrvUSDAggregatedPositionData, CrvUSDMarketData, CrvUSDUsedAssets } from '../../types';
|
|
3
3
|
import { MMUsedAssets, NetworkNumber } from '../../types/common';
|
|
4
4
|
import {
|
|
5
|
-
calcLeverageLiqPrice, getAssetsTotal, getExposure, isLeveragedPos,
|
|
5
|
+
calcLeverageLiqPrice, getAssetsTotal, getExposure, getSafetyRatioFromCollateralRatio, isLeveragedPos,
|
|
6
6
|
} from '../../moneymarket';
|
|
7
7
|
import { mapRange } from '../../services/utils';
|
|
8
|
+
import { calculateNetApyFromRates } from '../../staking';
|
|
8
9
|
|
|
9
10
|
export const getCrvUsdAggregatedData = ({
|
|
10
|
-
loanExists, usedAssets, network, selectedMarket, numOfBands, ...rest
|
|
11
|
+
loanExists, usedAssets, network, selectedMarket, numOfBands, borrowRate = '0', collStakingApy = '0', ...rest
|
|
11
12
|
}:{
|
|
12
|
-
loanExists: boolean,
|
|
13
|
+
loanExists: boolean,
|
|
14
|
+
usedAssets: CrvUSDUsedAssets,
|
|
15
|
+
network: NetworkNumber,
|
|
16
|
+
selectedMarket: CrvUSDMarketData,
|
|
17
|
+
numOfBands: number | string,
|
|
18
|
+
borrowRate?: string, // market borrow APY in %, see `CrvUSDGlobalMarketData.borrowRate`
|
|
19
|
+
collStakingApy?: string, // native yield APY in % of the collateral asset, if it is a staked asset
|
|
13
20
|
}): CrvUSDAggregatedPositionData => {
|
|
14
21
|
const payload = {} as CrvUSDAggregatedPositionData;
|
|
15
22
|
payload.supplied = getAssetsTotal(usedAssets, ({ isSupplied }: { isSupplied: boolean }) => isSupplied, ({ supplied }: { supplied: string }) => supplied); // this is wrong if we are in soft-liquidations
|
|
@@ -26,6 +33,7 @@ export const getCrvUsdAggregatedData = ({
|
|
|
26
33
|
|
|
27
34
|
// this is all approximation
|
|
28
35
|
payload.minAllowedRatio = mapRange(numOfBands, 4, 50, 115, 140); // collateral ratio
|
|
36
|
+
payload.safetyRatio = loanExists ? getSafetyRatioFromCollateralRatio(payload.ratio, payload.minAllowedRatio) : '0';
|
|
29
37
|
payload.collFactor = new Dec(1).div(payload.minAllowedRatio).mul(100).toString(); // collateral factor = 1 / collateral ratio
|
|
30
38
|
// only take in consideration collAsset
|
|
31
39
|
payload.borrowLimitUsd = usedAssets?.[selectedMarket.collAsset]?.isSupplied
|
|
@@ -42,5 +50,17 @@ export const getCrvUsdAggregatedData = ({
|
|
|
42
50
|
|
|
43
51
|
payload.exposure = getExposure(payload.borrowedUsd, payload.suppliedUsd);
|
|
44
52
|
|
|
53
|
+
// crvUSD debt accrues the market borrow rate. Collateral (including crvUSD held during soft liquidation) earns
|
|
54
|
+
// nothing from the protocol itself; only the native yield of staked collateral is counted, as an incentive.
|
|
55
|
+
const { netApy, totalInterestUsd, incentiveUsd } = calculateNetApyFromRates({
|
|
56
|
+
suppliedUsd: payload.suppliedUsd,
|
|
57
|
+
borrowedUsd: payload.borrowedUsd,
|
|
58
|
+
borrowRate,
|
|
59
|
+
incentives: [{ apy: collStakingApy, amountUsd: usedAssets?.[selectedMarket.collAsset]?.suppliedUsd || '0' }],
|
|
60
|
+
});
|
|
61
|
+
payload.netApy = netApy;
|
|
62
|
+
payload.totalInterestUsd = totalInterestUsd;
|
|
63
|
+
payload.incentiveUsd = incentiveUsd;
|
|
64
|
+
|
|
45
65
|
return payload;
|
|
46
66
|
};
|
|
@@ -143,6 +143,7 @@ borrowShares?: string,
|
|
|
143
143
|
payload.ratio = +payload.suppliedUsd ? new Dec(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
|
|
144
144
|
payload.collRatio = +payload.suppliedUsd ? new Dec(payload.suppliedUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
|
|
145
145
|
payload.minRatio = marketData.minRatio;
|
|
146
|
+
payload.safetyRatio = payload.ratio;
|
|
146
147
|
const { leveragedType, leveragedAsset } = isLeveragedPos(usedAssets);
|
|
147
148
|
|
|
148
149
|
payload.leveragedType = leveragedType;
|
|
@@ -69,6 +69,7 @@ export const getLiquityV2AggregatedPositionData = ({
|
|
|
69
69
|
payload.leftToBorrowUsd = leftToBorrowUsd.lte('0') ? '0' : leftToBorrowUsd.toString();
|
|
70
70
|
payload.ratio = (+payload.suppliedUsd && +payload.borrowedUsd) ? new Dec(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
|
|
71
71
|
payload.collRatio = (+payload.suppliedUsd && +payload.borrowedUsd) ? new Dec(payload.suppliedUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
|
|
72
|
+
payload.safetyRatio = payload.ratio;
|
|
72
73
|
const { netApy, incentiveUsd, totalInterestUsd } = calculateNetApyLiquityV2(usedAssets, assetsData, interestRate);
|
|
73
74
|
payload.netApy = netApy;
|
|
74
75
|
payload.incentiveUsd = incentiveUsd;
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from '../../types';
|
|
5
5
|
import { MMAssetsData, MMUsedAssets, NetworkNumber } from '../../types/common';
|
|
6
6
|
import {
|
|
7
|
-
calcLeverageLiqPrice, getAssetsTotal, getExposure, isLeveragedPos,
|
|
7
|
+
calcLeverageLiqPrice, getAssetsTotal, getExposure, getSafetyRatioFromCollateralRatio, isLeveragedPos,
|
|
8
8
|
} from '../../moneymarket';
|
|
9
9
|
import { mapRange } from '../../services/utils';
|
|
10
10
|
import { calculateNetApy } from '../../staking';
|
|
@@ -38,6 +38,7 @@ export const getLlamaLendAggregatedData = ({
|
|
|
38
38
|
|
|
39
39
|
// this is all approximation
|
|
40
40
|
payload.minAllowedRatio = mapRange(numOfBands, 4, 50, 115, 140); // collateral ratio
|
|
41
|
+
payload.safetyRatio = loanExists ? getSafetyRatioFromCollateralRatio(payload.ratio, payload.minAllowedRatio) : '0';
|
|
41
42
|
payload.collFactor = new Dec(1).div(payload.minAllowedRatio).mul(100).toString(); // collateral factor = 1 / collateral ratio
|
|
42
43
|
// only take in consideration collAsset
|
|
43
44
|
payload.borrowLimitUsd = usedAssets?.[collAsset]?.isSupplied
|
|
@@ -10,6 +10,7 @@ export const parseCollateralInfo = (
|
|
|
10
10
|
_rate: string,
|
|
11
11
|
_spot: string,
|
|
12
12
|
_line: string,
|
|
13
|
+
_dust: string,
|
|
13
14
|
_duty: string,
|
|
14
15
|
_futureRate: string,
|
|
15
16
|
_chop: string,
|
|
@@ -20,7 +21,7 @@ export const parseCollateralInfo = (
|
|
|
20
21
|
const rate = new Dec(_rate).toString();
|
|
21
22
|
const spot = new Dec(_spot).div(1e27).toString();
|
|
22
23
|
const line = new Dec(_line).div(1e45).toString();
|
|
23
|
-
const dust = new Dec(
|
|
24
|
+
const dust = new Dec(_dust).div(1e45).toString(); // Vat.ilks.dust, rad (1e45) -> DAI
|
|
24
25
|
const duty = new Dec(_duty).toString();
|
|
25
26
|
const futureRate = new Dec(_futureRate).toString();
|
|
26
27
|
const chop = new Dec(_chop).div(1e18).toString();
|
|
@@ -54,6 +54,8 @@ export const getMorphoBlueAggregatedPositionData = ({ usedAssets, assetsData, ma
|
|
|
54
54
|
payload.ltv = new Dec(usedAssets[loanToken]?.borrowed || 0).div(oracle).div(usedAssets[collateralToken]?.supplied || 1).toString(); // default to 1 because can't div 0
|
|
55
55
|
payload.ratio = new Dec(usedAssets[collateralToken]?.supplied || 0).mul(oracle).div(usedAssets[loanToken]?.borrowed || 1).mul(100)
|
|
56
56
|
.toString();
|
|
57
|
+
// Borrow limit over debt, so 100 sits on the market's LLTV however low it is (`ratio` is the raw collateral ratio).
|
|
58
|
+
payload.safetyRatio = +payload.borrowedUsd > 0 ? new Dec(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
|
|
57
59
|
|
|
58
60
|
const { leveragedType, leveragedAsset } = isLeveragedPos(usedAssets);
|
|
59
61
|
payload.leveragedType = leveragedType;
|
|
@@ -102,6 +102,8 @@ export const getMorphoMidnightAggregatedPositionData = ({
|
|
|
102
102
|
payload.ltv = new Dec(payload.suppliedCollateralUsd).eq(0) ? '0' : new Dec(payload.borrowedUsd).div(payload.suppliedCollateralUsd).toString();
|
|
103
103
|
payload.ratio = new Dec(payload.borrowedUsd).eq(0) ? '0' : new Dec(payload.suppliedCollateralUsd).div(payload.borrowedUsd).mul(100).toString();
|
|
104
104
|
payload.healthRatio = new Dec(payload.borrowedUsd).eq(0) ? 'Infinity' : new Dec(payload.liquidationLimitUsd).div(payload.borrowedUsd).toDP(4).toString();
|
|
105
|
+
// Borrow limit over debt, so 100 sits on the market's LLTV however low it is (`ratio` is the raw collateral ratio).
|
|
106
|
+
payload.safetyRatio = +payload.borrowedUsd > 0 ? new Dec(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
|
|
105
107
|
|
|
106
108
|
const { leveragedType, leveragedAsset } = isLeveragedPos(usedAssets);
|
|
107
109
|
payload.leveragedType = leveragedType;
|
|
@@ -96,6 +96,7 @@ export const sparkGetAggregatedPositionData = ({
|
|
|
96
96
|
payload.leftToBorrowUsd = leftToBorrowUsd.lte('0') ? '0' : leftToBorrowUsd.toString();
|
|
97
97
|
payload.ratio = +payload.suppliedUsd ? new Dec(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
|
|
98
98
|
payload.collRatio = +payload.suppliedUsd ? new Dec(payload.suppliedCollateralUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
|
|
99
|
+
payload.safetyRatio = payload.ratio;
|
|
99
100
|
const { netApy, incentiveUsd, totalInterestUsd } = calculateNetApy({ usedAssets, assetsData });
|
|
100
101
|
payload.netApy = netApy;
|
|
101
102
|
payload.incentiveUsd = incentiveUsd;
|