@1delta/margin-fetcher 0.0.219 → 0.0.221

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 (53) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +243 -244
  4. package/dist/index.js.map +1 -1
  5. package/dist/lending/public-data/aave-v2-type/publicCallParse.d.ts.map +1 -1
  6. package/dist/lending/public-data/aave-v3-type/publicCallParse.d.ts.map +1 -1
  7. package/dist/lending/public-data/aave-v4-type/fetcher/normalize.d.ts +83 -81
  8. package/dist/lending/public-data/aave-v4-type/fetcher/normalize.d.ts.map +1 -1
  9. package/dist/lending/public-data/aave-v4-type/fetcher/types.d.ts +16 -0
  10. package/dist/lending/public-data/aave-v4-type/fetcher/types.d.ts.map +1 -1
  11. package/dist/lending/public-data/aave-v4-type/publicCallBuild.d.ts +3 -2
  12. package/dist/lending/public-data/aave-v4-type/publicCallBuild.d.ts.map +1 -1
  13. package/dist/lending/public-data/aave-v4-type/publicCallParse.d.ts.map +1 -1
  14. package/dist/lending/public-data/compound-v2/convert/benqi.d.ts +1 -0
  15. package/dist/lending/public-data/compound-v2/convert/benqi.d.ts.map +1 -1
  16. package/dist/lending/public-data/compound-v2/convert/standard.d.ts +1 -0
  17. package/dist/lending/public-data/compound-v2/convert/standard.d.ts.map +1 -1
  18. package/dist/lending/public-data/compound-v2/convert/sumer.d.ts +1 -0
  19. package/dist/lending/public-data/compound-v2/convert/sumer.d.ts.map +1 -1
  20. package/dist/lending/public-data/compound-v2/convert/takara.d.ts +1 -0
  21. package/dist/lending/public-data/compound-v2/convert/takara.d.ts.map +1 -1
  22. package/dist/lending/public-data/compound-v2/convert/tectonic.d.ts +1 -0
  23. package/dist/lending/public-data/compound-v2/convert/tectonic.d.ts.map +1 -1
  24. package/dist/lending/public-data/compound-v3/publicCallParse.d.ts.map +1 -1
  25. package/dist/lending/public-data/euler/fetcher/normalize.d.ts +1 -0
  26. package/dist/lending/public-data/euler/fetcher/normalize.d.ts.map +1 -1
  27. package/dist/lending/public-data/euler/publicCallParse.d.ts.map +1 -1
  28. package/dist/lending/public-data/init/publicCallParse.d.ts.map +1 -1
  29. package/dist/lending/public-data/lista/getMarketsFromChain.d.ts.map +1 -1
  30. package/dist/lending/public-data/morpho/convertPublic.d.ts.map +1 -1
  31. package/dist/lending/public-data/morpho/getMarketsFromChain.d.ts.map +1 -1
  32. package/dist/lending/user-data/aave-v4-type/createAaveV4UserState.d.ts +16 -6
  33. package/dist/lending/user-data/aave-v4-type/createAaveV4UserState.d.ts.map +1 -1
  34. package/dist/lending/user-data/aave-v4-type/userCallParse.d.ts +22 -6
  35. package/dist/lending/user-data/aave-v4-type/userCallParse.d.ts.map +1 -1
  36. package/dist/lending/user-data/fetch-balances/parse.d.ts.map +1 -1
  37. package/dist/lending/user-data/utils/types.d.ts +0 -9
  38. package/dist/lending/user-data/utils/types.d.ts.map +1 -1
  39. package/dist/lending-pools/computeLenderDataFromPools.d.ts.map +1 -1
  40. package/dist/prices/oracle-prices/fetchers/aaveV4.d.ts.map +1 -1
  41. package/dist/types/apiReturnType.d.ts +1 -11
  42. package/dist/types/apiReturnType.d.ts.map +1 -1
  43. package/dist/types/lender/aave-v2-types.d.ts +1 -0
  44. package/dist/types/lender/aave-v2-types.d.ts.map +1 -1
  45. package/dist/types/lender/aave-v3-types.d.ts +1 -3
  46. package/dist/types/lender/aave-v3-types.d.ts.map +1 -1
  47. package/dist/types/lender/compound-v2-types.d.ts +1 -0
  48. package/dist/types/lender/compound-v2-types.d.ts.map +1 -1
  49. package/dist/types/lender/morpho-types.d.ts +1 -0
  50. package/dist/types/lender/morpho-types.d.ts.map +1 -1
  51. package/dist/types/lenderTypes.d.ts +1 -0
  52. package/dist/types/lenderTypes.d.ts.map +1 -1
  53. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -6308,6 +6308,12 @@ var aaveV4Hubs = () => getGlobalData2()?.aaveV4Hubs;
6308
6308
  var aaveV4Spokes = () => getGlobalData2()?.aaveV4Spokes;
6309
6309
  var aaveV4Reserves = () => getGlobalData2()?.aaveV4Reserves;
6310
6310
  var aaveV4Oracles = () => getGlobalData2()?.aaveV4Oracles;
6311
+ function aaveV4SpokeLenderKey(baseHubLender, spoke) {
6312
+ if (!spoke || spoke.length < 4 || !spoke.startsWith("0x")) {
6313
+ throw new Error(`aaveV4SpokeLenderKey: invalid spoke address ${spoke}`);
6314
+ }
6315
+ return `${baseHubLender}_${spoke.slice(2).toUpperCase()}`;
6316
+ }
6311
6317
  var getListUrl = (chainId) => `https://raw.githubusercontent.com/1delta-DAO/token-lists/main/${chainId}.json`;
