@1delta/margin-fetcher 0.0.212 → 0.0.214

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.
Files changed (34) hide show
  1. package/dist/index.js +808 -52
  2. package/dist/index.js.map +1 -1
  3. package/dist/lending/public-data/aave-v4-type/fetcher/normalize.d.ts +96 -0
  4. package/dist/lending/public-data/aave-v4-type/fetcher/normalize.d.ts.map +1 -0
  5. package/dist/lending/public-data/aave-v4-type/fetcher/types.d.ts +85 -0
  6. package/dist/lending/public-data/aave-v4-type/fetcher/types.d.ts.map +1 -0
  7. package/dist/lending/public-data/aave-v4-type/publicCallBuild.d.ts +37 -0
  8. package/dist/lending/public-data/aave-v4-type/publicCallBuild.d.ts.map +1 -0
  9. package/dist/lending/public-data/aave-v4-type/publicCallParse.d.ts +10 -0
  10. package/dist/lending/public-data/aave-v4-type/publicCallParse.d.ts.map +1 -0
  11. package/dist/lending/public-data/fetchLender.d.ts.map +1 -1
  12. package/dist/lending/user-data/aave-v4-type/userCallBuild.d.ts +22 -0
  13. package/dist/lending/user-data/aave-v4-type/userCallBuild.d.ts.map +1 -0
  14. package/dist/lending/user-data/aave-v4-type/userCallParse.d.ts +15 -0
  15. package/dist/lending/user-data/aave-v4-type/userCallParse.d.ts.map +1 -0
  16. package/dist/lending/user-data/abis.d.ts.map +1 -1
  17. package/dist/lending/user-data/fetch-balances/parse.d.ts.map +1 -1
  18. package/dist/lending/user-data/fetch-balances/prepare.d.ts.map +1 -1
  19. package/dist/lending/user-data/with-permissions/evaluate.d.ts.map +1 -1
  20. package/dist/prices/oracle-prices/fetchOraclePrices.d.ts.map +1 -1
  21. package/dist/prices/oracle-prices/fetchers/aave.d.ts.map +1 -1
  22. package/dist/prices/oracle-prices/fetchers/aaveV4.d.ts +31 -0
  23. package/dist/prices/oracle-prices/fetchers/aaveV4.d.ts.map +1 -0
  24. package/dist/prices/oracle-prices/fetchers/compoundV3.d.ts.map +1 -1
  25. package/dist/prices/oracle-prices/fetchers/index.d.ts +1 -0
  26. package/dist/prices/oracle-prices/fetchers/index.d.ts.map +1 -1
  27. package/dist/prices/oracle-prices/fetchers/morpho.d.ts.map +1 -1
  28. package/dist/prices/oracle-prices/types.d.ts +24 -4
  29. package/dist/prices/oracle-prices/types.d.ts.map +1 -1
  30. package/dist/utils/index.d.ts +1 -1
  31. package/dist/utils/index.d.ts.map +1 -1
  32. package/package.json +5 -5
  33. package/dist/lending/public-data/euler/fetcher/constants.d.ts +0 -27
  34. package/dist/lending/public-data/euler/fetcher/constants.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
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, isInit, isMorphoType, isCompoundV2Type, isVenusType, isSumerType, AAVE_V3_LENDERS, AAVE_V2_LENDERS, isAaveV2Type, isAaveV32Type, isAaveV3Type, isEulerType, isYLDR, isCompoundV3Type, isTectonicType, isBenqiType, isLista } from '@1delta/lender-registry';
4
+ import { Lender, isAaveType, isCompoundV3, isMultiMarket, isInit, isMorphoType, isCompoundV2Type, isVenusType, isSumerType, AAVE_V3_LENDERS, AAVE_V2_LENDERS, isAaveV2Type, isAaveV32Type, isAaveV3Type, isEulerType, isAaveV4Type, 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, multicallRetryUniversal, getEvmClient, getEvmClientUniversal } from '@1delta/providers';
8
- import { MorphoLensAbi, MorphoBlueAbi } from '@1delta/abis';
8
+ import { MorphoLensAbi, AaveV4SpokeAbi, AaveV4OracleAbi, AaveV4HubAbi, MorphoBlueAbi } from '@1delta/abis';
9
9
  export { MorphoLensAbi } from '@1delta/abis';
10
- import { prepareDebitDataMulticall, prepareLenderDebitMulticall, parseDebitDataResult, parseLenderDebitResult, getPermit2ContractAddress, InitMarginAddresses } from '@1delta/calldata-sdk';
10
+ import { prepareDebitDataMulticall, prepareLenderDebitMulticall, parseDebitDataResult, parseLenderDebitResult, getPermit2ContractAddress, getCompoundV3CometAddress as getCompoundV3CometAddress$1, getMorphoAddress, getAaveCollateralTokenAddress, InitMarginAddresses } from '@1delta/calldata-sdk';
11
11
  import { BALANCER_V2_FORKS, BALANCER_V3_FORKS, UNISWAP_V4_FORKS, FLASH_LOAN_IDS } from '@1delta/dex-registry';
12
12
 
13
13
  // src/abis/aave-v2/ProtocolDataProvider.ts
@@ -6268,12 +6268,16 @@ globalThis[GLOBAL_LENDER_DATA_KEY] = {
6268
6268
  morphoOracles: {},
6269
6269
  morphoTypeOracles: {},
6270
6270
  morphoTypeMarkets: {},
6271
+ aaveOraclesConfig: {},
6271
6272
  aaveWethGateway: {},
6272
6273
  morphoBundler3: {},
6273
6274
  listaNativeProvider: {},
6274
6275
  compoundV3Bulker: {},
6275
6276
  eulerConfigs: {},
6276
- eulerVaults: {}
6277
+ eulerVaults: {},
6278
+ aaveV4Spokes: {},
6279
+ aaveV4Reserves: {},
6280
+ aaveV4Oracles: {}
6277
6281
  };
6278
6282
  function getGlobalData2() {
6279
6283
  return globalThis[GLOBAL_LENDER_DATA_KEY];
@@ -6295,8 +6299,12 @@ var compoundV2Pools = () => getGlobalData2()?.compoundV2Pools;
6295
6299
  var compoundV2Tokens = () => getGlobalData2()?.compoundV2Tokens;
6296
6300
  var compoundV2TokenArray = () => getGlobalData2()?.compoundV2TokenArray;
6297
6301
  var initConfig = () => getGlobalData2()?.initConfig;
6302
+ var aaveOraclesConfig = () => getGlobalData2()?.aaveOraclesConfig;
6298
6303
  var eulerConfigs = () => getGlobalData2()?.eulerConfigs;
6299
6304
  var eulerVaults = () => getGlobalData2()?.eulerVaults;
6305
+ var aaveV4Spokes = () => getGlobalData2()?.aaveV4Spokes;
6306
+ var aaveV4Reserves = () => getGlobalData2()?.aaveV4Reserves;
6307
+ var aaveV4Oracles = () => getGlobalData2()?.aaveV4Oracles;
6300
6308
  var getListUrl = (chainId) => `https://raw.githubusercontent.com/1delta-DAO/token-lists/main/${chainId}.json`;
6301
6309
  async function fetchTokenList(chainId) {
6302
6310
  const data = await fetch(getListUrl(chainId));
@@ -7527,6 +7535,9 @@ var getLendersForChain = (c) => {
7527
7535
  if (data[c]?.length > 0) lenders.push(l);
7528
7536
  });
7529
7537
  }
