@1delta/margin-fetcher 0.0.218 → 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];
@@ -17902,6 +17903,13 @@ function isValidAddress(addr) {
17902
17903
  function getSpokeReserves(reservesMap, spokeAddr) {
17903
17904
  return reservesMap[spokeAddr.toLowerCase()] ?? reservesMap[spokeAddr] ?? [];
17904
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
+ }
17905
17913
  function getDynamicConfigCount(spokeEntry) {
17906
17914
  const max = spokeEntry.dynamicConfigKeyMax ?? 0;
17907
17915
  return max + 1;
@@ -18007,6 +18015,20 @@ var buildAaveV4LenderReserveCall = (chainId, lender) => {
18007
18015
  }
18008
18016
  );
18009
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
+ });
18030
+ }
18031
+ }
18010
18032
  }
18011
18033
  return calls;
18012
18034
  };
@@ -18029,6 +18051,13 @@ var getAaveV4ExpectedCallCount = (chainId, lender) => {
18029
18051
  const hubEntry = aaveV4Hubs()?.[lender]?.[chainId];
18030
18052
  if (hubEntry?.hub && isValidAddress(hubEntry.hub)) {
18031
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;
18059
+ }
18060
+ }
18032
18061
  }
18033
18062
  return count;
18034
18063
  };
@@ -18044,10 +18073,9 @@ function toTokenNumber(raw, decimals) {
18044
18073
  return Number(raw) / 10 ** decimals;
18045
18074
  }
18046
18075
  var RAY2 = 1e27;
18047
- var SECONDS_PER_YEAR4 = 31536e3;
18048
18076
  function rayRateToApr(rateRay) {
18049
18077
  if (rateRay === 0n) return 0;
18050
- return (Number(rateRay) / RAY2 - 1) * SECONDS_PER_YEAR4 * 100;
18078
+ return Number(rateRay) / RAY2 * 100;
18051
18079
  }
18052
18080
  function normalizeAaveV4(spokeDataList, chainId, lender, prices, additionalYields, tokenList, lenderShortNameFn, createMarketUidFn, toOracleKeyFn, toGenericPriceKeyFn, expectedHub) {
18053
18081
  const data = {};
@@ -18116,6 +18144,8 @@ function normalizeAaveV4(spokeDataList, chainId, lender, prices, additionalYield
18116
18144
  const hubUtilization = hubTotalSupply > 0 ? hubTotalOwed / hubTotalSupply : 0;
18117
18145
  const feeRate = reserve.hubAsset.liquidityFee ? reserve.hubAsset.liquidityFee / BPS : 0;
18118
18146
  const depositRate = variableBorrowRate * hubUtilization * (1 - feeRate);
18147
+ const collateralRiskBps = reserve.config.collateralRisk || reserve.reserve.collateralRisk || 0;
18148
+ const riskPremiumThresholdBps = reserve.spokeBinding?.riskPremiumThreshold ?? 0;
18119
18149
  const config = {};
18120
18150
  for (const [keyStr, dynCfg] of Object.entries(
18121
18151
  reserve.dynamicConfigs
@@ -18143,16 +18173,31 @@ function normalizeAaveV4(spokeDataList, chainId, lender, prices, additionalYield
18143
18173
  debtDisabled: !reserve.config.borrowable || reserve.config.paused
18144
18174
  };
18145
18175
  }
18176
+ const collateralEnabledOnThisSpoke = Object.values(
18177
+ reserve.dynamicConfigs
18178
+ ).some((c) => c.collateralFactor > 0);
18146
18179
  if (data[marketUid]) {
18147
18180
  Object.assign(data[marketUid].config, config);
18148
18181
  if (!data[marketUid].collateralActive) {
18149
- data[marketUid].collateralActive = Object.values(reserve.dynamicConfigs).some(
18150
- (c) => c.collateralFactor > 0
18151
- );
18182
+ data[marketUid].collateralActive = collateralEnabledOnThisSpoke;
18152
18183
  }
18153
18184
  if (!data[marketUid].borrowingEnabled) {
18154
18185
  data[marketUid].borrowingEnabled = reserve.config.borrowable;
18155
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;
18199
+ }
18200
+ }
18156
18201
  } else {
18157
18202
  data[marketUid] = {
18158
18203
  marketUid,
@@ -18192,6 +18237,17 @@ function normalizeAaveV4(spokeDataList, chainId, lender, prices, additionalYield
18192
18237
  assetId: reserve.reserve.assetId,
18193
18238
  reserveId: reserve.reserveId,
18194
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
+ }
18195
18251
  }
18196
18252
  }
18197
18253
  };
@@ -18375,6 +18431,32 @@ var getAaveV4ReservesDataConverter = (lender, chainId, prices, additionalYields,
18375
18431
  });
18376
18432
  }
18377
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
+ }
18378
18460
  }
18379
18461
  for (const spokeData of spokeDataList) {
18380
18462
  for (const reserve of spokeData.reserves) {
@@ -20282,6 +20364,61 @@ function getConfigScopedPrice(meta, spokeAddr) {
20282
20364
  function createAaveV4UserState(payload, lenderData, totalDeposits24h = 0, totalDebt24h = 0) {
20283
20365
  const assetKeys = getMarketUidsFromMeta(lenderData);
20284
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
+ };
20285
20422
  let depositInterest = 0;
20286
20423
  let borrowInterest = 0;
20287
20424
  let rewardDepositAccrual = 0;
@@ -20312,10 +20449,11 @@ function createAaveV4UserState(payload, lenderData, totalDeposits24h = 0, totalD
20312
20449
  flags,
20313
20450
  configs
20314
20451
  } = lenderData[marketUid];
20315
- const { config: userConfigForAsset } = resolveV4Config(
20316
- configs,
20317
- pos.userConfigKey
20318
- );
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;
20319
20457
  deposits += depositsUSD;
20320
20458
  debt += debtUSD + (debtStableUSD ?? 0);
20321
20459
  oracleDebt += debtUSDOracle + (pos.debtStableUSDOracle ?? debtStableUSD ?? 0);
@@ -20341,7 +20479,7 @@ function createAaveV4UserState(payload, lenderData, totalDeposits24h = 0, totalD
20341
20479
  collateralAllActive += (userConfigForAsset?.collateralFactor ?? 1) * depositsUSDOracle;
20342
20480
  }
20343
20481
  depositInterest += (depositRate ?? 0) * depositsUSD;
20344
- borrowInterest += debtUSD * (variableBorrowRate ?? 0) + (debtStableUSD ?? 0) * (stableBorrowRate ?? 0);
20482
+ borrowInterest += debtUSD * effectiveVariableBorrowRate + (debtStableUSD ?? 0) * (stableBorrowRate ?? 0);
20345
20483
  }
20346
20484
  const nav = deposits - debt;
20347
20485
  const balanceData2 = {
@@ -25742,6 +25880,12 @@ function resolveDebitDataKey(chainId, lender, tokenAddress, cToken) {
25742
25880
  function needsLenderApproval(params) {
25743
25881
  const { lender, lenderDebitData, tokenAddress, amount, chainId, cToken } = params;
25744
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
+ }
25745
25889
  if (isInit(lender) || isMorphoType(lender) || isCompoundV3(lender)) {
25746
25890
  const entry2 = Object.values(lenderDebitData)[0];
25747
25891
  if (!entry2 || entry2.amount === void 0) return true;