6312
6318
  async function fetchTokenList(chainId) {
6313
6319
  const data = await fetch(getListUrl(chainId));
@@ -8220,6 +8226,7 @@ var getAaveV2ReservesDataConverter = (lender, chainId, prices, additionalYields,
8220
8226
  // flags
8221
8227
  collateralActive,
8222
8228
  borrowingEnabled,
8229
+ depositsEnabled: true,
8223
8230
  hasStable: configData?.[7 /* stableBorrowRateEnabled */],
8224
8231
  isActive: configData?.[8 /* isActive */],
8225
8232
  isFrozen: configData?.[9 /* isFrozen */]
@@ -8372,6 +8379,7 @@ var getAaveV3ReservesDataConverter = (lender, chainId, prices, additionalYields,
8372
8379
  // flags
8373
8380
  collateralActive: usageAsCollateralEnabled,
8374
8381
  borrowingEnabled,
8382
+ depositsEnabled: true,
8375
8383
  hasStable: configData?.[7 /* stableBorrowRateEnabled */],
8376
8384
  isActive: configData?.[8 /* isActive */],
8377
8385
  isFrozen: configData?.[9 /* isFrozen */],
@@ -8580,6 +8588,7 @@ function parseYLDRCall(chainId, lender, additionalYields, prices, tokenList) {
8580
8588
  // flags
8581
8589
  collateralActive: usageAsCollateralEnabled,
8582
8590
  borrowingEnabled,
8591
+ depositsEnabled: true,
8583
8592
  hasStable: false,
8584
8593
  isActive: configData?.[7 /* isActive */],
8585
8594
  isFrozen: configData?.[8 /* isFrozen */]
@@ -8600,8 +8609,7 @@ function parseYLDRCall(chainId, lender, additionalYields, prices, tokenList) {
8600
8609
  }
8601
8610
  return {
8602
8611
  data: resultReserves,
8603
- chainId,
8604
- eModes: {}
8612
+ chainId
8605
8613
  };
8606
8614
  },
8607
8615
  expectedNumberOfCalls
@@ -8721,6 +8729,7 @@ function parseAave32(chainId, lender, prices, additionalYields, tokenList) {
8721
8729
  // flags
8722
8730
  collateralActive: usageAsCollateralEnabled,
8723
8731
  borrowingEnabled,
8732
+ depositsEnabled: true,
8724
8733
  hasStable: configData?.[7 /* stableBorrowRateEnabled */],
8725
8734
  isActive: configData?.[8 /* isActive */],
8726
8735
  isFrozen: configData?.[9 /* isFrozen */],
@@ -8830,6 +8839,7 @@ var getInitReservesDataConverter = (lender, chainId, prices, additionalYields, t
8830
8839
  rewards: [],
8831
8840
  config: {},
8832
8841
  borrowingEnabled: totalDebt !== "0",
8842
+ depositsEnabled: true,
8833
8843
  params
8834
8844
  };
8835
8845
  });
@@ -8962,7 +8972,8 @@ var getCompoundV3ReservesDataConverter = (lender, chainId, prices, additionalYie
8962
8972
  collateralActive: true,
8963
8973
  isActive: true,
8964
8974
  isFrozen: false,
8965
- borrowingEnabled: false
8975
+ borrowingEnabled: false,
8976
+ depositsEnabled: true
8966
8977
  };
8967
8978
  }
8968
8979
  const baseMeta = tokenList[baseAssetData.baseAsset];
@@ -9037,6 +9048,7 @@ var getCompoundV3ReservesDataConverter = (lender, chainId, prices, additionalYie
9037
9048
  }
9038
9049
  ] : [],
9039
9050
  borrowingEnabled: true,
9051
+ depositsEnabled: true,
9040
9052
  collateralActive: false,
9041
9053
  isActive: true,
9042
9054
  isFrozen: false,