7538
+ Object.entries(aaveV4Spokes() ?? {}).forEach(([l, data]) => {
7539
+ if (data[c]?.length > 0) lenders.push(l);
7540
+ });
7530
7541
  return lenders;
7531
7542
  };
7532
7543
  var filterLendersByProtocol = (allLenders, protocolList) => {
@@ -17881,7 +17892,499 @@ var getEulerV2ReservesDataConverter = (lender, chainId, prices, additionalYields
17881
17892
  ];
17882
17893
  };
17883
17894
 
17884
- // src/lending/public-data/fetchLender.ts
17895
+ // src/lending/public-data/aave-v4-type/publicCallBuild.ts
17896
+ var CALLS_PER_RESERVE = 6;
17897
+ var CALLS_PER_SPOKE_TAIL = 2;
17898
+ function hasValidOracle(oracle) {
17899
+ return !!oracle && oracle !== "0x" && oracle.length > 2;
17900
+ }
17901
+ function getSpokeReserves(reservesMap, spokeAddr) {
17902
+ return reservesMap[spokeAddr.toLowerCase()] ?? reservesMap[spokeAddr] ?? [];
17903
+ }
17904
+ var buildAaveV4LenderReserveCall = (chainId, lender) => {
17905
+ const spokes = aaveV4Spokes()?.[lender]?.[chainId] ?? [];
17906
+ const reservesMap = aaveV4Reserves()?.[lender]?.[chainId] ?? {};
17907
+ if (spokes.length === 0) return [];
17908
+ const calls = [];
17909
+ const hubAssetKeys = /* @__PURE__ */ new Set();
17910
+ const hubAssetList = [];
17911
+ for (const spokeEntry of spokes) {
17912
+ const spokeAddr = spokeEntry.spoke;
17913
+ const reserves = getSpokeReserves(reservesMap, spokeAddr);
17914
+ for (const entry of reserves) {
17915
+ const rid = typeof entry === "number" ? entry : entry.reserveId;
17916
+ calls.push(
17917
+ {
17918
+ address: spokeAddr,
17919
+ name: "getReserve",
17920
+ params: [rid]
17921
+ },
17922
+ {
17923
+ address: spokeAddr,
17924
+ name: "getReserveConfig",
17925
+ params: [rid]
17926
+ },
17927
+ {
17928
+ address: spokeAddr,
17929
+ name: "getReserveSuppliedAssets",
17930
+ params: [rid]
17931
+ },
17932
+ {
17933
+ address: spokeAddr,
17934
+ name: "getReserveDebt",
17935
+ params: [rid]
17936
+ },
17937
+ {
17938
+ address: spokeAddr,
17939
+ name: "getReserveTotalDebt",
17940
+ params: [rid]
17941
+ },
17942
+ {
17943
+ address: spokeAddr,
17944
+ name: "getDynamicReserveConfig",
17945
+ params: [rid, 0]
17946
+ }
17947
+ );
17948
+ if (typeof entry === "object" && spokeEntry.hub && entry.assetId !== void 0) {
17949
+ const key = `${spokeEntry.hub}:${entry.assetId}`;
17950
+ if (!hubAssetKeys.has(key)) {
17951
+ hubAssetKeys.add(key);
17952
+ hubAssetList.push({
17953
+ hub: spokeEntry.hub,
17954
+ assetId: entry.assetId
17955
+ });
17956
+ }
17957
+ }
17958
+ }
17959
+ calls.push(
17960
+ {
17961
+ address: spokeAddr,
17962
+ name: "getLiquidationConfig",
17963
+ params: []
17964
+ },
17965
+ {
17966
+ address: spokeAddr,
17967
+ name: "ORACLE",
17968
+ params: []
17969
+ }
17970
+ );
17971
+ }
17972
+ for (const spokeEntry of spokes) {
17973
+ const reserves = getSpokeReserves(
17974
+ reservesMap,
17975
+ spokeEntry.spoke
17976
+ );
17977
+ const rids = reserves.map(
17978
+ (e) => typeof e === "number" ? e : e.reserveId
17979
+ );
17980
+ if (rids.length > 0 && hasValidOracle(spokeEntry.oracle)) {
17981
+ calls.push({
17982
+ address: spokeEntry.oracle,
17983
+ name: "getReservesPrices",
17984
+ params: [rids]
17985
+ });
17986
+ }
17987
+ }
17988
+ for (const { hub, assetId } of hubAssetList) {
17989
+ calls.push(
17990
+ {
17991
+ address: hub,
17992
+ name: "getAsset",
17993
+ params: [assetId]
17994
+ },
17995
+ {
17996
+ address: hub,
17997
+ name: "getAddedAssets",
17998
+ params: [assetId]
17999
+ },
18000
+ {
18001
+ address: hub,
18002
+ name: "getAssetTotalOwed",
18003
+ params: [assetId]
18004
+ }
18005
+ );
18006
+ }
18007
+ return calls;
18008
+ };
18009
+ var getAaveV4ExpectedCallCount = (chainId, lender) => {
18010
+ const spokes = aaveV4Spokes()?.[lender]?.[chainId] ?? [];
18011
+ const reservesMap = aaveV4Reserves()?.[lender]?.[chainId] ?? {};
18012
+ let count = 0;
18013
+ const hubAssetKeys = /* @__PURE__ */ new Set();
18014
+ for (const spokeEntry of spokes) {
18015
+ const reserves = getSpokeReserves(
18016
+ reservesMap,
18017
+ spokeEntry.spoke
18018
+ );
18019
+ count += reserves.length * CALLS_PER_RESERVE + CALLS_PER_SPOKE_TAIL;
18020
+ const rids = reserves.map(
18021
+ (e) => typeof e === "number" ? e : e.reserveId
18022
+ );
18023
+ if (rids.length > 0 && hasValidOracle(spokeEntry.oracle)) {
18024
+ count += 1;
18025
+ }
18026
+ for (const entry of reserves) {
18027
+ if (typeof entry === "object" && spokeEntry.hub && entry.assetId !== void 0) {
18028
+ hubAssetKeys.add(`${spokeEntry.hub}:${entry.assetId}`);
18029
+ }
18030
+ }
18031
+ }
18032
+ count += hubAssetKeys.size * 3;
18033
+ return count;
18034
+ };
18035
+
18036
+ // src/lending/public-data/aave-v4-type/fetcher/normalize.ts
18037
+ function toTokenAmount2(raw, decimals) {
18038
+ if (raw === 0n) return "0";
18039
+ const divisor = 10 ** decimals;
18040
+ return (Number(raw) / divisor).toString();
18041
+ }
18042
+ function toTokenNumber(raw, decimals) {
18043
+ if (raw === 0n) return 0;
18044
+ return Number(raw) / 10 ** decimals;
18045
+ }
18046
+ var RAY2 = 1e27;
18047
+ function rayRateToApr(rateRay) {
18048
+ if (rateRay === 0n) return 0;
18049
+ return Number(rateRay) / RAY2 * 100;
18050
+ }
18051
+ function normalizeAaveV4(spokeDataList, chainId, lender, prices, additionalYields, tokenList, lenderShortNameFn, createMarketUidFn, toOracleKeyFn, toGenericPriceKeyFn) {
18052
+ const data = {};
18053
+ const eModes = {};
18054
+ for (const spokeData of spokeDataList) {
18055
+ const spokeAddr = spokeData.spoke.toLowerCase();
18056
+ const spokeReserves = spokeData.reserves;
18057
+ for (const reserve of spokeReserves) {
18058
+ for (const [keyStr, dynCfg] of Object.entries(
18059
+ reserve.dynamicConfigs
18060
+ )) {
18061
+ const configKey = `${spokeAddr}:${keyStr}`;
18062
+ if (!eModes[configKey] && dynCfg.collateralFactor > 0) {
18063
+ eModes[configKey] = {
18064
+ category: configKey,
18065
+ label: `${spokeData.label} / Config ${keyStr}`,
18066
+ borrowCollateralFactor: dynCfg.collateralFactor / BPS,
18067
+ collateralFactor: dynCfg.collateralFactor / BPS,
18068
+ priceSource: spokeData.oracle
18069
+ };
18070
+ }
18071
+ }
18072
+ }
18073
+ for (const reserve of spokeReserves) {
18074
+ const underlying = reserve.reserve.underlying.toLowerCase();
18075
+ const decimals = reserve.reserve.decimals;
18076
+ const refAddress = `${spokeAddr}:${reserve.reserveId}`;
18077
+ const marketUid = createMarketUidFn(chainId, lender, refAddress);
18078
+ const assetMeta = tokenList[underlying];
18079
+ const oracleKey = toOracleKeyFn(assetMeta?.assetGroup ?? null) ?? toGenericPriceKeyFn(underlying, chainId);
18080
+ let price = 0;
18081
+ if (reserve.price > 0n) {
18082
+ price = Number(reserve.price) / 10 ** spokeData.oracleDecimals;
18083
+ } else {
18084
+ price = prices[oracleKey] ?? 0;
18085
+ }
18086
+ const totalDeposits = toTokenAmount2(
18087
+ reserve.suppliedAssets,
18088
+ decimals
18089
+ );
18090
+ const totalDebt = toTokenAmount2(reserve.totalDebt, decimals);
18091
+ const totalDepositsNum = toTokenNumber(
18092
+ reserve.suppliedAssets,
18093
+ decimals
18094
+ );
18095
+ const totalDebtNum = toTokenNumber(reserve.totalDebt, decimals);
18096
+ const liquidity = totalDepositsNum - totalDebtNum;
18097
+ const variableBorrowRate = rayRateToApr(
18098
+ reserve.hubAsset.drawnRate
18099
+ );
18100
+ const hubDecimals = reserve.hubAsset.decimals || decimals;
18101
+ const hubTotalSupply = toTokenNumber(
18102
+ reserve.hubAsset.totalAddedAssets ?? 0n,
18103
+ hubDecimals
18104
+ );
18105
+ const hubTotalOwed = toTokenNumber(
18106
+ reserve.hubAsset.totalOwedAssets ?? 0n,
18107
+ hubDecimals
18108
+ );
18109
+ const hubUtilization = hubTotalSupply > 0 ? hubTotalOwed / hubTotalSupply : 0;
18110
+ const feeRate = reserve.hubAsset.liquidityFee ? reserve.hubAsset.liquidityFee / BPS : 0;
18111
+ const depositRate = variableBorrowRate * hubUtilization * (1 - feeRate);
18112
+ const config = {};
18113
+ for (const [keyStr, dynCfg] of Object.entries(
18114
+ reserve.dynamicConfigs
18115
+ )) {
18116
+ const configKey = `${spokeAddr}:${keyStr}`;
18117
+ config[configKey] = {
18118
+ category: configKey,
18119
+ label: `${spokeData.label} / Config ${keyStr}`,
18120
+ borrowCollateralFactor: dynCfg.collateralFactor / BPS,
18121
+ collateralFactor: dynCfg.collateralFactor / BPS,
18122
+ borrowFactor: 1,
18123
+ collateralDisabled: dynCfg.collateralFactor === 0 || reserve.config.paused,
18124
+ debtDisabled: !reserve.config.borrowable || reserve.config.paused
18125
+ };
18126
+ }
18127
+ if (Object.keys(config).length === 0) {
18128
+ const defaultKey = `${spokeAddr}:0`;
18129
+ config[defaultKey] = {
18130
+ category: defaultKey,
18131
+ label: `${spokeData.label} / Default`,
18132
+ borrowCollateralFactor: 0,
18133
+ collateralFactor: 0,
18134
+ borrowFactor: 1,
18135
+ collateralDisabled: true,
18136
+ debtDisabled: !reserve.config.borrowable || reserve.config.paused
18137
+ };
18138
+ }
18139
+ data[marketUid] = {
18140
+ marketUid,
18141
+ name: lenderShortNameFn(lender) + " " + (assetMeta?.symbol ?? ""),
18142
+ poolId: underlying,
18143
+ underlying,
18144
+ asset: assetMeta,
18145
+ totalDeposits,
18146
+ totalDebtStable: "0",
18147
+ totalDebt,
18148
+ totalLiquidity: liquidity,
18149
+ totalDepositsUSD: totalDepositsNum * price,
18150
+ totalDebtStableUSD: 0,
18151
+ totalDebtUSD: totalDebtNum * price,
18152
+ totalLiquidityUSD: liquidity * price,
18153
+ depositRate,
18154
+ variableBorrowRate,
18155
+ stableBorrowRate: 0,
18156
+ intrinsicYield: additionalYields?.intrinsicYields?.[oracleKey] ?? 0,
18157
+ rewards: [],
18158
+ decimals,
18159
+ config,
18160
+ collateralActive: Object.values(reserve.dynamicConfigs).some(
18161
+ (c) => c.collateralFactor > 0
18162
+ ),
18163
+ borrowingEnabled: reserve.config.borrowable,
18164
+ hasStable: false,
18165
+ isActive: !reserve.config.paused,
18166
+ isFrozen: reserve.config.frozen,
18167
+ borrowCap: 0,
18168
+ supplyCap: 0,
18169
+ debtCeiling: 0,
18170
+ params: {
18171
+ metadata: {
18172
+ spoke: spokeAddr,
18173
+ hub: reserve.reserve.hub.toLowerCase(),
18174
+ assetId: reserve.reserve.assetId,
18175
+ reserveId: reserve.reserveId,
18176
+ oracle: spokeData.oracle.toLowerCase()
18177
+ }
18178
+ }
18179
+ };
18180
+ }
18181
+ }
18182
+ return { data, chainId, eModes };
18183
+ }
18184
+
18185
+ // src/lending/public-data/aave-v4-type/publicCallParse.ts
18186
+ function hasValidOracle2(oracle) {
18187
+ return !!oracle && oracle !== "0x" && oracle.length > 2;
18188
+ }
18189
+ function getSpokeReserves2(reservesMap, spokeAddr) {
18190
+ return reservesMap[spokeAddr.toLowerCase()] ?? reservesMap[spokeAddr] ?? [];
18191
+ }
18192
+ var getAaveV4ReservesDataConverter = (lender, chainId, prices, additionalYields, tokenList = {}) => {
18193
+ const expectedCalls = getAaveV4ExpectedCallCount(chainId, lender);
18194
+ const converter = (data) => {
18195
+ if (data.length !== expectedCalls) return void 0;
18196
+ const spokes = aaveV4Spokes()?.[lender]?.[chainId] ?? [];
18197
+ const reservesMap = aaveV4Reserves()?.[lender]?.[chainId] ?? {};
18198
+ let offset = 0;
18199
+ const spokeDataList = [];
18200
+ const hubAssetKeys = /* @__PURE__ */ new Set();
18201
+ const hubAssetList = [];
18202
+ for (const spokeEntry of spokes) {
18203
+ const spokeAddr = spokeEntry.spoke;
18204
+ const reserves = getSpokeReserves2(reservesMap, spokeAddr);
18205
+ const reserveCount = reserves.length;
18206
+ const parsedReserves = [];
18207
+ for (let i = 0; i < reserveCount; i++) {
18208
+ const entry = reserves[i];
18209
+ const reserveId = typeof entry === "number" ? entry : entry.reserveId;
18210
+ const baseIdx = offset + i * CALLS_PER_RESERVE;
18211
+ const rawReserve = data[baseIdx];
18212
+ const rawConfig = data[baseIdx + 1];
18213
+ const rawSupplied = data[baseIdx + 2];
18214
+ const rawDebt = data[baseIdx + 3];
18215
+ const rawTotalDebt = data[baseIdx + 4];
18216
+ const rawDynConfig = data[baseIdx + 5];
18217
+ const reserve = {
18218
+ underlying: rawReserve?.underlying ?? "",
18219
+ hub: rawReserve?.hub ?? "",
18220
+ assetId: Number(rawReserve?.assetId ?? 0),
18221
+ decimals: Number(rawReserve?.decimals ?? 18),
18222
+ collateralRisk: Number(
18223
+ rawReserve?.collateralRisk ?? 0
18224
+ ),
18225
+ flags: Number(rawReserve?.flags ?? 0),
18226
+ dynamicConfigKey: Number(
18227
+ rawReserve?.dynamicConfigKey ?? 0
18228
+ )
18229
+ };
18230
+ const config = {
18231
+ collateralRisk: Number(rawConfig?.collateralRisk ?? 0),
18232
+ paused: rawConfig?.paused ?? false,
18233
+ frozen: rawConfig?.frozen ?? false,
18234
+ borrowable: rawConfig?.borrowable ?? false,
18235
+ receiveSharesEnabled: rawConfig?.receiveSharesEnabled ?? false
18236
+ };
18237
+ let drawnDebt = 0n;
18238
+ let premiumDebt = 0n;
18239
+ if (Array.isArray(rawDebt)) {
18240
+ drawnDebt = BigInt(rawDebt[0] ?? 0);
18241
+ premiumDebt = BigInt(rawDebt[1] ?? 0);
18242
+ } else {
18243
+ drawnDebt = BigInt(rawDebt ?? 0);
18244
+ }
18245
+ const dynamicConfigs = {};
18246
+ if (rawDynConfig && rawDynConfig !== "0x") {
18247
+ dynamicConfigs[0] = {
18248
+ collateralFactor: Number(
18249
+ rawDynConfig?.collateralFactor ?? 0
18250
+ ),
18251
+ maxLiquidationBonus: Number(
18252
+ rawDynConfig?.maxLiquidationBonus ?? 0
18253
+ ),
18254
+ liquidationFee: Number(
18255
+ rawDynConfig?.liquidationFee ?? 0
18256
+ )
18257
+ };
18258
+ }
18259
+ if (spokeEntry.hub && typeof entry === "object" && entry.assetId !== void 0) {
18260
+ const key = `${spokeEntry.hub}:${entry.assetId}`;
18261
+ if (!hubAssetKeys.has(key)) {
18262
+ hubAssetKeys.add(key);
18263
+ hubAssetList.push({
18264
+ hub: spokeEntry.hub,
18265
+ assetId: entry.assetId
18266
+ });
18267
+ }
18268
+ }
18269
+ parsedReserves.push({
18270
+ reserveId,
18271
+ reserve,
18272
+ config,
18273
+ dynamicConfigs,
18274
+ suppliedAssets: BigInt(rawSupplied ?? 0),
18275
+ drawnDebt,
18276
+ premiumDebt,
18277
+ totalDebt: BigInt(rawTotalDebt ?? 0),
18278
+ hubAsset: { drawnRate: 0n },
18279
+ price: 0n
18280
+ });
18281
+ }
18282
+ offset += reserveCount * CALLS_PER_RESERVE;
18283
+ const rawLiqConfig = data[offset];
18284
+ const rawOracle = data[offset + 1];
18285
+ offset += CALLS_PER_SPOKE_TAIL;
18286
+ const liquidationConfig = {
18287
+ targetHealthFactor: BigInt(
18288
+ rawLiqConfig?.targetHealthFactor ?? 0
18289
+ ),
18290
+ healthFactorForMaxBonus: BigInt(
18291
+ rawLiqConfig?.healthFactorForMaxBonus ?? 0
18292
+ ),
18293
+ liquidationBonusFactor: Number(
18294
+ rawLiqConfig?.liquidationBonusFactor ?? 0
18295
+ )
18296
+ };
18297
+ spokeDataList.push({
18298
+ spoke: spokeAddr,
18299
+ oracle: rawOracle ?? spokeEntry.oracle,
18300
+ label: spokeEntry.label,
18301
+ oracleDecimals: 8,
18302
+ liquidationConfig,
18303
+ reserves: parsedReserves
18304
+ });
18305
+ }
18306
+ for (let si = 0; si < spokes.length; si++) {
18307
+ const reserves = getSpokeReserves2(
18308
+ reservesMap,
18309
+ spokes[si].spoke
18310
+ );
18311
+ const rids = reserves.map(
18312
+ (e) => typeof e === "number" ? e : e.reserveId
18313
+ );
18314
+ if (rids.length > 0 && hasValidOracle2(spokes[si].oracle)) {
18315
+ const rawPrices = data[offset];
18316
+ offset += 1;
18317
+ const priceArray = Array.isArray(rawPrices) ? rawPrices : [];
18318
+ for (let ri = 0; ri < spokeDataList[si].reserves.length; ri++) {
18319
+ if (ri < priceArray.length) {
18320
+ spokeDataList[si].reserves[ri].price = BigInt(
18321
+ priceArray[ri] ?? 0
18322
+ );
18323
+ }
18324
+ }
18325
+ }
18326
+ }
18327
+ const hubAssetMap = /* @__PURE__ */ new Map();
18328
+ for (let hi = 0; hi < hubAssetList.length; hi++) {
18329
+ const baseIdx = offset + hi * 3;
18330
+ const rawHubAsset = data[baseIdx];
18331
+ const rawAddedAssets = data[baseIdx + 1];
18332
+ const rawTotalOwed = data[baseIdx + 2];
18333
+ if (!rawHubAsset || rawHubAsset === "0x") continue;
18334
+ const underlying = (rawHubAsset?.underlying ?? "").toLowerCase();
18335
+ const key = underlying || `${hubAssetList[hi].hub}:${hubAssetList[hi].assetId}`;
18336
+ hubAssetMap.set(key, {
18337
+ liquidity: BigInt(rawHubAsset?.liquidity ?? 0),
18338
+ realizedFees: BigInt(rawHubAsset?.realizedFees ?? 0),
18339
+ decimals: Number(rawHubAsset?.decimals ?? 18),
18340
+ addedShares: BigInt(rawHubAsset?.addedShares ?? 0),
18341
+ swept: BigInt(rawHubAsset?.swept ?? 0),
18342
+ premiumOffsetRay: BigInt(
18343
+ rawHubAsset?.premiumOffsetRay ?? 0
18344
+ ),
18345
+ drawnShares: BigInt(rawHubAsset?.drawnShares ?? 0),
18346
+ premiumShares: BigInt(rawHubAsset?.premiumShares ?? 0),
18347
+ liquidityFee: Number(rawHubAsset?.liquidityFee ?? 0),
18348
+ drawnIndex: BigInt(rawHubAsset?.drawnIndex ?? 0),
18349
+ drawnRate: BigInt(rawHubAsset?.drawnRate ?? 0),
18350
+ lastUpdateTimestamp: Number(
18351
+ rawHubAsset?.lastUpdateTimestamp ?? 0
18352
+ ),
18353
+ underlying: rawHubAsset?.underlying ?? "",
18354
+ irStrategy: rawHubAsset?.irStrategy ?? "",
18355
+ reinvestmentController: rawHubAsset?.reinvestmentController ?? "",
18356
+ feeReceiver: rawHubAsset?.feeReceiver ?? "",
18357
+ deficitRay: BigInt(rawHubAsset?.deficitRay ?? 0),
18358
+ totalAddedAssets: BigInt(rawAddedAssets ?? 0),
18359
+ totalOwedAssets: BigInt(rawTotalOwed ?? 0)
18360
+ });
18361
+ }
18362
+ for (const spokeData of spokeDataList) {
18363
+ for (const reserve of spokeData.reserves) {
18364
+ const underlying = reserve.reserve.underlying?.toLowerCase?.() ?? "";
18365
+ if (underlying) {
18366
+ const hubAsset = hubAssetMap.get(underlying);
18367
+ if (hubAsset) {
18368
+ reserve.hubAsset = hubAsset;
18369
+ }
18370
+ }
18371
+ }
18372
+ }
18373
+ return normalizeAaveV4(
18374
+ spokeDataList,
18375
+ chainId,
18376
+ lender,
18377
+ prices,
18378
+ additionalYields,
18379
+ tokenList,
18380
+ lenderShortName,
18381
+ createMarketUid,
18382
+ toOracleKey,
18383
+ toGenericPriceKey
18384
+ );
18385
+ };
18386
+ return [converter, expectedCalls];
18387
+ };
17885
18388
  function getMorphoTypeMarketConverter(lender, chainId, prices, additionalYields, tokenList = {}, marketsOverride) {
17886
18389
  if (lender.startsWith("LISTA_DAO"))
17887
18390
  return getListaMarketDataConverter(
@@ -17915,6 +18418,7 @@ function buildLenderCall(chainId, lender) {
17915
18418
  if (isCompoundV2Type(lender))
17916
18419
  return buildCompoundV2StyleLenderReserveCall(chainId, lender);
17917
18420
  if (isEulerType(lender)) return buildEulerV2LenderReserveCall(chainId, lender);
18421
+ if (isAaveV4Type(lender)) return buildAaveV4LenderReserveCall(chainId, lender);
17918
18422
  return [];
17919
18423
  }
17920
18424
  function getLenderDataConverter(lender, chainId, prices, additionalYields, tokenList = {}) {
@@ -17975,6 +18479,14 @@ function getLenderDataConverter(lender, chainId, prices, additionalYields, token
17975
18479
  additionalYields,
17976
18480
  tokenList
17977
18481
  );
18482
+ if (isAaveV4Type(lender))
18483
+ return getAaveV4ReservesDataConverter(
18484
+ lender,
18485
+ chainId,
18486
+ prices,
18487
+ additionalYields,
18488
+ tokenList
18489
+ );
17978
18490
  return [() => null, 0];
17979
18491
  }
17980
18492
  var getAbi = (lender) => {
@@ -17994,6 +18506,7 @@ var getAbi = (lender) => {
17994
18506
  if (isInit(lender)) return InitLensAbi;
17995
18507
  if (isMorphoType(lender)) return MorphoLensAbi;
17996
18508
  if (isEulerType(lender)) return vaultLensAbi;
18509
+ if (isAaveV4Type(lender)) return [...AaveV4SpokeAbi, ...AaveV4OracleAbi, ...AaveV4HubAbi];
17997
18510
  if (isSumerType(lender)) return [...SumerLensAbi, ...SumerComptrollerAbi];
17998
18511
  if (lender === Lender.TAKARA) return [...TakaraMarketStateAbi];
17999
18512
  if (isCompoundV2Type(lender)) return VenusLensAbi;
@@ -18525,8 +19038,43 @@ var buildEulerUserCall = async (chainId, lender, account, subAccountIndexes) =>
18525
19038
  }));
18526
19039
  };
