@1delta/margin-fetcher 0.0.320 → 0.0.322

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
@@ -6,7 +6,7 @@ export { isAaveType, isAaveV2Type, isAaveV32Type, isAaveV3Type, isCompoundV3, is
6
6
  import { aavePools, compoundV3Pools, initConfig, morphoPools, compoundV2Pools, eulerVaults, siloMarkets, siloV2LenderKey, siloMarketsV3, siloV3LenderKey, aaveV4Spokes, aaveV4SpokeLenderKey, fluidResolvers, gearboxResolvers, dolomiteConfigs, midnightConfig, aaveReserves, compoundV3Reserves, morphoTypeMarkets, getSiloV2MarketEntry, getSiloV3MarketEntry, dolomiteEmode, aaveTokens, morphoTypeVaults, eulerConfigs, gearboxMarketCompressor, gearboxMarketConfigurators, gearboxV3LenderKey, midnightMarketsByChain, parseAaveV4SpokeLenderKey, gearboxAccountCompressor, compoundV2Tokens, aaveOracles, aaveOraclesConfig, compoundV2Oracles, compoundV2TokenArray, compoundV2OraclesConfig, compoundV3OraclesData, compoundV3BaseData, compoundV2Reserves, fetchTokenLists, fetchTokenList, aaveV4Oracles, resolveMidnightApiBase } from '@1delta/data-sdk';
7
7
  import lodash from 'lodash';
8
8
  import { getEvmClient, getEvmChain, getEvmClientUniversal, multicallRetryUniversal } from '@1delta/providers';
9
- import { MetaMorphoAbi, FluidLendingResolverAbi, FluidVaultResolverAbi, MoolahVaultAbi, MorphoLensAbi, AaveV4SpokeAbi, AaveV4OracleAbi, AaveV4HubAbi, DolomiteMarginAbi, GearboxMarketCompressorV310Abi, MorphoBlueAbi, MidnightAbi, GearboxCreditAccountCompressorV310Abi } from '@1delta/abis';
9
+ import { MetaMorphoAbi, FluidLendingResolverAbi, FluidVaultResolverAbi, FluidLiquidityResolverAbi, MoolahVaultAbi, MorphoLensAbi, AaveV4SpokeAbi, AaveV4OracleAbi, AaveV4HubAbi, DolomiteMarginAbi, GearboxMarketCompressorV310Abi, MorphoBlueAbi, MidnightAbi, GearboxCreditAccountCompressorV310Abi } from '@1delta/abis';
10
10
  export { MorphoLensAbi } from '@1delta/abis';
11
11
  import { prepareDebitDataMulticall, prepareLenderDebitMulticall, parseDebitDataResult, parseLenderDebitResult, getPermit2ContractAddress, getCompoundV3CometAddress as getCompoundV3CometAddress$1, getMorphoAddress, getAaveCollateralTokenAddress, getSiloHalfForUnderlying, InitMarginAddresses, getLstAcceptedInputs } from '@1delta/calldata-sdk';
12
12
  import { proxyNativeFetch } from '@1delta/proxy-fetch';
@@ -13447,7 +13447,18 @@ function getListaMarketDataConverter(lender, chainId, prices, additionalYields =
13447
13447
  rateCap: rateCap?.toString() ?? "0",
13448
13448
  rateFloor: rateFloor?.toString() ?? "0",
13449
13449
  // term menu for brokered markets (warm via fetchListaFixedTerms)
13450
- terms: fixedTermsForMarket
13450
+ terms: fixedTermsForMarket,
13451
+ // Canonical cross-protocol fixed-term descriptor (Lista + Midnight
13452
+ // share this shape). Lista: rolling-duration menu (no single
13453
+ // maturity), no market-level fees, and a per-loan early-repay
13454
+ // penalty (the concrete amount is position-level, on the loan's
13455
+ // `term.earlyRepayPenalty`).
13456
+ fixedTerm: {
13457
+ model: "lista",
13458
+ maturity: void 0,
13459
+ fees: {},
13460
+ earlyRepay: { kind: "penalty" }
13461
+ }
13451
13462
  }
13452
13463
  };
13453
13464
  data[m].chainId = chainId;
