@1delta/margin-fetcher 0.0.13 → 0.0.15
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/dist/lending/morpho/convertPublic.js +2 -2
- package/dist/lending/user-data/fetchUserData.js +1 -1
- package/dist/lending/user-data/morpho/userCallParse.d.ts +2 -2
- package/dist/lending/user-data/morpho/userCallParse.d.ts.map +1 -1
- package/dist/lending/user-data/morpho/userCallParse.js +32 -26
- package/package.json +1 -1
- package/src/lending/morpho/convertPublic.ts +2 -2
- package/src/lending/user-data/fetchUserData.ts +1 -1
- package/src/lending/user-data/morpho/userCallParse.ts +76 -56
- package/test/userDataMorpho.test.ts +1 -0
- package/test/userdata.test.ts +134 -111
|
@@ -108,8 +108,8 @@ export function convertMarketsToMorphoResponse(response, chainId, additionalYiel
|
|
|
108
108
|
lltv,
|
|
109
109
|
oracle: oracleAddress,
|
|
110
110
|
irm: irmAddress,
|
|
111
|
-
collateralAddress:
|
|
112
|
-
loanAddress:
|
|
111
|
+
collateralAddress: collateralAssetAddress,
|
|
112
|
+
loanAddress: loanAssetAddress,
|
|
113
113
|
},
|
|
114
114
|
};
|
|
115
115
|
data[m].chainId = chainId;
|
|
@@ -35,7 +35,7 @@ function getUserDataConverter(lender, chainId, account, prices, pricesHist, lend
|
|
|
35
35
|
return getInitUserDataConverter(lender, chainId, account, prices, pricesHist, lenderPublicState?.data?.[lender]?.data);
|
|
36
36
|
if (isMorphoType(lender))
|
|
37
37
|
return getMorphoUserDataConverterWithlens(lender, chainId, account, params, prices, pricesHist, lenderPublicState?.data);
|
|
38
|
-
return getCompoundV3UserDataConverter(lender, chainId, account, prices, pricesHist, lenderPublicState);
|
|
38
|
+
return getCompoundV3UserDataConverter(lender, chainId, account, prices, pricesHist, lenderPublicState?.data?.[lender]?.data);
|
|
39
39
|
}
|
|
40
40
|
/**
|
|
41
41
|
* Builds the multicall calls for the given queries and returns the raw results
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Lender } from
|
|
2
|
-
import { MorphoUserReserveResponse } from
|
|
1
|
+
import { Lender } from '@1delta/asset-registry';
|
|
2
|
+
import { MorphoUserReserveResponse } from '../types';
|
|
3
3
|
export declare const getMorphoUserDataConverterWithlens: (lender: Lender, chainId: string, account: string, markets: string[], prices: {
|
|
4
4
|
[asset: string]: number;
|
|
5
5
|
}, pricesHist: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userCallParse.d.ts","sourceRoot":"","sources":["../../../../src/lending/user-data/morpho/userCallParse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAE/C,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAA;AAMpD,eAAO,MAAM,kCAAkC,GAC7C,QAAQ,MAAM,EACd,SAAS,MAAM,EACf,SAAS,MAAM,EACf,SAAS,MAAM,EAAE,EACjB,QAAQ;IAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,EACnC,YAAY;IAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,EACvC,YAAY,GAAG,KACd,
|
|
1
|
+
{"version":3,"file":"userCallParse.d.ts","sourceRoot":"","sources":["../../../../src/lending/user-data/morpho/userCallParse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAE/C,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAA;AAMpD,eAAO,MAAM,kCAAkC,GAC7C,QAAQ,MAAM,EACd,SAAS,MAAM,EACf,SAAS,MAAM,EACf,SAAS,MAAM,EAAE,EACjB,QAAQ;IAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,EACnC,YAAY;IAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,EACvC,YAAY,GAAG,KACd,CACD,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK;IAAE,CAAC,MAAM,EAAE,MAAM,GAAG,yBAAyB,CAAA;CAAE,GAAG,SAAS,EAC5E,MAAM,CAwDP,CAAA"}
|
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
import { getAssetMeta, toGenericPriceKey, toOracleKey } from
|
|
2
|
-
import { createBaseTypeUserState } from
|
|
3
|
-
import { parseRawAmount } from
|
|
4
|
-
import { decodePackedDataset } from
|
|
1
|
+
import { getAssetMeta, toGenericPriceKey, toOracleKey } from '../../../assets';
|
|
2
|
+
import { createBaseTypeUserState } from '../utils';
|
|
3
|
+
import { parseRawAmount } from '../../../utils/parsing';
|
|
4
|
+
import { decodePackedDataset } from './decoder';
|
|
5
5
|
export const getMorphoUserDataConverterWithlens = (lender, chainId, account, markets, prices, pricesHist, lenderData) => {
|
|
6
|
-
const expectedNumberOfCalls = markets.length
|
|
6
|
+
const expectedNumberOfCalls = Math.ceil(markets.length / 100);
|
|
7
7
|
return [
|
|
8
8
|
(data) => {
|
|
9
9
|
// chunksizes depend on markets
|
|
10
|
-
|
|
11
|
-
if (data.length !== slices) {
|
|
10
|
+
if (data.length !== expectedNumberOfCalls) {
|
|
12
11
|
return undefined;
|
|
13
12
|
}
|
|
14
13
|
// de-chunk the calldata
|
|
15
|
-
const returnDatas = data.flatMap(d => decodePackedDataset(d));
|
|
14
|
+
const returnDatas = data.flatMap((d) => decodePackedDataset(d));
|
|
16
15
|
let datas = {};
|
|
17
16
|
for (let i = 0; i < returnDatas.length; i++) {
|
|
18
17
|
let totalDebt24h = 0;
|
|
@@ -20,15 +19,13 @@ export const getMorphoUserDataConverterWithlens = (lender, chainId, account, mar
|
|
|
20
19
|
const balanceData = returnDatas[i];
|
|
21
20
|
const markeId = markets[balanceData.index];
|
|
22
21
|
const market = lenderData[markeId]?.params?.market;
|
|
23
|
-
const { dataForMarket, addedDebt, addedDeposits } = createMorphoEntryFromMarketWithLens(
|
|
24
|
-
if (!dataForMarket)
|
|
25
|
-
continue;
|
|
22
|
+
const { dataForMarket, addedDebt, addedDeposits } = createMorphoEntryFromMarketWithLens(balanceData, chainId, market, prices, pricesHist);
|
|
26
23
|
totalDebt24h += addedDebt;
|
|
27
24
|
totalDeposits24h += addedDeposits;
|
|
28
25
|
const payload = {
|
|
29
26
|
chainId,
|
|
30
27
|
account,
|
|
31
|
-
lendingPositions: {
|
|
28
|
+
lendingPositions: { '0': dataForMarket },
|
|
32
29
|
rewards: {},
|
|
33
30
|
userEMode: 0,
|
|
34
31
|
};
|
|
@@ -36,7 +33,7 @@ export const getMorphoUserDataConverterWithlens = (lender, chainId, account, mar
|
|
|
36
33
|
datas[market.lender] = {
|
|
37
34
|
...payload,
|
|
38
35
|
...userData,
|
|
39
|
-
id: market.id
|
|
36
|
+
id: market.id,
|
|
40
37
|
};
|
|
41
38
|
}
|
|
42
39
|
return datas;
|
|
@@ -44,7 +41,7 @@ export const getMorphoUserDataConverterWithlens = (lender, chainId, account, mar
|
|
|
44
41
|
expectedNumberOfCalls,
|
|
45
42
|
];
|
|
46
43
|
};
|
|
47
|
-
function createMorphoEntryFromMarketWithLens(
|
|
44
|
+
function createMorphoEntryFromMarketWithLens(balanceInfo, chainId, market, prices, pricesHist) {
|
|
48
45
|
const loanAddress = market.loanAddress.toLowerCase();
|
|
49
46
|
const loanMeta = getAssetMeta(chainId, loanAddress);
|
|
50
47
|
const loanKey = toOracleKey(loanMeta?.assetGroup) ?? toGenericPriceKey(loanAddress, chainId);
|
|
@@ -53,27 +50,36 @@ function createMorphoEntryFromMarketWithLens(i, balanceInfo, chainId, market, pr
|
|
|
53
50
|
const priceHistLoan = pricesHist?.[loanKey] ?? priceLoan;
|
|
54
51
|
const deposits = balanceInfo.supplyAssets;
|
|
55
52
|
const borrow = balanceInfo.borrowAssets;
|
|
53
|
+
const collateral = balanceInfo.collateral;
|
|
54
|
+
// return early if there are zeros
|
|
55
|
+
if (deposits === 0n && borrow === 0n && collateral === 0n)
|
|
56
|
+
return {
|
|
57
|
+
dataForMarket: {},
|
|
58
|
+
addedDeposits: 0,
|
|
59
|
+
addedDebt: 0,
|
|
60
|
+
};
|
|
61
|
+
const collateralAddress = market.collateralAddress.toLowerCase();
|
|
62
|
+
const assetMeta = getAssetMeta(chainId, collateralAddress);
|
|
63
|
+
const decimals = market.collateralDecimals ?? assetMeta?.decimals ?? 18;
|
|
56
64
|
const depositDec = parseRawAmount(deposits.toString(), market.loanDecimals ?? loanMeta?.decimals ?? 18);
|
|
65
|
+
const collateralDec = parseRawAmount(collateral.toString(), decimals);
|
|
57
66
|
const borrowDec = parseRawAmount(borrow.toString(), market.loanDecimals ?? loanMeta?.decimals ?? 18);
|
|
58
67
|
const dataForLoanAsset = {
|
|
59
68
|
poolId: loanAddress,
|
|
60
69
|
underlying: loanAddress,
|
|
61
70
|
deposits: parseRawAmount(deposits.toString(), market.loanDecimals ?? loanMeta?.decimals ?? 18),
|
|
62
71
|
depositsRaw: deposits.toString(),
|
|
63
|
-
debtStable:
|
|
72
|
+
debtStable: '0',
|
|
64
73
|
debt: borrowDec,
|
|
65
74
|
depositsUSD: Number(depositDec) * priceLoan,
|
|
66
75
|
debtStableUSD: 0,
|
|
67
76
|
debtUSD: Number(borrowDec) * priceLoan,
|
|
68
|
-
stableBorrowRate:
|
|
77
|
+
stableBorrowRate: '0',
|
|
69
78
|
collateralActive: true,
|
|
70
79
|
claimableRewards: 0,
|
|
71
80
|
};
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
const decimals = market.collateralDecimals ?? assetMeta?.decimals ?? 18;
|
|
75
|
-
const collateralDec = parseRawAmount(balanceInfo.collateral.toString(), decimals);
|
|
76
|
-
const key = toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(collateralAddress, chainId);
|
|
81
|
+
const key = toOracleKey(assetMeta?.assetGroup) ??
|
|
82
|
+
toGenericPriceKey(collateralAddress, chainId);
|
|
77
83
|
// prices
|
|
78
84
|
const price = prices[key] ?? 1;
|
|
79
85
|
const priceHist = pricesHist?.[key] ?? price;
|
|
@@ -82,21 +88,21 @@ function createMorphoEntryFromMarketWithLens(i, balanceInfo, chainId, market, pr
|
|
|
82
88
|
underlying: collateralAddress,
|
|
83
89
|
deposits: collateralDec,
|
|
84
90
|
depositsRaw: balanceInfo.collateral.toString(),
|
|
85
|
-
debtStable:
|
|
86
|
-
debt:
|
|
91
|
+
debtStable: '0',
|
|
92
|
+
debt: '0',
|
|
87
93
|
depositsUSD: Number(collateralDec) * price,
|
|
88
94
|
debtStableUSD: 0,
|
|
89
95
|
debtUSD: 0,
|
|
90
|
-
stableBorrowRate:
|
|
96
|
+
stableBorrowRate: '0',
|
|
91
97
|
collateralActive: true,
|
|
92
98
|
claimableRewards: 0,
|
|
93
99
|
};
|
|
94
100
|
return {
|
|
95
101
|
dataForMarket: {
|
|
96
102
|
[loanAddress]: dataForLoanAsset,
|
|
97
|
-
[collateralAddress]: dataForCollateralAsset
|
|
103
|
+
[collateralAddress]: dataForCollateralAsset,
|
|
98
104
|
},
|
|
99
105
|
addedDeposits: Number(depositDec) * priceHistLoan + Number(collateralDec) * priceHist,
|
|
100
|
-
addedDebt: Number(borrowDec) * priceHistLoan
|
|
106
|
+
addedDebt: Number(borrowDec) * priceHistLoan,
|
|
101
107
|
};
|
|
102
108
|
}
|
package/package.json
CHANGED
|
@@ -141,8 +141,8 @@ export function convertMarketsToMorphoResponse(
|
|
|
141
141
|
lltv,
|
|
142
142
|
oracle: oracleAddress,
|
|
143
143
|
irm: irmAddress,
|
|
144
|
-
collateralAddress:
|
|
145
|
-
loanAddress:
|
|
144
|
+
collateralAddress: collateralAssetAddress,
|
|
145
|
+
loanAddress: loanAssetAddress,
|
|
146
146
|
},
|
|
147
147
|
}
|
|
148
148
|
data[m].chainId = chainId
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Lender } from
|
|
2
|
-
import { getAssetMeta, toGenericPriceKey, toOracleKey } from
|
|
3
|
-
import { MorphoUserReserveResponse } from
|
|
4
|
-
import { createBaseTypeUserState } from
|
|
5
|
-
import { parseRawAmount } from
|
|
6
|
-
import { MorphoMarket } from
|
|
7
|
-
import { BalanceInfo, decodePackedDataset } from
|
|
1
|
+
import { Lender } from '@1delta/asset-registry'
|
|
2
|
+
import { getAssetMeta, toGenericPriceKey, toOracleKey } from '../../../assets'
|
|
3
|
+
import { MorphoUserReserveResponse } from '../types'
|
|
4
|
+
import { createBaseTypeUserState } from '../utils'
|
|
5
|
+
import { parseRawAmount } from '../../../utils/parsing'
|
|
6
|
+
import { MorphoMarket } from '../../morpho/types'
|
|
7
|
+
import { BalanceInfo, decodePackedDataset } from './decoder'
|
|
8
8
|
|
|
9
9
|
export const getMorphoUserDataConverterWithlens = (
|
|
10
10
|
lender: Lender,
|
|
@@ -13,41 +13,36 @@ export const getMorphoUserDataConverterWithlens = (
|
|
|
13
13
|
markets: string[],
|
|
14
14
|
prices: { [asset: string]: number },
|
|
15
15
|
pricesHist: { [asset: string]: number },
|
|
16
|
-
lenderData: any
|
|
17
|
-
): [
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
lenderData: any,
|
|
17
|
+
): [
|
|
18
|
+
(data: any[]) => { [market: string]: MorphoUserReserveResponse } | undefined,
|
|
19
|
+
number,
|
|
20
|
+
] => {
|
|
21
|
+
const expectedNumberOfCalls = Math.ceil(markets.length / 100)
|
|
20
22
|
return [
|
|
21
23
|
(data: any[]) => {
|
|
22
24
|
// chunksizes depend on markets
|
|
23
|
-
|
|
24
|
-
if (data.length !== slices) {
|
|
25
|
+
if (data.length !== expectedNumberOfCalls) {
|
|
25
26
|
return undefined
|
|
26
27
|
}
|
|
27
28
|
// de-chunk the calldata
|
|
28
|
-
const returnDatas = data.flatMap(d => decodePackedDataset(d))
|
|
29
|
+
const returnDatas = data.flatMap((d) => decodePackedDataset(d))
|
|
29
30
|
|
|
30
31
|
let datas: { [market: string]: MorphoUserReserveResponse } = {}
|
|
31
32
|
for (let i = 0; i < returnDatas.length; i++) {
|
|
32
|
-
|
|
33
33
|
let totalDebt24h = 0
|
|
34
34
|
let totalDeposits24h = 0
|
|
35
35
|
const balanceData = returnDatas[i]
|
|
36
36
|
const markeId = markets[balanceData.index]
|
|
37
37
|
const market = lenderData[markeId]?.params?.market
|
|
38
|
-
const {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
market,
|
|
47
|
-
prices,
|
|
48
|
-
pricesHist,
|
|
49
|
-
)
|
|
50
|
-
if (!dataForMarket) continue;
|
|
38
|
+
const { dataForMarket, addedDebt, addedDeposits } =
|
|
39
|
+
createMorphoEntryFromMarketWithLens(
|
|
40
|
+
balanceData,
|
|
41
|
+
chainId,
|
|
42
|
+
market,
|
|
43
|
+
prices,
|
|
44
|
+
pricesHist,
|
|
45
|
+
)
|
|
51
46
|
|
|
52
47
|
totalDebt24h += addedDebt
|
|
53
48
|
totalDeposits24h += addedDeposits
|
|
@@ -55,19 +50,23 @@ export const getMorphoUserDataConverterWithlens = (
|
|
|
55
50
|
const payload = {
|
|
56
51
|
chainId,
|
|
57
52
|
account,
|
|
58
|
-
lendingPositions: {
|
|
53
|
+
lendingPositions: { '0': dataForMarket },
|
|
59
54
|
rewards: {},
|
|
60
|
-
userEMode
|
|
55
|
+
userEMode: 0,
|
|
61
56
|
}
|
|
62
57
|
|
|
63
|
-
const userData = createBaseTypeUserState(
|
|
58
|
+
const userData = createBaseTypeUserState(
|
|
59
|
+
payload,
|
|
60
|
+
lenderData[markeId].data,
|
|
61
|
+
totalDeposits24h,
|
|
62
|
+
totalDebt24h,
|
|
63
|
+
)
|
|
64
64
|
|
|
65
65
|
datas[market.lender] = {
|
|
66
66
|
...payload,
|
|
67
67
|
...userData,
|
|
68
|
-
id: market.id
|
|
68
|
+
id: market.id,
|
|
69
69
|
}
|
|
70
|
-
|
|
71
70
|
}
|
|
72
71
|
return datas
|
|
73
72
|
},
|
|
@@ -76,50 +75,70 @@ export const getMorphoUserDataConverterWithlens = (
|
|
|
76
75
|
}
|
|
77
76
|
|
|
78
77
|
function createMorphoEntryFromMarketWithLens(
|
|
79
|
-
i: number,
|
|
80
78
|
balanceInfo: BalanceInfo,
|
|
81
79
|
chainId: string,
|
|
82
80
|
market: MorphoMarket,
|
|
83
81
|
prices: any,
|
|
84
82
|
pricesHist: any,
|
|
85
83
|
) {
|
|
86
|
-
|
|
87
84
|
const loanAddress = market.loanAddress.toLowerCase()
|
|
88
85
|
const loanMeta = getAssetMeta(chainId, loanAddress)
|
|
89
86
|
|
|
90
|
-
const loanKey =
|
|
87
|
+
const loanKey =
|
|
88
|
+
toOracleKey(loanMeta?.assetGroup) ?? toGenericPriceKey(loanAddress, chainId)
|
|
91
89
|
// prices
|
|
92
90
|
const priceLoan = prices[loanKey] ?? 1
|
|
93
91
|
const priceHistLoan = pricesHist?.[loanKey] ?? priceLoan
|
|
94
92
|
|
|
95
93
|
const deposits = balanceInfo.supplyAssets
|
|
96
94
|
const borrow = balanceInfo.borrowAssets
|
|
97
|
-
const
|
|
98
|
-
|
|
95
|
+
const collateral = balanceInfo.collateral
|
|
96
|
+
|
|
97
|
+
// return early if there are zeros
|
|
98
|
+
if (deposits === 0n && borrow === 0n && collateral === 0n)
|
|
99
|
+
return {
|
|
100
|
+
dataForMarket: {},
|
|
101
|
+
addedDeposits: 0,
|
|
102
|
+
addedDebt: 0,
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const collateralAddress = market.collateralAddress.toLowerCase()
|
|
106
|
+
const assetMeta = getAssetMeta(chainId, collateralAddress)
|
|
107
|
+
|
|
108
|
+
const decimals = market.collateralDecimals ?? assetMeta?.decimals ?? 18
|
|
109
|
+
|
|
110
|
+
const depositDec = parseRawAmount(
|
|
111
|
+
deposits.toString(),
|
|
112
|
+
market.loanDecimals ?? loanMeta?.decimals ?? 18,
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
const collateralDec = parseRawAmount(collateral.toString(), decimals)
|
|
116
|
+
const borrowDec = parseRawAmount(
|
|
117
|
+
borrow.toString(),
|
|
118
|
+
market.loanDecimals ?? loanMeta?.decimals ?? 18,
|
|
119
|
+
)
|
|
99
120
|
|
|
100
121
|
const dataForLoanAsset = {
|
|
101
122
|
poolId: loanAddress,
|
|
102
123
|
underlying: loanAddress,
|
|
103
|
-
deposits: parseRawAmount(
|
|
124
|
+
deposits: parseRawAmount(
|
|
125
|
+
deposits.toString(),
|
|
126
|
+
market.loanDecimals ?? loanMeta?.decimals ?? 18,
|
|
127
|
+
),
|
|
104
128
|
depositsRaw: deposits.toString(),
|
|
105
|
-
debtStable:
|
|
129
|
+
debtStable: '0',
|
|
106
130
|
debt: borrowDec,
|
|
107
131
|
depositsUSD: Number(depositDec) * priceLoan,
|
|
108
132
|
debtStableUSD: 0,
|
|
109
133
|
debtUSD: Number(borrowDec) * priceLoan,
|
|
110
|
-
stableBorrowRate:
|
|
134
|
+
stableBorrowRate: '0',
|
|
111
135
|
collateralActive: true,
|
|
112
136
|
claimableRewards: 0,
|
|
113
137
|
}
|
|
114
138
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
const decimals = market.collateralDecimals ?? assetMeta?.decimals ?? 18
|
|
119
|
-
|
|
120
|
-
const collateralDec = parseRawAmount(balanceInfo.collateral.toString(), decimals)
|
|
121
|
-
|
|
122
|
-
const key = toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(collateralAddress, chainId)
|
|
139
|
+
const key =
|
|
140
|
+
toOracleKey(assetMeta?.assetGroup) ??
|
|
141
|
+
toGenericPriceKey(collateralAddress, chainId)
|
|
123
142
|
// prices
|
|
124
143
|
const price = prices[key] ?? 1
|
|
125
144
|
const priceHist = pricesHist?.[key] ?? price
|
|
@@ -129,12 +148,12 @@ function createMorphoEntryFromMarketWithLens(
|
|
|
129
148
|
underlying: collateralAddress,
|
|
130
149
|
deposits: collateralDec,
|
|
131
150
|
depositsRaw: balanceInfo.collateral.toString(),
|
|
132
|
-
debtStable:
|
|
133
|
-
debt:
|
|
151
|
+
debtStable: '0',
|
|
152
|
+
debt: '0',
|
|
134
153
|
depositsUSD: Number(collateralDec) * price,
|
|
135
154
|
debtStableUSD: 0,
|
|
136
155
|
debtUSD: 0,
|
|
137
|
-
stableBorrowRate:
|
|
156
|
+
stableBorrowRate: '0',
|
|
138
157
|
collateralActive: true,
|
|
139
158
|
claimableRewards: 0,
|
|
140
159
|
}
|
|
@@ -142,9 +161,10 @@ function createMorphoEntryFromMarketWithLens(
|
|
|
142
161
|
return {
|
|
143
162
|
dataForMarket: {
|
|
144
163
|
[loanAddress]: dataForLoanAsset,
|
|
145
|
-
[collateralAddress]: dataForCollateralAsset
|
|
164
|
+
[collateralAddress]: dataForCollateralAsset,
|
|
146
165
|
},
|
|
147
|
-
addedDeposits:
|
|
148
|
-
|
|
166
|
+
addedDeposits:
|
|
167
|
+
Number(depositDec) * priceHistLoan + Number(collateralDec) * priceHist,
|
|
168
|
+
addedDebt: Number(borrowDec) * priceHistLoan,
|
|
149
169
|
}
|
|
150
|
-
}
|
|
170
|
+
}
|
|
@@ -61,6 +61,7 @@ describe(
|
|
|
61
61
|
try {
|
|
62
62
|
const { userData } = await getUserData(Chain.BASE, [
|
|
63
63
|
'MORPHO_BLUE_6600AAE6C56D242FA6BA68BD527AFF1A146E77813074413186828FD3F1CDCA91',
|
|
64
|
+
'MORPHO_BLUE_3A4048C64BA1B375330D376B1CE40E4047D03B47AB4D48AF484EDEC9FEC801BA',
|
|
64
65
|
])
|
|
65
66
|
|
|
66
67
|
prettyPrint(userData)
|
package/test/userdata.test.ts
CHANGED
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
import { describe, it, expect, beforeAll } from
|
|
1
|
+
import { describe, it, expect, beforeAll } from 'vitest'
|
|
2
2
|
import {
|
|
3
3
|
getLenderUserDataResult,
|
|
4
4
|
convertLenderUserDataResult,
|
|
5
|
-
} from
|
|
5
|
+
} from '../src/lending/user-data/fetchUserData'
|
|
6
6
|
import {
|
|
7
7
|
fetchGeneralYields,
|
|
8
8
|
fetchMainPrices,
|
|
9
9
|
getLenderPublicData,
|
|
10
|
-
} from
|
|
11
|
-
import { multicallRetry, getEvmClient } from
|
|
12
|
-
import { Chain, Lender } from
|
|
13
|
-
import { LenderUserQuery } from
|
|
14
|
-
import { getLendersForChain } from
|
|
10
|
+
} from '../src'
|
|
11
|
+
import { multicallRetry, getEvmClient } from '@1delta/providers'
|
|
12
|
+
import { Chain, Lender } from '@1delta/asset-registry'
|
|
13
|
+
import { LenderUserQuery } from '../src/lending/user-data/types'
|
|
14
|
+
import { getLendersForChain } from '../src/utils'
|
|
15
15
|
|
|
16
|
-
const TEST_ADDRESS =
|
|
17
|
-
let prices, yields
|
|
16
|
+
const TEST_ADDRESS = '0xbadA9c382165b31419F4CC0eDf0Fa84f80A3C8E5'
|
|
17
|
+
let prices, yields
|
|
18
18
|
|
|
19
19
|
async function getUserData(chainId: Chain, lenders: Lender[]) {
|
|
20
|
-
const _lenders = getLendersForChain(chainId)
|
|
20
|
+
const _lenders = getLendersForChain(chainId)
|
|
21
21
|
const publicData = {
|
|
22
22
|
data: await getLenderPublicData(
|
|
23
23
|
chainId,
|
|
24
24
|
_lenders as any,
|
|
25
25
|
prices as any,
|
|
26
26
|
yields as any,
|
|
27
|
-
multicallRetry
|
|
28
|
-
)
|
|
27
|
+
multicallRetry,
|
|
28
|
+
),
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
// Define user queries
|
|
32
32
|
const queries: LenderUserQuery[] = lenders.map((lender) => ({
|
|
33
33
|
lender,
|
|
34
34
|
account: TEST_ADDRESS.toLowerCase(),
|
|
35
|
-
}))
|
|
35
|
+
}))
|
|
36
36
|
|
|
37
37
|
// Fetch raw user data
|
|
38
38
|
const rawUserData = await getLenderUserDataResult(
|
|
39
39
|
chainId,
|
|
40
40
|
queries,
|
|
41
|
-
getEvmClient
|
|
42
|
-
)
|
|
41
|
+
getEvmClient,
|
|
42
|
+
)
|
|
43
43
|
|
|
44
44
|
// Convert raw data to structured format
|
|
45
45
|
const userData = convertLenderUserDataResult(
|
|
@@ -48,142 +48,170 @@ async function getUserData(chainId: Chain, lenders: Lender[]) {
|
|
|
48
48
|
rawUserData,
|
|
49
49
|
prices as any,
|
|
50
50
|
prices as any,
|
|
51
|
-
{ [chainId]: publicData }
|
|
52
|
-
)
|
|
51
|
+
{ [chainId]: publicData },
|
|
52
|
+
)
|
|
53
53
|
|
|
54
|
-
return { userData, rawUserData, publicData, queries }
|
|
54
|
+
return { userData, rawUserData, publicData, queries }
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
describe(
|
|
58
|
-
|
|
58
|
+
'user data fetching',
|
|
59
59
|
() => {
|
|
60
60
|
beforeAll(async () => {
|
|
61
|
-
[prices, yields] = await Promise.all([
|
|
61
|
+
;[prices, yields] = await Promise.all([
|
|
62
62
|
fetchMainPrices([Chain.MANTLE], getEvmClient),
|
|
63
63
|
fetchGeneralYields(),
|
|
64
|
-
])
|
|
65
|
-
}, 30000)
|
|
64
|
+
])
|
|
65
|
+
}, 30000)
|
|
66
66
|
|
|
67
67
|
it(
|
|
68
|
-
|
|
68
|
+
'should fetch user data for LENDLE PT CMETH on Mantle',
|
|
69
69
|
async () => {
|
|
70
70
|
try {
|
|
71
|
-
const { userData } = await getUserData(Chain.MANTLE, [
|
|
71
|
+
const { userData } = await getUserData(Chain.MANTLE, [
|
|
72
|
+
Lender.LENDLE_PT_CMETH,
|
|
73
|
+
])
|
|
72
74
|
|
|
73
|
-
console.log(
|
|
75
|
+
console.log(
|
|
76
|
+
'LENDLE PT CMETH Mantle user data:',
|
|
77
|
+
userData[Lender.LENDLE_PT_CMETH][TEST_ADDRESS.toLowerCase()],
|
|
78
|
+
)
|
|
74
79
|
|
|
75
80
|
// Basic validation
|
|
76
|
-
expect(userData).toBeDefined()
|
|
77
|
-
expect(typeof userData).toBe(
|
|
81
|
+
expect(userData).toBeDefined()
|
|
82
|
+
expect(typeof userData).toBe('object')
|
|
78
83
|
} catch (error) {
|
|
79
|
-
console.log(
|
|
84
|
+
console.log('Error fetching LENDLE PT CMETH Mantle data:', error)
|
|
80
85
|
}
|
|
81
86
|
},
|
|
82
|
-
{ timeout: 30000 }
|
|
83
|
-
)
|
|
87
|
+
{ timeout: 30000 },
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
it(
|
|
91
|
+
'should fetch user data for COMET on Arb',
|
|
92
|
+
async () => {
|
|
93
|
+
try {
|
|
94
|
+
const { userData } = await getUserData(Chain.ARBITRUM_ONE, [
|
|
95
|
+
Lender.COMPOUND_V3_USDC,
|
|
96
|
+
])
|
|
84
97
|
|
|
98
|
+
console.log('COMET Mantle user data:', userData[Lender.COMPOUND_V3_USDC]?.[TEST_ADDRESS.toLowerCase()])
|
|
85
99
|
|
|
100
|
+
// Basic validation
|
|
101
|
+
expect(userData).toBeDefined()
|
|
102
|
+
expect(typeof userData).toBe('object')
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.log('Error fetching INIT Mantle data:', error)
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
{ timeout: 30000 },
|
|
108
|
+
)
|
|
86
109
|
|
|
87
110
|
it(
|
|
88
|
-
|
|
111
|
+
'should fetch user data for INIT on Mantle',
|
|
89
112
|
async () => {
|
|
90
113
|
try {
|
|
91
|
-
const { userData } = await getUserData(Chain.MANTLE, [Lender.INIT])
|
|
114
|
+
const { userData } = await getUserData(Chain.MANTLE, [Lender.INIT])
|
|
92
115
|
|
|
93
|
-
console.log(
|
|
116
|
+
console.log('INIT Mantle user data:', userData)
|
|
94
117
|
|
|
95
118
|
// Basic validation
|
|
96
|
-
expect(userData).toBeDefined()
|
|
97
|
-
expect(typeof userData).toBe(
|
|
119
|
+
expect(userData).toBeDefined()
|
|
120
|
+
expect(typeof userData).toBe('object')
|
|
98
121
|
} catch (error) {
|
|
99
|
-
console.log(
|
|
122
|
+
console.log('Error fetching INIT Mantle data:', error)
|
|
100
123
|
}
|
|
101
124
|
},
|
|
102
|
-
{ timeout: 30000 }
|
|
103
|
-
)
|
|
104
|
-
|
|
125
|
+
{ timeout: 30000 },
|
|
126
|
+
)
|
|
105
127
|
|
|
106
128
|
it(
|
|
107
|
-
|
|
129
|
+
'should fetch user data for AAVE V3 on Polygon',
|
|
108
130
|
async () => {
|
|
109
131
|
try {
|
|
110
|
-
const { userData } = await getUserData(Chain.ARBITRUM_ONE, [
|
|
132
|
+
const { userData } = await getUserData(Chain.ARBITRUM_ONE, [
|
|
133
|
+
Lender.AAVE_V3,
|
|
134
|
+
])
|
|
111
135
|
|
|
112
|
-
console.log(
|
|
113
|
-
|
|
136
|
+
console.log(
|
|
137
|
+
'AAVE_V3 Polygon user data:',
|
|
138
|
+
userData[Lender.AAVE_V3][TEST_ADDRESS.toLowerCase()]
|
|
139
|
+
.lendingPositions,
|
|
140
|
+
)
|
|
141
|
+
console.log('AAVE_V3 Polygon user aprData:', userData[Lender.AAVE_V3])
|
|
114
142
|
|
|
115
143
|
// Basic validation
|
|
116
|
-
expect(userData).toBeDefined()
|
|
117
|
-
expect(typeof userData).toBe(
|
|
144
|
+
expect(userData).toBeDefined()
|
|
145
|
+
expect(typeof userData).toBe('object')
|
|
118
146
|
} catch (error) {
|
|
119
|
-
console.log(
|
|
147
|
+
console.log('Error fetching AAVE_V3 Polygon data:', error)
|
|
120
148
|
}
|
|
121
149
|
},
|
|
122
|
-
{ timeout: 30000 }
|
|
123
|
-
)
|
|
124
|
-
|
|
150
|
+
{ timeout: 30000 },
|
|
151
|
+
)
|
|
125
152
|
|
|
126
153
|
it(
|
|
127
|
-
|
|
154
|
+
'should fetch user data for AAVE V3 on Base',
|
|
128
155
|
async () => {
|
|
129
156
|
try {
|
|
130
|
-
const { userData } = await getUserData(Chain.BASE, [Lender.AAVE_V3])
|
|
157
|
+
const { userData } = await getUserData(Chain.BASE, [Lender.AAVE_V3])
|
|
131
158
|
|
|
132
|
-
console.log(
|
|
159
|
+
console.log('AAVE V3 Base user data:', userData)
|
|
133
160
|
|
|
134
161
|
// Basic validation
|
|
135
|
-
expect(userData).toBeDefined()
|
|
136
|
-
expect(typeof userData).toBe(
|
|
162
|
+
expect(userData).toBeDefined()
|
|
163
|
+
expect(typeof userData).toBe('object')
|
|
137
164
|
} catch (error) {
|
|
138
|
-
console.log(
|
|
165
|
+
console.log('Error fetching AAVE V3 Base data:', error)
|
|
139
166
|
}
|
|
140
167
|
},
|
|
141
|
-
{ timeout: 30000 }
|
|
142
|
-
)
|
|
168
|
+
{ timeout: 30000 },
|
|
169
|
+
)
|
|
143
170
|
|
|
144
171
|
it(
|
|
145
|
-
|
|
172
|
+
'should fetch user data for multiple protocols on Arbitrum',
|
|
146
173
|
async () => {
|
|
147
174
|
try {
|
|
148
|
-
const { userData, queries } = await getUserData(
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
175
|
+
const { userData, queries } = await getUserData(Chain.ARBITRUM_ONE, [
|
|
176
|
+
Lender.AAVE_V3,
|
|
177
|
+
Lender.COMPOUND_V3_USDC,
|
|
178
|
+
Lender.COMPOUND_V3_USDCE,
|
|
179
|
+
])
|
|
152
180
|
|
|
153
|
-
console.log(
|
|
181
|
+
console.log('Arbitrum multi-protocol user data:', userData)
|
|
154
182
|
|
|
155
|
-
expect(userData).toBeDefined()
|
|
156
|
-
expect(typeof userData).toBe(
|
|
183
|
+
expect(userData).toBeDefined()
|
|
184
|
+
expect(typeof userData).toBe('object')
|
|
157
185
|
|
|
158
186
|
// Check that we get data for each queried protocol
|
|
159
187
|
queries.forEach((query) => {
|
|
160
188
|
if (userData[query.lender]) {
|
|
161
|
-
console.log(`Found data for ${query.lender} on Arbitrum`)
|
|
162
|
-
expect(userData[query.lender]).toBeDefined()
|
|
189
|
+
console.log(`Found data for ${query.lender} on Arbitrum`)
|
|
190
|
+
expect(userData[query.lender]).toBeDefined()
|
|
163
191
|
}
|
|
164
|
-
})
|
|
192
|
+
})
|
|
165
193
|
} catch (error) {
|
|
166
|
-
console.log(
|
|
194
|
+
console.log('Error fetching Arbitrum multi-protocol data:', error)
|
|
167
195
|
}
|
|
168
196
|
},
|
|
169
|
-
{ timeout: 30000 }
|
|
170
|
-
)
|
|
197
|
+
{ timeout: 30000 },
|
|
198
|
+
)
|
|
171
199
|
|
|
172
200
|
it(
|
|
173
|
-
|
|
201
|
+
'should fetch user data across multiple chains',
|
|
174
202
|
async () => {
|
|
175
203
|
const testChains = [
|
|
176
204
|
Chain.ETHEREUM_MAINNET,
|
|
177
205
|
Chain.POLYGON_MAINNET,
|
|
178
206
|
Chain.BASE,
|
|
179
|
-
]
|
|
207
|
+
]
|
|
180
208
|
|
|
181
209
|
try {
|
|
182
210
|
for (const chainId of testChains) {
|
|
183
|
-
const lenders = getLendersForChain(chainId)
|
|
211
|
+
const lenders = getLendersForChain(chainId)
|
|
184
212
|
if (lenders.length === 0) {
|
|
185
|
-
console.log(`No lenders available on ${chainId}`)
|
|
186
|
-
continue
|
|
213
|
+
console.log(`No lenders available on ${chainId}`)
|
|
214
|
+
continue
|
|
187
215
|
}
|
|
188
216
|
|
|
189
217
|
const publicData = await getLenderPublicData(
|
|
@@ -191,19 +219,19 @@ describe(
|
|
|
191
219
|
lenders as any,
|
|
192
220
|
prices as any,
|
|
193
221
|
yields as any,
|
|
194
|
-
multicallRetry
|
|
195
|
-
)
|
|
222
|
+
multicallRetry,
|
|
223
|
+
)
|
|
196
224
|
|
|
197
|
-
const firstLender = lenders[0] as Lender
|
|
225
|
+
const firstLender = lenders[0] as Lender
|
|
198
226
|
const queries: LenderUserQuery[] = [
|
|
199
227
|
{ lender: firstLender, account: TEST_ADDRESS.toLowerCase() }, // test first lender
|
|
200
|
-
]
|
|
228
|
+
]
|
|
201
229
|
|
|
202
230
|
const rawUserData = await getLenderUserDataResult(
|
|
203
231
|
chainId,
|
|
204
232
|
queries,
|
|
205
|
-
getEvmClient
|
|
206
|
-
)
|
|
233
|
+
getEvmClient,
|
|
234
|
+
)
|
|
207
235
|
|
|
208
236
|
const userData = convertLenderUserDataResult(
|
|
209
237
|
chainId,
|
|
@@ -211,51 +239,46 @@ describe(
|
|
|
211
239
|
rawUserData,
|
|
212
240
|
prices as any,
|
|
213
241
|
prices as any,
|
|
214
|
-
publicData
|
|
215
|
-
)
|
|
242
|
+
publicData,
|
|
243
|
+
)
|
|
216
244
|
|
|
217
|
-
console.log(`${chainId} - ${firstLender} user data:`, userData)
|
|
245
|
+
console.log(`${chainId} - ${firstLender} user data:`, userData)
|
|
218
246
|
|
|
219
|
-
expect(userData).toBeDefined()
|
|
220
|
-
expect(typeof userData).toBe(
|
|
247
|
+
expect(userData).toBeDefined()
|
|
248
|
+
expect(typeof userData).toBe('object')
|
|
221
249
|
}
|
|
222
250
|
} catch (error) {
|
|
223
|
-
console.log(
|
|
251
|
+
console.log('Error in multi-chain test:', error)
|
|
224
252
|
}
|
|
225
253
|
},
|
|
226
|
-
{ timeout: 60000 }
|
|
227
|
-
)
|
|
254
|
+
{ timeout: 60000 },
|
|
255
|
+
)
|
|
228
256
|
|
|
229
257
|
it(
|
|
230
|
-
|
|
258
|
+
'should fetch user data for Init protocol on Mantle',
|
|
231
259
|
async () => {
|
|
232
|
-
const chainId = Chain.MANTLE
|
|
260
|
+
const chainId = Chain.MANTLE
|
|
233
261
|
|
|
234
262
|
try {
|
|
235
|
-
const { userData } = await getUserData(
|
|
236
|
-
Chain.MANTLE,
|
|
237
|
-
[Lender.INIT]
|
|
238
|
-
);
|
|
263
|
+
const { userData } = await getUserData(Chain.MANTLE, [Lender.INIT])
|
|
239
264
|
|
|
240
|
-
console.log(
|
|
265
|
+
console.log('Init protocol Mantle user data:', userData)
|
|
241
266
|
|
|
242
|
-
expect(userData).toBeDefined()
|
|
243
|
-
expect(typeof userData).toBe(
|
|
267
|
+
expect(userData).toBeDefined()
|
|
268
|
+
expect(typeof userData).toBe('object')
|
|
244
269
|
} catch (error) {
|
|
245
|
-
console.log(
|
|
270
|
+
console.log('Error fetching Init protocol data:', error)
|
|
246
271
|
}
|
|
247
272
|
},
|
|
248
|
-
{ timeout: 30000 }
|
|
249
|
-
)
|
|
250
|
-
|
|
251
|
-
it("should handle empty queries", async () => {
|
|
252
|
-
const { userData } = await getUserData(Chain.BASE, []);
|
|
253
|
-
|
|
254
|
-
expect(userData).toBeDefined();
|
|
255
|
-
expect(Object.keys(userData)).toHaveLength(0);
|
|
256
|
-
});
|
|
273
|
+
{ timeout: 30000 },
|
|
274
|
+
)
|
|
257
275
|
|
|
276
|
+
it('should handle empty queries', async () => {
|
|
277
|
+
const { userData } = await getUserData(Chain.BASE, [])
|
|
258
278
|
|
|
279
|
+
expect(userData).toBeDefined()
|
|
280
|
+
expect(Object.keys(userData)).toHaveLength(0)
|
|
281
|
+
})
|
|
259
282
|
},
|
|
260
|
-
{ timeout: 90000 }
|
|
261
|
-
)
|
|
283
|
+
{ timeout: 90000 },
|
|
284
|
+
)
|