18527
19040
 
19041
+ // src/lending/user-data/aave-v4-type/userCallBuild.ts
19042
+ var USER_CALLS_PER_RESERVE = 3;
19043
+ var buildAaveV4UserCall = (chainId, lender, account) => {
19044
+ const spokes = aaveV4Spokes()?.[lender]?.[chainId] ?? [];
19045
+ const reservesMap = aaveV4Reserves()?.[lender]?.[chainId] ?? {};
19046
+ if (spokes.length === 0) return [];
19047
+ const calls = [];
19048
+ for (const spokeEntry of spokes) {
19049
+ const spokeAddr = spokeEntry.spoke;
19050
+ const reserveIds = reservesMap[spokeAddr.toLowerCase()] ?? reservesMap[spokeAddr] ?? [];
19051
+ for (const entry of reserveIds) {
19052
+ const rid = typeof entry === "number" ? entry : entry.reserveId;
19053
+ calls.push(
19054
+ {
19055
+ address: spokeAddr,
19056
+ name: "getUserSuppliedAssets",
19057
+ params: [rid, account]
19058
+ },
19059
+ {
19060
+ address: spokeAddr,
19061
+ name: "getUserDebt",
19062
+ params: [rid, account]
19063
+ },
19064
+ {
19065
+ address: spokeAddr,
19066
+ name: "getUserReserveStatus",
19067
+ params: [rid, account]
19068
+ }
19069
+ );
19070
+ }
19071
+ }
19072
+ return calls;
19073
+ };
19074
+
18528
19075
  // src/lending/user-data/fetch-balances/prepare.ts
