@1delta/margin-fetcher 0.0.217 → 0.0.219

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/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, 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';
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';
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';
@@ -6278,7 +6278,8 @@ globalThis[GLOBAL_LENDER_DATA_KEY] = {
6278
6278
  aaveV4Hubs: {},
6279
6279
  aaveV4Spokes: {},
6280
6280
  aaveV4Reserves: {},
6281
- aaveV4Oracles: {}
6281
+ aaveV4Oracles: {},
6282
+ aaveV4Peripherals: {}
6282
6283
  };
6283
6284
  function getGlobalData2() {
6284
6285
  return globalThis[GLOBAL_LENDER_DATA_KEY];
@@ -8471,18 +8472,18 @@ var populateEModes32 = (borrowCollateralFactor, collateralFactor, collateralBitm
8471
8472
  data[e].borrowCollateralFactor = borrowCollateralFactor;
8472
8473
  data[e].debtDisabled = !!eModeConfigs[e];
8473
8474
  if (eModeConfigs[e]) {
8474
- data[e] = {
8475
- ...data[e],
8476
- category: e,
8477
- borrowCollateralFactor: eModeConfigs[e]?.borrowCollateralFactor ?? 0,
8478
- collateralFactor: eModeConfigs[e]?.collateralFactor ?? 0,
8479
- borrowFactor: 1,
8480
- collateralDisabled: !isReserveEnabledOnBitmap(
8481
- collateralBitmap[e],
8482
- assetIndex
8483
- ),
8484
- debtDisabled: !isReserveEnabledOnBitmap(debtBitmap[e], assetIndex)
8485
- };
8475
+ data[e].category = e;
8476
+ data[e].borrowCollateralFactor = eModeConfigs[e]?.borrowCollateralFactor ?? 0;
8477
+ data[e].collateralFactor = eModeConfigs[e]?.collateralFactor ?? 0;
8478
+ data[e].borrowFactor = 1;
8479
+ data[e].collateralDisabled = !isReserveEnabledOnBitmap(
8480
+ collateralBitmap[e],
8481
+ assetIndex
8482
+ );
8483
+ data[e].debtDisabled = !isReserveEnabledOnBitmap(
8484
+ debtBitmap[e],
8485
+ assetIndex
8486
+ );
8486
8487
  }
8487
8488
  }
8488
8489
  }
@@ -8777,65 +8778,61 @@ var getInitReservesDataConverter = (lender, chainId, prices, additionalYields, t
8777
8778
  return void 0;
8778
8779
  }
8779
8780
  const modeOne = 0;
8780
- let result = Object.assign(
8781
- {},
8782
- ...data[modeOne]?.map((dat) => {
8783
- const asset = dat?.underlying.toLowerCase();
8784
- const meta = tokenList[asset];
8785
- const totalDeposits = parseRawAmount(
8786
- dat?.totalSupply.toString(),
8787
- meta?.decimals
8788
- );
8789
- const totalDebt = parseRawAmount(
8790
- dat?.totalDebt.toString(),
8781
+ const result = {};
8782
+ data[modeOne]?.forEach((dat) => {
8783
+ const asset = dat?.underlying.toLowerCase();
8784
+ const meta = tokenList[asset];
8785
+ const totalDeposits = parseRawAmount(
8786
+ dat?.totalSupply.toString(),
8787
+ meta?.decimals
8788
+ );
8789
+ const totalDebt = parseRawAmount(
8790
+ dat?.totalDebt.toString(),
8791
+ meta.decimals
8792
+ );
8793
+ const oracleKey = toOracleKey(meta?.assetGroup) ?? toGenericPriceKey(asset, chainId);
8794
+ const price = prices[oracleKey];
8795
+ const liquidity = Number(totalDeposits) - Number(totalDebt);
8796
+ const poolId = underlyingToPoolMap.get(asset);
8797
+ const params = !!poolId ? { metadata: { poolId } } : void 0;
8798
+ if (!poolId) return;
8799
+ const marketUid = createMarketUid(chainId, lender, poolId);
8800
+ const name = INIT_POOL_NAME_OVERRIDES[poolId.toLowerCase()] ?? lenderShortName(lender) + " " + (meta?.symbol ?? "");
8801
+ result[asset] = {
8802
+ marketUid,
8803
+ name,
8804
+ poolId: asset,
8805
+ underlying: asset,
8806
+ asset: meta,
8807
+ borrowCap: parseRawAmount(
8808
+ dat?.borrowCap.toString(),
8791
8809
  meta.decimals
8792
- );
8793
- const oracleKey = toOracleKey(meta?.assetGroup) ?? toGenericPriceKey(asset, chainId);
8794
- const price = prices[oracleKey];
8795
- const liquidity = Number(totalDeposits) - Number(totalDebt);
8796
- const poolId = underlyingToPoolMap.get(asset);
8797
- const params = !!poolId ? { metadata: { poolId } } : void 0;
8798
- if (!poolId) return;
8799
- const marketUid = createMarketUid(chainId, lender, poolId);
8800
- const name = INIT_POOL_NAME_OVERRIDES[poolId.toLowerCase()] ?? lenderShortName(lender) + " " + (meta?.symbol ?? "");
8801
- return {
8802
- [asset]: {
8803
- marketUid,
8804
- name,
8805
- poolId: asset,
8806
- underlying: asset,
8807
- asset: meta,
8808
- borrowCap: parseRawAmount(
8809
- dat?.borrowCap.toString(),
8810
- meta.decimals
8811
- ),
8812
- canBurn: Boolean(dat?.canBurn),
8813
- canFlash: Boolean(dat?.canFlash),
8814
- canMint: Boolean(dat?.canMint),
8815
- canRepay: Boolean(dat?.canRepay),
8816
- totalDeposits,
8817
- totalDebt,
8818
- totalDepositsUSD: price * Number(totalDeposits),
8819
- totalDebtUSD: price * Number(totalDebt),
8820
- totalLiquidity: liquidity,
8821
- totalLiquidityUSD: liquidity * price,
8822
- depositRate: convertRateToApr(
8823
- Number(parseRawAmount(dat?.supplyRate.toString(), 18))
8824
- ),
8825
- variableBorrowRate: convertRateToApr(
8826
- Number(parseRawAmount(dat?.borrowRate.toString(), 18))
8827
- ),
8828
- stableBorrowRate: 0,
8829
- collateralActive: true,
8830
- intrinsicYield: additionalYields?.intrinsicYields?.[oracleKey] ?? 0,
8831
- rewards: [],
8832
- config: {},
8833
- borrowingEnabled: totalDebt !== "0",
8834
- params
8835
- }
8836
- };
8837
- })
8838
- );
8810
+ ),
8811
+ canBurn: Boolean(dat?.canBurn),
8812
+ canFlash: Boolean(dat?.canFlash),
8813
+ canMint: Boolean(dat?.canMint),
8814
+ canRepay: Boolean(dat?.canRepay),
8815
+ totalDeposits,
8816
+ totalDebt,
8817
+ totalDepositsUSD: price * Number(totalDeposits),
8818
+ totalDebtUSD: price * Number(totalDebt),
8819
+ totalLiquidity: liquidity,
8820
+ totalLiquidityUSD: liquidity * price,
8821
+ depositRate: convertRateToApr(
8822
+ Number(parseRawAmount(dat?.supplyRate.toString(), 18))
8823
+ ),
8824
+ variableBorrowRate: convertRateToApr(
8825
+ Number(parseRawAmount(dat?.borrowRate.toString(), 18))
8826
+ ),
8827
+ stableBorrowRate: 0,
8828
+ collateralActive: true,
8829
+ intrinsicYield: additionalYields?.intrinsicYields?.[oracleKey] ?? 0,
8830
+ rewards: [],
8831
+ config: {},
8832
+ borrowingEnabled: totalDebt !== "0",
8833
+ params
8834
+ };
8835
+ });
8839
8836
  let eModes = {};
