@1delta/margin-fetcher 0.0.26 → 0.0.28
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/user-data/aave-v3-type/userCallParse.d.ts +2 -2
- package/dist/lending/user-data/aave-v3-type/userCallParse.d.ts.map +1 -1
- package/dist/lending/user-data/aave-v3-type/userCallParse.js +13 -12
- package/dist/lending/user-data/fetchUserData.d.ts +5 -2
- package/dist/lending/user-data/fetchUserData.d.ts.map +1 -1
- package/dist/lending/user-data/fetchUserData.js +7 -4
- package/dist/prices/main-prices/fetchOracleData.d.ts +3 -2
- package/dist/prices/main-prices/fetchOracleData.d.ts.map +1 -1
- package/dist/prices/main-prices/fetchOracleData.js +3 -3
- package/dist/utils/multicall.d.ts +2 -1
- package/dist/utils/multicall.d.ts.map +1 -1
- package/dist/utils/multicall.js +12 -6
- package/package.json +2 -2
- package/src/lending/user-data/aave-v3-type/userCallParse.ts +45 -31
- package/src/lending/user-data/fetchUserData.ts +18 -4
- package/src/prices/main-prices/fetchOracleData.ts +9 -6
- package/src/utils/multicall.ts +15 -4
- package/test/dataMainnet.ts +45256 -0
- package/test/mainPrices.test.ts +7 -8
- package/test/userDataAave.test.ts +2 -7
- package/test/userDataAaveMainnet.test.ts +102 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Lender } from
|
|
2
|
-
import { AaveV3UserReserveResponse } from
|
|
1
|
+
import { Lender } from '@1delta/asset-registry';
|
|
2
|
+
import { AaveV3UserReserveResponse } from '../types';
|
|
3
3
|
export declare const getAaveV3UserDataConverter: (lender: Lender, chainId: string, account: 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/aave-v3-type/userCallParse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"userCallParse.d.ts","sourceRoot":"","sources":["../../../../src/lending/user-data/aave-v3-type/userCallParse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAO/C,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAA;AAKpD,eAAO,MAAM,0BAA0B,GACrC,QAAQ,MAAM,EACd,SAAS,MAAM,EACf,SAAS,MAAM,EACf,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,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,yBAAyB,GAAG,SAAS,EAAE,MAAM,CAqDjE,CAAA"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { getAaveAssets, getAssetMeta, toGenericPriceKey, toOracleKey } from
|
|
2
|
-
import { createBaseTypeUserState } from
|
|
3
|
-
import { AaveTypeGetUserReserveIndexes } from
|
|
4
|
-
import { parseRawAmount } from
|
|
1
|
+
import { getAaveAssets, getAssetMeta, toGenericPriceKey, toOracleKey, } from '../../../assets';
|
|
2
|
+
import { createBaseTypeUserState } from '../utils';
|
|
3
|
+
import { AaveTypeGetUserReserveIndexes } from '../../aave-v3-type/types';
|
|
4
|
+
import { parseRawAmount } from '../../../utils/parsing';
|
|
5
5
|
export const getAaveV3UserDataConverter = (lender, chainId, account, prices, pricesHist, lenderData) => {
|
|
6
6
|
const assetsToQuery = getAaveAssets(chainId, lender);
|
|
7
7
|
const expectedNumberOfCalls = assetsToQuery.length + 1;
|
|
@@ -26,14 +26,14 @@ export const getAaveV3UserDataConverter = (lender, chainId, account, prices, pri
|
|
|
26
26
|
const payload = {
|
|
27
27
|
chainId,
|
|
28
28
|
account,
|
|
29
|
-
lendingPositions: {
|
|
29
|
+
lendingPositions: { '0': lendingPositions },
|
|
30
30
|
rewards: {},
|
|
31
31
|
userEMode,
|
|
32
32
|
};
|
|
33
33
|
const userData = createBaseTypeUserState(payload, lenderData, totalDeposits24h, totalDebt24h);
|
|
34
34
|
return {
|
|
35
35
|
...payload,
|
|
36
|
-
...userData
|
|
36
|
+
...userData,
|
|
37
37
|
};
|
|
38
38
|
},
|
|
39
39
|
expectedNumberOfCalls,
|
|
@@ -44,13 +44,13 @@ function createAaveV3Entry(i, data, chainId, asset, prices, pricesHist) {
|
|
|
44
44
|
const currentATokenBalanceRaw = reserveData[AaveTypeGetUserReserveIndexes.currentATokenBalance]?.toString();
|
|
45
45
|
const currentStableDebtRaw = reserveData[AaveTypeGetUserReserveIndexes.currentStableDebt]?.toString();
|
|
46
46
|
const currentVariableDebtRaw = reserveData[AaveTypeGetUserReserveIndexes.currentVariableDebt]?.toString();
|
|
47
|
-
if (currentATokenBalanceRaw ===
|
|
48
|
-
currentStableDebtRaw ===
|
|
49
|
-
currentVariableDebtRaw ===
|
|
47
|
+
if (currentATokenBalanceRaw === '0' &&
|
|
48
|
+
currentStableDebtRaw === '0' &&
|
|
49
|
+
currentVariableDebtRaw === '0') {
|
|
50
50
|
return {
|
|
51
51
|
dataForAsset: undefined,
|
|
52
52
|
addedDeposits: 0,
|
|
53
|
-
addedDebt: 0
|
|
53
|
+
addedDebt: 0,
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
56
|
const assetMeta = getAssetMeta(chainId, asset);
|
|
@@ -72,13 +72,14 @@ function createAaveV3Entry(i, data, chainId, asset, prices, pricesHist) {
|
|
|
72
72
|
depositsUSD: Number(currentATokenBalance) * price,
|
|
73
73
|
debtStableUSD: Number(currentStableDebt) * price,
|
|
74
74
|
debtUSD: Number(currentVariableDebt) * price,
|
|
75
|
-
stableBorrowRate: reserveData[AaveTypeGetUserReserveIndexes.stableBorrowRate]?.toString() ??
|
|
75
|
+
stableBorrowRate: reserveData[AaveTypeGetUserReserveIndexes.stableBorrowRate]?.toString() ??
|
|
76
|
+
'0',
|
|
76
77
|
collateralActive: Boolean(reserveData[AaveTypeGetUserReserveIndexes.usageAsCollateralEnabled]),
|
|
77
78
|
claimableRewards: 0,
|
|
78
79
|
};
|
|
79
80
|
return {
|
|
80
81
|
dataForAsset,
|
|
81
82
|
addedDeposits: Number(currentATokenBalance) * priceHist,
|
|
82
|
-
addedDebt: (Number(currentVariableDebt) + Number(currentStableDebt)) * priceHist
|
|
83
|
+
addedDebt: (Number(currentVariableDebt) + Number(currentStableDebt)) * priceHist,
|
|
83
84
|
};
|
|
84
85
|
}
|
|
@@ -5,9 +5,12 @@ import { GetEvmClientFunction } from '../../types';
|
|
|
5
5
|
* @param chainId - The chain ID
|
|
6
6
|
* @param queries - The queries to fetch data for
|
|
7
7
|
* @param getEvmClient - Injected function to get EVM client
|
|
8
|
-
* @
|
|
8
|
+
* @param allowFailure - multicall can fail in single call, default is true - note that this might mess with the retries as it will never error
|
|
9
|
+
* @param batchSize - multicall batch size, default is 4096
|
|
10
|
+
* @param logs - show multicall error logs, default is false
|
|
11
|
+
* @returns The raw results from the multicall, "0x" for failures
|
|
9
12
|
*/
|
|
10
|
-
export declare const getLenderUserDataResult: (chainId: string, queriesRaw: LenderUserQuery[], getEvmClient: GetEvmClientFunction) => Promise<any[]>;
|
|
13
|
+
export declare const getLenderUserDataResult: (chainId: string, queriesRaw: LenderUserQuery[], getEvmClient: GetEvmClientFunction, allowFailure?: boolean, batchSize?: number, retries?: number, logs?: boolean) => Promise<any[]>;
|
|
11
14
|
/**
|
|
12
15
|
* Converts the raw results into the desired format
|
|
13
16
|
* @param chainId - The chain ID
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetchUserData.d.ts","sourceRoot":"","sources":["../../../src/lending/user-data/fetchUserData.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fetchUserData.d.ts","sourceRoot":"","sources":["../../../src/lending/user-data/fetchUserData.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,eAAe,EAAuB,MAAM,SAAS,CAAA;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AA6FlD;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,GAClC,SAAS,MAAM,EACf,YAAY,eAAe,EAAE,EAC7B,cAAc,oBAAoB,EAClC,sBAAmB,EACnB,kBAAwC,EACxC,gBAAW,EACX,cAAY,KACX,OAAO,CAAC,GAAG,EAAE,CA+Bf,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B,GACtC,SAAS,MAAM,EACf,YAAY,eAAe,EAAE,EAC7B,YAAY,GAAG,EAAE,EACjB,QAAQ,GAAG,EACX,YAAY,GAAG,EACf,aAAa,GAAG,KACf;IAAE,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAAA;CAsCzB,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { multicallViemAbiArray } from '../../utils/multicall';
|
|
1
|
+
import { MULTICALL_DEFAULT_BATCH_SIZE, multicallViemAbiArray, } from '../../utils/multicall';
|
|
2
2
|
import { isAaveV2Type, isAaveV3Type, isInit, isMorphoType, isMultiMarket, isYLDR, } from '../../utils';
|
|
3
3
|
import { organizeUserQueries } from './types';
|
|
4
4
|
import { buildAaveV2UserCall } from './aave-v2-type/userCallBuild';
|
|
@@ -42,9 +42,12 @@ function getUserDataConverter(lender, chainId, account, prices, pricesHist, lend
|
|
|
42
42
|
* @param chainId - The chain ID
|
|
43
43
|
* @param queries - The queries to fetch data for
|
|
44
44
|
* @param getEvmClient - Injected function to get EVM client
|
|
45
|
-
* @
|
|
45
|
+
* @param allowFailure - multicall can fail in single call, default is true - note that this might mess with the retries as it will never error
|
|
46
|
+
* @param batchSize - multicall batch size, default is 4096
|
|
47
|
+
* @param logs - show multicall error logs, default is false
|
|
48
|
+
* @returns The raw results from the multicall, "0x" for failures
|
|
46
49
|
*/
|
|
47
|
-
export const getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient) => {
|
|
50
|
+
export const getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, retries = 3, logs = false) => {
|
|
48
51
|
let calls = [];
|
|
49
52
|
const queries = organizeUserQueries(queriesRaw);
|
|
50
53
|
for (const query of queries) {
|
|
@@ -53,7 +56,7 @@ export const getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient)
|
|
|
53
56
|
const mappedCalls = callData.map((call) => ({ call, abi }));
|
|
54
57
|
calls = [...calls, ...mappedCalls];
|
|
55
58
|
}
|
|
56
|
-
return await multicallViemAbiArray(chainId, calls.map((call) => call.abi), calls.map((call) => call.call), getEvmClient, true, 0,
|
|
59
|
+
return await multicallViemAbiArray(chainId, calls.map((call) => call.abi), calls.map((call) => call.call), getEvmClient, true, 0, retries, allowFailure, batchSize, logs);
|
|
57
60
|
};
|
|
58
61
|
/**
|
|
59
62
|
* Converts the raw results into the desired format
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { GetEvmClientFunction } from '../../types';
|
|
2
1
|
export declare const formatAavePrice: (price: string, isV2?: boolean) => number;
|
|
3
2
|
export declare const formatMorphoPrice: (price: string, collateralDec: number, debtDec: number) => number;
|
|
4
3
|
interface OracleData {
|
|
@@ -7,6 +6,8 @@ interface OracleData {
|
|
|
7
6
|
/**
|
|
8
7
|
* Fetches Aave and uniswap V2 oracle data
|
|
9
8
|
*/
|
|
10
|
-
export declare const fetchMainPrices: (chainIds: string[],
|
|
9
|
+
export declare const fetchMainPrices: (chainIds: string[], rpcOverrides?: {
|
|
10
|
+
[chainId: string]: string;
|
|
11
|
+
}) => Promise<OracleData>;
|
|
11
12
|
export {};
|
|
12
13
|
//# sourceMappingURL=fetchOracleData.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetchOracleData.d.ts","sourceRoot":"","sources":["../../../src/prices/main-prices/fetchOracleData.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fetchOracleData.d.ts","sourceRoot":"","sources":["../../../src/prices/main-prices/fetchOracleData.ts"],"names":[],"mappings":"AAwBA,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,EAAE,cAAY,KAAG,MAY7D,CAAA;AAED,eAAO,MAAM,iBAAiB,GAC5B,OAAO,MAAM,EACb,eAAe,MAAM,EACrB,SAAS,MAAM,KACd,MAYF,CAAA;AAOD,UAAU,UAAU;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CACtB;AAID;;GAEG;AACH,eAAO,MAAM,eAAe,GAC1B,UAAU,MAAM,EAAE,EAClB,eAAe;IAAE,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,KAC3C,OAAO,CAAC,UAAU,CAkKpB,CAAA"}
|
|
@@ -10,12 +10,12 @@ import { getAaveAssets } from '../../assets';
|
|
|
10
10
|
import { chainlinkOracles, getChainLinkKeys, ChainlinkAggregatorIndexes, } from './addresses/chainlink';
|
|
11
11
|
import { fetchDefillamaData } from '../defillama';
|
|
12
12
|
import { fetchPendlePrices } from '../pendle';
|
|
13
|
-
import { multicallViemAbiArray } from '../../utils/multicall';
|
|
14
13
|
import { AAVE_STYLE_ORACLES } from './addresses/aaveOracles';
|
|
15
14
|
import { AAVES_PER_CHAIN } from '../../utils';
|
|
16
15
|
import { parseRawAmount } from '../../utils/parsing';
|
|
17
16
|
import { ProxyOracleAbi } from '../../abis/oracle/ProxyOracle';
|
|
18
17
|
import { MrophoOracles } from './addresses/morpho';
|
|
18
|
+
import { multicallRetry } from '@1delta/providers';
|
|
19
19
|
export const formatAavePrice = (price, isV2 = false) => {
|
|
20
20
|
try {
|
|
21
21
|
return Number(formatEther(BigInt(price ?? '0') *
|
|
@@ -43,7 +43,7 @@ const RWA_DYNAMIC_ORACLE = '0xA96abbe61AfEdEB0D14a20440Ae7100D9aB4882f';
|
|
|
43
43
|
/**
|
|
44
44
|
* Fetches Aave and uniswap V2 oracle data
|
|
45
45
|
*/
|
|
46
|
-
export const fetchMainPrices = async (chainIds,
|
|
46
|
+
export const fetchMainPrices = async (chainIds, rpcOverrides) => {
|
|
47
47
|
const multicallPromises = chainIds.map(async (chainId) => {
|
|
48
48
|
const aaveForks = AAVES_PER_CHAIN[chainId];
|
|
49
49
|
const reservesToQuery = aaveForks?.map((a) => ({
|
|
@@ -87,7 +87,7 @@ export const fetchMainPrices = async (chainIds, getEvmClient) => {
|
|
|
87
87
|
...RWADynamicOracleAbi,
|
|
88
88
|
...ProxyOracleAbi,
|
|
89
89
|
];
|
|
90
|
-
const result = await
|
|
90
|
+
const result = await multicallRetry(chainId, allCalls, abis, undefined, 3, 0, true, rpcOverrides);
|
|
91
91
|
return {
|
|
92
92
|
chainId,
|
|
93
93
|
result,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { GeneralCall, GetEvmClientFunction } from '../types';
|
|
2
2
|
export type Call = GeneralCall;
|
|
3
|
+
export declare const MULTICALL_DEFAULT_BATCH_SIZE = 4096;
|
|
3
4
|
/** Same as Multicall viem except that the abi param is supposed to be the abi per call */
|
|
4
|
-
export declare const multicallViemAbiArray: (chainId: string, abi: any[], calls: Call[], getEvmClient: GetEvmClientFunction, retry?: boolean, providerId?: number, retries?: number) => Promise<any[]>;
|
|
5
|
+
export declare const multicallViemAbiArray: (chainId: string, abi: any[], calls: Call[], getEvmClient: GetEvmClientFunction, retry?: boolean, providerId?: number, retries?: number, allowFailure?: boolean, batchSize?: number, logs?: boolean) => Promise<any[]>;
|
|
5
6
|
//# sourceMappingURL=multicall.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multicall.d.ts","sourceRoot":"","sources":["../../src/utils/multicall.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAE5D,MAAM,MAAM,IAAI,GAAG,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"multicall.d.ts","sourceRoot":"","sources":["../../src/utils/multicall.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAE5D,MAAM,MAAM,IAAI,GAAG,WAAW,CAAA;AAO9B,eAAO,MAAM,4BAA4B,OAAO,CAAA;AAIhD,0FAA0F;AAC1F,eAAO,MAAM,qBAAqB,GAChC,SAAS,MAAM,EACf,KAAK,GAAG,EAAE,EACV,OAAO,IAAI,EAAE,EACb,cAAc,oBAAoB,EAClC,eAAY,EACZ,mBAAc,EACd,gBAAoB,EACpB,sBAAmB,EACnB,kBAAwC,EACxC,cAAY,KACX,OAAO,CAAC,GAAG,EAAE,CA6Cf,CAAA"}
|
package/dist/utils/multicall.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { isArray } from 'lodash';
|
|
2
|
-
const MULTICALL_DEFAULT_BATCH_SIZE = 4096;
|
|
2
|
+
export const MULTICALL_DEFAULT_BATCH_SIZE = 4096;
|
|
3
3
|
const maxRetries = 3;
|
|
4
4
|
/** Same as Multicall viem except that the abi param is supposed to be the abi per call */
|
|
5
|
-
export const multicallViemAbiArray = async (chainId, abi, calls, getEvmClient, retry = true, providerId = 0, retries = maxRetries) => {
|
|
5
|
+
export const multicallViemAbiArray = async (chainId, abi, calls, getEvmClient, retry = true, providerId = 0, retries = maxRetries, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, logs = false) => {
|
|
6
6
|
try {
|
|
7
7
|
const provider = getEvmClient(chainId, providerId);
|
|
8
8
|
const abiIsArray = isArray(abi[0]);
|
|
9
9
|
const returnData = await provider.multicall({
|
|
10
|
-
allowFailure
|
|
11
|
-
batchSize
|
|
10
|
+
allowFailure,
|
|
11
|
+
batchSize,
|
|
12
12
|
contracts: calls.map(({ address, name, params }, i) => ({
|
|
13
13
|
abi: abiIsArray ? abi?.[i] : abi,
|
|
14
14
|
address: address,
|
|
@@ -16,15 +16,21 @@ export const multicallViemAbiArray = async (chainId, abi, calls, getEvmClient, r
|
|
|
16
16
|
args: params,
|
|
17
17
|
})),
|
|
18
18
|
});
|
|
19
|
+
// no failure - result is directly exposed
|
|
20
|
+
if (!allowFailure)
|
|
21
|
+
return returnData;
|
|
22
|
+
// allow failure, return 0x in case of errors
|
|
19
23
|
const res = returnData.map(({ result, status }) => status !== 'success' ? '0x' : result);
|
|
20
24
|
return res;
|
|
21
25
|
}
|
|
22
26
|
catch (error) {
|
|
23
|
-
|
|
27
|
+
// optionally log errors
|
|
28
|
+
if (logs)
|
|
29
|
+
console.log('error in multicall', error);
|
|
24
30
|
retries--;
|
|
25
31
|
if (retries < 0)
|
|
26
32
|
throw new Error('Failed too often');
|
|
27
33
|
providerId++;
|
|
28
|
-
return multicallViemAbiArray(chainId, abi, calls, getEvmClient, retry, providerId, retries);
|
|
34
|
+
return multicallViemAbiArray(chainId, abi, calls, getEvmClient, retry, providerId, retries, allowFailure, batchSize, logs);
|
|
29
35
|
}
|
|
30
36
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@1delta/margin-fetcher",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.28",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"@types/async-retry": "^1.4.9",
|
|
18
18
|
"async-retry": "^1.3.3",
|
|
19
19
|
"typescript": "^5.9.2",
|
|
20
|
-
"@1delta/providers": "0.0.
|
|
20
|
+
"@1delta/providers": "0.0.9"
|
|
21
21
|
},
|
|
22
22
|
"scripts": {
|
|
23
23
|
"build": "tsc",
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import { Lender } from
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { Lender } from '@1delta/asset-registry'
|
|
2
|
+
import {
|
|
3
|
+
getAaveAssets,
|
|
4
|
+
getAssetMeta,
|
|
5
|
+
toGenericPriceKey,
|
|
6
|
+
toOracleKey,
|
|
7
|
+
} from '../../../assets'
|
|
8
|
+
import { AaveV3UserReserveResponse } from '../types'
|
|
9
|
+
import { createBaseTypeUserState } from '../utils'
|
|
10
|
+
import { AaveTypeGetUserReserveIndexes } from '../../aave-v3-type/types'
|
|
11
|
+
import { parseRawAmount } from '../../../utils/parsing'
|
|
7
12
|
|
|
8
13
|
export const getAaveV3UserDataConverter = (
|
|
9
14
|
lender: Lender,
|
|
@@ -11,12 +16,11 @@ export const getAaveV3UserDataConverter = (
|
|
|
11
16
|
account: string,
|
|
12
17
|
prices: { [asset: string]: number },
|
|
13
18
|
pricesHist: { [asset: string]: number },
|
|
14
|
-
lenderData: any
|
|
19
|
+
lenderData: any,
|
|
15
20
|
): [(data: any[]) => AaveV3UserReserveResponse | undefined, number] => {
|
|
16
|
-
|
|
17
21
|
const assetsToQuery = getAaveAssets(chainId, lender)
|
|
18
22
|
const expectedNumberOfCalls = assetsToQuery.length + 1
|
|
19
|
-
|
|
23
|
+
|
|
20
24
|
return [
|
|
21
25
|
(data: any[]) => {
|
|
22
26
|
if (data.length !== expectedNumberOfCalls) {
|
|
@@ -31,11 +35,7 @@ export const getAaveV3UserDataConverter = (
|
|
|
31
35
|
|
|
32
36
|
for (let i = 0; i < assetsToQuery.length; i++) {
|
|
33
37
|
const asset = assetsToQuery[i]
|
|
34
|
-
const {
|
|
35
|
-
dataForAsset,
|
|
36
|
-
addedDebt,
|
|
37
|
-
addedDeposits
|
|
38
|
-
} = createAaveV3Entry(
|
|
38
|
+
const { dataForAsset, addedDebt, addedDeposits } = createAaveV3Entry(
|
|
39
39
|
i,
|
|
40
40
|
data,
|
|
41
41
|
chainId,
|
|
@@ -43,7 +43,7 @@ export const getAaveV3UserDataConverter = (
|
|
|
43
43
|
prices,
|
|
44
44
|
pricesHist,
|
|
45
45
|
)
|
|
46
|
-
if (!dataForAsset) continue
|
|
46
|
+
if (!dataForAsset) continue
|
|
47
47
|
|
|
48
48
|
totalDebt24h += addedDebt
|
|
49
49
|
totalDeposits24h += addedDeposits
|
|
@@ -53,14 +53,19 @@ export const getAaveV3UserDataConverter = (
|
|
|
53
53
|
const payload = {
|
|
54
54
|
chainId,
|
|
55
55
|
account,
|
|
56
|
-
lendingPositions: {
|
|
56
|
+
lendingPositions: { '0': lendingPositions },
|
|
57
57
|
rewards: {},
|
|
58
58
|
userEMode,
|
|
59
59
|
}
|
|
60
|
-
const userData = createBaseTypeUserState(
|
|
60
|
+
const userData = createBaseTypeUserState(
|
|
61
|
+
payload,
|
|
62
|
+
lenderData,
|
|
63
|
+
totalDeposits24h,
|
|
64
|
+
totalDebt24h,
|
|
65
|
+
)
|
|
61
66
|
return {
|
|
62
67
|
...payload,
|
|
63
|
-
...userData
|
|
68
|
+
...userData,
|
|
64
69
|
}
|
|
65
70
|
},
|
|
66
71
|
expectedNumberOfCalls,
|
|
@@ -77,18 +82,22 @@ function createAaveV3Entry(
|
|
|
77
82
|
) {
|
|
78
83
|
const reserveData = data[i]
|
|
79
84
|
|
|
80
|
-
const currentATokenBalanceRaw =
|
|
81
|
-
|
|
82
|
-
const
|
|
85
|
+
const currentATokenBalanceRaw =
|
|
86
|
+
reserveData[AaveTypeGetUserReserveIndexes.currentATokenBalance]?.toString()
|
|
87
|
+
const currentStableDebtRaw =
|
|
88
|
+
reserveData[AaveTypeGetUserReserveIndexes.currentStableDebt]?.toString()
|
|
89
|
+
const currentVariableDebtRaw =
|
|
90
|
+
reserveData[AaveTypeGetUserReserveIndexes.currentVariableDebt]?.toString()
|
|
83
91
|
|
|
84
92
|
if (
|
|
85
|
-
currentATokenBalanceRaw ===
|
|
86
|
-
currentStableDebtRaw ===
|
|
87
|
-
currentVariableDebtRaw ===
|
|
93
|
+
currentATokenBalanceRaw === '0' &&
|
|
94
|
+
currentStableDebtRaw === '0' &&
|
|
95
|
+
currentVariableDebtRaw === '0'
|
|
96
|
+
) {
|
|
88
97
|
return {
|
|
89
98
|
dataForAsset: undefined,
|
|
90
99
|
addedDeposits: 0,
|
|
91
|
-
addedDebt: 0
|
|
100
|
+
addedDebt: 0,
|
|
92
101
|
}
|
|
93
102
|
}
|
|
94
103
|
|
|
@@ -99,8 +108,8 @@ function createAaveV3Entry(
|
|
|
99
108
|
const currentStableDebt = parseRawAmount(currentStableDebtRaw, decimals)
|
|
100
109
|
const currentVariableDebt = parseRawAmount(currentVariableDebtRaw, decimals)
|
|
101
110
|
|
|
102
|
-
|
|
103
|
-
|
|
111
|
+
const key =
|
|
112
|
+
toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(asset, chainId)
|
|
104
113
|
// prices
|
|
105
114
|
const price = prices[key] ?? 1
|
|
106
115
|
const priceHist = pricesHist?.[key] ?? price
|
|
@@ -115,14 +124,19 @@ function createAaveV3Entry(
|
|
|
115
124
|
depositsUSD: Number(currentATokenBalance) * price,
|
|
116
125
|
debtStableUSD: Number(currentStableDebt) * price,
|
|
117
126
|
debtUSD: Number(currentVariableDebt) * price,
|
|
118
|
-
stableBorrowRate:
|
|
119
|
-
|
|
127
|
+
stableBorrowRate:
|
|
128
|
+
reserveData[AaveTypeGetUserReserveIndexes.stableBorrowRate]?.toString() ??
|
|
129
|
+
'0',
|
|
130
|
+
collateralActive: Boolean(
|
|
131
|
+
reserveData[AaveTypeGetUserReserveIndexes.usageAsCollateralEnabled],
|
|
132
|
+
),
|
|
120
133
|
claimableRewards: 0,
|
|
121
134
|
}
|
|
122
135
|
|
|
123
136
|
return {
|
|
124
137
|
dataForAsset,
|
|
125
138
|
addedDeposits: Number(currentATokenBalance) * priceHist,
|
|
126
|
-
addedDebt:
|
|
139
|
+
addedDebt:
|
|
140
|
+
(Number(currentVariableDebt) + Number(currentStableDebt)) * priceHist,
|
|
127
141
|
}
|
|
128
|
-
}
|
|
142
|
+
}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Call,
|
|
3
|
+
MULTICALL_DEFAULT_BATCH_SIZE,
|
|
4
|
+
multicallViemAbiArray,
|
|
5
|
+
} from '../../utils/multicall'
|
|
2
6
|
import { Lender } from '@1delta/asset-registry'
|
|
3
7
|
import {
|
|
4
8
|
isAaveV2Type,
|
|
@@ -107,12 +111,19 @@ function getUserDataConverter(
|
|
|
107
111
|
* @param chainId - The chain ID
|
|
108
112
|
* @param queries - The queries to fetch data for
|
|
109
113
|
* @param getEvmClient - Injected function to get EVM client
|
|
110
|
-
* @
|
|
114
|
+
* @param allowFailure - multicall can fail in single call, default is true - note that this might mess with the retries as it will never error
|
|
115
|
+
* @param batchSize - multicall batch size, default is 4096
|
|
116
|
+
* @param logs - show multicall error logs, default is false
|
|
117
|
+
* @returns The raw results from the multicall, "0x" for failures
|
|
111
118
|
*/
|
|
112
119
|
export const getLenderUserDataResult = async (
|
|
113
120
|
chainId: string,
|
|
114
121
|
queriesRaw: LenderUserQuery[],
|
|
115
122
|
getEvmClient: GetEvmClientFunction,
|
|
123
|
+
allowFailure = true,
|
|
124
|
+
batchSize = MULTICALL_DEFAULT_BATCH_SIZE,
|
|
125
|
+
retries = 3,
|
|
126
|
+
logs = false,
|
|
116
127
|
): Promise<any[]> => {
|
|
117
128
|
let calls: {
|
|
118
129
|
call: Call
|
|
@@ -131,7 +142,7 @@ export const getLenderUserDataResult = async (
|
|
|
131
142
|
const mappedCalls = callData.map((call) => ({ call, abi }))
|
|
132
143
|
calls = [...calls, ...mappedCalls]
|
|
133
144
|
}
|
|
134
|
-
|
|
145
|
+
|
|
135
146
|
return await multicallViemAbiArray(
|
|
136
147
|
chainId,
|
|
137
148
|
calls.map((call) => call.abi),
|
|
@@ -139,7 +150,10 @@ export const getLenderUserDataResult = async (
|
|
|
139
150
|
getEvmClient,
|
|
140
151
|
true,
|
|
141
152
|
0,
|
|
142
|
-
|
|
153
|
+
retries,
|
|
154
|
+
allowFailure,
|
|
155
|
+
batchSize,
|
|
156
|
+
logs,
|
|
143
157
|
)
|
|
144
158
|
}
|
|
145
159
|
|
|
@@ -15,13 +15,12 @@ import {
|
|
|
15
15
|
} from './addresses/chainlink'
|
|
16
16
|
import { fetchDefillamaData } from '../defillama'
|
|
17
17
|
import { fetchPendlePrices } from '../pendle'
|
|
18
|
-
import { multicallViemAbiArray } from '../../utils/multicall'
|
|
19
18
|
import { AAVE_STYLE_ORACLES } from './addresses/aaveOracles'
|
|
20
19
|
import { AAVES_PER_CHAIN } from '../../utils'
|
|
21
|
-
import { GetEvmClientFunction } from '../../types'
|
|
22
20
|
import { parseRawAmount } from '../../utils/parsing'
|
|
23
21
|
import { ProxyOracleAbi } from '../../abis/oracle/ProxyOracle'
|
|
24
22
|
import { MrophoOracleInfo, MrophoOracles } from './addresses/morpho'
|
|
23
|
+
import { multicallRetry } from '@1delta/providers'
|
|
25
24
|
|
|
26
25
|
export const formatAavePrice = (price: string, isV2 = false): number => {
|
|
27
26
|
try {
|
|
@@ -71,7 +70,7 @@ type QueryAave = { oracle: string; assets: string[]; fork: string }
|
|
|
71
70
|
*/
|
|
72
71
|
export const fetchMainPrices = async (
|
|
73
72
|
chainIds: string[],
|
|
74
|
-
|
|
73
|
+
rpcOverrides?: { [chainId: string]: string },
|
|
75
74
|
): Promise<OracleData> => {
|
|
76
75
|
const multicallPromises = chainIds.map(async (chainId) => {
|
|
77
76
|
const aaveForks = AAVES_PER_CHAIN[chainId]
|
|
@@ -126,11 +125,15 @@ export const fetchMainPrices = async (
|
|
|
126
125
|
...ProxyOracleAbi,
|
|
127
126
|
]
|
|
128
127
|
|
|
129
|
-
const result = await
|
|
128
|
+
const result = await multicallRetry(
|
|
130
129
|
chainId,
|
|
131
|
-
abis,
|
|
132
130
|
allCalls,
|
|
133
|
-
|
|
131
|
+
abis,
|
|
132
|
+
undefined,
|
|
133
|
+
3,
|
|
134
|
+
0,
|
|
135
|
+
true,
|
|
136
|
+
rpcOverrides,
|
|
134
137
|
)
|
|
135
138
|
|
|
136
139
|
return {
|
package/src/utils/multicall.ts
CHANGED
|
@@ -8,7 +8,7 @@ interface ViemMulticallresult {
|
|
|
8
8
|
status: string
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
const MULTICALL_DEFAULT_BATCH_SIZE = 4096
|
|
11
|
+
export const MULTICALL_DEFAULT_BATCH_SIZE = 4096
|
|
12
12
|
|
|
13
13
|
const maxRetries = 3
|
|
14
14
|
|
|
@@ -21,14 +21,17 @@ export const multicallViemAbiArray = async (
|
|
|
21
21
|
retry = true,
|
|
22
22
|
providerId = 0,
|
|
23
23
|
retries = maxRetries,
|
|
24
|
+
allowFailure = true,
|
|
25
|
+
batchSize = MULTICALL_DEFAULT_BATCH_SIZE,
|
|
26
|
+
logs = false,
|
|
24
27
|
): Promise<any[]> => {
|
|
25
28
|
try {
|
|
26
29
|
const provider = getEvmClient(chainId, providerId)
|
|
27
30
|
|
|
28
31
|
const abiIsArray = isArray(abi[0])
|
|
29
32
|
const returnData = await provider.multicall({
|
|
30
|
-
allowFailure
|
|
31
|
-
batchSize
|
|
33
|
+
allowFailure,
|
|
34
|
+
batchSize,
|
|
32
35
|
contracts: calls.map(({ address, name, params }, i) => ({
|
|
33
36
|
abi: abiIsArray ? (abi?.[i] as any) : abi,
|
|
34
37
|
address: address as any,
|
|
@@ -37,13 +40,18 @@ export const multicallViemAbiArray = async (
|
|
|
37
40
|
})),
|
|
38
41
|
})
|
|
39
42
|
|
|
43
|
+
// no failure - result is directly exposed
|
|
44
|
+
if (!allowFailure) return returnData
|
|
45
|
+
|
|
46
|
+
// allow failure, return 0x in case of errors
|
|
40
47
|
const res = (returnData as any[]).map(
|
|
41
48
|
({ result, status }: ViemMulticallresult) =>
|
|
42
49
|
status !== 'success' ? '0x' : result,
|
|
43
50
|
)
|
|
44
51
|
return res
|
|
45
52
|
} catch (error: any) {
|
|
46
|
-
|
|
53
|
+
// optionally log errors
|
|
54
|
+
if (logs) console.log('error in multicall', error)
|
|
47
55
|
retries--
|
|
48
56
|
if (retries < 0) throw new Error('Failed too often')
|
|
49
57
|
providerId++
|
|
@@ -56,6 +64,9 @@ export const multicallViemAbiArray = async (
|
|
|
56
64
|
retry,
|
|
57
65
|
providerId,
|
|
58
66
|
retries,
|
|
67
|
+
allowFailure,
|
|
68
|
+
batchSize,
|
|
69
|
+
logs,
|
|
59
70
|
)
|
|
60
71
|
}
|
|
61
72
|
}
|