18529
19076
  async function buildUserCall(chainId, lender, account, params) {
19077
+ if (isAaveV4Type(lender)) return buildAaveV4UserCall(chainId, lender, account);
18530
19078
  if (isAaveV2Type(lender)) return buildAaveV2UserCall(chainId, lender, account);
18531
19079
  if (isAaveV3Type(lender)) return buildAaveV3UserCall(chainId, lender, account);
18532
19080
  if (isInit(lender)) return buildInitUserCall(chainId, lender, account);
@@ -19685,8 +20233,114 @@ var getEulerUserDataConverter = (lender, chainId, account, metaMap, subAccountIn
19685
20233
  ];
19686
20234
  };
19687
20235
 
20236
+ // src/lending/user-data/aave-v4-type/userCallParse.ts
20237
+ var getAaveV4UserDataConverter = (lender, chainId, account, metaMap) => {
20238
+ const spokes = aaveV4Spokes()?.[lender]?.[chainId] ?? [];
20239
+ const reservesMap = aaveV4Reserves()?.[lender]?.[chainId] ?? {};
20240
+ const reserveEntries = [];
20241
+ for (const spokeEntry of spokes) {
20242
+ const spokeAddr = spokeEntry.spoke;
20243
+ const reserveIds = reservesMap[spokeAddr.toLowerCase()] ?? reservesMap[spokeAddr] ?? [];
20244
+ for (const entry of reserveIds) {
20245
+ const rid = typeof entry === "number" ? entry : entry.reserveId;
20246
+ reserveEntries.push({ spokeAddr, reserveId: rid });
20247
+ }
20248
+ }
20249
+ const expectedNumberOfCalls = reserveEntries.length * USER_CALLS_PER_RESERVE;
20250
+ return [
20251
+ (data) => {
20252
+ if (data.length !== expectedNumberOfCalls) {
20253
+ return void 0;
20254
+ }
20255
+ const lendingPositions = {};
20256
+ let totalDebt24h = 0;
20257
+ let totalDeposits24h = 0;
20258
+ for (let i = 0; i < reserveEntries.length; i++) {
20259
+ const { spokeAddr, reserveId } = reserveEntries[i];
20260
+ const refAddress = `${spokeAddr.toLowerCase()}:${reserveId}`;
20261
+ const key = createMarketUid(chainId, lender, refAddress);
20262
+ const metaEntity = metaMap?.[key];
20263
+ if (!metaEntity) continue;
20264
+ const base = i * USER_CALLS_PER_RESERVE;
20265
+ const { dataForAsset, addedDebt, addedDeposits } = createAaveV4Entry(
20266
+ base,
20267
+ data,
20268
+ key,
20269
+ metaEntity
20270
+ );
20271
+ if (!dataForAsset) continue;
20272
+ totalDebt24h += addedDebt;
20273
+ totalDeposits24h += addedDeposits;
20274
+ lendingPositions[key] = dataForAsset;
20275
+ }
20276
+ const payload = {
20277
+ chainId,
20278
+ account,
20279
+ lendingPositions,
20280
+ rewards: [],
20281
+ userEMode: 0
20282
+ };
20283
+ const userData = createBaseTypeUserState(
20284
+ payload,
20285
+ metaMap,
20286
+ totalDeposits24h,
20287
+ totalDebt24h
20288
+ );
20289
+ return userData;
20290
+ },
20291
+ expectedNumberOfCalls
20292
+ ];
20293
+ };
20294
+ function createAaveV4Entry(base, data, key, meta) {
20295
+ const rawSupply = data[base];
20296
+ const debtResult = data[base + 1];
20297
+ const statusResult = data[base + 2];
20298
+ const suppliedRaw = rawSupply === "0x" || rawSupply === void 0 ? "0" : rawSupply.toString();
20299
+ const drawnDebtRaw = Array.isArray(debtResult) ? debtResult[0]?.toString() ?? "0" : "0";
20300
+ const premiumDebtRaw = Array.isArray(debtResult) ? debtResult[1]?.toString() ?? "0" : "0";
20301
+ const totalDebtRaw = (BigInt(drawnDebtRaw || "0") + BigInt(premiumDebtRaw || "0")).toString();
20302
+ if ((suppliedRaw === "0" || !suppliedRaw) && totalDebtRaw === "0") {
20303
+ return {
20304
+ dataForAsset: void 0,
20305
+ addedDeposits: 0,
20306
+ addedDebt: 0
20307
+ };
20308
+ }
20309
+ const assetMeta = meta.asset;
20310
+ const decimals = assetMeta?.decimals ?? 18;
20311
+ const currentDeposits = parseRawAmount(suppliedRaw, decimals);
20312
+ const currentDebt = parseRawAmount(totalDebtRaw, decimals);
20313
+ const collateralEnabled = Boolean(statusResult?.[0]);
20314
+ const price = getDisplayPrice(meta);
20315
+ const oPrice = getOraclePrice(meta);
20316
+ const priceHist = meta?.price?.priceUsd24h ?? price;
20317
+ const dataForAsset = {
20318
+ marketUid: key,
20319
+ underlying: assetMeta.address,
20320
+ deposits: currentDeposits,
20321
+ debtStable: "0",
20322
+ debt: currentDebt,
20323
+ depositsUSD: Number(currentDeposits) * price,
20324
+ debtStableUSD: 0,
20325
+ debtUSD: Number(currentDebt) * price,
20326
+ depositsUSDOracle: Number(currentDeposits) * oPrice,
20327
+ debtStableUSDOracle: 0,
20328
+ debtUSDOracle: Number(currentDebt) * oPrice,
20329
+ stableBorrowRate: 0,
20330
+ collateralEnabled,
20331
+ claimableRewards: 0
20332
+ };
20333
+ return {
20334
+ dataForAsset,
20335
+ addedDeposits: Number(currentDeposits) * priceHist,
20336
+ addedDebt: Number(currentDebt) * priceHist
20337
+ };
20338
+ }
20339
+
19688
20340
  // src/lending/user-data/fetch-balances/parse.ts