@@ -12165,6 +12177,7 @@ function convertMarketsToMorphoResponse(response, chainId, additionalYields = {
12165
12177
  },
12166
12178
  collateralActive: false,
12167
12179
  borrowingEnabled: true,
12180
+ depositsEnabled: true,
12168
12181
  hasStable: false,
12169
12182
  isActive: true,
12170
12183
  isFrozen: false
@@ -12215,6 +12228,7 @@ function convertMarketsToMorphoResponse(response, chainId, additionalYields = {
12215
12228
  },
12216
12229
  collateralActive: true,
12217
12230
  borrowingEnabled: false,
12231
+ depositsEnabled: true,
12218
12232
  hasStable: false,
12219
12233
  isActive: true,
12220
12234
  isFrozen: false
@@ -12915,6 +12929,7 @@ function getListaMarketDataConverter(lender, chainId, prices, additionalYields =
12915
12929
  },
12916
12930
  collateralActive: false,
12917
12931
  borrowingEnabled: true,
12932
+ depositsEnabled: true,
12918
12933
  hasStable: false,
12919
12934
  isActive: true,
12920
12935
  isFrozen: false
@@ -12955,6 +12970,7 @@ function getListaMarketDataConverter(lender, chainId, prices, additionalYields =
12955
12970
  },
12956
12971
  collateralActive: true,
12957
12972
  borrowingEnabled: false,
12973
+ depositsEnabled: true,
12958
12974
  hasStable: false,
12959
12975
  isActive: true,
12960
12976
  isFrozen: false
@@ -13122,6 +13138,7 @@ function getMorphoMarketDataConverter(lender, chainId, prices, additionalYields
13122
13138
  },
13123
13139
  collateralActive: false,
13124
13140
  borrowingEnabled: true,
13141
+ depositsEnabled: true,
13125
13142
  hasStable: false,
13126
13143
  isActive: true,
13127
13144
  isFrozen: false
@@ -13167,6 +13184,7 @@ function getMorphoMarketDataConverter(lender, chainId, prices, additionalYields
13167
13184
  },
13168
13185
  collateralActive: true,
13169
13186
  borrowingEnabled: false,
13187
+ depositsEnabled: true,
13170
13188
  hasStable: false,
13171
13189
  isActive: true,
13172
13190
  isFrozen: false
@@ -15764,6 +15782,7 @@ function convertSingleEntry(opts) {
15764
15782
  rewards: [],
15765
15783
  collateralActive,
15766
15784
  borrowingEnabled,
15785
+ depositsEnabled: !pausedActions[0 /* MINT */],
15767
15786
  params: {
15768
15787
  metadata: {
15769
15788
  cToken,
@@ -15854,6 +15873,7 @@ function convertSumerEntry(opts) {
15854
15873
  rewards: [],
15855
15874
  collateralActive,
15856
15875
  borrowingEnabled,
15876
+ depositsEnabled: true,
15857
15877
  params: {
15858
15878
  metadata: {
15859
15879
  cToken,
@@ -15925,6 +15945,7 @@ function convertTakaraEntry(opts) {
15925
15945
  rewards: [],
15926
15946
  collateralActive: info.isListed,
15927
15947
  borrowingEnabled: info.isListed,
15948
+ depositsEnabled: true,
15928
15949
  params: {
15929
15950
  metadata: {
15930
15951
  cToken,
@@ -15989,6 +16010,7 @@ function convertTectonicEntry(opts) {
15989
16010
  rewards: [],
15990
16011
  collateralActive: info.asCollateralEnabled,
15991
16012
  borrowingEnabled: info.asCollateralEnabled,
16013
+ depositsEnabled: true,
15992
16014
  params: {
15993
16015
  metadata: {
15994
16016
  cToken,
@@ -16152,6 +16174,7 @@ function convertBenqiEntry(opts) {
16152
16174
  rewards: [],
16153
16175
  collateralActive,
16154
16176
  borrowingEnabled,
16177
+ depositsEnabled: !parsed.mintPaused,
16155
16178
  params: {
16156
16179
  metadata: {
16157
16180
  cToken,
@@ -17733,6 +17756,7 @@ function buildTokenEntry(info, config, collateralActive, borrowVaults, opts) {
17733
17756
  config,
17734
17757
  collateralActive,
17735
17758
  borrowingEnabled: isBorrowVault,
17759
+ depositsEnabled: true,
17736
17760
  hasStable: false,
17737
17761
  isActive: true,
17738
17762
  isFrozen: false,
@@ -17870,6 +17894,7 @@ var getEulerV2ReservesDataConverter = (lender, chainId, prices, additionalYields
17870
17894
  // flags
17871
17895
  collateralActive: entry.collateralActive,
17872
17896
  borrowingEnabled: entry.borrowingEnabled,
17897
+ depositsEnabled: entry.depositsEnabled,
17873
17898
  hasStable: entry.hasStable,
17874
17899
  isActive: entry.isActive,
17875
17900
  isFrozen: entry.isFrozen,
@@ -17895,7 +17920,7 @@ var getEulerV2ReservesDataConverter = (lender, chainId, prices, additionalYields
17895
17920
 
17896
17921
  // src/lending/public-data/aave-v4-type/publicCallBuild.ts
17897
17922
  var BASE_CALLS_PER_RESERVE = 5;
17898
- var CALLS_PER_SPOKE_TAIL = 2;
17923
+ var CALLS_PER_SPOKE_TAIL = 1;
17899
17924
  var MAX_HUB_ASSETS = 25;
17900
17925
  function isValidAddress(addr) {
17901
17926
  return !!addr && addr !== "0x" && addr.length > 2;
@@ -17961,18 +17986,11 @@ var buildAaveV4LenderReserveCall = (chainId, lender) => {
17961
17986
  });
17962
17987
  }
17963
17988
  }
17964
- calls.push(
17965
- {
17966
- address: spokeAddr,
17967
- name: "getLiquidationConfig",
17968
- params: []
17969
- },
17970
- {
17971
- address: spokeAddr,
17972
- name: "ORACLE",
17973
- params: []
17974
- }
17975
- );
17989
+ calls.push({
17990
+ address: spokeAddr,
17991
+ name: "getLiquidationConfig",
17992
+ params: []
17993
+ });
17976
17994
  }
17977
17995
  for (const spokeEntry of spokes) {
17978
17996
  if (!isValidAddress(spokeEntry.spoke)) continue;
@@ -18065,51 +18083,49 @@ var getAaveV4ExpectedCallCount = (chainId, lender) => {
18065
18083
  // src/lending/public-data/aave-v4-type/fetcher/normalize.ts
18066
18084
  function toTokenAmount2(raw, decimals) {
18067
18085
  if (raw === 0n) return "0";
18068
- const divisor = 10 ** decimals;
18069
- return (Number(raw) / divisor).toString();
18086
+ const negative = raw < 0n;
18087
+ const abs = negative ? -raw : raw;
18088
+ const s = abs.toString();
18089
+ let intPart;
18090
+ let fracPart;
18091
+ if (s.length <= decimals) {
18092
+ intPart = "0";
18093
+ fracPart = "0".repeat(decimals - s.length) + s;
18094
+ } else {
18095
+ intPart = s.slice(0, s.length - decimals);
18096
+ fracPart = s.slice(s.length - decimals);
18097
+ }
18098
+ fracPart = fracPart.replace(/0+$/, "");
18099
+ const out = fracPart ? `${intPart}.${fracPart}` : intPart;
18100
+ return negative ? `-${out}` : out;
18070
18101
  }
18071
18102
  function toTokenNumber(raw, decimals) {
18072
18103
  if (raw === 0n) return 0;
18073
18104
  return Number(raw) / 10 ** decimals;
18074
18105
  }
18075
18106
  var RAY2 = 1e27;
18107
+ var MAX_SPOKE_CAP = 2 ** 40 - 1;
18076
18108
  function rayRateToApr(rateRay) {
18077
18109
  if (rateRay === 0n) return 0;
18078
18110
  return Number(rateRay) / RAY2 * 100;
18079
18111
  }
18080
- function normalizeAaveV4(spokeDataList, chainId, lender, prices, additionalYields, tokenList, lenderShortNameFn, createMarketUidFn, toOracleKeyFn, toGenericPriceKeyFn, expectedHub) {
18081
- const data = {};
18082
- const eModes = {};
18112
+ function normalizeAaveV4(spokeDataList, chainId, baseHubLender, prices, additionalYields, tokenList, lenderShortNameFn, createMarketUidFn, toOracleKeyFn, toGenericPriceKeyFn, expectedHub) {
18113
+ const out = {};
18083
18114
  const hubFilter = expectedHub?.toLowerCase();
18084
18115
  for (const spokeData of spokeDataList) {
18085
18116
  const spokeAddr = spokeData.spoke.toLowerCase();
18117
+ const spokeLenderKey = aaveV4SpokeLenderKey(baseHubLender, spokeAddr);
18118
+ let spokeHub = "";
18086
18119
  const spokeReserves = spokeData.reserves;
18120
+ const data = {};
18087
18121
  for (const reserve of spokeReserves) {
18088
18122
  const reserveHub = reserve.reserve.hub?.toLowerCase();
18089
18123
  if (hubFilter && reserveHub && reserveHub !== hubFilter)
18090
18124
  continue;
18091
- for (const [keyStr, dynCfg] of Object.entries(
18092
- reserve.dynamicConfigs
18093
- )) {
18094
- const configKey = `${spokeAddr}:${keyStr}`;
18095
- if (!eModes[configKey] && dynCfg.collateralFactor > 0) {
18096
- eModes[configKey] = {
18097
- category: configKey,
18098
- label: `${spokeData.label} / Config ${keyStr}`,
18099
- borrowCollateralFactor: dynCfg.collateralFactor / BPS,
18100
- collateralFactor: dynCfg.collateralFactor / BPS,
18101
- priceSource: spokeData.oracle
18102
- };
18103
- }
18104
- }
18105
- }
18106
- for (const reserve of spokeReserves) {
18107
- const reserveHub = reserve.reserve.hub?.toLowerCase();
18108
- if (hubFilter && reserveHub && reserveHub !== hubFilter)
18109
- continue;
18125
+ if (!spokeHub) spokeHub = reserveHub ?? "";
18110
18126
  const underlying = reserve.reserve.underlying.toLowerCase();
18111
18127
  const decimals = reserve.reserve.decimals;
18112
- const marketUid = createMarketUidFn(chainId, lender, underlying);
18128
+ const marketUid = createMarketUidFn(chainId, spokeLenderKey, underlying);
18113
18129
  const assetMeta = tokenList[underlying];
18114
18130
  const oracleKey = toOracleKeyFn(assetMeta?.assetGroup ?? null) ?? toGenericPriceKeyFn(underlying, chainId);
18115
18131
  let price = 0;
@@ -18118,21 +18134,34 @@ function normalizeAaveV4(spokeDataList, chainId, lender, prices, additionalYield
18118
18134
  } else {
18119
18135
  price = prices[oracleKey] ?? 0;
18120
18136
  }
18121
- const totalDeposits = toTokenAmount2(
18137
+ const totalDepositsStr = toTokenAmount2(
18122
18138
  reserve.suppliedAssets,
18123
18139
  decimals
18124
18140
  );
18125
- const totalDebt = toTokenAmount2(reserve.totalDebt, decimals);
18141
+ const totalDebtStr = toTokenAmount2(reserve.totalDebt, decimals);
18126
18142
  const totalDepositsNum = toTokenNumber(
18127
18143
  reserve.suppliedAssets,
18128
18144
  decimals
18129
18145
  );
18130
18146
  const totalDebtNum = toTokenNumber(reserve.totalDebt, decimals);
18131
- const liquidity = totalDepositsNum - totalDebtNum;
18132
- const variableBorrowRate = rayRateToApr(
18133
- reserve.hubAsset.drawnRate
18134
- );
18147
+ const totalDepositsUSD = totalDepositsNum * price;
18148
+ const totalDebtUSD = totalDebtNum * price;
18149
+ const supplyCap = reserve.spokeBinding?.addCap ?? 0;
18150
+ const borrowCap = reserve.spokeBinding?.drawCap ?? 0;
18135
18151
  const hubDecimals = reserve.hubAsset.decimals || decimals;
18152
+ const hubLiquidityNum = toTokenNumber(
18153
+ reserve.hubAsset.liquidity ?? 0n,
18154
+ hubDecimals
18155
+ );
18156
+ let borrowLiquidityNum = hubLiquidityNum;
18157
+ if (borrowCap > 0 && borrowCap < MAX_SPOKE_CAP) {
18158
+ const spokeHeadroom = borrowCap - totalDebtNum;
18159
+ if (spokeHeadroom < borrowLiquidityNum)
18160
+ borrowLiquidityNum = spokeHeadroom;
18161
+ }
18162
+ if (borrowLiquidityNum < 0) borrowLiquidityNum = 0;
18163
+ const borrowLiquidityUSD = borrowLiquidityNum * price;
18164
+ const variableBorrowRate = rayRateToApr(reserve.hubAsset.drawnRate);
18136
18165
  const hubTotalSupply = toTokenNumber(
18137
18166
  reserve.hubAsset.totalAddedAssets ?? 0n,
18138
18167
  hubDecimals
@@ -18150,9 +18179,8 @@ function normalizeAaveV4(spokeDataList, chainId, lender, prices, additionalYield
18150
18179
  for (const [keyStr, dynCfg] of Object.entries(
18151
18180
  reserve.dynamicConfigs
18152
18181
  )) {
18153
- const configKey = `${spokeAddr}:${keyStr}`;
18154
- config[configKey] = {
18155
- category: configKey,
18182
+ config[keyStr] = {
18183
+ category: keyStr,
18156
18184
  label: `${spokeData.label} / Config ${keyStr}`,
18157
18185
  borrowCollateralFactor: dynCfg.collateralFactor / BPS,
18158
18186
  collateralFactor: dynCfg.collateralFactor / BPS,
@@ -18162,9 +18190,8 @@ function normalizeAaveV4(spokeDataList, chainId, lender, prices, additionalYield
18162
18190
  };
18163
18191
  }
18164
18192
  if (Object.keys(config).length === 0) {
18165
- const defaultKey = `${spokeAddr}:0`;
18166
- config[defaultKey] = {
18167
- category: defaultKey,
18193
+ config["0"] = {
18194
+ category: "0",
18168
18195
  label: `${spokeData.label} / Default`,
18169
18196
  borrowCollateralFactor: 0,
18170
18197
  collateralFactor: 0,
@@ -18173,88 +18200,66 @@ function normalizeAaveV4(spokeDataList, chainId, lender, prices, additionalYield
18173
18200
  debtDisabled: !reserve.config.borrowable || reserve.config.paused
18174
18201
  };
18175
18202
  }
18176
- const collateralEnabledOnThisSpoke = Object.values(
18177
- reserve.dynamicConfigs
18178
- ).some((c) => c.collateralFactor > 0);
18179
- if (data[marketUid]) {
18180
- Object.assign(data[marketUid].config, config);
18181
- if (!data[marketUid].collateralActive) {
18182
- data[marketUid].collateralActive = collateralEnabledOnThisSpoke;
18183
- }
18184
- if (!data[marketUid].borrowingEnabled) {
18185
- data[marketUid].borrowingEnabled = reserve.config.borrowable;
18186
- }
18187
- const rp = data[marketUid].params.riskPremium;
18188
- rp.bySpoke[spokeAddr] = {
18189
- collateralRiskBps,
18190
- riskPremiumThresholdBps
18191
- };
18192
- if (riskPremiumThresholdBps > rp.maxBps) {
18193
- rp.maxBps = riskPremiumThresholdBps;
18194
- rp.maxEffectiveBorrowRate = data[marketUid].variableBorrowRate * (1 + riskPremiumThresholdBps / BPS);
18195
- }
18196
- if (collateralEnabledOnThisSpoke) {
18197
- if (rp.minCollateralRiskBps == null || collateralRiskBps < rp.minCollateralRiskBps) {
18198
- rp.minCollateralRiskBps = collateralRiskBps;
18203
+ const collateralActive = Object.values(reserve.dynamicConfigs).some(
18204
+ (c) => c.collateralFactor > 0
18205
+ );
18206
+ data[marketUid] = {
18207
+ marketUid,
18208
+ name: lenderShortNameFn(baseHubLender) + " " + (assetMeta?.symbol ?? ""),
18209
+ poolId: underlying,
18210
+ underlying,
18211
+ asset: assetMeta,
18212
+ totalDeposits: totalDepositsStr,
18213
+ totalDebtStable: "0",
18214
+ totalDebt: totalDebtStr,
18215
+ // V4 borrow liquidity comes from the hub, not from local supplies.
18216
+ // See the comment block where `borrowLiquidityNum` is computed.
18217
+ totalLiquidity: borrowLiquidityNum,
18218
+ totalDepositsUSD,
18219
+ totalDebtStableUSD: 0,
18220
+ totalDebtUSD,
18221
+ totalLiquidityUSD: borrowLiquidityUSD,
18222
+ depositRate,
18223
+ variableBorrowRate,
18224
+ stableBorrowRate: 0,
18225
+ intrinsicYield: additionalYields?.intrinsicYields?.[oracleKey] ?? 0,
18226
+ rewards: [],
18227
+ decimals,
18228
+ config,
18229
+ collateralActive,
18230
+ borrowingEnabled: reserve.config.borrowable,
18231
+ depositsEnabled: reserve.config.receiveSharesEnabled && !reserve.config.paused,
18232
+ hasStable: false,
18233
+ isActive: !reserve.config.paused,
18234
+ isFrozen: reserve.config.frozen,
18235
+ borrowCap,
18236
+ supplyCap,
18237
+ debtCeiling: 0,
18238
+ params: {
18239
+ metadata: {
18240
+ assetId: reserve.reserve.assetId,
18241
+ reserveId: reserve.reserveId
18199
18242
  }
18243
+ },
18244
+ collateralRiskBps,
18245
+ riskPremiumThresholdBps
18246
+ };
18247
+ }
18248
+ if (Object.keys(data).length > 0) {
18249
+ out[spokeLenderKey] = {
18250
+ data,
18251
+ chainId,
18252
+ params: {
18253
+ spoke: spokeAddr,
18254
+ hub: spokeHub,
18255
+ oracle: spokeData.oracle.toLowerCase(),
18256
+ baseHubLender,
18257
+ label: spokeData.label
18200
18258
  }
18201
- } else {
18202
- data[marketUid] = {
18203
- marketUid,
18204
- name: lenderShortNameFn(lender) + " " + (assetMeta?.symbol ?? ""),
18205
- poolId: underlying,
18206
- underlying,
18207
- asset: assetMeta,
18208
- totalDeposits,
18209
- totalDebtStable: "0",
18210
- totalDebt,
18211
- totalLiquidity: liquidity,
18212
- totalDepositsUSD: totalDepositsNum * price,
18213
- totalDebtStableUSD: 0,
18214
- totalDebtUSD: totalDebtNum * price,
18215
- totalLiquidityUSD: liquidity * price,
18216
- depositRate,
18217
- variableBorrowRate,
18218
- stableBorrowRate: 0,
18219
- intrinsicYield: additionalYields?.intrinsicYields?.[oracleKey] ?? 0,
18220
- rewards: [],
18221
- decimals,
18222
- config,
18223
- collateralActive: Object.values(reserve.dynamicConfigs).some(
18224
- (c) => c.collateralFactor > 0
18225
- ),
18226
- borrowingEnabled: reserve.config.borrowable,
18227
- hasStable: false,
18228
- isActive: !reserve.config.paused,
18229
- isFrozen: reserve.config.frozen,
18230
- borrowCap: 0,
18231
- supplyCap: 0,
18232
- debtCeiling: 0,
18233
- params: {
18234
- metadata: {
18235
- spoke: spokeAddr,
18236
- hub: reserve.reserve.hub.toLowerCase(),
18237
- assetId: reserve.reserve.assetId,
18238
- reserveId: reserve.reserveId,
18239
- oracle: spokeData.oracle.toLowerCase()
18240
- },
18241
- riskPremium: {
18242
- maxBps: riskPremiumThresholdBps,
18243
- maxEffectiveBorrowRate: variableBorrowRate * (1 + riskPremiumThresholdBps / BPS),
18244
- minCollateralRiskBps: collateralEnabledOnThisSpoke ? collateralRiskBps : void 0,
18245
- bySpoke: {
18246
- [spokeAddr]: {
18247
- collateralRiskBps,
18248
- riskPremiumThresholdBps
18249
- }
18250
- }
18251
- }
18252
- }
18253
- };
18254
- }
18259
+ };
18255
18260
  }
18256
18261
  }
18257
- return { data, chainId, eModes };
18262
+ return out;
18258
18263
  }
18259
18264
 
18260
18265
  // src/lending/public-data/aave-v4-type/publicCallParse.ts
@@ -18347,7 +18352,6 @@ var getAaveV4ReservesDataConverter = (lender, chainId, prices, additionalYields,
18347
18352
  });
18348
18353
  }
18349
18354
  const rawLiqConfig = data[offset];
18350
- const rawOracle = data[offset + 1];
18351
18355
  offset += CALLS_PER_SPOKE_TAIL;
18352
18356
  const liquidationConfig = {
18353
18357
  targetHealthFactor: BigInt(
@@ -18362,7 +18366,7 @@ var getAaveV4ReservesDataConverter = (lender, chainId, prices, additionalYields,
18362
18366
  };
18363
18367
  spokeDataList.push({
18364
18368
  spoke: spokeAddr,
18365
- oracle: rawOracle ?? spokeEntry.oracle,
18369
+ oracle: spokeEntry.oracle,
18366
18370
  label: spokeEntry.label,
18367
18371
  oracleDecimals: 8,
18368
18372
  liquidationConfig,
@@ -18448,7 +18452,9 @@ var getAaveV4ReservesDataConverter = (lender, chainId, prices, additionalYields,
18448
18452
  rawBinding?.riskPremiumThreshold ?? 0
18449
18453
  ),
18450
18454
  active: Boolean(rawBinding?.active ?? false),
18451
- halted: Boolean(rawBinding?.halted ?? false)
18455
+ halted: Boolean(rawBinding?.halted ?? false),
18456
+ addCap: Number(rawBinding?.addCap ?? 0),
18457
+ drawCap: Number(rawBinding?.drawCap ?? 0)
18452
18458
  };
18453
18459
  const targetReserveId = typeof meta === "number" ? meta : meta.reserveId;
18454
18460
  const target = spokeData.reserves.find(
@@ -20339,42 +20345,30 @@ var getEulerUserDataConverter = (lender, chainId, account, metaMap, subAccountIn
20339
20345
  };
20340
20346
 
20341
20347
  // src/lending/user-data/aave-v4-type/createAaveV4UserState.ts
20342
- function resolveV4Config(configs, userConfigKey) {
20343
- if (!configs) return { config: void 0, spokeAddr: void 0 };
20344
- if (userConfigKey && configs[userConfigKey]) {
20345
- return {
20346
- config: configs[userConfigKey],
20347
- spokeAddr: userConfigKey.split(":")[0]
20348
- };
20349
- }
20350
- const entries = Object.entries(configs);
20351
- if (entries.length === 0) return { config: void 0, spokeAddr: void 0 };
20352
- const [key, config] = entries[0];
20353
- const spokeAddr = key.split(":")[0];
20354
- return { config, spokeAddr };
20348
+ function resolveDynamicConfig(configs, userConfigKey) {
20349
+ if (!configs) return void 0;
20350
+ if (userConfigKey && configs[userConfigKey]) return configs[userConfigKey];
20351
+ const entries = Object.values(configs);
20352
+ return entries.length > 0 ? entries[0] : void 0;
20355
20353
  }
20356
- function getConfigScopedPrice(meta, spokeAddr) {
20357
- if (spokeAddr) {
20358
- const byConfig = meta?.oraclePrice?.byConfig;
20359
- const configPrice = byConfig?.[spokeAddr]?.oraclePriceUsd;
20360
- if (configPrice != null && configPrice > 0) return configPrice;
20361
- }
20354
+ function getSpokeScopedPrice(meta) {
20362
20355
  return getOraclePrice(meta);
20363
20356
  }
20364
20357
  function createAaveV4UserState(payload, lenderData, totalDeposits24h = 0, totalDebt24h = 0) {
20365
- const assetKeys = getMarketUidsFromMeta(lenderData);
20366
20358
  const { chainId, account } = payload;
20367
- const collateralsBySpoke = /* @__PURE__ */ new Map();
20368
- const debtBySpoke = /* @__PURE__ */ new Map();
20369
- for (const marketUid of assetKeys) {
20359
+ const positions = payload.lendingPositions ?? {};
20360
+ const positionMarketUids = Object.keys(positions);
20361
+ const spokeLenderKey = positionMarketUids.length > 0 ? positionMarketUids[0].split(":")[0] : "";
20362
+ const allMarketUids = getMarketUidsFromMeta(lenderData);
20363
+ const spokeMarketUids = spokeLenderKey ? allMarketUids.filter((uid) => uid.startsWith(spokeLenderKey + ":")) : [];
20364
+ const collaterals = [];
20365
+ let totalDebtForPremium = 0;
20366
+ for (const marketUid of positionMarketUids) {
20370
20367
  const meta = lenderData?.[marketUid];
20371
- const pos = payload.lendingPositions?.[marketUid];
20368
+ const pos = positions[marketUid];
20372
20369
  if (!meta || !pos) continue;
20373
20370
  const userConfigKey = pos.userConfigKey;
20374
- if (!userConfigKey) continue;
20375
- const spokeLc = userConfigKey.split(":")[0];
20376
- if (!spokeLc) continue;
20377
- const { config: userConfig2 } = resolveV4Config(
20371
+ const userConfig2 = resolveDynamicConfig(
20378
20372
  meta.configs ?? null,
20379
20373
  userConfigKey
20380
20374
  );
@@ -20382,28 +20376,17 @@ function createAaveV4UserState(payload, lenderData, totalDeposits24h = 0, totalD
20382
20376
  const depositsUSDOracle = pos.depositsUSDOracle ?? pos.depositsUSD ?? 0;
20383
20377
  const debtUSDOracle = pos.debtUSDOracle ?? pos.debtUSD ?? 0;
20384
20378
  if (pos.collateralEnabled && !userConfig2?.collateralDisabled && collateralFactor > 0 && depositsUSDOracle > 0) {
20385
- const riskBps = Number(
20386
- meta.params?.riskPremium?.bySpoke?.[spokeLc]?.collateralRiskBps ?? 0
20387
- );
20388
- const arr = collateralsBySpoke.get(spokeLc) ?? [];
20389
- arr.push({ riskBps, valueUsd: depositsUSDOracle });
20390
- collateralsBySpoke.set(spokeLc, arr);
20379
+ const riskBps = Number(meta.collateralRiskBps ?? 0);
20380
+ collaterals.push({ riskBps, valueUsd: depositsUSDOracle });
20391
20381
  }
20392
20382
  if (debtUSDOracle > 0) {
20393
- debtBySpoke.set(
20394
- spokeLc,
20395
- (debtBySpoke.get(spokeLc) ?? 0) + debtUSDOracle
20396
- );
20383
+ totalDebtForPremium += debtUSDOracle;
20397
20384
  }
20398
20385
  }
20399
- const riskPremiumBpsBySpoke = {};
20400
- for (const [spokeLc, totalDebt] of debtBySpoke.entries()) {
20401
- if (totalDebt <= 0) {
20402
- riskPremiumBpsBySpoke[spokeLc] = 0;
20403
- continue;
20404
- }
20405
- const sorted = (collateralsBySpoke.get(spokeLc) ?? []).slice().sort((a, b) => a.riskBps - b.riskBps);
20406
- let debtLeft = totalDebt;
20386
+ let riskPremiumBps = 0;
20387
+ if (totalDebtForPremium > 0) {
20388
+ const sorted = collaterals.slice().sort((a, b) => a.riskBps - b.riskBps);
20389
+ let debtLeft = totalDebtForPremium;
20407
20390
  let weightedSum = 0;
20408
20391
  for (const c of sorted) {
20409
20392
  if (debtLeft <= 0) break;
@@ -20411,14 +20394,9 @@ function createAaveV4UserState(payload, lenderData, totalDeposits24h = 0, totalD
20411
20394
  weightedSum += used * c.riskBps;
20412
20395
  debtLeft -= used;
20413
20396
  }
20414
- const covered = totalDebt - debtLeft;
20415
- riskPremiumBpsBySpoke[spokeLc] = covered > 0 ? weightedSum / covered : 0;
20397
+ const covered = totalDebtForPremium - debtLeft;
20398
+ riskPremiumBps = covered > 0 ? weightedSum / covered : 0;
20416
20399
  }
20417
- const premiumMultiplierForSpoke = (spokeLc) => {
20418
- if (!spokeLc) return 1;
20419
- const bps = riskPremiumBpsBySpoke[spokeLc] ?? 0;
20420
- return 1 + bps / 1e4;
20421
- };
20422
20400
  let depositInterest = 0;
20423
20401
  let borrowInterest = 0;
20424
20402
  let rewardDepositAccrual = 0;
@@ -20433,10 +20411,10 @@ function createAaveV4UserState(payload, lenderData, totalDeposits24h = 0, totalD
20433
20411
  let borrowDiscountedCollateralAllActive = 0;
20434
20412
  let collateralAllActive = 0;
20435
20413
  let rewardsPerAsset = {};
20436
- for (const marketUid of assetKeys) {
20437
- if (!lenderData?.[marketUid] || !payload.lendingPositions[marketUid])
20438
- continue;
20439
- const pos = payload.lendingPositions[marketUid];
20414
+ for (const marketUid of positionMarketUids) {
20415
+ const meta = lenderData?.[marketUid];
20416
+ const pos = positions[marketUid];
20417
+ if (!meta || !pos) continue;
20440
20418
  const { depositsUSD, debtStableUSD, debtUSD, collateralEnabled } = pos;
20441
20419
  const depositsUSDOracle = pos.depositsUSDOracle ?? depositsUSD;
20442
20420
  const debtUSDOracle = pos.debtUSDOracle ?? debtUSD;
@@ -20448,12 +20426,19 @@ function createAaveV4UserState(payload, lenderData, totalDeposits24h = 0, totalD
20448
20426
  rewards,
20449
20427
  flags,
20450
20428
  configs
20451
- } = lenderData[marketUid];
20452
- const { config: userConfigForAsset, spokeAddr: userSpokeAddr } = resolveV4Config(configs, pos.userConfigKey);
20453
- const userPremiumMultiplier = premiumMultiplierForSpoke(userSpokeAddr);
20429
+ } = meta;
20430
+ const userConfigForAsset = resolveDynamicConfig(
20431
+ configs,
20432
+ pos.userConfigKey
20433
+ );
20434
+ const positionThresholdBps = Number(
20435
+ meta.riskPremiumThresholdBps ?? 0
20436
+ );
20437
+ const clampedPremiumBps = positionThresholdBps > 0 ? Math.min(riskPremiumBps, positionThresholdBps) : riskPremiumBps;
20438
+ const userPremiumMultiplier = 1 + clampedPremiumBps / 1e4;
20454
20439
  const effectiveVariableBorrowRate = (variableBorrowRate ?? 0) * userPremiumMultiplier;
20455
20440
  pos.variableBorrowRate = effectiveVariableBorrowRate;
20456
- pos.riskPremiumBps = userSpokeAddr ? riskPremiumBpsBySpoke[userSpokeAddr] ?? 0 : 0;
20441
+ pos.riskPremiumBps = clampedPremiumBps;
20457
20442
  deposits += depositsUSD;
20458
20443
  debt += debtUSD + (debtStableUSD ?? 0);
20459
20444
  oracleDebt += debtUSDOracle + (pos.debtStableUSDOracle ?? debtStableUSD ?? 0);
@@ -20517,16 +20502,16 @@ function createAaveV4UserState(payload, lenderData, totalDeposits24h = 0, totalD
20517
20502
  0,
20518
20503
  borrowDiscountedCollateral - balanceData2.adjustedDebt
20519
20504
  );
20520
- for (const marketUid of assetKeys) {
20521
- if (!lenderData?.[marketUid]) continue;
20522
- const meta = lenderData[marketUid];
20505
+ for (const marketUid of spokeMarketUids) {
20506
+ const meta = lenderData?.[marketUid];
20507
+ if (!meta) continue;
20523
20508
  const { configs, flags, borrowLiquidity, withdrawLiquidity } = meta;
20524
- const pos = payload.lendingPositions[marketUid];
20525
- const { config, spokeAddr } = resolveV4Config(
20509
+ const pos = positions[marketUid];
20510
+ const config = resolveDynamicConfig(
20526
20511
  configs,
20527
20512
  pos ? pos.userConfigKey : void 0
20528
20513
  );
20529
- const price = getConfigScopedPrice(meta, spokeAddr);
20514
+ const price = getSpokeScopedPrice(meta);
20530
20515
  const bcf = config?.borrowCollateralFactor ?? 1;
20531
20516
  const bf = config?.borrowFactor ?? 1;
20532
20517
  if (pos) {
@@ -20562,7 +20547,7 @@ function createAaveV4UserState(payload, lenderData, totalDeposits24h = 0, totalD
20562
20547
  if (borrowLiquidity != null) {
20563
20548
  borrowable = String(Math.min(Number(borrowable), borrowLiquidity));
20564
20549
  }
20565
- payload.lendingPositions[marketUid] = {
20550
+ positions[marketUid] = {
20566
20551
  marketUid,
20567
20552
  deposits: "0",
20568
20553
  debt: "0",
@@ -20590,7 +20575,7 @@ function createAaveV4UserState(payload, lenderData, totalDeposits24h = 0, totalD
20590
20575
  balanceData: balanceData2,
20591
20576
  aprData: aprData2,
20592
20577
  userConfig,
20593
- positions: Object.values(payload.lendingPositions)
20578
+ positions: Object.values(positions)
20594
20579
  }
20595
20580
  ]
20596
20581
  };
@@ -20600,6 +20585,18 @@ function createAaveV4UserState(payload, lenderData, totalDeposits24h = 0, totalD
20600
20585
  var getAaveV4UserDataConverter = (lender, chainId, account, metaMap) => {
20601
20586
  const spokes = aaveV4Spokes()?.[lender]?.[chainId] ?? [];
20602
20587
  const reservesMap = aaveV4Reserves()?.[lender]?.[chainId] ?? {};
20588
+ const flatMeta = {};
20589
+ if (metaMap) {
20590
+ const expectedPrefix = lender + "_";
20591
+ for (const [topKey, lenderMetaSubMap] of Object.entries(metaMap)) {
20592
+ if (!topKey.startsWith(expectedPrefix)) continue;
20593
+ for (const [marketUid, meta] of Object.entries(
20594
+ lenderMetaSubMap
20595
+ )) {
20596
+ flatMeta[marketUid] = meta;
20597
+ }
20598
+ }
20599
+ }
20603
20600
  const oracleEntries = aaveV4Oracles()?.[lender]?.[chainId] ?? [];
20604
20601
  const spokeReserveToUnderlying = /* @__PURE__ */ new Map();
20605
20602
  for (const oe of oracleEntries) {
@@ -20614,12 +20611,16 @@ var getAaveV4UserDataConverter = (lender, chainId, account, metaMap) => {
20614
20611
  for (const spokeEntry of spokes) {
20615
20612
  const spokeAddr = spokeEntry.spoke;
20616
20613
  if (!spokeAddr || spokeAddr === "0x" || spokeAddr.length <= 2) continue;
20617
- const reserves = reservesMap[spokeAddr.toLowerCase()] ?? reservesMap[spokeAddr] ?? [];
20614
+ const spokeAddrLc = spokeAddr.toLowerCase();
20615
+ const spokeLenderKey = aaveV4SpokeLenderKey(lender, spokeAddrLc);
20616
+ const reserves = reservesMap[spokeAddrLc] ?? reservesMap[spokeAddr] ?? [];
20618
20617
  for (const entry of reserves) {
20619
20618
  const rid = typeof entry === "number" ? entry : entry.reserveId;
20620
- const underlying = ((typeof entry === "object" ? entry.underlying : void 0) ?? spokeReserveToUnderlying.get(`${spokeAddr.toLowerCase()}:${rid}`) ?? "").toLowerCase();
20619
+ const underlying = ((typeof entry === "object" ? entry.underlying : void 0) ?? spokeReserveToUnderlying.get(`${spokeAddrLc}:${rid}`) ?? "").toLowerCase();
20621
20620
  reserveEntries.push({
20622
20621
  spokeAddr,
20622
+ spokeAddrLc,
20623
+ spokeLenderKey,
20623
20624
  reserveId: rid,
20624
20625
  underlying
20625
20626
  });
@@ -20631,23 +20632,14 @@ var getAaveV4UserDataConverter = (lender, chainId, account, metaMap) => {
20631
20632
  if (data.length !== expectedNumberOfCalls) {
20632
20633
  return void 0;
20633
20634
  }
20634
- const lendingPositions = {};
20635
- const underlyingToUid = /* @__PURE__ */ new Map();
20636
- if (metaMap) {
20637
- for (const [uid, meta] of Object.entries(metaMap)) {
20638
- const addr = (meta?.underlying ?? "").toLowerCase();
20639
- if (addr) underlyingToUid.set(addr, uid);
20640
- }
20641
- }
20642
- let totalDebt24h = 0;
20643
- let totalDeposits24h = 0;
20635
+ const perSpoke = {};
20644
20636
  for (let i = 0; i < reserveEntries.length; i++) {
20645
- const { underlying, spokeAddr } = reserveEntries[i];
20646
- const key = underlying ? createMarketUid(chainId, lender, underlying) : underlyingToUid.get(underlying) ?? "";
20647
- const metaEntity = metaMap?.[key];
20637
+ const { underlying, spokeAddrLc, spokeLenderKey } = reserveEntries[i];
20638
+ if (!underlying) continue;
20639
+ const key = createMarketUid(chainId, spokeLenderKey, underlying);
20640
+ const metaEntity = flatMeta[key];
20648
20641
  if (!metaEntity) continue;
20649
20642
  const base = i * USER_CALLS_PER_RESERVE;
20650
- const spokeLc = spokeAddr.toLowerCase();
20651
20643
  const userPositionResult = data[base + 3];
20652
20644
  const userDynConfigKey = Number(
20653
20645
  userPositionResult?.dynamicConfigKey ?? 0
@@ -20657,26 +20649,34 @@ var getAaveV4UserDataConverter = (lender, chainId, account, metaMap) => {
20657
20649
  data,
20658
20650
  key,
20659
20651
  metaEntity,
20660
- spokeLc
20652
+ spokeAddrLc
20661
20653
  );
20662
20654
  if (!dataForAsset) continue;
20663
- dataForAsset.userConfigKey = `${spokeLc}:${userDynConfigKey}`;
20664
- totalDebt24h += addedDebt;
20665
- totalDeposits24h += addedDeposits;
20666
- lendingPositions[key] = dataForAsset;
20655
+ dataForAsset.userConfigKey = String(userDynConfigKey);
20656
+ const bucket = perSpoke[spokeLenderKey] ?? (perSpoke[spokeLenderKey] = {
20657
+ lendingPositions: {},
20658
+ totalDebt24h: 0,
20659
+ totalDeposits24h: 0
20660
+ });
20661
+ bucket.totalDebt24h += addedDebt;
20662
+ bucket.totalDeposits24h += addedDeposits;
20663
+ bucket.lendingPositions[key] = dataForAsset;
20667
20664
  }
20668
- const payload = {
20669
- chainId,
20670
- account,
20671
- lendingPositions,
20672
- rewards: []};
20673
- const userData = createAaveV4UserState(
20674
- payload,
20675
- metaMap,
20676
- totalDeposits24h,
20677
- totalDebt24h
20678
- );
20679
- return userData;
20665
+ const out = {};
20666
+ for (const [spokeLenderKey, bucket] of Object.entries(perSpoke)) {
20667
+ const payload = {
20668
+ chainId,
20669
+ account,
20670
+ lendingPositions: bucket.lendingPositions,
20671
+ rewards: []};
20672
+ out[spokeLenderKey] = createAaveV4UserState(
20673
+ payload,
20674
+ flatMeta,
20675
+ bucket.totalDeposits24h,
20676
+ bucket.totalDebt24h
20677
+ );
20678
+ }
20679
+ return out;
20680
20680
  },
20681
20681
  expectedNumberOfCalls
20682
20682
  ];
@@ -20738,7 +20738,7 @@ function createAaveV4Entry(base, data, key, meta, spokeAddr) {
20738
20738
  // src/lending/user-data/fetch-balances/parse.ts
20739
20739
  function getUserDataConverter(lender, chainId, account, params, meta) {
20740
20740
  if (isAaveV4Type(lender))
20741
- return getAaveV4UserDataConverter(lender, chainId, account, meta?.[lender]);
20741
+ return getAaveV4UserDataConverter(lender, chainId, account, meta);
20742
20742
  if (isYLDR(lender))
20743
20743
  return getYldrUserDataConverter(lender, chainId, account, meta?.[lender]);
20744
20744
  if (isAaveV2Type(lender))
@@ -25530,7 +25530,6 @@ function unflattenLenderData(pools) {
25530
25530
  if (!result[chainId].data[lender]) {
25531
25531
  result[chainId].data[lender] = {
25532
25532
  data: {},
25533
- eModes: {},
25534
25533
  chainId: String(chainId)
25535
25534
  };
25536
25535
  }
@@ -27292,7 +27291,7 @@ function generateLendingPairs(lenderData, prices, histPrices) {
27292
27291
  apr: totalApr,
27293
27292
  baseApr,
27294
27293
  rewardApr,
27295
- eMode: long.eMode?.category ?? 0,
27294
+ eMode: Number(leverageParams.eModeConfigId) || 0,
27296
27295
  eModeConfigId: leverageParams.eModeConfigId,
27297
27296
  borrowCollateralFactorLong: leverageParams.borrowCollateralFactorLong,
27298
27297
  collateralFactorLong: leverageParams.collateralFactorLong,
@@ -32339,15 +32338,15 @@ function parseAaveV4Results(data, meta, context) {
32339
32338
  try {
32340
32339
  const priceNum = Number(BigInt(rawPrice.toString())) / divisor;
32341
32340
  if (isNaN(priceNum) || priceNum === 0) continue;
32341
+ const spokeLenderKey = aaveV4SpokeLenderKey(meta.fork, entry.spoke);
32342
32342
  entries.push({
32343
32343
  asset: entry.underlying,
32344
32344
  price: priceNum,
32345
32345
  priceUSD: priceNum,
32346
- marketUid: createMarketUid(
32347
- chainId,
32348
- meta.fork,
32349
- `${entry.hub}:${entry.underlying}`
32350
- ),
32346
+ marketUid: createMarketUid(chainId, spokeLenderKey, entry.underlying),
32347
+ // Route into the per-spoke lender bucket so price entries live under
32348
+ // the same lender key as the lending data (mirrors Morpho's pattern).
32349
+ targetLender: spokeLenderKey,
32351
32350
  configId: entry.spoke
32352
32351
  });
32353
32352
  } catch {