@1delta/margin-fetcher 0.0.334 → 0.0.336

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 { fetchTokenLists, fetchTokenList, aavePools, compoundV3Pools, initConfig, morphoPools, compoundV2Pools, eulerVaults, siloMarkets, siloV2LenderKey, siloMarketsV3, siloV3LenderKey, aaveV4Spokes, aaveV4SpokeLenderKey, fluidResolvers, gearboxResolvers, dolomiteConfigs, midnightConfig, termConfig, termMarketsByChain, exactlyConfig, liquityLendersByChain, riverLendersByChain, tellerConfigByChain, tellerPoolsByChain, aaveReserves, compoundV3Reserves, liquityConfigFor, liquityBranchesByChain, riverConfigFor, riverChainData, morphoTypeMarkets, resolveMidnightApiBase, resolveTermApiBase, getSiloV2MarketEntry, getSiloV3MarketEntry, dolomiteEmode, aaveTokens, morphoTypeVaults, eulerConfigs, gearboxMarketCompressor, gearboxMarketConfigurators, gearboxV3LenderKey, midnightMarketsByChain, parseAaveV4SpokeLenderKey, gearboxAccountCompressor, compoundV2Tokens, exactlyMarketsByChain, aaveOracles, aaveOraclesConfig, compoundV2Oracles, compoundV2TokenArray, compoundV2OraclesConfig, compoundV3OraclesData, compoundV3BaseData, compoundV2Reserves, aaveV4Oracles } from '@1delta/data-sdk';
7
7
  import lodash from 'lodash';
8
8
  import { getEvmClient, multicallRetryUniversal, getEvmChain, getEvmClientUniversal } from '@1delta/providers';