19689
20341
  function getUserDataConverter(lender, chainId, account, params, meta) {
20342
+ if (isAaveV4Type(lender))
20343
+ return getAaveV4UserDataConverter(lender, chainId, account, meta?.[lender]);
19690
20344
  if (isYLDR(lender))
19691
20345
  return getYldrUserDataConverter(lender, chainId, account, meta?.[lender]);
19692
20346
  if (isAaveV2Type(lender))
@@ -24365,6 +25019,7 @@ var accountLensAbi = [
24365
25019
 
24366
25020
  // src/lending/user-data/abis.ts
24367
25021
  var getAbi2 = (lender) => {
25022
+ if (isAaveV4Type(lender)) return [...AaveV4SpokeAbi];
24368
25023
  if (isAaveV2Type(lender))
24369
25024
  return [
24370
25025
  ...AavePoolAndDataProviderAbi,
@@ -24805,12 +25460,27 @@ function resolveDebitDataKey(chainId, lender, tokenAddress, cToken) {
24805
25460
  if (resolved) return resolved.toLowerCase();
24806
25461
  }
24807
25462
  }
25463
+ if (isCompoundV3Type(lender)) {
25464
+ const comet = getCompoundV3CometAddress$1(chainId, lender);
25465
+ if (comet) return comet;
25466
+ }
25467
+ if (isMorphoType(lender)) {
25468
+ const comet = getMorphoAddress(
25469
+ chainId,
25470
+ isLista(lender) ? Lender.LISTA_DAO : Lender.MORPHO_BLUE
25471
+ );
25472
+ if (comet) return comet;
25473
+ }
25474
+ if (isAaveType(lender)) {
25475
+ const aToken = getAaveCollateralTokenAddress(chainId, lender, tokenAddress);
25476
+ if (aToken) return aToken;
25477
+ }
24808
25478
  return tokenAddress.toLowerCase();
24809
25479
  }
24810
25480
  function needsLenderApproval(params) {
24811
25481
  const { lender, lenderDebitData, tokenAddress, amount, chainId, cToken } = params;
24812
25482
  if (!lenderDebitData) return true;
24813
- if (isInit(lender) || isMorphoType(lender)) {
25483
+ if (isInit(lender) || isMorphoType(lender) || isCompoundV3(lender)) {
24814
25484
  const entry2 = Object.values(lenderDebitData)[0];
24815
25485
  if (!entry2 || entry2.amount === void 0) return true;
24816
25486
  return entry2.amount === 0n;
@@ -30396,38 +31066,8 @@ var parseRWADynamicOracleResults = (chainId, data, assetName) => {
30396
31066
  }
30397
31067
  }
30398
31068
  };
30399
- var AAVE_LENDER_OVERRIDES = {
30400
- [Lender.KLAYBANK]: {
30401
- [Chain.KAIA_MAINNET]: {
30402
- // KLAYBANK on KAIA uses WKLAY as base asset
30403
- baseAsset: "0x19aac5f612f524b754ca7e7c41cbfa2e981a4432",
30404
- // BASE_CURRENCY_UNIT call reverts, oracle returns 18 decimals
30405
- baseCurrencyUnit: 1000000000000000000n,
30406
- // Use RHOMBUS oracle for WKLAY USD price
30407
- baseAssetSource: Lender.AVALON
30408
- }
30409
- },
30410
- [Lender.KLAP]: {
30411
- [Chain.KAIA_MAINNET]: {
30412
- // BASE_CURRENCY_UNIT call reverts, oracle returns 18 decimals (USD denominated)
30413
- baseCurrencyUnit: 1000000000000000000n
30414
- }
30415
- },
30416
- [Lender.MOLEND]: {
30417
- [Chain.MODE]: {
30418
- // BASE_CURRENCY_UNIT call reverts, oracle returns 18 decimals (USD denominated)
30419
- baseCurrencyUnit: 100000000n
30420
- }
30421
- },
30422
- [Lender.MOOLA]: {
30423
- [Chain.CELO_MAINNET]: {
30424
- baseAsset: "0x471ece3750da237f93b8e339c536989b8978a438",
30425
- // BASE_CURRENCY_UNIT call reverts, oracle returns 18 decimals
30426
- baseCurrencyUnit: 1000000000000000000n,
30427
- baseAssetSource: Lender.AAVE_V3
30428
- }
30429
- }
30430
- };
31069
+
31070
+ // src/prices/oracle-prices/fetchers/aave.ts
30431
31071
  function getAaveLendersForChain(chainId) {
30432
31072
  const oracles = aaveOracles() ?? {};
30433
31073
  const reserves = aaveReserves() ?? {};
@@ -30461,7 +31101,8 @@ function getAaveCalls2(chainId) {
30461
31101
  params: [asset]
30462
31102
  });
30463
31103
  }
30464
- const lenderOverride = AAVE_LENDER_OVERRIDES[lender]?.[chainId];
31104
+ const config = aaveOraclesConfig() ?? {};
31105
+ const lenderOverride = config[lender]?.[chainId];
30465
31106
  results.push({
30466
31107
  calls,
30467
31108
  meta: {
@@ -30471,7 +31112,7 @@ function getAaveCalls2(chainId) {
30471
31112
  baseCurrencyUnitIndex: 0,
30472
31113
  assetCallCount: assets.length,
30473
31114
  baseAssetOverride: lenderOverride?.baseAsset,
30474
- baseCurrencyUnitOverride: lenderOverride?.baseCurrencyUnit,
31115
+ baseCurrencyUnitOverride: lenderOverride?.baseCurrencyUnit ? BigInt(lenderOverride.baseCurrencyUnit) : void 0,
30475
31116
  baseAssetSource: lenderOverride?.baseAssetSource
30476
31117
  },
30477
31118
  lender
@@ -30511,13 +31152,15 @@ function parseAaveResults2(data, meta, context) {
30511
31152
  );
30512
31153
  if (isNaN(rawPriceNum) || rawPriceNum === 0) continue;
30513
31154
  const priceUSD = rawPriceNum * baseAssetUSD;
31155
+ const isBaseAsset = meta.baseAssetOverride && asset.toLowerCase() === meta.baseAssetOverride.toLowerCase();
30514
31156
  entries.push({
30515
31157
  asset: asset.toLowerCase(),
30516
31158
  price: rawPriceNum,
30517
31159
  // Raw price (in base asset terms)
30518
31160
  priceUSD,
30519
31161
  marketUid: createMarketUid(chainId, meta.fork, asset),
30520
- staticBase: meta.baseAssetOverride
31162
+ staticBase: isBaseAsset || void 0,
31163
+ baseAsset: meta.baseAssetOverride
30521
31164
  });
30522
31165
  } catch {
30523
31166
  continue;
@@ -30626,7 +31269,8 @@ function parseMorphoResults2(data, meta, context) {
30626
31269
  marketUid: createMarketUid(chainId, lenderKey, loanAsset),
30627
31270
  targetLender: lenderKey,
30628
31271
  description: "Morpho loan asset",
30629
- staticBase: loanAsset
31272
+ staticBase: true,
31273
+ baseAsset: loanAsset
30630
31274
  });
30631
31275
  const collateralPriceUSD = priceDebtToCollateral * loanAssetUSD;
30632
31276
  entries.push({
@@ -30636,7 +31280,7 @@ function parseMorphoResults2(data, meta, context) {
30636
31280
  priceUSD: collateralPriceUSD,
30637
31281
  marketUid: createMarketUid(chainId, lenderKey, collateralAsset),
30638
31282
  targetLender: lenderKey,
30639
- staticBase: loanAsset
31283
+ baseAsset: loanAsset
30640
31284
  });
30641
31285
  }
30642
31286
  }
@@ -30753,7 +31397,7 @@ function processMarketsToEntries(chainId, allMarkets, source) {
30753
31397
  priceUSD: resolvedCollateralUSD,
30754
31398
  marketUid: createMarketUid(chainId, lenderKey, collateralAsset),
30755
31399
  targetLender: lenderKey,
30756
- staticBase: loanAsset
31400
+ baseAsset: loanAsset
30757
31401
  });
30758
31402
  }
30759
31403
  if (resolvedLoanUSD > 0) {
@@ -30764,7 +31408,8 @@ function processMarketsToEntries(chainId, allMarkets, source) {
30764
31408
  marketUid: createMarketUid(chainId, lenderKey, loanAsset),
30765
31409
  targetLender: lenderKey,
30766
31410
  description: "Morpho loan asset",
30767
- staticBase: loanAsset
31411
+ staticBase: true,
31412
+ baseAsset: loanAsset
30768
31413
  });
30769
31414
  }
