@defisaver/positions-sdk 2.1.72-aave-v4-dev → 2.1.72-aave-v4-4-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/aaveV4/index.d.ts +2 -2
- package/cjs/aaveV4/index.js +133 -14
- package/cjs/aaveV4/lend.d.ts +45 -0
- package/cjs/aaveV4/lend.js +141 -0
- package/cjs/helpers/aaveV4Helpers/index.d.ts +1 -2
- package/cjs/helpers/aaveV4Helpers/index.js +7 -7
- package/cjs/markets/aaveV4/index.js +1 -1
- package/cjs/types/aaveV4.d.ts +8 -0
- package/esm/aaveV4/index.d.ts +2 -2
- package/esm/aaveV4/index.js +97 -12
- package/esm/aaveV4/lend.d.ts +45 -0
- package/esm/aaveV4/lend.js +134 -0
- package/esm/helpers/aaveV4Helpers/index.d.ts +1 -2
- package/esm/helpers/aaveV4Helpers/index.js +1 -1
- package/esm/markets/aaveV4/index.js +1 -1
- package/esm/types/aaveV4.d.ts +8 -0
- package/package.json +1 -1
- package/src/aaveV4/index.ts +128 -18
- package/src/aaveV4/lend.ts +180 -0
- package/src/helpers/aaveV4Helpers/index.ts +7 -2
- package/src/markets/aaveV4/index.ts +1 -1
- package/src/types/aaveV4.ts +8 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { assetAmountInEth, getAssetInfoByAddress } from '@defisaver/tokens';
|
|
2
|
+
import { AaveV4ViewContractViem } from '../contracts';
|
|
3
|
+
import { getViemProvider } from '../services/viem';
|
|
4
|
+
import { wethToEth } from '../services/utils';
|
|
5
|
+
import {
|
|
6
|
+
EthAddress,
|
|
7
|
+
EthereumProvider,
|
|
8
|
+
NetworkNumber,
|
|
9
|
+
} from '../types/common';
|
|
10
|
+
|
|
11
|
+
export interface AaveV4TokenizationSpokeData {
|
|
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
|
+
}
|
|
30
|
+
|
|
31
|
+
export const AAVE_V4_TOKENIZED_SPOKES: Record<string, EthAddress> = {
|
|
32
|
+
AAVE_CORE: '0x08309234884cF7E015b07Bf22569017Aa035cdeF',
|
|
33
|
+
EURC_CORE: '0x73596dED4B2Eb0aC85e477b3c8dB56FC427E6774',
|
|
34
|
+
GHO_CORE: '0xf7E1f1b43922527e5054bD77E7f863Cf182b194D',
|
|
35
|
+
GHO_PRIME: '0xeF1cAd5c6a2C9cb83c952b4B96bbD35b3F61F18f',
|
|
36
|
+
LBTC_CORE: '0x8f4D423590F22833131e3493bf67A27213398f8e',
|
|
37
|
+
LINK_CORE: '0xBE1197750b423e30137E97d9183065d33E903BE6',
|
|
38
|
+
PT_USDe_PLUS: '0x8cA27Ab284F2aA2BcF33D9129e11c101aD2d16de',
|
|
39
|
+
PT_sUSDe_PLUS: '0xb8A464EC56071a98c854f30fE19CfeCc41FA6233',
|
|
40
|
+
PYUSD_CORE: '0x203FB463087005698d50768FcA837047f738632d',
|
|
41
|
+
RLUSD_CORE: '0xa9afdd0c54fb153CaE39cE86E49626B5e9d15513',
|
|
42
|
+
USDC_CORE: '0xa2e476f4cbB06C7bFA8Ad51bCcbF198cd32CfD35',
|
|
43
|
+
USDC_PLUS: '0x320Bec4fB7a25e64c003A007D0AeF7AB3D6C30d7',
|
|
44
|
+
USDC_PRIME: '0x0A0507F7A1129892b5cf74b8B4e911442c466b87',
|
|
45
|
+
USDG_CORE: '0x87c224256f09a014C1BC3e9FbB094C3AdD8fBaCC',
|
|
46
|
+
USDT_CORE: '0x3f12BD5999b9172550893FF52691c980676f9E73',
|
|
47
|
+
USDT_PLUS: '0xa4E74a78bED2d3ab8971e8AB26fb39f26DD8eEd9',
|
|
48
|
+
USDT_PRIME: '0xF565fB55bc96d65561887898bfeb25C1dE7e06d2',
|
|
49
|
+
USDe_PLUS: '0xA0d346ab2699B689AC67aba5174164A84206BB73',
|
|
50
|
+
WBTC_CORE: '0x837Ab872A665e0CF467d41cF56a054031b4A38bc',
|
|
51
|
+
WBTC_PRIME: '0xeae98b8a1798738182B2123DF1eB93d97BD29F34',
|
|
52
|
+
WETH_CORE: '0x3961a75099E986F59a1a31c6f945061641dFD2b2',
|
|
53
|
+
WETH_PRIME: '0xa411826a6ef5d289c0FAa7d5B45FE8aAB52257F6',
|
|
54
|
+
XAUt_CORE: '0x470341bC0e2B833C54D0120642713BdF762A494F',
|
|
55
|
+
cbBTC_CORE: '0xe8D5E595d5b6b5EFf84B7064765fd0e8DfD214C9',
|
|
56
|
+
cbBTC_PRIME: '0x0E986545150DcDDe46Ea9df355D0fD2af33bd75D',
|
|
57
|
+
frxUSD_CORE: '0x00C8A6a42947Cc4E7B6f27963Cab0143ccaaD2B5',
|
|
58
|
+
frxUSD_PLUS: '0xCAB288d37CAb5a9db7b503F086455276Dcde61F1',
|
|
59
|
+
rsETH_CORE: '0x6eEce89caE2163584bA7Ff9743861B9633c245E0',
|
|
60
|
+
sUSDe_PLUS: '0xdf47fc43c88B06edC47753b7d647ff18037D2F3d',
|
|
61
|
+
weETH_CORE: '0xB67F20bFF413C8E5d633B54BD28899c4c9e33ed0',
|
|
62
|
+
wstETH_CORE: '0x474602394d0B02F43AC3D7C8c5cFc0814b03fd40',
|
|
63
|
+
wstETH_PRIME: '0xAcCdAb49ECB9A801CfF62a92fc80D52339b33770',
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const AAVE_V4_TOKENIZED_SPOKE_ADDRESSES: Partial<Record<NetworkNumber, EthAddress[]>> = {
|
|
67
|
+
[NetworkNumber.Eth]: Object.values(AAVE_V4_TOKENIZED_SPOKES),
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export type AaveV4TokenizedHubKey = 'CORE' | 'PLUS' | 'PRIME';
|
|
71
|
+
|
|
72
|
+
export const aaveV4GetTokenizedHubKey = (hubNameOrKey?: string | null): AaveV4TokenizedHubKey | null => {
|
|
73
|
+
if (!hubNameOrKey) return null;
|
|
74
|
+
const normalized = hubNameOrKey.trim().toUpperCase();
|
|
75
|
+
|
|
76
|
+
// TODO AaveV4 Maybe turn into constants
|
|
77
|
+
if (normalized === 'CORE' || normalized === 'CORE HUB') return 'CORE';
|
|
78
|
+
if (normalized === 'PLUS' || normalized === 'PLUS HUB') return 'PLUS';
|
|
79
|
+
if (normalized === 'PRIME' || normalized === 'PRIME HUB') return 'PRIME';
|
|
80
|
+
|
|
81
|
+
if (normalized.includes('CORE')) return 'CORE';
|
|
82
|
+
if (normalized.includes('PLUS')) return 'PLUS';
|
|
83
|
+
if (normalized.includes('PRIME')) return 'PRIME';
|
|
84
|
+
|
|
85
|
+
return null;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export const aaveV4GetTokenizedVaultKey = (
|
|
89
|
+
symbol: string,
|
|
90
|
+
hubNameOrKey?: string | null,
|
|
91
|
+
): string | null => {
|
|
92
|
+
if (!symbol) return null;
|
|
93
|
+
const hubKey = aaveV4GetTokenizedHubKey(hubNameOrKey);
|
|
94
|
+
if (!hubKey) return null;
|
|
95
|
+
|
|
96
|
+
const normalizedSymbol = symbol.trim().replace(/-/g, '_');
|
|
97
|
+
|
|
98
|
+
return `${normalizedSymbol}_${hubKey}`;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export const aaveV4GetTokenizedVaultAddress = (
|
|
102
|
+
network: NetworkNumber,
|
|
103
|
+
symbol: string,
|
|
104
|
+
hubNameOrKey?: string | null,
|
|
105
|
+
): EthAddress | undefined => {
|
|
106
|
+
if (network !== NetworkNumber.Eth) return undefined;
|
|
107
|
+
const key = aaveV4GetTokenizedVaultKey(symbol, hubNameOrKey);
|
|
108
|
+
if (!key) return undefined;
|
|
109
|
+
return AAVE_V4_TOKENIZED_SPOKES[key];
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
/** Parsed tokenization spoke data with human-readable supplied amounts for display */
|
|
113
|
+
export interface AaveV4TokenizationSpokeDataParsed {
|
|
114
|
+
vaultAddress: EthAddress;
|
|
115
|
+
key: string | null;
|
|
116
|
+
symbol: string;
|
|
117
|
+
hubKey: string;
|
|
118
|
+
userSuppliedAssetsEth: string;
|
|
119
|
+
userSuppliedSharesEth: string;
|
|
120
|
+
userSuppliedAssets: string;
|
|
121
|
+
userSuppliedShares: string;
|
|
122
|
+
underlyingAsset: EthAddress;
|
|
123
|
+
spoke: EthAddress;
|
|
124
|
+
decimals: number;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const AAVE_V4_TOKENIZED_SPOKE_ADDRESS_TO_KEY: Record<string, string> = Object.entries(
|
|
128
|
+
AAVE_V4_TOKENIZED_SPOKES,
|
|
129
|
+
).reduce((acc, [k, v]) => {
|
|
130
|
+
acc[v.toLowerCase()] = k;
|
|
131
|
+
return acc;
|
|
132
|
+
}, {} as Record<string, string>);
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Fetches tokenization vault data for the given user via getTokenizationSpokesData.
|
|
136
|
+
* Returns parsed data including userSuppliedAssets in human-readable form for each vault.
|
|
137
|
+
*/
|
|
138
|
+
export async function getAaveV4TokenizationSpokesData(
|
|
139
|
+
provider: EthereumProvider,
|
|
140
|
+
network: NetworkNumber,
|
|
141
|
+
userAddress: EthAddress,
|
|
142
|
+
): Promise<AaveV4TokenizationSpokeDataParsed[]> {
|
|
143
|
+
const spokes = AAVE_V4_TOKENIZED_SPOKE_ADDRESSES[network] ?? [];
|
|
144
|
+
if (spokes.length === 0) return [];
|
|
145
|
+
|
|
146
|
+
const client = getViemProvider(provider, network);
|
|
147
|
+
const viewContract = AaveV4ViewContractViem(client, network);
|
|
148
|
+
const raw = await viewContract.read.getTokenizationSpokesData([spokes, userAddress]);
|
|
149
|
+
|
|
150
|
+
return raw.map((r: any, i: number) => {
|
|
151
|
+
const vaultAddress = spokes[i];
|
|
152
|
+
const key = AAVE_V4_TOKENIZED_SPOKE_ADDRESS_TO_KEY[vaultAddress.toLowerCase()] ?? null;
|
|
153
|
+
const symbol = wethToEth(getAssetInfoByAddress(r.underlyingAsset, network).symbol);
|
|
154
|
+
if (symbol === '?') { // unsupported asset
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
const hubKey = key ? key.split('_').pop() ?? '' : '';
|
|
158
|
+
const decimals = Number(r.decimals ?? 18);
|
|
159
|
+
const userSuppliedAssetsRaw = r.userSuppliedAssets ?? 0;
|
|
160
|
+
const userSuppliedSharesRaw = r.userSuppliedShares ?? 0;
|
|
161
|
+
|
|
162
|
+
const userSuppliedAssetsEth = assetAmountInEth(userSuppliedAssetsRaw.toString(), symbol);
|
|
163
|
+
const userSuppliedSharesEth = assetAmountInEth(userSuppliedSharesRaw.toString(), symbol);
|
|
164
|
+
return {
|
|
165
|
+
vaultAddress,
|
|
166
|
+
key,
|
|
167
|
+
symbol,
|
|
168
|
+
hubKey,
|
|
169
|
+
userSuppliedAssetsEth,
|
|
170
|
+
userSuppliedSharesEth,
|
|
171
|
+
userSuppliedAssets: userSuppliedAssetsRaw.toString(),
|
|
172
|
+
userSuppliedShares: userSuppliedSharesRaw.toString(),
|
|
173
|
+
underlyingAsset: r.underlyingAsset,
|
|
174
|
+
spoke: r.spoke,
|
|
175
|
+
decimals,
|
|
176
|
+
};
|
|
177
|
+
}).filter(item => item != null);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import Dec from 'decimal.js';
|
|
2
2
|
import { calcLeverageLiqPrice, getAssetsTotal, STABLE_ASSETS } from '../../moneymarket';
|
|
3
3
|
import {
|
|
4
|
-
AaveV4AggregatedPositionData,
|
|
4
|
+
AaveV4AggregatedPositionData,
|
|
5
|
+
AaveV4AssetsData,
|
|
6
|
+
AaveV4ReserveAssetData,
|
|
7
|
+
AaveV4UsedReserveAsset,
|
|
8
|
+
AaveV4UsedReserveAssets,
|
|
9
|
+
LeverageType,
|
|
10
|
+
NetworkNumber,
|
|
5
11
|
} from '../../types';
|
|
6
|
-
import { LeverageType, NetworkNumber } from '../../types/common';
|
|
7
12
|
|
|
8
13
|
export const aaveV4GetCollateralFactor = (assetData: AaveV4ReserveAssetData, usedAssetData: AaveV4UsedReserveAsset, useUserCollateralFactor: boolean = false): number => (useUserCollateralFactor ? usedAssetData.collateralFactor : assetData.collateralFactor);
|
|
9
14
|
|
|
@@ -61,7 +61,7 @@ export const AAVE_V4_ETHENA_SPOKE = (networkId: NetworkNumber): AaveV4SpokeInfo
|
|
|
61
61
|
label: 'Ethena Spoke',
|
|
62
62
|
value: AaveV4SpokesType.AaveV4EthenaSpoke,
|
|
63
63
|
url: 'ethena',
|
|
64
|
-
address: '
|
|
64
|
+
address: '0xf3b207c235f6154120F41eB63D5ACCBAfD4086D1',
|
|
65
65
|
hubs: [
|
|
66
66
|
AAVE_V4_CORE_HUB(NetworkNumber.Eth).address,
|
|
67
67
|
AAVE_V4_PLUS_HUB(NetworkNumber.Eth).address,
|
package/src/types/aaveV4.ts
CHANGED
|
@@ -28,6 +28,12 @@ export interface AaveV4HubInfo {
|
|
|
28
28
|
export interface AaveV4HubAssetOnChainData {
|
|
29
29
|
assetId: number,
|
|
30
30
|
drawnRate: bigint,
|
|
31
|
+
liquidity: bigint,
|
|
32
|
+
liquidityFee: number,
|
|
33
|
+
swept: bigint,
|
|
34
|
+
totalDrawn: bigint,
|
|
35
|
+
totalDrawnShares: bigint,
|
|
36
|
+
totalPremiumShares: bigint,
|
|
31
37
|
}
|
|
32
38
|
|
|
33
39
|
export interface AaveV4HubOnChainData {
|
|
@@ -98,6 +104,7 @@ export interface AaveV4ReserveAssetData {
|
|
|
98
104
|
spokeHalted: boolean,
|
|
99
105
|
drawnRate: string,
|
|
100
106
|
supplyRate: string,
|
|
107
|
+
borrowRate: string,
|
|
101
108
|
supplyIncentives: IncentiveData[];
|
|
102
109
|
borrowIncentives: IncentiveData[];
|
|
103
110
|
canBeBorrowed: boolean;
|
|
@@ -158,4 +165,5 @@ export type AaveV4UsedReserveAssets = Record<string, AaveV4UsedReserveAsset>;
|
|
|
158
165
|
export interface AaveV4AccountData extends AaveV4AggregatedPositionData {
|
|
159
166
|
usedAssets: AaveV4UsedReserveAssets,
|
|
160
167
|
healthFactor: string,
|
|
168
|
+
riskPremiumBps: number,
|
|
161
169
|
}
|