@1delta/margin-fetcher 0.0.225 → 0.0.228
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/silo-v2/Silo.d.ts +101 -0
- package/dist/abis/silo-v2/Silo.d.ts.map +1 -0
- package/dist/abis/silo-v2/SiloConfig.d.ts +78 -0
- package/dist/abis/silo-v2/SiloConfig.d.ts.map +1 -0
- package/dist/abis/silo-v2/SiloLens.d.ts +50 -0
- package/dist/abis/silo-v2/SiloLens.d.ts.map +1 -0
- package/dist/abis/silo-v2/index.d.ts +4 -0
- package/dist/abis/silo-v2/index.d.ts.map +1 -0
- package/dist/index.js +1850 -95
- package/dist/index.js.map +1 -1
- package/dist/lending/public-data/aave-v4-type/fetcher/normalize.d.ts +1 -0
- package/dist/lending/public-data/aave-v4-type/fetcher/normalize.d.ts.map +1 -1
- package/dist/lending/public-data/fetchLender.d.ts.map +1 -1
- package/dist/lending/public-data/fetchLenderAll.d.ts.map +1 -1
- package/dist/lending/public-data/fetchLenderExt.d.ts.map +1 -1
- package/dist/lending/public-data/lista/getMarketsFromChain.d.ts.map +1 -1
- package/dist/lending/public-data/silo-v2/convertPublic.d.ts +28 -0
- package/dist/lending/public-data/silo-v2/convertPublic.d.ts.map +1 -0
- package/dist/lending/public-data/silo-v2/fetchPublic.d.ts +70 -0
- package/dist/lending/public-data/silo-v2/fetchPublic.d.ts.map +1 -0
- package/dist/lending/public-data/silo-v2/publicCallBuild.d.ts +23 -0
- package/dist/lending/public-data/silo-v2/publicCallBuild.d.ts.map +1 -0
- package/dist/lending/public-data/silo-v2/publicCallParse.d.ts +25 -0
- package/dist/lending/public-data/silo-v2/publicCallParse.d.ts.map +1 -0
- package/dist/lending/public-data/silo-v3/convertPublic.d.ts +18 -0
- package/dist/lending/public-data/silo-v3/convertPublic.d.ts.map +1 -0
- package/dist/lending/public-data/silo-v3/publicCallBuild.d.ts +19 -0
- package/dist/lending/public-data/silo-v3/publicCallBuild.d.ts.map +1 -0
- package/dist/lending/public-data/silo-v3/publicCallParse.d.ts +16 -0
- package/dist/lending/public-data/silo-v3/publicCallParse.d.ts.map +1 -0
- package/dist/lending/user-data/abis.d.ts.map +1 -1
- package/dist/lending/user-data/fetch-balances/parse.d.ts.map +1 -1
- package/dist/lending/user-data/fetch-balances/prepare.d.ts.map +1 -1
- package/dist/lending/user-data/silo-v2/userCallBuild.d.ts +21 -0
- package/dist/lending/user-data/silo-v2/userCallBuild.d.ts.map +1 -0
- package/dist/lending/user-data/silo-v2/userCallParse.d.ts +23 -0
- package/dist/lending/user-data/silo-v2/userCallParse.d.ts.map +1 -0
- package/dist/lending/user-data/utils/types.d.ts +20 -0
- package/dist/lending/user-data/utils/types.d.ts.map +1 -1
- package/dist/prices/oracle-prices/fetchOraclePrices.d.ts.map +1 -1
- package/dist/prices/oracle-prices/fetchers/index.d.ts +2 -0
- package/dist/prices/oracle-prices/fetchers/index.d.ts.map +1 -1
- package/dist/prices/oracle-prices/fetchers/siloV2.d.ts +108 -0
- package/dist/prices/oracle-prices/fetchers/siloV2.d.ts.map +1 -0
- package/dist/prices/oracle-prices/fetchers/siloV2Graphql.d.ts +36 -0
- package/dist/prices/oracle-prices/fetchers/siloV2Graphql.d.ts.map +1 -0
- package/dist/prices/oracle-prices/fetchers/siloV3.d.ts +52 -0
- package/dist/prices/oracle-prices/fetchers/siloV3.d.ts.map +1 -0
- package/dist/prices/oracle-prices/fetchers/siloV3Graphql.d.ts +19 -0
- package/dist/prices/oracle-prices/fetchers/siloV3Graphql.d.ts.map +1 -0
- package/dist/prices/oracle-prices/index.d.ts +2 -0
- package/dist/prices/oracle-prices/index.d.ts.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { parseAbi, formatEther, BaseError, encodeFunctionData, formatUnits, decodeFunctionResult, decodeAbiParameters, AbiEncodingLengthMismatchError, concatHex, isAddress, InvalidAddressError, pad, stringToHex, boolToHex, integerRegex, numberToHex, bytesRegex, BytesSizeMismatchError, arrayRegex, UnsupportedPackedAbiType } from './chunk-ZVIJSUIM.js';
|
|
2
2
|
import './chunk-BYTNVMX7.js';
|
|
3
3
|
import './chunk-PR4QN5HX.js';
|
|
4
|
-
import { Lender, isAaveType, isCompoundV3, isMultiMarket, isAaveV4Type, isInit, isMorphoType, isCompoundV2Type, isVenusType, isSumerType, AAVE_V3_LENDERS, AAVE_V2_LENDERS, isAaveV2Type, isAaveV32Type, isAaveV3Type, isEulerType, isYLDR, isCompoundV3Type, isLista, isTectonicType, isBenqiType } from '@1delta/lender-registry';
|
|
4
|
+
import { Lender, isAaveType, isCompoundV3, isMultiMarket, isSiloV2Type, isSiloV3Type, isAaveV4Type, isInit, isMorphoType, isCompoundV2Type, isVenusType, isSumerType, AAVE_V3_LENDERS, AAVE_V2_LENDERS, isAaveV2Type, isAaveV32Type, isAaveV3Type, isEulerType, isYLDR, isCompoundV3Type, isLista, isTectonicType, isBenqiType } 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
7
|
import { getEvmChain, getEvmClient, getEvmClientUniversal, multicallRetryUniversal } from '@1delta/providers';
|
|
@@ -6277,7 +6277,11 @@ globalThis[GLOBAL_LENDER_DATA_KEY] = {
|
|
|
6277
6277
|
eulerVaults: {},
|
|
6278
6278
|
aaveV4Spokes: {},
|
|
6279
6279
|
aaveV4Oracles: {},
|
|
6280
|
-
aaveV4Peripherals: {}
|
|
6280
|
+
aaveV4Peripherals: {},
|
|
6281
|
+
siloMarkets: {},
|
|
6282
|
+
siloPeripherals: {},
|
|
6283
|
+
siloMarketsV3: {},
|
|
6284
|
+
siloPeripheralsV3: {}
|
|
6281
6285
|
};
|
|
6282
6286
|
function getGlobalData2() {
|
|
6283
6287
|
return globalThis[GLOBAL_LENDER_DATA_KEY];
|
|
@@ -6303,6 +6307,8 @@ var eulerConfigs = () => getGlobalData2()?.eulerConfigs;
|
|
|
6303
6307
|
var eulerVaults = () => getGlobalData2()?.eulerVaults;
|
|
6304
6308
|
var aaveV4Spokes = () => getGlobalData2()?.aaveV4Spokes;
|
|
6305
6309
|
var aaveV4Oracles = () => getGlobalData2()?.aaveV4Oracles;
|
|
6310
|
+
var siloMarkets = () => getGlobalData2()?.siloMarkets;
|
|
6311
|
+
var siloMarketsV3 = () => getGlobalData2()?.siloMarketsV3;
|
|
6306
6312
|
function aaveV4SpokeLenderKey(spoke) {
|
|
6307
6313
|
if (!spoke || !spoke.startsWith("0x") || spoke.length !== 42) {
|
|
6308
6314
|
throw new Error(`aaveV4SpokeLenderKey: invalid spoke address ${spoke}`);
|
|
@@ -6314,6 +6320,46 @@ function parseAaveV4SpokeLenderKey(lenderKey) {
|
|
|
6314
6320
|
if (!match) return void 0;
|
|
6315
6321
|
return { spokeAddrLower: "0x" + match[1].toLowerCase() };
|
|
6316
6322
|
}
|
|
6323
|
+
function siloV2LenderKey(siloConfig) {
|
|
6324
|
+
if (!siloConfig || !siloConfig.startsWith("0x") || siloConfig.length !== 42) {
|
|
6325
|
+
throw new Error(`siloV2LenderKey: invalid siloConfig address ${siloConfig}`);
|
|
6326
|
+
}
|
|
6327
|
+
return `SILO_V2_${siloConfig.slice(2).toUpperCase()}`;
|
|
6328
|
+
}
|
|
6329
|
+
function parseSiloV2LenderKey(lenderKey) {
|
|
6330
|
+
const match = lenderKey.match(/^SILO_V2_([0-9A-F]{40})$/);
|
|
6331
|
+
if (!match) return void 0;
|
|
6332
|
+
return { siloConfigAddrLower: "0x" + match[1].toLowerCase() };
|
|
6333
|
+
}
|
|
6334
|
+
function getSiloV2MarketEntry(chainId, lenderKey) {
|
|
6335
|
+
const parsed = parseSiloV2LenderKey(lenderKey);
|
|
6336
|
+
if (!parsed) return void 0;
|
|
6337
|
+
const list = getGlobalData2()?.siloMarkets?.[chainId];
|
|
6338
|
+
if (!list) return void 0;
|
|
6339
|
+
return list.find(
|
|
6340
|
+
(m) => m.siloConfig.toLowerCase() === parsed.siloConfigAddrLower
|
|
6341
|
+
);
|
|
6342
|
+
}
|
|
6343
|
+
function siloV3LenderKey(siloConfig) {
|
|
6344
|
+
if (!siloConfig || !siloConfig.startsWith("0x") || siloConfig.length !== 42) {
|
|
6345
|
+
throw new Error(`siloV3LenderKey: invalid siloConfig address ${siloConfig}`);
|
|
6346
|
+
}
|
|
6347
|
+
return `SILO_V3_${siloConfig.slice(2).toUpperCase()}`;
|
|
6348
|
+
}
|
|
6349
|
+
function parseSiloV3LenderKey(lenderKey) {
|
|
6350
|
+
const match = lenderKey.match(/^SILO_V3_([0-9A-F]{40})$/);
|
|
6351
|
+
if (!match) return void 0;
|
|
6352
|
+
return { siloConfigAddrLower: "0x" + match[1].toLowerCase() };
|
|
6353
|
+
}
|
|
6354
|
+
function getSiloV3MarketEntry(chainId, lenderKey) {
|
|
6355
|
+
const parsed = parseSiloV3LenderKey(lenderKey);
|
|
6356
|
+
if (!parsed) return void 0;
|
|
6357
|
+
const list = getGlobalData2()?.siloMarketsV3?.[chainId];
|
|
6358
|
+
if (!list) return void 0;
|
|
6359
|
+
return list.find(
|
|
6360
|
+
(m) => m.siloConfig.toLowerCase() === parsed.siloConfigAddrLower
|
|
6361
|
+
);
|
|
6362
|
+
}
|
|
6317
6363
|
var getListUrl = (chainId) => `https://raw.githubusercontent.com/1delta-DAO/token-lists/main/${chainId}.json`;
|
|
6318
6364
|
async function fetchTokenList(chainId) {
|
|
6319
6365
|
const data = await fetch(getListUrl(chainId));
|
|
@@ -7544,6 +7590,10 @@ var getLendersForChain = (c) => {
|
|
|
7544
7590
|
if (data[c]?.length > 0) lenders.push(l);
|
|
7545
7591
|
});
|
|
7546
7592
|
}
|
|
7593
|
+
const siloChainPairs = siloMarkets()?.[c] ?? [];
|
|
7594
|
+
for (const market of siloChainPairs) {
|
|
7595
|
+
lenders.push(siloV2LenderKey(market.siloConfig));
|
|
7596
|
+
}
|
|
7547
7597
|
const v4ChainSpokes = aaveV4Spokes()?.[c] ?? {};
|
|
7548
7598
|
for (const spokeAddr of Object.keys(v4ChainSpokes)) {
|
|
7549
7599
|
lenders.push(aaveV4SpokeLenderKey(spokeAddr));
|
|
@@ -13003,7 +13053,11 @@ function getListaMarketDataConverter(lender, chainId, prices, additionalYields =
|
|
|
13003
13053
|
};
|
|
13004
13054
|
const ltv = parseLtv(lltv);
|
|
13005
13055
|
const metaCollateral = tokens[collateralAssetAddress] ?? collateralAsset;
|
|
13006
|
-
const collateralMarketUid = createMarketUid(
|
|
13056
|
+
const collateralMarketUid = createMarketUid(
|
|
13057
|
+
chainId,
|
|
13058
|
+
m,
|
|
13059
|
+
collateralAssetAddress
|
|
13060
|
+
);
|
|
13007
13061
|
data[m].data[collateralMarketUid] = {
|
|
13008
13062
|
marketUid: collateralMarketUid,
|
|
13009
13063
|
name: "Collateral " + (metaCollateral?.symbol ?? ""),
|
|
@@ -18330,7 +18384,8 @@ function normalizeAaveV4(spokeDataList, chainId, spokeLenderKeyArg, prices, addi
|
|
|
18330
18384
|
collateralRiskBps,
|
|
18331
18385
|
riskPremiumThresholdBps,
|
|
18332
18386
|
depositable: depositableNum,
|
|
18333
|
-
borrowLiquidity: borrowLiquidityNum
|
|
18387
|
+
borrowLiquidity: borrowLiquidityNum,
|
|
18388
|
+
borrowLiquidityUSD: borrowLiquidityNum * price
|
|
18334
18389
|
};
|
|
18335
18390
|
}
|
|
18336
18391
|
if (Object.keys(data).length === 0) return void 0;
|
|
@@ -18552,6 +18607,399 @@ var getAaveV4ReservesDataConverter = (lender, chainId, prices, additionalYields,
|
|
|
18552
18607
|
};
|
|
18553
18608
|
return [converter, expectedCalls];
|
|
18554
18609
|
};
|
|
18610
|
+
|
|
18611
|
+
// src/abis/silo-v2/Silo.ts
|
|
18612
|
+
var SiloAbi = [
|
|
18613
|
+
{
|
|
18614
|
+
type: "function",
|
|
18615
|
+
name: "totalAssets",
|
|
18616
|
+
stateMutability: "view",
|
|
18617
|
+
inputs: [],
|
|
18618
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
18619
|
+
},
|
|
18620
|
+
{
|
|
18621
|
+
type: "function",
|
|
18622
|
+
name: "getDebtAssets",
|
|
18623
|
+
stateMutability: "view",
|
|
18624
|
+
inputs: [],
|
|
18625
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
18626
|
+
},
|
|
18627
|
+
{
|
|
18628
|
+
type: "function",
|
|
18629
|
+
name: "getCollateralAssets",
|
|
18630
|
+
stateMutability: "view",
|
|
18631
|
+
inputs: [],
|
|
18632
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
18633
|
+
},
|
|
18634
|
+
{
|
|
18635
|
+
type: "function",
|
|
18636
|
+
name: "asset",
|
|
18637
|
+
stateMutability: "view",
|
|
18638
|
+
inputs: [],
|
|
18639
|
+
outputs: [{ name: "", type: "address" }]
|
|
18640
|
+
},
|
|
18641
|
+
{
|
|
18642
|
+
type: "function",
|
|
18643
|
+
name: "balanceOf",
|
|
18644
|
+
stateMutability: "view",
|
|
18645
|
+
inputs: [{ name: "account", type: "address" }],
|
|
18646
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
18647
|
+
},
|
|
18648
|
+
{
|
|
18649
|
+
type: "function",
|
|
18650
|
+
name: "convertToAssets",
|
|
18651
|
+
stateMutability: "view",
|
|
18652
|
+
inputs: [{ name: "shares", type: "uint256" }],
|
|
18653
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
18654
|
+
},
|
|
18655
|
+
{
|
|
18656
|
+
type: "function",
|
|
18657
|
+
name: "maxRepay",
|
|
18658
|
+
stateMutability: "view",
|
|
18659
|
+
inputs: [{ name: "borrower", type: "address" }],
|
|
18660
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
18661
|
+
}
|
|
18662
|
+
];
|
|
18663
|
+
var SiloConvertToAssetsTypedAbi = [
|
|
18664
|
+
{
|
|
18665
|
+
type: "function",
|
|
18666
|
+
name: "convertToAssets",
|
|
18667
|
+
stateMutability: "view",
|
|
18668
|
+
inputs: [
|
|
18669
|
+
{ name: "shares", type: "uint256" },
|
|
18670
|
+
{ name: "assetType", type: "uint8" }
|
|
18671
|
+
],
|
|
18672
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
18673
|
+
}
|
|
18674
|
+
];
|
|
18675
|
+
|
|
18676
|
+
// src/abis/silo-v2/SiloLens.ts
|
|
18677
|
+
var SiloLensAbi = [
|
|
18678
|
+
{
|
|
18679
|
+
type: "function",
|
|
18680
|
+
name: "getDepositAPR",
|
|
18681
|
+
stateMutability: "view",
|
|
18682
|
+
inputs: [{ name: "_silo", type: "address" }],
|
|
18683
|
+
outputs: [{ name: "depositAPR", type: "uint256" }]
|
|
18684
|
+
},
|
|
18685
|
+
{
|
|
18686
|
+
type: "function",
|
|
18687
|
+
name: "getBorrowAPR",
|
|
18688
|
+
stateMutability: "view",
|
|
18689
|
+
inputs: [{ name: "_silo", type: "address" }],
|
|
18690
|
+
outputs: [{ name: "borrowAPR", type: "uint256" }]
|
|
18691
|
+
},
|
|
18692
|
+
{
|
|
18693
|
+
type: "function",
|
|
18694
|
+
name: "getUtilization",
|
|
18695
|
+
stateMutability: "view",
|
|
18696
|
+
inputs: [{ name: "_silo", type: "address" }],
|
|
18697
|
+
outputs: [{ name: "utilization", type: "uint256" }]
|
|
18698
|
+
},
|
|
18699
|
+
{
|
|
18700
|
+
type: "function",
|
|
18701
|
+
name: "getRawLiquidity",
|
|
18702
|
+
stateMutability: "view",
|
|
18703
|
+
inputs: [{ name: "_silo", type: "address" }],
|
|
18704
|
+
outputs: [{ name: "liquidity", type: "uint256" }]
|
|
18705
|
+
}
|
|
18706
|
+
];
|
|
18707
|
+
|
|
18708
|
+
// src/lending/public-data/silo-v2/publicCallBuild.ts
|
|
18709
|
+
var SILO_V2_CALLS_PER_SIDE = 2;
|
|
18710
|
+
var SILO_V2_CALLS_PER_PAIR = SILO_V2_CALLS_PER_SIDE * 2;
|
|
18711
|
+
function buildSiloV2LenderReserveCall(_chainId, lender) {
|
|
18712
|
+
const market = getSiloV2MarketEntry(_chainId, lender);
|
|
18713
|
+
if (!market) return [];
|
|
18714
|
+
const calls = [];
|
|
18715
|
+
for (const half of [market.silo0, market.silo1]) {
|
|
18716
|
+
calls.push(
|
|
18717
|
+
{
|
|
18718
|
+
address: half.silo,
|
|
18719
|
+
name: "totalAssets",
|
|
18720
|
+
params: [],
|
|
18721
|
+
abi: SiloAbi
|
|
18722
|
+
},
|
|
18723
|
+
{
|
|
18724
|
+
address: half.silo,
|
|
18725
|
+
name: "getDebtAssets",
|
|
18726
|
+
params: [],
|
|
18727
|
+
abi: SiloAbi
|
|
18728
|
+
}
|
|
18729
|
+
);
|
|
18730
|
+
}
|
|
18731
|
+
return calls;
|
|
18732
|
+
}
|
|
18733
|
+
|
|
18734
|
+
// src/lending/public-data/silo-v2/publicCallParse.ts
|
|
18735
|
+
var getSiloV2ReservesDataConverter = (lender, chainId, prices, additionalYields, tokenList = {}) => {
|
|
18736
|
+
const market = getSiloV2MarketEntry(chainId, lender);
|
|
18737
|
+
if (!market) return [() => void 0, 0];
|
|
18738
|
+
return [
|
|
18739
|
+
(data) => {
|
|
18740
|
+
if (!data || data.length !== SILO_V2_CALLS_PER_PAIR) return void 0;
|
|
18741
|
+
const out = {};
|
|
18742
|
+
const sides = [
|
|
18743
|
+
{ self: market.silo0, other: market.silo1 },
|
|
18744
|
+
{ self: market.silo1, other: market.silo0 }
|
|
18745
|
+
];
|
|
18746
|
+
const toBigInt6 = (v) => {
|
|
18747
|
+
if (v === void 0 || v === null || v === "0x") return 0n;
|
|
18748
|
+
if (typeof v === "bigint") return v;
|
|
18749
|
+
try {
|
|
18750
|
+
return BigInt(v);
|
|
18751
|
+
} catch {
|
|
18752
|
+
return 0n;
|
|
18753
|
+
}
|
|
18754
|
+
};
|
|
18755
|
+
for (let s = 0; s < 2; s++) {
|
|
18756
|
+
const { self, other } = sides[s];
|
|
18757
|
+
const slot = s * SILO_V2_CALLS_PER_SIDE;
|
|
18758
|
+
const totalAssetsRaw = toBigInt6(data[slot]);
|
|
18759
|
+
const debtAssetsRaw = toBigInt6(data[slot + 1]);
|
|
18760
|
+
const decimals = self.decimals;
|
|
18761
|
+
const totalDeposits = Number(formatUnits(totalAssetsRaw, decimals));
|
|
18762
|
+
const totalDebt = Number(formatUnits(debtAssetsRaw, decimals));
|
|
18763
|
+
const totalLiquidity = totalDeposits - totalDebt;
|
|
18764
|
+
const utilization = totalDeposits > 0 ? totalDebt / totalDeposits : 0;
|
|
18765
|
+
const depositRatePct = 0;
|
|
18766
|
+
const variableBorrowRatePct = 0;
|
|
18767
|
+
const tokenAddrLc = self.token.toLowerCase();
|
|
18768
|
+
const assetMeta = tokenList[tokenAddrLc];
|
|
18769
|
+
const oracleKey = toOracleKey(assetMeta?.assetGroup ?? null) || toGenericPriceKey(tokenAddrLc, chainId);
|
|
18770
|
+
const price = prices[oracleKey] ?? 0;
|
|
18771
|
+
const collateralLt = Number(other.lt) / 1e18;
|
|
18772
|
+
const collateralMaxLtv = Number(other.maxLtv) / 1e18;
|
|
18773
|
+
const selfLt = Number(self.lt) / 1e18;
|
|
18774
|
+
const borrowingEnabled = collateralLt > 0;
|
|
18775
|
+
const collateralActive = selfLt > 0;
|
|
18776
|
+
const marketUid = createMarketUid(chainId, lender, self.silo);
|
|
18777
|
+
out[marketUid] = {
|
|
18778
|
+
marketUid,
|
|
18779
|
+
name: market.name ? `Silo V2 ${market.name} ${assetMeta?.symbol ?? ""}` : `Silo V2 ${assetMeta?.symbol ?? ""}`,
|
|
18780
|
+
poolId: self.silo.toLowerCase(),
|
|
18781
|
+
underlying: tokenAddrLc,
|
|
18782
|
+
asset: {
|
|
18783
|
+
...assetMeta ?? {},
|
|
18784
|
+
chainId,
|
|
18785
|
+
decimals,
|
|
18786
|
+
address: tokenAddrLc,
|
|
18787
|
+
symbol: assetMeta?.symbol ?? self.symbol ?? "",
|
|
18788
|
+
name: assetMeta?.name ?? self.symbol ?? ""
|
|
18789
|
+
},
|
|
18790
|
+
// token amounts
|
|
18791
|
+
totalDeposits,
|
|
18792
|
+
totalDebt,
|
|
18793
|
+
totalDebtStable: 0,
|
|
18794
|
+
totalLiquidity,
|
|
18795
|
+
borrowLiquidity: totalLiquidity,
|
|
18796
|
+
// USD amounts
|
|
18797
|
+
totalDepositsUSD: totalDeposits * price,
|
|
18798
|
+
totalDebtUSD: totalDebt * price,
|
|
18799
|
+
totalDebtStableUSD: 0,
|
|
18800
|
+
totalLiquidityUSD: totalLiquidity * price,
|
|
18801
|
+
borrowLiquidityUSD: totalLiquidity * price,
|
|
18802
|
+
utilization,
|
|
18803
|
+
depositRate: depositRatePct,
|
|
18804
|
+
variableBorrowRate: variableBorrowRatePct,
|
|
18805
|
+
stableBorrowRate: 0,
|
|
18806
|
+
intrinsicYield: additionalYields?.intrinsicYields?.[assetMeta?.assetGroup] ?? 0,
|
|
18807
|
+
rewards: void 0,
|
|
18808
|
+
decimals,
|
|
18809
|
+
// Each Silo v2 per-pair lender represents exactly ONE pair, so
|
|
18810
|
+
// there is only one collateral counterparty (the OTHER silo) and
|
|
18811
|
+
// a single config entry. Key it as `'0'` to match the Morpho
|
|
18812
|
+
// convention (`config[0]` is the single mode with the market's
|
|
18813
|
+
// LLTV) — the counterparty silo address is still surfaced via
|
|
18814
|
+
// `params.counterpartySilo`.
|
|
18815
|
+
config: {
|
|
18816
|
+
0: {
|
|
18817
|
+
category: 0,
|
|
18818
|
+
borrowCollateralFactor: collateralMaxLtv,
|
|
18819
|
+
collateralFactor: collateralLt,
|
|
18820
|
+
borrowFactor: 1,
|
|
18821
|
+
collateralDisabled: !borrowingEnabled,
|
|
18822
|
+
debtDisabled: !collateralActive
|
|
18823
|
+
}
|
|
18824
|
+
},
|
|
18825
|
+
collateralActive,
|
|
18826
|
+
borrowingEnabled,
|
|
18827
|
+
depositsEnabled: true,
|
|
18828
|
+
hasStable: false,
|
|
18829
|
+
isActive: true,
|
|
18830
|
+
isFrozen: false,
|
|
18831
|
+
params: {
|
|
18832
|
+
metadata: {
|
|
18833
|
+
silo: self.silo,
|
|
18834
|
+
counterpartySilo: other.silo,
|
|
18835
|
+
siloConfig: market.siloConfig,
|
|
18836
|
+
oracle: self.solvencyOracle,
|
|
18837
|
+
irm: self.interestRateModel,
|
|
18838
|
+
shareTokens: {
|
|
18839
|
+
collateral: self.collateralShareToken,
|
|
18840
|
+
protected: self.protectedShareToken,
|
|
18841
|
+
debt: self.debtShareToken
|
|
18842
|
+
},
|
|
18843
|
+
fees: {
|
|
18844
|
+
dao: self.daoFee,
|
|
18845
|
+
deployer: self.deployerFee,
|
|
18846
|
+
liquidation: self.liquidationFee,
|
|
18847
|
+
flashloan: self.flashloanFee
|
|
18848
|
+
}
|
|
18849
|
+
}
|
|
18850
|
+
}
|
|
18851
|
+
};
|
|
18852
|
+
}
|
|
18853
|
+
return { data: out, chainId };
|
|
18854
|
+
},
|
|
18855
|
+
SILO_V2_CALLS_PER_PAIR
|
|
18856
|
+
];
|
|
18857
|
+
};
|
|
18858
|
+
|
|
18859
|
+
// src/lending/public-data/silo-v3/publicCallBuild.ts
|
|
18860
|
+
var SILO_V3_CALLS_PER_SIDE = 2;
|
|
18861
|
+
var SILO_V3_CALLS_PER_PAIR = SILO_V3_CALLS_PER_SIDE * 2;
|
|
18862
|
+
function buildSiloV3LenderReserveCall(_chainId, lender) {
|
|
18863
|
+
const market = getSiloV3MarketEntry(_chainId, lender);
|
|
18864
|
+
if (!market) return [];
|
|
18865
|
+
const calls = [];
|
|
18866
|
+
for (const half of [market.silo0, market.silo1]) {
|
|
18867
|
+
calls.push(
|
|
18868
|
+
{
|
|
18869
|
+
address: half.silo,
|
|
18870
|
+
name: "totalAssets",
|
|
18871
|
+
params: [],
|
|
18872
|
+
abi: SiloAbi
|
|
18873
|
+
},
|
|
18874
|
+
{
|
|
18875
|
+
address: half.silo,
|
|
18876
|
+
name: "getDebtAssets",
|
|
18877
|
+
params: [],
|
|
18878
|
+
abi: SiloAbi
|
|
18879
|
+
}
|
|
18880
|
+
);
|
|
18881
|
+
}
|
|
18882
|
+
return calls;
|
|
18883
|
+
}
|
|
18884
|
+
|
|
18885
|
+
// src/lending/public-data/silo-v3/publicCallParse.ts
|
|
18886
|
+
var getSiloV3ReservesDataConverter = (lender, chainId, prices, additionalYields, tokenList = {}) => {
|
|
18887
|
+
const market = getSiloV3MarketEntry(chainId, lender);
|
|
18888
|
+
if (!market) return [() => void 0, 0];
|
|
18889
|
+
return [
|
|
18890
|
+
(data) => {
|
|
18891
|
+
if (!data || data.length !== SILO_V3_CALLS_PER_PAIR) return void 0;
|
|
18892
|
+
const out = {};
|
|
18893
|
+
const sides = [
|
|
18894
|
+
{ self: market.silo0, other: market.silo1 },
|
|
18895
|
+
{ self: market.silo1, other: market.silo0 }
|
|
18896
|
+
];
|
|
18897
|
+
const toBigInt6 = (v) => {
|
|
18898
|
+
if (v === void 0 || v === null || v === "0x") return 0n;
|
|
18899
|
+
if (typeof v === "bigint") return v;
|
|
18900
|
+
try {
|
|
18901
|
+
return BigInt(v);
|
|
18902
|
+
} catch {
|
|
18903
|
+
return 0n;
|
|
18904
|
+
}
|
|
18905
|
+
};
|
|
18906
|
+
for (let s = 0; s < 2; s++) {
|
|
18907
|
+
const { self, other } = sides[s];
|
|
18908
|
+
const slot = s * SILO_V3_CALLS_PER_SIDE;
|
|
18909
|
+
const totalAssetsRaw = toBigInt6(data[slot]);
|
|
18910
|
+
const debtAssetsRaw = toBigInt6(data[slot + 1]);
|
|
18911
|
+
const decimals = self.decimals;
|
|
18912
|
+
const totalDeposits = Number(formatUnits(totalAssetsRaw, decimals));
|
|
18913
|
+
const totalDebt = Number(formatUnits(debtAssetsRaw, decimals));
|
|
18914
|
+
const totalLiquidity = totalDeposits - totalDebt;
|
|
18915
|
+
const utilization = totalDeposits > 0 ? totalDebt / totalDeposits : 0;
|
|
18916
|
+
const depositRatePct = 0;
|
|
18917
|
+
const variableBorrowRatePct = 0;
|
|
18918
|
+
const tokenAddrLc = self.token.toLowerCase();
|
|
18919
|
+
const assetMeta = tokenList[tokenAddrLc];
|
|
18920
|
+
const oracleKey = toOracleKey(assetMeta?.assetGroup ?? null) || toGenericPriceKey(tokenAddrLc, chainId);
|
|
18921
|
+
const price = prices[oracleKey] ?? 0;
|
|
18922
|
+
const collateralLt = Number(other.lt) / 1e18;
|
|
18923
|
+
const collateralMaxLtv = Number(other.maxLtv) / 1e18;
|
|
18924
|
+
const selfLt = Number(self.lt) / 1e18;
|
|
18925
|
+
const borrowingEnabled = collateralLt > 0;
|
|
18926
|
+
const collateralActive = selfLt > 0;
|
|
18927
|
+
const marketUid = createMarketUid(chainId, lender, self.silo);
|
|
18928
|
+
out[marketUid] = {
|
|
18929
|
+
marketUid,
|
|
18930
|
+
name: market.name ? `Silo V3 ${market.name} ${assetMeta?.symbol ?? ""}` : `Silo V3 ${assetMeta?.symbol ?? ""}`,
|
|
18931
|
+
poolId: self.silo.toLowerCase(),
|
|
18932
|
+
underlying: tokenAddrLc,
|
|
18933
|
+
asset: {
|
|
18934
|
+
...assetMeta ?? {},
|
|
18935
|
+
chainId,
|
|
18936
|
+
decimals,
|
|
18937
|
+
address: tokenAddrLc,
|
|
18938
|
+
symbol: assetMeta?.symbol ?? self.symbol ?? "",
|
|
18939
|
+
name: assetMeta?.name ?? self.symbol ?? ""
|
|
18940
|
+
},
|
|
18941
|
+
totalDeposits,
|
|
18942
|
+
totalDebt,
|
|
18943
|
+
totalDebtStable: 0,
|
|
18944
|
+
totalLiquidity,
|
|
18945
|
+
borrowLiquidity: totalLiquidity,
|
|
18946
|
+
totalDepositsUSD: totalDeposits * price,
|
|
18947
|
+
totalDebtUSD: totalDebt * price,
|
|
18948
|
+
totalDebtStableUSD: 0,
|
|
18949
|
+
totalLiquidityUSD: totalLiquidity * price,
|
|
18950
|
+
borrowLiquidityUSD: totalLiquidity * price,
|
|
18951
|
+
utilization,
|
|
18952
|
+
depositRate: depositRatePct,
|
|
18953
|
+
variableBorrowRate: variableBorrowRatePct,
|
|
18954
|
+
stableBorrowRate: 0,
|
|
18955
|
+
intrinsicYield: additionalYields?.intrinsicYields?.[assetMeta?.assetGroup] ?? 0,
|
|
18956
|
+
rewards: void 0,
|
|
18957
|
+
decimals,
|
|
18958
|
+
config: {
|
|
18959
|
+
0: {
|
|
18960
|
+
category: 0,
|
|
18961
|
+
borrowCollateralFactor: collateralMaxLtv,
|
|
18962
|
+
collateralFactor: collateralLt,
|
|
18963
|
+
borrowFactor: 1,
|
|
18964
|
+
collateralDisabled: !borrowingEnabled,
|
|
18965
|
+
debtDisabled: !collateralActive
|
|
18966
|
+
}
|
|
18967
|
+
},
|
|
18968
|
+
collateralActive,
|
|
18969
|
+
borrowingEnabled,
|
|
18970
|
+
depositsEnabled: true,
|
|
18971
|
+
hasStable: false,
|
|
18972
|
+
isActive: true,
|
|
18973
|
+
isFrozen: false,
|
|
18974
|
+
params: {
|
|
18975
|
+
metadata: {
|
|
18976
|
+
silo: self.silo,
|
|
18977
|
+
counterpartySilo: other.silo,
|
|
18978
|
+
siloConfig: market.siloConfig,
|
|
18979
|
+
oracle: self.solvencyOracle,
|
|
18980
|
+
irm: self.interestRateModel,
|
|
18981
|
+
shareTokens: {
|
|
18982
|
+
collateral: self.collateralShareToken,
|
|
18983
|
+
protected: self.protectedShareToken,
|
|
18984
|
+
debt: self.debtShareToken
|
|
18985
|
+
},
|
|
18986
|
+
fees: {
|
|
18987
|
+
dao: self.daoFee,
|
|
18988
|
+
deployer: self.deployerFee,
|
|
18989
|
+
liquidation: self.liquidationFee,
|
|
18990
|
+
flashloan: self.flashloanFee
|
|
18991
|
+
}
|
|
18992
|
+
}
|
|
18993
|
+
}
|
|
18994
|
+
};
|
|
18995
|
+
}
|
|
18996
|
+
return { data: out, chainId };
|
|
18997
|
+
},
|
|
18998
|
+
SILO_V3_CALLS_PER_PAIR
|
|
18999
|
+
];
|
|
19000
|
+
};
|
|
19001
|
+
|
|
19002
|
+
// src/lending/public-data/fetchLender.ts
|
|
18555
19003
|
function getMorphoTypeMarketConverter(lender, chainId, prices, additionalYields, tokenList = {}, marketsOverride) {
|
|
18556
19004
|
if (lender.startsWith("LISTA_DAO"))
|
|
18557
19005
|
return getListaMarketDataConverter(
|
|
@@ -18586,6 +19034,8 @@ function buildLenderCall(chainId, lender) {
|
|
|
18586
19034
|
return buildCompoundV2StyleLenderReserveCall(chainId, lender);
|
|
18587
19035
|
if (isEulerType(lender)) return buildEulerV2LenderReserveCall(chainId, lender);
|
|
18588
19036
|
if (isAaveV4Type(lender)) return buildAaveV4LenderReserveCall(chainId, lender);
|
|
19037
|
+
if (isSiloV2Type(lender)) return buildSiloV2LenderReserveCall(chainId, lender);
|
|
19038
|
+
if (isSiloV3Type(lender)) return buildSiloV3LenderReserveCall(chainId, lender);
|
|
18589
19039
|
return [];
|
|
18590
19040
|
}
|
|
18591
19041
|
function getLenderDataConverter(lender, chainId, prices, additionalYields, tokenList = {}) {
|
|
@@ -18654,6 +19104,22 @@ function getLenderDataConverter(lender, chainId, prices, additionalYields, token
|
|
|
18654
19104
|
additionalYields,
|
|
18655
19105
|
tokenList
|
|
18656
19106
|
);
|
|
19107
|
+
if (isSiloV2Type(lender))
|
|
19108
|
+
return getSiloV2ReservesDataConverter(
|
|
19109
|
+
lender,
|
|
19110
|
+
chainId,
|
|
19111
|
+
prices,
|
|
19112
|
+
additionalYields,
|
|
19113
|
+
tokenList
|
|
19114
|
+
);
|
|
19115
|
+
if (isSiloV3Type(lender))
|
|
19116
|
+
return getSiloV3ReservesDataConverter(
|
|
19117
|
+
lender,
|
|
19118
|
+
chainId,
|
|
19119
|
+
prices,
|
|
19120
|
+
additionalYields,
|
|
19121
|
+
tokenList
|
|
19122
|
+
);
|
|
18657
19123
|
return [() => null, 0];
|
|
18658
19124
|
}
|
|
18659
19125
|
var getAbi = (lender) => {
|
|
@@ -18674,6 +19140,8 @@ var getAbi = (lender) => {
|
|
|
18674
19140
|
if (isMorphoType(lender)) return MorphoLensAbi;
|
|
18675
19141
|
if (isEulerType(lender)) return vaultLensAbi;
|
|
18676
19142
|
if (isAaveV4Type(lender)) return [...AaveV4SpokeAbi, ...AaveV4OracleAbi, ...AaveV4HubAbi];
|
|
19143
|
+
if (isSiloV2Type(lender)) return [...SiloAbi, ...SiloLensAbi];
|
|
19144
|
+
if (isSiloV3Type(lender)) return [...SiloAbi, ...SiloLensAbi];
|
|
18677
19145
|
if (isSumerType(lender)) return [...SumerLensAbi, ...SumerComptrollerAbi];
|
|
18678
19146
|
if (lender === Lender.TAKARA) return [...TakaraMarketStateAbi];
|
|
18679
19147
|
if (isCompoundV2Type(lender)) return VenusLensAbi;
|
|
@@ -18734,58 +19202,539 @@ var getLenderPublicData = async (chainId, lenders, prices, additionalYields, mul
|
|
|
18734
19202
|
}
|
|
18735
19203
|
return lenderData;
|
|
18736
19204
|
};
|
|
18737
|
-
|
|
18738
|
-
|
|
18739
|
-
|
|
18740
|
-
|
|
18741
|
-
|
|
18742
|
-
|
|
18743
|
-
|
|
18744
|
-
|
|
18745
|
-
|
|
19205
|
+
|
|
19206
|
+
// src/lending/public-data/silo-v2/fetchPublic.ts
|
|
19207
|
+
var BASE_URL2 = "https://api-v3.silo.finance";
|
|
19208
|
+
var SILO_API_SUPPORTED_CHAIN_IDS = /* @__PURE__ */ new Set([
|
|
19209
|
+
"1",
|
|
19210
|
+
// Ethereum
|
|
19211
|
+
"42161",
|
|
19212
|
+
// Arbitrum
|
|
19213
|
+
"43114",
|
|
19214
|
+
// Avalanche
|
|
19215
|
+
"50",
|
|
19216
|
+
// XDC
|
|
19217
|
+
"1776"
|
|
19218
|
+
// Injective
|
|
19219
|
+
]);
|
|
19220
|
+
var query2 = (chainId, limit) => `
|
|
19221
|
+
query GetSilos {
|
|
19222
|
+
silos(where: {chainId_in: [${chainId}]}, limit: ${limit}) {
|
|
19223
|
+
items {
|
|
19224
|
+
id
|
|
19225
|
+
chainId
|
|
19226
|
+
configAddress
|
|
19227
|
+
name
|
|
19228
|
+
protocol {
|
|
19229
|
+
protocolVersion
|
|
19230
|
+
}
|
|
19231
|
+
market1 {
|
|
19232
|
+
index
|
|
19233
|
+
inputTokenId
|
|
19234
|
+
inputToken { id symbol decimals }
|
|
19235
|
+
lt
|
|
19236
|
+
maxLtv
|
|
19237
|
+
liquidationTargetLtv
|
|
19238
|
+
daoFee
|
|
19239
|
+
deployerFee
|
|
19240
|
+
liquidationFee
|
|
19241
|
+
flashLoanFee
|
|
19242
|
+
borrowRate
|
|
19243
|
+
depositRate
|
|
19244
|
+
supply
|
|
19245
|
+
borrowed
|
|
19246
|
+
supplyUsd
|
|
19247
|
+
borrowedUsd
|
|
19248
|
+
liquidityUsd
|
|
19249
|
+
utilization
|
|
19250
|
+
solvencyOracleAddress
|
|
19251
|
+
maxLtvOracleAddress
|
|
19252
|
+
interestRateModelId
|
|
19253
|
+
sTokenId
|
|
19254
|
+
spTokenId
|
|
19255
|
+
dTokenId
|
|
19256
|
+
solvencyOracle {
|
|
19257
|
+
id
|
|
19258
|
+
quote
|
|
19259
|
+
quoteTimestamp
|
|
19260
|
+
baseTokenId
|
|
19261
|
+
quoteTokenId
|
|
19262
|
+
}
|
|
19263
|
+
maxLtvOracle {
|
|
19264
|
+
id
|
|
19265
|
+
quote
|
|
19266
|
+
quoteTimestamp
|
|
19267
|
+
}
|
|
19268
|
+
}
|
|
19269
|
+
market2 {
|
|
19270
|
+
index
|
|
19271
|
+
inputTokenId
|
|
19272
|
+
inputToken { id symbol decimals }
|
|
19273
|
+
lt
|
|
19274
|
+
maxLtv
|
|
19275
|
+
liquidationTargetLtv
|
|
19276
|
+
daoFee
|
|
19277
|
+
deployerFee
|
|
19278
|
+
liquidationFee
|
|
19279
|
+
flashLoanFee
|
|
19280
|
+
borrowRate
|
|
19281
|
+
depositRate
|
|
19282
|
+
supply
|
|
19283
|
+
borrowed
|
|
19284
|
+
supplyUsd
|
|
19285
|
+
borrowedUsd
|
|
19286
|
+
liquidityUsd
|
|
19287
|
+
utilization
|
|
19288
|
+
solvencyOracleAddress
|
|
19289
|
+
maxLtvOracleAddress
|
|
19290
|
+
interestRateModelId
|
|
19291
|
+
sTokenId
|
|
19292
|
+
spTokenId
|
|
19293
|
+
dTokenId
|
|
19294
|
+
solvencyOracle {
|
|
19295
|
+
id
|
|
19296
|
+
quote
|
|
19297
|
+
quoteTimestamp
|
|
19298
|
+
baseTokenId
|
|
19299
|
+
quoteTokenId
|
|
19300
|
+
}
|
|
19301
|
+
maxLtvOracle {
|
|
19302
|
+
id
|
|
19303
|
+
quote
|
|
19304
|
+
quoteTimestamp
|
|
19305
|
+
}
|
|
19306
|
+
}
|
|
19307
|
+
}
|
|
19308
|
+
}
|
|
18746
19309
|
}
|
|
18747
|
-
|
|
18748
|
-
|
|
18749
|
-
|
|
18750
|
-
|
|
18751
|
-
|
|
18752
|
-
|
|
18753
|
-
|
|
18754
|
-
|
|
18755
|
-
|
|
18756
|
-
|
|
18757
|
-
|
|
18758
|
-
|
|
18759
|
-
)
|
|
19310
|
+
`;
|
|
19311
|
+
async function fetchSiloMarkets(chainId, options) {
|
|
19312
|
+
if (!SILO_API_SUPPORTED_CHAIN_IDS.has(chainId)) return [];
|
|
19313
|
+
const limit = options?.limit ?? 500;
|
|
19314
|
+
const response = await fetch(BASE_URL2, {
|
|
19315
|
+
method: "POST",
|
|
19316
|
+
headers: { "Content-Type": "application/json" },
|
|
19317
|
+
body: JSON.stringify({ query: query2(chainId, limit) })
|
|
19318
|
+
});
|
|
19319
|
+
if (!response.ok) {
|
|
19320
|
+
throw new Error(
|
|
19321
|
+
`[silo-api] Network error: ${response.status} - ${response.statusText}`
|
|
18760
19322
|
);
|
|
18761
19323
|
}
|
|
18762
|
-
const
|
|
18763
|
-
|
|
18764
|
-
|
|
18765
|
-
|
|
18766
|
-
console.warn(
|
|
18767
|
-
`[lending] tokenList fetch failed on chain ${chainId}:`,
|
|
18768
|
-
listResult.reason
|
|
19324
|
+
const payload = await response.json();
|
|
19325
|
+
if (payload?.errors?.length) {
|
|
19326
|
+
throw new Error(
|
|
19327
|
+
`[silo-api] GraphQL error: ${payload.errors.map((e) => e?.message).join("; ")}`
|
|
18769
19328
|
);
|
|
18770
19329
|
}
|
|
18771
|
-
const
|
|
18772
|
-
|
|
19330
|
+
const items = payload?.data?.silos?.items ?? [];
|
|
19331
|
+
if (!options?.protocolVersion) return items;
|
|
19332
|
+
return items.filter(
|
|
19333
|
+
(s) => s.protocol?.protocolVersion === options.protocolVersion
|
|
19334
|
+
);
|
|
19335
|
+
}
|
|
19336
|
+
|
|
19337
|
+
// src/lending/public-data/silo-v2/convertPublic.ts
|
|
19338
|
+
function convertSiloMarketsToPublicResponse(apiItems, chainId, prices, additionalYields = {
|
|
19339
|
+
intrinsicYields: {},
|
|
19340
|
+
lenderRewards: {},
|
|
19341
|
+
loaded: true
|
|
19342
|
+
}, tokenList = {}) {
|
|
19343
|
+
const out = {};
|
|
19344
|
+
for (const item of apiItems) {
|
|
19345
|
+
if (item.protocol && item.protocol.protocolVersion !== "v2") continue;
|
|
19346
|
+
let lenderKey;
|
|
18773
19347
|
try {
|
|
18774
|
-
|
|
18775
|
-
|
|
18776
|
-
|
|
18777
|
-
|
|
18778
|
-
|
|
18779
|
-
|
|
18780
|
-
|
|
18781
|
-
|
|
18782
|
-
|
|
18783
|
-
|
|
18784
|
-
|
|
18785
|
-
|
|
18786
|
-
|
|
18787
|
-
|
|
18788
|
-
|
|
19348
|
+
lenderKey = siloV2LenderKey(item.configAddress);
|
|
19349
|
+
} catch {
|
|
19350
|
+
continue;
|
|
19351
|
+
}
|
|
19352
|
+
const registryEntry = getSiloV2MarketEntry(chainId, lenderKey);
|
|
19353
|
+
if (!registryEntry) continue;
|
|
19354
|
+
const [apiSide0, apiSide1] = item.market1.index === 0 ? [item.market1, item.market2] : [item.market2, item.market1];
|
|
19355
|
+
const sides = [
|
|
19356
|
+
{ api: apiSide0, self: registryEntry.silo0, other: registryEntry.silo1 },
|
|
19357
|
+
{ api: apiSide1, self: registryEntry.silo1, other: registryEntry.silo0 }
|
|
19358
|
+
];
|
|
19359
|
+
const data = {};
|
|
19360
|
+
for (const { api, self, other } of sides) {
|
|
19361
|
+
const decimals = api.inputToken?.decimals ?? self.decimals;
|
|
19362
|
+
const tokenAddrLc = (api.inputTokenId ?? self.token).toLowerCase();
|
|
19363
|
+
const totalDeposits = safeNumber(api.supply);
|
|
19364
|
+
const totalDebt = safeNumber(api.borrowed);
|
|
19365
|
+
const totalLiquidity = totalDeposits - totalDebt;
|
|
19366
|
+
const utilization = totalDeposits > 0 ? totalDebt / totalDeposits : safeNumber(api.utilization);
|
|
19367
|
+
const variableBorrowRatePct = safeNumber(api.borrowRate) * 100;
|
|
19368
|
+
const depositRatePct = safeNumber(api.depositRate) * 100;
|
|
19369
|
+
const assetMeta = tokenList[tokenAddrLc];
|
|
19370
|
+
const oracleKey = toOracleKey(assetMeta?.assetGroup ?? null) || toGenericPriceKey(tokenAddrLc, chainId);
|
|
19371
|
+
const fallbackPrice = prices[oracleKey] ?? 0;
|
|
19372
|
+
const totalDepositsUSD = api.supplyUsd != null && api.supplyUsd > 0 ? api.supplyUsd : totalDeposits * fallbackPrice;
|
|
19373
|
+
const totalDebtUSD = api.borrowedUsd != null && api.borrowedUsd > 0 ? api.borrowedUsd : totalDebt * fallbackPrice;
|
|
19374
|
+
const totalLiquidityUSD = Math.max(totalDepositsUSD - totalDebtUSD, 0);
|
|
19375
|
+
const collateralLt = safeLtvOrFee(api, "lt", other.lt);
|
|
19376
|
+
const collateralMaxLtv = safeLtvOrFee(api, "maxLtv", other.maxLtv);
|
|
19377
|
+
const selfLt = bigintToLtv(api.lt ?? self.lt);
|
|
19378
|
+
const collateralLtFromApi = sides[0].api === api ? bigintToLtv(apiSide1.lt) : bigintToLtv(apiSide0.lt);
|
|
19379
|
+
const collateralMaxLtvFromApi = sides[0].api === api ? bigintToLtv(apiSide1.maxLtv) : bigintToLtv(apiSide0.maxLtv);
|
|
19380
|
+
const borrowingEnabled = (collateralLtFromApi || collateralLt) > 0;
|
|
19381
|
+
const collateralActive = selfLt > 0;
|
|
19382
|
+
const siloAddrLc = self.silo.toLowerCase();
|
|
19383
|
+
const marketUid = createMarketUid(chainId, lenderKey, siloAddrLc);
|
|
19384
|
+
data[marketUid] = {
|
|
19385
|
+
marketUid,
|
|
19386
|
+
name: item.name ? `Silo V2 ${item.name} ${assetMeta?.symbol ?? api.inputToken?.symbol ?? ""}` : `Silo V2 ${assetMeta?.symbol ?? api.inputToken?.symbol ?? ""}`,
|
|
19387
|
+
poolId: siloAddrLc,
|
|
19388
|
+
underlying: tokenAddrLc,
|
|
19389
|
+
asset: {
|
|
19390
|
+
...assetMeta ?? {},
|
|
19391
|
+
chainId,
|
|
19392
|
+
decimals,
|
|
19393
|
+
address: tokenAddrLc,
|
|
19394
|
+
symbol: assetMeta?.symbol ?? api.inputToken?.symbol ?? self.symbol ?? "",
|
|
19395
|
+
name: assetMeta?.name ?? api.inputToken?.symbol ?? self.symbol ?? ""
|
|
19396
|
+
},
|
|
19397
|
+
// token amounts
|
|
19398
|
+
totalDeposits,
|
|
19399
|
+
totalDebt,
|
|
19400
|
+
totalDebtStable: 0,
|
|
19401
|
+
totalLiquidity,
|
|
19402
|
+
borrowLiquidity: totalLiquidity,
|
|
19403
|
+
// USD amounts
|
|
19404
|
+
totalDepositsUSD,
|
|
19405
|
+
totalDebtUSD,
|
|
19406
|
+
totalDebtStableUSD: 0,
|
|
19407
|
+
totalLiquidityUSD,
|
|
19408
|
+
borrowLiquidityUSD: totalLiquidityUSD,
|
|
19409
|
+
utilization,
|
|
19410
|
+
depositRate: depositRatePct,
|
|
19411
|
+
variableBorrowRate: variableBorrowRatePct,
|
|
19412
|
+
stableBorrowRate: 0,
|
|
19413
|
+
intrinsicYield: additionalYields?.intrinsicYields?.[assetMeta?.assetGroup] ?? 0,
|
|
19414
|
+
rewards: void 0,
|
|
19415
|
+
decimals,
|
|
19416
|
+
config: {
|
|
19417
|
+
0: {
|
|
19418
|
+
category: 0,
|
|
19419
|
+
borrowCollateralFactor: collateralMaxLtvFromApi || collateralMaxLtv,
|
|
19420
|
+
collateralFactor: collateralLtFromApi || collateralLt,
|
|
19421
|
+
borrowFactor: 1,
|
|
19422
|
+
collateralDisabled: !borrowingEnabled,
|
|
19423
|
+
debtDisabled: !collateralActive
|
|
19424
|
+
}
|
|
19425
|
+
},
|
|
19426
|
+
collateralActive,
|
|
19427
|
+
borrowingEnabled,
|
|
19428
|
+
depositsEnabled: true,
|
|
19429
|
+
hasStable: false,
|
|
19430
|
+
isActive: true,
|
|
19431
|
+
isFrozen: false,
|
|
19432
|
+
params: {
|
|
19433
|
+
metadata: {
|
|
19434
|
+
silo: self.silo.toLowerCase(),
|
|
19435
|
+
counterpartySilo: other.silo.toLowerCase(),
|
|
19436
|
+
siloConfig: registryEntry.siloConfig.toLowerCase(),
|
|
19437
|
+
oracle: (api.solvencyOracleAddress ?? self.solvencyOracle).toLowerCase(),
|
|
19438
|
+
irm: (api.interestRateModelId ?? self.interestRateModel).toLowerCase(),
|
|
19439
|
+
shareTokens: {
|
|
19440
|
+
collateral: self.collateralShareToken,
|
|
19441
|
+
protected: self.protectedShareToken,
|
|
19442
|
+
debt: self.debtShareToken
|
|
19443
|
+
},
|
|
19444
|
+
fees: {
|
|
19445
|
+
dao: api.daoFee ?? self.daoFee,
|
|
19446
|
+
deployer: api.deployerFee ?? self.deployerFee,
|
|
19447
|
+
liquidation: api.liquidationFee ?? self.liquidationFee,
|
|
19448
|
+
flashloan: api.flashLoanFee ?? self.flashloanFee
|
|
19449
|
+
}
|
|
19450
|
+
}
|
|
19451
|
+
}
|
|
19452
|
+
};
|
|
19453
|
+
}
|
|
19454
|
+
out[lenderKey] = { data, chainId };
|
|
19455
|
+
}
|
|
19456
|
+
return out;
|
|
19457
|
+
}
|
|
19458
|
+
function safeNumber(v) {
|
|
19459
|
+
if (v == null) return 0;
|
|
19460
|
+
const n = typeof v === "number" ? v : Number(v);
|
|
19461
|
+
return Number.isFinite(n) ? n : 0;
|
|
19462
|
+
}
|
|
19463
|
+
function bigintToLtv(v) {
|
|
19464
|
+
if (!v) return 0;
|
|
19465
|
+
try {
|
|
19466
|
+
return Number(BigInt(v)) / 1e18;
|
|
19467
|
+
} catch {
|
|
19468
|
+
const n = Number(v);
|
|
19469
|
+
return Number.isFinite(n) ? n / 1e18 : 0;
|
|
19470
|
+
}
|
|
19471
|
+
}
|
|
19472
|
+
function safeLtvOrFee(api, field5, fallback) {
|
|
19473
|
+
return bigintToLtv(api[field5] ?? fallback);
|
|
19474
|
+
}
|
|
19475
|
+
|
|
19476
|
+
// src/lending/public-data/silo-v3/convertPublic.ts
|
|
19477
|
+
function convertSiloV3MarketsToPublicResponse(apiItems, chainId, prices, additionalYields = {
|
|
19478
|
+
intrinsicYields: {},
|
|
19479
|
+
lenderRewards: {},
|
|
19480
|
+
loaded: true
|
|
19481
|
+
}, tokenList = {}) {
|
|
19482
|
+
const out = {};
|
|
19483
|
+
for (const item of apiItems) {
|
|
19484
|
+
if (item.protocol && item.protocol.protocolVersion !== "v3") continue;
|
|
19485
|
+
let lenderKey;
|
|
19486
|
+
try {
|
|
19487
|
+
lenderKey = siloV3LenderKey(item.configAddress);
|
|
19488
|
+
} catch {
|
|
19489
|
+
continue;
|
|
19490
|
+
}
|
|
19491
|
+
const registryEntry = getSiloV3MarketEntry(chainId, lenderKey);
|
|
19492
|
+
if (!registryEntry) continue;
|
|
19493
|
+
const [apiSide0, apiSide1] = item.market1.index === 0 ? [item.market1, item.market2] : [item.market2, item.market1];
|
|
19494
|
+
const sides = [
|
|
19495
|
+
{ api: apiSide0, self: registryEntry.silo0, other: registryEntry.silo1 },
|
|
19496
|
+
{ api: apiSide1, self: registryEntry.silo1, other: registryEntry.silo0 }
|
|
19497
|
+
];
|
|
19498
|
+
const data = {};
|
|
19499
|
+
for (const { api, self, other } of sides) {
|
|
19500
|
+
const decimals = api.inputToken?.decimals ?? self.decimals;
|
|
19501
|
+
const tokenAddrLc = (api.inputTokenId ?? self.token).toLowerCase();
|
|
19502
|
+
const totalDeposits = safeNumber2(api.supply);
|
|
19503
|
+
const totalDebt = safeNumber2(api.borrowed);
|
|
19504
|
+
const totalLiquidity = totalDeposits - totalDebt;
|
|
19505
|
+
const utilization = totalDeposits > 0 ? totalDebt / totalDeposits : safeNumber2(api.utilization);
|
|
19506
|
+
const variableBorrowRatePct = safeNumber2(api.borrowRate) * 100;
|
|
19507
|
+
const depositRatePct = safeNumber2(api.depositRate) * 100;
|
|
19508
|
+
const assetMeta = tokenList[tokenAddrLc];
|
|
19509
|
+
const oracleKey = toOracleKey(assetMeta?.assetGroup ?? null) || toGenericPriceKey(tokenAddrLc, chainId);
|
|
19510
|
+
const fallbackPrice = prices[oracleKey] ?? 0;
|
|
19511
|
+
const totalDepositsUSD = api.supplyUsd != null && api.supplyUsd > 0 ? api.supplyUsd : totalDeposits * fallbackPrice;
|
|
19512
|
+
const totalDebtUSD = api.borrowedUsd != null && api.borrowedUsd > 0 ? api.borrowedUsd : totalDebt * fallbackPrice;
|
|
19513
|
+
const totalLiquidityUSD = Math.max(totalDepositsUSD - totalDebtUSD, 0);
|
|
19514
|
+
const collateralLt = safeLtvOrFee2(api, "lt", other.lt);
|
|
19515
|
+
const collateralMaxLtv = safeLtvOrFee2(api, "maxLtv", other.maxLtv);
|
|
19516
|
+
const selfLt = bigintToLtv2(api.lt ?? self.lt);
|
|
19517
|
+
const collateralLtFromApi = sides[0].api === api ? bigintToLtv2(apiSide1.lt) : bigintToLtv2(apiSide0.lt);
|
|
19518
|
+
const collateralMaxLtvFromApi = sides[0].api === api ? bigintToLtv2(apiSide1.maxLtv) : bigintToLtv2(apiSide0.maxLtv);
|
|
19519
|
+
const borrowingEnabled = (collateralLtFromApi || collateralLt) > 0;
|
|
19520
|
+
const collateralActive = selfLt > 0;
|
|
19521
|
+
const siloAddrLc = self.silo.toLowerCase();
|
|
19522
|
+
const marketUid = createMarketUid(chainId, lenderKey, siloAddrLc);
|
|
19523
|
+
data[marketUid] = {
|
|
19524
|
+
marketUid,
|
|
19525
|
+
name: item.name ? `Silo V3 ${item.name} ${assetMeta?.symbol ?? api.inputToken?.symbol ?? ""}` : `Silo V3 ${assetMeta?.symbol ?? api.inputToken?.symbol ?? ""}`,
|
|
19526
|
+
poolId: siloAddrLc,
|
|
19527
|
+
underlying: tokenAddrLc,
|
|
19528
|
+
asset: {
|
|
19529
|
+
...assetMeta ?? {},
|
|
19530
|
+
chainId,
|
|
19531
|
+
decimals,
|
|
19532
|
+
address: tokenAddrLc,
|
|
19533
|
+
symbol: assetMeta?.symbol ?? api.inputToken?.symbol ?? self.symbol ?? "",
|
|
19534
|
+
name: assetMeta?.name ?? api.inputToken?.symbol ?? self.symbol ?? ""
|
|
19535
|
+
},
|
|
19536
|
+
totalDeposits,
|
|
19537
|
+
totalDebt,
|
|
19538
|
+
totalDebtStable: 0,
|
|
19539
|
+
totalLiquidity,
|
|
19540
|
+
borrowLiquidity: totalLiquidity,
|
|
19541
|
+
totalDepositsUSD,
|
|
19542
|
+
totalDebtUSD,
|
|
19543
|
+
totalDebtStableUSD: 0,
|
|
19544
|
+
totalLiquidityUSD,
|
|
19545
|
+
borrowLiquidityUSD: totalLiquidityUSD,
|
|
19546
|
+
utilization,
|
|
19547
|
+
depositRate: depositRatePct,
|
|
19548
|
+
variableBorrowRate: variableBorrowRatePct,
|
|
19549
|
+
stableBorrowRate: 0,
|
|
19550
|
+
intrinsicYield: additionalYields?.intrinsicYields?.[assetMeta?.assetGroup] ?? 0,
|
|
19551
|
+
rewards: void 0,
|
|
19552
|
+
decimals,
|
|
19553
|
+
config: {
|
|
19554
|
+
0: {
|
|
19555
|
+
category: 0,
|
|
19556
|
+
borrowCollateralFactor: collateralMaxLtvFromApi || collateralMaxLtv,
|
|
19557
|
+
collateralFactor: collateralLtFromApi || collateralLt,
|
|
19558
|
+
borrowFactor: 1,
|
|
19559
|
+
collateralDisabled: !borrowingEnabled,
|
|
19560
|
+
debtDisabled: !collateralActive
|
|
19561
|
+
}
|
|
19562
|
+
},
|
|
19563
|
+
collateralActive,
|
|
19564
|
+
borrowingEnabled,
|
|
19565
|
+
depositsEnabled: true,
|
|
19566
|
+
hasStable: false,
|
|
19567
|
+
isActive: true,
|
|
19568
|
+
isFrozen: false,
|
|
19569
|
+
params: {
|
|
19570
|
+
metadata: {
|
|
19571
|
+
silo: self.silo.toLowerCase(),
|
|
19572
|
+
counterpartySilo: other.silo.toLowerCase(),
|
|
19573
|
+
siloConfig: registryEntry.siloConfig.toLowerCase(),
|
|
19574
|
+
oracle: (api.solvencyOracleAddress ?? self.solvencyOracle).toLowerCase(),
|
|
19575
|
+
irm: (api.interestRateModelId ?? self.interestRateModel).toLowerCase(),
|
|
19576
|
+
shareTokens: {
|
|
19577
|
+
collateral: self.collateralShareToken,
|
|
19578
|
+
protected: self.protectedShareToken,
|
|
19579
|
+
debt: self.debtShareToken
|
|
19580
|
+
},
|
|
19581
|
+
fees: {
|
|
19582
|
+
dao: api.daoFee ?? self.daoFee,
|
|
19583
|
+
deployer: api.deployerFee ?? self.deployerFee,
|
|
19584
|
+
liquidation: api.liquidationFee ?? self.liquidationFee,
|
|
19585
|
+
flashloan: api.flashLoanFee ?? self.flashloanFee
|
|
19586
|
+
}
|
|
19587
|
+
}
|
|
19588
|
+
}
|
|
19589
|
+
};
|
|
19590
|
+
}
|
|
19591
|
+
out[lenderKey] = { data, chainId };
|
|
19592
|
+
}
|
|
19593
|
+
return out;
|
|
19594
|
+
}
|
|
19595
|
+
function safeNumber2(v) {
|
|
19596
|
+
if (v == null) return 0;
|
|
19597
|
+
const n = typeof v === "number" ? v : Number(v);
|
|
19598
|
+
return Number.isFinite(n) ? n : 0;
|
|
19599
|
+
}
|
|
19600
|
+
function bigintToLtv2(v) {
|
|
19601
|
+
if (!v) return 0;
|
|
19602
|
+
try {
|
|
19603
|
+
return Number(BigInt(v)) / 1e18;
|
|
19604
|
+
} catch {
|
|
19605
|
+
const n = Number(v);
|
|
19606
|
+
return Number.isFinite(n) ? n / 1e18 : 0;
|
|
19607
|
+
}
|
|
19608
|
+
}
|
|
19609
|
+
function safeLtvOrFee2(api, field5, fallback) {
|
|
19610
|
+
return bigintToLtv2(api[field5] ?? fallback);
|
|
19611
|
+
}
|
|
19612
|
+
|
|
19613
|
+
// src/lending/public-data/fetchLenderExt.ts
|
|
19614
|
+
async function getLenderDataFromApi(lender, chainId, prices, additionalYields, includeUnlisted = false) {
|
|
19615
|
+
if (isMorphoType(lender))
|
|
19616
|
+
return await fetchMorphoMarkets(chainId, includeUnlisted);
|
|
19617
|
+
return {};
|
|
19618
|
+
}
|
|
19619
|
+
function convertLenderDataFromApi(lender, chainId, data, prices, additionalYields, list = {}) {
|
|
19620
|
+
if (isMorphoType(lender))
|
|
19621
|
+
return convertMarketsToMorphoResponse(data, chainId, additionalYields, list);
|
|
19622
|
+
return {};
|
|
19623
|
+
}
|
|
19624
|
+
var getLenderPublicDataViaApi = async (chainId, lenders, prices, additionalYields, tokenList = async () => {
|
|
19625
|
+
return {};
|
|
19626
|
+
}, includeUnlisted = false) => {
|
|
19627
|
+
const siloV2Lenders = lenders.filter((l) => isSiloV2Type(l));
|
|
19628
|
+
const siloV3Lenders = lenders.filter((l) => isSiloV3Type(l));
|
|
19629
|
+
const otherLenders = lenders.filter(
|
|
19630
|
+
(l) => !isSiloV2Type(l) && !isSiloV3Type(l)
|
|
19631
|
+
);
|
|
19632
|
+
const siloV2Promise = siloV2Lenders.length > 0 ? fetchSiloMarkets(chainId, { protocolVersion: "v2" }).then((items) => ({
|
|
19633
|
+
__silo_items__: items
|
|
19634
|
+
})) : Promise.resolve({});
|
|
19635
|
+
const siloV3Promise = siloV3Lenders.length > 0 ? fetchSiloMarkets(chainId, { protocolVersion: "v3" }).then((items) => ({
|
|
19636
|
+
__silo_items__: items
|
|
19637
|
+
})) : Promise.resolve({});
|
|
19638
|
+
let promises = [];
|
|
19639
|
+
for (const lender of otherLenders) {
|
|
19640
|
+
promises.push(
|
|
19641
|
+
getLenderDataFromApi(
|
|
19642
|
+
lender,
|
|
19643
|
+
chainId,
|
|
19644
|
+
prices,
|
|
19645
|
+
additionalYields,
|
|
19646
|
+
includeUnlisted
|
|
19647
|
+
)
|
|
19648
|
+
);
|
|
19649
|
+
}
|
|
19650
|
+
const settled = await Promise.allSettled([
|
|
19651
|
+
tokenList(),
|
|
19652
|
+
siloV2Promise,
|
|
19653
|
+
siloV3Promise,
|
|
19654
|
+
...promises
|
|
19655
|
+
]);
|
|
19656
|
+
const listResult = settled[0];
|
|
19657
|
+
const list = listResult.status === "fulfilled" ? listResult.value : {};
|
|
19658
|
+
if (listResult.status === "rejected") {
|
|
19659
|
+
console.warn(
|
|
19660
|
+
`[lending] tokenList fetch failed on chain ${chainId}:`,
|
|
19661
|
+
listResult.reason
|
|
19662
|
+
);
|
|
19663
|
+
}
|
|
19664
|
+
const lenderData = {};
|
|
19665
|
+
const siloV2Result = settled[1];
|
|
19666
|
+
if (siloV2Lenders.length > 0) {
|
|
19667
|
+
if (siloV2Result.status === "fulfilled") {
|
|
19668
|
+
const items = siloV2Result.value?.__silo_items__ ?? [];
|
|
19669
|
+
try {
|
|
19670
|
+
const converted = convertSiloMarketsToPublicResponse(
|
|
19671
|
+
items,
|
|
19672
|
+
chainId,
|
|
19673
|
+
prices,
|
|
19674
|
+
additionalYields,
|
|
19675
|
+
list
|
|
19676
|
+
);
|
|
19677
|
+
for (const lk of siloV2Lenders) {
|
|
19678
|
+
if (converted[lk]) lenderData[lk] = converted[lk];
|
|
19679
|
+
}
|
|
19680
|
+
} catch (e) {
|
|
19681
|
+
console.warn(
|
|
19682
|
+
`[lending] Silo v2 API convert failed on chain ${chainId}:`,
|
|
19683
|
+
e?.message ?? e
|
|
19684
|
+
);
|
|
19685
|
+
}
|
|
19686
|
+
} else {
|
|
19687
|
+
console.warn(
|
|
19688
|
+
`[lending] Silo v2 API fetch failed on chain ${chainId}:`,
|
|
19689
|
+
siloV2Result.reason?.message ?? siloV2Result.reason
|
|
19690
|
+
);
|
|
19691
|
+
}
|
|
19692
|
+
}
|
|
19693
|
+
const siloV3Result = settled[2];
|
|
19694
|
+
if (siloV3Lenders.length > 0) {
|
|
19695
|
+
if (siloV3Result.status === "fulfilled") {
|
|
19696
|
+
const items = siloV3Result.value?.__silo_items__ ?? [];
|
|
19697
|
+
try {
|
|
19698
|
+
const converted = convertSiloV3MarketsToPublicResponse(
|
|
19699
|
+
items,
|
|
19700
|
+
chainId,
|
|
19701
|
+
prices,
|
|
19702
|
+
additionalYields,
|
|
19703
|
+
list
|
|
19704
|
+
);
|
|
19705
|
+
for (const lk of siloV3Lenders) {
|
|
19706
|
+
if (converted[lk]) lenderData[lk] = converted[lk];
|
|
19707
|
+
}
|
|
19708
|
+
} catch (e) {
|
|
19709
|
+
console.warn(
|
|
19710
|
+
`[lending] Silo v3 API convert failed on chain ${chainId}:`,
|
|
19711
|
+
e?.message ?? e
|
|
19712
|
+
);
|
|
19713
|
+
}
|
|
19714
|
+
} else {
|
|
19715
|
+
console.warn(
|
|
19716
|
+
`[lending] Silo v3 API fetch failed on chain ${chainId}:`,
|
|
19717
|
+
siloV3Result.reason?.message ?? siloV3Result.reason
|
|
19718
|
+
);
|
|
19719
|
+
}
|
|
19720
|
+
}
|
|
19721
|
+
for (let i = 0; i < otherLenders.length; i++) {
|
|
19722
|
+
try {
|
|
19723
|
+
const result = settled[i + 3];
|
|
19724
|
+
if (result.status === "rejected") {
|
|
19725
|
+
console.warn(
|
|
19726
|
+
`[lending] API fetch failed for ${otherLenders[i]} on chain ${chainId}:`,
|
|
19727
|
+
result.reason?.message ?? result.reason
|
|
19728
|
+
);
|
|
19729
|
+
continue;
|
|
19730
|
+
}
|
|
19731
|
+
const lender = otherLenders[i];
|
|
19732
|
+
if (isMultiMarket(lender)) {
|
|
19733
|
+
const dataObtained = result.value;
|
|
19734
|
+
const converted = convertLenderDataFromApi(
|
|
19735
|
+
lender,
|
|
19736
|
+
chainId,
|
|
19737
|
+
dataObtained,
|
|
18789
19738
|
prices,
|
|
18790
19739
|
additionalYields,
|
|
18791
19740
|
list
|
|
@@ -18807,7 +19756,7 @@ var getLenderPublicDataViaApi = async (chainId, lenders, prices, additionalYield
|
|
|
18807
19756
|
}
|
|
18808
19757
|
return lenderData;
|
|
18809
19758
|
};
|
|
18810
|
-
function
|
|
19759
|
+
function lenderApiOnly(lender, chainId) {
|
|
18811
19760
|
if (lender === Lender.MORPHO_BLUE) {
|
|
18812
19761
|
if (chainId === Chain.SONEIUM) return false;
|
|
18813
19762
|
if (chainId === Chain.HEMI_NETWORK) return false;
|
|
@@ -18818,9 +19767,17 @@ function lenderCanUseApi(lender, chainId) {
|
|
|
18818
19767
|
}
|
|
18819
19768
|
return false;
|
|
18820
19769
|
}
|
|
19770
|
+
function lenderApiWithOnChainFallback(lender, chainId) {
|
|
19771
|
+
if (isSiloV2Type(lender) || isSiloV3Type(lender)) {
|
|
19772
|
+
return SILO_API_SUPPORTED_CHAIN_IDS.has(chainId);
|
|
19773
|
+
}
|
|
19774
|
+
return false;
|
|
19775
|
+
}
|
|
18821
19776
|
var getLenderPublicDataAll = async (chainId, lenders, prices, additionalYields, multicallRetry, tokenList, includeUnlistedMorphoMarkets = false) => {
|
|
18822
|
-
const lendersApi = lenders.filter(
|
|
18823
|
-
|
|
19777
|
+
const lendersApi = lenders.filter(
|
|
19778
|
+
(l) => lenderApiOnly(l, chainId) || lenderApiWithOnChainFallback(l, chainId)
|
|
19779
|
+
);
|
|
19780
|
+
const lendersOnChain = lenders.filter((l) => !lenderApiOnly(l, chainId));
|
|
18824
19781
|
const onChain = getLenderPublicData(
|
|
18825
19782
|
chainId,
|
|
18826
19783
|
lendersOnChain,
|
|
@@ -19133,7 +20090,7 @@ function fetchEulerSubAccountIndexes(chainId, owner) {
|
|
|
19133
20090
|
async function fetchSubAccountsFromSubgraph(chainId, owner) {
|
|
19134
20091
|
const url = EULER_SUBGRAPH_URLS[chainId];
|
|
19135
20092
|
if (!url) return [0];
|
|
19136
|
-
const
|
|
20093
|
+
const query3 = `{
|
|
19137
20094
|
accounts(first: 100, where: { owner: "${owner.toLowerCase()}" }) {
|
|
19138
20095
|
id
|
|
19139
20096
|
subAccount
|
|
@@ -19142,7 +20099,7 @@ async function fetchSubAccountsFromSubgraph(chainId, owner) {
|
|
|
19142
20099
|
const response = await fetch(url, {
|
|
19143
20100
|
method: "POST",
|
|
19144
20101
|
headers: { "Content-Type": "application/json" },
|
|
19145
|
-
body: JSON.stringify({ query:
|
|
20102
|
+
body: JSON.stringify({ query: query3 })
|
|
19146
20103
|
});
|
|
19147
20104
|
if (!response.ok) return [0];
|
|
19148
20105
|
const data = await response.json();
|
|
@@ -19245,6 +20202,55 @@ var buildAaveV4UserCall = (chainId, lender, account) => {
|
|
|
19245
20202
|
return calls;
|
|
19246
20203
|
};
|
|
19247
20204
|
|
|
20205
|
+
// src/lending/user-data/silo-v2/userCallBuild.ts
|
|
20206
|
+
var ASSET_TYPE_PROTECTED = 0;
|
|
20207
|
+
var ASSET_TYPE_COLLATERAL = 1;
|
|
20208
|
+
var SILO_V2_USER_CALLS_PER_SIDE = 5;
|
|
20209
|
+
var SILO_V2_USER_CALLS_PER_PAIR = SILO_V2_USER_CALLS_PER_SIDE * 2;
|
|
20210
|
+
var buildSiloV2UserCall = (chainId, lender, account) => {
|
|
20211
|
+
const market = getSiloV2MarketEntry(chainId, lender);
|
|
20212
|
+
if (!market) return [];
|
|
20213
|
+
const calls = [];
|
|
20214
|
+
for (const half of [market.silo0, market.silo1]) {
|
|
20215
|
+
const oneUnit = BigInt(10) ** BigInt(half.decimals);
|
|
20216
|
+
calls.push(
|
|
20217
|
+
// [0] collateral shares (silo IS the collateral share token)
|
|
20218
|
+
{
|
|
20219
|
+
address: half.silo,
|
|
20220
|
+
name: "balanceOf",
|
|
20221
|
+
params: [account]
|
|
20222
|
+
},
|
|
20223
|
+
// [1] protected shares (separate ERC-20)
|
|
20224
|
+
{
|
|
20225
|
+
address: half.protectedShareToken,
|
|
20226
|
+
name: "balanceOf",
|
|
20227
|
+
params: [account]
|
|
20228
|
+
},
|
|
20229
|
+
// [2] collateral rate: assets per unit of collateral shares
|
|
20230
|
+
{
|
|
20231
|
+
address: half.silo,
|
|
20232
|
+
name: "convertToAssets",
|
|
20233
|
+
params: [oneUnit, ASSET_TYPE_COLLATERAL],
|
|
20234
|
+
abi: SiloConvertToAssetsTypedAbi
|
|
20235
|
+
},
|
|
20236
|
+
// [3] protected rate: assets per unit of protected shares
|
|
20237
|
+
{
|
|
20238
|
+
address: half.silo,
|
|
20239
|
+
name: "convertToAssets",
|
|
20240
|
+
params: [oneUnit, ASSET_TYPE_PROTECTED],
|
|
20241
|
+
abi: SiloConvertToAssetsTypedAbi
|
|
20242
|
+
},
|
|
20243
|
+
// [4] debt position (already in assets, includes accrued interest)
|
|
20244
|
+
{
|
|
20245
|
+
address: half.silo,
|
|
20246
|
+
name: "maxRepay",
|
|
20247
|
+
params: [account]
|
|
20248
|
+
}
|
|
20249
|
+
);
|
|
20250
|
+
}
|
|
20251
|
+
return calls;
|
|
20252
|
+
};
|
|
20253
|
+
|
|
19248
20254
|
// src/lending/user-data/fetch-balances/prepare.ts
|
|
19249
20255
|
async function buildUserCall(chainId, lender, account, params) {
|
|
19250
20256
|
if (isAaveV4Type(lender)) return buildAaveV4UserCall(chainId, lender, account);
|
|
@@ -19257,6 +20263,8 @@ async function buildUserCall(chainId, lender, account, params) {
|
|
|
19257
20263
|
return buildCompoundV3UserCall(chainId, lender, account);
|
|
19258
20264
|
if (isEulerType(lender))
|
|
19259
20265
|
return buildEulerUserCall(chainId, lender, account, params?.subAccountIndexes);
|
|
20266
|
+
if (isSiloV2Type(lender))
|
|
20267
|
+
return buildSiloV2UserCall(chainId, lender, account);
|
|
19260
20268
|
return buildCompoundV2UserCall(chainId, lender, account);
|
|
19261
20269
|
}
|
|
19262
20270
|
function organizeUserQueries(queries) {
|
|
@@ -20759,6 +21767,104 @@ function createAaveV4Entry(base, data, key, meta, spokeAddr) {
|
|
|
20759
21767
|
};
|
|
20760
21768
|
}
|
|
20761
21769
|
|
|
21770
|
+
// src/lending/user-data/silo-v2/userCallParse.ts
|
|
21771
|
+
var getSiloV2UserDataConverter = (lender, chainId, account, metaMap) => {
|
|
21772
|
+
const market = getSiloV2MarketEntry(chainId, lender);
|
|
21773
|
+
if (!market) return [() => void 0, 0];
|
|
21774
|
+
return [
|
|
21775
|
+
(data) => {
|
|
21776
|
+
if (!data || data.length !== SILO_V2_USER_CALLS_PER_PAIR)
|
|
21777
|
+
return void 0;
|
|
21778
|
+
const sides = [
|
|
21779
|
+
{ self: market.silo0, other: market.silo1 },
|
|
21780
|
+
{ self: market.silo1, other: market.silo0 }
|
|
21781
|
+
];
|
|
21782
|
+
const lendingPositions = {};
|
|
21783
|
+
let addedDeposits = 0;
|
|
21784
|
+
let addedDebt = 0;
|
|
21785
|
+
let hasAnyPosition = false;
|
|
21786
|
+
for (let s = 0; s < 2; s++) {
|
|
21787
|
+
const { self } = sides[s];
|
|
21788
|
+
const slot = s * SILO_V2_USER_CALLS_PER_SIDE;
|
|
21789
|
+
const collateralShares = toBigInt5(data[slot]);
|
|
21790
|
+
const protectedShares = toBigInt5(data[slot + 1]);
|
|
21791
|
+
const collateralRate = toBigInt5(data[slot + 2]);
|
|
21792
|
+
const protectedRate = toBigInt5(data[slot + 3]);
|
|
21793
|
+
const repayRaw = toBigInt5(data[slot + 4]);
|
|
21794
|
+
const decimals = self.decimals;
|
|
21795
|
+
const oneUnit = BigInt(10) ** BigInt(decimals);
|
|
21796
|
+
const collateralAssets = oneUnit > 0n ? collateralShares * collateralRate / oneUnit : 0n;
|
|
21797
|
+
const protectedAssets = oneUnit > 0n ? protectedShares * protectedRate / oneUnit : 0n;
|
|
21798
|
+
const depositAssetsRaw = collateralAssets + protectedAssets;
|
|
21799
|
+
if (depositAssetsRaw === 0n && repayRaw === 0n) continue;
|
|
21800
|
+
hasAnyPosition = true;
|
|
21801
|
+
const marketUid = createMarketUid(chainId, lender, self.silo);
|
|
21802
|
+
const meta = metaMap?.[marketUid];
|
|
21803
|
+
const metaDecimals = meta?.asset?.decimals ?? decimals;
|
|
21804
|
+
const depositsStr = parseRawAmount(
|
|
21805
|
+
depositAssetsRaw.toString(),
|
|
21806
|
+
metaDecimals
|
|
21807
|
+
);
|
|
21808
|
+
const debtStr = parseRawAmount(repayRaw.toString(), metaDecimals);
|
|
21809
|
+
const depositsNum = Number(depositsStr);
|
|
21810
|
+
const debtNum = Number(debtStr);
|
|
21811
|
+
const displayPrice = meta ? getDisplayPrice(meta) : 0;
|
|
21812
|
+
const oraclePrice = meta ? getOraclePrice(meta) : 0;
|
|
21813
|
+
const priceHist = meta?.price?.priceUsd24h ?? displayPrice;
|
|
21814
|
+
const depositsUSD = depositsNum * displayPrice;
|
|
21815
|
+
const debtUSD = debtNum * displayPrice;
|
|
21816
|
+
const depositsUSDOracle = depositsNum * oraclePrice;
|
|
21817
|
+
const debtUSDOracle = debtNum * oraclePrice;
|
|
21818
|
+
addedDeposits += depositsNum * priceHist;
|
|
21819
|
+
addedDebt += debtNum * priceHist;
|
|
21820
|
+
const selfLt = Number(self.lt) / 1e18;
|
|
21821
|
+
const collateralEnabled = selfLt > 0 && depositAssetsRaw > 0n;
|
|
21822
|
+
lendingPositions[marketUid] = {
|
|
21823
|
+
marketUid,
|
|
21824
|
+
underlying: self.token.toLowerCase(),
|
|
21825
|
+
deposits: depositsStr,
|
|
21826
|
+
debt: debtStr,
|
|
21827
|
+
debtStable: "0",
|
|
21828
|
+
depositsUSD,
|
|
21829
|
+
debtUSD,
|
|
21830
|
+
debtStableUSD: 0,
|
|
21831
|
+
depositsUSDOracle,
|
|
21832
|
+
debtUSDOracle,
|
|
21833
|
+
debtStableUSDOracle: 0,
|
|
21834
|
+
stableBorrowRate: "0",
|
|
21835
|
+
collateralEnabled,
|
|
21836
|
+
claimableRewards: 0
|
|
21837
|
+
};
|
|
21838
|
+
}
|
|
21839
|
+
if (!hasAnyPosition) return void 0;
|
|
21840
|
+
const payload = {
|
|
21841
|
+
chainId,
|
|
21842
|
+
account,
|
|
21843
|
+
lendingPositions,
|
|
21844
|
+
rewards: [],
|
|
21845
|
+
userEMode: 0
|
|
21846
|
+
};
|
|
21847
|
+
return createBaseTypeUserState(
|
|
21848
|
+
payload,
|
|
21849
|
+
metaMap,
|
|
21850
|
+
addedDeposits,
|
|
21851
|
+
addedDebt,
|
|
21852
|
+
lender
|
|
21853
|
+
);
|
|
21854
|
+
},
|
|
21855
|
+
SILO_V2_USER_CALLS_PER_PAIR
|
|
21856
|
+
];
|
|
21857
|
+
};
|
|
21858
|
+
function toBigInt5(v) {
|
|
21859
|
+
if (v === void 0 || v === null || v === "0x") return 0n;
|
|
21860
|
+
if (typeof v === "bigint") return v;
|
|
21861
|
+
try {
|
|
21862
|
+
return BigInt(v);
|
|
21863
|
+
} catch {
|
|
21864
|
+
return 0n;
|
|
21865
|
+
}
|
|
21866
|
+
}
|
|
21867
|
+
|
|
20762
21868
|
// src/lending/user-data/fetch-balances/parse.ts
|
|
20763
21869
|
function getUserDataConverter(lender, chainId, account, params, meta) {
|
|
20764
21870
|
if (isAaveV4Type(lender))
|
|
@@ -20793,6 +21899,8 @@ function getUserDataConverter(lender, chainId, account, params, meta) {
|
|
|
20793
21899
|
);
|
|
20794
21900
|
if (isEulerType(lender))
|
|
20795
21901
|
return getEulerUserDataConverter(lender, chainId, account, meta?.[lender], params?.subAccountIndexes);
|
|
21902
|
+
if (isSiloV2Type(lender))
|
|
21903
|
+
return getSiloV2UserDataConverter(lender, chainId, account, meta?.[lender]);
|
|
20796
21904
|
return getCompoundV2UserDataConverter(
|
|
20797
21905
|
lender,
|
|
20798
21906
|
chainId,
|
|
@@ -20814,19 +21922,19 @@ var convertLenderUserDataResult = (chainId, queriesRaw, rawResults, lenderState)
|
|
|
20814
21922
|
const queries = organizeUserQueries(queriesRaw);
|
|
20815
21923
|
const lenderData = {};
|
|
20816
21924
|
let currentSlice = 0;
|
|
20817
|
-
for (const
|
|
21925
|
+
for (const query3 of queries) {
|
|
20818
21926
|
const [converter, sliceLength] = getUserDataConverter(
|
|
20819
|
-
|
|
21927
|
+
query3.lender,
|
|
20820
21928
|
chainId,
|
|
20821
|
-
|
|
20822
|
-
|
|
21929
|
+
query3.account,
|
|
21930
|
+
query3.params,
|
|
20823
21931
|
lenderState
|
|
20824
21932
|
);
|
|
20825
21933
|
try {
|
|
20826
21934
|
const data = rawResults.slice(currentSlice, currentSlice + sliceLength);
|
|
20827
21935
|
const convertedData = converter(data);
|
|
20828
21936
|
if (convertedData) {
|
|
20829
|
-
if (isMultiMarket(
|
|
21937
|
+
if (isMultiMarket(query3.lender)) {
|
|
20830
21938
|
Object.keys(convertedData).forEach((market) => {
|
|
20831
21939
|
const filtered = filterEmptyUserData(convertedData[market]);
|
|
20832
21940
|
if (filtered) {
|
|
@@ -20837,8 +21945,8 @@ var convertLenderUserDataResult = (chainId, queriesRaw, rawResults, lenderState)
|
|
|
20837
21945
|
} else {
|
|
20838
21946
|
const filtered = filterEmptyUserData(convertedData);
|
|
20839
21947
|
if (filtered) {
|
|
20840
|
-
filtered.lender =
|
|
20841
|
-
lenderData[
|
|
21948
|
+
filtered.lender = query3.lender;
|
|
21949
|
+
lenderData[query3.lender] = filtered;
|
|
20842
21950
|
}
|
|
20843
21951
|
}
|
|
20844
21952
|
}
|
|
@@ -25472,6 +26580,7 @@ var getAbi2 = (lender) => {
|
|
|
25472
26580
|
if (isEulerType(lender)) return accountLensAbi;
|
|
25473
26581
|
if (isCompoundV2Type(lender))
|
|
25474
26582
|
return [...ComptrollerAbi, ...CompoundV2CollateralToken];
|
|
26583
|
+
if (isSiloV2Type(lender)) return [...SiloAbi];
|
|
25475
26584
|
return [];
|
|
25476
26585
|
};
|
|
25477
26586
|
|
|
@@ -25578,15 +26687,15 @@ function unflattenLenderData(pools) {
|
|
|
25578
26687
|
var getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient3, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, retries = 3, logs = false) => {
|
|
25579
26688
|
const queries = organizeUserQueries(queriesRaw);
|
|
25580
26689
|
const builtCalls = await Promise.all(
|
|
25581
|
-
queries.map(async (
|
|
25582
|
-
const abi = getAbi2(
|
|
26690
|
+
queries.map(async (query3) => {
|
|
26691
|
+
const abi = getAbi2(query3.lender);
|
|
25583
26692
|
const callData = await buildUserCall(
|
|
25584
26693
|
chainId,
|
|
25585
|
-
|
|
25586
|
-
|
|
25587
|
-
|
|
26694
|
+
query3.lender,
|
|
26695
|
+
query3.account,
|
|
26696
|
+
query3.params
|
|
25588
26697
|
);
|
|
25589
|
-
return callData.map((call) => ({ call, abi }));
|
|
26698
|
+
return callData.map((call) => ({ call, abi: call.abi ?? abi }));
|
|
25590
26699
|
})
|
|
25591
26700
|
);
|
|
25592
26701
|
const calls = builtCalls.flat();
|
|
@@ -25607,15 +26716,15 @@ var prepareLenderUserDataRpcCalls = async (chainId, queriesRaw, batchSize = MULT
|
|
|
25607
26716
|
const multicallAddress = getEvmChain(chainId).contracts?.multicall3?.address;
|
|
25608
26717
|
const queries = organizeUserQueries(queriesRaw);
|
|
25609
26718
|
const builtCalls = await Promise.all(
|
|
25610
|
-
queries.map(async (
|
|
25611
|
-
const abi = getAbi2(
|
|
26719
|
+
queries.map(async (query3) => {
|
|
26720
|
+
const abi = getAbi2(query3.lender);
|
|
25612
26721
|
const callData = await buildUserCall(
|
|
25613
26722
|
chainId,
|
|
25614
|
-
|
|
25615
|
-
|
|
25616
|
-
|
|
26723
|
+
query3.lender,
|
|
26724
|
+
query3.account,
|
|
26725
|
+
query3.params
|
|
25617
26726
|
);
|
|
25618
|
-
return callData.map((call) => ({ call, abi }));
|
|
26727
|
+
return callData.map((call) => ({ call, abi: call.abi ?? abi }));
|
|
25619
26728
|
})
|
|
25620
26729
|
);
|
|
25621
26730
|
const calls = builtCalls.flat();
|
|
@@ -25724,13 +26833,13 @@ async function prepareMergedRpcCalls(chainId, balanceQueries, permissionParams,
|
|
|
25724
26833
|
);
|
|
25725
26834
|
let balanceCalls = [];
|
|
25726
26835
|
const organizedQueries = organizeUserQueries(balanceQueries);
|
|
25727
|
-
for (const
|
|
25728
|
-
const abi = getAbi2(
|
|
26836
|
+
for (const query3 of organizedQueries) {
|
|
26837
|
+
const abi = getAbi2(query3.lender);
|
|
25729
26838
|
const callData = await buildUserCall(
|
|
25730
26839
|
chainId,
|
|
25731
|
-
|
|
25732
|
-
|
|
25733
|
-
|
|
26840
|
+
query3.lender,
|
|
26841
|
+
query3.account,
|
|
26842
|
+
query3.params
|
|
25734
26843
|
);
|
|
25735
26844
|
const mappedCalls = callData.map((call) => ({ call, abi }));
|
|
25736
26845
|
balanceCalls = [...balanceCalls, ...mappedCalls];
|
|
@@ -25789,13 +26898,13 @@ async function prepareMergedMulticallParams(chainId, balanceQueries, permissionP
|
|
|
25789
26898
|
const permissionAbis = permissionCalls.map(() => permissionResult.abi);
|
|
25790
26899
|
let balanceCalls = [];
|
|
25791
26900
|
const organizedQueries = organizeUserQueries(balanceQueries);
|
|
25792
|
-
for (const
|
|
25793
|
-
const abi = getAbi2(
|
|
26901
|
+
for (const query3 of organizedQueries) {
|
|
26902
|
+
const abi = getAbi2(query3.lender);
|
|
25794
26903
|
const callData = await buildUserCall(
|
|
25795
26904
|
chainId,
|
|
25796
|
-
|
|
25797
|
-
|
|
25798
|
-
|
|
26905
|
+
query3.lender,
|
|
26906
|
+
query3.account,
|
|
26907
|
+
query3.params
|
|
25799
26908
|
);
|
|
25800
26909
|
const mappedCalls = callData.map((call) => ({ call, abi }));
|
|
25801
26910
|
balanceCalls = [...balanceCalls, ...mappedCalls];
|
|
@@ -28592,12 +29701,12 @@ function getMorphoCalls(chainId, context) {
|
|
|
28592
29701
|
const queries = getMorphoMarketsForChain(chainId, context?.marketOverrides);
|
|
28593
29702
|
if (queries.length === 0) return [];
|
|
28594
29703
|
const oracleGroups = /* @__PURE__ */ new Map();
|
|
28595
|
-
for (const
|
|
28596
|
-
const oracleLc =
|
|
29704
|
+
for (const query3 of queries) {
|
|
29705
|
+
const oracleLc = query3.oracle.toLowerCase();
|
|
28597
29706
|
if (!oracleGroups.has(oracleLc)) {
|
|
28598
29707
|
oracleGroups.set(oracleLc, []);
|
|
28599
29708
|
}
|
|
28600
|
-
oracleGroups.get(oracleLc).push(
|
|
29709
|
+
oracleGroups.get(oracleLc).push(query3);
|
|
28601
29710
|
}
|
|
28602
29711
|
return Array.from(oracleGroups.values()).map((markets) => {
|
|
28603
29712
|
const call = {
|
|
@@ -29333,6 +30442,550 @@ var aaveV4Fetcher = {
|
|
|
29333
30442
|
getAbi: getAaveV4Abi
|
|
29334
30443
|
};
|
|
29335
30444
|
|
|
30445
|
+
// src/prices/oracle-prices/fetchers/siloV2.ts
|
|
30446
|
+
var SiloOracleAbi = [
|
|
30447
|
+
{
|
|
30448
|
+
inputs: [
|
|
30449
|
+
{ name: "_baseAmount", type: "uint256" },
|
|
30450
|
+
{ name: "_baseToken", type: "address" }
|
|
30451
|
+
],
|
|
30452
|
+
name: "quote",
|
|
30453
|
+
outputs: [{ name: "quoteAmount", type: "uint256" }],
|
|
30454
|
+
stateMutability: "view",
|
|
30455
|
+
type: "function"
|
|
30456
|
+
},
|
|
30457
|
+
{
|
|
30458
|
+
inputs: [],
|
|
30459
|
+
name: "quoteToken",
|
|
30460
|
+
outputs: [{ name: "", type: "address" }],
|
|
30461
|
+
stateMutability: "view",
|
|
30462
|
+
type: "function"
|
|
30463
|
+
}
|
|
30464
|
+
];
|
|
30465
|
+
var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
30466
|
+
function lookupUSD(context, asset) {
|
|
30467
|
+
const lc = asset.toLowerCase();
|
|
30468
|
+
const groupKey = context.tokenList?.[lc]?.assetGroup ?? `${context.chainId}-${lc}`;
|
|
30469
|
+
return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
|
|
30470
|
+
}
|
|
30471
|
+
function getSiloV2Calls(chainId) {
|
|
30472
|
+
const allMarkets = siloMarkets()?.[chainId];
|
|
30473
|
+
if (!allMarkets || allMarkets.length === 0) return [];
|
|
30474
|
+
const tokensWithRealOracle = /* @__PURE__ */ new Set();
|
|
30475
|
+
for (const market of allMarkets) {
|
|
30476
|
+
for (const half of [market.silo0, market.silo1]) {
|
|
30477
|
+
if (half.solvencyOracle && half.solvencyOracle !== ZERO_ADDRESS) {
|
|
30478
|
+
tokensWithRealOracle.add(half.token.toLowerCase());
|
|
30479
|
+
}
|
|
30480
|
+
}
|
|
30481
|
+
}
|
|
30482
|
+
const calls = [];
|
|
30483
|
+
const callIndexMap = {};
|
|
30484
|
+
const quoteTokenIndexMap = {};
|
|
30485
|
+
const entries = [];
|
|
30486
|
+
for (const market of allMarkets) {
|
|
30487
|
+
const lenderKey = siloV2LenderKey(market.siloConfig);
|
|
30488
|
+
const halves = [market.silo0, market.silo1];
|
|
30489
|
+
const isStatic = halves.map(
|
|
30490
|
+
(h) => !h.solvencyOracle || h.solvencyOracle === ZERO_ADDRESS
|
|
30491
|
+
);
|
|
30492
|
+
if (isStatic[0] && isStatic[1]) {
|
|
30493
|
+
const t0 = halves[0].token.toLowerCase();
|
|
30494
|
+
const t1 = halves[1].token.toLowerCase();
|
|
30495
|
+
if (!tokensWithRealOracle.has(t0) && !tokensWithRealOracle.has(t1)) {
|
|
30496
|
+
continue;
|
|
30497
|
+
}
|
|
30498
|
+
}
|
|
30499
|
+
for (let i = 0; i < 2; i++) {
|
|
30500
|
+
const half = halves[i];
|
|
30501
|
+
const partner = halves[1 - i];
|
|
30502
|
+
const tokenLc = half.token.toLowerCase();
|
|
30503
|
+
const partnerLc = partner.token.toLowerCase();
|
|
30504
|
+
if (isStatic[i]) {
|
|
30505
|
+
entries.push({
|
|
30506
|
+
token: tokenLc,
|
|
30507
|
+
decimals: half.decimals,
|
|
30508
|
+
silo: half.silo.toLowerCase(),
|
|
30509
|
+
lenderKey,
|
|
30510
|
+
oracle: ZERO_ADDRESS,
|
|
30511
|
+
partnerToken: partnerLc,
|
|
30512
|
+
isStatic: true
|
|
30513
|
+
});
|
|
30514
|
+
continue;
|
|
30515
|
+
}
|
|
30516
|
+
const oracleLc = half.solvencyOracle.toLowerCase();
|
|
30517
|
+
entries.push({
|
|
30518
|
+
token: tokenLc,
|
|
30519
|
+
decimals: half.decimals,
|
|
30520
|
+
silo: half.silo.toLowerCase(),
|
|
30521
|
+
lenderKey,
|
|
30522
|
+
oracle: oracleLc,
|
|
30523
|
+
partnerToken: partnerLc,
|
|
30524
|
+
isStatic: false
|
|
30525
|
+
});
|
|
30526
|
+
const quoteKey = `${oracleLc}:${tokenLc}`;
|
|
30527
|
+
if (!(quoteKey in callIndexMap)) {
|
|
30528
|
+
callIndexMap[quoteKey] = calls.length;
|
|
30529
|
+
calls.push({
|
|
30530
|
+
address: half.solvencyOracle,
|
|
30531
|
+
name: "quote",
|
|
30532
|
+
params: [BigInt(10) ** BigInt(half.decimals), half.token]
|
|
30533
|
+
});
|
|
30534
|
+
}
|
|
30535
|
+
if (!(oracleLc in quoteTokenIndexMap)) {
|
|
30536
|
+
quoteTokenIndexMap[oracleLc] = calls.length;
|
|
30537
|
+
calls.push({
|
|
30538
|
+
address: half.solvencyOracle,
|
|
30539
|
+
name: "quoteToken",
|
|
30540
|
+
params: []
|
|
30541
|
+
});
|
|
30542
|
+
}
|
|
30543
|
+
}
|
|
30544
|
+
}
|
|
30545
|
+
if (entries.length === 0) return [];
|
|
30546
|
+
return [
|
|
30547
|
+
{
|
|
30548
|
+
calls,
|
|
30549
|
+
meta: { entries, callIndexMap, quoteTokenIndexMap },
|
|
30550
|
+
lender: "SILO_V2"
|
|
30551
|
+
}
|
|
30552
|
+
];
|
|
30553
|
+
}
|
|
30554
|
+
function parseSiloV2Results(data, meta, context) {
|
|
30555
|
+
const entries = [];
|
|
30556
|
+
const seen = /* @__PURE__ */ new Set();
|
|
30557
|
+
for (const entry of meta.entries) {
|
|
30558
|
+
const dedupKey = `${entry.lenderKey}:${entry.token}`;
|
|
30559
|
+
if (seen.has(dedupKey)) continue;
|
|
30560
|
+
try {
|
|
30561
|
+
let priceUSD = 0;
|
|
30562
|
+
let rawPrice = 1;
|
|
30563
|
+
if (entry.isStatic) {
|
|
30564
|
+
const ownUSD = lookupUSD(context, entry.token);
|
|
30565
|
+
const partnerUSD = lookupUSD(context, entry.partnerToken);
|
|
30566
|
+
priceUSD = ownUSD || partnerUSD;
|
|
30567
|
+
if (!priceUSD) continue;
|
|
30568
|
+
rawPrice = 1;
|
|
30569
|
+
} else {
|
|
30570
|
+
const quoteCallIdx = meta.callIndexMap[`${entry.oracle}:${entry.token}`];
|
|
30571
|
+
if (quoteCallIdx === void 0) continue;
|
|
30572
|
+
const rawQuote = data[quoteCallIdx];
|
|
30573
|
+
if (!rawQuote || rawQuote === "0x") continue;
|
|
30574
|
+
const quoteAmount = BigInt(rawQuote.toString());
|
|
30575
|
+
if (quoteAmount === 0n) continue;
|
|
30576
|
+
const qtIdx = meta.quoteTokenIndexMap[entry.oracle];
|
|
30577
|
+
if (qtIdx === void 0) continue;
|
|
30578
|
+
const rawQt = data[qtIdx];
|
|
30579
|
+
if (!rawQt || rawQt === "0x") continue;
|
|
30580
|
+
const quoteTokenAddr = rawQt.toLowerCase();
|
|
30581
|
+
const qtMeta = context.tokenList?.[quoteTokenAddr];
|
|
30582
|
+
const qtDecimals = qtMeta?.decimals ?? 18;
|
|
30583
|
+
const priceInQt = Number(quoteAmount) / Number(10n ** BigInt(qtDecimals));
|
|
30584
|
+
if (isNaN(priceInQt) || priceInQt === 0) continue;
|
|
30585
|
+
const qtUSD = lookupUSD(context, quoteTokenAddr);
|
|
30586
|
+
if (!qtUSD) continue;
|
|
30587
|
+
rawPrice = priceInQt;
|
|
30588
|
+
priceUSD = priceInQt * qtUSD;
|
|
30589
|
+
}
|
|
30590
|
+
if (isNaN(priceUSD) || priceUSD === 0) continue;
|
|
30591
|
+
entries.push({
|
|
30592
|
+
asset: entry.token,
|
|
30593
|
+
price: rawPrice,
|
|
30594
|
+
priceUSD,
|
|
30595
|
+
marketUid: createMarketUid(
|
|
30596
|
+
context.chainId,
|
|
30597
|
+
entry.lenderKey,
|
|
30598
|
+
entry.silo
|
|
30599
|
+
),
|
|
30600
|
+
targetLender: entry.lenderKey,
|
|
30601
|
+
...entry.isStatic ? { staticBase: true, baseAsset: entry.token } : {}
|
|
30602
|
+
});
|
|
30603
|
+
seen.add(dedupKey);
|
|
30604
|
+
} catch {
|
|
30605
|
+
}
|
|
30606
|
+
}
|
|
30607
|
+
return entries;
|
|
30608
|
+
}
|
|
30609
|
+
function getSiloV2Abi() {
|
|
30610
|
+
return SiloOracleAbi;
|
|
30611
|
+
}
|
|
30612
|
+
var siloV2Fetcher = {
|
|
30613
|
+
getCalls: getSiloV2Calls,
|
|
30614
|
+
parse: parseSiloV2Results,
|
|
30615
|
+
getAbi: getSiloV2Abi
|
|
30616
|
+
};
|
|
30617
|
+
|
|
30618
|
+
// src/prices/oracle-prices/fetchers/siloV3.ts
|
|
30619
|
+
var SiloOracleAbi2 = [
|
|
30620
|
+
{
|
|
30621
|
+
inputs: [
|
|
30622
|
+
{ name: "_baseAmount", type: "uint256" },
|
|
30623
|
+
{ name: "_baseToken", type: "address" }
|
|
30624
|
+
],
|
|
30625
|
+
name: "quote",
|
|
30626
|
+
outputs: [{ name: "quoteAmount", type: "uint256" }],
|
|
30627
|
+
stateMutability: "view",
|
|
30628
|
+
type: "function"
|
|
30629
|
+
},
|
|
30630
|
+
{
|
|
30631
|
+
inputs: [],
|
|
30632
|
+
name: "quoteToken",
|
|
30633
|
+
outputs: [{ name: "", type: "address" }],
|
|
30634
|
+
stateMutability: "view",
|
|
30635
|
+
type: "function"
|
|
30636
|
+
}
|
|
30637
|
+
];
|
|
30638
|
+
var ZERO_ADDRESS2 = "0x0000000000000000000000000000000000000000";
|
|
30639
|
+
function lookupUSD2(context, asset) {
|
|
30640
|
+
const lc = asset.toLowerCase();
|
|
30641
|
+
const groupKey = context.tokenList?.[lc]?.assetGroup ?? `${context.chainId}-${lc}`;
|
|
30642
|
+
return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
|
|
30643
|
+
}
|
|
30644
|
+
function getSiloV3Calls(chainId) {
|
|
30645
|
+
const allMarkets = siloMarketsV3()?.[chainId];
|
|
30646
|
+
if (!allMarkets || allMarkets.length === 0) return [];
|
|
30647
|
+
const tokensWithRealOracle = /* @__PURE__ */ new Set();
|
|
30648
|
+
for (const market of allMarkets) {
|
|
30649
|
+
for (const half of [market.silo0, market.silo1]) {
|
|
30650
|
+
if (half.solvencyOracle && half.solvencyOracle !== ZERO_ADDRESS2) {
|
|
30651
|
+
tokensWithRealOracle.add(half.token.toLowerCase());
|
|
30652
|
+
}
|
|
30653
|
+
}
|
|
30654
|
+
}
|
|
30655
|
+
const calls = [];
|
|
30656
|
+
const callIndexMap = {};
|
|
30657
|
+
const quoteTokenIndexMap = {};
|
|
30658
|
+
const entries = [];
|
|
30659
|
+
for (const market of allMarkets) {
|
|
30660
|
+
const lenderKey = siloV3LenderKey(market.siloConfig);
|
|
30661
|
+
const halves = [market.silo0, market.silo1];
|
|
30662
|
+
const isStatic = halves.map(
|
|
30663
|
+
(h) => !h.solvencyOracle || h.solvencyOracle === ZERO_ADDRESS2
|
|
30664
|
+
);
|
|
30665
|
+
if (isStatic[0] && isStatic[1]) {
|
|
30666
|
+
const t0 = halves[0].token.toLowerCase();
|
|
30667
|
+
const t1 = halves[1].token.toLowerCase();
|
|
30668
|
+
if (!tokensWithRealOracle.has(t0) && !tokensWithRealOracle.has(t1)) {
|
|
30669
|
+
continue;
|
|
30670
|
+
}
|
|
30671
|
+
}
|
|
30672
|
+
for (let i = 0; i < 2; i++) {
|
|
30673
|
+
const half = halves[i];
|
|
30674
|
+
const partner = halves[1 - i];
|
|
30675
|
+
const tokenLc = half.token.toLowerCase();
|
|
30676
|
+
const partnerLc = partner.token.toLowerCase();
|
|
30677
|
+
if (isStatic[i]) {
|
|
30678
|
+
entries.push({
|
|
30679
|
+
token: tokenLc,
|
|
30680
|
+
decimals: half.decimals,
|
|
30681
|
+
silo: half.silo.toLowerCase(),
|
|
30682
|
+
lenderKey,
|
|
30683
|
+
oracle: ZERO_ADDRESS2,
|
|
30684
|
+
partnerToken: partnerLc,
|
|
30685
|
+
isStatic: true
|
|
30686
|
+
});
|
|
30687
|
+
continue;
|
|
30688
|
+
}
|
|
30689
|
+
const oracleLc = half.solvencyOracle.toLowerCase();
|
|
30690
|
+
entries.push({
|
|
30691
|
+
token: tokenLc,
|
|
30692
|
+
decimals: half.decimals,
|
|
30693
|
+
silo: half.silo.toLowerCase(),
|
|
30694
|
+
lenderKey,
|
|
30695
|
+
oracle: oracleLc,
|
|
30696
|
+
partnerToken: partnerLc,
|
|
30697
|
+
isStatic: false
|
|
30698
|
+
});
|
|
30699
|
+
const quoteKey = `${oracleLc}:${tokenLc}`;
|
|
30700
|
+
if (!(quoteKey in callIndexMap)) {
|
|
30701
|
+
callIndexMap[quoteKey] = calls.length;
|
|
30702
|
+
calls.push({
|
|
30703
|
+
address: half.solvencyOracle,
|
|
30704
|
+
name: "quote",
|
|
30705
|
+
params: [BigInt(10) ** BigInt(half.decimals), half.token]
|
|
30706
|
+
});
|
|
30707
|
+
}
|
|
30708
|
+
if (!(oracleLc in quoteTokenIndexMap)) {
|
|
30709
|
+
quoteTokenIndexMap[oracleLc] = calls.length;
|
|
30710
|
+
calls.push({
|
|
30711
|
+
address: half.solvencyOracle,
|
|
30712
|
+
name: "quoteToken",
|
|
30713
|
+
params: []
|
|
30714
|
+
});
|
|
30715
|
+
}
|
|
30716
|
+
}
|
|
30717
|
+
}
|
|
30718
|
+
if (entries.length === 0) return [];
|
|
30719
|
+
return [
|
|
30720
|
+
{
|
|
30721
|
+
calls,
|
|
30722
|
+
meta: { entries, callIndexMap, quoteTokenIndexMap },
|
|
30723
|
+
lender: "SILO_V3"
|
|
30724
|
+
}
|
|
30725
|
+
];
|
|
30726
|
+
}
|
|
30727
|
+
function parseSiloV3Results(data, meta, context) {
|
|
30728
|
+
const entries = [];
|
|
30729
|
+
const seen = /* @__PURE__ */ new Set();
|
|
30730
|
+
for (const entry of meta.entries) {
|
|
30731
|
+
const dedupKey = `${entry.lenderKey}:${entry.token}`;
|
|
30732
|
+
if (seen.has(dedupKey)) continue;
|
|
30733
|
+
try {
|
|
30734
|
+
let priceUSD = 0;
|
|
30735
|
+
let rawPrice = 1;
|
|
30736
|
+
if (entry.isStatic) {
|
|
30737
|
+
const ownUSD = lookupUSD2(context, entry.token);
|
|
30738
|
+
const partnerUSD = lookupUSD2(context, entry.partnerToken);
|
|
30739
|
+
priceUSD = ownUSD || partnerUSD;
|
|
30740
|
+
if (!priceUSD) continue;
|
|
30741
|
+
rawPrice = 1;
|
|
30742
|
+
} else {
|
|
30743
|
+
const quoteCallIdx = meta.callIndexMap[`${entry.oracle}:${entry.token}`];
|
|
30744
|
+
if (quoteCallIdx === void 0) continue;
|
|
30745
|
+
const rawQuote = data[quoteCallIdx];
|
|
30746
|
+
if (!rawQuote || rawQuote === "0x") continue;
|
|
30747
|
+
const quoteAmount = BigInt(rawQuote.toString());
|
|
30748
|
+
if (quoteAmount === 0n) continue;
|
|
30749
|
+
const qtIdx = meta.quoteTokenIndexMap[entry.oracle];
|
|
30750
|
+
if (qtIdx === void 0) continue;
|
|
30751
|
+
const rawQt = data[qtIdx];
|
|
30752
|
+
if (!rawQt || rawQt === "0x") continue;
|
|
30753
|
+
const quoteTokenAddr = rawQt.toLowerCase();
|
|
30754
|
+
const qtMeta = context.tokenList?.[quoteTokenAddr];
|
|
30755
|
+
const qtDecimals = qtMeta?.decimals ?? 18;
|
|
30756
|
+
const priceInQt = Number(quoteAmount) / Number(10n ** BigInt(qtDecimals));
|
|
30757
|
+
if (isNaN(priceInQt) || priceInQt === 0) continue;
|
|
30758
|
+
const qtUSD = lookupUSD2(context, quoteTokenAddr);
|
|
30759
|
+
if (!qtUSD) continue;
|
|
30760
|
+
rawPrice = priceInQt;
|
|
30761
|
+
priceUSD = priceInQt * qtUSD;
|
|
30762
|
+
}
|
|
30763
|
+
if (isNaN(priceUSD) || priceUSD === 0) continue;
|
|
30764
|
+
entries.push({
|
|
30765
|
+
asset: entry.token,
|
|
30766
|
+
price: rawPrice,
|
|
30767
|
+
priceUSD,
|
|
30768
|
+
marketUid: createMarketUid(
|
|
30769
|
+
context.chainId,
|
|
30770
|
+
entry.lenderKey,
|
|
30771
|
+
entry.silo
|
|
30772
|
+
),
|
|
30773
|
+
targetLender: entry.lenderKey,
|
|
30774
|
+
...entry.isStatic ? { staticBase: true, baseAsset: entry.token } : {}
|
|
30775
|
+
});
|
|
30776
|
+
seen.add(dedupKey);
|
|
30777
|
+
} catch {
|
|
30778
|
+
}
|
|
30779
|
+
}
|
|
30780
|
+
return entries;
|
|
30781
|
+
}
|
|
30782
|
+
function getSiloV3Abi() {
|
|
30783
|
+
return SiloOracleAbi2;
|
|
30784
|
+
}
|
|
30785
|
+
var siloV3Fetcher = {
|
|
30786
|
+
getCalls: getSiloV3Calls,
|
|
30787
|
+
parse: parseSiloV3Results,
|
|
30788
|
+
getAbi: getSiloV3Abi
|
|
30789
|
+
};
|
|
30790
|
+
|
|
30791
|
+
// src/prices/oracle-prices/fetchers/siloV2Graphql.ts
|
|
30792
|
+
async function fetchSiloV2GraphQLMarkets(chainId) {
|
|
30793
|
+
if (!SILO_API_SUPPORTED_CHAIN_IDS.has(chainId)) return null;
|
|
30794
|
+
try {
|
|
30795
|
+
const items = await fetchSiloMarkets(chainId, { protocolVersion: "v2" });
|
|
30796
|
+
return items;
|
|
30797
|
+
} catch (e) {
|
|
30798
|
+
console.warn(
|
|
30799
|
+
`[prices] Silo v2 GraphQL fetch failed on chain ${chainId}:`,
|
|
30800
|
+
e?.message ?? e
|
|
30801
|
+
);
|
|
30802
|
+
return null;
|
|
30803
|
+
}
|
|
30804
|
+
}
|
|
30805
|
+
function safeNumber3(v) {
|
|
30806
|
+
if (v == null) return 0;
|
|
30807
|
+
const n = typeof v === "number" ? v : Number(v);
|
|
30808
|
+
return Number.isFinite(n) ? n : 0;
|
|
30809
|
+
}
|
|
30810
|
+
function lookupUSD3(context, asset) {
|
|
30811
|
+
const lc = asset.toLowerCase();
|
|
30812
|
+
const groupKey = context.tokenList?.[lc]?.assetGroup ?? `${context.chainId}-${lc}`;
|
|
30813
|
+
return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
|
|
30814
|
+
}
|
|
30815
|
+
function parseSiloV2GraphQLResults(items, context) {
|
|
30816
|
+
const ZERO_ADDRESS3 = "0x0000000000000000000000000000000000000000";
|
|
30817
|
+
const out = [];
|
|
30818
|
+
const seen = /* @__PURE__ */ new Set();
|
|
30819
|
+
for (const item of items) {
|
|
30820
|
+
let lenderKey;
|
|
30821
|
+
try {
|
|
30822
|
+
lenderKey = siloV2LenderKey(item.configAddress);
|
|
30823
|
+
} catch {
|
|
30824
|
+
continue;
|
|
30825
|
+
}
|
|
30826
|
+
const registryEntry = getSiloV2MarketEntry(context.chainId, lenderKey);
|
|
30827
|
+
if (!registryEntry) continue;
|
|
30828
|
+
const [apiSide0, apiSide1] = item.market1.index === 0 ? [item.market1, item.market2] : [item.market2, item.market1];
|
|
30829
|
+
const sideTuples = [
|
|
30830
|
+
{ api: apiSide0, self: registryEntry.silo0, other: registryEntry.silo1 },
|
|
30831
|
+
{ api: apiSide1, self: registryEntry.silo1, other: registryEntry.silo0 }
|
|
30832
|
+
];
|
|
30833
|
+
for (const { api: side, self, other } of sideTuples) {
|
|
30834
|
+
const tokenLc = (side.inputTokenId ?? side.inputToken?.id ?? self.token).toLowerCase();
|
|
30835
|
+
if (!tokenLc) continue;
|
|
30836
|
+
const partnerTokenLc = other.token.toLowerCase();
|
|
30837
|
+
const dedupKey = `${lenderKey}:${tokenLc}`;
|
|
30838
|
+
if (seen.has(dedupKey)) continue;
|
|
30839
|
+
const oracleAddr = (side.solvencyOracleAddress ?? side.solvencyOracle?.id ?? self.solvencyOracle ?? ZERO_ADDRESS3).toLowerCase();
|
|
30840
|
+
const isStatic = !oracleAddr || oracleAddr === ZERO_ADDRESS3;
|
|
30841
|
+
const siloAddrLc = self.silo.toLowerCase();
|
|
30842
|
+
try {
|
|
30843
|
+
let priceUSD = 0;
|
|
30844
|
+
let rawPrice = 1;
|
|
30845
|
+
const supplyNum = safeNumber3(side.supply);
|
|
30846
|
+
const supplyUsdNum = side.supplyUsd != null ? Number(side.supplyUsd) : 0;
|
|
30847
|
+
const borrowedNum = safeNumber3(side.borrowed);
|
|
30848
|
+
const borrowedUsdNum = side.borrowedUsd != null ? Number(side.borrowedUsd) : 0;
|
|
30849
|
+
if (supplyNum > 0 && supplyUsdNum > 0) {
|
|
30850
|
+
priceUSD = supplyUsdNum / supplyNum;
|
|
30851
|
+
rawPrice = isStatic ? 1 : priceUSD;
|
|
30852
|
+
} else if (borrowedNum > 0 && borrowedUsdNum > 0) {
|
|
30853
|
+
priceUSD = borrowedUsdNum / borrowedNum;
|
|
30854
|
+
rawPrice = isStatic ? 1 : priceUSD;
|
|
30855
|
+
} else if (isStatic) {
|
|
30856
|
+
const ownUSD = lookupUSD3(context, tokenLc);
|
|
30857
|
+
const partnerUSD = partnerTokenLc ? lookupUSD3(context, partnerTokenLc) : 0;
|
|
30858
|
+
priceUSD = ownUSD || partnerUSD;
|
|
30859
|
+
if (!priceUSD) continue;
|
|
30860
|
+
rawPrice = 1;
|
|
30861
|
+
} else {
|
|
30862
|
+
const quoteStr = side.solvencyOracle?.quote;
|
|
30863
|
+
if (!quoteStr) continue;
|
|
30864
|
+
const quoteNum = Number(quoteStr);
|
|
30865
|
+
if (!Number.isFinite(quoteNum) || quoteNum === 0) continue;
|
|
30866
|
+
const quoteTokenLc = (side.solvencyOracle?.quoteTokenId ?? "").toLowerCase();
|
|
30867
|
+
if (!quoteTokenLc) continue;
|
|
30868
|
+
const qtUSD = lookupUSD3(context, quoteTokenLc);
|
|
30869
|
+
if (!qtUSD) continue;
|
|
30870
|
+
rawPrice = quoteNum;
|
|
30871
|
+
priceUSD = quoteNum * qtUSD;
|
|
30872
|
+
}
|
|
30873
|
+
if (!Number.isFinite(priceUSD) || priceUSD === 0) continue;
|
|
30874
|
+
out.push({
|
|
30875
|
+
asset: tokenLc,
|
|
30876
|
+
price: rawPrice,
|
|
30877
|
+
priceUSD,
|
|
30878
|
+
marketUid: createMarketUid(context.chainId, lenderKey, siloAddrLc),
|
|
30879
|
+
targetLender: lenderKey,
|
|
30880
|
+
...isStatic ? { staticBase: true, baseAsset: tokenLc } : {}
|
|
30881
|
+
});
|
|
30882
|
+
seen.add(dedupKey);
|
|
30883
|
+
} catch {
|
|
30884
|
+
}
|
|
30885
|
+
}
|
|
30886
|
+
}
|
|
30887
|
+
return out;
|
|
30888
|
+
}
|
|
30889
|
+
|
|
30890
|
+
// src/prices/oracle-prices/fetchers/siloV3Graphql.ts
|
|
30891
|
+
async function fetchSiloV3GraphQLMarkets(chainId) {
|
|
30892
|
+
if (!SILO_API_SUPPORTED_CHAIN_IDS.has(chainId)) return null;
|
|
30893
|
+
try {
|
|
30894
|
+
const items = await fetchSiloMarkets(chainId, { protocolVersion: "v3" });
|
|
30895
|
+
return items;
|
|
30896
|
+
} catch (e) {
|
|
30897
|
+
console.warn(
|
|
30898
|
+
`[prices] Silo v3 GraphQL fetch failed on chain ${chainId}:`,
|
|
30899
|
+
e?.message ?? e
|
|
30900
|
+
);
|
|
30901
|
+
return null;
|
|
30902
|
+
}
|
|
30903
|
+
}
|
|
30904
|
+
function safeNumber4(v) {
|
|
30905
|
+
if (v == null) return 0;
|
|
30906
|
+
const n = typeof v === "number" ? v : Number(v);
|
|
30907
|
+
return Number.isFinite(n) ? n : 0;
|
|
30908
|
+
}
|
|
30909
|
+
function lookupUSD4(context, asset) {
|
|
30910
|
+
const lc = asset.toLowerCase();
|
|
30911
|
+
const groupKey = context.tokenList?.[lc]?.assetGroup ?? `${context.chainId}-${lc}`;
|
|
30912
|
+
return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
|
|
30913
|
+
}
|
|
30914
|
+
function parseSiloV3GraphQLResults(items, context) {
|
|
30915
|
+
const ZERO_ADDRESS3 = "0x0000000000000000000000000000000000000000";
|
|
30916
|
+
const out = [];
|
|
30917
|
+
const seen = /* @__PURE__ */ new Set();
|
|
30918
|
+
for (const item of items) {
|
|
30919
|
+
let lenderKey;
|
|
30920
|
+
try {
|
|
30921
|
+
lenderKey = siloV3LenderKey(item.configAddress);
|
|
30922
|
+
} catch {
|
|
30923
|
+
continue;
|
|
30924
|
+
}
|
|
30925
|
+
const registryEntry = getSiloV3MarketEntry(context.chainId, lenderKey);
|
|
30926
|
+
if (!registryEntry) continue;
|
|
30927
|
+
const [apiSide0, apiSide1] = item.market1.index === 0 ? [item.market1, item.market2] : [item.market2, item.market1];
|
|
30928
|
+
const sideTuples = [
|
|
30929
|
+
{ api: apiSide0, self: registryEntry.silo0, other: registryEntry.silo1 },
|
|
30930
|
+
{ api: apiSide1, self: registryEntry.silo1, other: registryEntry.silo0 }
|
|
30931
|
+
];
|
|
30932
|
+
for (const { api: side, self, other } of sideTuples) {
|
|
30933
|
+
const tokenLc = (side.inputTokenId ?? side.inputToken?.id ?? self.token).toLowerCase();
|
|
30934
|
+
if (!tokenLc) continue;
|
|
30935
|
+
const partnerTokenLc = other.token.toLowerCase();
|
|
30936
|
+
const dedupKey = `${lenderKey}:${tokenLc}`;
|
|
30937
|
+
if (seen.has(dedupKey)) continue;
|
|
30938
|
+
const oracleAddr = (side.solvencyOracleAddress ?? side.solvencyOracle?.id ?? self.solvencyOracle ?? ZERO_ADDRESS3).toLowerCase();
|
|
30939
|
+
const isStatic = !oracleAddr || oracleAddr === ZERO_ADDRESS3;
|
|
30940
|
+
const siloAddrLc = self.silo.toLowerCase();
|
|
30941
|
+
try {
|
|
30942
|
+
let priceUSD = 0;
|
|
30943
|
+
let rawPrice = 1;
|
|
30944
|
+
const supplyNum = safeNumber4(side.supply);
|
|
30945
|
+
const supplyUsdNum = side.supplyUsd != null ? Number(side.supplyUsd) : 0;
|
|
30946
|
+
const borrowedNum = safeNumber4(side.borrowed);
|
|
30947
|
+
const borrowedUsdNum = side.borrowedUsd != null ? Number(side.borrowedUsd) : 0;
|
|
30948
|
+
if (supplyNum > 0 && supplyUsdNum > 0) {
|
|
30949
|
+
priceUSD = supplyUsdNum / supplyNum;
|
|
30950
|
+
rawPrice = isStatic ? 1 : priceUSD;
|
|
30951
|
+
} else if (borrowedNum > 0 && borrowedUsdNum > 0) {
|
|
30952
|
+
priceUSD = borrowedUsdNum / borrowedNum;
|
|
30953
|
+
rawPrice = isStatic ? 1 : priceUSD;
|
|
30954
|
+
} else if (isStatic) {
|
|
30955
|
+
const ownUSD = lookupUSD4(context, tokenLc);
|
|
30956
|
+
const partnerUSD = partnerTokenLc ? lookupUSD4(context, partnerTokenLc) : 0;
|
|
30957
|
+
priceUSD = ownUSD || partnerUSD;
|
|
30958
|
+
if (!priceUSD) continue;
|
|
30959
|
+
rawPrice = 1;
|
|
30960
|
+
} else {
|
|
30961
|
+
const quoteStr = side.solvencyOracle?.quote;
|
|
30962
|
+
if (!quoteStr) continue;
|
|
30963
|
+
const quoteNum = Number(quoteStr);
|
|
30964
|
+
if (!Number.isFinite(quoteNum) || quoteNum === 0) continue;
|
|
30965
|
+
const quoteTokenLc = (side.solvencyOracle?.quoteTokenId ?? "").toLowerCase();
|
|
30966
|
+
if (!quoteTokenLc) continue;
|
|
30967
|
+
const qtUSD = lookupUSD4(context, quoteTokenLc);
|
|
30968
|
+
if (!qtUSD) continue;
|
|
30969
|
+
rawPrice = quoteNum;
|
|
30970
|
+
priceUSD = quoteNum * qtUSD;
|
|
30971
|
+
}
|
|
30972
|
+
if (!Number.isFinite(priceUSD) || priceUSD === 0) continue;
|
|
30973
|
+
out.push({
|
|
30974
|
+
asset: tokenLc,
|
|
30975
|
+
price: rawPrice,
|
|
30976
|
+
priceUSD,
|
|
30977
|
+
marketUid: createMarketUid(context.chainId, lenderKey, siloAddrLc),
|
|
30978
|
+
targetLender: lenderKey,
|
|
30979
|
+
...isStatic ? { staticBase: true, baseAsset: tokenLc } : {}
|
|
30980
|
+
});
|
|
30981
|
+
seen.add(dedupKey);
|
|
30982
|
+
} catch {
|
|
30983
|
+
}
|
|
30984
|
+
}
|
|
30985
|
+
}
|
|
30986
|
+
return out;
|
|
30987
|
+
}
|
|
30988
|
+
|
|
29336
30989
|
// src/prices/oracle-prices/fetchOraclePrices.ts
|
|
29337
30990
|
function countFailures(data, offset, count) {
|
|
29338
30991
|
let failures = 0;
|
|
@@ -29483,6 +31136,16 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
29483
31136
|
}),
|
|
29484
31137
|
getCallsErrors
|
|
29485
31138
|
) : [];
|
|
31139
|
+
const siloV2Results = isActive("silov2") ? safeGetCalls(
|
|
31140
|
+
"siloV2",
|
|
31141
|
+
() => siloV2Fetcher.getCalls(chainId),
|
|
31142
|
+
getCallsErrors
|
|
31143
|
+
) : [];
|
|
31144
|
+
const siloV3Results = isActive("silov3") ? safeGetCalls(
|
|
31145
|
+
"siloV3",
|
|
31146
|
+
() => siloV3Fetcher.getCalls(chainId),
|
|
31147
|
+
getCallsErrors
|
|
31148
|
+
) : [];
|
|
29486
31149
|
const aaveGroup = buildGroup(
|
|
29487
31150
|
"aave",
|
|
29488
31151
|
aaveResults,
|
|
@@ -29525,6 +31188,18 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
29525
31188
|
morphoFetcher.parse,
|
|
29526
31189
|
ProxyOracleAbi
|
|
29527
31190
|
);
|
|
31191
|
+
const siloV2Group = buildGroup(
|
|
31192
|
+
"siloV2",
|
|
31193
|
+
siloV2Results,
|
|
31194
|
+
siloV2Fetcher.parse,
|
|
31195
|
+
getSiloV2Abi()
|
|
31196
|
+
);
|
|
31197
|
+
const siloV3Group = buildGroup(
|
|
31198
|
+
"siloV3",
|
|
31199
|
+
siloV3Results,
|
|
31200
|
+
siloV3Fetcher.parse,
|
|
31201
|
+
getSiloV3Abi()
|
|
31202
|
+
);
|
|
29528
31203
|
const allGroups = [
|
|
29529
31204
|
aaveGroup,
|
|
29530
31205
|
compoundV2Group,
|
|
@@ -29532,7 +31207,9 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
29532
31207
|
listaGroup,
|
|
29533
31208
|
eulerGroup,
|
|
29534
31209
|
aaveV4Group,
|
|
29535
|
-
morphoGroup
|
|
31210
|
+
morphoGroup,
|
|
31211
|
+
siloV2Group,
|
|
31212
|
+
siloV3Group
|
|
29536
31213
|
];
|
|
29537
31214
|
const totalCalls = allGroups.reduce((s, g) => s + g.calls.length, 0);
|
|
29538
31215
|
if (totalCalls === 0 && !isActive("morpho")) {
|
|
@@ -29551,6 +31228,8 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
29551
31228
|
}
|
|
29552
31229
|
const chainBatchSize = batchSize?.[chainId];
|
|
29553
31230
|
const morphoGqlPromise = isActive("morpho") ? fetchMorphoGraphQLPrices(chainId) : Promise.resolve(null);
|
|
31231
|
+
const siloV2GqlPromise = fetchSiloV2GraphQLMarkets(chainId);
|
|
31232
|
+
const siloV3GqlPromise = fetchSiloV3GraphQLMarkets(chainId);
|
|
29554
31233
|
const [
|
|
29555
31234
|
aaveData,
|
|
29556
31235
|
compoundV2Data,
|
|
@@ -29558,7 +31237,9 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
29558
31237
|
listaData,
|
|
29559
31238
|
eulerData,
|
|
29560
31239
|
aaveV4Data,
|
|
29561
|
-
morphoGqlEntries
|
|
31240
|
+
morphoGqlEntries,
|
|
31241
|
+
siloV2GqlItems,
|
|
31242
|
+
siloV3GqlItems
|
|
29562
31243
|
] = await Promise.all([
|
|
29563
31244
|
executeGroup(
|
|
29564
31245
|
aaveGroup,
|
|
@@ -29608,10 +31289,40 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
29608
31289
|
allowFailure,
|
|
29609
31290
|
rpcOverrides
|
|
29610
31291
|
),
|
|
29611
|
-
morphoGqlPromise
|
|
31292
|
+
morphoGqlPromise,
|
|
31293
|
+
siloV2GqlPromise,
|
|
31294
|
+
siloV3GqlPromise
|
|
29612
31295
|
]);
|
|
31296
|
+
if (siloV2GqlItems == null && siloV2Group.calls.length > 0) {
|
|
31297
|
+
console.warn(
|
|
31298
|
+
`[prices] chain ${chainId}: Silo v2 GraphQL unavailable, falling back to on-chain (${siloV2Group.trackers.length} trackers)`
|
|
31299
|
+
);
|
|
31300
|
+
}
|
|
31301
|
+
const siloV2Data = siloV2GqlItems != null ? { results: [], error: void 0 } : await executeGroup(
|
|
31302
|
+
siloV2Group,
|
|
31303
|
+
chainId,
|
|
31304
|
+
chainBatchSize,
|
|
31305
|
+
retries,
|
|
31306
|
+
allowFailure,
|
|
31307
|
+
rpcOverrides
|
|
31308
|
+
);
|
|
31309
|
+
if (siloV3GqlItems == null && siloV3Group.calls.length > 0) {
|
|
31310
|
+
console.warn(
|
|
31311
|
+
`[prices] chain ${chainId}: Silo v3 GraphQL unavailable, falling back to on-chain (${siloV3Group.trackers.length} trackers)`
|
|
31312
|
+
);
|
|
31313
|
+
}
|
|
31314
|
+
const siloV3Data = siloV3GqlItems != null ? { results: [], error: void 0 } : await executeGroup(
|
|
31315
|
+
siloV3Group,
|
|
31316
|
+
chainId,
|
|
31317
|
+
chainBatchSize,
|
|
31318
|
+
retries,
|
|
31319
|
+
allowFailure,
|
|
31320
|
+
rpcOverrides
|
|
31321
|
+
);
|
|
29613
31322
|
if (morphoGqlEntries == null && isActive("morpho")) {
|
|
29614
|
-
console.warn(
|
|
31323
|
+
console.warn(
|
|
31324
|
+
`[prices] chain ${chainId}: Morpho GraphQL returned null, falling back to on-chain (${morphoGroup.trackers.length} trackers)`
|
|
31325
|
+
);
|
|
29615
31326
|
}
|
|
29616
31327
|
const morphoData = morphoGqlEntries != null ? { results: [], error: void 0 } : await executeGroup(
|
|
29617
31328
|
morphoGroup,
|
|
@@ -29629,6 +31340,8 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
29629
31340
|
{ group: listaGroup, data: listaData },
|
|
29630
31341
|
{ group: eulerGroup, data: eulerData },
|
|
29631
31342
|
{ group: aaveV4Group, data: aaveV4Data },
|
|
31343
|
+
...siloV2GqlItems != null ? [] : [{ group: siloV2Group, data: siloV2Data }],
|
|
31344
|
+
...siloV3GqlItems != null ? [] : [{ group: siloV3Group, data: siloV3Data }],
|
|
29632
31345
|
...useMorphoGql ? [] : [{ group: morphoGroup, data: morphoData }]
|
|
29633
31346
|
];
|
|
29634
31347
|
for (const { group, data } of groupResults) {
|
|
@@ -29713,6 +31426,48 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
29713
31426
|
true,
|
|
29714
31427
|
(t) => !!t.meta.baseAssetSource
|
|
29715
31428
|
);
|
|
31429
|
+
if (siloV2GqlItems != null) {
|
|
31430
|
+
const context = { chainId, usdPrices, tokenList };
|
|
31431
|
+
const entries = parseSiloV2GraphQLResults(siloV2GqlItems, context);
|
|
31432
|
+
const diag2 = {
|
|
31433
|
+
lender: "SILO_V2 (GraphQL)",
|
|
31434
|
+
callCount: 0,
|
|
31435
|
+
failedCalls: 0,
|
|
31436
|
+
parsedEntries: entries.length
|
|
31437
|
+
};
|
|
31438
|
+
for (const entry of entries) {
|
|
31439
|
+
const lender = entry.targetLender ?? "SILO_V2";
|
|
31440
|
+
if (!chainResult[lender]) chainResult[lender] = [];
|
|
31441
|
+
chainResult[lender].push(entry);
|
|
31442
|
+
const oracleKey = tokenList[entry.asset]?.assetGroup ?? `${chainId}-${entry.asset}`;
|
|
31443
|
+
usdPrices[oracleKey] = entry.priceUSD;
|
|
31444
|
+
usdPrices[entry.asset] = entry.priceUSD;
|
|
31445
|
+
}
|
|
31446
|
+
trackerDiags.push(diag2);
|
|
31447
|
+
} else {
|
|
31448
|
+
parseTrackers(siloV2Group, siloV2Data.results);
|
|
31449
|
+
}
|
|
31450
|
+
if (siloV3GqlItems != null) {
|
|
31451
|
+
const context = { chainId, usdPrices, tokenList };
|
|
31452
|
+
const entries = parseSiloV3GraphQLResults(siloV3GqlItems, context);
|
|
31453
|
+
const diag2 = {
|
|
31454
|
+
lender: "SILO_V3 (GraphQL)",
|
|
31455
|
+
callCount: 0,
|
|
31456
|
+
failedCalls: 0,
|
|
31457
|
+
parsedEntries: entries.length
|
|
31458
|
+
};
|
|
31459
|
+
for (const entry of entries) {
|
|
31460
|
+
const lender = entry.targetLender ?? "SILO_V3";
|
|
31461
|
+
if (!chainResult[lender]) chainResult[lender] = [];
|
|
31462
|
+
chainResult[lender].push(entry);
|
|
31463
|
+
const oracleKey = tokenList[entry.asset]?.assetGroup ?? `${chainId}-${entry.asset}`;
|
|
31464
|
+
usdPrices[oracleKey] = entry.priceUSD;
|
|
31465
|
+
usdPrices[entry.asset] = entry.priceUSD;
|
|
31466
|
+
}
|
|
31467
|
+
trackerDiags.push(diag2);
|
|
31468
|
+
} else {
|
|
31469
|
+
parseTrackers(siloV3Group, siloV3Data.results);
|
|
31470
|
+
}
|
|
29716
31471
|
if (useMorphoGql) {
|
|
29717
31472
|
const morphoGqlDiag = {
|
|
29718
31473
|
lender: "MORPHO_BLUE (GraphQL)",
|
|
@@ -30588,21 +32343,21 @@ function prepareTokenBalanceRpcCalls(chainId, account, tokens, blockTag = "lates
|
|
|
30588
32343
|
encodedCalldata
|
|
30589
32344
|
};
|
|
30590
32345
|
}
|
|
30591
|
-
function parseTokenBalanceResult(rawResult,
|
|
32346
|
+
function parseTokenBalanceResult(rawResult, query3) {
|
|
30592
32347
|
if (!rawResult || rawResult === "0x") {
|
|
30593
32348
|
return {};
|
|
30594
32349
|
}
|
|
30595
32350
|
const parsed = parseBalanceFetcherResult(
|
|
30596
32351
|
rawResult,
|
|
30597
|
-
[
|
|
30598
|
-
|
|
32352
|
+
[query3.account],
|
|
32353
|
+
query3.tokens
|
|
30599
32354
|
);
|
|
30600
32355
|
if (parsed.balances.length === 0) {
|
|
30601
32356
|
return {};
|
|
30602
32357
|
}
|
|
30603
32358
|
const result = {};
|
|
30604
32359
|
const userBalances = parsed.balances[0].balances;
|
|
30605
|
-
for (const token of
|
|
32360
|
+
for (const token of query3.tokens) {
|
|
30606
32361
|
const balanceEntry = userBalances[token];
|
|
30607
32362
|
if (balanceEntry) {
|
|
30608
32363
|
result[token] = {
|