@1delta/margin-fetcher 0.0.196 → 0.0.197
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/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +566 -173
- package/dist/index.js.map +1 -1
- package/dist/lending/public-data/fetchLender.d.ts.map +1 -1
- package/dist/prices/oracle-prices/fetchOraclePrices.d.ts +22 -13
- package/dist/prices/oracle-prices/fetchOraclePrices.d.ts.map +1 -1
- package/dist/prices/oracle-prices/fetchers/index.d.ts +1 -1
- package/dist/prices/oracle-prices/fetchers/index.d.ts.map +1 -1
- package/dist/prices/oracle-prices/fetchers/morpho.d.ts +7 -0
- package/dist/prices/oracle-prices/fetchers/morpho.d.ts.map +1 -1
- package/dist/prices/oracle-prices/index.d.ts +2 -2
- package/dist/prices/oracle-prices/index.d.ts.map +1 -1
- package/dist/prices/oracle-prices/types.d.ts +75 -0
- package/dist/prices/oracle-prices/types.d.ts.map +1 -1
- package/dist/types/providers.d.ts +12 -1
- package/dist/types/providers.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import './chunk-PR4QN5HX.js';
|
|
|
4
4
|
import { Lender, isAaveType, isCompoundV3, isMultiMarket, isInit, isMorphoType, isCompoundV2Type, isVenusType, isSumerType, AAVE_V3_LENDERS, AAVE_V2_LENDERS, isAaveV2Type, isAaveV32Type, isAaveV3Type, isEulerType, isYLDR, isCompoundV3Type, isTectonicType, isBenqiType, isLista } from '@1delta/lender-registry';
|
|
5
5
|
export { isAaveType, isAaveV2Type, isAaveV32Type, isAaveV3Type, isCompoundV3, isCompoundV3Type, isInit, isMorphoType, isMultiMarket, isYLDR } from '@1delta/lender-registry';
|
|
6
6
|
import lodash from 'lodash';
|
|
7
|
-
import { getEvmChain,
|
|
7
|
+
import { getEvmChain, multicallRetryUniversal, getEvmClient, getEvmClientUniversal } from '@1delta/providers';
|
|
8
8
|
import { MorphoLensAbi, MorphoBlueAbi } from '@1delta/abis';
|
|
9
9
|
export { MorphoLensAbi } from '@1delta/abis';
|
|
10
10
|
import { prepareDebitDataMulticall, prepareLenderDebitMulticall, parseDebitDataResult, parseLenderDebitResult, getPermit2ContractAddress, InitMarginAddresses } from '@1delta/calldata-sdk';
|
|
@@ -17998,7 +17998,7 @@ var getAbi = (lender) => {
|
|
|
17998
17998
|
if (isCompoundV2Type(lender)) return VenusLensAbi;
|
|
17999
17999
|
return [];
|
|
18000
18000
|
};
|
|
18001
|
-
var getLenderPublicData = async (chainId, lenders, prices, additionalYields,
|
|
18001
|
+
var getLenderPublicData = async (chainId, lenders, prices, additionalYields, multicallRetry, tokenList = async () => {
|
|
18002
18002
|
return {};
|
|
18003
18003
|
}) => {
|
|
18004
18004
|
let calls = [];
|
|
@@ -18009,16 +18009,12 @@ var getLenderPublicData = async (chainId, lenders, prices, additionalYields, mul
|
|
|
18009
18009
|
calls = [...calls, ...mappedCalls];
|
|
18010
18010
|
}
|
|
18011
18011
|
const [rawResults, list] = await Promise.all([
|
|
18012
|
-
|
|
18013
|
-
chainId,
|
|
18014
|
-
calls.map((call) => call.call),
|
|
18015
|
-
calls.map((call) => call.abi),
|
|
18016
|
-
chainId === Chain.ETHEREUM_MAINNET ? 500 : void 0
|
|
18017
|
-
|
|
18018
|
-
// retries = 3
|
|
18019
|
-
// provider = 0
|
|
18020
|
-
// allowFailure = false
|
|
18021
|
-
),
|
|
18012
|
+
multicallRetry({
|
|
18013
|
+
chain: chainId,
|
|
18014
|
+
calls: calls.map((call) => call.call),
|
|
18015
|
+
abi: calls.map((call) => call.abi),
|
|
18016
|
+
batchSize: chainId === Chain.ETHEREUM_MAINNET ? 500 : void 0
|
|
18017
|
+
}),
|
|
18022
18018
|
await tokenList()
|
|
18023
18019
|
]);
|
|
18024
18020
|
const invalidLenders = [];
|
|
@@ -18126,7 +18122,7 @@ function lenderCanUseApi(lender, chainId) {
|
|
|
18126
18122
|
}
|
|
18127
18123
|
return false;
|
|
18128
18124
|
}
|
|
18129
|
-
var getLenderPublicDataAll = async (chainId, lenders, prices, additionalYields,
|
|
18125
|
+
var getLenderPublicDataAll = async (chainId, lenders, prices, additionalYields, multicallRetry, tokenList, includeUnlistedMorphoMarkets = false) => {
|
|
18130
18126
|
const lendersApi = lenders.filter((l) => lenderCanUseApi(l, chainId));
|
|
18131
18127
|
const lendersOnChain = lenders.filter((l) => !lenderCanUseApi(l, chainId));
|
|
18132
18128
|
const onChain = getLenderPublicData(
|
|
@@ -18134,7 +18130,7 @@ var getLenderPublicDataAll = async (chainId, lenders, prices, additionalYields,
|
|
|
18134
18130
|
lendersOnChain,
|
|
18135
18131
|
prices,
|
|
18136
18132
|
additionalYields,
|
|
18137
|
-
|
|
18133
|
+
multicallRetry,
|
|
18138
18134
|
tokenList
|
|
18139
18135
|
);
|
|
18140
18136
|
const api = getLenderPublicDataViaApi(
|
|
@@ -24732,20 +24728,20 @@ function parseMergedResult(chainId, rawResults, prepared, lenderState) {
|
|
|
24732
24728
|
}
|
|
24733
24729
|
|
|
24734
24730
|
// src/lending/user-data/with-permissions/e2e.ts
|
|
24735
|
-
async function getMergedUserData(chainId, balanceQueries, permissionParams, lenderState,
|
|
24731
|
+
async function getMergedUserData(chainId, balanceQueries, permissionParams, lenderState, multicallRetry, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, maxRetries2 = 3, tokenApprovalParams) {
|
|
24736
24732
|
const prepared = await prepareMergedMulticallParams(
|
|
24737
24733
|
chainId,
|
|
24738
24734
|
balanceQueries,
|
|
24739
24735
|
permissionParams,
|
|
24740
24736
|
tokenApprovalParams
|
|
24741
24737
|
);
|
|
24742
|
-
const rawResults = await
|
|
24743
|
-
chainId,
|
|
24744
|
-
prepared.calls,
|
|
24745
|
-
prepared.abis,
|
|
24738
|
+
const rawResults = await multicallRetry({
|
|
24739
|
+
chain: chainId,
|
|
24740
|
+
calls: prepared.calls,
|
|
24741
|
+
abi: prepared.abis,
|
|
24746
24742
|
batchSize,
|
|
24747
|
-
maxRetries2
|
|
24748
|
-
);
|
|
24743
|
+
maxRetries: maxRetries2
|
|
24744
|
+
});
|
|
24749
24745
|
return parseMergedResult(chainId, rawResults, prepared, lenderState);
|
|
24750
24746
|
}
|
|
24751
24747
|
function toCompoundV2Shares(entry, amount) {
|
|
@@ -29057,16 +29053,16 @@ var fetchMainPrices = async (chainIds, rpcOverrides, lists = {}, retries = 3, ba
|
|
|
29057
29053
|
...CometAbi,
|
|
29058
29054
|
...VenusLensAbi
|
|
29059
29055
|
];
|
|
29060
|
-
const result = await
|
|
29061
|
-
chainId,
|
|
29062
|
-
allCalls,
|
|
29063
|
-
abis,
|
|
29056
|
+
const result = await multicallRetryUniversal({
|
|
29057
|
+
chain: chainId,
|
|
29058
|
+
calls: allCalls,
|
|
29059
|
+
abi: abis,
|
|
29064
29060
|
batchSize,
|
|
29065
|
-
retries,
|
|
29066
|
-
0,
|
|
29061
|
+
maxRetries: retries,
|
|
29062
|
+
providerId: 0,
|
|
29067
29063
|
allowFailure,
|
|
29068
|
-
rpcOverrides
|
|
29069
|
-
);
|
|
29064
|
+
overrdies: rpcOverrides
|
|
29065
|
+
});
|
|
29070
29066
|
return {
|
|
29071
29067
|
chainId,
|
|
29072
29068
|
result,
|
|
@@ -30365,6 +30361,13 @@ var aaveFetcher = {
|
|
|
30365
30361
|
parse: parseAaveResults2,
|
|
30366
30362
|
getAbi: getAaveAbi
|
|
30367
30363
|
};
|
|
30364
|
+
function morphoApiAvailable(chainId) {
|
|
30365
|
+
if (chainId === Chain.SONEIUM) return false;
|
|
30366
|
+
if (chainId === Chain.HEMI_NETWORK) return false;
|
|
30367
|
+
if (chainId === Chain.BERACHAIN) return false;
|
|
30368
|
+
if (chainId === Chain.SEI_NETWORK) return false;
|
|
30369
|
+
return true;
|
|
30370
|
+
}
|
|
30368
30371
|
function generateMarketId(oracle, loanAsset, collateralAsset) {
|
|
30369
30372
|
return `${oracle}${loanAsset}${collateralAsset}`.replace(/0x/gi, "").toUpperCase();
|
|
30370
30373
|
}
|
|
@@ -30456,6 +30459,111 @@ function parseMorphoResults2(data, meta, context) {
|
|
|
30456
30459
|
function getMorphoAbi() {
|
|
30457
30460
|
return ProxyOracleAbi;
|
|
30458
30461
|
}
|
|
30462
|
+
var MORPHO_GRAPHQL_URL = "https://blue-api.morpho.org/graphql";
|
|
30463
|
+
var PRICE_QUERY = (first, skip, chainId) => `
|
|
30464
|
+
query GetMarketPrices {
|
|
30465
|
+
markets(first: ${first}, skip: ${skip}, where: {
|
|
30466
|
+
chainId_in: [${chainId}],
|
|
30467
|
+
whitelisted: true
|
|
30468
|
+
},
|
|
30469
|
+
orderBy: SupplyAssetsUsd,
|
|
30470
|
+
orderDirection: Desc
|
|
30471
|
+
) {
|
|
30472
|
+
items {
|
|
30473
|
+
uniqueKey
|
|
30474
|
+
oracleAddress
|
|
30475
|
+
loanAsset {
|
|
30476
|
+
address
|
|
30477
|
+
decimals
|
|
30478
|
+
priceUsd
|
|
30479
|
+
}
|
|
30480
|
+
collateralAsset {
|
|
30481
|
+
address
|
|
30482
|
+
decimals
|
|
30483
|
+
priceUsd
|
|
30484
|
+
}
|
|
30485
|
+
state {
|
|
30486
|
+
price
|
|
30487
|
+
}
|
|
30488
|
+
}
|
|
30489
|
+
}
|
|
30490
|
+
}
|
|
30491
|
+
`;
|
|
30492
|
+
async function fetchMorphoGraphQLPrices(chainId) {
|
|
30493
|
+
if (!morphoApiAvailable(chainId)) return null;
|
|
30494
|
+
try {
|
|
30495
|
+
const pages = chainId === "1" ? [
|
|
30496
|
+
fetch(MORPHO_GRAPHQL_URL, {
|
|
30497
|
+
method: "POST",
|
|
30498
|
+
headers: { "Content-Type": "application/json" },
|
|
30499
|
+
body: JSON.stringify({
|
|
30500
|
+
query: PRICE_QUERY(200, 0, chainId)
|
|
30501
|
+
})
|
|
30502
|
+
}).then((r) => r.json()),
|
|
30503
|
+
fetch(MORPHO_GRAPHQL_URL, {
|
|
30504
|
+
method: "POST",
|
|
30505
|
+
headers: { "Content-Type": "application/json" },
|
|
30506
|
+
body: JSON.stringify({
|
|
30507
|
+
query: PRICE_QUERY(200, 200, chainId)
|
|
30508
|
+
})
|
|
30509
|
+
}).then((r) => r.json())
|
|
30510
|
+
] : [
|
|
30511
|
+
fetch(MORPHO_GRAPHQL_URL, {
|
|
30512
|
+
method: "POST",
|
|
30513
|
+
headers: { "Content-Type": "application/json" },
|
|
30514
|
+
body: JSON.stringify({
|
|
30515
|
+
query: PRICE_QUERY(200, 0, chainId)
|
|
30516
|
+
})
|
|
30517
|
+
}).then((r) => r.json())
|
|
30518
|
+
];
|
|
30519
|
+
const results = await Promise.all(pages);
|
|
30520
|
+
const allMarkets = [];
|
|
30521
|
+
for (const result of results) {
|
|
30522
|
+
const items = result?.data?.markets?.items;
|
|
30523
|
+
if (!Array.isArray(items)) return null;
|
|
30524
|
+
allMarkets.push(...items);
|
|
30525
|
+
}
|
|
30526
|
+
if (allMarkets.length === 0) return null;
|
|
30527
|
+
const entries = [];
|
|
30528
|
+
for (const market of allMarkets) {
|
|
30529
|
+
if (!market.collateralAsset) continue;
|
|
30530
|
+
const oracle = market.oracleAddress;
|
|
30531
|
+
const loanAsset = market.loanAsset.address.toLowerCase();
|
|
30532
|
+
const collateralAsset = market.collateralAsset.address.toLowerCase();
|
|
30533
|
+
const marketId = market.uniqueKey?.replace(/^0x/i, "").toUpperCase() ?? generateMarketId(oracle, loanAsset, collateralAsset);
|
|
30534
|
+
const lenderKey = generateMorphoLenderKey(marketId);
|
|
30535
|
+
const loanPriceUSD = market.loanAsset.priceUsd;
|
|
30536
|
+
const collateralPriceUSD = market.collateralAsset.priceUsd;
|
|
30537
|
+
const statePrice = market.state?.price;
|
|
30538
|
+
const oracleRatio = statePrice != null ? formatMorphoPrice(
|
|
30539
|
+
statePrice,
|
|
30540
|
+
market.loanAsset.decimals,
|
|
30541
|
+
market.collateralAsset.decimals
|
|
30542
|
+
) : 0;
|
|
30543
|
+
if (collateralPriceUSD != null && collateralPriceUSD > 0) {
|
|
30544
|
+
entries.push({
|
|
30545
|
+
asset: collateralAsset,
|
|
30546
|
+
price: oracleRatio || collateralPriceUSD,
|
|
30547
|
+
priceUSD: collateralPriceUSD,
|
|
30548
|
+
marketUid: createMarketUid(chainId, lenderKey, collateralAsset),
|
|
30549
|
+
targetLender: lenderKey
|
|
30550
|
+
});
|
|
30551
|
+
}
|
|
30552
|
+
if (loanPriceUSD != null && loanPriceUSD > 0) {
|
|
30553
|
+
entries.push({
|
|
30554
|
+
asset: loanAsset,
|
|
30555
|
+
price: oracleRatio > 0 ? 1 / oracleRatio : loanPriceUSD,
|
|
30556
|
+
priceUSD: loanPriceUSD,
|
|
30557
|
+
marketUid: createMarketUid(chainId, lenderKey, loanAsset),
|
|
30558
|
+
targetLender: lenderKey
|
|
30559
|
+
});
|
|
30560
|
+
}
|
|
30561
|
+
}
|
|
30562
|
+
return entries.length > 0 ? entries : null;
|
|
30563
|
+
} catch {
|
|
30564
|
+
return null;
|
|
30565
|
+
}
|
|
30566
|
+
}
|
|
30459
30567
|
var morphoFetcher = {
|
|
30460
30568
|
getCalls: getMorphoCalls2,
|
|
30461
30569
|
parse: parseMorphoResults2,
|
|
@@ -30806,162 +30914,447 @@ var eulerV2Fetcher = {
|
|
|
30806
30914
|
};
|
|
30807
30915
|
|
|
30808
30916
|
// src/prices/oracle-prices/fetchOraclePrices.ts
|
|
30809
|
-
|
|
30917
|
+
function countFailures(data, offset, count) {
|
|
30918
|
+
let failures = 0;
|
|
30919
|
+
for (let i = offset; i < offset + count; i++) {
|
|
30920
|
+
if (data[i] === "0x" || data[i] === void 0) failures++;
|
|
30921
|
+
}
|
|
30922
|
+
return failures;
|
|
30923
|
+
}
|
|
30924
|
+
function safeGetCalls(fetcherName, fn, errors) {
|
|
30925
|
+
try {
|
|
30926
|
+
return fn();
|
|
30927
|
+
} catch (e) {
|
|
30928
|
+
errors[fetcherName] = e instanceof Error ? e.message : String(e);
|
|
30929
|
+
return [];
|
|
30930
|
+
}
|
|
30931
|
+
}
|
|
30932
|
+
function buildGroup(fetcherName, results, parse, abi) {
|
|
30933
|
+
const group = {
|
|
30934
|
+
fetcherName,
|
|
30935
|
+
calls: [],
|
|
30936
|
+
abi,
|
|
30937
|
+
trackers: []
|
|
30938
|
+
};
|
|
30939
|
+
for (const fr of results) {
|
|
30940
|
+
group.trackers.push({
|
|
30941
|
+
lender: fr.lender,
|
|
30942
|
+
meta: fr.meta,
|
|
30943
|
+
offset: group.calls.length,
|
|
30944
|
+
count: fr.calls.length,
|
|
30945
|
+
parse
|
|
30946
|
+
});
|
|
30947
|
+
group.calls.push(...fr.calls);
|
|
30948
|
+
}
|
|
30949
|
+
return group;
|
|
30950
|
+
}
|
|
30951
|
+
function isFailed(r) {
|
|
30952
|
+
return r === "0x" || r === void 0;
|
|
30953
|
+
}
|
|
30954
|
+
async function executeGroup(group, chainId, chainBatchSize, retries, allowFailure, rpcOverrides, failRetries = 2) {
|
|
30955
|
+
if (group.calls.length === 0) {
|
|
30956
|
+
return { results: [] };
|
|
30957
|
+
}
|
|
30958
|
+
try {
|
|
30959
|
+
const results = await multicallRetryUniversal({
|
|
30960
|
+
chain: chainId,
|
|
30961
|
+
calls: group.calls,
|
|
30962
|
+
abi: group.abi,
|
|
30963
|
+
batchSize: chainBatchSize,
|
|
30964
|
+
maxRetries: retries,
|
|
30965
|
+
providerId: void 0,
|
|
30966
|
+
allowFailure,
|
|
30967
|
+
overrdies: rpcOverrides,
|
|
30968
|
+
logErrors: true
|
|
30969
|
+
});
|
|
30970
|
+
let failedIndices = results.map((r, i) => isFailed(r) ? i : -1).filter((i) => i >= 0);
|
|
30971
|
+
for (let round = 0; round < failRetries && failedIndices.length > 0; round++) {
|
|
30972
|
+
const retryCalls = failedIndices.map((i) => group.calls[i]);
|
|
30973
|
+
try {
|
|
30974
|
+
const retryResults = await multicallRetryUniversal({
|
|
30975
|
+
chain: chainId,
|
|
30976
|
+
calls: retryCalls,
|
|
30977
|
+
abi: group.abi,
|
|
30978
|
+
batchSize: chainBatchSize,
|
|
30979
|
+
maxRetries: retries,
|
|
30980
|
+
providerId: round + 1,
|
|
30981
|
+
// rotate to next RPC provider
|
|
30982
|
+
allowFailure,
|
|
30983
|
+
overrdies: rpcOverrides,
|
|
30984
|
+
logErrors: true
|
|
30985
|
+
});
|
|
30986
|
+
const stillFailed = [];
|
|
30987
|
+
for (let j = 0; j < failedIndices.length; j++) {
|
|
30988
|
+
if (!isFailed(retryResults[j])) {
|
|
30989
|
+
results[failedIndices[j]] = retryResults[j];
|
|
30990
|
+
} else {
|
|
30991
|
+
stillFailed.push(failedIndices[j]);
|
|
30992
|
+
}
|
|
30993
|
+
}
|
|
30994
|
+
failedIndices = stillFailed;
|
|
30995
|
+
} catch {
|
|
30996
|
+
break;
|
|
30997
|
+
}
|
|
30998
|
+
}
|
|
30999
|
+
const failCount = results.filter((r) => isFailed(r)).length;
|
|
31000
|
+
const allFailed = failCount === results.length && results.length > 0;
|
|
31001
|
+
return {
|
|
31002
|
+
results,
|
|
31003
|
+
error: allFailed ? `All ${group.calls.length} calls returned 0x (${group.fetcherName})` : void 0
|
|
31004
|
+
};
|
|
31005
|
+
} catch (e) {
|
|
31006
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
31007
|
+
return {
|
|
31008
|
+
results: Array(group.calls.length).fill("0x"),
|
|
31009
|
+
error: `multicall threw: ${msg.slice(0, 200)}`
|
|
31010
|
+
};
|
|
31011
|
+
}
|
|
31012
|
+
}
|
|
31013
|
+
async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3, batchSize = void 0, allowFailure = true, basePrices = {}, morphoMarketOverrides, listaMarketOverrides, stalenessThresholdSeconds = 3600, onlyFetchers) {
|
|
31014
|
+
const totalStart = Date.now();
|
|
30810
31015
|
const result = {};
|
|
30811
|
-
const combinedAbi = [
|
|
30812
|
-
...AaveOracleAbi,
|
|
30813
|
-
...ProxyOracleAbi,
|
|
30814
|
-
...CompoundV2OracleAbi,
|
|
30815
|
-
...ChainlinkAggregatorAbi,
|
|
30816
|
-
...vaultLensAbi
|
|
30817
|
-
];
|
|
30818
31016
|
const chainPromises = chainIds.map(async (chainId) => {
|
|
31017
|
+
const chainStart = Date.now();
|
|
30819
31018
|
const chainResult = {};
|
|
30820
31019
|
const tokenList = lists[chainId] ?? {};
|
|
30821
|
-
const
|
|
30822
|
-
const
|
|
30823
|
-
const
|
|
30824
|
-
const
|
|
30825
|
-
|
|
30826
|
-
|
|
30827
|
-
const
|
|
30828
|
-
const
|
|
30829
|
-
|
|
30830
|
-
|
|
30831
|
-
|
|
30832
|
-
|
|
30833
|
-
|
|
30834
|
-
|
|
30835
|
-
|
|
30836
|
-
|
|
30837
|
-
|
|
30838
|
-
|
|
30839
|
-
|
|
30840
|
-
|
|
30841
|
-
|
|
30842
|
-
|
|
30843
|
-
|
|
30844
|
-
|
|
30845
|
-
|
|
30846
|
-
|
|
30847
|
-
|
|
30848
|
-
|
|
30849
|
-
|
|
30850
|
-
|
|
30851
|
-
|
|
30852
|
-
|
|
30853
|
-
|
|
30854
|
-
|
|
30855
|
-
|
|
30856
|
-
|
|
30857
|
-
|
|
30858
|
-
|
|
30859
|
-
|
|
30860
|
-
|
|
30861
|
-
|
|
30862
|
-
|
|
30863
|
-
|
|
30864
|
-
|
|
30865
|
-
|
|
30866
|
-
|
|
30867
|
-
|
|
30868
|
-
|
|
30869
|
-
|
|
30870
|
-
|
|
30871
|
-
|
|
30872
|
-
|
|
30873
|
-
|
|
30874
|
-
|
|
30875
|
-
|
|
30876
|
-
|
|
30877
|
-
|
|
30878
|
-
|
|
30879
|
-
|
|
30880
|
-
|
|
30881
|
-
|
|
30882
|
-
|
|
30883
|
-
|
|
30884
|
-
|
|
30885
|
-
|
|
30886
|
-
|
|
30887
|
-
|
|
30888
|
-
|
|
30889
|
-
|
|
30890
|
-
|
|
30891
|
-
|
|
30892
|
-
|
|
30893
|
-
|
|
30894
|
-
|
|
31020
|
+
const getCallsErrors = {};
|
|
31021
|
+
const trackerDiags = [];
|
|
31022
|
+
const unresolvedMorphoMarkets = [];
|
|
31023
|
+
const staleFeeds = [];
|
|
31024
|
+
const multicallErrors = [];
|
|
31025
|
+
const active = onlyFetchers ? new Set(onlyFetchers.map((f) => f.toLowerCase())) : null;
|
|
31026
|
+
const isActive = (name) => !active || active.has(name);
|
|
31027
|
+
const aaveResults = isActive("aave") ? safeGetCalls(
|
|
31028
|
+
"aave",
|
|
31029
|
+
() => aaveFetcher.getCalls(chainId),
|
|
31030
|
+
getCallsErrors
|
|
31031
|
+
) : [];
|
|
31032
|
+
const compoundV2Results = isActive("compoundv2") ? safeGetCalls(
|
|
31033
|
+
"compoundV2",
|
|
31034
|
+
() => compoundV2Fetcher.getCalls(chainId),
|
|
31035
|
+
getCallsErrors
|
|
31036
|
+
) : [];
|
|
31037
|
+
const compoundV3Results = isActive("compoundv3") ? safeGetCalls(
|
|
31038
|
+
"compoundV3",
|
|
31039
|
+
() => compoundV3Fetcher.getCalls(chainId),
|
|
31040
|
+
getCallsErrors
|
|
31041
|
+
) : [];
|
|
31042
|
+
const listaResults = isActive("lista") ? safeGetCalls(
|
|
31043
|
+
"lista",
|
|
31044
|
+
() => listaFetcher.getCalls(chainId, {
|
|
31045
|
+
marketOverrides: listaMarketOverrides
|
|
31046
|
+
}),
|
|
31047
|
+
getCallsErrors
|
|
31048
|
+
) : [];
|
|
31049
|
+
const eulerResults = isActive("eulerv2") ? safeGetCalls(
|
|
31050
|
+
"eulerV2",
|
|
31051
|
+
() => eulerV2Fetcher.getCalls(chainId),
|
|
31052
|
+
getCallsErrors
|
|
31053
|
+
) : [];
|
|
31054
|
+
const morphoResults = isActive("morpho") ? safeGetCalls(
|
|
31055
|
+
"morpho",
|
|
31056
|
+
() => morphoFetcher.getCalls(chainId, {
|
|
31057
|
+
marketOverrides: morphoMarketOverrides
|
|
31058
|
+
}),
|
|
31059
|
+
getCallsErrors
|
|
31060
|
+
) : [];
|
|
31061
|
+
const aaveGroup = buildGroup(
|
|
31062
|
+
"aave",
|
|
31063
|
+
aaveResults,
|
|
31064
|
+
aaveFetcher.parse,
|
|
31065
|
+
AaveOracleAbi
|
|
31066
|
+
);
|
|
31067
|
+
const compoundV2Group = buildGroup(
|
|
31068
|
+
"compoundV2",
|
|
31069
|
+
compoundV2Results,
|
|
31070
|
+
compoundV2Fetcher.parse,
|
|
31071
|
+
CompoundV2OracleAbi
|
|
31072
|
+
);
|
|
31073
|
+
const compoundV3Group = buildGroup(
|
|
31074
|
+
"compoundV3",
|
|
31075
|
+
compoundV3Results,
|
|
31076
|
+
compoundV3Fetcher.parse,
|
|
31077
|
+
ChainlinkAggregatorAbi
|
|
31078
|
+
);
|
|
31079
|
+
const listaGroup = buildGroup(
|
|
31080
|
+
"lista",
|
|
31081
|
+
listaResults,
|
|
31082
|
+
listaFetcher.parse,
|
|
31083
|
+
ProxyOracleAbi
|
|
31084
|
+
);
|
|
31085
|
+
const eulerGroup = buildGroup(
|
|
31086
|
+
"eulerV2",
|
|
31087
|
+
eulerResults,
|
|
31088
|
+
eulerV2Fetcher.parse,
|
|
31089
|
+
vaultLensAbi
|
|
31090
|
+
);
|
|
31091
|
+
const morphoGroup = buildGroup(
|
|
31092
|
+
"morpho",
|
|
31093
|
+
morphoResults,
|
|
31094
|
+
morphoFetcher.parse,
|
|
31095
|
+
ProxyOracleAbi
|
|
31096
|
+
);
|
|
31097
|
+
const allGroups = [
|
|
31098
|
+
aaveGroup,
|
|
31099
|
+
compoundV2Group,
|
|
31100
|
+
compoundV3Group,
|
|
31101
|
+
listaGroup,
|
|
31102
|
+
eulerGroup,
|
|
31103
|
+
morphoGroup
|
|
31104
|
+
];
|
|
31105
|
+
const totalCalls = allGroups.reduce((s, g) => s + g.calls.length, 0);
|
|
31106
|
+
if (totalCalls === 0) {
|
|
31107
|
+
const diag2 = {
|
|
31108
|
+
chainId,
|
|
31109
|
+
totalCalls: 0,
|
|
31110
|
+
totalFailedCalls: 0,
|
|
31111
|
+
totalParsedEntries: 0,
|
|
31112
|
+
durationMs: Date.now() - chainStart,
|
|
31113
|
+
trackers: [],
|
|
31114
|
+
getCallsErrors,
|
|
31115
|
+
unresolvedMorphoMarkets: [],
|
|
31116
|
+
staleFeeds: []
|
|
31117
|
+
};
|
|
31118
|
+
return { chainId, data: chainResult, diagnostic: diag2 };
|
|
30895
31119
|
}
|
|
30896
|
-
const
|
|
31120
|
+
const chainBatchSize = batchSize?.[chainId];
|
|
31121
|
+
const morphoGqlPromise = isActive("morpho") ? fetchMorphoGraphQLPrices(chainId) : Promise.resolve(null);
|
|
31122
|
+
const [
|
|
31123
|
+
aaveData,
|
|
31124
|
+
compoundV2Data,
|
|
31125
|
+
compoundV3Data,
|
|
31126
|
+
listaData,
|
|
31127
|
+
eulerData,
|
|
31128
|
+
morphoGqlEntries
|
|
31129
|
+
] = await Promise.all([
|
|
31130
|
+
executeGroup(
|
|
31131
|
+
aaveGroup,
|
|
31132
|
+
chainId,
|
|
31133
|
+
chainBatchSize,
|
|
31134
|
+
retries,
|
|
31135
|
+
allowFailure,
|
|
31136
|
+
rpcOverrides
|
|
31137
|
+
),
|
|
31138
|
+
executeGroup(
|
|
31139
|
+
compoundV2Group,
|
|
31140
|
+
chainId,
|
|
31141
|
+
chainBatchSize,
|
|
31142
|
+
retries,
|
|
31143
|
+
allowFailure,
|
|
31144
|
+
rpcOverrides
|
|
31145
|
+
),
|
|
31146
|
+
executeGroup(
|
|
31147
|
+
compoundV3Group,
|
|
31148
|
+
chainId,
|
|
31149
|
+
chainBatchSize,
|
|
31150
|
+
retries,
|
|
31151
|
+
allowFailure,
|
|
31152
|
+
rpcOverrides
|
|
31153
|
+
),
|
|
31154
|
+
executeGroup(
|
|
31155
|
+
listaGroup,
|
|
31156
|
+
chainId,
|
|
31157
|
+
chainBatchSize,
|
|
31158
|
+
retries,
|
|
31159
|
+
allowFailure,
|
|
31160
|
+
rpcOverrides
|
|
31161
|
+
),
|
|
31162
|
+
executeGroup(
|
|
31163
|
+
eulerGroup,
|
|
31164
|
+
chainId,
|
|
31165
|
+
chainBatchSize,
|
|
31166
|
+
retries,
|
|
31167
|
+
allowFailure,
|
|
31168
|
+
rpcOverrides
|
|
31169
|
+
),
|
|
31170
|
+
morphoGqlPromise
|
|
31171
|
+
]);
|
|
31172
|
+
const morphoData = morphoGqlEntries != null ? { results: [], error: void 0 } : await executeGroup(
|
|
31173
|
+
morphoGroup,
|
|
30897
31174
|
chainId,
|
|
30898
|
-
|
|
30899
|
-
combinedAbi,
|
|
30900
|
-
batchSize?.[chainId],
|
|
31175
|
+
chainBatchSize,
|
|
30901
31176
|
retries,
|
|
30902
|
-
void 0,
|
|
30903
31177
|
allowFailure,
|
|
30904
31178
|
rpcOverrides
|
|
30905
31179
|
);
|
|
31180
|
+
const useMorphoGql = morphoGqlEntries != null;
|
|
31181
|
+
const groupResults = [
|
|
31182
|
+
{ group: aaveGroup, data: aaveData },
|
|
31183
|
+
{ group: compoundV2Group, data: compoundV2Data },
|
|
31184
|
+
{ group: compoundV3Group, data: compoundV3Data },
|
|
31185
|
+
{ group: listaGroup, data: listaData },
|
|
31186
|
+
{ group: eulerGroup, data: eulerData },
|
|
31187
|
+
...useMorphoGql ? [] : [{ group: morphoGroup, data: morphoData }]
|
|
31188
|
+
];
|
|
31189
|
+
for (const { group, data } of groupResults) {
|
|
31190
|
+
if (data.error) {
|
|
31191
|
+
multicallErrors.push(`[${group.fetcherName}] ${data.error}`);
|
|
31192
|
+
}
|
|
31193
|
+
}
|
|
30906
31194
|
const usdPrices = { ...basePrices };
|
|
30907
|
-
const
|
|
30908
|
-
const
|
|
30909
|
-
|
|
30910
|
-
tracker.offset
|
|
30911
|
-
|
|
30912
|
-
|
|
30913
|
-
|
|
30914
|
-
|
|
30915
|
-
|
|
30916
|
-
|
|
30917
|
-
|
|
30918
|
-
|
|
30919
|
-
|
|
30920
|
-
|
|
30921
|
-
|
|
30922
|
-
|
|
30923
|
-
|
|
30924
|
-
|
|
30925
|
-
const
|
|
30926
|
-
|
|
30927
|
-
|
|
31195
|
+
const parseTrackers = (group, data, updatePrices = true, filter) => {
|
|
31196
|
+
const trackers = filter ? group.trackers.filter(filter) : group.trackers;
|
|
31197
|
+
for (const tracker of trackers) {
|
|
31198
|
+
const failedCalls = countFailures(data, tracker.offset, tracker.count);
|
|
31199
|
+
const diag2 = {
|
|
31200
|
+
lender: tracker.lender,
|
|
31201
|
+
callCount: tracker.count,
|
|
31202
|
+
failedCalls,
|
|
31203
|
+
parsedEntries: 0
|
|
31204
|
+
};
|
|
31205
|
+
try {
|
|
31206
|
+
const dataSlice = data.slice(
|
|
31207
|
+
tracker.offset,
|
|
31208
|
+
tracker.offset + tracker.count
|
|
31209
|
+
);
|
|
31210
|
+
const context = { chainId, usdPrices, tokenList };
|
|
31211
|
+
const entries = tracker.parse(dataSlice, tracker.meta, context);
|
|
31212
|
+
diag2.parsedEntries = entries.length;
|
|
31213
|
+
for (const entry of entries) {
|
|
31214
|
+
const lender = entry.targetLender ?? tracker.lender;
|
|
31215
|
+
if (!chainResult[lender]) {
|
|
31216
|
+
chainResult[lender] = [];
|
|
31217
|
+
}
|
|
31218
|
+
chainResult[lender].push(entry);
|
|
31219
|
+
if (updatePrices) {
|
|
31220
|
+
const oracleKey = tokenList[entry.asset]?.assetGroup ?? `${chainId}-${entry.asset}`;
|
|
31221
|
+
usdPrices[oracleKey] = entry.priceUSD;
|
|
31222
|
+
usdPrices[entry.asset] = entry.priceUSD;
|
|
31223
|
+
}
|
|
31224
|
+
}
|
|
31225
|
+
} catch (e) {
|
|
31226
|
+
diag2.parseError = e instanceof Error ? e.message : String(e);
|
|
30928
31227
|
}
|
|
31228
|
+
trackerDiags.push(diag2);
|
|
30929
31229
|
}
|
|
30930
31230
|
};
|
|
30931
|
-
|
|
30932
|
-
|
|
30933
|
-
|
|
30934
|
-
|
|
30935
|
-
(t) =>
|
|
31231
|
+
parseTrackers(
|
|
31232
|
+
aaveGroup,
|
|
31233
|
+
aaveData.results,
|
|
31234
|
+
true,
|
|
31235
|
+
(t) => !t.meta.baseAssetSource
|
|
30936
31236
|
);
|
|
30937
|
-
|
|
30938
|
-
|
|
30939
|
-
);
|
|
30940
|
-
|
|
30941
|
-
|
|
30942
|
-
|
|
30943
|
-
|
|
30944
|
-
|
|
30945
|
-
|
|
30946
|
-
|
|
30947
|
-
|
|
30948
|
-
|
|
30949
|
-
|
|
30950
|
-
|
|
31237
|
+
parseTrackers(compoundV2Group, compoundV2Data.results);
|
|
31238
|
+
parseTrackers(compoundV3Group, compoundV3Data.results);
|
|
31239
|
+
parseTrackers(listaGroup, listaData.results);
|
|
31240
|
+
parseTrackers(eulerGroup, eulerData.results);
|
|
31241
|
+
if (stalenessThresholdSeconds > 0) {
|
|
31242
|
+
const nowSeconds = Math.floor(Date.now() / 1e3);
|
|
31243
|
+
for (const tracker of compoundV3Group.trackers) {
|
|
31244
|
+
const meta = tracker.meta;
|
|
31245
|
+
for (let i = 0; i < tracker.count; i++) {
|
|
31246
|
+
const raw = compoundV3Data.results[tracker.offset + i];
|
|
31247
|
+
if (!raw || raw === "0x" || !Array.isArray(raw)) continue;
|
|
31248
|
+
const updatedAt = Number(raw[3]);
|
|
31249
|
+
if (updatedAt > 0) {
|
|
31250
|
+
const staleSeconds = nowSeconds - updatedAt;
|
|
31251
|
+
if (staleSeconds > stalenessThresholdSeconds) {
|
|
31252
|
+
const queryMeta = meta[i];
|
|
31253
|
+
staleFeeds.push({
|
|
31254
|
+
asset: queryMeta?.asset?.toLowerCase() ?? "unknown",
|
|
31255
|
+
lender: queryMeta?.lender ?? tracker.lender,
|
|
31256
|
+
oracle: queryMeta?.oracle ?? "unknown",
|
|
31257
|
+
staleSeconds
|
|
31258
|
+
});
|
|
31259
|
+
}
|
|
31260
|
+
}
|
|
31261
|
+
}
|
|
31262
|
+
}
|
|
30951
31263
|
}
|
|
30952
|
-
|
|
30953
|
-
|
|
31264
|
+
parseTrackers(
|
|
31265
|
+
aaveGroup,
|
|
31266
|
+
aaveData.results,
|
|
31267
|
+
true,
|
|
31268
|
+
(t) => !!t.meta.baseAssetSource
|
|
30954
31269
|
);
|
|
30955
|
-
|
|
30956
|
-
|
|
31270
|
+
if (useMorphoGql) {
|
|
31271
|
+
const morphoGqlDiag = {
|
|
31272
|
+
lender: "MORPHO_BLUE (GraphQL)",
|
|
31273
|
+
callCount: 0,
|
|
31274
|
+
failedCalls: 0,
|
|
31275
|
+
parsedEntries: morphoGqlEntries.length
|
|
31276
|
+
};
|
|
31277
|
+
for (const entry of morphoGqlEntries) {
|
|
31278
|
+
const lender = entry.targetLender ?? "MORPHO_BLUE";
|
|
31279
|
+
if (!chainResult[lender]) chainResult[lender] = [];
|
|
31280
|
+
chainResult[lender].push(entry);
|
|
31281
|
+
}
|
|
31282
|
+
trackerDiags.push(morphoGqlDiag);
|
|
31283
|
+
} else {
|
|
31284
|
+
for (const tracker of morphoGroup.trackers) {
|
|
31285
|
+
const meta = tracker.meta;
|
|
31286
|
+
if (meta.markets) {
|
|
31287
|
+
for (const market of meta.markets) {
|
|
31288
|
+
const loanAsset = market.loanAsset?.toLowerCase();
|
|
31289
|
+
const collateralAsset = market.collateralAsset?.toLowerCase();
|
|
31290
|
+
const loanOracleKey = tokenList[loanAsset]?.assetGroup ?? `${chainId}-${loanAsset}`;
|
|
31291
|
+
const collateralOracleKey = tokenList[collateralAsset]?.assetGroup ?? `${chainId}-${collateralAsset}`;
|
|
31292
|
+
const hasLoanPrice = usdPrices[loanOracleKey] !== void 0 || usdPrices[loanAsset] !== void 0;
|
|
31293
|
+
const hasCollateralPrice = usdPrices[collateralOracleKey] !== void 0 || usdPrices[collateralAsset] !== void 0;
|
|
31294
|
+
if (!hasLoanPrice && !hasCollateralPrice) {
|
|
31295
|
+
unresolvedMorphoMarkets.push(
|
|
31296
|
+
`${market.oracle}:${loanAsset}/${collateralAsset}`
|
|
31297
|
+
);
|
|
31298
|
+
}
|
|
31299
|
+
}
|
|
31300
|
+
}
|
|
31301
|
+
}
|
|
31302
|
+
parseTrackers(morphoGroup, morphoData.results, false);
|
|
30957
31303
|
}
|
|
30958
|
-
|
|
31304
|
+
const totalFailedCalls = trackerDiags.reduce(
|
|
31305
|
+
(sum, d) => sum + d.failedCalls,
|
|
31306
|
+
0
|
|
31307
|
+
);
|
|
31308
|
+
const totalParsedEntries = trackerDiags.reduce(
|
|
31309
|
+
(sum, d) => sum + d.parsedEntries,
|
|
31310
|
+
0
|
|
31311
|
+
);
|
|
31312
|
+
const diag = {
|
|
31313
|
+
chainId,
|
|
31314
|
+
totalCalls,
|
|
31315
|
+
totalFailedCalls,
|
|
31316
|
+
totalParsedEntries,
|
|
31317
|
+
durationMs: Date.now() - chainStart,
|
|
31318
|
+
trackers: trackerDiags,
|
|
31319
|
+
getCallsErrors,
|
|
31320
|
+
chainError: multicallErrors.length > 0 ? multicallErrors.join("; ") : void 0,
|
|
31321
|
+
unresolvedMorphoMarkets,
|
|
31322
|
+
staleFeeds
|
|
31323
|
+
};
|
|
31324
|
+
return { chainId, data: chainResult, diagnostic: diag };
|
|
30959
31325
|
});
|
|
30960
|
-
const
|
|
30961
|
-
|
|
30962
|
-
|
|
31326
|
+
const settled = await Promise.allSettled(chainPromises);
|
|
31327
|
+
const chainDiagnostics = [];
|
|
31328
|
+
const failedChains = [];
|
|
31329
|
+
for (let i = 0; i < settled.length; i++) {
|
|
31330
|
+
const settlement = settled[i];
|
|
31331
|
+
const chainId = chainIds[i];
|
|
31332
|
+
if (settlement.status === "fulfilled") {
|
|
31333
|
+
const { data, diagnostic } = settlement.value;
|
|
31334
|
+
result[chainId] = data;
|
|
31335
|
+
chainDiagnostics.push(diagnostic);
|
|
31336
|
+
} else {
|
|
31337
|
+
failedChains.push(chainId);
|
|
31338
|
+
chainDiagnostics.push({
|
|
31339
|
+
chainId,
|
|
31340
|
+
totalCalls: 0,
|
|
31341
|
+
totalFailedCalls: 0,
|
|
31342
|
+
totalParsedEntries: 0,
|
|
31343
|
+
durationMs: 0,
|
|
31344
|
+
trackers: [],
|
|
31345
|
+
getCallsErrors: {},
|
|
31346
|
+
chainError: settlement.reason instanceof Error ? settlement.reason.message : String(settlement.reason),
|
|
31347
|
+
unresolvedMorphoMarkets: [],
|
|
31348
|
+
staleFeeds: []
|
|
31349
|
+
});
|
|
31350
|
+
}
|
|
30963
31351
|
}
|
|
30964
|
-
|
|
31352
|
+
const diagnostics = {
|
|
31353
|
+
chains: chainDiagnostics,
|
|
31354
|
+
totalDurationMs: Date.now() - totalStart,
|
|
31355
|
+
failedChains
|
|
31356
|
+
};
|
|
31357
|
+
return { prices: result, diagnostics };
|
|
30965
31358
|
}
|
|
30966
31359
|
var DEFAULT_PRIORITY = {
|
|
30967
31360
|
chainPriority: [
|
|
@@ -31175,7 +31568,7 @@ var FLASHLOAN_ENABLED_MASK = BigInt(
|
|
|
31175
31568
|
function getFlashLoanEnabled(data) {
|
|
31176
31569
|
return (data & ~FLASHLOAN_ENABLED_MASK) !== BigInt(0);
|
|
31177
31570
|
}
|
|
31178
|
-
async function fetchFlashLiquidityForChain(chain,
|
|
31571
|
+
async function fetchFlashLiquidityForChain(chain, multicallRetry, list = {}) {
|
|
31179
31572
|
let callLengths = {};
|
|
31180
31573
|
let aaveAssets = {};
|
|
31181
31574
|
let aaveCalls = [];
|
|
@@ -31290,15 +31683,15 @@ async function fetchFlashLiquidityForChain(chain, multicallRetry3, list = {}) {
|
|
|
31290
31683
|
...balancerV3Calls,
|
|
31291
31684
|
...uniswapV4Calls
|
|
31292
31685
|
];
|
|
31293
|
-
const rawResults = await
|
|
31686
|
+
const rawResults = await multicallRetry({
|
|
31294
31687
|
chain,
|
|
31295
31688
|
calls,
|
|
31296
|
-
FlashAbi,
|
|
31297
|
-
DEFAULT_BATCH_SIZE,
|
|
31298
|
-
3,
|
|
31299
|
-
0,
|
|
31300
|
-
false
|
|
31301
|
-
);
|
|
31689
|
+
abi: FlashAbi,
|
|
31690
|
+
batchSize: DEFAULT_BATCH_SIZE,
|
|
31691
|
+
maxRetries: 3,
|
|
31692
|
+
providerId: 0,
|
|
31693
|
+
allowFailure: false
|
|
31694
|
+
});
|
|
31302
31695
|
let liquidity = {};
|
|
31303
31696
|
let currentOffset = 0;
|
|
31304
31697
|
aaveProtocols.forEach((aave) => {
|