@1delta/margin-fetcher 0.0.195 → 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 +578 -180
- 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 +28 -15
- 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/dist/utils/index.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';
|
|
@@ -7485,16 +7485,21 @@ var DISABLED_COMPOUNDS = {
|
|
|
7485
7485
|
[Chain.ETHEREUM_MAINNET]: [Lender.CREAM_FINANCE]
|
|
7486
7486
|
};
|
|
7487
7487
|
var ENABLED_EULER_V2_CHAINS = [
|
|
7488
|
+
Chain.ETHEREUM_MAINNET,
|
|
7488
7489
|
Chain.BNB_SMART_CHAIN_MAINNET,
|
|
7489
|
-
Chain.PLASMA_MAINNET,
|
|
7490
|
-
Chain.BERACHAIN,
|
|
7491
|
-
Chain.HYPEREVM,
|
|
7492
7490
|
Chain.UNICHAIN,
|
|
7493
|
-
Chain.SONIC_MAINNET,
|
|
7494
7491
|
Chain.MONAD_MAINNET,
|
|
7495
|
-
Chain.
|
|
7496
|
-
|
|
7497
|
-
|
|
7492
|
+
Chain.SONIC_MAINNET,
|
|
7493
|
+
Chain.TAC_MAINNET,
|
|
7494
|
+
Chain.SWELLCHAIN,
|
|
7495
|
+
Chain.BASE,
|
|
7496
|
+
Chain.PLASMA_MAINNET,
|
|
7497
|
+
Chain.ARBITRUM_ONE,
|
|
7498
|
+
Chain.AVALANCHE_C_CHAIN,
|
|
7499
|
+
Chain.LINEA,
|
|
7500
|
+
Chain.BOB,
|
|
7501
|
+
Chain.BERACHAIN,
|
|
7502
|
+
Chain.HYPEREVM
|
|
7498
7503
|
];
|
|
7499
7504
|
var getLendersForChain = (c) => {
|
|
7500
7505
|
let lenders = [];
|
|
@@ -17993,7 +17998,7 @@ var getAbi = (lender) => {
|
|
|
17993
17998
|
if (isCompoundV2Type(lender)) return VenusLensAbi;
|
|
17994
17999
|
return [];
|
|
17995
18000
|
};
|
|
17996
|
-
var getLenderPublicData = async (chainId, lenders, prices, additionalYields,
|
|
18001
|
+
var getLenderPublicData = async (chainId, lenders, prices, additionalYields, multicallRetry, tokenList = async () => {
|
|
17997
18002
|
return {};
|
|
17998
18003
|
}) => {
|
|
17999
18004
|
let calls = [];
|
|
@@ -18004,16 +18009,12 @@ var getLenderPublicData = async (chainId, lenders, prices, additionalYields, mul
|
|
|
18004
18009
|
calls = [...calls, ...mappedCalls];
|
|
18005
18010
|
}
|
|
18006
18011
|
const [rawResults, list] = await Promise.all([
|
|
18007
|
-
|
|
18008
|
-
chainId,
|
|
18009
|
-
calls.map((call) => call.call),
|
|
18010
|
-
calls.map((call) => call.abi),
|
|
18011
|
-
chainId === Chain.ETHEREUM_MAINNET ? 500 : void 0
|
|
18012
|
-
|
|
18013
|
-
// retries = 3
|
|
18014
|
-
// provider = 0
|
|
18015
|
-
// allowFailure = false
|
|
18016
|
-
),
|
|
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
|
+
}),
|
|
18017
18018
|
await tokenList()
|
|
18018
18019
|
]);
|
|
18019
18020
|
const invalidLenders = [];
|
|
@@ -18121,7 +18122,7 @@ function lenderCanUseApi(lender, chainId) {
|
|
|
18121
18122
|
}
|
|
18122
18123
|
return false;
|
|
18123
18124
|
}
|
|
18124
|
-
var getLenderPublicDataAll = async (chainId, lenders, prices, additionalYields,
|
|
18125
|
+
var getLenderPublicDataAll = async (chainId, lenders, prices, additionalYields, multicallRetry, tokenList, includeUnlistedMorphoMarkets = false) => {
|
|
18125
18126
|
const lendersApi = lenders.filter((l) => lenderCanUseApi(l, chainId));
|
|
18126
18127
|
const lendersOnChain = lenders.filter((l) => !lenderCanUseApi(l, chainId));
|
|
18127
18128
|
const onChain = getLenderPublicData(
|
|
@@ -18129,7 +18130,7 @@ var getLenderPublicDataAll = async (chainId, lenders, prices, additionalYields,
|
|
|
18129
18130
|
lendersOnChain,
|
|
18130
18131
|
prices,
|
|
18131
18132
|
additionalYields,
|
|
18132
|
-
|
|
18133
|
+
multicallRetry,
|
|
18133
18134
|
tokenList
|
|
18134
18135
|
);
|
|
18135
18136
|
const api = getLenderPublicDataViaApi(
|
|
@@ -24727,20 +24728,20 @@ function parseMergedResult(chainId, rawResults, prepared, lenderState) {
|
|
|
24727
24728
|
}
|
|
24728
24729
|
|
|
24729
24730
|
// src/lending/user-data/with-permissions/e2e.ts
|
|
24730
|
-
async function getMergedUserData(chainId, balanceQueries, permissionParams, lenderState,
|
|
24731
|
+
async function getMergedUserData(chainId, balanceQueries, permissionParams, lenderState, multicallRetry, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, maxRetries2 = 3, tokenApprovalParams) {
|
|
24731
24732
|
const prepared = await prepareMergedMulticallParams(
|
|
24732
24733
|
chainId,
|
|
24733
24734
|
balanceQueries,
|
|
24734
24735
|
permissionParams,
|
|
24735
24736
|
tokenApprovalParams
|
|
24736
24737
|
);
|
|
24737
|
-
const rawResults = await
|
|
24738
|
-
chainId,
|
|
24739
|
-
prepared.calls,
|
|
24740
|
-
prepared.abis,
|
|
24738
|
+
const rawResults = await multicallRetry({
|
|
24739
|
+
chain: chainId,
|
|
24740
|
+
calls: prepared.calls,
|
|
24741
|
+
abi: prepared.abis,
|
|
24741
24742
|
batchSize,
|
|
24742
|
-
maxRetries2
|
|
24743
|
-
);
|
|
24743
|
+
maxRetries: maxRetries2
|
|
24744
|
+
});
|
|
24744
24745
|
return parseMergedResult(chainId, rawResults, prepared, lenderState);
|
|
24745
24746
|
}
|
|
24746
24747
|
function toCompoundV2Shares(entry, amount) {
|
|
@@ -29052,16 +29053,16 @@ var fetchMainPrices = async (chainIds, rpcOverrides, lists = {}, retries = 3, ba
|
|
|
29052
29053
|
...CometAbi,
|
|
29053
29054
|
...VenusLensAbi
|
|
29054
29055
|
];
|
|
29055
|
-
const result = await
|
|
29056
|
-
chainId,
|
|
29057
|
-
allCalls,
|
|
29058
|
-
abis,
|
|
29056
|
+
const result = await multicallRetryUniversal({
|
|
29057
|
+
chain: chainId,
|
|
29058
|
+
calls: allCalls,
|
|
29059
|
+
abi: abis,
|
|
29059
29060
|
batchSize,
|
|
29060
|
-
retries,
|
|
29061
|
-
0,
|
|
29061
|
+
maxRetries: retries,
|
|
29062
|
+
providerId: 0,
|
|
29062
29063
|
allowFailure,
|
|
29063
|
-
rpcOverrides
|
|
29064
|
-
);
|
|
29064
|
+
overrdies: rpcOverrides
|
|
29065
|
+
});
|
|
29065
29066
|
return {
|
|
29066
29067
|
chainId,
|
|
29067
29068
|
result,
|
|
@@ -30360,6 +30361,13 @@ var aaveFetcher = {
|
|
|
30360
30361
|
parse: parseAaveResults2,
|
|
30361
30362
|
getAbi: getAaveAbi
|
|
30362
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
|
+
}
|
|
30363
30371
|
function generateMarketId(oracle, loanAsset, collateralAsset) {
|
|
30364
30372
|
return `${oracle}${loanAsset}${collateralAsset}`.replace(/0x/gi, "").toUpperCase();
|
|
30365
30373
|
}
|
|
@@ -30451,6 +30459,111 @@ function parseMorphoResults2(data, meta, context) {
|
|
|
30451
30459
|
function getMorphoAbi() {
|
|
30452
30460
|
return ProxyOracleAbi;
|
|
30453
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
|
+
}
|
|
30454
30567
|
var morphoFetcher = {
|
|
30455
30568
|
getCalls: getMorphoCalls2,
|
|
30456
30569
|
parse: parseMorphoResults2,
|
|
@@ -30801,162 +30914,447 @@ var eulerV2Fetcher = {
|
|
|
30801
30914
|
};
|
|
30802
30915
|
|
|
30803
30916
|
// src/prices/oracle-prices/fetchOraclePrices.ts
|
|
30804
|
-
|
|
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();
|
|
30805
31015
|
const result = {};
|
|
30806
|
-
const combinedAbi = [
|
|
30807
|
-
...AaveOracleAbi,
|
|
30808
|
-
...ProxyOracleAbi,
|
|
30809
|
-
...CompoundV2OracleAbi,
|
|
30810
|
-
...ChainlinkAggregatorAbi,
|
|
30811
|
-
...vaultLensAbi
|
|
30812
|
-
];
|
|
30813
31016
|
const chainPromises = chainIds.map(async (chainId) => {
|
|
31017
|
+
const chainStart = Date.now();
|
|
30814
31018
|
const chainResult = {};
|
|
30815
31019
|
const tokenList = lists[chainId] ?? {};
|
|
30816
|
-
const
|
|
30817
|
-
const
|
|
30818
|
-
const
|
|
30819
|
-
const
|
|
30820
|
-
|
|
30821
|
-
|
|
30822
|
-
const
|
|
30823
|
-
const
|
|
30824
|
-
|
|
30825
|
-
|
|
30826
|
-
|
|
30827
|
-
|
|
30828
|
-
|
|
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
|
-
|
|
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 };
|
|
30890
31119
|
}
|
|
30891
|
-
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,
|
|
30892
31174
|
chainId,
|
|
30893
|
-
|
|
30894
|
-
combinedAbi,
|
|
30895
|
-
batchSize,
|
|
31175
|
+
chainBatchSize,
|
|
30896
31176
|
retries,
|
|
30897
|
-
0,
|
|
30898
31177
|
allowFailure,
|
|
30899
31178
|
rpcOverrides
|
|
30900
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
|
+
}
|
|
30901
31194
|
const usdPrices = { ...basePrices };
|
|
30902
|
-
const
|
|
30903
|
-
const
|
|
30904
|
-
|
|
30905
|
-
tracker.offset
|
|
30906
|
-
|
|
30907
|
-
|
|
30908
|
-
|
|
30909
|
-
|
|
30910
|
-
|
|
30911
|
-
|
|
30912
|
-
|
|
30913
|
-
|
|
30914
|
-
|
|
30915
|
-
|
|
30916
|
-
|
|
30917
|
-
|
|
30918
|
-
|
|
30919
|
-
|
|
30920
|
-
const
|
|
30921
|
-
|
|
30922
|
-
|
|
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);
|
|
30923
31227
|
}
|
|
31228
|
+
trackerDiags.push(diag2);
|
|
30924
31229
|
}
|
|
30925
31230
|
};
|
|
30926
|
-
|
|
30927
|
-
|
|
30928
|
-
|
|
30929
|
-
|
|
30930
|
-
(t) =>
|
|
30931
|
-
);
|
|
30932
|
-
const aaveDependentTrackers = nonMorphoTrackers.filter(
|
|
30933
|
-
(t) => t.parse === aaveFetcher.parse && t.meta.baseAssetSource
|
|
31231
|
+
parseTrackers(
|
|
31232
|
+
aaveGroup,
|
|
31233
|
+
aaveData.results,
|
|
31234
|
+
true,
|
|
31235
|
+
(t) => !t.meta.baseAssetSource
|
|
30934
31236
|
);
|
|
30935
|
-
|
|
30936
|
-
|
|
30937
|
-
);
|
|
30938
|
-
|
|
30939
|
-
|
|
30940
|
-
|
|
30941
|
-
|
|
30942
|
-
|
|
30943
|
-
|
|
30944
|
-
|
|
30945
|
-
|
|
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
|
+
}
|
|
30946
31263
|
}
|
|
30947
|
-
|
|
30948
|
-
|
|
31264
|
+
parseTrackers(
|
|
31265
|
+
aaveGroup,
|
|
31266
|
+
aaveData.results,
|
|
31267
|
+
true,
|
|
31268
|
+
(t) => !!t.meta.baseAssetSource
|
|
30949
31269
|
);
|
|
30950
|
-
|
|
30951
|
-
|
|
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);
|
|
30952
31303
|
}
|
|
30953
|
-
|
|
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 };
|
|
30954
31325
|
});
|
|
30955
|
-
const
|
|
30956
|
-
|
|
30957
|
-
|
|
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
|
+
}
|
|
30958
31351
|
}
|
|
30959
|
-
|
|
31352
|
+
const diagnostics = {
|
|
31353
|
+
chains: chainDiagnostics,
|
|
31354
|
+
totalDurationMs: Date.now() - totalStart,
|
|
31355
|
+
failedChains
|
|
31356
|
+
};
|
|
31357
|
+
return { prices: result, diagnostics };
|
|
30960
31358
|
}
|
|
30961
31359
|
var DEFAULT_PRIORITY = {
|
|
30962
31360
|
chainPriority: [
|
|
@@ -31170,7 +31568,7 @@ var FLASHLOAN_ENABLED_MASK = BigInt(
|
|
|
31170
31568
|
function getFlashLoanEnabled(data) {
|
|
31171
31569
|
return (data & ~FLASHLOAN_ENABLED_MASK) !== BigInt(0);
|
|
31172
31570
|
}
|
|
31173
|
-
async function fetchFlashLiquidityForChain(chain,
|
|
31571
|
+
async function fetchFlashLiquidityForChain(chain, multicallRetry, list = {}) {
|
|
31174
31572
|
let callLengths = {};
|
|
31175
31573
|
let aaveAssets = {};
|
|
31176
31574
|
let aaveCalls = [];
|
|
@@ -31285,15 +31683,15 @@ async function fetchFlashLiquidityForChain(chain, multicallRetry3, list = {}) {
|
|
|
31285
31683
|
...balancerV3Calls,
|
|
31286
31684
|
...uniswapV4Calls
|
|
31287
31685
|
];
|
|
31288
|
-
const rawResults = await
|
|
31686
|
+
const rawResults = await multicallRetry({
|
|
31289
31687
|
chain,
|
|
31290
31688
|
calls,
|
|
31291
|
-
FlashAbi,
|
|
31292
|
-
DEFAULT_BATCH_SIZE,
|
|
31293
|
-
3,
|
|
31294
|
-
0,
|
|
31295
|
-
false
|
|
31296
|
-
);
|
|
31689
|
+
abi: FlashAbi,
|
|
31690
|
+
batchSize: DEFAULT_BATCH_SIZE,
|
|
31691
|
+
maxRetries: 3,
|
|
31692
|
+
providerId: 0,
|
|
31693
|
+
allowFailure: false
|
|
31694
|
+
});
|
|
31297
31695
|
let liquidity = {};
|
|
31298
31696
|
let currentOffset = 0;
|
|
31299
31697
|
aaveProtocols.forEach((aave) => {
|