9
- import { LiquityTroveManagerAbi, LiquityActivePoolAbi, LiquityStabilityPoolAbi, LiquityPriceFeedAbi, LiquitySortedTrovesAbi, RiverTroveManagerAbi, RiverStabilityPoolAbi, MetaMorphoAbi, ExactlyPreviewerAbi, ExactlyAuditorAbi, LenderCommitmentGroupAbi, TellerMarketRegistryAbi, TellerV2Abi, FluidLendingResolverAbi, FluidVaultResolverAbi, FluidLiquidityResolverAbi, MoolahVaultAbi, MorphoLensAbi, AaveV4SpokeAbi, AaveV4OracleAbi, AaveV4HubAbi, DolomiteMarginAbi, GearboxMarketCompressorV310Abi, MorphoBlueAbi, MidnightAbi, TermRepoTokenAbi, TermRepoServicerAbi, TermRepoCollateralManagerAbi, LiquityTroveNFTAbi, LiquityCollSurplusPoolAbi, TellerCollateralManagerAbi, GearboxCreditAccountCompressorV310Abi, TermPriceConsumerAbi } from '@1delta/abis';
9
+ import { LiquityTroveManagerAbi, LiquityActivePoolAbi, LiquityStabilityPoolAbi, LiquityPriceFeedAbi, LiquitySortedTrovesAbi, RiverTroveManagerAbi, RiverStabilityPoolAbi, TellerMarketRegistryAbi, TellerV2Abi, MetaMorphoAbi, ExactlyPreviewerAbi, ExactlyAuditorAbi, LenderCommitmentGroupAbi, FluidLendingResolverAbi, FluidVaultResolverAbi, FluidLiquidityResolverAbi, MoolahVaultAbi, MorphoLensAbi, AaveV4SpokeAbi, AaveV4OracleAbi, AaveV4HubAbi, DolomiteMarginAbi, GearboxMarketCompressorV310Abi, MorphoBlueAbi, MidnightAbi, TermRepoTokenAbi, TermRepoServicerAbi, TermRepoCollateralManagerAbi, LiquityTroveNFTAbi, LiquityCollSurplusPoolAbi, TellerCollateralManagerAbi, GearboxCreditAccountCompressorV310Abi, TermPriceConsumerAbi } 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';
@@ -21300,20 +21300,25 @@ function convertMidnightMarketsToResponse(raw, chainId, prices = {}, _additional
21300
21300
  const cursor = toBigIntOr0(c.liquidationCursor);
21301
21301
  const liquidationPenalty = cursor > 0n ? midnightLiquidationPenaltyNumber(toBigIntOr0(c.lltv), cursor) : liquidationPenaltyFromLltv(ltv);
21302
21302
  const collUid = createMarketUid(chainId, m, collAddr);
21303
+ const collAsset = tokens[collAddr];
21304
+ const collKey = toOracleKey(collAsset?.assetGroup) || toGenericPriceKey(collAddr, chainId);
21305
+ const collPrice = prices[collKey] ?? 0;
21306
+ const collCapacityUSD = ltv > 0 ? borrowLiquidity * loanPrice / ltv : borrowLiquidity * loanPrice;
21307
+ const collCapacity = collPrice > 0 ? collCapacityUSD / collPrice : 0;
21303
21308
  entry.data[collUid] = {
21304
21309
  marketUid: collUid,
21305
21310
  name: "Collateral " + (tokens[collAddr]?.symbol ?? ""),
21306
21311
  poolId: collAddr,
21307
21312
  underlying: collAddr,
21308
21313
  asset: currencyFor(collAddr, c.decimals, tokens),
21309
- totalDeposits: 0,
21314
+ totalDeposits: collCapacity,
21310
21315
  totalDebtStable: 0,
21311
21316
  totalDebt: 0,
21312
- totalLiquidity: 0,
21317
+ totalLiquidity: collCapacity,
21313
21318
  borrowLiquidity: 0,
21314
- totalLiquidityUSD: 0,
21319
+ totalLiquidityUSD: collCapacityUSD,
21315
21320
  borrowLiquidityUSD: 0,
21316
- totalDepositsUSD: 0,
21321
+ totalDepositsUSD: collCapacityUSD,
21317
21322
  totalDebtStableUSD: 0,
21318
21323
  totalDebtUSD: 0,
21319
21324
  utilization: 0,
@@ -22661,8 +22666,9 @@ function convertRiverMarketsToResponse(raw, chainId, prices = {}, _additionalYie
22661
22666
  }
22662
22667
  return out;
22663
22668
  }
22664
- var READS_PER_POOL = 6;
22665
- var READS_PER_MARKET = 2;
22669
+ var READS_PER_POOL = 7;
22670
+ var READS_PER_MARKET = 4;
22671
+ var MARKET_PHASE_ABI = [...TellerMarketRegistryAbi, ...TellerV2Abi];
22666
22672
  async function fetchTellerMarkets(chainId) {
22667
22673
  const pools = tellerPoolsByChain(chainId);
22668
22674
  if (pools.length === 0) return { chainId, pools: [] };
@@ -22679,7 +22685,12 @@ async function fetchTellerMarkets(chainId) {
22679
22685
  params: [onePrincipal]
22680
22686
  },
22681
22687
  { address: p.pool, name: "getMaxLoanDuration", params: [] },
22682
- { address: p.pool, name: "getMarketId", params: [] }
22688
+ { address: p.pool, name: "getMarketId", params: [] },
22689
+ // ERC-4626 CURRENT principal TVL (V2/V3). `totalPrincipalTokensCommitted`
22690
+ // is a CUMULATIVE lifetime counter, NOT the current balance — using it
22691
+ // overstates deposits by orders of magnitude. `totalAssets` reverts on V1
22692
+ // Smart pools (→ null), where we fall back to the committed counter.
22693
+ { address: p.pool, name: "totalAssets", params: [] }
22683
22694
  ];
22684
22695
  });
22685
22696
  let results = [];
@@ -22719,10 +22730,13 @@ async function fetchTellerMarkets(chainId) {
22719
22730
  minRateBps: num6(base + 2),
22720
22731
  collateralPerPrincipal: big4(base + 3),
22721
22732
  maxLoanDuration: num6(base + 4),
22722
- marketId: big4(base + 5)
22733
+ marketId: big4(base + 5),
22734
+ totalAssets: big4(base + 6)
22723
22735
  };
22724
22736
  });
22725
22737
  const attByMarket = /* @__PURE__ */ new Map();