30770
31415
  }
@@ -30890,13 +31535,9 @@ function getCompoundV3Calls(chainId) {
30890
31535
  const skipBaseScaling = USD_PRICED_OVERRIDES[lender]?.has(chainId);
30891
31536
  const baseAsset = skipBaseScaling ? void 0 : baseData[lender]?.[chainId]?.baseAsset?.toLowerCase();
30892
31537
  const entries = Object.entries(assetOracles);
30893
- const constantEntry = entries.find(
31538
+ const hasConstantFeed = entries.some(
30894
31539
  ([, e]) => e.description?.toLowerCase().includes("constant price")
30895
31540
  );
30896
- let staticBase;
30897
- if (constantEntry && baseAsset) {
30898
- staticBase = baseAsset;
30899
- }
30900
31541
  const calls = [];
30901
31542
  const meta = [];
30902
31543
  for (const [asset, entry] of entries) {
@@ -30905,13 +31546,14 @@ function getCompoundV3Calls(chainId) {
30905
31546
  name: "latestRoundData",
30906
31547
  params: []
30907
31548
  });
31549
+ const isBaseAsset = hasConstantFeed && baseAsset && asset.toLowerCase() === baseAsset;
30908
31550
  meta.push({
30909
31551
  asset,
30910
31552
  oracle: entry.oracle,
30911
31553
  baseAsset,
30912
31554
  lender,
30913
31555
  description: entry.description,
30914
- staticBase
31556
+ staticBase: isBaseAsset || void 0
30915
31557
  });
30916
31558
  }
30917
31559
  if (calls.length > 0) {
@@ -30954,7 +31596,8 @@ function parseCompoundV3Results(data, meta, context) {
30954
31596
  priceUSD,
30955
31597
  marketUid: createMarketUid(chainId, queryMeta.lender, queryMeta.asset),
30956
31598
  description: queryMeta.description,
30957
- staticBase: queryMeta.staticBase
31599
+ staticBase: queryMeta.staticBase || void 0,
31600
+ baseAsset: queryMeta.baseAsset
30958
31601
  });
30959
31602
  } catch {
30960
31603
  }
