@1delta/margin-fetcher 0.0.340 → 0.0.341
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/abis/oracle/AaveOracle.d.ts +14 -0
- package/dist/abis/oracle/AaveOracle.d.ts.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +561 -87
- package/dist/index.js.map +1 -1
- package/dist/prices/oracle-prices/derivation.d.ts +25 -0
- package/dist/prices/oracle-prices/derivation.d.ts.map +1 -0
- package/dist/prices/oracle-prices/feedStaleness.d.ts +44 -0
- package/dist/prices/oracle-prices/feedStaleness.d.ts.map +1 -0
- package/dist/prices/oracle-prices/feedStats.d.ts +145 -0
- package/dist/prices/oracle-prices/feedStats.d.ts.map +1 -0
- package/dist/prices/oracle-prices/fetchOraclePrices.d.ts +14 -2
- package/dist/prices/oracle-prices/fetchOraclePrices.d.ts.map +1 -1
- package/dist/prices/oracle-prices/fetchers/aave.d.ts +14 -0
- package/dist/prices/oracle-prices/fetchers/aave.d.ts.map +1 -1
- package/dist/prices/oracle-prices/fetchers/compoundV3.d.ts.map +1 -1
- package/dist/prices/oracle-prices/fetchers/euler.d.ts.map +1 -1
- package/dist/prices/oracle-prices/fetchers/morpho.d.ts.map +1 -1
- package/dist/prices/oracle-prices/index.d.ts +7 -2
- package/dist/prices/oracle-prices/index.d.ts.map +1 -1
- package/dist/prices/oracle-prices/lenderKeys.d.ts +18 -0
- package/dist/prices/oracle-prices/lenderKeys.d.ts.map +1 -0
- package/dist/prices/oracle-prices/outlierGuard.d.ts +43 -0
- package/dist/prices/oracle-prices/outlierGuard.d.ts.map +1 -0
- package/dist/prices/oracle-prices/selectAssetGroupPrices.d.ts +45 -4
- package/dist/prices/oracle-prices/selectAssetGroupPrices.d.ts.map +1 -1
- package/dist/prices/oracle-prices/types.d.ts +114 -1
- package/dist/prices/oracle-prices/types.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import './chunk-BYTNVMX7.js';
|
|
|
3
3
|
import './chunk-PR4QN5HX.js';
|
|
4
4
|
import { Lender, LIQUITY_FAMILY_LENDERS, isAaveType, isCompoundV3, isMultiMarket, isSiloV2Type, isSiloV3Type, isDolomite, isEulerType, isAaveV4Type, isInit, isMorphoType, isCompoundV2Type, isVenusType, isSumerType, AAVE_V3_LENDERS, AAVE_V2_LENDERS, isAaveV2Type, isAaveV32Type, isAaveV3Type, isFluid, isGearboxV3, isMidnight, isTerm, isExactly, isLiquityFamily, isRiver, isTeller, isYLDR, isCompoundV3Type, isLista, isTectonicType, isKineticType, isBenqiType } from '@1delta/lender-registry';
|
|
5
5
|
export { isAaveType, isAaveV2Type, isAaveV32Type, isAaveV3Type, isCompoundV3, isCompoundV3Type, isInit, isMorphoType, isMultiMarket, isYLDR } from '@1delta/lender-registry';
|
|
6
|
-
import { fetchTokenLists, fetchTokenList, aavePools, compoundV3Pools, initConfig, morphoPools, compoundV2Pools, eulerVaults, siloMarkets, siloV2LenderKey, siloMarketsV3, siloV3LenderKey, aaveV4Spokes, aaveV4SpokeLenderKey, fluidResolvers, gearboxResolvers, dolomiteConfigs, midnightConfig, termConfig, termMarketsByChain, exactlyConfig, liquityLendersByChain, riverLendersByChain, tellerConfigByChain, tellerPoolsByChain, aaveReserves, compoundV3Reserves, liquityConfigFor, liquityBranchesByChain, riverConfigFor, riverChainData, morphoTypeMarkets, resolveMidnightApiBase, resolveTermApiBase, getSiloV2MarketEntry, getSiloV3MarketEntry, dolomiteEmode, aaveTokens, morphoTypeVaults, eulerConfigs, gearboxMarketCompressor, gearboxMarketConfigurators, gearboxV3LenderKey, midnightMarketsByChain, parseAaveV4SpokeLenderKey, gearboxAccountCompressor, compoundV2Tokens, exactlyMarketsByChain,
|
|
6
|
+
import { fetchTokenLists, fetchTokenList, aavePools, compoundV3Pools, initConfig, morphoPools, compoundV2Pools, eulerVaults, siloMarkets, siloV2LenderKey, siloMarketsV3, siloV3LenderKey, aaveV4Spokes, aaveV4SpokeLenderKey, fluidResolvers, gearboxResolvers, dolomiteConfigs, midnightConfig, termConfig, termMarketsByChain, exactlyConfig, liquityLendersByChain, riverLendersByChain, tellerConfigByChain, tellerPoolsByChain, aaveReserves, compoundV3Reserves, liquityConfigFor, liquityBranchesByChain, riverConfigFor, riverChainData, aaveOracles, morphoTypeMarkets, resolveMidnightApiBase, resolveTermApiBase, getSiloV2MarketEntry, getSiloV3MarketEntry, dolomiteEmode, aaveTokens, morphoTypeVaults, eulerConfigs, gearboxMarketCompressor, gearboxMarketConfigurators, gearboxV3LenderKey, midnightMarketsByChain, parseAaveV4SpokeLenderKey, gearboxAccountCompressor, compoundV2Tokens, exactlyMarketsByChain, aaveOraclesConfig, compoundV2Oracles, compoundV2TokenArray, compoundV2OraclesConfig, compoundV3OraclesData, compoundV3BaseData, compoundV2Reserves, aaveV4Oracles } from '@1delta/data-sdk';
|
|
7
7
|
import lodash from 'lodash';
|
|
8
8
|
import { getEvmClient, multicallRetryUniversal, getEvmChain, getEvmClientUniversal } from '@1delta/providers';
|
|
9
9
|
import { LiquityTroveManagerAbi, LiquityActivePoolAbi, LiquityStabilityPoolAbi, LiquityPriceFeedAbi, LiquitySortedTrovesAbi, RiverTroveManagerAbi, RiverStabilityPoolAbi, TellerMarketRegistryAbi, TellerV2Abi, MetaMorphoAbi, ExactlyPreviewerAbi, ExactlyAuditorAbi, LenderCommitmentGroupAbi, FluidLendingResolverAbi, FluidVaultResolverAbi, FluidLiquidityResolverAbi, MoolahVaultAbi, MorphoLensAbi, AaveV4SpokeAbi, AaveV4OracleAbi, AaveV4HubAbi, DolomiteMarginAbi, GearboxMarketCompressorV310Abi, MorphoBlueAbi, MidnightAbi, TermRepoTokenAbi, TermRepoServicerAbi, TermRepoCollateralManagerAbi, LiquityTroveNFTAbi, LiquityCollSurplusPoolAbi, TellerCollateralManagerAbi, GearboxCreditAccountCompressorV310Abi, TermPriceConsumerAbi } from '@1delta/abis';
|
|
@@ -39275,6 +39275,25 @@ var AaveOracleAbi = [
|
|
|
39275
39275
|
],
|
|
39276
39276
|
stateMutability: "view",
|
|
39277
39277
|
type: "function"
|
|
39278
|
+
},
|
|
39279
|
+
{
|
|
39280
|
+
inputs: [
|
|
39281
|
+
{
|
|
39282
|
+
internalType: "address",
|
|
39283
|
+
name: "asset",
|
|
39284
|
+
type: "address"
|
|
39285
|
+
}
|
|
39286
|
+
],
|
|
39287
|
+
name: "getSourceOfAsset",
|
|
39288
|
+
outputs: [
|
|
39289
|
+
{
|
|
39290
|
+
internalType: "address",
|
|
39291
|
+
name: "",
|
|
39292
|
+
type: "address"
|
|
39293
|
+
}
|
|
39294
|
+
],
|
|
39295
|
+
stateMutability: "view",
|
|
39296
|
+
type: "function"
|
|
39278
39297
|
}
|
|
39279
39298
|
];
|
|
39280
39299
|
|
|
@@ -39631,6 +39650,8 @@ function processMarketsToEntries(chainId, allMarkets, source) {
|
|
|
39631
39650
|
) : 0;
|
|
39632
39651
|
const resolvedLoanUSD = loanPriceUSD != null && loanPriceUSD > 0 ? loanPriceUSD : collateralPriceUSD != null && collateralPriceUSD > 0 && oracleRatio > 0 ? collateralPriceUSD / oracleRatio : 0;
|
|
39633
39652
|
const resolvedCollateralUSD = collateralPriceUSD != null && collateralPriceUSD > 0 ? collateralPriceUSD : loanPriceUSD != null && loanPriceUSD > 0 && oracleRatio > 0 ? oracleRatio * loanPriceUSD : 0;
|
|
39653
|
+
const collateralFromApi = collateralPriceUSD != null && collateralPriceUSD > 0;
|
|
39654
|
+
const loanFromApi = loanPriceUSD != null && loanPriceUSD > 0;
|
|
39634
39655
|
if (resolvedCollateralUSD > 0) {
|
|
39635
39656
|
entries.push({
|
|
39636
39657
|
asset: collateralAsset,
|
|
@@ -39639,7 +39660,8 @@ function processMarketsToEntries(chainId, allMarkets, source) {
|
|
|
39639
39660
|
priceUSD: resolvedCollateralUSD,
|
|
39640
39661
|
marketUid: createMarketUid(chainId, lenderKey, collateralAsset),
|
|
39641
39662
|
targetLender: lenderKey,
|
|
39642
|
-
baseAsset: loanAsset
|
|
39663
|
+
baseAsset: loanAsset,
|
|
39664
|
+
derivation: collateralFromApi ? "direct" : "derived"
|
|
39643
39665
|
});
|
|
39644
39666
|
}
|
|
39645
39667
|
if (resolvedLoanUSD > 0) {
|
|
@@ -39651,7 +39673,8 @@ function processMarketsToEntries(chainId, allMarkets, source) {
|
|
|
39651
39673
|
targetLender: lenderKey,
|
|
39652
39674
|
description: "Morpho loan asset",
|
|
39653
39675
|
staticBase: true,
|
|
39654
|
-
baseAsset: loanAsset
|
|
39676
|
+
baseAsset: loanAsset,
|
|
39677
|
+
derivation: loanFromApi ? "direct" : "derived"
|
|
39655
39678
|
});
|
|
39656
39679
|
}
|
|
39657
39680
|
}
|
|
@@ -40200,6 +40223,7 @@ var ChainlinkAggregatorAbi = [
|
|
|
40200
40223
|
}
|
|
40201
40224
|
];
|
|
40202
40225
|
var ANSWER_INDEX = 1;
|
|
40226
|
+
var UPDATED_AT_INDEX = 3;
|
|
40203
40227
|
var CHAINLINK_DECIMALS = 8;
|
|
40204
40228
|
var USD_PRICED_OVERRIDES = {
|
|
40205
40229
|
[Lender.COMPOUND_V3_AERO]: /* @__PURE__ */ new Set(["8453"]),
|
|
@@ -40271,6 +40295,7 @@ function parseCompoundV3Results(data, meta, context) {
|
|
|
40271
40295
|
priceUSD = rawPrice * baseAssetUSD;
|
|
40272
40296
|
}
|
|
40273
40297
|
}
|
|
40298
|
+
const updatedAtRaw = Array.isArray(rawResult) ? Number(rawResult[UPDATED_AT_INDEX]) : 0;
|
|
40274
40299
|
entries.push({
|
|
40275
40300
|
asset: assetLc,
|
|
40276
40301
|
price: rawPrice,
|
|
@@ -40279,7 +40304,9 @@ function parseCompoundV3Results(data, meta, context) {
|
|
|
40279
40304
|
marketUid: createMarketUid(chainId, queryMeta.lender, queryMeta.asset),
|
|
40280
40305
|
description: queryMeta.description,
|
|
40281
40306
|
staticBase: queryMeta.staticBase || void 0,
|
|
40282
|
-
baseAsset: queryMeta.baseAsset
|
|
40307
|
+
baseAsset: queryMeta.baseAsset,
|
|
40308
|
+
updatedAt: updatedAtRaw > 0 ? updatedAtRaw : void 0,
|
|
40309
|
+
feedSource: updatedAtRaw > 0 ? queryMeta.oracle : void 0
|
|
40283
40310
|
});
|
|
40284
40311
|
} catch {
|
|
40285
40312
|
}
|
|
@@ -40527,12 +40554,15 @@ function parseEulerV2Results(data, meta, context) {
|
|
|
40527
40554
|
const priceInUoA = Number(amountOutMid) / Number(10n ** unitOfAccountDecimals);
|
|
40528
40555
|
if (isNaN(priceInUoA) || priceInUoA === 0) return;
|
|
40529
40556
|
let priceUSD;
|
|
40557
|
+
let derivation;
|
|
40530
40558
|
if (isUsdUnitOfAccount(unitOfAccount)) {
|
|
40531
40559
|
priceUSD = priceInUoA;
|
|
40560
|
+
derivation = "direct";
|
|
40532
40561
|
} else {
|
|
40533
40562
|
const uoaUSD = context.usdPrices[unitOfAccount] ?? 0;
|
|
40534
40563
|
if (uoaUSD === 0) return;
|
|
40535
40564
|
priceUSD = priceInUoA * uoaUSD;
|
|
40565
|
+
derivation = "quoted";
|
|
40536
40566
|
}
|
|
40537
40567
|
if (isNaN(priceUSD) || priceUSD === 0) return;
|
|
40538
40568
|
if (priceUSD > MAX_SANE_PRICE_USD) return;
|
|
@@ -40544,7 +40574,8 @@ function parseEulerV2Results(data, meta, context) {
|
|
|
40544
40574
|
context.chainId,
|
|
40545
40575
|
queryMeta.lender,
|
|
40546
40576
|
queryMeta.vault
|
|
40547
|
-
)
|
|
40577
|
+
),
|
|
40578
|
+
derivation
|
|
40548
40579
|
});
|
|
40549
40580
|
} catch {
|
|
40550
40581
|
}
|
|
@@ -41257,7 +41288,7 @@ function lookupUSD3(context, asset) {
|
|
|
41257
41288
|
return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
|
|
41258
41289
|
}
|
|
41259
41290
|
function parseSiloV2GraphQLResults(items, context) {
|
|
41260
|
-
const
|
|
41291
|
+
const ZERO_ADDRESS8 = "0x0000000000000000000000000000000000000000";
|
|
41261
41292
|
const out = [];
|
|
41262
41293
|
const seen = /* @__PURE__ */ new Set();
|
|
41263
41294
|
for (const item of items) {
|
|
@@ -41280,8 +41311,8 @@ function parseSiloV2GraphQLResults(items, context) {
|
|
|
41280
41311
|
const partnerTokenLc = other.token.toLowerCase();
|
|
41281
41312
|
const dedupKey = `${lenderKey}:${tokenLc}`;
|
|
41282
41313
|
if (seen.has(dedupKey)) continue;
|
|
41283
|
-
const oracleAddr = (side.solvencyOracleAddress ?? side.solvencyOracle?.id ?? self.solvencyOracle ??
|
|
41284
|
-
const isStatic = !oracleAddr || oracleAddr ===
|
|
41314
|
+
const oracleAddr = (side.solvencyOracleAddress ?? side.solvencyOracle?.id ?? self.solvencyOracle ?? ZERO_ADDRESS8).toLowerCase();
|
|
41315
|
+
const isStatic = !oracleAddr || oracleAddr === ZERO_ADDRESS8;
|
|
41285
41316
|
const siloAddrLc = self.silo.toLowerCase();
|
|
41286
41317
|
try {
|
|
41287
41318
|
let priceUSD = 0;
|
|
@@ -41399,7 +41430,7 @@ function lookupUSD4(context, asset) {
|
|
|
41399
41430
|
return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
|
|
41400
41431
|
}
|
|
41401
41432
|
function parseSiloV3GraphQLResults(items, context) {
|
|
41402
|
-
const
|
|
41433
|
+
const ZERO_ADDRESS8 = "0x0000000000000000000000000000000000000000";
|
|
41403
41434
|
const out = [];
|
|
41404
41435
|
const seen = /* @__PURE__ */ new Set();
|
|
41405
41436
|
for (const item of items) {
|
|
@@ -41422,8 +41453,8 @@ function parseSiloV3GraphQLResults(items, context) {
|
|
|
41422
41453
|
const partnerTokenLc = other.token.toLowerCase();
|
|
41423
41454
|
const dedupKey = `${lenderKey}:${tokenLc}`;
|
|
41424
41455
|
if (seen.has(dedupKey)) continue;
|
|
41425
|
-
const oracleAddr = (side.solvencyOracleAddress ?? side.solvencyOracle?.id ?? self.solvencyOracle ??
|
|
41426
|
-
const isStatic = !oracleAddr || oracleAddr ===
|
|
41456
|
+
const oracleAddr = (side.solvencyOracleAddress ?? side.solvencyOracle?.id ?? self.solvencyOracle ?? ZERO_ADDRESS8).toLowerCase();
|
|
41457
|
+
const isStatic = !oracleAddr || oracleAddr === ZERO_ADDRESS8;
|
|
41427
41458
|
const siloAddrLc = self.silo.toLowerCase();
|
|
41428
41459
|
try {
|
|
41429
41460
|
let priceUSD = 0;
|
|
@@ -41532,6 +41563,116 @@ async function fetchMorphoMysticPrices(chainId) {
|
|
|
41532
41563
|
return null;
|
|
41533
41564
|
}
|
|
41534
41565
|
}
|
|
41566
|
+
var DESCRIPTION_ABI = [
|
|
41567
|
+
{
|
|
41568
|
+
inputs: [],
|
|
41569
|
+
name: "description",
|
|
41570
|
+
outputs: [{ internalType: "string", name: "", type: "string" }],
|
|
41571
|
+
stateMutability: "view",
|
|
41572
|
+
type: "function"
|
|
41573
|
+
}
|
|
41574
|
+
];
|
|
41575
|
+
var AGGREGATOR_ABI = [...ChainlinkAggregatorAbi, ...DESCRIPTION_ABI];
|
|
41576
|
+
function isFailed(r) {
|
|
41577
|
+
return r === "0x" || r === void 0 || r === null;
|
|
41578
|
+
}
|
|
41579
|
+
var ZERO_ADDRESS7 = "0x0000000000000000000000000000000000000000";
|
|
41580
|
+
async function probeAaveFeedTimestamps(chainId, options = {}) {
|
|
41581
|
+
const { rpcOverrides, batchSize, retries = 2 } = options;
|
|
41582
|
+
const result = {};
|
|
41583
|
+
const oracles = aaveOracles() ?? {};
|
|
41584
|
+
const reserves = aaveReserves() ?? {};
|
|
41585
|
+
const jobs = [];
|
|
41586
|
+
for (const [lender, chains] of Object.entries(oracles)) {
|
|
41587
|
+
const oracle = chains?.[chainId];
|
|
41588
|
+
const assets = reserves[lender]?.[chainId] ?? [];
|
|
41589
|
+
if (!oracle || assets.length === 0) continue;
|
|
41590
|
+
for (const asset of assets) jobs.push({ lender, oracle, asset });
|
|
41591
|
+
}
|
|
41592
|
+
if (jobs.length === 0) return result;
|
|
41593
|
+
try {
|
|
41594
|
+
const sourceResults = await multicallRetryUniversal({
|
|
41595
|
+
chain: chainId,
|
|
41596
|
+
calls: jobs.map((j) => ({
|
|
41597
|
+
address: j.oracle,
|
|
41598
|
+
name: "getSourceOfAsset",
|
|
41599
|
+
params: [j.asset]
|
|
41600
|
+
})),
|
|
41601
|
+
abi: AaveOracleAbi,
|
|
41602
|
+
batchSize,
|
|
41603
|
+
maxRetries: retries,
|
|
41604
|
+
providerId: void 0,
|
|
41605
|
+
allowFailure: true,
|
|
41606
|
+
overrdies: rpcOverrides,
|
|
41607
|
+
logErrors: false
|
|
41608
|
+
});
|
|
41609
|
+
const sourceOf = /* @__PURE__ */ new Map();
|
|
41610
|
+
const uniqueSources = [];
|
|
41611
|
+
const sourceIndex = /* @__PURE__ */ new Map();
|
|
41612
|
+
jobs.forEach((_3, i) => {
|
|
41613
|
+
const raw = sourceResults[i];
|
|
41614
|
+
if (isFailed(raw)) return;
|
|
41615
|
+
const source = String(raw).toLowerCase();
|
|
41616
|
+
if (source === ZERO_ADDRESS7) return;
|
|
41617
|
+
sourceOf.set(i, source);
|
|
41618
|
+
if (!sourceIndex.has(source)) {
|
|
41619
|
+
sourceIndex.set(source, uniqueSources.length);
|
|
41620
|
+
uniqueSources.push(source);
|
|
41621
|
+
}
|
|
41622
|
+
});
|
|
41623
|
+
if (uniqueSources.length === 0) return result;
|
|
41624
|
+
const roundResults = await multicallRetryUniversal({
|
|
41625
|
+
chain: chainId,
|
|
41626
|
+
calls: uniqueSources.flatMap((source) => [
|
|
41627
|
+
{ address: source, name: "latestRoundData", params: [] },
|
|
41628
|
+
{ address: source, name: "description", params: [] }
|
|
41629
|
+
]),
|
|
41630
|
+
abi: AGGREGATOR_ABI,
|
|
41631
|
+
batchSize,
|
|
41632
|
+
maxRetries: retries,
|
|
41633
|
+
providerId: void 0,
|
|
41634
|
+
allowFailure: true,
|
|
41635
|
+
overrdies: rpcOverrides,
|
|
41636
|
+
logErrors: false
|
|
41637
|
+
});
|
|
41638
|
+
const infoOfSource = /* @__PURE__ */ new Map();
|
|
41639
|
+
uniqueSources.forEach((source, i) => {
|
|
41640
|
+
const round = roundResults[i * 2];
|
|
41641
|
+
const description = roundResults[i * 2 + 1];
|
|
41642
|
+
if (isFailed(round) || !Array.isArray(round)) return;
|
|
41643
|
+
const updatedAt = Number(round[3]);
|
|
41644
|
+
if (!(updatedAt > 0)) return;
|
|
41645
|
+
infoOfSource.set(source, {
|
|
41646
|
+
source,
|
|
41647
|
+
updatedAt,
|
|
41648
|
+
description: isFailed(description) ? void 0 : String(description)
|
|
41649
|
+
});
|
|
41650
|
+
});
|
|
41651
|
+
for (const [i, source] of sourceOf) {
|
|
41652
|
+
const info = infoOfSource.get(source);
|
|
41653
|
+
if (!info) continue;
|
|
41654
|
+
const { lender, asset } = jobs[i];
|
|
41655
|
+
if (!result[lender]) result[lender] = {};
|
|
41656
|
+
result[lender][asset.toLowerCase()] = info;
|
|
41657
|
+
}
|
|
41658
|
+
} catch {
|
|
41659
|
+
return result;
|
|
41660
|
+
}
|
|
41661
|
+
return result;
|
|
41662
|
+
}
|
|
41663
|
+
|
|
41664
|
+
// src/prices/oracle-prices/derivation.ts
|
|
41665
|
+
var DERIVATION_RANK = {
|
|
41666
|
+
direct: 0,
|
|
41667
|
+
quoted: 1,
|
|
41668
|
+
derived: 2
|
|
41669
|
+
};
|
|
41670
|
+
function resolveDerivation(entry, groupDefault) {
|
|
41671
|
+
if (entry.derivation) return entry.derivation;
|
|
41672
|
+
if (groupDefault === "derived") return "derived";
|
|
41673
|
+
if (entry.baseAsset && !entry.staticBase) return "quoted";
|
|
41674
|
+
return groupDefault ?? "direct";
|
|
41675
|
+
}
|
|
41535
41676
|
|
|
41536
41677
|
// src/prices/oracle-prices/fetchOraclePrices.ts
|
|
41537
41678
|
function countFailures(data, offset, count) {
|
|
@@ -41549,11 +41690,12 @@ function safeGetCalls(fetcherName, fn, errors) {
|
|
|
41549
41690
|
return [];
|
|
41550
41691
|
}
|
|
41551
41692
|
}
|
|
41552
|
-
function buildGroup(fetcherName, results, parse, abi) {
|
|
41693
|
+
function buildGroup(fetcherName, results, parse, abi, derivation) {
|
|
41553
41694
|
const group = {
|
|
41554
41695
|
fetcherName,
|
|
41555
41696
|
calls: [],
|
|
41556
41697
|
abi,
|
|
41698
|
+
derivation,
|
|
41557
41699
|
trackers: []
|
|
41558
41700
|
};
|
|
41559
41701
|
for (const fr of results) {
|
|
@@ -41568,7 +41710,7 @@ function buildGroup(fetcherName, results, parse, abi) {
|
|
|
41568
41710
|
}
|
|
41569
41711
|
return group;
|
|
41570
41712
|
}
|
|
41571
|
-
function
|
|
41713
|
+
function isFailed2(r) {
|
|
41572
41714
|
return r === "0x" || r === void 0;
|
|
41573
41715
|
}
|
|
41574
41716
|
async function executeGroup(group, chainId, chainBatchSize, retries, allowFailure, rpcOverrides, failRetries = 2) {
|
|
@@ -41587,7 +41729,7 @@ async function executeGroup(group, chainId, chainBatchSize, retries, allowFailur
|
|
|
41587
41729
|
overrdies: rpcOverrides,
|
|
41588
41730
|
logErrors: true
|
|
41589
41731
|
});
|
|
41590
|
-
let failedIndices = results.map((r, i) =>
|
|
41732
|
+
let failedIndices = results.map((r, i) => isFailed2(r) ? i : -1).filter((i) => i >= 0);
|
|
41591
41733
|
for (let round = 0; round < failRetries && failedIndices.length > 0; round++) {
|
|
41592
41734
|
const retryCalls = failedIndices.map((i) => group.calls[i]);
|
|
41593
41735
|
try {
|
|
@@ -41605,7 +41747,7 @@ async function executeGroup(group, chainId, chainBatchSize, retries, allowFailur
|
|
|
41605
41747
|
});
|
|
41606
41748
|
const stillFailed = [];
|
|
41607
41749
|
for (let j = 0; j < failedIndices.length; j++) {
|
|
41608
|
-
if (!
|
|
41750
|
+
if (!isFailed2(retryResults[j])) {
|
|
41609
41751
|
results[failedIndices[j]] = retryResults[j];
|
|
41610
41752
|
} else {
|
|
41611
41753
|
stillFailed.push(failedIndices[j]);
|
|
@@ -41616,7 +41758,7 @@ async function executeGroup(group, chainId, chainBatchSize, retries, allowFailur
|
|
|
41616
41758
|
break;
|
|
41617
41759
|
}
|
|
41618
41760
|
}
|
|
41619
|
-
const failCount = results.filter((r) =>
|
|
41761
|
+
const failCount = results.filter((r) => isFailed2(r)).length;
|
|
41620
41762
|
const allFailed = failCount === results.length && results.length > 0;
|
|
41621
41763
|
return {
|
|
41622
41764
|
results,
|
|
@@ -41630,7 +41772,7 @@ async function executeGroup(group, chainId, chainBatchSize, retries, allowFailur
|
|
|
41630
41772
|
};
|
|
41631
41773
|
}
|
|
41632
41774
|
}
|
|
41633
|
-
async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3, batchSize = void 0, allowFailure = true, basePrices = {}, morphoMarketOverrides, listaMarketOverrides, stalenessThresholdSeconds = 3600, onlyFetchers) {
|
|
41775
|
+
async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3, batchSize = void 0, allowFailure = true, basePrices = {}, morphoMarketOverrides, listaMarketOverrides, stalenessThresholdSeconds = 3600, onlyFetchers, probeFeedStaleness = true) {
|
|
41634
41776
|
const totalStart = Date.now();
|
|
41635
41777
|
const result = {};
|
|
41636
41778
|
const chainPromises = chainIds.map(async (chainId) => {
|
|
@@ -41698,7 +41840,11 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
41698
41840
|
() => exactlyFetcher.getCalls(chainId),
|
|
41699
41841
|
getCallsErrors
|
|
41700
41842
|
) : [];
|
|
41701
|
-
const termResults = isActive("term") ? safeGetCalls(
|
|
41843
|
+
const termResults = isActive("term") ? safeGetCalls(
|
|
41844
|
+
"term",
|
|
41845
|
+
() => termFetcher.getCalls(chainId),
|
|
41846
|
+
getCallsErrors
|
|
41847
|
+
) : [];
|
|
41702
41848
|
const liquityResults = isActive("liquity") ? safeGetCalls(
|
|
41703
41849
|
"liquity",
|
|
41704
41850
|
() => liquityFetcher.getCalls(chainId),
|
|
@@ -41743,109 +41889,127 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
41743
41889
|
"aave",
|
|
41744
41890
|
aaveResults,
|
|
41745
41891
|
aaveFetcher.parse,
|
|
41746
|
-
AaveOracleAbi
|
|
41892
|
+
AaveOracleAbi,
|
|
41893
|
+
"direct"
|
|
41747
41894
|
);
|
|
41748
41895
|
const compoundV2Group = buildGroup(
|
|
41749
41896
|
"compoundV2",
|
|
41750
41897
|
compoundV2Results,
|
|
41751
41898
|
compoundV2Fetcher.parse,
|
|
41752
|
-
CompoundV2OracleAbi
|
|
41899
|
+
CompoundV2OracleAbi,
|
|
41900
|
+
"direct"
|
|
41753
41901
|
);
|
|
41754
41902
|
const compoundV3Group = buildGroup(
|
|
41755
41903
|
"compoundV3",
|
|
41756
41904
|
compoundV3Results,
|
|
41757
41905
|
compoundV3Fetcher.parse,
|
|
41758
|
-
ChainlinkAggregatorAbi
|
|
41906
|
+
ChainlinkAggregatorAbi,
|
|
41907
|
+
"direct"
|
|
41759
41908
|
);
|
|
41760
41909
|
const listaGroup = buildGroup(
|
|
41761
41910
|
"lista",
|
|
41762
41911
|
listaResults,
|
|
41763
41912
|
listaFetcher.parse,
|
|
41764
|
-
ProxyOracleAbi
|
|
41913
|
+
ProxyOracleAbi,
|
|
41914
|
+
"direct"
|
|
41765
41915
|
);
|
|
41766
41916
|
const eulerGroup = buildGroup(
|
|
41767
41917
|
"eulerV2",
|
|
41768
41918
|
eulerResults,
|
|
41769
41919
|
eulerV2Fetcher.parse,
|
|
41770
|
-
getEulerV2Abi()
|
|
41920
|
+
getEulerV2Abi(),
|
|
41921
|
+
"direct"
|
|
41771
41922
|
);
|
|
41772
41923
|
const aaveV4Group = buildGroup(
|
|
41773
41924
|
"aaveV4",
|
|
41774
41925
|
aaveV4Results,
|
|
41775
41926
|
aaveV4Fetcher.parse,
|
|
41776
|
-
getAaveV4Abi()
|
|
41927
|
+
getAaveV4Abi(),
|
|
41928
|
+
"direct"
|
|
41777
41929
|
);
|
|
41778
41930
|
const morphoGroup = buildGroup(
|
|
41779
41931
|
"morpho",
|
|
41780
41932
|
morphoResults,
|
|
41781
41933
|
morphoFetcher.parse,
|
|
41782
|
-
ProxyOracleAbi
|
|
41934
|
+
ProxyOracleAbi,
|
|
41935
|
+
"derived"
|
|
41783
41936
|
);
|
|
41784
41937
|
const midnightGroup = buildGroup(
|
|
41785
41938
|
"midnight",
|
|
41786
41939
|
midnightResults,
|
|
41787
41940
|
midnightFetcher.parse,
|
|
41788
|
-
ProxyOracleAbi
|
|
41941
|
+
ProxyOracleAbi,
|
|
41942
|
+
"derived"
|
|
41789
41943
|
);
|
|
41790
41944
|
const exactlyGroup = buildGroup(
|
|
41791
41945
|
"exactly",
|
|
41792
41946
|
exactlyResults,
|
|
41793
41947
|
exactlyFetcher.parse,
|
|
41794
|
-
getExactlyAbi()
|
|
41948
|
+
getExactlyAbi(),
|
|
41949
|
+
"direct"
|
|
41795
41950
|
);
|
|
41796
41951
|
const termGroup = buildGroup(
|
|
41797
41952
|
"term",
|
|
41798
41953
|
termResults,
|
|
41799
41954
|
termFetcher.parse,
|
|
41800
|
-
getTermAbi()
|
|
41955
|
+
getTermAbi(),
|
|
41956
|
+
"direct"
|
|
41801
41957
|
);
|
|
41802
41958
|
const liquityGroup = buildGroup(
|
|
41803
41959
|
"liquity",
|
|
41804
41960
|
liquityResults,
|
|
41805
41961
|
liquityFetcher.parse,
|
|
41806
|
-
getLiquityAbi()
|
|
41962
|
+
getLiquityAbi(),
|
|
41963
|
+
"direct"
|
|
41807
41964
|
);
|
|
41808
41965
|
const riverGroup = buildGroup(
|
|
41809
41966
|
"river",
|
|
41810
41967
|
riverResults,
|
|
41811
41968
|
riverFetcher.parse,
|
|
41812
|
-
getRiverAbi()
|
|
41969
|
+
getRiverAbi(),
|
|
41970
|
+
"direct"
|
|
41813
41971
|
);
|
|
41814
41972
|
const tellerGroup = buildGroup(
|
|
41815
41973
|
"teller",
|
|
41816
41974
|
tellerResults,
|
|
41817
41975
|
tellerFetcher.parse,
|
|
41818
|
-
getTellerAbi()
|
|
41976
|
+
getTellerAbi(),
|
|
41977
|
+
"derived"
|
|
41819
41978
|
);
|
|
41820
41979
|
const siloV2Group = buildGroup(
|
|
41821
41980
|
"siloV2",
|
|
41822
41981
|
siloV2Results,
|
|
41823
41982
|
siloV2Fetcher.parse,
|
|
41824
|
-
getSiloV2Abi()
|
|
41983
|
+
getSiloV2Abi(),
|
|
41984
|
+
"derived"
|
|
41825
41985
|
);
|
|
41826
41986
|
const siloV3Group = buildGroup(
|
|
41827
41987
|
"siloV3",
|
|
41828
41988
|
siloV3Results,
|
|
41829
41989
|
siloV3Fetcher.parse,
|
|
41830
|
-
getSiloV3Abi()
|
|
41990
|
+
getSiloV3Abi(),
|
|
41991
|
+
"derived"
|
|
41831
41992
|
);
|
|
41832
41993
|
const fluidGroup = buildGroup(
|
|
41833
41994
|
"fluid",
|
|
41834
41995
|
fluidResults,
|
|
41835
41996
|
fluidFetcher.parse,
|
|
41836
|
-
getFluidAbi()
|
|
41997
|
+
getFluidAbi(),
|
|
41998
|
+
"derived"
|
|
41837
41999
|
);
|
|
41838
42000
|
const gearboxV3Group = buildGroup(
|
|
41839
42001
|
"gearboxV3",
|
|
41840
42002
|
gearboxV3Results,
|
|
41841
42003
|
gearboxV3Fetcher.parse,
|
|
41842
|
-
getGearboxV3Abi()
|
|
42004
|
+
getGearboxV3Abi(),
|
|
42005
|
+
"derived"
|
|
41843
42006
|
);
|
|
41844
42007
|
const dolomiteGroup = buildGroup(
|
|
41845
42008
|
"dolomite",
|
|
41846
42009
|
dolomiteResults,
|
|
41847
42010
|
dolomiteFetcher.parse,
|
|
41848
|
-
getDolomiteAbi()
|
|
42011
|
+
getDolomiteAbi(),
|
|
42012
|
+
"direct"
|
|
41849
42013
|
);
|
|
41850
42014
|
const allGroups = [
|
|
41851
42015
|
aaveGroup,
|
|
@@ -41886,6 +42050,11 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
41886
42050
|
const morphoGqlPromise = morphoUseMystic ? fetchMorphoMysticPrices(chainId) : morphoUseApi ? fetchMorphoGraphQLPrices(chainId) : Promise.resolve(null);
|
|
41887
42051
|
const siloV2GqlPromise = isActive("silov2") ? fetchSiloV2GraphQLPrices(chainId, basePrices, tokenList) : Promise.resolve(null);
|
|
41888
42052
|
const siloV3GqlPromise = isActive("silov3") ? fetchSiloV3GraphQLPrices(chainId, basePrices, tokenList) : Promise.resolve(null);
|
|
42053
|
+
const feedTimestampsPromise = stalenessThresholdSeconds > 0 && probeFeedStaleness ? probeAaveFeedTimestamps(chainId, {
|
|
42054
|
+
rpcOverrides,
|
|
42055
|
+
batchSize: chainBatchSize,
|
|
42056
|
+
retries
|
|
42057
|
+
}) : Promise.resolve({});
|
|
41889
42058
|
const [
|
|
41890
42059
|
aaveData,
|
|
41891
42060
|
compoundV2Data,
|
|
@@ -42112,6 +42281,7 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
42112
42281
|
if (!chainResult[lender]) {
|
|
42113
42282
|
chainResult[lender] = [];
|
|
42114
42283
|
}
|
|
42284
|
+
entry.derivation = resolveDerivation(entry, group.derivation);
|
|
42115
42285
|
chainResult[lender].push(entry);
|
|
42116
42286
|
if (updatePrices) {
|
|
42117
42287
|
const oracleKey = tokenList[entry.asset]?.assetGroup ?? `${chainId}-${entry.asset}`;
|
|
@@ -42136,29 +42306,6 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
42136
42306
|
parseTrackers(listaGroup, listaData.results);
|
|
42137
42307
|
parseTrackers(eulerGroup, eulerData.results);
|
|
42138
42308
|
parseTrackers(aaveV4Group, aaveV4Data.results);
|
|
42139
|
-
if (stalenessThresholdSeconds > 0) {
|
|
42140
|
-
const nowSeconds = Math.floor(Date.now() / 1e3);
|
|
42141
|
-
for (const tracker of compoundV3Group.trackers) {
|
|
42142
|
-
const meta = tracker.meta;
|
|
42143
|
-
for (let i = 0; i < tracker.count; i++) {
|
|
42144
|
-
const raw = compoundV3Data.results[tracker.offset + i];
|
|
42145
|
-
if (!raw || raw === "0x" || !Array.isArray(raw)) continue;
|
|
42146
|
-
const updatedAt = Number(raw[3]);
|
|
42147
|
-
if (updatedAt > 0) {
|
|
42148
|
-
const staleSeconds = nowSeconds - updatedAt;
|
|
42149
|
-
if (staleSeconds > stalenessThresholdSeconds) {
|
|
42150
|
-
const queryMeta = meta[i];
|
|
42151
|
-
staleFeeds.push({
|
|
42152
|
-
asset: queryMeta?.asset?.toLowerCase() ?? "unknown",
|
|
42153
|
-
lender: queryMeta?.lender ?? tracker.lender,
|
|
42154
|
-
oracle: queryMeta?.oracle ?? "unknown",
|
|
42155
|
-
staleSeconds
|
|
42156
|
-
});
|
|
42157
|
-
}
|
|
42158
|
-
}
|
|
42159
|
-
}
|
|
42160
|
-
}
|
|
42161
|
-
}
|
|
42162
42309
|
parseTrackers(
|
|
42163
42310
|
aaveGroup,
|
|
42164
42311
|
aaveData.results,
|
|
@@ -42182,6 +42329,7 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
42182
42329
|
for (const entry of siloV2GqlEntries) {
|
|
42183
42330
|
const lender = entry.targetLender ?? "SILO_V2";
|
|
42184
42331
|
if (!chainResult[lender]) chainResult[lender] = [];
|
|
42332
|
+
entry.derivation = resolveDerivation(entry, "derived");
|
|
42185
42333
|
chainResult[lender].push(entry);
|
|
42186
42334
|
const oracleKey = tokenList[entry.asset]?.assetGroup ?? `${chainId}-${entry.asset}`;
|
|
42187
42335
|
usdPrices[oracleKey] = entry.priceUSD;
|
|
@@ -42201,6 +42349,7 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
42201
42349
|
for (const entry of siloV3GqlEntries) {
|
|
42202
42350
|
const lender = entry.targetLender ?? "SILO_V3";
|
|
42203
42351
|
if (!chainResult[lender]) chainResult[lender] = [];
|
|
42352
|
+
entry.derivation = resolveDerivation(entry, "derived");
|
|
42204
42353
|
chainResult[lender].push(entry);
|
|
42205
42354
|
const oracleKey = tokenList[entry.asset]?.assetGroup ?? `${chainId}-${entry.asset}`;
|
|
42206
42355
|
usdPrices[oracleKey] = entry.priceUSD;
|
|
@@ -42232,6 +42381,7 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
42232
42381
|
const key = `${lender}|${entry.marketUid}|${entry.asset}`;
|
|
42233
42382
|
if (onChainKeys.has(key)) continue;
|
|
42234
42383
|
if (!chainResult[lender]) chainResult[lender] = [];
|
|
42384
|
+
entry.derivation = resolveDerivation(entry, "derived");
|
|
42235
42385
|
chainResult[lender].push(entry);
|
|
42236
42386
|
gqlPushed++;
|
|
42237
42387
|
}
|
|
@@ -42251,6 +42401,7 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
42251
42401
|
for (const entry of morphoGqlEntries) {
|
|
42252
42402
|
const lender = entry.targetLender ?? "MORPHO_BLUE";
|
|
42253
42403
|
if (!chainResult[lender]) chainResult[lender] = [];
|
|
42404
|
+
entry.derivation = resolveDerivation(entry, "derived");
|
|
42254
42405
|
chainResult[lender].push(entry);
|
|
42255
42406
|
}
|
|
42256
42407
|
trackerDiags.push(morphoGqlDiag);
|
|
@@ -42277,6 +42428,39 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
42277
42428
|
}
|
|
42278
42429
|
parseTrackers(midnightGroup, midnightData.results, false);
|
|
42279
42430
|
parseTrackers(tellerGroup, tellerData.results, false);
|
|
42431
|
+
if (stalenessThresholdSeconds > 0) {
|
|
42432
|
+
const feedTimestamps = await feedTimestampsPromise;
|
|
42433
|
+
for (const [lender, assetMap] of Object.entries(feedTimestamps)) {
|
|
42434
|
+
for (const entry of chainResult[lender] ?? []) {
|
|
42435
|
+
const info = assetMap[entry.asset];
|
|
42436
|
+
if (!info) continue;
|
|
42437
|
+
entry.updatedAt = info.updatedAt;
|
|
42438
|
+
entry.feedSource = info.source;
|
|
42439
|
+
if (!entry.description && info.description) {
|
|
42440
|
+
entry.description = info.description;
|
|
42441
|
+
}
|
|
42442
|
+
}
|
|
42443
|
+
}
|
|
42444
|
+
const nowSeconds = Math.floor(Date.now() / 1e3);
|
|
42445
|
+
const reported = /* @__PURE__ */ new Set();
|
|
42446
|
+
for (const [lender, entries] of Object.entries(chainResult)) {
|
|
42447
|
+
for (const entry of entries) {
|
|
42448
|
+
if (!entry.updatedAt || entry.updatedAt <= 0) continue;
|
|
42449
|
+
const staleSeconds = nowSeconds - entry.updatedAt;
|
|
42450
|
+
if (staleSeconds <= stalenessThresholdSeconds) continue;
|
|
42451
|
+
const key = `${lender}|${entry.asset}|${entry.feedSource ?? ""}`;
|
|
42452
|
+
if (reported.has(key)) continue;
|
|
42453
|
+
reported.add(key);
|
|
42454
|
+
staleFeeds.push({
|
|
42455
|
+
asset: entry.asset,
|
|
42456
|
+
lender,
|
|
42457
|
+
oracle: entry.feedSource ?? "unknown",
|
|
42458
|
+
staleSeconds,
|
|
42459
|
+
description: entry.description
|
|
42460
|
+
});
|
|
42461
|
+
}
|
|
42462
|
+
}
|
|
42463
|
+
}
|
|
42280
42464
|
const totalFailedCalls = trackerDiags.reduce(
|
|
42281
42465
|
(sum, d) => sum + d.failedCalls,
|
|
42282
42466
|
0
|
|
@@ -42332,6 +42516,217 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
42332
42516
|
};
|
|
42333
42517
|
return { prices: result, diagnostics };
|
|
42334
42518
|
}
|
|
42519
|
+
|
|
42520
|
+
// src/prices/oracle-prices/lenderKeys.ts
|
|
42521
|
+
function lenderFamily(lender) {
|
|
42522
|
+
return lender.replace(/_(0X)?[0-9A-F]{6,}$/i, "");
|
|
42523
|
+
}
|
|
42524
|
+
|
|
42525
|
+
// src/prices/oracle-prices/outlierGuard.ts
|
|
42526
|
+
var DEFAULT_OUTLIER_GUARD = {
|
|
42527
|
+
minAgreeingFamilies: 3,
|
|
42528
|
+
agreementTolerance: 0.05,
|
|
42529
|
+
rejectFactor: 2
|
|
42530
|
+
};
|
|
42531
|
+
function median(values) {
|
|
42532
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
42533
|
+
const mid = Math.floor(sorted.length / 2);
|
|
42534
|
+
return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
|
|
42535
|
+
}
|
|
42536
|
+
function consensusReference(candidates, guard = DEFAULT_OUTLIER_GUARD) {
|
|
42537
|
+
if (candidates.length < guard.minAgreeingFamilies) return void 0;
|
|
42538
|
+
const perFeed = /* @__PURE__ */ new Map();
|
|
42539
|
+
for (const c of candidates) {
|
|
42540
|
+
const bucket = perFeed.get(c.feedKey);
|
|
42541
|
+
if (bucket) bucket.push(c.priceUSD);
|
|
42542
|
+
else perFeed.set(c.feedKey, [c.priceUSD]);
|
|
42543
|
+
}
|
|
42544
|
+
if (perFeed.size < guard.minAgreeingFamilies) return void 0;
|
|
42545
|
+
const feedPrices = [...perFeed.values()].map(median);
|
|
42546
|
+
const reference = median(feedPrices);
|
|
42547
|
+
if (!(reference > 0)) return void 0;
|
|
42548
|
+
const agreeing = feedPrices.filter(
|
|
42549
|
+
(p) => Math.abs(p / reference - 1) <= guard.agreementTolerance
|
|
42550
|
+
).length;
|
|
42551
|
+
if (agreeing < guard.minAgreeingFamilies) return void 0;
|
|
42552
|
+
return reference;
|
|
42553
|
+
}
|
|
42554
|
+
function rejectOutliers(candidates, guard = DEFAULT_OUTLIER_GUARD) {
|
|
42555
|
+
const reference = consensusReference(candidates, guard);
|
|
42556
|
+
if (reference === void 0) return candidates;
|
|
42557
|
+
const upper = reference * guard.rejectFactor;
|
|
42558
|
+
const lower = reference / guard.rejectFactor;
|
|
42559
|
+
const kept = candidates.filter(
|
|
42560
|
+
(c) => c.priceUSD <= upper && c.priceUSD >= lower
|
|
42561
|
+
);
|
|
42562
|
+
return kept.length > 0 ? kept : candidates;
|
|
42563
|
+
}
|
|
42564
|
+
|
|
42565
|
+
// src/prices/oracle-prices/feedStats.ts
|
|
42566
|
+
var EWMA_ALPHA = 0.1;
|
|
42567
|
+
var MIN_DEVIATION_SAMPLES = 5;
|
|
42568
|
+
var BAD_DEVIATION = 0.25;
|
|
42569
|
+
var DEGRADED_DEVIATION = 0.05;
|
|
42570
|
+
var STALE_INTERVAL_MULTIPLE = 4;
|
|
42571
|
+
var MIN_LEARNED_STALE_SECONDS = 6 * 3600;
|
|
42572
|
+
var MIN_UPDATES_FOR_INTERVAL = 4;
|
|
42573
|
+
var FRESHNESS_RANK = {
|
|
42574
|
+
fresh: 0,
|
|
42575
|
+
unknown: 0,
|
|
42576
|
+
// absence of evidence must not demote
|
|
42577
|
+
stale: 1
|
|
42578
|
+
};
|
|
42579
|
+
var RELIABILITY_RANK = {
|
|
42580
|
+
good: 0,
|
|
42581
|
+
unknown: 0,
|
|
42582
|
+
// absence of evidence must not demote
|
|
42583
|
+
degraded: 1,
|
|
42584
|
+
bad: 2
|
|
42585
|
+
};
|
|
42586
|
+
function feedKeyOf(entry, lender) {
|
|
42587
|
+
if (entry.feedSource) return entry.feedSource.toLowerCase();
|
|
42588
|
+
return `${lenderFamily(lender)}|${entry.asset.toLowerCase()}`;
|
|
42589
|
+
}
|
|
42590
|
+
function feedStatKey(chainId, feedKey) {
|
|
42591
|
+
return `${chainId}|${feedKey}`;
|
|
42592
|
+
}
|
|
42593
|
+
function ewma(prev, sample) {
|
|
42594
|
+
if (prev === void 0 || !(prev > 0)) return sample;
|
|
42595
|
+
return prev * (1 - EWMA_ALPHA) + sample * EWMA_ALPHA;
|
|
42596
|
+
}
|
|
42597
|
+
function updateFeedStats(prev, observations, nowSeconds = Math.floor(Date.now() / 1e3)) {
|
|
42598
|
+
const next = { ...prev };
|
|
42599
|
+
for (const obs of observations) {
|
|
42600
|
+
const key = feedStatKey(obs.chainId, obs.feedKey);
|
|
42601
|
+
const existing = next[key];
|
|
42602
|
+
const stat = existing ? { ...existing } : {
|
|
42603
|
+
chainId: obs.chainId,
|
|
42604
|
+
feedKey: obs.feedKey,
|
|
42605
|
+
lastUpdatedAt: 0,
|
|
42606
|
+
lastObservedAt: nowSeconds,
|
|
42607
|
+
updates: 0,
|
|
42608
|
+
intervalEwmaSeconds: 0,
|
|
42609
|
+
intervalMaxSeconds: 0,
|
|
42610
|
+
deviationSamples: 0
|
|
42611
|
+
};
|
|
42612
|
+
if (obs.updatedAt && obs.updatedAt > 0) {
|
|
42613
|
+
if (obs.updatedAt > stat.lastUpdatedAt) {
|
|
42614
|
+
if (stat.lastUpdatedAt > 0) {
|
|
42615
|
+
const interval = obs.updatedAt - stat.lastUpdatedAt;
|
|
42616
|
+
stat.intervalEwmaSeconds = ewma(stat.intervalEwmaSeconds, interval);
|
|
42617
|
+
stat.intervalMaxSeconds = Math.max(stat.intervalMaxSeconds, interval);
|
|
42618
|
+
}
|
|
42619
|
+
stat.lastUpdatedAt = obs.updatedAt;
|
|
42620
|
+
stat.updates += 1;
|
|
42621
|
+
}
|
|
42622
|
+
}
|
|
42623
|
+
if (obs.consensusDeviation !== void 0) {
|
|
42624
|
+
stat.deviationEwma = ewma(stat.deviationEwma, obs.consensusDeviation);
|
|
42625
|
+
stat.deviationSamples += 1;
|
|
42626
|
+
}
|
|
42627
|
+
stat.lastObservedAt = nowSeconds;
|
|
42628
|
+
next[key] = stat;
|
|
42629
|
+
}
|
|
42630
|
+
return next;
|
|
42631
|
+
}
|
|
42632
|
+
function classifyFreshness(updatedAt, stat, defaultStaleSeconds, nowSeconds = Math.floor(Date.now() / 1e3)) {
|
|
42633
|
+
if (!updatedAt || updatedAt <= 0) return "unknown";
|
|
42634
|
+
const age = nowSeconds - updatedAt;
|
|
42635
|
+
if (age < 0) return "fresh";
|
|
42636
|
+
const learned = stat && stat.updates >= MIN_UPDATES_FOR_INTERVAL ? Math.max(
|
|
42637
|
+
stat.intervalEwmaSeconds * STALE_INTERVAL_MULTIPLE,
|
|
42638
|
+
stat.intervalMaxSeconds * 1.5,
|
|
42639
|
+
MIN_LEARNED_STALE_SECONDS
|
|
42640
|
+
) : void 0;
|
|
42641
|
+
const threshold = learned === void 0 ? defaultStaleSeconds : Math.min(learned, defaultStaleSeconds * 2);
|
|
42642
|
+
return age > threshold ? "stale" : "fresh";
|
|
42643
|
+
}
|
|
42644
|
+
function classifyReliability(stat) {
|
|
42645
|
+
if (!stat) return "unknown";
|
|
42646
|
+
if (stat.deviationEwma === void 0 || stat.deviationSamples < MIN_DEVIATION_SAMPLES) {
|
|
42647
|
+
return "unknown";
|
|
42648
|
+
}
|
|
42649
|
+
if (stat.deviationEwma > BAD_DEVIATION) return "bad";
|
|
42650
|
+
if (stat.deviationEwma > DEGRADED_DEVIATION) return "degraded";
|
|
42651
|
+
return "good";
|
|
42652
|
+
}
|
|
42653
|
+
function collectFeedObservations(structuredPrices, lists = {}, guard = DEFAULT_OUTLIER_GUARD) {
|
|
42654
|
+
const byGroup = /* @__PURE__ */ new Map();
|
|
42655
|
+
const samples = [];
|
|
42656
|
+
for (const [chainId, lenders] of Object.entries(structuredPrices)) {
|
|
42657
|
+
const tokenList = lists[chainId] ?? {};
|
|
42658
|
+
for (const [lender, entries] of Object.entries(lenders)) {
|
|
42659
|
+
if (!Array.isArray(entries)) continue;
|
|
42660
|
+
for (const entry of entries) {
|
|
42661
|
+
if (!entry?.asset || !(entry.priceUSD > 0)) continue;
|
|
42662
|
+
const sample = {
|
|
42663
|
+
chainId,
|
|
42664
|
+
feedKey: feedKeyOf(entry, lender),
|
|
42665
|
+
priceUSD: entry.priceUSD,
|
|
42666
|
+
updatedAt: entry.updatedAt
|
|
42667
|
+
};
|
|
42668
|
+
samples.push(sample);
|
|
42669
|
+
const groupKey = tokenList[entry.asset]?.assetGroup ?? `${chainId}-${entry.asset.toLowerCase()}`;
|
|
42670
|
+
const bucket = byGroup.get(groupKey);
|
|
42671
|
+
if (bucket) bucket.push(sample);
|
|
42672
|
+
else byGroup.set(groupKey, [sample]);
|
|
42673
|
+
}
|
|
42674
|
+
}
|
|
42675
|
+
}
|
|
42676
|
+
const observations = [];
|
|
42677
|
+
const seen = /* @__PURE__ */ new Set();
|
|
42678
|
+
for (const [, group] of byGroup) {
|
|
42679
|
+
const perFeed = /* @__PURE__ */ new Map();
|
|
42680
|
+
for (const s of group) {
|
|
42681
|
+
const bucket = perFeed.get(s.feedKey);
|
|
42682
|
+
if (bucket) bucket.push(s.priceUSD);
|
|
42683
|
+
else perFeed.set(s.feedKey, [s.priceUSD]);
|
|
42684
|
+
}
|
|
42685
|
+
if (perFeed.size < 2) continue;
|
|
42686
|
+
const feedPrices = [...perFeed.entries()].map(([feedKey, prices]) => ({
|
|
42687
|
+
feedKey,
|
|
42688
|
+
price: median(prices)
|
|
42689
|
+
}));
|
|
42690
|
+
for (const { feedKey, price: price2 } of feedPrices) {
|
|
42691
|
+
const others = feedPrices.filter((f) => f.feedKey !== feedKey).map((f) => ({ feedKey: f.feedKey, priceUSD: f.price }));
|
|
42692
|
+
const reference = consensusReference(others, guard);
|
|
42693
|
+
const sample = group.find((s) => s.feedKey === feedKey);
|
|
42694
|
+
const dedupKey = `${sample.chainId}|${feedKey}`;
|
|
42695
|
+
if (seen.has(dedupKey)) continue;
|
|
42696
|
+
seen.add(dedupKey);
|
|
42697
|
+
observations.push({
|
|
42698
|
+
chainId: sample.chainId,
|
|
42699
|
+
feedKey,
|
|
42700
|
+
updatedAt: sample.updatedAt,
|
|
42701
|
+
// Undefined when the rest of the group does not agree on anything —
|
|
42702
|
+
// no verdict is recorded rather than a meaningless one.
|
|
42703
|
+
consensusDeviation: reference === void 0 ? void 0 : Math.abs(price2 / reference - 1)
|
|
42704
|
+
});
|
|
42705
|
+
}
|
|
42706
|
+
}
|
|
42707
|
+
for (const s of samples) {
|
|
42708
|
+
const dedupKey = `${s.chainId}|${s.feedKey}`;
|
|
42709
|
+
if (seen.has(dedupKey)) continue;
|
|
42710
|
+
seen.add(dedupKey);
|
|
42711
|
+
observations.push({
|
|
42712
|
+
chainId: s.chainId,
|
|
42713
|
+
feedKey: s.feedKey,
|
|
42714
|
+
updatedAt: s.updatedAt
|
|
42715
|
+
});
|
|
42716
|
+
}
|
|
42717
|
+
return observations;
|
|
42718
|
+
}
|
|
42719
|
+
function pruneFeedStats(stats, maxAgeSeconds = 30 * 24 * 3600, nowSeconds = Math.floor(Date.now() / 1e3)) {
|
|
42720
|
+
const out = {};
|
|
42721
|
+
for (const [key, stat] of Object.entries(stats)) {
|
|
42722
|
+
if (nowSeconds - stat.lastObservedAt <= maxAgeSeconds) out[key] = stat;
|
|
42723
|
+
}
|
|
42724
|
+
return out;
|
|
42725
|
+
}
|
|
42726
|
+
|
|
42727
|
+
// src/prices/oracle-prices/selectAssetGroupPrices.ts
|
|
42728
|
+
var DEFAULT_STALE_REJECT_SECONDS = 172800;
|
|
42729
|
+
var AAVE_V4_PREFIX = "AAVE_V4";
|
|
42335
42730
|
var DEFAULT_PRIORITY = {
|
|
42336
42731
|
chainPriority: [
|
|
42337
42732
|
Chain.ETHEREUM_MAINNET,
|
|
@@ -42340,7 +42735,10 @@ var DEFAULT_PRIORITY = {
|
|
|
42340
42735
|
Chain.BASE,
|
|
42341
42736
|
Chain.AVALANCHE_C_CHAIN
|
|
42342
42737
|
],
|
|
42343
|
-
|
|
42738
|
+
// Aave V4 has no enum member — every key is the runtime-synthesized
|
|
42739
|
+
// `AAVE_V4_<SPOKE_HEX>` — so it is matched by the literal prefix, the same
|
|
42740
|
+
// way `isAaveV4Type()` does.
|
|
42741
|
+
lenderPriority: [Lender.AAVE_V3, AAVE_V4_PREFIX, "COMPOUND_V3"],
|
|
42344
42742
|
lowPriorityLenders: [Lender.ZEROLEND, Lender.AVALON, Lender.MORPHO_BLUE],
|
|
42345
42743
|
excludedLenders: {
|
|
42346
42744
|
// paused
|
|
@@ -42351,64 +42749,140 @@ var DEFAULT_PRIORITY = {
|
|
|
42351
42749
|
"1": [Lender.ZEROLEND_STABLECOINS_RWA, Lender.ZEROLEND_ETH_LRTS],
|
|
42352
42750
|
"534352": ["LORE"],
|
|
42353
42751
|
"167000": [Lender.TAKOTAKO, Lender.TAKOTAKO_ETH],
|
|
42354
|
-
|
|
42752
|
+
// GAMMA (Planet Finance) is abandoned and its oracle is frozen at ~2022
|
|
42753
|
+
// prices across the board — AVAX $23.78 vs $6.44, BTCB $23k vs $64k, and
|
|
42754
|
+
// it still quotes LUNA/UST. Kept as a hard veto because it prices several
|
|
42755
|
+
// dead assets NOTHING else prices, so no consensus can form to catch it.
|
|
42756
|
+
"56": [Lender.AVALON_USDX, Lender.GAMMA],
|
|
42355
42757
|
// broken
|
|
42356
42758
|
"169": [Lender.ZEROLEND]
|
|
42357
42759
|
},
|
|
42358
42760
|
lenderPriorityPerChain: {
|
|
42359
|
-
|
|
42761
|
+
// NOTE: a per-chain list REPLACES the global one, so it has to repeat
|
|
42762
|
+
// every prefix that should still rank on that chain.
|
|
42763
|
+
[Chain.BNB_SMART_CHAIN_MAINNET]: [
|
|
42764
|
+
Lender.AAVE_V3,
|
|
42765
|
+
AAVE_V4_PREFIX,
|
|
42766
|
+
Lender.VENUS
|
|
42767
|
+
],
|
|
42360
42768
|
[Chain.XDC_NETWORK]: [Lender.PRIME_FI, Lender.FATHOM],
|
|
42361
42769
|
[Chain.HYPEREVM]: [Lender.HYPERLEND, Lender.HYPURRFI]
|
|
42362
42770
|
},
|
|
42363
42771
|
lowPriorityLendersPerChain: {},
|
|
42364
|
-
excludedLendersPerChain: {}
|
|
42365
|
-
|
|
42366
|
-
|
|
42367
|
-
|
|
42772
|
+
excludedLendersPerChain: {},
|
|
42773
|
+
staleRejectSeconds: DEFAULT_STALE_REJECT_SECONDS,
|
|
42774
|
+
outlierGuard: DEFAULT_OUTLIER_GUARD
|
|
42775
|
+
};
|
|
42776
|
+
var LENDER_RANK_UNLISTED = 1e3;
|
|
42777
|
+
var LENDER_RANK_LOW = 2e3;
|
|
42778
|
+
var CHAIN_RANK_UNLISTED = 1e3;
|
|
42779
|
+
function lenderRankOf(lender, chainId, cfg) {
|
|
42368
42780
|
const excluded = cfg.excludedLenders[chainId];
|
|
42369
42781
|
if (excluded?.some((p) => lender.startsWith(p))) return -1;
|
|
42370
42782
|
const excludedPerChain = cfg.excludedLendersPerChain[chainId];
|
|
42371
42783
|
if (excludedPerChain?.some((p) => lender.startsWith(p))) return -1;
|
|
42372
42784
|
const lowPerChain = cfg.lowPriorityLendersPerChain[chainId];
|
|
42373
42785
|
const isLow = lowPerChain ? lowPerChain.some((p) => lender.startsWith(p)) : cfg.lowPriorityLenders.some((p) => lender.startsWith(p));
|
|
42374
|
-
if (isLow) return
|
|
42786
|
+
if (isLow) return LENDER_RANK_LOW;
|
|
42375
42787
|
const lenderPriority = cfg.lenderPriorityPerChain[chainId] ?? cfg.lenderPriority;
|
|
42376
|
-
const
|
|
42377
|
-
|
|
42378
|
-
|
|
42379
|
-
|
|
42380
|
-
|
|
42381
|
-
|
|
42382
|
-
|
|
42383
|
-
|
|
42788
|
+
const idx = lenderPriority.findIndex((p) => lender.startsWith(p));
|
|
42789
|
+
return idx >= 0 ? idx : LENDER_RANK_UNLISTED;
|
|
42790
|
+
}
|
|
42791
|
+
function depthOf(entryMarketUid, lender, depth) {
|
|
42792
|
+
if (!depth) return 0;
|
|
42793
|
+
if (entryMarketUid) {
|
|
42794
|
+
const perMarket = depth[entryMarketUid];
|
|
42795
|
+
if (typeof perMarket === "number") return perMarket;
|
|
42796
|
+
}
|
|
42797
|
+
const perLender = depth[lender];
|
|
42798
|
+
return typeof perLender === "number" ? perLender : 0;
|
|
42799
|
+
}
|
|
42800
|
+
function compareCandidates(a, b) {
|
|
42801
|
+
return a.freshnessRank - b.freshnessRank || a.reliabilityRank - b.reliabilityRank || a.derivationRank - b.derivationRank || a.lenderRank - b.lenderRank || b.depth - a.depth || a.chainRank - b.chainRank || cmpStr(a.lender, b.lender) || cmpStr(a.chainId, b.chainId) || // One lender can emit many entries for the same asset (Euler prices a
|
|
42802
|
+
// token in every vault that lists it), so lender+chain is NOT a unique
|
|
42803
|
+
// identity. Without these last two the winner among them fell out of
|
|
42804
|
+
// enumeration order and the flat price moved between runs.
|
|
42805
|
+
cmpStr(a.marketUid, b.marketUid) || a.priceUSD - b.priceUSD;
|
|
42806
|
+
}
|
|
42807
|
+
function cmpStr(a, b) {
|
|
42808
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
42809
|
+
}
|
|
42810
|
+
function selectAssetGroupPrices(structuredPrices, lists = {}, depthOrTvl = {}, priorityCfg = DEFAULT_PRIORITY, options = {}) {
|
|
42811
|
+
const staleRejectSeconds = priorityCfg.staleRejectSeconds ?? DEFAULT_STALE_REJECT_SECONDS;
|
|
42812
|
+
const guard = priorityCfg.outlierGuard === void 0 ? DEFAULT_OUTLIER_GUARD : priorityCfg.outlierGuard;
|
|
42813
|
+
const depth = options.depth ?? depthOrTvl;
|
|
42814
|
+
const feedStats = options.feedStats;
|
|
42815
|
+
const nowSeconds = options.nowSeconds ?? Math.floor(Date.now() / 1e3);
|
|
42816
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
42384
42817
|
for (const [chainId, lenders] of Object.entries(structuredPrices)) {
|
|
42385
42818
|
const tokenList = lists[chainId] ?? {};
|
|
42386
42819
|
for (const [lender, entries] of Object.entries(lenders)) {
|
|
42387
42820
|
if (!Array.isArray(entries)) continue;
|
|
42388
|
-
const
|
|
42389
|
-
if (
|
|
42390
|
-
const
|
|
42821
|
+
const lenderRank = lenderRankOf(lender, chainId, priorityCfg);
|
|
42822
|
+
if (lenderRank < 0) continue;
|
|
42823
|
+
const family = lenderFamily(lender);
|
|
42824
|
+
const chainIdx = priorityCfg.chainPriority.indexOf(chainId);
|
|
42825
|
+
const chainRank = chainIdx >= 0 ? chainIdx : CHAIN_RANK_UNLISTED;
|
|
42391
42826
|
for (const entry of entries) {
|
|
42392
42827
|
if (!entry?.asset || entry.priceUSD <= 0) continue;
|
|
42828
|
+
const feedKey = feedKeyOf(entry, lender);
|
|
42829
|
+
const stat = feedStats?.[feedStatKey(chainId, feedKey)];
|
|
42830
|
+
const freshness = staleRejectSeconds > 0 ? classifyFreshness(
|
|
42831
|
+
entry.updatedAt,
|
|
42832
|
+
stat,
|
|
42833
|
+
staleRejectSeconds,
|
|
42834
|
+
nowSeconds
|
|
42835
|
+
) : "unknown";
|
|
42393
42836
|
const oracleKey = tokenList[entry.asset]?.assetGroup ?? `${chainId}-${entry.asset.toLowerCase()}`;
|
|
42394
|
-
|
|
42837
|
+
const candidate = {
|
|
42395
42838
|
oracleKey,
|
|
42396
42839
|
priceUSD: entry.priceUSD,
|
|
42397
|
-
|
|
42398
|
-
|
|
42399
|
-
|
|
42840
|
+
chainId,
|
|
42841
|
+
lender,
|
|
42842
|
+
family,
|
|
42843
|
+
feedKey,
|
|
42844
|
+
marketUid: entry.marketUid ?? "",
|
|
42845
|
+
derivationRank: DERIVATION_RANK[resolveDerivation(entry)],
|
|
42846
|
+
freshnessRank: FRESHNESS_RANK[freshness],
|
|
42847
|
+
reliabilityRank: RELIABILITY_RANK[classifyReliability(stat)],
|
|
42848
|
+
lenderRank,
|
|
42849
|
+
depth: depthOf(entry.marketUid, lender, depth),
|
|
42850
|
+
chainRank
|
|
42851
|
+
};
|
|
42852
|
+
const bucket = byKey.get(oracleKey);
|
|
42853
|
+
if (bucket) bucket.push(candidate);
|
|
42854
|
+
else byKey.set(oracleKey, [candidate]);
|
|
42400
42855
|
}
|
|
42401
42856
|
}
|
|
42402
42857
|
}
|
|
42403
|
-
candidates.sort((a, b) => a.priority - b.priority || b.tvl - a.tvl);
|
|
42404
42858
|
const flatPrices = {};
|
|
42405
|
-
for (const
|
|
42406
|
-
|
|
42407
|
-
|
|
42859
|
+
for (const [oracleKey, candidates] of byKey) {
|
|
42860
|
+
const viable = guard ? rejectOutliers(candidates, guard) : candidates;
|
|
42861
|
+
let best = viable[0];
|
|
42862
|
+
for (const c of viable) {
|
|
42863
|
+
if (compareCandidates(c, best) < 0) best = c;
|
|
42864
|
+
}
|
|
42865
|
+
if (!best) continue;
|
|
42866
|
+
flatPrices[oracleKey] = best.priceUSD;
|
|
42867
|
+
if (options.onSelection) {
|
|
42868
|
+
options.onSelection({
|
|
42869
|
+
assetGroup: oracleKey,
|
|
42870
|
+
priceUSD: best.priceUSD,
|
|
42871
|
+
chainId: best.chainId,
|
|
42872
|
+
lender: best.lender,
|
|
42873
|
+
feedKey: best.feedKey,
|
|
42874
|
+
derivation: derivationOfRank(best.derivationRank),
|
|
42875
|
+
candidates: candidates.length,
|
|
42876
|
+
rejected: candidates.length - viable.length
|
|
42877
|
+
});
|
|
42408
42878
|
}
|
|
42409
42879
|
}
|
|
42410
42880
|
return flatPrices;
|
|
42411
42881
|
}
|
|
42882
|
+
var RANK_TO_DERIVATION = ["direct", "quoted", "derived"];
|
|
42883
|
+
function derivationOfRank(rank) {
|
|
42884
|
+
return RANK_TO_DERIVATION[rank] ?? "derived";
|
|
42885
|
+
}
|
|
42412
42886
|
var { uniq: uniq2 } = lodash;
|
|
42413
42887
|
function createAssetArrayPerChain() {
|
|
42414
42888
|
let assetsPerChain = {};
|
|
@@ -53111,6 +53585,6 @@ async function fetchTokenBalances(chainId, account, tokens, options = {}) {
|
|
|
53111
53585
|
return parseTokenBalanceResult(rawResult, prepared.query);
|
|
53112
53586
|
}
|
|
53113
53587
|
|
|
53114
|
-
export { ApiBookSource, DEFAULT_MIDNIGHT_API, EMPTY_BALANCE, GMX_API_HOSTS, GMX_READ_CONTRACTS, GMX_SUPPORTED_CHAINS, HYPERCORE_VAULT_REGISTRY, IDLE_MARKET_ID, INTERFACE_IDS, LAGOON_API_URL, LAGOON_CHAIN_IDS, MORPHO_LENS, MaxParamThresholds, STABLECOIN_SYMBOLS, STCELO_MANAGER_ADDRESS, TELLER_CALLS_PER_BID, TermSubgraphSource, UPSHIFT_CHAIN_IDS, UPSHIFT_VAULTS_URL, VAULT_SHARE_PRICE_PROBE, VOLATILE_VAULT_OVERRIDES, YEARN_CHAIN_IDS, YEARN_YDAEMON_BASE, accountDepositListKey, accountWithdrawalListKey, appendSnapshot, applyPositionDelta, attachPricesToFlashLiquidity, buildFluidFTokensCall, buildLiquityUserCall, buildLoopResult, buildMorphoTypeCall, buildMorphoTypeUserCallWithLens, buildPortfolioTotals, buildSumerAccumulators, buildSummaries, buildTellerUserCall, buildVaultLookup, calculateLeverage, calculateNetApr, calculateOverallNetApr, calculateWeightedAverage, classifyVault, computeBorrowDelta2 as computeBorrowDelta, computeCloseTradeDeltas, computeCollateralSwapDeltas, computeDebtSwapDeltas, computeDepositDelta2 as computeDepositDelta, computeEModeAnalysis, computeOpenTradeDeltas, computePostTradeMetrics, computeRepayDelta2 as computeRepayDelta, computeSumerBorrowDelta, computeSumerDepositDelta, computeSumerRepayDelta, computeSumerWaterfall, computeSumerWithdrawDelta, computeVaultApr, computeWithdrawDelta2 as computeWithdrawDelta, computeZapTradeDeltas, convertExactlyMarketsToResponse, convertLenderUserDataResult, convertLiquityMarketsToResponse, convertRiverMarketsToResponse, convertTellerMarketsToResponse, convertTermMarketsToResponse, createMarketUid, createMidnightBookSource, createMulticallRpcCall, createRawRpcCalls, createTermBookSource, decodeListaMarkets, decodeMarkets, decodePackedListaUserDataset, decodePackedMorphoUserDataset, detectInterfaceKinds, encodeBalanceFetcherCalldata, exactlyLenderKey, exactlyMarketFromLenderKey, exactlyPairLtv, exactlyPenaltyRateToAprPercent, exactlyWadRateToPercent, fetchDolomiteAccountNumbers, fetchEulerEarnVaults, fetchEulerEarnVaultsFromSubgraph, fetchEulerSubAccountIndexes, fetchExactlyMarkets, fetchFlashLiquidityForChain, fetchFluidFTokens, fetchGeneralYields, fetchGeneralYieldsByMarketUid, fetchGmxExecutionFees, fetchGmxTickerPrices, fetchGmxVaults, fetchHypercoreVaults, fetchLagoonApiVaults, fetchLagoonVaults, fetchLiquityMarkets, fetchListaVaultsFromChain, fetchMorphoUserBalances, fetchMorphoUserPositionMarkets, fetchMorphoVaults, fetchMorphoVaultsFromApi, fetchMorphoVaultsFromChain, fetchOraclePrices, fetchPendlePrices, fetchRiverMarkets, fetchSiloVaults, fetchTellerMarkets, fetchTermMarkets, fetchTokenBalances, fetchTokenMetadata, fetchUpshiftApiVaults, fetchUpshiftVaults, fetchYearnApiVaults, fetchYearnVaults, filterActiveLenders, filterLendersByProtocol, fuseLenderData, generateLendingPools, getAavesForChain, getAssetConfig, getBalanceForMarketUid, getBorrowCapacity, getCachedLiquityTroves, getCachedTellerBids, getCoreValidators, getFluidFTokensConverter, getGmxApiHost, getGmxReadContracts, getGmxUserPositions, getHealthFactor, getHypercoreUserPositions, getHypercoreVaultRegistry, getLenderAssets, getLenderPublicData, getLenderPublicDataAll, getLenderPublicDataViaApi, getLenderUserDataMulti, getLenderUserDataResult, getLendersForChain, getLstDelegation, getLstValidators, getLstWithdrawalRegistry, getLstWithdrawalRequests, getMaxAmountClose, getMaxAmountCollateralSwap, getMaxAmountDebtSwap, getMaxAmountOpen, getMergedUserData, getMorphoTypeMarketConverter, getResolvedDolomiteAccountNumbers, getStCeloValidatorGroups, getSubAccountAddress, getSubAccountIndex, getVaultPublicDataAll, getVaultWithdrawalRequests, hasEulerEarnVaultSubgraph, hasLagoonVaults, hasMorphoPositionIndex, hasMorphoUserApi, hasMorphoUserSubgraph, hasUpshiftVaults, hasYearnVaults, isStablecoinSymbol, isYearnV3, keysFromMaps, liquityCandidateTroveIds, liquityKeyParts, liquityLenderKey, multicall3Abi, nanTo, needsLenderApproval, needsTokenApproval, noOpResult, normalizeToBytes, parseBalanceFetcherResult, parseMergedResult, parseMulticallRpcResponses, parseRawRpcBatchResponses, parseRawRpcResponses, parseTokenBalanceResult, positivePart2 as positivePart, prepareLenderUserDataRpcCalls, prepareMergedMulticallParams, prepareMergedRpcCalls, prepareMulticallInputs, prepareTokenBalanceRpcCalls, priceGlvVaults, priceGmMarkets, readVaultSharePrices, resolveStCeloDepositGroup, riverKeyParts, riverLenderKey, selectAssetGroupPrices, stampVaultClassification, tellerBpsToPercent, tellerImpliedLtv, tellerLenderKey, tellerPoolFromLenderKey, termLenderKey, tickToAprNumber, tickToPrice, unflattenLenderData };
|
|
53588
|
+
export { ApiBookSource, DEFAULT_MIDNIGHT_API, DEFAULT_OUTLIER_GUARD, DEFAULT_STALE_REJECT_SECONDS, EMPTY_BALANCE, GMX_API_HOSTS, GMX_READ_CONTRACTS, GMX_SUPPORTED_CHAINS, HYPERCORE_VAULT_REGISTRY, IDLE_MARKET_ID, INTERFACE_IDS, LAGOON_API_URL, LAGOON_CHAIN_IDS, MORPHO_LENS, MaxParamThresholds, STABLECOIN_SYMBOLS, STCELO_MANAGER_ADDRESS, TELLER_CALLS_PER_BID, TermSubgraphSource, UPSHIFT_CHAIN_IDS, UPSHIFT_VAULTS_URL, VAULT_SHARE_PRICE_PROBE, VOLATILE_VAULT_OVERRIDES, YEARN_CHAIN_IDS, YEARN_YDAEMON_BASE, accountDepositListKey, accountWithdrawalListKey, appendSnapshot, applyPositionDelta, attachPricesToFlashLiquidity, buildFluidFTokensCall, buildLiquityUserCall, buildLoopResult, buildMorphoTypeCall, buildMorphoTypeUserCallWithLens, buildPortfolioTotals, buildSumerAccumulators, buildSummaries, buildTellerUserCall, buildVaultLookup, calculateLeverage, calculateNetApr, calculateOverallNetApr, calculateWeightedAverage, classifyFreshness, classifyReliability, classifyVault, collectFeedObservations, computeBorrowDelta2 as computeBorrowDelta, computeCloseTradeDeltas, computeCollateralSwapDeltas, computeDebtSwapDeltas, computeDepositDelta2 as computeDepositDelta, computeEModeAnalysis, computeOpenTradeDeltas, computePostTradeMetrics, computeRepayDelta2 as computeRepayDelta, computeSumerBorrowDelta, computeSumerDepositDelta, computeSumerRepayDelta, computeSumerWaterfall, computeSumerWithdrawDelta, computeVaultApr, computeWithdrawDelta2 as computeWithdrawDelta, computeZapTradeDeltas, consensusReference, convertExactlyMarketsToResponse, convertLenderUserDataResult, convertLiquityMarketsToResponse, convertRiverMarketsToResponse, convertTellerMarketsToResponse, convertTermMarketsToResponse, createMarketUid, createMidnightBookSource, createMulticallRpcCall, createRawRpcCalls, createTermBookSource, decodeListaMarkets, decodeMarkets, decodePackedListaUserDataset, decodePackedMorphoUserDataset, detectInterfaceKinds, encodeBalanceFetcherCalldata, exactlyLenderKey, exactlyMarketFromLenderKey, exactlyPairLtv, exactlyPenaltyRateToAprPercent, exactlyWadRateToPercent, feedKeyOf, feedStatKey, fetchDolomiteAccountNumbers, fetchEulerEarnVaults, fetchEulerEarnVaultsFromSubgraph, fetchEulerSubAccountIndexes, fetchExactlyMarkets, fetchFlashLiquidityForChain, fetchFluidFTokens, fetchGeneralYields, fetchGeneralYieldsByMarketUid, fetchGmxExecutionFees, fetchGmxTickerPrices, fetchGmxVaults, fetchHypercoreVaults, fetchLagoonApiVaults, fetchLagoonVaults, fetchLiquityMarkets, fetchListaVaultsFromChain, fetchMorphoUserBalances, fetchMorphoUserPositionMarkets, fetchMorphoVaults, fetchMorphoVaultsFromApi, fetchMorphoVaultsFromChain, fetchOraclePrices, fetchPendlePrices, fetchRiverMarkets, fetchSiloVaults, fetchTellerMarkets, fetchTermMarkets, fetchTokenBalances, fetchTokenMetadata, fetchUpshiftApiVaults, fetchUpshiftVaults, fetchYearnApiVaults, fetchYearnVaults, filterActiveLenders, filterLendersByProtocol, fuseLenderData, generateLendingPools, getAavesForChain, getAssetConfig, getBalanceForMarketUid, getBorrowCapacity, getCachedLiquityTroves, getCachedTellerBids, getCoreValidators, getFluidFTokensConverter, getGmxApiHost, getGmxReadContracts, getGmxUserPositions, getHealthFactor, getHypercoreUserPositions, getHypercoreVaultRegistry, getLenderAssets, getLenderPublicData, getLenderPublicDataAll, getLenderPublicDataViaApi, getLenderUserDataMulti, getLenderUserDataResult, getLendersForChain, getLstDelegation, getLstValidators, getLstWithdrawalRegistry, getLstWithdrawalRequests, getMaxAmountClose, getMaxAmountCollateralSwap, getMaxAmountDebtSwap, getMaxAmountOpen, getMergedUserData, getMorphoTypeMarketConverter, getResolvedDolomiteAccountNumbers, getStCeloValidatorGroups, getSubAccountAddress, getSubAccountIndex, getVaultPublicDataAll, getVaultWithdrawalRequests, hasEulerEarnVaultSubgraph, hasLagoonVaults, hasMorphoPositionIndex, hasMorphoUserApi, hasMorphoUserSubgraph, hasUpshiftVaults, hasYearnVaults, isStablecoinSymbol, isYearnV3, keysFromMaps, lenderFamily, liquityCandidateTroveIds, liquityKeyParts, liquityLenderKey, multicall3Abi, nanTo, needsLenderApproval, needsTokenApproval, noOpResult, normalizeToBytes, parseBalanceFetcherResult, parseMergedResult, parseMulticallRpcResponses, parseRawRpcBatchResponses, parseRawRpcResponses, parseTokenBalanceResult, positivePart2 as positivePart, prepareLenderUserDataRpcCalls, prepareMergedMulticallParams, prepareMergedRpcCalls, prepareMulticallInputs, prepareTokenBalanceRpcCalls, priceGlvVaults, priceGmMarkets, probeAaveFeedTimestamps, pruneFeedStats, readVaultSharePrices, rejectOutliers as rejectPriceOutliers, resolveDerivation, resolveStCeloDepositGroup, riverKeyParts, riverLenderKey, selectAssetGroupPrices, stampVaultClassification, tellerBpsToPercent, tellerImpliedLtv, tellerLenderKey, tellerPoolFromLenderKey, termLenderKey, tickToAprNumber, tickToPrice, unflattenLenderData, updateFeedStats };
|
|
53115
53589
|
//# sourceMappingURL=index.js.map
|
|
53116
53590
|
//# sourceMappingURL=index.js.map
|