@@ -19880,6 +19891,11 @@ var buildFluidCall = (chainId, _lender) => {
19880
19891
  address: resolvers.vaultResolver,
19881
19892
  name: "getVaultsEntireData",
19882
19893
  params: []
19894
+ },
19895
+ {
19896
+ address: resolvers.liquidityResolver,
19897
+ name: "getAllOverallTokensData",
19898
+ params: []
19883
19899
  }
19884
19900
  ];
19885
19901
  };
@@ -19892,12 +19908,36 @@ var scaleFluidRate = (raw) => {
19892
19908
  if (raw === void 0 || raw === null) return 0;
19893
19909
  return Number(raw) / FLUID_RATE_SCALE;
19894
19910
  };
19911
+ var parseOverallTokensData = (overallTokensData) => {
19912
+ const out = {};
19913
+ if (!Array.isArray(overallTokensData)) return out;
19914
+ for (const td of overallTokensData) {
19915
+ const rateData = td?.rateData;
19916
+ if (!rateData) continue;
19917
+ const version = Number(rateData.version ?? 1);
19918
+ const rawToken = ((version === 2 ? rateData.rateDataV2?.token : rateData.rateDataV1?.token) ?? "").toString().toLowerCase();
19919
+ if (!rawToken || rawToken === zeroAddress) continue;
19920
+ const token = normalizeUnderlying(rawToken);
19921
+ const maxUtilizationRaw = Number(td.maxUtilization ?? 0);
19922
+ out[token] = {
19923
+ utilization: Number(td.lastStoredUtilization ?? 0) / BPS,
19924
+ fee: Number(td.fee ?? 0) / BPS,
19925
+ maxUtilization: maxUtilizationRaw > 0 ? maxUtilizationRaw / BPS : 1,
19926
+ totalSupply: (td.totalSupply ?? 0n).toString(),
19927
+ totalBorrow: (td.totalBorrow ?? 0n).toString(),
19928
+ borrowRate: scaleFluidRate(td.borrowRate),
19929
+ supplyRate: scaleFluidRate(td.supplyRate)
19930
+ };
19931
+ }
19932
+ return out;
19933
+ };
19895
19934
  var getFluidPublicDataConverter = (_lender, chainId, prices, additionalYields, tokenList = {}) => {
19896
- const expectedNumberOfCalls = 1;
19935
+ const expectedNumberOfCalls = 2;
19897
19936
  return [
19898
19937
  (data) => {
19899
19938
  if (data.length !== expectedNumberOfCalls) return void 0;
19900
- const [vaultEntireData] = data;
19939
+ const [vaultEntireData, overallTokensData] = data;
19940
+ const liquidityByToken = parseOverallTokensData(overallTokensData);
19901
19941
  const out = {};
19902
19942
  for (const vault of vaultEntireData ?? []) {
19903
19943
  const parsed = parseVault(
@@ -19905,7 +19945,8 @@ var getFluidPublicDataConverter = (_lender, chainId, prices, additionalYields, t
19905
19945
  chainId,
19906
19946
  prices,
19907
19947
  additionalYields,
19908
- tokenList
19948
+ tokenList,
19949
+ liquidityByToken
19909
19950
  );
19910
19951
  if (parsed) {
19911
19952
  out[parsed.lender] = {
@@ -19920,7 +19961,7 @@ var getFluidPublicDataConverter = (_lender, chainId, prices, additionalYields, t
19920
19961
  expectedNumberOfCalls
19921
19962
  ];
19922
19963
  };
19923
- function parseVault(vault, chainId, prices, additionalYields, tokenList) {
19964
+ function parseVault(vault, chainId, prices, additionalYields, tokenList, liquidityByToken = {}) {
19924
19965
  const vaultAddress = (vault.vault ?? "").toLowerCase();
19925
19966
  const constants = vault.constantVariables;
19926
19967
  const configs = vault.configs;
@@ -19970,9 +20011,14 @@ function parseVault(vault, chainId, prices, additionalYields, tokenList) {
19970
20011
  const liquidationPenalty = Number(configs.liquidationPenalty ?? 0) / BPS;
19971
20012
  const supplyRate = scaleFluidRate(rates.supplyRateVault);
19972
20013
  const borrowRate = scaleFluidRate(rates.borrowRateVault);
19973
- const utilization = totalSupply > 0 ? totalBorrow / totalSupply : 0;
20014
+ const collateralLiquidity = liquidityByToken[collateralAddress];
20015
+ const loanLiquidity = liquidityByToken[loanAddress];
19974
20016
  const data = {};
19975
- const collateralMarketUid = createMarketUid(chainId, lender, collateralAddress);
20017
+ const collateralMarketUid = createMarketUid(
20018
+ chainId,
20019
+ lender,
20020
+ collateralAddress
20021
+ );
19976
20022
  data[collateralMarketUid] = {
19977
20023
  marketUid: collateralMarketUid,
19978
20024
  name: "Collateral " + (collateralMeta?.symbol ?? ""),
@@ -19989,7 +20035,12 @@ function parseVault(vault, chainId, prices, additionalYields, tokenList) {
19989
20035
  totalDebtUSD: 0,
19990
20036
  totalLiquidityUSD: totalSupply * collateralPrice,
19991
20037
  borrowLiquidityUSD: 0,
19992
- utilization: lockupRatio,
20038
+ // IRM x-coordinate: the collateral token's Liquidity-layer utilization —
20039
+ // it drives the supply rate (borrowRate × utilization × (1 - fee)).
20040
+ utilization: collateralLiquidity?.utilization ?? 0,
20041
+ // Share of this vault's collateral currently locked below the LL
20042
+ // withdrawal limit (withdrawLimit / totalSupplyVault).
20043
+ lockupRatio,
19993
20044
  depositRate: supplyRate,
19994
20045
  // vault collateral earns the supply side rate
19995
20046
  variableBorrowRate: 0,
@@ -20035,7 +20086,9 @@ function parseVault(vault, chainId, prices, additionalYields, tokenList) {
20035
20086
  totalDebtUSD: totalBorrow * loanPrice,
20036
20087
  totalLiquidityUSD: borrowable * loanPrice,
20037
20088
  borrowLiquidityUSD: borrowable * loanPrice,
20038
- utilization,
20089
+ // IRM x-coordinate: the loan token's Liquidity-layer utilization — the
20090
+ // exact input the current borrow rate was computed from.
20091
+ utilization: loanLiquidity?.utilization ?? 0,
20039
20092
  depositRate: 0,
20040
20093
  variableBorrowRate: borrowRate,
20041
20094
  stableBorrowRate: 0,
@@ -20072,6 +20125,15 @@ function parseVault(vault, chainId, prices, additionalYields, tokenList) {
20072
20125
  expandDuration: Number(llSupply.expandDuration ?? 0),
20073
20126
  lastUpdateTimestamp: Number(llSupply.lastUpdateTimestamp ?? 0)
20074
20127
  } : void 0;
20128
+ const formatLiquidity = (state, decimals) => state ? {
20129
+ utilization: state.utilization,
20130
+ fee: state.fee,
20131
+ maxUtilization: state.maxUtilization,
20132
+ totalSupply: Number(parseRawAmount(state.totalSupply, decimals)),
20133
+ totalBorrow: Number(parseRawAmount(state.totalBorrow, decimals)),
20134
+ borrowRate: state.borrowRate,
20135
+ supplyRate: state.supplyRate
20136
+ } : void 0;
20075
20137
  return {
20076
20138
  lender,
20077
20139
  data,
@@ -20093,7 +20155,11 @@ function parseVault(vault, chainId, prices, additionalYields, tokenList) {
20093
20155
  oraclePriceLiquidate: configs.oraclePriceLiquidate?.toString(),
20094
20156
  isSmartCol: !!vault.isSmartCol,
20095
20157
  isSmartDebt: !!vault.isSmartDebt,
20096
- liquidityUserSupply
20158
+ liquidityUserSupply,
20159
+ liquidity: {
20160
+ supplyToken: formatLiquidity(collateralLiquidity, colDecimals),
20161
+ borrowToken: formatLiquidity(loanLiquidity, borrowDecimals)
20162
+ }
20097
20163
  }
20098
20164
  }
20099
20165
  };
@@ -20682,16 +20748,16 @@ var getAbi = (lender) => {
20682
20748
  if (isInit(lender)) return InitLensAbi;
20683
20749
  if (isMorphoType(lender)) return MorphoLensAbi;
20684
20750
  if (isEulerType(lender)) return vaultLensAbi;
20685
- if (isAaveV4Type(lender)) return [...AaveV4SpokeAbi, ...AaveV4OracleAbi, ...AaveV4HubAbi];
20751
+ if (isAaveV4Type(lender))
20752
+ return [...AaveV4SpokeAbi, ...AaveV4OracleAbi, ...AaveV4HubAbi];
20686
20753
  if (isSiloV2Type(lender))
20687
20754
  return [...SiloAbi, ...SiloLensAbi, ...InterestRateModelV2Abi];
20688
20755
  if (isSiloV3Type(lender))
20689
20756
  return [...SiloAbi, ...SiloLensAbi, ...InterestRateModelV2Abi];
20690
20757
  if (isFluid(lender))
20691
- return [...FluidVaultResolverAbi];
20758
+ return [...FluidVaultResolverAbi, ...FluidLiquidityResolverAbi];
20692
20759
  if (isDolomite(lender)) return [...DolomiteMarginAbi];
20693
- if (isGearboxV3(lender))
20694
- return [...GearboxMarketCompressorV310Abi];
20760
+ if (isGearboxV3(lender)) return [...GearboxMarketCompressorV310Abi];
20695
20761
  if (isSumerType(lender)) return [...SumerLensAbi, ...SumerComptrollerAbi];
20696
20762
  if (lender === Lender.TAKARA) return [...TakaraMarketStateAbi];
20697
20763
  if (isCompoundV2Type(lender)) return VenusLensAbi;
@@ -21021,11 +21087,6 @@ function convertMidnightMarketsToResponse(raw, chainId, prices = {}, _additional
21021
21087
  // Midnight is fixed-rate: expose the fixed borrow APR on stableBorrowRate
21022
21088
  // too, so fixed-rate consumers pick it up like a term product.
21023
21089
  stableBorrowRate: borrowAprPct,
21024
- // Mutable per-market fees (display convenience; authoritative raw values
21025
- // live on params.market). continuousFeeApr is a %/yr lender-side haircut;
21026
- // settlementFee is the effective fraction at the current TTM.
21027
- continuousFeeApr: continuousFeeAprPct,
21028
- settlementFee,
21029
21090
  intrinsicYield: 0,
21030
21091
  rewards: void 0,
21031
21092
  decimals: config.loanDecimals,
@@ -21121,13 +21182,23 @@ function convertMidnightMarketsToResponse(raw, chainId, prices = {}, _additional
21121
21182
  // Midnight-specific extras (consumed by calldata / worker-api resolvers)
21122
21183
  maturity: config.maturity,
21123
21184
  rcfThreshold: config.rcfThreshold,
21124
- // Mutable, on-chain-snapshotted fees. Raw values are authoritative for
21125
- // downstream ingest (yield-tracer); the derived `continuousFeeApr` (%)
21126
- // and `settlementFee` (fraction at current TTM) are convenience fields.
21185
+ // Raw on-chain-snapshotted fees authoritative for downstream ingest
21186
+ // (yield-tracer reads these verbatim).
21127
21187
  settlementFeeCbp: config.settlementFeeCbp,
21128
21188
  continuousFee: config.continuousFee,
21129
- continuousFeeApr: continuousFeeAprPct,
21130
- settlementFee,
21189
+ // Canonical cross-protocol fixed-term descriptor (Lista + Midnight share
21190
+ // this shape). Midnight: single calendar maturity, continuous +
21191
+ // settlement fees, and NO early-repay penalty (exit = buy debt units
21192
+ // back on the book at market price).
21193
+ fixedTerm: {
21194
+ model: "midnight",
21195
+ maturity: Number(config.maturity),
21196
+ fees: {
21197
+ continuousFeeApr: continuousFeeAprPct,
21198
+ settlementFee
21199
+ },
21200
+ earlyRepay: { kind: "none" }
21201
+ },
21131
21202
  enterGate: config.enterGate,
21132
21203
  liquidatorGate: config.liquidatorGate,
21133
21204
  collateralParams: config.collateralParams
@@ -22628,7 +22699,7 @@ var buildDolomiteUserCall = async (chainId, _lender, account, accountNumbers) =>
22628
22699
  params: [{ owner: account, number }]
22629
22700
  }));
22630
22701
  };
22631
- var midnightMarketCallCount = (collateralCount) => 1 + collateralCount;
22702
+ var midnightMarketCallCount = (collateralCount) => 2 + collateralCount;
22632
22703
  var buildMidnightUserCall = (chainId, _lender, account) => {
22633
22704
  const midnight = midnightConfig()?.[chainId]?.midnight;
22634
22705
  const markets = midnightMarketsByChain(chainId);
@@ -22640,6 +22711,29 @@ var buildMidnightUserCall = (chainId, _lender, account) => {
22640
22711
  name: "position",
22641
22712
  params: [market.marketId, account]
22642
22713
  });
22714
+ calls.push({
22715
+ address: midnight,
22716
+ name: "updatePositionView",
22717
+ params: [
22718
+ {
22719
+ chainId: BigInt(chainId),
22720
+ midnight,
22721
+ loanToken: market.loanToken,
22722
+ collateralParams: market.collateralParams.map((c) => ({
22723
+ token: c.token,
22724
+ lltv: BigInt(c.lltv),
22725
+ liquidationCursor: BigInt(c.liquidationCursor),
22726
+ oracle: c.oracle
22727
+ })),
22728
+ maturity: BigInt(market.maturity),
22729
+ rcfThreshold: BigInt(market.rcfThreshold),
22730
+ enterGate: market.enterGate,
22731
+ liquidatorGate: market.liquidatorGate
22732
+ },
22733
+ market.marketId,
22734
+ account
22735
+ ]
22736
+ });
22643
22737
  for (let index = 0; index < market.collateralParams.length; index++) {
22644
22738
  calls.push({
22645
22739
  address: midnight,
@@ -24909,6 +25003,21 @@ function readDebtUnits(positionResult) {
24909
25003
  return toBigInt10(positionResult.debt);
24910
25004
  return 0n;
24911
25005
  }
25006
+ function readUpdatedLender(updateResult) {
25007
+ if (Array.isArray(updateResult)) {
25008
+ return {
25009
+ credit: toBigInt10(updateResult[0]),
25010
+ pendingFee: toBigInt10(updateResult[1])
25011
+ };
25012
+ }
25013
+ if (updateResult && typeof updateResult === "object") {
25014
+ return {
25015
+ credit: toBigInt10(updateResult.newCredit),
25016
+ pendingFee: toBigInt10(updateResult.newPendingFee)
25017
+ };
25018
+ }
25019
+ return { credit: 0n, pendingFee: 0n };
25020
+ }
24912
25021
  var getMidnightUserDataConverter = (_lender, chainId, account, meta) => {
24913
25022
  const markets = midnightMarketsByChain(chainId);
24914
25023
  const totalCalls = markets.reduce(
@@ -24922,8 +25031,9 @@ var getMidnightUserDataConverter = (_lender, chainId, account, meta) => {
24922
25031
  let cursor = 0;
24923
25032
  for (const market of markets) {
24924
25033
  const positionResult = data[cursor];
25034
+ const updateResult = data[cursor + 1];
24925
25035
  const collateralResults = market.collateralParams.map(
24926
- (_c, i) => data[cursor + 1 + i]
25036
+ (_c, i) => data[cursor + 2 + i]
24927
25037
  );
24928
25038
  cursor += midnightMarketCallCount(market.collateralParams.length);
24929
25039
  const lenderKey = midnightLenderKey(market.marketId);
@@ -24938,24 +25048,40 @@ var getMidnightUserDataConverter = (_lender, chainId, account, meta) => {
24938
25048
  const debtUnits = readDebtUnits(positionResult);
24939
25049
  const debtStr = parseRawAmount(debtUnits.toString(), market.loanDecimals);
24940
25050
  const debtNum = Number(debtStr);
25051
+ const { credit, pendingFee } = readUpdatedLender(updateResult);
25052
+ const netCreditUnits = credit > pendingFee ? credit - pendingFee : 0n;
25053
+ const depositsStr = parseRawAmount(
25054
+ netCreditUnits.toString(),
25055
+ market.loanDecimals
25056
+ );
25057
+ const depositsNum = Number(depositsStr);
25058
+ const pendingFeeStr = parseRawAmount(
25059
+ pendingFee.toString(),
25060
+ market.loanDecimals
25061
+ );
24941
25062
  const posData = {};
24942
- let anyBalance = debtUnits > 0n;
24943
- let depositsUSD24h = 0;
25063
+ let anyBalance = debtUnits > 0n || netCreditUnits > 0n;
25064
+ let depositsUSD24h = depositsNum * loanPriceHist;
24944
25065
  posData[loanUid] = {
24945
25066
  marketUid: loanUid,
24946
25067
  underlying: loanAddr,
24947
- deposits: "0",
25068
+ deposits: depositsStr,
24948
25069
  debt: debtStr,
24949
25070
  debtStable: "0",
24950
- depositsUSD: 0,
25071
+ depositsUSD: depositsNum * loanDisplayPrice,
24951
25072
  debtUSD: debtNum * loanDisplayPrice,
24952
25073
  debtStableUSD: 0,
24953
- depositsUSDOracle: 0,
25074
+ depositsUSDOracle: depositsNum * loanOraclePrice,
24954
25075
  debtUSDOracle: debtNum * loanOraclePrice,
24955
25076
  debtStableUSDOracle: 0,
24956
25077
  stableBorrowRate: "0",
25078
+ // Supply on Midnight is a lend position, not collateral for a borrow.
24957
25079
  collateralEnabled: false,
24958
- claimableRewards: 0
25080
+ claimableRewards: 0,
25081
+ // Midnight-specific: accrued continuous fee owed by the lender (loan
25082
+ // units), already netted out of `deposits`. 0 on markets with no
25083
+ // continuous fee (the current live default).
25084
+ pendingFee: pendingFeeStr
24959
25085
  };
24960
25086
  market.collateralParams.forEach((c, i) => {
24961
25087
  const collAmt = toBigInt10(collateralResults[i]);
@@ -24968,19 +25094,19 @@ var getMidnightUserDataConverter = (_lender, chainId, account, meta) => {
24968
25094
  const collDisplayPrice = collMeta ? getDisplayPrice(collMeta) : 0;
24969
25095
  const collOraclePrice = collMeta ? getOraclePrice(collMeta) : 0;
24970
25096
  const collPriceHist = collMeta?.price?.priceUsd24h ?? collDisplayPrice;
24971
- const depositsStr = parseRawAmount(collAmt.toString(), collDec);
24972
- const depositsNum = Number(depositsStr);
24973
- depositsUSD24h += depositsNum * collPriceHist;
25097
+ const depositsStr2 = parseRawAmount(collAmt.toString(), collDec);
25098
+ const depositsNum2 = Number(depositsStr2);
25099
+ depositsUSD24h += depositsNum2 * collPriceHist;
24974
25100
  posData[collUid] = {
24975
25101
  marketUid: collUid,
24976
25102
  underlying: collAddr,
24977
- deposits: depositsStr,
25103
+ deposits: depositsStr2,
24978
25104
  debt: "0",
24979
25105
  debtStable: "0",
24980
- depositsUSD: depositsNum * collDisplayPrice,
25106
+ depositsUSD: depositsNum2 * collDisplayPrice,
24981
25107
  debtUSD: 0,
24982
25108
  debtStableUSD: 0,
24983
- depositsUSDOracle: depositsNum * collOraclePrice,
25109
+ depositsUSDOracle: depositsNum2 * collOraclePrice,
24984
25110
  debtUSDOracle: 0,
24985
25111
  debtStableUSDOracle: 0,
24986
25112
  stableBorrowRate: "0",
@@ -37135,7 +37261,12 @@ async function fetchFluidExposures(chainId, multicallRetry, prices, tokenList) {
37135
37261
  const rawVaults = await multicallRetry({
37136
37262
  chain: chainId,
37137
37263
  calls: vaultCalls,
37138
- abi: vaultCalls.map(() => FluidVaultResolverAbi)
37264
+ // buildFluidCall mixes vault-resolver and liquidity-resolver calls; the
37265
+ // merged ABI lets viem resolve each call by function name.
37266
+ abi: vaultCalls.map(() => [
37267
+ ...FluidVaultResolverAbi,
37268
+ ...FluidLiquidityResolverAbi
37269
+ ])
37139
37270
  });
37140
37271
  const [convert] = getFluidPublicDataConverter(
37141
37272
  "FLUID",