@@ -31232,6 +31875,96 @@ var eulerV2Fetcher = {
31232
31875
  parse: parseEulerV2Results,
31233
31876
  getAbi: getEulerV2Abi
31234
31877
  };
31878
+ function getAaveV4OracleGroups(chainId) {
31879
+ const oracles = aaveV4Oracles() ?? {};
31880
+ const groups = [];
31881
+ for (const [fork, chains] of Object.entries(oracles)) {
31882
+ const oracleEntries = chains[chainId] ?? [];
31883
+ if (oracleEntries.length === 0) continue;
31884
+ const byOracle = /* @__PURE__ */ new Map();
31885
+ for (const entry of oracleEntries) {
31886
+ if (!entry.oracle || entry.oracle === "0x") continue;
31887
+ const key = entry.oracle.toLowerCase();
31888
+ let group = byOracle.get(key);
31889
+ if (!group) {
31890
+ group = { decimals: entry.decimals ?? 8, entries: [] };
31891
+ byOracle.set(key, group);
31892
+ }
31893
+ group.entries.push({
31894
+ underlying: entry.underlying.toLowerCase(),
31895
+ spoke: entry.spoke.toLowerCase(),
31896
+ reserveId: entry.reserveId
31897
+ });
31898
+ }
31899
+ for (const [oracle, group] of byOracle) {
31900
+ groups.push({
31901
+ fork,
31902
+ oracle,
31903
+ decimals: group.decimals,
31904
+ entries: group.entries
31905
+ });
31906
+ }
31907
+ }
31908
+ return groups;
31909
+ }
31910
+ function getAaveV4Calls(chainId) {
31911
+ const groups = getAaveV4OracleGroups(chainId);
31912
+ const results = [];
31913
+ for (const { fork, oracle, decimals, entries } of groups) {
31914
+ const calls = entries.map((e) => ({
31915
+ address: oracle,
31916
+ name: "getReservePrice",
31917
+ params: [e.reserveId]
31918
+ }));
31919
+ results.push({
31920
+ calls,
31921
+ meta: {
31922
+ oracle,
31923
+ oracleDecimals: decimals,
31924
+ entries,
31925
+ fork
31926
+ },
31927
+ lender: fork
31928
+ });
31929
+ }
31930
+ return results;
31931
+ }
31932
+ function parseAaveV4Results(data, meta, context) {
31933
+ const { chainId } = context;
31934
+ const entries = [];
31935
+ if (data.length === 0) return entries;
31936
+ const divisor = 10 ** meta.oracleDecimals;
31937
+ for (let i = 0; i < meta.entries.length; i++) {
31938
+ const rawPrice = data[i];
31939
+ if (rawPrice === void 0 || rawPrice === "0x") continue;
31940
+ const entry = meta.entries[i];
31941
+ try {
31942
+ const priceNum = Number(BigInt(rawPrice.toString())) / divisor;
31943
+ if (isNaN(priceNum) || priceNum === 0) continue;
31944
+ entries.push({
31945
+ asset: entry.underlying,
31946
+ price: priceNum,
31947
+ priceUSD: priceNum,
31948
+ marketUid: createMarketUid(
31949
+ chainId,
31950
+ meta.fork,
31951
+ `${entry.spoke}:${entry.reserveId}`
31952
+ )
31953
+ });
31954
+ } catch {
31955
+ continue;
31956
+ }
31957
+ }
31958
+ return entries;
31959
+ }
31960
+ function getAaveV4Abi() {
31961
+ return AaveV4OracleAbi;
31962
+ }
31963
+ var aaveV4Fetcher = {
31964
+ getCalls: getAaveV4Calls,
31965
+ parse: parseAaveV4Results,
31966
+ getAbi: getAaveV4Abi
31967
+ };
31235
31968
 