22738
+ let protocolFeeBps;
22739
+ const proto = tellerConfigByChain(chainId);
22726
22740
  if (marketRegistry) {
22727
22741
  const uniqueMarkets = [
22728
22742
  ...new Set(
@@ -22730,28 +22744,45 @@ async function fetchTellerMarkets(chainId) {
22730
22744
  )
22731
22745
  ];
22732
22746
  if (uniqueMarkets.length > 0) {
22733
- const mCalls = uniqueMarkets.flatMap((m) => [
22734
- {
22735
- address: marketRegistry,
22736
- name: "getMarketAttestationRequirements",
22737
- params: [BigInt(m)]
22738
- },
22739
- { address: marketRegistry, name: "isMarketOpen", params: [BigInt(m)] }
22740
- ]);
22747
+ const mCalls = [
22748
+ { address: proto?.tellerV2 ?? marketRegistry, name: "protocolFee", params: [] },
22749
+ ...uniqueMarkets.flatMap((m) => [
22750
+ {
22751
+ address: marketRegistry,
22752
+ name: "getMarketAttestationRequirements",
22753
+ params: [BigInt(m)]
22754
+ },
22755
+ { address: marketRegistry, name: "isMarketOpen", params: [BigInt(m)] },
22756
+ { address: marketRegistry, name: "getMarketplaceFee", params: [BigInt(m)] },
22757
+ {
22758
+ address: marketRegistry,
22759
+ name: "getPaymentDefaultDuration",
22760
+ params: [BigInt(m)]
22761
+ }
22762
+ ])
22763
+ ];
22741
22764
  try {
22742
22765
  const mRes = await multicallRetryUniversal({
22743
22766
  chain: chainId,
22744
22767
  calls: mCalls,
22745
- abi: TellerMarketRegistryAbi,
22768
+ abi: MARKET_PHASE_ABI,
22746
22769
  allowFailure: true
22747
22770
  });
22771
+ const pf = mRes[0];
22772
+ protocolFeeBps = typeof pf === "bigint" || typeof pf === "number" ? Number(pf) : void 0;
22748
22773
  uniqueMarkets.forEach((m, i) => {
22749
- const att = mRes[i * READS_PER_MARKET];
22750
- const open = mRes[i * READS_PER_MARKET + 1];
22774
+ const base = 1 + i * READS_PER_MARKET;
22775
+ const att = mRes[base];
22776
+ const open = mRes[base + 1];
22777
+ const fee = mRes[base + 2];
22778
+ const dur = mRes[base + 3];
22751
22779
  const borrowerRequired = (att?.borrowerAttestationRequired ?? att?.[1]) === true;
22780
+ const asNum = (v) => typeof v === "bigint" || typeof v === "number" ? Number(v) : void 0;
22752
22781
  attByMarket.set(m, {
22753
22782
  requiresBorrowerAttestation: borrowerRequired,
22754
- marketOpen: open === false ? false : true
22783
+ marketOpen: open === false ? false : true,
22784
+ marketFeeBps: asNum(fee),
22785
+ paymentDefaultDuration: asNum(dur)
22755
22786
  });
22756
22787
  });
22757
22788
  } catch {
@@ -22763,7 +22794,10 @@ async function fetchTellerMarkets(chainId) {
22763
22794
  return {
22764
22795
  ...p,
22765
22796
  requiresBorrowerAttestation: att?.requiresBorrowerAttestation,
22766
- marketOpen: att?.marketOpen
22797
+ marketOpen: att?.marketOpen,
22798
+ marketFeeBps: att?.marketFeeBps,
22799
+ protocolFeeBps,
22800
+ paymentDefaultDuration: att?.paymentDefaultDuration
22767
22801
  };
22768
22802
  });
22769
22803
  return { chainId, pools: out };
@@ -22801,6 +22835,12 @@ function currencyFor6(address, decimals, symbol, tokens) {
22801
22835
  const lower = address.toLowerCase();
22802
22836
  return tokens[lower] ?? { address: lower, symbol, name: symbol, decimals };
22803
22837
  }
22838
+ function fmtDuration(sec) {
22839
+ if (sec == null || sec <= 0) return "a short window";
22840
+ if (sec < 3600) return `${Math.round(sec / 60)} minute${sec < 120 ? "" : "s"}`;
22841
+ if (sec < 86400) return `${Math.round(sec / 3600)} hour${sec < 7200 ? "" : "s"}`;
22842
+ return `${Math.round(sec / 86400)} day${sec < 172800 ? "" : "s"}`;
22843
+ }
22804
22844
  function priceFor(address, chainId, tokens, prices) {
22805
22845
  const lower = address.toLowerCase();
22806
22846
  const token = tokens[lower];
@@ -22822,7 +22862,10 @@ function convertTellerMarketsToResponse(raw, chainId, prices = {}, _additionalYi
22822
22862
  const principalPrice = priceFor(principalAddr, chainId, tokens, prices);
22823
22863
  const collateralPrice = priceFor(collateralAddr, chainId, tokens, prices);
22824
22864
  const borrowLiquidity = tellerToHuman(p.available, cfg.principalDecimals);
22825
- const totalDeposits = tellerToHuman(p.committed, cfg.principalDecimals);
22865
+ const totalDeposits = tellerToHuman(
22866
+ p.totalAssets ?? p.committed,
22867
+ cfg.principalDecimals
22868
+ );
22826
22869
  const totalDebt = Math.max(0, totalDeposits - borrowLiquidity);
22827
22870
  const utilization = totalDeposits > 0 ? totalDebt / totalDeposits : 0;
22828
22871
  const borrowApr = tellerBpsToPercent(p.minRateBps);
@@ -22953,11 +22996,31 @@ function convertTellerMarketsToResponse(raw, chainId, prices = {}, _additionalYi
22953
22996
  isActive: true,
22954
22997
  isFrozen: false
22955
22998
  };
22956
- const implications = [
22957
- "Fixed-term, fixed-APR loan: the rate is locked at borrow time for a duration you choose (up to the pool max).",
22958
- "TIME-based liquidation only \u2014 collateral is seized if a payment is missed past the market window. There is NO price-based liquidation and NO margin call.",
22959
- "Closing is a FULL repayment: it repays principal + interest and releases ALL collateral in one tx (no partial collateral withdrawal; a partial repay keeps the collateral escrowed)."
22960
- ];
22999
+ const marketFeeBps = p.marketFeeBps ?? 0;
23000
+ const protocolFeeBps = p.protocolFeeBps ?? 0;
23001
+ const originationFeeBps = marketFeeBps + protocolFeeBps;
23002
+ const originationFeePercent = originationFeeBps / 100;
23003
+ const graceSec = p.paymentDefaultDuration;
23004
+ const graceHuman = fmtDuration(graceSec);
23005
+ const ltvPct = ltv > 0 ? Math.round(ltv * 100) : void 0;
23006
+ const lossX = ltv > 0 ? (1 / ltv).toFixed(1) : void 0;
23007
+ const implications = [];
23008
+ implications.push(
23009
+ graceSec != null ? `\u26A0 FULL-COLLATERAL liquidation: after the loan term you have only a SHORT grace window (~${graceHuman}) to roll over or repay. Miss it and the loan DEFAULTS \u2014 a liquidator can seize your ENTIRE escrowed collateral, not just the amount owed.${lossX ? ` At ${ltvPct}% LTV that is ~${lossX}\xD7 the borrowed value lost.` : ""}` : `\u26A0 FULL-COLLATERAL liquidation: if you miss the rollover/repay deadline past the market's grace window, the loan DEFAULTS and your ENTIRE collateral can be seized \u2014 not just the amount owed.`
23010
+ );
23011
+ implications.push(
23012
+ "TIME-based liquidation only \u2014 NO price-based liquidation and NO margin call; the ONLY trigger is a missed payment past the deadline. Set a reminder to roll over or repay on time."
23013
+ );
23014
+ if (originationFeeBps > 0)
23015
+ implications.push(
23016
+ `Upfront origination fee of ${originationFeePercent}% is charged on the borrow (market ${marketFeeBps / 100}% + protocol ${protocolFeeBps / 100}%).`
23017
+ );
23018
+ implications.push(
23019
+ "Fixed-term, fixed-APR: the rate is locked at borrow time for a duration you choose (up to the pool max)."
23020
+ );
23021
+ implications.push(
23022
+ "Closing is a FULL repayment: it repays principal + interest and releases ALL collateral in one tx (a partial repay keeps the collateral escrowed)."
23023
+ );
22961
23024
  if (p.requiresBorrowerAttestation)
22962
23025
  implications.push(
22963
23026
  "This market requires borrower ATTESTATION \u2014 the borrower must be whitelisted by the market owner before borrowing."
@@ -22985,7 +23048,7 @@ function convertTellerMarketsToResponse(raw, chainId, prices = {}, _additionalYi
22985
23048
  fixedTerm: {
22986
23049
  model: "teller",
22987
23050
  maturity: void 0,
22988
- fees: {},
23051
+ fees: originationFeeBps > 0 ? { originationFeePercent } : {},
22989
23052
  earlyRepay: { kind: "none" },
22990
23053
  provider: { kind: "pool", address: cfg.pool.toLowerCase() }
22991
23054
  },
@@ -23001,6 +23064,13 @@ function convertTellerMarketsToResponse(raw, chainId, prices = {}, _additionalYi
23001
23064
  // UI/allocator). `marketOpen` = MarketRegistry.isMarketOpen.
23002
23065
  requiresBorrowerAttestation: p.requiresBorrowerAttestation,
23003
23066
  marketOpen: p.marketOpen,
23067
+ // Fees (bps + combined percent) — upfront origination fee on the borrow.
23068
+ marketFeeBps: p.marketFeeBps,
23069
+ protocolFeeBps: p.protocolFeeBps,
23070
+ originationFeePercent: originationFeeBps > 0 ? originationFeePercent : void 0,
23071
+ /** Grace window (secs) after the term before DEFAULT + full-collateral
23072
+ * liquidation. Can be very short (observed 300s = 5 min). */
23073
+ paymentDefaultDuration: p.paymentDefaultDuration,
23004
23074
  /** Human-readable caveats for the UI to surface (see above). */
23005
23075
  implications,
23006
23076
  minInterestRateBps: p.minRateBps ?? void 0,
@@ -39711,19 +39781,12 @@ function parseTellerResults(data, meta, context) {
39711
39781
  const principal = meta.principal;
39712
39782
  const collateral = meta.collateral;
39713
39783
  const lenderKey = tellerLenderKey(meta.pool);
39714
- const principalOracleKey = tokenList?.[principal]?.assetGroup ?? `${chainId}-${principal}`;
39715
- const principalUSD = usdPrices[principalOracleKey] ?? usdPrices[principal];
39716
- if (!principalUSD) return entries;
39717
- entries.push({
39718
- asset: principal,
39719
- price: 1,
39720
- priceUSD: principalUSD,
39721
- marketUid: createMarketUid(chainId, lenderKey, principal),
39722
- targetLender: lenderKey,
39723
- description: "Teller principal asset",
39724
- staticBase: true,
39725
- baseAsset: principal
39726
- });
39784
+ const usdOf = (addr) => {
39785
+ const key = tokenList?.[addr]?.assetGroup ?? `${chainId}-${addr}`;
39786
+ return usdPrices[key] ?? usdPrices[addr];
39787
+ };
39788
+ const principalUSD = usdOf(principal);
39789
+ const collateralUSD = usdOf(collateral);
39727
39790
  const rawCollateral = data?.[0];
39728
39791
  if (rawCollateral == null || rawCollateral === "0x") return entries;
39729
39792
  let equivalent;
@@ -39734,17 +39797,48 @@ function parseTellerResults(data, meta, context) {
39734
39797
  }
39735
39798
  if (equivalent <= 0n) return entries;
39736
39799
  const collateralDecimals = meta.collateralDecimals ?? tokenList?.[collateral]?.decimals ?? 18;
39737
- const priceCollateralInPrincipal = 10 ** collateralDecimals / Number(equivalent);
39738
- if (!(priceCollateralInPrincipal > 0)) return entries;
39739
- entries.push({
39740
- asset: collateral,
39741
- price: priceCollateralInPrincipal,
39742
- // raw: collateral price in principal terms
39743
- priceUSD: priceCollateralInPrincipal * principalUSD,
39744
- marketUid: createMarketUid(chainId, lenderKey, collateral),
39745
- targetLender: lenderKey,
39746
- baseAsset: principal
39747
- });
39800
+ const collPerPrincipal = Number(equivalent) / 10 ** collateralDecimals;
39801
+ if (!(collPerPrincipal > 0)) return entries;
39802
+ if (principalUSD) {
39803
+ const collateralPriceInPrincipal = 1 / collPerPrincipal;
39804
+ entries.push({
39805
+ asset: principal,
39806
+ price: 1,
39807
+ priceUSD: principalUSD,
39808
+ marketUid: createMarketUid(chainId, lenderKey, principal),
39809
+ targetLender: lenderKey,
39810
+ description: "Teller principal asset",
39811
+ staticBase: true,
39812
+ baseAsset: principal
39813
+ });
39814
+ entries.push({
39815
+ asset: collateral,
39816
+ price: collateralPriceInPrincipal,
39817
+ priceUSD: collateralPriceInPrincipal * principalUSD,
39818
+ marketUid: createMarketUid(chainId, lenderKey, collateral),
39819
+ targetLender: lenderKey,
39820
+ baseAsset: principal
39821
+ });
39822
+ } else if (collateralUSD) {
39823
+ entries.push({
39824
+ asset: collateral,
39825
+ price: 1,
39826
+ priceUSD: collateralUSD,
39827
+ marketUid: createMarketUid(chainId, lenderKey, collateral),
39828
+ targetLender: lenderKey,
39829
+ description: "Teller collateral asset",
39830
+ staticBase: true,
39831
+ baseAsset: collateral
39832
+ });
39833
+ entries.push({
39834
+ asset: principal,
39835
+ price: collPerPrincipal,
39836
+ priceUSD: collPerPrincipal * collateralUSD,
39837
+ marketUid: createMarketUid(chainId, lenderKey, principal),
39838
+ targetLender: lenderKey,
39839
+ baseAsset: collateral
39840
+ });
39841
+ }
39748
39842
  return entries;
39749
39843
  }
39750
39844
  function getTellerAbi() {