@1delta/margin-fetcher 0.0.226 → 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 +1848 -94
- package/dist/index.js.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 ?? ""),
|
|
@@ -18553,6 +18607,399 @@ var getAaveV4ReservesDataConverter = (lender, chainId, prices, additionalYields,
|
|
|
18553
18607
|
};
|
|
18554
18608
|
return [converter, expectedCalls];
|
|
18555
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
|
|
18556
19003
|
function getMorphoTypeMarketConverter(lender, chainId, prices, additionalYields, tokenList = {}, marketsOverride) {
|
|
18557
19004
|
if (lender.startsWith("LISTA_DAO"))
|
|
18558
19005
|
return getListaMarketDataConverter(
|
|
@@ -18587,6 +19034,8 @@ function buildLenderCall(chainId, lender) {
|
|
|
18587
19034
|
return buildCompoundV2StyleLenderReserveCall(chainId, lender);
|
|
18588
19035
|
if (isEulerType(lender)) return buildEulerV2LenderReserveCall(chainId, lender);
|
|
18589
19036
|
if (isAaveV4Type(lender)) return buildAaveV4LenderReserveCall(chainId, lender);
|
|
19037
|
+
if (isSiloV2Type(lender)) return buildSiloV2LenderReserveCall(chainId, lender);
|
|
19038
|
+
if (isSiloV3Type(lender)) return buildSiloV3LenderReserveCall(chainId, lender);
|
|
18590
19039
|
return [];
|
|
18591
19040
|
}
|
|
18592
19041
|
function getLenderDataConverter(lender, chainId, prices, additionalYields, tokenList = {}) {
|
|
@@ -18655,6 +19104,22 @@ function getLenderDataConverter(lender, chainId, prices, additionalYields, token
|
|
|
18655
19104
|
additionalYields,
|
|
18656
19105
|
tokenList
|
|
18657
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
|
+
);
|
|
18658
19123
|
return [() => null, 0];
|
|
18659
19124
|
}
|
|
18660
19125
|
var getAbi = (lender) => {
|
|
@@ -18675,6 +19140,8 @@ var getAbi = (lender) => {
|
|
|
18675
19140
|
if (isMorphoType(lender)) return MorphoLensAbi;
|
|
18676
19141
|
if (isEulerType(lender)) return vaultLensAbi;
|
|
18677
19142
|
if (isAaveV4Type(lender)) return [...AaveV4SpokeAbi, ...AaveV4OracleAbi, ...AaveV4HubAbi];
|
|
19143
|
+
if (isSiloV2Type(lender)) return [...SiloAbi, ...SiloLensAbi];
|
|
19144
|
+
if (isSiloV3Type(lender)) return [...SiloAbi, ...SiloLensAbi];
|
|
18678
19145
|
if (isSumerType(lender)) return [...SumerLensAbi, ...SumerComptrollerAbi];
|
|
18679
19146
|
if (lender === Lender.TAKARA) return [...TakaraMarketStateAbi];
|
|
18680
19147
|
if (isCompoundV2Type(lender)) return VenusLensAbi;
|
|
@@ -18735,58 +19202,539 @@ var getLenderPublicData = async (chainId, lenders, prices, additionalYields, mul
|
|
|
18735
19202
|
}
|
|
18736
19203
|
return lenderData;
|
|
18737
19204
|
};
|
|
18738
|
-
|
|
18739
|
-
|
|
18740
|
-
|
|
18741
|
-
|
|
18742
|
-
|
|
18743
|
-
|
|
18744
|
-
|
|
18745
|
-
|
|
18746
|
-
|
|
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
|
+
}
|
|
18747
19309
|
}
|
|
18748
|
-
|
|
18749
|
-
|
|
18750
|
-
|
|
18751
|
-
|
|
18752
|
-
|
|
18753
|
-
|
|
18754
|
-
|
|
18755
|
-
|
|
18756
|
-
|
|
18757
|
-
|
|
18758
|
-
|
|
18759
|
-
|
|
18760
|
-
)
|
|
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}`
|
|
18761
19322
|
);
|
|
18762
19323
|
}
|
|
18763
|
-
const
|
|
18764
|
-
|
|
18765
|
-
|
|
18766
|
-
|
|
18767
|
-
console.warn(
|
|
18768
|
-
`[lending] tokenList fetch failed on chain ${chainId}:`,
|
|
18769
|
-
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("; ")}`
|
|
18770
19328
|
);
|
|
18771
19329
|
}
|
|
18772
|
-
const
|
|
18773
|
-
|
|
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;
|
|
18774
19347
|
try {
|
|
18775
|
-
|
|
18776
|
-
|
|
18777
|
-
|
|
18778
|
-
|
|
18779
|
-
|
|
18780
|
-
|
|
18781
|
-
|
|
18782
|
-
|
|
18783
|
-
|
|
18784
|
-
|
|
18785
|
-
|
|
18786
|
-
|
|
18787
|
-
|
|
18788
|
-
|
|
18789
|
-
|
|
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,
|
|
18790
19738
|
prices,
|
|
18791
19739
|
additionalYields,
|
|
18792
19740
|
list
|
|
@@ -18808,7 +19756,7 @@ var getLenderPublicDataViaApi = async (chainId, lenders, prices, additionalYield
|
|
|
18808
19756
|
}
|
|
18809
19757
|
return lenderData;
|
|
18810
19758
|
};
|
|
18811
|
-
function
|
|
19759
|
+
function lenderApiOnly(lender, chainId) {
|
|
18812
19760
|
if (lender === Lender.MORPHO_BLUE) {
|
|
18813
19761
|
if (chainId === Chain.SONEIUM) return false;
|
|
18814
19762
|
if (chainId === Chain.HEMI_NETWORK) return false;
|
|
@@ -18819,9 +19767,17 @@ function lenderCanUseApi(lender, chainId) {
|
|
|
18819
19767
|
}
|
|
18820
19768
|
return false;
|
|
18821
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
|
+
}
|
|
18822
19776
|
var getLenderPublicDataAll = async (chainId, lenders, prices, additionalYields, multicallRetry, tokenList, includeUnlistedMorphoMarkets = false) => {
|
|
18823
|
-
const lendersApi = lenders.filter(
|
|
18824
|
-
|
|
19777
|
+
const lendersApi = lenders.filter(
|
|
19778
|
+
(l) => lenderApiOnly(l, chainId) || lenderApiWithOnChainFallback(l, chainId)
|
|
19779
|
+
);
|
|
19780
|
+
const lendersOnChain = lenders.filter((l) => !lenderApiOnly(l, chainId));
|
|
18825
19781
|
const onChain = getLenderPublicData(
|
|
18826
19782
|
chainId,
|
|
18827
19783
|
lendersOnChain,
|
|
@@ -19134,7 +20090,7 @@ function fetchEulerSubAccountIndexes(chainId, owner) {
|
|
|
19134
20090
|
async function fetchSubAccountsFromSubgraph(chainId, owner) {
|
|
19135
20091
|
const url = EULER_SUBGRAPH_URLS[chainId];
|
|
19136
20092
|
if (!url) return [0];
|
|
19137
|
-
const
|
|
20093
|
+
const query3 = `{
|
|
19138
20094
|
accounts(first: 100, where: { owner: "${owner.toLowerCase()}" }) {
|
|
19139
20095
|
id
|
|
19140
20096
|
subAccount
|
|
@@ -19143,7 +20099,7 @@ async function fetchSubAccountsFromSubgraph(chainId, owner) {
|
|
|
19143
20099
|
const response = await fetch(url, {
|
|
19144
20100
|
method: "POST",
|
|
19145
20101
|
headers: { "Content-Type": "application/json" },
|
|
19146
|
-
body: JSON.stringify({ query:
|
|
20102
|
+
body: JSON.stringify({ query: query3 })
|
|
19147
20103
|
});
|
|
19148
20104
|
if (!response.ok) return [0];
|
|
19149
20105
|
const data = await response.json();
|
|
@@ -19246,6 +20202,55 @@ var buildAaveV4UserCall = (chainId, lender, account) => {
|
|
|
19246
20202
|
return calls;
|
|
19247
20203
|
};
|
|
19248
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
|
+
|
|
19249
20254
|
// src/lending/user-data/fetch-balances/prepare.ts
|
|
19250
20255
|
async function buildUserCall(chainId, lender, account, params) {
|
|
19251
20256
|
if (isAaveV4Type(lender)) return buildAaveV4UserCall(chainId, lender, account);
|
|
@@ -19258,6 +20263,8 @@ async function buildUserCall(chainId, lender, account, params) {
|
|
|
19258
20263
|
return buildCompoundV3UserCall(chainId, lender, account);
|
|
19259
20264
|
if (isEulerType(lender))
|
|
19260
20265
|
return buildEulerUserCall(chainId, lender, account, params?.subAccountIndexes);
|
|
20266
|
+
if (isSiloV2Type(lender))
|
|
20267
|
+
return buildSiloV2UserCall(chainId, lender, account);
|
|
19261
20268
|
return buildCompoundV2UserCall(chainId, lender, account);
|
|
19262
20269
|
}
|
|
19263
20270
|
function organizeUserQueries(queries) {
|
|
@@ -20760,6 +21767,104 @@ function createAaveV4Entry(base, data, key, meta, spokeAddr) {
|
|
|
20760
21767
|
};
|
|
20761
21768
|
}
|
|
20762
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
|
+
|
|
20763
21868
|
// src/lending/user-data/fetch-balances/parse.ts
|
|
20764
21869
|
function getUserDataConverter(lender, chainId, account, params, meta) {
|
|
20765
21870
|
if (isAaveV4Type(lender))
|
|
@@ -20794,6 +21899,8 @@ function getUserDataConverter(lender, chainId, account, params, meta) {
|
|
|
20794
21899
|
);
|
|
20795
21900
|
if (isEulerType(lender))
|
|
20796
21901
|
return getEulerUserDataConverter(lender, chainId, account, meta?.[lender], params?.subAccountIndexes);
|
|
21902
|
+
if (isSiloV2Type(lender))
|
|
21903
|
+
return getSiloV2UserDataConverter(lender, chainId, account, meta?.[lender]);
|
|
20797
21904
|
return getCompoundV2UserDataConverter(
|
|
20798
21905
|
lender,
|
|
20799
21906
|
chainId,
|
|
@@ -20815,19 +21922,19 @@ var convertLenderUserDataResult = (chainId, queriesRaw, rawResults, lenderState)
|
|
|
20815
21922
|
const queries = organizeUserQueries(queriesRaw);
|
|
20816
21923
|
const lenderData = {};
|
|
20817
21924
|
let currentSlice = 0;
|
|
20818
|
-
for (const
|
|
21925
|
+
for (const query3 of queries) {
|
|
20819
21926
|
const [converter, sliceLength] = getUserDataConverter(
|
|
20820
|
-
|
|
21927
|
+
query3.lender,
|
|
20821
21928
|
chainId,
|
|
20822
|
-
|
|
20823
|
-
|
|
21929
|
+
query3.account,
|
|
21930
|
+
query3.params,
|
|
20824
21931
|
lenderState
|
|
20825
21932
|
);
|
|
20826
21933
|
try {
|
|
20827
21934
|
const data = rawResults.slice(currentSlice, currentSlice + sliceLength);
|
|
20828
21935
|
const convertedData = converter(data);
|
|
20829
21936
|
if (convertedData) {
|
|
20830
|
-
if (isMultiMarket(
|
|
21937
|
+
if (isMultiMarket(query3.lender)) {
|
|
20831
21938
|
Object.keys(convertedData).forEach((market) => {
|
|
20832
21939
|
const filtered = filterEmptyUserData(convertedData[market]);
|
|
20833
21940
|
if (filtered) {
|
|
@@ -20838,8 +21945,8 @@ var convertLenderUserDataResult = (chainId, queriesRaw, rawResults, lenderState)
|
|
|
20838
21945
|
} else {
|
|
20839
21946
|
const filtered = filterEmptyUserData(convertedData);
|
|
20840
21947
|
if (filtered) {
|
|
20841
|
-
filtered.lender =
|
|
20842
|
-
lenderData[
|
|
21948
|
+
filtered.lender = query3.lender;
|
|
21949
|
+
lenderData[query3.lender] = filtered;
|
|
20843
21950
|
}
|
|
20844
21951
|
}
|
|
20845
21952
|
}
|
|
@@ -25473,6 +26580,7 @@ var getAbi2 = (lender) => {
|
|
|
25473
26580
|
if (isEulerType(lender)) return accountLensAbi;
|
|
25474
26581
|
if (isCompoundV2Type(lender))
|
|
25475
26582
|
return [...ComptrollerAbi, ...CompoundV2CollateralToken];
|
|
26583
|
+
if (isSiloV2Type(lender)) return [...SiloAbi];
|
|
25476
26584
|
return [];
|
|
25477
26585
|
};
|
|
25478
26586
|
|
|
@@ -25579,15 +26687,15 @@ function unflattenLenderData(pools) {
|
|
|
25579
26687
|
var getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient3, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, retries = 3, logs = false) => {
|
|
25580
26688
|
const queries = organizeUserQueries(queriesRaw);
|
|
25581
26689
|
const builtCalls = await Promise.all(
|
|
25582
|
-
queries.map(async (
|
|
25583
|
-
const abi = getAbi2(
|
|
26690
|
+
queries.map(async (query3) => {
|
|
26691
|
+
const abi = getAbi2(query3.lender);
|
|
25584
26692
|
const callData = await buildUserCall(
|
|
25585
26693
|
chainId,
|
|
25586
|
-
|
|
25587
|
-
|
|
25588
|
-
|
|
26694
|
+
query3.lender,
|
|
26695
|
+
query3.account,
|
|
26696
|
+
query3.params
|
|
25589
26697
|
);
|
|
25590
|
-
return callData.map((call) => ({ call, abi }));
|
|
26698
|
+
return callData.map((call) => ({ call, abi: call.abi ?? abi }));
|
|
25591
26699
|
})
|
|
25592
26700
|
);
|
|
25593
26701
|
const calls = builtCalls.flat();
|
|
@@ -25608,15 +26716,15 @@ var prepareLenderUserDataRpcCalls = async (chainId, queriesRaw, batchSize = MULT
|
|
|
25608
26716
|
const multicallAddress = getEvmChain(chainId).contracts?.multicall3?.address;
|
|
25609
26717
|
const queries = organizeUserQueries(queriesRaw);
|
|
25610
26718
|
const builtCalls = await Promise.all(
|
|
25611
|
-
queries.map(async (
|
|
25612
|
-
const abi = getAbi2(
|
|
26719
|
+
queries.map(async (query3) => {
|
|
26720
|
+
const abi = getAbi2(query3.lender);
|
|
25613
26721
|
const callData = await buildUserCall(
|
|
25614
26722
|
chainId,
|
|
25615
|
-
|
|
25616
|
-
|
|
25617
|
-
|
|
26723
|
+
query3.lender,
|
|
26724
|
+
query3.account,
|
|
26725
|
+
query3.params
|
|
25618
26726
|
);
|
|
25619
|
-
return callData.map((call) => ({ call, abi }));
|
|
26727
|
+
return callData.map((call) => ({ call, abi: call.abi ?? abi }));
|
|
25620
26728
|
})
|
|
25621
26729
|
);
|
|
25622
26730
|
const calls = builtCalls.flat();
|
|
@@ -25725,13 +26833,13 @@ async function prepareMergedRpcCalls(chainId, balanceQueries, permissionParams,
|
|
|
25725
26833
|
);
|
|
25726
26834
|
let balanceCalls = [];
|
|
25727
26835
|
const organizedQueries = organizeUserQueries(balanceQueries);
|
|
25728
|
-
for (const
|
|
25729
|
-
const abi = getAbi2(
|
|
26836
|
+
for (const query3 of organizedQueries) {
|
|
26837
|
+
const abi = getAbi2(query3.lender);
|
|
25730
26838
|
const callData = await buildUserCall(
|
|
25731
26839
|
chainId,
|
|
25732
|
-
|
|
25733
|
-
|
|
25734
|
-
|
|
26840
|
+
query3.lender,
|
|
26841
|
+
query3.account,
|
|
26842
|
+
query3.params
|
|
25735
26843
|
);
|
|
25736
26844
|
const mappedCalls = callData.map((call) => ({ call, abi }));
|
|
25737
26845
|
balanceCalls = [...balanceCalls, ...mappedCalls];
|
|
@@ -25790,13 +26898,13 @@ async function prepareMergedMulticallParams(chainId, balanceQueries, permissionP
|
|
|
25790
26898
|
const permissionAbis = permissionCalls.map(() => permissionResult.abi);
|
|
25791
26899
|
let balanceCalls = [];
|
|
25792
26900
|
const organizedQueries = organizeUserQueries(balanceQueries);
|
|
25793
|
-
for (const
|
|
25794
|
-
const abi = getAbi2(
|
|
26901
|
+
for (const query3 of organizedQueries) {
|
|
26902
|
+
const abi = getAbi2(query3.lender);
|
|
25795
26903
|
const callData = await buildUserCall(
|
|
25796
26904
|
chainId,
|
|
25797
|
-
|
|
25798
|
-
|
|
25799
|
-
|
|
26905
|
+
query3.lender,
|
|
26906
|
+
query3.account,
|
|
26907
|
+
query3.params
|
|
25800
26908
|
);
|
|
25801
26909
|
const mappedCalls = callData.map((call) => ({ call, abi }));
|
|
25802
26910
|
balanceCalls = [...balanceCalls, ...mappedCalls];
|
|
@@ -28593,12 +29701,12 @@ function getMorphoCalls(chainId, context) {
|
|
|
28593
29701
|
const queries = getMorphoMarketsForChain(chainId, context?.marketOverrides);
|
|
28594
29702
|
if (queries.length === 0) return [];
|
|
28595
29703
|
const oracleGroups = /* @__PURE__ */ new Map();
|
|
28596
|
-
for (const
|
|
28597
|
-
const oracleLc =
|
|
29704
|
+
for (const query3 of queries) {
|
|
29705
|
+
const oracleLc = query3.oracle.toLowerCase();
|
|
28598
29706
|
if (!oracleGroups.has(oracleLc)) {
|
|
28599
29707
|
oracleGroups.set(oracleLc, []);
|
|
28600
29708
|
}
|
|
28601
|
-
oracleGroups.get(oracleLc).push(
|
|
29709
|
+
oracleGroups.get(oracleLc).push(query3);
|
|
28602
29710
|
}
|
|
28603
29711
|
return Array.from(oracleGroups.values()).map((markets) => {
|
|
28604
29712
|
const call = {
|
|
@@ -29334,6 +30442,550 @@ var aaveV4Fetcher = {
|
|
|
29334
30442
|
getAbi: getAaveV4Abi
|
|
29335
30443
|
};
|
|
29336
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
|
+
|
|
29337
30989
|
// src/prices/oracle-prices/fetchOraclePrices.ts
|
|
29338
30990
|
function countFailures(data, offset, count) {
|
|
29339
30991
|
let failures = 0;
|
|
@@ -29484,6 +31136,16 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
29484
31136
|
}),
|
|
29485
31137
|
getCallsErrors
|
|
29486
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
|
+
) : [];
|
|
29487
31149
|
const aaveGroup = buildGroup(
|
|
29488
31150
|
"aave",
|
|
29489
31151
|
aaveResults,
|
|
@@ -29526,6 +31188,18 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
29526
31188
|
morphoFetcher.parse,
|
|
29527
31189
|
ProxyOracleAbi
|
|
29528
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
|
+
);
|
|
29529
31203
|
const allGroups = [
|
|
29530
31204
|
aaveGroup,
|
|
29531
31205
|
compoundV2Group,
|
|
@@ -29533,7 +31207,9 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
29533
31207
|
listaGroup,
|
|
29534
31208
|
eulerGroup,
|
|
29535
31209
|
aaveV4Group,
|
|
29536
|
-
morphoGroup
|
|
31210
|
+
morphoGroup,
|
|
31211
|
+
siloV2Group,
|
|
31212
|
+
siloV3Group
|
|
29537
31213
|
];
|
|
29538
31214
|
const totalCalls = allGroups.reduce((s, g) => s + g.calls.length, 0);
|
|
29539
31215
|
if (totalCalls === 0 && !isActive("morpho")) {
|
|
@@ -29552,6 +31228,8 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
29552
31228
|
}
|
|
29553
31229
|
const chainBatchSize = batchSize?.[chainId];
|
|
29554
31230
|
const morphoGqlPromise = isActive("morpho") ? fetchMorphoGraphQLPrices(chainId) : Promise.resolve(null);
|
|
31231
|
+
const siloV2GqlPromise = fetchSiloV2GraphQLMarkets(chainId);
|
|
31232
|
+
const siloV3GqlPromise = fetchSiloV3GraphQLMarkets(chainId);
|
|
29555
31233
|
const [
|
|
29556
31234
|
aaveData,
|
|
29557
31235
|
compoundV2Data,
|
|
@@ -29559,7 +31237,9 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
29559
31237
|
listaData,
|
|
29560
31238
|
eulerData,
|
|
29561
31239
|
aaveV4Data,
|
|
29562
|
-
morphoGqlEntries
|
|
31240
|
+
morphoGqlEntries,
|
|
31241
|
+
siloV2GqlItems,
|
|
31242
|
+
siloV3GqlItems
|
|
29563
31243
|
] = await Promise.all([
|
|
29564
31244
|
executeGroup(
|
|
29565
31245
|
aaveGroup,
|
|
@@ -29609,10 +31289,40 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
29609
31289
|
allowFailure,
|
|
29610
31290
|
rpcOverrides
|
|
29611
31291
|
),
|
|
29612
|
-
morphoGqlPromise
|
|
31292
|
+
morphoGqlPromise,
|
|
31293
|
+
siloV2GqlPromise,
|
|
31294
|
+
siloV3GqlPromise
|
|
29613
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
|
+
);
|
|
29614
31322
|
if (morphoGqlEntries == null && isActive("morpho")) {
|
|
29615
|
-
console.warn(
|
|
31323
|
+
console.warn(
|
|
31324
|
+
`[prices] chain ${chainId}: Morpho GraphQL returned null, falling back to on-chain (${morphoGroup.trackers.length} trackers)`
|
|
31325
|
+
);
|
|
29616
31326
|
}
|
|
29617
31327
|
const morphoData = morphoGqlEntries != null ? { results: [], error: void 0 } : await executeGroup(
|
|
29618
31328
|
morphoGroup,
|
|
@@ -29630,6 +31340,8 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
29630
31340
|
{ group: listaGroup, data: listaData },
|
|
29631
31341
|
{ group: eulerGroup, data: eulerData },
|
|
29632
31342
|
{ group: aaveV4Group, data: aaveV4Data },
|
|
31343
|
+
...siloV2GqlItems != null ? [] : [{ group: siloV2Group, data: siloV2Data }],
|
|
31344
|
+
...siloV3GqlItems != null ? [] : [{ group: siloV3Group, data: siloV3Data }],
|
|
29633
31345
|
...useMorphoGql ? [] : [{ group: morphoGroup, data: morphoData }]
|
|
29634
31346
|
];
|
|
29635
31347
|
for (const { group, data } of groupResults) {
|
|
@@ -29714,6 +31426,48 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
|
|
|
29714
31426
|
true,
|
|
29715
31427
|
(t) => !!t.meta.baseAssetSource
|
|
29716
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
|
+
}
|
|
29717
31471
|
if (useMorphoGql) {
|
|
29718
31472
|
const morphoGqlDiag = {
|
|
29719
31473
|
lender: "MORPHO_BLUE (GraphQL)",
|
|
@@ -30589,21 +32343,21 @@ function prepareTokenBalanceRpcCalls(chainId, account, tokens, blockTag = "lates
|
|
|
30589
32343
|
encodedCalldata
|
|
30590
32344
|
};
|
|
30591
32345
|
}
|
|
30592
|
-
function parseTokenBalanceResult(rawResult,
|
|
32346
|
+
function parseTokenBalanceResult(rawResult, query3) {
|
|
30593
32347
|
if (!rawResult || rawResult === "0x") {
|
|
30594
32348
|
return {};
|
|
30595
32349
|
}
|
|
30596
32350
|
const parsed = parseBalanceFetcherResult(
|
|
30597
32351
|
rawResult,
|
|
30598
|
-
[
|
|
30599
|
-
|
|
32352
|
+
[query3.account],
|
|
32353
|
+
query3.tokens
|
|
30600
32354
|
);
|
|
30601
32355
|
if (parsed.balances.length === 0) {
|
|
30602
32356
|
return {};
|
|
30603
32357
|
}
|
|
30604
32358
|
const result = {};
|
|
30605
32359
|
const userBalances = parsed.balances[0].balances;
|
|
30606
|
-
for (const token of
|
|
32360
|
+
for (const token of query3.tokens) {
|
|
30607
32361
|
const balanceEntry = userBalances[token];
|
|
30608
32362
|
if (balanceEntry) {
|
|
30609
32363
|
result[token] = {
|