8840
8837
  INIT_MODES.forEach((mode, index) => {
8841
8838
  data[index]?.forEach((multicallData) => {
@@ -8859,11 +8856,12 @@ var getInitReservesDataConverter = (lender, chainId, prices, additionalYields, t
8859
8856
  result[asset].config[mode] = modeData;
8860
8857
  });
8861
8858
  });
8862
- Object.entries(eModes).forEach(([modeId, data2]) => {
8863
- Object.entries(result)?.forEach(([key, _3]) => {
8859
+ Object.entries(eModes).forEach(([modeId, modeData]) => {
8860
+ Object.entries(result).forEach(([key, _3]) => {
8864
8861
  if (!result[key].config[modeId]) {
8865
- let mode = {
8866
- ...data2,
8862
+ result[key].config[modeId] = {
8863
+ label: modeData.label,
8864
+ category: modeData.category,
8867
8865
  debtDisabled: true,
8868
8866
  collateralDisabled: true,
8869
8867
  collateralFactor: 0,
@@ -8871,7 +8869,6 @@ var getInitReservesDataConverter = (lender, chainId, prices, additionalYields, t
8871
8869
  borrowFactor: 3402823669209385e5
8872
8870
  // disabled flag
8873
8871
  };
8874
- result[key].config[modeId] = mode;
8875
8872
  }
8876
8873
  });
8877
8874
  });
@@ -17899,12 +17896,20 @@ var getEulerV2ReservesDataConverter = (lender, chainId, prices, additionalYields
17899
17896
  // src/lending/public-data/aave-v4-type/publicCallBuild.ts
17900
17897
  var BASE_CALLS_PER_RESERVE = 5;
17901
17898
  var CALLS_PER_SPOKE_TAIL = 2;
17899
+ var MAX_HUB_ASSETS = 25;
17902
17900
  function isValidAddress(addr) {
17903
17901
  return !!addr && addr !== "0x" && addr.length > 2;
17904
17902
  }
17905
17903
  function getSpokeReserves(reservesMap, spokeAddr) {
17906
17904
  return reservesMap[spokeAddr.toLowerCase()] ?? reservesMap[spokeAddr] ?? [];
17907
17905
  }
17906
+ function getReserveAssetId(entry) {
17907
+ if (typeof entry === "object" && entry != null) {
17908
+ const v = entry.assetId;
17909
+ if (typeof v === "number") return v;
17910
+ }
17911
+ return void 0;
17912
+ }
17908
17913
  function getDynamicConfigCount(spokeEntry) {
17909
17914
  const max = spokeEntry.dynamicConfigKeyMax ?? 0;
17910
17915
  return max + 1;
@@ -17914,8 +17919,6 @@ var buildAaveV4LenderReserveCall = (chainId, lender) => {
17914
17919
  const reservesMap = aaveV4Reserves()?.[lender]?.[chainId] ?? {};
17915
17920
  if (spokes.length === 0) return [];
17916
17921
  const calls = [];
17917
- const hubAssetKeys = /* @__PURE__ */ new Set();
17918
- const hubAssetList = [];
17919
17922
  for (const spokeEntry of spokes) {
17920
17923
  if (!isValidAddress(spokeEntry.spoke)) continue;
17921
17924
  const spokeAddr = spokeEntry.spoke;
@@ -17957,17 +17960,6 @@ var buildAaveV4LenderReserveCall = (chainId, lender) => {
17957
17960
  params: [rid, key]
17958
17961
  });
17959
17962
  }
17960
- if (typeof entry === "object" && spokeEntry.hub && entry.assetId !== void 0) {
17961
- const hubLc = spokeEntry.hub.toLowerCase();
17962
- const key = `${hubLc}:${entry.assetId}`;
17963
- if (!hubAssetKeys.has(key)) {
17964
- hubAssetKeys.add(key);
17965
- hubAssetList.push({
17966
- hub: hubLc,
17967
- assetId: entry.assetId
17968
- });
17969
- }
17970
- }
17971
17963
  }
17972
17964
  calls.push(
17973
17965
  {
@@ -17984,10 +17976,7 @@ var buildAaveV4LenderReserveCall = (chainId, lender) => {
17984
17976
  }
17985
17977
  for (const spokeEntry of spokes) {
17986
17978
  if (!isValidAddress(spokeEntry.spoke)) continue;
17987
- const reserves = getSpokeReserves(
17988
- reservesMap,
17989
- spokeEntry.spoke
17990
- );
17979
+ const reserves = getSpokeReserves(reservesMap, spokeEntry.spoke);
17991
17980
  const rids = reserves.map(
17992
17981
  (e) => typeof e === "number" ? e : e.reserveId
17993
17982
  );
@@ -17999,24 +17988,47 @@ var buildAaveV4LenderReserveCall = (chainId, lender) => {
17999
17988
  });
18000
17989
  }
18001
17990
  }
18002
- for (const { hub, assetId } of hubAssetList) {
18003
- calls.push(
18004
- {
18005
- address: hub,
18006
- name: "getAsset",
18007
- params: [assetId]
18008
- },
18009
- {
18010
- address: hub,
18011
- name: "getAddedAssets",
18012
- params: [assetId]
18013
- },
18014
- {
18015
- address: hub,
18016
- name: "getAssetTotalOwed",
18017
- params: [assetId]
17991
+ const hubEntry = aaveV4Hubs()?.[lender]?.[chainId];
17992
+ if (hubEntry?.hub && isValidAddress(hubEntry.hub)) {
17993
+ const hubAddr = hubEntry.hub.toLowerCase();
17994
+ calls.push({
17995
+ address: hubAddr,
17996
+ name: "getAssetCount",
17997
+ params: []
17998
+ });
17999
+ for (let i = 0; i < MAX_HUB_ASSETS; i++) {
18000
+ calls.push(
18001
+ {
18002
+ address: hubAddr,
18003
+ name: "getAsset",
18004
+ params: [i]
18005
+ },
18006
+ {
18007
+ address: hubAddr,
18008
+ name: "getAddedAssets",
18009
+ params: [i]
18010
+ },
18011
+ {
18012
+ address: hubAddr,
18013
+ name: "getAssetTotalOwed",
18014
+ params: [i]
18015
+ }
18016
+ );
18017
+ }
18018
+ for (const spokeEntry of spokes) {
18019
+ if (!isValidAddress(spokeEntry.spoke)) continue;
18020
+ const spokeAddr = spokeEntry.spoke;
18021
+ const reserves = getSpokeReserves(reservesMap, spokeAddr);
18022
+ for (const entry of reserves) {
18023
+ const assetId = getReserveAssetId(entry);
18024
+ if (assetId == null) continue;
18025
+ calls.push({
18026
+ address: hubAddr,
18027
+ name: "getSpoke",
18028
+ params: [assetId, spokeAddr]
18029
+ });
18018
18030
  }
18019
- );
18031
+ }
18020
18032
  }
18021
18033
  return calls;
18022
18034
  };
@@ -18024,13 +18036,9 @@ var getAaveV4ExpectedCallCount = (chainId, lender) => {
18024
18036
  const spokes = aaveV4Spokes()?.[lender]?.[chainId] ?? [];
18025
18037
  const reservesMap = aaveV4Reserves()?.[lender]?.[chainId] ?? {};
18026
18038
  let count = 0;
18027
- const hubAssetKeys = /* @__PURE__ */ new Set();
18028
18039
  for (const spokeEntry of spokes) {
18029
18040
  if (!isValidAddress(spokeEntry.spoke)) continue;
18030
- const reserves = getSpokeReserves(
18031
- reservesMap,
18032
- spokeEntry.spoke
18033
- );
18041
+ const reserves = getSpokeReserves(reservesMap, spokeEntry.spoke);
18034
18042
  const dynConfigCount = getDynamicConfigCount(spokeEntry);
18035
18043
  count += reserves.length * (BASE_CALLS_PER_RESERVE + dynConfigCount) + CALLS_PER_SPOKE_TAIL;
18036
18044
  const rids = reserves.map(
@@ -18039,15 +18047,18 @@ var getAaveV4ExpectedCallCount = (chainId, lender) => {
18039
18047
  if (rids.length > 0 && isValidAddress(spokeEntry.oracle)) {
18040
18048
  count += 1;
18041
18049
  }
18042
- for (const entry of reserves) {
18043
- if (typeof entry === "object" && spokeEntry.hub && entry.assetId !== void 0) {
18044
- hubAssetKeys.add(
18045
- `${spokeEntry.hub.toLowerCase()}:${entry.assetId}`
18046
- );
18050
+ }
18051
+ const hubEntry = aaveV4Hubs()?.[lender]?.[chainId];
18052
+ if (hubEntry?.hub && isValidAddress(hubEntry.hub)) {
18053
+ count += 1 + MAX_HUB_ASSETS * 3;
18054
+ for (const spokeEntry of spokes) {
18055
+ if (!isValidAddress(spokeEntry.spoke)) continue;
18056
+ const reserves = getSpokeReserves(reservesMap, spokeEntry.spoke);
18057
+ for (const entry of reserves) {
18058
+ if (getReserveAssetId(entry) != null) count += 1;
18047
18059
  }
18048
18060
  }
18049
18061
  }
18050
- count += hubAssetKeys.size * 3;
18051
18062
  return count;
18052
18063
  };
18053
18064
 
@@ -18098,9 +18109,7 @@ function normalizeAaveV4(spokeDataList, chainId, lender, prices, additionalYield
18098
18109
  continue;
18099
18110
  const underlying = reserve.reserve.underlying.toLowerCase();
18100
18111
  const decimals = reserve.reserve.decimals;
18101
- const hubAddr = reserve.reserve.hub.toLowerCase();
18102
- const refAddress = `${hubAddr}:${underlying}`;
18103
- const marketUid = createMarketUidFn(chainId, lender, refAddress);
18112
+ const marketUid = createMarketUidFn(chainId, lender, underlying);
18104
18113
  const assetMeta = tokenList[underlying];
18105
18114
  const oracleKey = toOracleKeyFn(assetMeta?.assetGroup ?? null) ?? toGenericPriceKeyFn(underlying, chainId);
18106
18115
  let price = 0;
@@ -18135,6 +18144,8 @@ function normalizeAaveV4(spokeDataList, chainId, lender, prices, additionalYield
18135
18144
  const hubUtilization = hubTotalSupply > 0 ? hubTotalOwed / hubTotalSupply : 0;
18136
18145
  const feeRate = reserve.hubAsset.liquidityFee ? reserve.hubAsset.liquidityFee / BPS : 0;
18137
18146
  const depositRate = variableBorrowRate * hubUtilization * (1 - feeRate);
18147
+ const collateralRiskBps = reserve.config.collateralRisk || reserve.reserve.collateralRisk || 0;
18148
+ const riskPremiumThresholdBps = reserve.spokeBinding?.riskPremiumThreshold ?? 0;
18138
18149
  const config = {};
18139
18150
  for (const [keyStr, dynCfg] of Object.entries(
18140
18151
  reserve.dynamicConfigs
@@ -18162,47 +18173,85 @@ function normalizeAaveV4(spokeDataList, chainId, lender, prices, additionalYield
18162
18173
  debtDisabled: !reserve.config.borrowable || reserve.config.paused
18163
18174
  };
18164
18175
  }
18165
- data[marketUid] = {
18166
- marketUid,
18167
- name: lenderShortNameFn(lender) + " " + (assetMeta?.symbol ?? ""),
18168
- poolId: underlying,
18169
- underlying,
18170
- asset: assetMeta,
18171
- totalDeposits,
18172
- totalDebtStable: "0",
18173
- totalDebt,
18174
- totalLiquidity: liquidity,
18175
- totalDepositsUSD: totalDepositsNum * price,
18176
- totalDebtStableUSD: 0,
18177
- totalDebtUSD: totalDebtNum * price,
18178
- totalLiquidityUSD: liquidity * price,
18179
- depositRate,
18180
- variableBorrowRate,
18181
- stableBorrowRate: 0,
18182
- intrinsicYield: additionalYields?.intrinsicYields?.[oracleKey] ?? 0,
18183
- rewards: [],
18184
- decimals,
18185
- config,
18186
- collateralActive: Object.values(reserve.dynamicConfigs).some(
18187
- (c) => c.collateralFactor > 0
18188
- ),
18189
- borrowingEnabled: reserve.config.borrowable,
18190
- hasStable: false,
18191
- isActive: !reserve.config.paused,
18192
- isFrozen: reserve.config.frozen,
18193
- borrowCap: 0,
18194
- supplyCap: 0,
18195
- debtCeiling: 0,
18196
- params: {
18197
- metadata: {
18198
- spoke: spokeAddr,
18199
- hub: reserve.reserve.hub.toLowerCase(),
18200
- assetId: reserve.reserve.assetId,
18201
- reserveId: reserve.reserveId,
18202
- oracle: spokeData.oracle.toLowerCase()
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
18199
  }
18204
18200
  }
18205
- };
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
+ }
18206
18255
  }
18207
18256
  }
18208
18257
  return { data, chainId, eModes };
@@ -18223,8 +18272,6 @@ var getAaveV4ReservesDataConverter = (lender, chainId, prices, additionalYields,
18223
18272
  const reservesMap = aaveV4Reserves()?.[lender]?.[chainId] ?? {};
18224
18273
  let offset = 0;
18225
18274
  const spokeDataList = [];
18226
- const hubAssetKeys = /* @__PURE__ */ new Set();
18227
- const hubAssetList = [];
18228
18275
  for (const spokeEntry of spokes) {
18229
18276
  if (!isValidAddress2(spokeEntry.spoke)) continue;
18230
18277
  const spokeAddr = spokeEntry.spoke;
@@ -18286,17 +18333,6 @@ var getAaveV4ReservesDataConverter = (lender, chainId, prices, additionalYields,
18286
18333
  } else {
18287
18334
  drawnDebt = BigInt(rawDebt ?? 0);
18288
18335
  }
18289
- if (spokeEntry.hub && typeof entry === "object" && entry.assetId !== void 0) {
18290
- const hubLc = spokeEntry.hub.toLowerCase();
18291
- const key = `${hubLc}:${entry.assetId}`;
18292
- if (!hubAssetKeys.has(key)) {
18293
- hubAssetKeys.add(key);
18294
- hubAssetList.push({
18295
- hub: hubLc,
18296
- assetId: entry.assetId
18297
- });
18298
- }
18299
- }
18300
18336
  parsedReserves.push({
18301
18337
  reserveId,
18302
18338
  reserve,
@@ -18350,40 +18386,77 @@ var getAaveV4ReservesDataConverter = (lender, chainId, prices, additionalYields,
18350
18386
  }
18351
18387
  }
18352
18388
  }
18389
+ const hubEntry = aaveV4Hubs()?.[lender]?.[chainId];
18353
18390
  const hubAssetMap = /* @__PURE__ */ new Map();
18354
- for (let hi = 0; hi < hubAssetList.length; hi++) {
18355
- const baseIdx = offset + hi * 3;
18356
- const rawHubAsset = data[baseIdx];
18357
- const rawAddedAssets = data[baseIdx + 1];
18358
- const rawTotalOwed = data[baseIdx + 2];
18359
- if (!rawHubAsset || rawHubAsset === "0x") continue;
18360
- const underlying = (rawHubAsset?.underlying ?? "").toLowerCase();
18361
- const key = underlying || `${hubAssetList[hi].hub}:${hubAssetList[hi].assetId}`;
18362
- hubAssetMap.set(key, {
18363
- liquidity: BigInt(rawHubAsset?.liquidity ?? 0),
18364
- realizedFees: BigInt(rawHubAsset?.realizedFees ?? 0),
18365
- decimals: Number(rawHubAsset?.decimals ?? 18),
18366
- addedShares: BigInt(rawHubAsset?.addedShares ?? 0),
18367
- swept: BigInt(rawHubAsset?.swept ?? 0),
18368
- premiumOffsetRay: BigInt(
18369
- rawHubAsset?.premiumOffsetRay ?? 0
18370
- ),
18371
- drawnShares: BigInt(rawHubAsset?.drawnShares ?? 0),
18372
- premiumShares: BigInt(rawHubAsset?.premiumShares ?? 0),
18373
- liquidityFee: Number(rawHubAsset?.liquidityFee ?? 0),
18374
- drawnIndex: BigInt(rawHubAsset?.drawnIndex ?? 0),
18375
- drawnRate: BigInt(rawHubAsset?.drawnRate ?? 0),
18376
- lastUpdateTimestamp: Number(
18377
- rawHubAsset?.lastUpdateTimestamp ?? 0
18378
- ),
18379
- underlying: rawHubAsset?.underlying ?? "",
18380
- irStrategy: rawHubAsset?.irStrategy ?? "",
18381
- reinvestmentController: rawHubAsset?.reinvestmentController ?? "",
18382
- feeReceiver: rawHubAsset?.feeReceiver ?? "",
18383
- deficitRay: BigInt(rawHubAsset?.deficitRay ?? 0),
18384
- totalAddedAssets: BigInt(rawAddedAssets ?? 0),
18385
- totalOwedAssets: BigInt(rawTotalOwed ?? 0)
18386
- });
18391
+ if (hubEntry?.hub && isValidAddress2(hubEntry.hub)) {
18392
+ const rawAssetCount = data[offset];
18393
+ offset += 1;
18394
+ const assetCount = Math.min(
18395
+ Number(rawAssetCount ?? 0),
18396
+ MAX_HUB_ASSETS
18397
+ );
18398
+ for (let i = 0; i < MAX_HUB_ASSETS; i++) {
18399
+ const baseIdx = offset + i * 3;
18400
+ const rawHubAsset = data[baseIdx];
18401
+ const rawAddedAssets = data[baseIdx + 1];
18402
+ const rawTotalOwed = data[baseIdx + 2];
18403
+ if (i >= assetCount || !rawHubAsset || rawHubAsset === "0x")
18404
+ continue;
18405
+ const underlying = (rawHubAsset?.underlying ?? "").toLowerCase();
18406
+ if (!underlying) continue;
18407
+ hubAssetMap.set(underlying, {
18408
+ liquidity: BigInt(rawHubAsset?.liquidity ?? 0),
18409
+ realizedFees: BigInt(rawHubAsset?.realizedFees ?? 0),
18410
+ decimals: Number(rawHubAsset?.decimals ?? 18),
18411
+ addedShares: BigInt(rawHubAsset?.addedShares ?? 0),
18412
+ swept: BigInt(rawHubAsset?.swept ?? 0),
18413
+ premiumOffsetRay: BigInt(
18414
+ rawHubAsset?.premiumOffsetRay ?? 0
18415
+ ),
18416
+ drawnShares: BigInt(rawHubAsset?.drawnShares ?? 0),
18417
+ premiumShares: BigInt(rawHubAsset?.premiumShares ?? 0),
18418
+ liquidityFee: Number(rawHubAsset?.liquidityFee ?? 0),
18419
+ drawnIndex: BigInt(rawHubAsset?.drawnIndex ?? 0),
18420
+ drawnRate: BigInt(rawHubAsset?.drawnRate ?? 0),
18421
+ lastUpdateTimestamp: Number(
18422
+ rawHubAsset?.lastUpdateTimestamp ?? 0
18423
+ ),
18424
+ underlying: rawHubAsset?.underlying ?? "",
18425
+ irStrategy: rawHubAsset?.irStrategy ?? "",
18426
+ reinvestmentController: rawHubAsset?.reinvestmentController ?? "",
18427
+ feeReceiver: rawHubAsset?.feeReceiver ?? "",
18428
+ deficitRay: BigInt(rawHubAsset?.deficitRay ?? 0),
18429
+ totalAddedAssets: BigInt(rawAddedAssets ?? 0),
18430
+ totalOwedAssets: BigInt(rawTotalOwed ?? 0)
18431
+ });
18432
+ }
18433
+ offset += MAX_HUB_ASSETS * 3;
18434
+ for (const spokeData of spokeDataList) {
18435
+ const spokeReservesMeta = getSpokeReserves2(
18436
+ reservesMap,
18437
+ spokeData.spoke
18438
+ );
18439
+ for (let ri = 0; ri < spokeReservesMeta.length; ri++) {
18440
+ const meta = spokeReservesMeta[ri];
18441
+ const assetId = typeof meta === "object" && meta != null ? meta.assetId : void 0;
18442
+ if (typeof assetId !== "number") continue;
18443
+ const rawBinding = data[offset];
18444
+ offset += 1;
18445
+ if (!rawBinding || rawBinding === "0x") continue;
18446
+ const binding = {
18447
+ riskPremiumThreshold: Number(
18448
+ rawBinding?.riskPremiumThreshold ?? 0
18449
+ ),
18450
+ active: Boolean(rawBinding?.active ?? false),
18451
+ halted: Boolean(rawBinding?.halted ?? false)
18452
+ };
18453
+ const targetReserveId = typeof meta === "number" ? meta : meta.reserveId;
18454
+ const target = spokeData.reserves.find(
18455
+ (r) => r.reserveId === targetReserveId
18456
+ );
18457
+ if (target) target.spokeBinding = binding;
18458
+ }
18459
+ }
18387
18460
  }
18388
18461
  for (const spokeData of spokeDataList) {
18389
18462
  for (const reserve of spokeData.reserves) {
@@ -18396,7 +18469,6 @@ var getAaveV4ReservesDataConverter = (lender, chainId, prices, additionalYields,
18396
18469
  }
18397
18470
  }
18398
18471
  }
18399
- const hubEntry = aaveV4Hubs()?.[lender]?.[chainId];
18400
18472
  const expectedHub = hubEntry?.hub;
18401
18473
  return normalizeAaveV4(
18402
18474
  spokeDataList,
@@ -18549,7 +18621,7 @@ var getLenderPublicData = async (chainId, lenders, prices, additionalYields, mul
18549
18621
  const abi = getAbi(lender);
18550
18622
  const callData = buildLenderCall(chainId, lender);
18551
18623
  const mappedCalls = callData.map((call) => ({ call, abi: call.abi ?? abi }));
18552
- calls = [...calls, ...mappedCalls];
18624
+ calls.push(...mappedCalls);
18553
18625
  }
18554
18626
  const [rawResults, list] = await Promise.all([
18555
18627
  multicallRetry({
@@ -18558,7 +18630,7 @@ var getLenderPublicData = async (chainId, lenders, prices, additionalYields, mul
18558
18630
  abi: calls.map((call) => call.abi),
18559
18631
  batchSize: chainId === Chain.ETHEREUM_MAINNET ? 500 : void 0
18560
18632
  }),
18561
- await tokenList()
18633
+ tokenList()
18562
18634
  ]);
18563
18635
  const invalidLenders = [];
18564
18636
  let lenderData = {};
@@ -18579,7 +18651,7 @@ var getLenderPublicData = async (chainId, lenders, prices, additionalYields, mul
18579
18651
  if (!convertedData) {
18580
18652
  invalidLenders.push(lender);
18581
18653
  } else {
18582
- lenderData = { ...lenderData, ...convertedData };
18654
+ Object.assign(lenderData, convertedData);
18583
18655
  }
18584
18656
  } else {
18585
18657
  if (!convertedData) {
@@ -18652,9 +18724,7 @@ var getLenderPublicDataViaApi = async (chainId, lenders, prices, additionalYield
18652
18724
  additionalYields,
18653
18725
  list
18654
18726
  );
18655
- Object.keys(converted).forEach((marketId) => {
18656
- lenderData[marketId] = converted[marketId];
18657
- });
18727
+ Object.assign(lenderData, converted);
18658
18728
  } else {
18659
18729
  lenderData[lender] = convertLenderDataFromApi(
18660
18730
  lender,
@@ -20283,12 +20353,72 @@ function resolveV4Config(configs, userConfigKey) {
20283
20353
  const spokeAddr = key.split(":")[0];
20284
20354
  return { config, spokeAddr };
20285
20355
  }
20286
- function getConfigScopedPrice(meta, spokeAddr, configPriceMap) {
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
+ }
20287
20362
  return getOraclePrice(meta);
20288
20363
  }
20289
- function createAaveV4UserState(payload, lenderData, totalDeposits24h = 0, totalDebt24h = 0, configPriceMap) {
20364
+ function createAaveV4UserState(payload, lenderData, totalDeposits24h = 0, totalDebt24h = 0) {
20290
20365
  const assetKeys = getMarketUidsFromMeta(lenderData);
20291
20366
  const { chainId, account } = payload;
20367
+ const collateralsBySpoke = /* @__PURE__ */ new Map();
20368
+ const debtBySpoke = /* @__PURE__ */ new Map();
20369
+ for (const marketUid of assetKeys) {
20370
+ const meta = lenderData?.[marketUid];
20371
+ const pos = payload.lendingPositions?.[marketUid];
20372
+ if (!meta || !pos) continue;
20373
+ const userConfigKey = pos.userConfigKey;
20374
+ if (!userConfigKey) continue;
20375
+ const spokeLc = userConfigKey.split(":")[0];
20376
+ if (!spokeLc) continue;
20377
+ const { config: userConfig2 } = resolveV4Config(
20378
+ meta.configs ?? null,
20379
+ userConfigKey
20380
+ );
20381
+ const collateralFactor = userConfig2?.collateralFactor ?? 0;
20382
+ const depositsUSDOracle = pos.depositsUSDOracle ?? pos.depositsUSD ?? 0;
20383
+ const debtUSDOracle = pos.debtUSDOracle ?? pos.debtUSD ?? 0;
20384
+ 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);
20391
+ }
20392
+ if (debtUSDOracle > 0) {
20393
+ debtBySpoke.set(
20394
+ spokeLc,
20395
+ (debtBySpoke.get(spokeLc) ?? 0) + debtUSDOracle
20396
+ );
20397
+ }
20398
+ }
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;
20407
+ let weightedSum = 0;
20408
+ for (const c of sorted) {
20409
+ if (debtLeft <= 0) break;
20410
+ const used = Math.min(c.valueUsd, debtLeft);
20411
+ weightedSum += used * c.riskBps;
20412
+ debtLeft -= used;
20413
+ }
20414
+ const covered = totalDebt - debtLeft;
20415
+ riskPremiumBpsBySpoke[spokeLc] = covered > 0 ? weightedSum / covered : 0;
20416
+ }
20417
+ const premiumMultiplierForSpoke = (spokeLc) => {
20418
+ if (!spokeLc) return 1;
20419
+ const bps = riskPremiumBpsBySpoke[spokeLc] ?? 0;
20420
+ return 1 + bps / 1e4;
20421
+ };
20292
20422
  let depositInterest = 0;
20293
20423
  let borrowInterest = 0;
20294
20424
  let rewardDepositAccrual = 0;
@@ -20319,10 +20449,11 @@ function createAaveV4UserState(payload, lenderData, totalDeposits24h = 0, totalD
20319
20449
  flags,
20320
20450
  configs
20321
20451
  } = lenderData[marketUid];
20322
- const { config: userConfigForAsset } = resolveV4Config(
20323
- configs,
20324
- pos.userConfigKey
20325
- );
20452
+ const { config: userConfigForAsset, spokeAddr: userSpokeAddr } = resolveV4Config(configs, pos.userConfigKey);
20453
+ const userPremiumMultiplier = premiumMultiplierForSpoke(userSpokeAddr);
20454
+ const effectiveVariableBorrowRate = (variableBorrowRate ?? 0) * userPremiumMultiplier;
20455
+ pos.variableBorrowRate = effectiveVariableBorrowRate;
20456
+ pos.riskPremiumBps = userSpokeAddr ? riskPremiumBpsBySpoke[userSpokeAddr] ?? 0 : 0;
20326
20457
  deposits += depositsUSD;
20327
20458
  debt += debtUSD + (debtStableUSD ?? 0);
20328
20459
  oracleDebt += debtUSDOracle + (pos.debtStableUSDOracle ?? debtStableUSD ?? 0);
@@ -20348,7 +20479,7 @@ function createAaveV4UserState(payload, lenderData, totalDeposits24h = 0, totalD
20348
20479
  collateralAllActive += (userConfigForAsset?.collateralFactor ?? 1) * depositsUSDOracle;
20349
20480
  }
20350
20481
  depositInterest += (depositRate ?? 0) * depositsUSD;
20351
- borrowInterest += debtUSD * (variableBorrowRate ?? 0) + (debtStableUSD ?? 0) * (stableBorrowRate ?? 0);
20482
+ borrowInterest += debtUSD * effectiveVariableBorrowRate + (debtStableUSD ?? 0) * (stableBorrowRate ?? 0);
20352
20483
  }
20353
20484
  const nav = deposits - debt;
20354
20485
  const balanceData2 = {
@@ -20395,7 +20526,7 @@ function createAaveV4UserState(payload, lenderData, totalDeposits24h = 0, totalD
20395
20526
  configs,
20396
20527
  pos ? pos.userConfigKey : void 0
20397
20528
  );
20398
- const price = getConfigScopedPrice(meta);
20529
+ const price = getConfigScopedPrice(meta, spokeAddr);
20399
20530
  const bcf = config?.borrowCollateralFactor ?? 1;
20400
20531
  const bf = config?.borrowFactor ?? 1;
20401
20532
  if (pos) {
@@ -20490,7 +20621,6 @@ var getAaveV4UserDataConverter = (lender, chainId, account, metaMap) => {
20490
20621
  reserveEntries.push({
20491
20622
  spokeAddr,
20492
20623
  reserveId: rid,
20493
- hub: (spokeEntry.hub ?? "").toLowerCase(),
20494
20624
  underlying
20495
20625
  });
20496
20626
  }
@@ -20512,28 +20642,25 @@ var getAaveV4UserDataConverter = (lender, chainId, account, metaMap) => {
20512
20642
  let totalDebt24h = 0;
20513
20643
  let totalDeposits24h = 0;
20514
20644
  for (let i = 0; i < reserveEntries.length; i++) {
20515
- const { hub, underlying, spokeAddr } = reserveEntries[i];
20516
- let key;
20517
- if (hub) {
20518
- key = createMarketUid(chainId, lender, `${hub}:${underlying}`);
20519
- } else {
20520
- key = underlyingToUid.get(underlying) ?? createMarketUid(chainId, lender, `:${underlying}`);
20521
- }
20645
+ const { underlying, spokeAddr } = reserveEntries[i];
20646
+ const key = underlying ? createMarketUid(chainId, lender, underlying) : underlyingToUid.get(underlying) ?? "";
20522
20647
  const metaEntity = metaMap?.[key];
20523
20648
  if (!metaEntity) continue;
20524
20649
  const base = i * USER_CALLS_PER_RESERVE;
20650
+ const spokeLc = spokeAddr.toLowerCase();
20651
+ const userPositionResult = data[base + 3];
20652
+ const userDynConfigKey = Number(
20653
+ userPositionResult?.dynamicConfigKey ?? 0
20654
+ );
20525
20655
  const { dataForAsset, addedDebt, addedDeposits } = createAaveV4Entry(
20526
20656
  base,
20527
20657
  data,
20528
20658
  key,
20529
- metaEntity
20659
+ metaEntity,
20660
+ spokeLc
20530
20661
  );
20531
20662
  if (!dataForAsset) continue;
20532
- const userPositionResult = data[base + 3];
20533
- const userDynConfigKey = Number(
20534
- userPositionResult?.dynamicConfigKey ?? 0
20535
- );
20536
- dataForAsset.userConfigKey = `${spokeAddr.toLowerCase()}:${userDynConfigKey}`;
20663
+ dataForAsset.userConfigKey = `${spokeLc}:${userDynConfigKey}`;
20537
20664
  totalDebt24h += addedDebt;
20538
20665
  totalDeposits24h += addedDeposits;
20539
20666
  lendingPositions[key] = dataForAsset;
@@ -20554,7 +20681,15 @@ var getAaveV4UserDataConverter = (lender, chainId, account, metaMap) => {
20554
20681
  expectedNumberOfCalls
20555
20682
  ];
20556
20683
  };
20557
- function createAaveV4Entry(base, data, key, meta) {
20684
+ function getConfigOraclePrice(meta, spokeAddr) {
20685
+ if (spokeAddr) {
20686
+ const byConfig = meta?.oraclePrice?.byConfig;
20687
+ const configPrice = byConfig?.[spokeAddr]?.oraclePriceUsd;
20688
+ if (configPrice != null && configPrice > 0) return configPrice;
20689
+ }
20690
+ return getOraclePrice(meta);
20691
+ }
20692
+ function createAaveV4Entry(base, data, key, meta, spokeAddr) {
20558
20693
  const rawSupply = data[base];
20559
20694
  const debtResult = data[base + 1];
20560
20695
  const statusResult = data[base + 2];
@@ -20575,7 +20710,7 @@ function createAaveV4Entry(base, data, key, meta) {
20575
20710
  const currentDebt = parseRawAmount(totalDebtRaw, decimals);
20576
20711
  const collateralEnabled = Boolean(statusResult?.[0]);
20577
20712
  const price = getDisplayPrice(meta);
20578
- const oPrice = getOraclePrice(meta);
20713
+ const oPrice = getConfigOraclePrice(meta, spokeAddr);
20579
20714
  const priceHist = meta?.price?.priceUsd24h ?? price;
20580
20715
  const dataForAsset = {
20581
20716
  marketUid: key,
@@ -25413,19 +25548,20 @@ function unflattenLenderData(pools) {
25413
25548
  return result;
25414
25549
  }
25415
25550
  var getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient3, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, retries = 3, logs = false) => {
25416
- let calls = [];
25417
25551
  const queries = organizeUserQueries(queriesRaw);
25418
- for (const query2 of queries) {
25419
- const abi = getAbi2(query2.lender);
25420
- const callData = await buildUserCall(
25421
- chainId,
25422
- query2.lender,
25423
- query2.account,
25424
- query2.params
25425
- );
25426
- const mappedCalls = callData.map((call) => ({ call, abi }));
25427
- calls = [...calls, ...mappedCalls];
25428
- }
25552
+ const builtCalls = await Promise.all(
25553
+ queries.map(async (query2) => {
25554
+ const abi = getAbi2(query2.lender);
25555
+ const callData = await buildUserCall(
25556
+ chainId,
25557
+ query2.lender,
25558
+ query2.account,
25559
+ query2.params
25560
+ );
25561
+ return callData.map((call) => ({ call, abi }));
25562
+ })
25563
+ );
25564
+ const calls = builtCalls.flat();
25429
25565
  return await multicallViemAbiArray(
25430
25566
  chainId,
25431
25567
  calls.map((call) => call.abi),
@@ -25440,20 +25576,21 @@ var getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient3, allowFa
25440
25576
  );
25441
25577
  };
25442
25578
  var prepareLenderUserDataRpcCalls = async (chainId, queriesRaw, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, blockTag = "latest", allowFailure = true) => {
25443
- let calls = [];
25444
25579
  const multicallAddress = getEvmChain(chainId).contracts?.multicall3?.address;
25445
25580
  const queries = organizeUserQueries(queriesRaw);
25446
- for (const query2 of queries) {
25447
- const abi = getAbi2(query2.lender);
25448
- const callData = await buildUserCall(
25449
- chainId,
25450
- query2.lender,
25451
- query2.account,
25452
- query2.params
25453
- );
25454
- const mappedCalls = callData.map((call) => ({ call, abi }));
25455
- calls = [...calls, ...mappedCalls];
25456
- }
25581
+ const builtCalls = await Promise.all(
25582
+ queries.map(async (query2) => {
25583
+ const abi = getAbi2(query2.lender);
25584
+ const callData = await buildUserCall(
25585
+ chainId,
25586
+ query2.lender,
25587
+ query2.account,
25588
+ query2.params
25589
+ );
25590
+ return callData.map((call) => ({ call, abi }));
25591
+ })
25592
+ );
25593
+ const calls = builtCalls.flat();
25457
25594
  const preparedCalls = prepareMulticallInputs(
25458
25595
  calls.map((c) => c.abi),
25459
25596
  calls.map((c) => c.call)
@@ -25743,6 +25880,12 @@ function resolveDebitDataKey(chainId, lender, tokenAddress, cToken) {
25743
25880
  function needsLenderApproval(params) {
25744
25881
  const { lender, lenderDebitData, tokenAddress, amount, chainId, cToken } = params;
25745
25882
  if (!lenderDebitData) return true;
25883
+ if (isAaveV4Type(lender)) {
25884
+ const key2 = (params.aaveV4Spoke ?? tokenAddress).toLowerCase();
25885
+ const entry2 = lenderDebitData[key2];
25886
+ if (!entry2 || entry2.amount === void 0) return true;
25887
+ return entry2.amount === 0n;
25888
+ }
25746
25889
  if (isInit(lender) || isMorphoType(lender) || isCompoundV3(lender)) {
25747
25890
  const entry2 = Object.values(lenderDebitData)[0];
25748
25891
  if (!entry2 || entry2.amount === void 0) return true;