31236
31969
  // src/prices/oracle-prices/fetchOraclePrices.ts
31237
31970
  function countFailures(data, offset, count) {
@@ -31371,6 +32104,11 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
31371
32104
  () => eulerV2Fetcher.getCalls(chainId),
31372
32105
  getCallsErrors
31373
32106
  ) : [];
32107
+ const aaveV4Results = isActive("aavev4") ? safeGetCalls(
32108
+ "aaveV4",
32109
+ () => aaveV4Fetcher.getCalls(chainId),
32110
+ getCallsErrors
32111
+ ) : [];
31374
32112
  const morphoResults = isActive("morpho") ? safeGetCalls(
31375
32113
  "morpho",
31376
32114
  () => morphoFetcher.getCalls(chainId, {
@@ -31408,6 +32146,12 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
31408
32146
  eulerV2Fetcher.parse,
31409
32147
  getEulerV2Abi()
31410
32148
  );
32149
+ const aaveV4Group = buildGroup(
32150
+ "aaveV4",
32151
+ aaveV4Results,
32152
+ aaveV4Fetcher.parse,
32153
+ getAaveV4Abi()
32154
+ );
31411
32155
  const morphoGroup = buildGroup(
31412
32156
  "morpho",
31413
32157
  morphoResults,
@@ -31420,6 +32164,7 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
31420
32164
  compoundV3Group,
31421
32165
  listaGroup,
31422
32166
  eulerGroup,
32167
+ aaveV4Group,
31423
32168
  morphoGroup
31424
32169
  ];
31425
32170
  const totalCalls = allGroups.reduce((s, g) => s + g.calls.length, 0);
@@ -31445,6 +32190,7 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
31445
32190
  compoundV3Data,
31446
32191
  listaData,
31447
32192
  eulerData,
32193
+ aaveV4Data,
31448
32194
  morphoGqlEntries
31449
32195
  ] = await Promise.all([
31450
32196
  executeGroup(
@@ -31487,6 +32233,14 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
31487
32233
  allowFailure,
31488
32234
  rpcOverrides
31489
32235
  ),
32236
+ executeGroup(
32237
+ aaveV4Group,
32238
+ chainId,
32239
+ chainBatchSize,
32240
+ retries,
32241
+ allowFailure,
32242
+ rpcOverrides
32243
+ ),
31490
32244
  morphoGqlPromise
31491
32245
  ]);
31492
32246
  if (morphoGqlEntries == null && isActive("morpho")) {
@@ -31507,6 +32261,7 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
31507
32261
  { group: compoundV3Group, data: compoundV3Data },
31508
32262
  { group: listaGroup, data: listaData },
31509
32263
  { group: eulerGroup, data: eulerData },
32264
+ { group: aaveV4Group, data: aaveV4Data },
31510
32265
  ...useMorphoGql ? [] : [{ group: morphoGroup, data: morphoData }]
31511
32266
  ];
31512
32267
  for (const { group, data } of groupResults) {
@@ -31561,6 +32316,7 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
31561
32316
  parseTrackers(compoundV3Group, compoundV3Data.results);
31562
32317
  parseTrackers(listaGroup, listaData.results);
31563
32318
  parseTrackers(eulerGroup, eulerData.results);
32319
+ parseTrackers(aaveV4Group, aaveV4Data.results);
31564
32320
  if (stalenessThresholdSeconds > 0) {
31565
32321
  const nowSeconds = Math.floor(Date.now() / 1e3);
31566
32322
  for (const tracker of compoundV3Group.trackers) {