@1delta/margin-fetcher 5.0.88 → 5.0.90

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,9 +1,9 @@
1
- import { parseAbi, keccak256, encodeAbiParameters, formatEther, BaseError, erc20Abi, stringToHex, isAddress, pad, encodeFunctionData, formatUnits, getAddress, decodeFunctionResult, decodeAbiParameters, concat, parseAbiParameters, hexToString, AbiEncodingLengthMismatchError, concatHex, toBytes, slice, InvalidAddressError, boolToHex, integerRegex, numberToHex, bytesRegex, BytesSizeMismatchError, arrayRegex, UnsupportedPackedAbiType } from './chunk-JUYF2XLF.js';
1
+ import { parseAbi, keccak256, encodeAbiParameters, formatEther, BaseError, erc20Abi, isAddress, stringToHex, pad, encodeFunctionData, formatUnits, getAddress, decodeFunctionResult, decodeAbiParameters, toBytes, slice, concat, AbiEncodingLengthMismatchError, concatHex, parseAbiParameters, hexToString, InvalidAddressError, boolToHex, integerRegex, numberToHex, bytesRegex, BytesSizeMismatchError, arrayRegex, UnsupportedPackedAbiType } from './chunk-JUYF2XLF.js';
2
2
  import './chunk-BYTNVMX7.js';
3
3
  import './chunk-PR4QN5HX.js';
4
4
  import { Lender, isExactly, isMidnight, isTerm, isTermMax, isTeller, isListaDao, isLiquityFamily, isRiver, isInverse, isCooler, isDssType, isCompoundV3Type, isFluid, isGearboxV3, isLlamaLend, isFrankencoin, isResupply, isCurvance, isFlyingTulip, isTwyne, isFraxlend, isAaveV4Type, LIQUITY_FAMILY_LENDERS, isAaveType, isCompoundV3, isCompoundV2Type, isMultiMarket, isSiloV2Type, isSiloV3Type, isDolomite, isMorphoType, isUsdd, isSky, hasCrossMarginRisk, isEulerType, isInit, isVenusType, isSumerType, AAVE_V3_LENDERS, AAVE_V2_LENDERS, isMorphoBlue, isAaveV2Type, isAaveV32Type, isAaveV3Type, isYLDR, isLista, hasSubAccounts, isTectonicType, isKineticType, isBenqiType } from '@1delta/lender-registry';
5
5
  export { hasCrossMarginRisk, isAaveType, isAaveV2Type, isAaveV32Type, isAaveV3Type, isCompoundV3, isCompoundV3Type, isInit, isMorphoType, isMultiMarket, isYLDR } from '@1delta/lender-registry';
6
- import { fetchTokenLists, fetchTokenList, aavePools, compoundV3Pools, initConfig, morphoPools, compoundV2Pools, eulerVaults, siloMarkets, siloV2LenderKey, siloMarketsV3, siloV3LenderKey, aaveV4Spokes, aaveV4SpokeLenderKey, fluidResolvers, gearboxResolvers, dolomiteConfigs, midnightConfig, termConfig, termMarketsByChain, exactlyConfig, flyingTulipLendersByChain, liquityLendersByChain, riverLendersByChain, inverseLendersByChain, coolerLendersByChain, llamaLendLendersByChain, usddLendersByChain, skyLendersByChain, frankencoinLendersByChain, resupplyLendersByChain, curvanceLendersByChain, fraxlendLendersByChain, twyneLendersByChain, tellerConfigByChain, tellerPoolsByChain, termMaxConfigByChain, aaveReserves, compoundV3Reserves, dolomiteIsolationMarket, morphoTypeMarkets, resolveTermApiBase, flyingTulipConfigFor, flyingTulipAssetsFor, liquityConfigFor, liquityBranchesByChain, riverConfigFor, riverChainData, termMaxApiBaseUrl, termMaxLenderKey, inverseConfigFor, inverseChainData, coolerConfigFor, llamaLendConfigFor, llamaLendChainData, llamaLendApiBaseUrl, resupplyConfigFor, fraxlendConfigFor, dssConfigFor, dssChainData, dssDebtToken, dssDebtJoin, frankencoinConfigFor, frankencoinChainData, aaveOracles, resolveMidnightApiBase, llamaLendMarketByVault, getSiloV2MarketEntry, getSiloV3MarketEntry, dolomiteEmode, curvanceConfigFor, aaveTokens, morphoTypeVaults, listaCollateralProvider, eulerConfigs, gearboxMarketCompressor, gearboxMarketConfigurators, compoundV2TokenArray, gearboxV3LenderKey, midnightMarketsByChain, twyneConfigFor, twyneChainData, midnightCollateralRef, parseAaveV4SpokeLenderKey, fraxlendPairsFor, gearboxAccountCompressor, compoundV2Tokens, exactlyMarketsByChain, aaveOraclesConfig, compoundV2Oracles, compoundV2OraclesConfig, compoundV3OraclesData, compoundV3BaseData, compoundV2Reserves, aaveV4Oracles, morphoTypeOracles } from '@1delta/data-sdk';
6
+ import { fetchTokenLists, fetchTokenList, aavePools, compoundV3Pools, initConfig, morphoPools, compoundV2Pools, eulerVaults, siloMarkets, siloV2LenderKey, siloMarketsV3, siloV3LenderKey, aaveV4Spokes, aaveV4SpokeLenderKey, fluidResolvers, gearboxResolvers, dolomiteConfigs, midnightConfig, termConfig, termMarketsByChain, exactlyConfig, flyingTulipLendersByChain, liquityLendersByChain, riverLendersByChain, inverseLendersByChain, coolerLendersByChain, llamaLendLendersByChain, usddLendersByChain, skyLendersByChain, frankencoinLendersByChain, resupplyLendersByChain, curvanceLendersByChain, fraxlendLendersByChain, twyneLendersByChain, tellerConfigByChain, tellerPoolsByChain, termMaxConfigByChain, aaveReserves, compoundV3Reserves, dolomiteIsolationMarket, morphoTypeMarkets, resolveTermApiBase, flyingTulipConfigFor, flyingTulipAssetsFor, liquityConfigFor, liquityBranchesByChain, riverConfigFor, riverChainData, termMaxApiBaseUrl, termMaxLenderKey, inverseConfigFor, inverseChainData, coolerConfigFor, llamaLendConfigFor, llamaLendChainData, llamaLendApiBaseUrl, resupplyConfigFor, fraxlendConfigFor, dssConfigFor, dssChainData, dssDebtToken, dssDebtJoin, frankencoinConfigFor, frankencoinChainData, aaveTokens, compoundV3BaseData, compoundV2TokenArray, morphoTypeVaults, eulerConfigs, fluidVaultEntries, gearboxMarketConfigurators, dolomiteIsolation, liquityMarkets, riverMarkets, tellerConfig, tellerPools, termMarkets, termMaxConfig, midnightMarkets, midnightCollateralRef, llamaLendMarkets, fraxlendPairsFor, inverseMarkets, curvanceConfig, frankencoinMarkets, twyneMarkets, twyneConfigFor, exactlyMarkets, aaveOracles, resolveMidnightApiBase, llamaLendMarketByVault, getSiloV2MarketEntry, getSiloV3MarketEntry, dolomiteEmode, curvanceConfigFor, listaCollateralProvider, gearboxMarketCompressor, gearboxV3LenderKey, midnightMarketsByChain, twyneChainData, parseAaveV4SpokeLenderKey, gearboxAccountCompressor, compoundV2Tokens, exactlyMarketsByChain, aaveOraclesConfig, compoundV2Oracles, compoundV2OraclesConfig, compoundV3OraclesData, compoundV2Reserves, aaveV4Oracles, morphoTypeOracles } from '@1delta/data-sdk';
7
7
  import lodash from 'lodash';
8
8
  import { Chain, isEvmChainId } from '@1delta/chain-registry';
9
9
  import { multicallRetryUniversal, getEvmClient, getEvmChain, createMulticallRetryUniversal, LIST_OVERRIDES, getEvmClientUniversal } from '@1delta/providers';
@@ -12,6 +12,7 @@ export { MorphoLensAbi } from '@1delta/abis';
12
12
  import { prepareDebitDataMulticall, prepareLenderDebitMulticall, parseDebitDataResult, parseLenderDebitResult, getPermit2ContractAddress, getLstAcceptedInputs, savingsVerbRequires, savingsSupportsVerb, getCompoundV2Comptroller as getCompoundV2Comptroller$1, getCompoundV3CometAddress as getCompoundV3CometAddress$1, getMorphoAddress, FLUID_VAULT_FACTORY, getAaveStyleLenderTokenAddress, LendingMode, getAaveCollateralTokenAddress, getSiloHalfForUnderlying, findSavingsWithdrawEntry, bandLtvCurve, InitMarginAddresses, ignoresReceiver, buildLstWithdrawRequest, SAVINGS_RECEIVER_CAPABILITY } from '@1delta/calldata-sdk';
13
13
  import { proxyNativeFetch } from '@1delta/proxy-fetch';
14
14
  import { BALANCER_V2_FORKS, BALANCER_V3_FORKS, UNISWAP_V4_FORKS, isFlashLoanSourceExcluded, FLASH_LOAN_IDS } from '@1delta/dex-registry';
15
+ import { getNativeDecimals } from '@1delta/wnative';
15
16
 
16
17
  // src/abis/aave-v2/ProtocolDataProvider.ts
17
18
  var ProtocolDataProviderAbi = [
@@ -6754,6 +6755,12 @@ var buildAaveV3StyleLenderReserveCall = (chainId, lender) => {
6754
6755
  }
6755
6756
  }
6756
6757
  };
6758
+ function getInitPosManagerAddress(chainId) {
6759
+ return addressesInitCore.PosManager[chainId];
6760
+ }
6761
+ function getInitCoreAddress(chainId) {
6762
+ return addressesInitCore.Core[chainId];
6763
+ }
6757
6764
  function getInitLensAddress(chainId) {
6758
6765
  return addressesInitCore.PublicLens[chainId];
6759
6766
  }
@@ -7326,15 +7333,15 @@ var getAaveV2ReservesDataConverter = (lender, chainId, prices, additionalYields,
7326
7333
  isActive: configData?.[8 /* isActive */],
7327
7334
  isFrozen: configData?.[9 /* isFrozen */]
7328
7335
  };
7329
- const aaveTokens3 = aaveTokenMap[asset];
7330
- if (!!aaveTokens3) {
7336
+ const aaveTokens4 = aaveTokenMap[asset];
7337
+ if (!!aaveTokens4) {
7331
7338
  resultReserves[marketUid] = {
7332
7339
  ...resultReserves[marketUid],
7333
7340
  params: {
7334
7341
  metadata: {
7335
- aToken: aaveTokens3.aToken,
7336
- vToken: aaveTokens3.vToken,
7337
- sToken: aaveTokens3.sToken
7342
+ aToken: aaveTokens4.aToken,
7343
+ vToken: aaveTokens4.vToken,
7344
+ sToken: aaveTokens4.sToken
7338
7345
  }
7339
7346
  }
7340
7347
  };
@@ -7564,15 +7571,15 @@ var getAaveV3ReservesDataConverter = (lender, chainId, prices, additionalYields,
7564
7571
  };
7565
7572
  })()
7566
7573
  };
7567
- const aaveTokens3 = aaveTokenMap[asset];
7568
- if (!!aaveTokens3) {
7574
+ const aaveTokens4 = aaveTokenMap[asset];
7575
+ if (!!aaveTokens4) {
7569
7576
  resultReserves[marketUid] = {
7570
7577
  ...resultReserves[marketUid],
7571
7578
  params: {
7572
7579
  metadata: {
7573
- aToken: aaveTokens3.aToken,
7574
- vToken: aaveTokens3.vToken,
7575
- sToken: aaveTokens3.sToken
7580
+ aToken: aaveTokens4.aToken,
7581
+ vToken: aaveTokens4.vToken,
7582
+ sToken: aaveTokens4.sToken
7576
7583
  }
7577
7584
  }
7578
7585
  };
@@ -7803,15 +7810,15 @@ function parseYLDRCall(chainId, lender, additionalYields, prices, tokenList) {
7803
7810
  isActive: configData?.[7 /* isActive */],
7804
7811
  isFrozen: configData?.[8 /* isFrozen */]
7805
7812
  };
7806
- const aaveTokens3 = aaveTokenMap[asset];
7807
- if (!!aaveTokens3) {
7813
+ const aaveTokens4 = aaveTokenMap[asset];
7814
+ if (!!aaveTokens4) {
7808
7815
  resultReserves[marketUid] = {
7809
7816
  ...resultReserves[marketUid],
7810
7817
  params: {
7811
7818
  metadata: {
7812
- aToken: aaveTokens3.aToken,
7813
- vToken: aaveTokens3.vToken,
7814
- sToken: aaveTokens3.sToken
7819
+ aToken: aaveTokens4.aToken,
7820
+ vToken: aaveTokens4.vToken,
7821
+ sToken: aaveTokens4.sToken
7815
7822
  }
7816
7823
  }
7817
7824
  };
@@ -8003,15 +8010,15 @@ function parseAave32(chainId, lender, prices, additionalYields, tokenList) {
8003
8010
  };
8004
8011
  })()
8005
8012
  };
8006
- const aaveTokens3 = aaveTokenMap[asset];
8007
- if (!!aaveTokens3) {
8013
+ const aaveTokens4 = aaveTokenMap[asset];
8014
+ if (!!aaveTokens4) {
8008
8015
  resultReserves[marketUid] = {
8009
8016
  ...resultReserves[marketUid],
8010
8017
  params: {
8011
8018
  metadata: {
8012
- aToken: aaveTokens3.aToken,
8013
- vToken: aaveTokens3.vToken,
8014
- sToken: aaveTokens3.sToken
8019
+ aToken: aaveTokens4.aToken,
8020
+ vToken: aaveTokens4.vToken,
8021
+ sToken: aaveTokens4.sToken
8015
8022
  }
8016
8023
  }
8017
8024
  };
@@ -12166,6 +12173,21 @@ function createMultiAccountTypeUserState(payload, lenderData, histData) {
12166
12173
  data
12167
12174
  };
12168
12175
  }
12176
+ var isFixedTermLender = (lender) => isMidnight(lender) || isTerm(lender) || isTermMax(lender) || isTeller(lender) || isExactly(lender);
12177
+ function positionUnitKind(lenderKey, p) {
12178
+ const hasShares = p.depositShares !== void 0 || p.debtShares !== void 0;
12179
+ if (isMorphoType(lenderKey) && hasShares) return "morpho_shares";
12180
+ if (isCompoundV2Type(lenderKey) && p.depositShares !== void 0)
12181
+ return "ctoken";
12182
+ if ((isSiloV2Type(lenderKey) || isSiloV3Type(lenderKey)) && hasShares)
12183
+ return "silo_shares";
12184
+ if (isDolomite(lenderKey) && p.debtPar !== void 0) return "dolomite_par";
12185
+ if (isFixedTermLender(lenderKey)) return "face_value";
12186
+ return "resolved_amount";
12187
+ }
12188
+ function withUnitKind(lenderKey, p) {
12189
+ return p.unitKind ? p : { ...p, unitKind: positionUnitKind(lenderKey, p) };
12190
+ }
12169
12191
 
12170
12192
  // src/lending/user-data/utils/index.ts
12171
12193
  function divideAccrualsToAprs(aprs, nav, deposits, debt) {
@@ -18383,6 +18405,113 @@ var buildEulerV2LenderReserveCall = (chainId, lender) => {
18383
18405
  }));
18384
18406
  };
18385
18407
 
18408
+ // src/abis/multicall/Multicall.ts
18409
+ var MulticallABI = [
18410
+ {
18411
+ inputs: [],
18412
+ name: "getCurrentBlockTimestamp",
18413
+ outputs: [
18414
+ {
18415
+ internalType: "uint256",
18416
+ name: "timestamp",
18417
+ type: "uint256"
18418
+ }
18419
+ ],
18420
+ stateMutability: "view",
18421
+ type: "function"
18422
+ },
18423
+ {
18424
+ inputs: [
18425
+ {
18426
+ internalType: "address",
18427
+ name: "addr",
18428
+ type: "address"
18429
+ }
18430
+ ],
18431
+ name: "getEthBalance",
18432
+ outputs: [
18433
+ {
18434
+ internalType: "uint256",
18435
+ name: "balance",
18436
+ type: "uint256"
18437
+ }
18438
+ ],
18439
+ stateMutability: "view",
18440
+ type: "function"
18441
+ },
18442
+ {
18443
+ inputs: [],
18444
+ name: "getBlockNumber",
18445
+ outputs: [
18446
+ {
18447
+ internalType: "uint256",
18448
+ name: "blockNumber",
18449
+ type: "uint256"
18450
+ }
18451
+ ],
18452
+ stateMutability: "view",
18453
+ type: "function"
18454
+ },
18455
+ {
18456
+ inputs: [
18457
+ {
18458
+ components: [
18459
+ {
18460
+ internalType: "address",
18461
+ name: "target",
18462
+ type: "address"
18463
+ },
18464
+ {
18465
+ internalType: "uint256",
18466
+ name: "gasLimit",
18467
+ type: "uint256"
18468
+ },
18469
+ {
18470
+ internalType: "bytes",
18471
+ name: "callData",
18472
+ type: "bytes"
18473
+ }
18474
+ ],
18475
+ internalType: "struct UniswapInterfaceMulticall.Call[]",
18476
+ name: "calls",
18477
+ type: "tuple[]"
18478
+ }
18479
+ ],
18480
+ name: "multicall",
18481
+ outputs: [
18482
+ {
18483
+ internalType: "uint256",
18484
+ name: "blockNumber",
18485
+ type: "uint256"
18486
+ },
18487
+ {
18488
+ components: [
18489
+ {
18490
+ internalType: "bool",
18491
+ name: "success",
18492
+ type: "bool"
18493
+ },
18494
+ {
18495
+ internalType: "uint256",
18496
+ name: "gasUsed",
18497
+ type: "uint256"
18498
+ },
18499
+ {
18500
+ internalType: "bytes",
18501
+ name: "returnData",
18502
+ type: "bytes"
18503
+ }
18504
+ ],
18505
+ internalType: "struct UniswapInterfaceMulticall.Result[]",
18506
+ name: "returnData",
18507
+ type: "tuple[]"
18508
+ }
18509
+ ],
18510
+ stateMutability: "nonpayable",
18511
+ type: "function"
18512
+ }
18513
+ ];
18514
+
18386
18515
  // src/lending/public-data/euler/fetcher/cluster.ts
18387
18516
  function getActiveCollaterals(ltvInfo) {
18388
18517
  const active = /* @__PURE__ */ new Set();
@@ -20627,24 +20756,68 @@ var dolomiteFactors = (p, R) => ({
20627
20756
  borrowCollateralFactor: 1 / ((1 + R) * (1 + p)),
20628
20757
  borrowFactor: 1 + p
20629
20758
  });
20630
- function buildDolomiteConfigs(marketId, marginPremium, R, isClosing, emode) {
20759
+ var DOLOMITE_ISOLATION_MODE_PREFIX = "iso:";
20760
+ var dolomiteIsolationMode = (marketId) => `${DOLOMITE_ISOLATION_MODE_PREFIX}${marketId}`;
20761
+ var DISABLED = {
20762
+ collateralFactor: 0,
20763
+ borrowCollateralFactor: 0,
20764
+ borrowFactor: DISABLED_BORROW_FACTOR,
20765
+ debtDisabled: true,
20766
+ collateralDisabled: true,
20767
+ liquidationPenalty: 0,
20768
+ closeFactor: 1
20769
+ };
20770
+ function buildDolomiteConfigs(marketId, marginPremium, R, isClosing, emode, isolation) {
20631
20771
  const borrowOnly = emode?.riskFeatures?.[marketId]?.feature === "BORROW_ONLY";
20772
+ const isReceipt = !!isolation?.[marketId];
20632
20773
  const base = dolomiteFactors(marginPremium, R);
20633
20774
  const configs = {
20634
20775
  ["0"]: {
20635
20776
  category: "0",
20636
20777
  label: "Cross-margin",
20637
20778
  ...base,
20638
- debtDisabled: isClosing,
20639
- collateralDisabled: borrowOnly,
20779
+ debtDisabled: isClosing || isReceipt,
20780
+ collateralDisabled: borrowOnly || isReceipt,
20640
20781
  liquidationPenalty: BASE_LIQUIDATION_PENALTY,
20641
20782
  closeFactor: 1
20642
20783
  }
20643
20784
  };
20785
+ for (const [isoId, vault] of Object.entries(isolation ?? {})) {
20786
+ const mode = dolomiteIsolationMode(isoId);
20787
+ const label = `Isolation: ${vault.underlyingSymbol || isoId}`;
20788
+ if (isoId === marketId) {
20789
+ configs[mode] = {
20790
+ category: mode,
20791
+ label,
20792
+ ...base,
20793
+ debtDisabled: true,
20794
+ // a receipt is never borrowable
20795
+ collateralDisabled: false,
20796
+ liquidationPenalty: BASE_LIQUIDATION_PENALTY,
20797
+ closeFactor: 1
20798
+ };
20799
+ continue;
20800
+ }
20801
+ const debtAllowed = vault.allowableDebtMarketIds.length === 0 || vault.allowableDebtMarketIds.includes(marketId);
20802
+ const collateralAllowed = vault.allowableCollateralMarketIds.length === 0 || vault.allowableCollateralMarketIds.includes(marketId);
20803
+ if (isReceipt || !debtAllowed && !collateralAllowed) {
20804
+ configs[mode] = { category: mode, label, ...DISABLED };
20805
+ continue;
20806
+ }
20807
+ configs[mode] = {
20808
+ category: mode,
20809
+ label,
20810
+ ...base,
20811
+ debtDisabled: isClosing || !debtAllowed,
20812
+ collateralDisabled: borrowOnly || !collateralAllowed,
20813
+ liquidationPenalty: BASE_LIQUIDATION_PENALTY,
20814
+ closeFactor: 1
20815
+ };
20816
+ }
20644
20817
  if (!emode?.categories) return configs;
20645
20818
  const marketCategory = emode.marketCategories?.[marketId];
20646
20819
  for (const [cat, param] of Object.entries(emode.categories)) {
20647
- if (marketCategory === cat) {
20820
+ if (marketCategory === cat && !isReceipt) {
20648
20821
  const f = dolomiteFactors(0, param.marginRatioOverride);
20649
20822
  configs[cat] = {
20650
20823
  category: cat,
@@ -20671,7 +20844,9 @@ function buildDolomiteConfigs(marketId, marginPremium, R, isClosing, emode) {
20671
20844
  }
20672
20845
  return configs;
20673
20846
  }
20674
- function resolveDolomiteMode(heldMarketIds, emode) {
20847
+ function resolveDolomiteMode(heldMarketIds, emode, isolationMarketId) {
20848
+ if (isolationMarketId !== void 0)
20849
+ return dolomiteIsolationMode(isolationMarketId);
20675
20850
  if (!emode?.marketCategories || heldMarketIds.length === 0) return "0";
20676
20851
  const cats = /* @__PURE__ */ new Set();
20677
20852
  for (const m of heldMarketIds) {
@@ -20757,6 +20932,7 @@ var getDolomitePublicDataConverter = (lender, chainId, _prices, additionalYields
20757
20932
  const R = Number(parseRawAmount(toBig(data[0]?.value), 18));
20758
20933
  const earningsRate = Number(parseRawAmount(toBig(data[1]?.value), 18));
20759
20934
  const emode = dolomiteEmode()?.[chainId];
20935
+ const isolation = dolomiteIsolation()?.[chainId];
20760
20936
  const result = {};
20761
20937
  marketIds.forEach((marketId, m) => {
20762
20938
  const base = GLOBAL_COUNT + MARKET_STRIDE * m;
@@ -20788,7 +20964,14 @@ var getDolomitePublicDataConverter = (lender, chainId, _prices, additionalYields
20788
20964
  parseRawAmount(toBig(data[base + 5 /* marginPremium */]?.value), 18)
20789
20965
  );
20790
20966
  const isClosing = Boolean(data[base + 1 /* isClosing */]);
20791
- const config = buildDolomiteConfigs(marketId, p, R, isClosing, emode);
20967
+ const config = buildDolomiteConfigs(
20968
+ marketId,
20969
+ p,
20970
+ R,
20971
+ isClosing,
20972
+ emode,
20973
+ isolation
20974
+ );
20792
20975
  const liquidity = Number(totalDeposits) - Number(totalDebt);
20793
20976
  const marketUid = createMarketUid(chainId, lender, String(marketId));
20794
20977
  const identity = resolveDolomiteRowIdentity(
@@ -21296,6 +21479,8 @@ var getLenderPublicData = async (chainId, lenders, prices, additionalYields, mul
21296
21479
  const validLenders = [];
21297
21480
  const sliceStart = {};
21298
21481
  const sliceBuilt = {};
21482
+ const blockSentinel = buildBlockSentinelCall(chainId);
21483
+ if (blockSentinel) calls.push(blockSentinel);
21299
21484
  for (const lender of lenders) {
21300
21485
  const abi = getAbi(lender);
21301
21486
  const callData = buildLenderCall(chainId, lender);
@@ -21414,8 +21599,44 @@ var getLenderPublicData = async (chainId, lenders, prices, additionalYields, mul
21414
21599
  } catch {
21415
21600
  }
21416
21601
  }
21602
+ if (blockSentinel) {
21603
+ const block = parseBlockNumber(rawResults?.[0]);
21604
+ if (block !== void 0) stampAccumulatorBlock(lenderData, block);
21605
+ }
21417
21606
  return lenderData;
21418
21607
  };
21608
+ function buildBlockSentinelCall(chainId) {
21609
+ const address = getEvmChain(chainId)?.contracts?.multicall3?.address;
21610
+ if (!address) return void 0;
21611
+ return {
21612
+ call: { address, name: "getBlockNumber", params: [] },
21613
+ abi: MulticallABI
21614
+ };
21615
+ }
21616
+ function parseBlockNumber(raw) {
21617
+ if (raw === void 0 || raw === null || raw === "0x") return void 0;
21618
+ try {
21619
+ const b = typeof raw === "bigint" ? raw : BigInt(String(raw));
21620
+ return b > 0n && b <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(b) : void 0;
21621
+ } catch {
21622
+ return void 0;
21623
+ }
21624
+ }
21625
+ function stampAccumulatorBlock(lenderData, block) {
21626
+ let stamped = 0;
21627
+ for (const bundle of Object.values(lenderData)) {
21628
+ const pools = bundle?.data;
21629
+ if (!pools || typeof pools !== "object") continue;
21630
+ for (const pool of Object.values(pools)) {
21631
+ const acc = pool?.accumulator;
21632
+ if (acc && typeof acc.supplyIndex === "string") {
21633
+ acc.blockNumber = block;
21634
+ stamped++;
21635
+ }
21636
+ }
21637
+ }
21638
+ return stamped;
21639
+ }
21419
21640
  function sliceLenderResults(chainId, rawResults, entries) {
21420
21641
  const out = {};
21421
21642
  for (const { lender, start, built, declared } of entries) {
@@ -26593,7 +26814,7 @@ async function fetchFraxlendPairs(lender, chainId) {
26593
26814
  rateContract,
26594
26815
  swapperOk
26595
26816
  ] = s;
26596
- if (typeof asset !== "string" || typeof collateral !== "string") return;
26817
+ if (!isAddress(asset) || !isAddress(collateral)) return;
26597
26818
  if (!preview || !xrInfo) return;
26598
26819
  const rateInfo = preview[3] ?? {};
26599
26820
  const totalAsset = preview[4] ?? {};
@@ -29597,6 +29818,7 @@ async function fetchDolomiteMarketsFromSubgraph(chainId) {
29597
29818
  function convertDolomiteSubgraphMarkets(raw, chainId, prices, additionalYields, tokenList = {}) {
29598
29819
  const R = raw.liquidationRatio > 0 ? raw.liquidationRatio - 1 : 0;
29599
29820
  const emode = dolomiteEmode()?.[chainId];
29821
+ const isolation = dolomiteIsolation()?.[chainId];
29600
29822
  const result = {};
29601
29823
  for (const info of raw.riskInfos) {
29602
29824
  const underlying = info.token.id.toLowerCase();
@@ -29616,7 +29838,8 @@ function convertDolomiteSubgraphMarkets(raw, chainId, prices, additionalYields,
29616
29838
  p,
29617
29839
  R,
29618
29840
  isClosing,
29619
- emode
29841
+ emode,
29842
+ isolation
29620
29843
  );
29621
29844
  const marketUid = createMarketUid(
29622
29845
  chainId,
@@ -31322,6 +31545,15 @@ function parseDolomiteSubAccountId(id) {
31322
31545
  function toDolomiteSubAccountId(number, isolationMarketId) {
31323
31546
  return isolationMarketId ? `${DOLOMITE_ISO_ID_PREFIX}${isolationMarketId}:${number}` : number;
31324
31547
  }
31548
+ function dolomiteVaultAddress(chainId, marketId, user) {
31549
+ const m = dolomiteIsolationMarket(chainId, marketId);
31550
+ if (!m?.vaultInitCodeHash) return void 0;
31551
+ return getCreate2Address({
31552
+ from: m.factory,
31553
+ salt: keccak256(encodePacked(["address"], [user])),
31554
+ bytecodeHash: m.vaultInitCodeHash
31555
+ }).toLowerCase();
31556
+ }
31325
31557
  var subgraphCache = /* @__PURE__ */ new Map();
31326
31558
  function fetchDolomiteSubAccounts(chainId, owner) {
31327
31559
  const key3 = `${chainId}:${owner.toLowerCase()}`;
@@ -31408,6 +31640,27 @@ async function fetchSubAccountsFromSubgraph(chainId, owner) {
31408
31640
  }
31409
31641
  var RESOLVED_STORE_TTL_MS2 = 6e4;
31410
31642
  var resolvedStore = /* @__PURE__ */ new Map();
31643
+ function toSubAccount(chainId, account, id) {
31644
+ const parsed = parseDolomiteSubAccountId(id);
31645
+ if (parsed.isolationMarketId === void 0) {
31646
+ return [{ id, owner: account, number: parsed.number }];
31647
+ }
31648
+ const vault = dolomiteVaultAddress(chainId, parsed.isolationMarketId, account);
31649
+ if (!vault) {
31650
+ console.warn(
31651
+ `[dolomite] cannot derive the vault for position ${id} on chain ${chainId} (no isolation table / init-code hash); skipped`
31652
+ );
31653
+ return [];
31654
+ }
31655
+ return [
31656
+ {
31657
+ id: toDolomiteSubAccountId(parsed.number, parsed.isolationMarketId),
31658
+ owner: vault,
31659
+ number: parsed.number,
31660
+ isolationMarketId: parsed.isolationMarketId
31661
+ }
31662
+ ];
31663
+ }
31411
31664
  function getResolvedDolomiteSubAccounts(chainId, account) {
31412
31665
  return resolvedStore.get(`${chainId}:${account.toLowerCase()}`)?.accounts;
31413
31666
  }
@@ -31429,7 +31682,7 @@ var buildDolomiteUserCall = async (chainId, _lender, account, accountNumbers) =>
31429
31682
  if (!margin) return [];
31430
31683
  const accounts = accountNumbers ? withDefault(
31431
31684
  account,
31432
- accountNumbers.map((n) => ({ id: n, owner: account, number: n }))
31685
+ accountNumbers.flatMap((id) => toSubAccount(chainId, account, id))
31433
31686
  ) : await fetchDolomiteSubAccounts(chainId, account);
31434
31687
  storeResolved(chainId, account, accounts);
31435
31688
  return accounts.map(({ owner, number }) => ({
@@ -35274,7 +35527,8 @@ var getDolomiteUserDataConverter = (lender, chainId, account, metaMap) => {
35274
35527
  const pars = res?.[2 /* pars */] ?? [];
35275
35528
  modes[id] = resolveDolomiteMode(
35276
35529
  marketIds.map((m) => String(m)),
35277
- emode
35530
+ emode,
35531
+ subAccounts[i].isolationMarketId
35278
35532
  );
35279
35533
  tokens.forEach((token, k) => {
35280
35534
  const wei = weis[k];
@@ -43716,7 +43970,12 @@ function fuseLenderData(userDataResult, summary) {
43716
43970
  lender,
43717
43971
  chainId,
43718
43972
  account: userData.account,
43719
- data: userData.data,
43973
+ // Tag every row with the unit it carries (POSITION_INDEX_SUPPORT.md,
43974
+ // Contract B): a copy, never a mutation of the parser's objects.
43975
+ data: userData.data.map((sa) => ({
43976
+ ...sa,
43977
+ positions: sa.positions.map((p) => withUnitKind(lender, p))
43978
+ })),
43720
43979
  // Carry the partial-read marker onto the entry the client renders — the
43721
43980
  // top-level `incompleteLenders` list alone leaves a consumer to re-join it
43722
43981
  // by key, which no client did, so broken aggregates rendered as fact.
@@ -43732,1460 +43991,554 @@ function fuseLenderData(userDataResult, summary) {
43732
43991
  return entries;
43733
43992
  }
43734
43993
 
43735
- // src/lending/margin/base/standard/deposit.ts
43736
- function computeDepositDelta(amount4, price2, balanceData2, config, modeId, createNewSubAccount = false, apr, yieldParams) {
43737
- const { borrowCollateralFactor, collateralFactor } = getAssetConfig(config, modeId);
43738
- const base = createNewSubAccount ? EMPTY_BALANCE : balanceData2;
43739
- const dollarAmount = amount4 * price2;
43740
- const postTrade = {
43741
- ...base,
43742
- borrowDiscountedCollateral: base.borrowDiscountedCollateral + borrowCollateralFactor * dollarAmount,
43743
- collateral: base.collateral + collateralFactor * dollarAmount,
43744
- deposits: base.deposits + dollarAmount,
43745
- nav: base.nav + dollarAmount
43746
- };
43747
- const result = computePostTradeMetrics(base, postTrade);
43748
- if (apr && yieldParams) {
43749
- const cashFlowDeposits = base.deposits * apr.depositApr;
43750
- const cashFlowDebt = base.debt * apr.borrowApr;
43751
- const rewardFlowDeposits = base.deposits * (apr.rewardDepositApr ?? 0);
43752
- const rewardFlowDebt = base.debt * (apr.rewardBorrowApr ?? 0);
43753
- const intrinsicFlowDeposits = base.deposits * apr.intrinsicDepositApr;
43754
- const intrinsicFlowDebt = base.debt * apr.intrinsicBorrowApr;
43755
- const newApr = { ...apr };
43756
- [newApr.borrowApr, newApr.depositApr, newApr.apr] = getOrganicYieldDeposit(
43757
- dollarAmount,
43758
- cashFlowDeposits,
43759
- cashFlowDebt,
43760
- base.deposits,
43761
- base.debt,
43762
- yieldParams
43763
- );
43764
- newApr.rewards = getRewardYieldDeposit(
43765
- dollarAmount,
43766
- rewardFlowDeposits,
43767
- rewardFlowDebt,
43768
- base.deposits,
43769
- base.debt,
43770
- yieldParams
43771
- );
43772
- [newApr.intrinsicBorrowApr, newApr.intrinsicDepositApr, newApr.intrinsicApr] = getIntrinsicYieldDeposit(
43773
- dollarAmount,
43774
- intrinsicFlowDeposits,
43775
- intrinsicFlowDebt,
43776
- base.deposits,
43777
- base.debt,
43778
- yieldParams
43779
- );
43780
- result.post.aprData = newApr;
43781
- }
43782
- return result;
43783
- }
43784
-
43785
- // src/lending/margin/base/deposit.ts
43786
- function computeDepositDelta2(lender, amount4, price2, balanceData2, config, modeId, createNewSubAccount, apr, yieldParams, targetMarketUid, positions) {
43787
- if (isSumerType(lender)) {
43788
- if (!positions || targetMarketUid === void 0) {
43789
- throw new Error("Sumer operations require positions and targetMarketUid");
43994
+ // src/yields/intrinsic/fetchers/lido.ts
43995
+ var WSTETH_URL = "https://eth-api.lido.fi/v1/protocol/steth/apr/sma";
43996
+ var DEFILLAMA_LIDO_URL = "https://yields.llama.fi/chart/747c1d2a-c668-4682-b9f9-296708a3dd90";
43997
+ var tETH = "Treehouse ETH::TETH";
43998
+ var robustFetchJson = async (url, { timeoutMs = 5e3, attempts = 3 } = {}) => {
43999
+ let lastErr;
44000
+ for (let i = 0; i < attempts; i++) {
44001
+ try {
44002
+ const res = await fetch(url, {
44003
+ headers: {
44004
+ accept: "application/json",
44005
+ "user-agent": "1delta-margin-fetcher"
44006
+ },
44007
+ signal: AbortSignal.timeout(timeoutMs)
44008
+ });
44009
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
44010
+ return await res.json();
44011
+ } catch (e) {
44012
+ lastErr = e;
44013
+ if (i < attempts - 1) {
44014
+ await new Promise((r) => setTimeout(r, 250 * (i + 1)));
44015
+ }
43790
44016
  }
43791
- return computeSumerDepositDelta(
43792
- amount4,
43793
- price2,
43794
- targetMarketUid,
43795
- balanceData2,
43796
- positions,
43797
- createNewSubAccount,
43798
- apr,
43799
- yieldParams
43800
- );
43801
44017
  }
43802
- if (!config || modeId === void 0) {
43803
- throw new Error("Standard operations require config and modeId");
44018
+ throw lastErr;
44019
+ };
44020
+ async function fetchLidoApr() {
44021
+ try {
44022
+ const res = await robustFetchJson(WSTETH_URL);
44023
+ return Number(res.data.aprs.at(-1).apr) * 0.9;
44024
+ } catch {
44025
+ const res = await robustFetchJson(DEFILLAMA_LIDO_URL);
44026
+ const latest = res.data.at(-1);
44027
+ return Number(latest.apyBase) * 0.9;
43804
44028
  }
43805
- return computeDepositDelta(
43806
- amount4,
43807
- price2,
43808
- balanceData2,
43809
- config,
43810
- modeId,
43811
- createNewSubAccount,
43812
- apr,
43813
- yieldParams
43814
- );
43815
44029
  }
44030
+ var wstethFetcher = {
44031
+ label: "WSTETH",
44032
+ fetch: async () => {
44033
+ const apr = await fetchLidoApr();
44034
+ return {
44035
+ WSTETH: apr,
44036
+ [tETH]: apr
44037
+ };
44038
+ }
44039
+ };
44040
+ var stmaticFetcher = {
44041
+ label: "STMATIC",
44042
+ fetch: async () => {
44043
+ return { STMATIC: 0 };
44044
+ }
44045
+ };
43816
44046
 
43817
- // src/lending/margin/base/standard/withdraw.ts
43818
- function computeWithdrawDelta(amount4, price2, balanceData2, config, modeId, apr, yieldParams) {
43819
- const { borrowCollateralFactor, collateralFactor } = getAssetConfig(config, modeId);
43820
- const dollarAmount = amount4 * price2;
43821
- const postTrade = {
43822
- ...balanceData2,
43823
- borrowDiscountedCollateral: balanceData2.borrowDiscountedCollateral - borrowCollateralFactor * dollarAmount,
43824
- collateral: balanceData2.collateral - collateralFactor * dollarAmount,
43825
- deposits: balanceData2.deposits - dollarAmount,
43826
- nav: balanceData2.nav - dollarAmount
43827
- };
43828
- const result = computePostTradeMetrics(balanceData2, postTrade);
43829
- if (apr && yieldParams) {
43830
- const cashFlowDeposits = balanceData2.deposits * apr.depositApr;
43831
- const cashFlowDebt = balanceData2.debt * apr.borrowApr;
43832
- const rewardFlowDeposits = balanceData2.deposits * (apr.rewardDepositApr ?? 0);
43833
- const rewardFlowDebt = balanceData2.debt * (apr.rewardBorrowApr ?? 0);
43834
- const intrinsicFlowDeposits = balanceData2.deposits * apr.intrinsicDepositApr;
43835
- const intrinsicFlowDebt = balanceData2.debt * apr.intrinsicBorrowApr;
43836
- const newApr = { ...apr };
43837
- [newApr.borrowApr, newApr.depositApr, newApr.apr] = getOrganicYieldWithdraw(
43838
- dollarAmount,
43839
- cashFlowDeposits,
43840
- cashFlowDebt,
43841
- balanceData2.deposits,
43842
- balanceData2.debt,
43843
- yieldParams
43844
- );
43845
- newApr.rewards = getRewardYieldWithdraw(
43846
- dollarAmount,
43847
- rewardFlowDeposits,
43848
- rewardFlowDebt,
43849
- balanceData2.deposits,
43850
- balanceData2.debt,
43851
- yieldParams
43852
- );
43853
- [newApr.intrinsicBorrowApr, newApr.intrinsicDepositApr, newApr.intrinsicApr] = getIntrinsicYieldWithdraw(
43854
- dollarAmount,
43855
- intrinsicFlowDeposits,
43856
- intrinsicFlowDebt,
43857
- balanceData2.deposits,
43858
- balanceData2.debt,
43859
- yieldParams
43860
- );
43861
- result.post.aprData = newApr;
44047
+ // src/yields/intrinsic/fetchers/rocketpool.ts
44048
+ var RETH_URL = "https://api.rocketpool.net/api/mainnet/payload";
44049
+ var rethFetcher = {
44050
+ label: "RETH",
44051
+ fetch: async () => {
44052
+ const res = await fetch(RETH_URL).then((r) => r.json());
44053
+ return { RETH: Number(res.rethAPR) };
43862
44054
  }
43863
- return result;
43864
- }
44055
+ };
43865
44056
 
43866
- // src/lending/margin/base/withdraw.ts
43867
- function computeWithdrawDelta2(lender, amount4, price2, balanceData2, config, modeId, apr, yieldParams, targetMarketUid, positions) {
43868
- if (isSumerType(lender)) {
43869
- if (!positions || targetMarketUid === void 0) {
43870
- throw new Error("Sumer operations require positions and targetMarketUid");
43871
- }
43872
- return computeSumerWithdrawDelta(
43873
- amount4,
43874
- price2,
43875
- targetMarketUid,
43876
- balanceData2,
43877
- positions,
43878
- apr,
43879
- yieldParams
43880
- );
44057
+ // src/yields/intrinsic/fetchers/renzo.ts
44058
+ var EZETH_URL = "https://app.renzoprotocol.com/api/stats?chainId=1";
44059
+ var ezethFetcher = {
44060
+ label: "EZETH",
44061
+ fetch: async () => {
44062
+ const res = await fetch(EZETH_URL).then((r) => r.json());
44063
+ return { EZETH: Number(res.data.apr.data.rate) };
43881
44064
  }
43882
- if (!config || modeId === void 0) {
43883
- throw new Error("Standard operations require config and modeId");
44065
+ };
44066
+
44067
+ // src/yields/intrinsic/fetchers/kelp.ts
44068
+ var RSETH_URL = "https://universe.kelpdao.xyz/rseth/totalApy";
44069
+ var rsethFetcher = {
44070
+ label: "RSETH",
44071
+ fetch: async () => {
44072
+ const res = await fetch(RSETH_URL).then((r) => r.json());
44073
+ return { RSETH: apyToAprPercent(res.totalAPY) };
43884
44074
  }
43885
- return computeWithdrawDelta(
43886
- amount4,
43887
- price2,
43888
- balanceData2,
43889
- config,
43890
- modeId,
43891
- apr,
43892
- yieldParams
43893
- );
43894
- }
44075
+ };
43895
44076
 
43896
- // src/lending/margin/base/standard/borrow.ts
43897
- function computeBorrowDelta(amount4, price2, balanceData2, config, modeId, apr, yieldParams, irMode) {
43898
- const { borrowFactor } = getAssetConfig(config, modeId);
43899
- const dollarAmount = amount4 * price2;
43900
- const postTrade = {
43901
- ...balanceData2,
43902
- debt: balanceData2.debt + dollarAmount,
43903
- adjustedDebt: balanceData2.adjustedDebt + borrowFactor * dollarAmount,
43904
- nav: balanceData2.nav - dollarAmount
43905
- };
43906
- const result = computePostTradeMetrics(balanceData2, postTrade);
43907
- if (apr && yieldParams) {
43908
- const mode = irMode ?? 2;
43909
- const cashFlowDeposits = balanceData2.deposits * apr.depositApr;
43910
- const cashFlowDebt = balanceData2.debt * apr.borrowApr;
43911
- const rewardFlowDeposits = balanceData2.deposits * (apr.rewardDepositApr ?? 0);
43912
- const rewardFlowDebt = balanceData2.debt * (apr.rewardBorrowApr ?? 0);
43913
- const intrinsicFlowDeposits = balanceData2.deposits * apr.intrinsicDepositApr;
43914
- const intrinsicFlowDebt = balanceData2.debt * apr.intrinsicBorrowApr;
43915
- const newApr = { ...apr };
43916
- [newApr.borrowApr, newApr.depositApr, newApr.apr] = getOrganicYieldBorrow(
43917
- dollarAmount,
43918
- mode,
43919
- cashFlowDeposits,
43920
- cashFlowDebt,
43921
- balanceData2.deposits,
43922
- balanceData2.debt,
43923
- yieldParams
43924
- );
43925
- newApr.rewards = getRewardYieldBorrow(
43926
- dollarAmount,
43927
- mode,
43928
- rewardFlowDeposits,
43929
- rewardFlowDebt,
43930
- balanceData2.deposits,
43931
- balanceData2.debt,
43932
- yieldParams
43933
- );
43934
- [newApr.intrinsicBorrowApr, newApr.intrinsicDepositApr, newApr.intrinsicApr] = getIntrinsicYieldBorrow(
43935
- dollarAmount,
43936
- intrinsicFlowDeposits,
43937
- intrinsicFlowDebt,
43938
- balanceData2.deposits,
43939
- balanceData2.debt,
43940
- yieldParams
43941
- );
43942
- result.post.aprData = newApr;
44077
+ // src/yields/intrinsic/fetchers/swell.ts
44078
+ var RSWETH_URL = "https://v3-lst.svc.swellnetwork.io/api/tokens/sweth/apr";
44079
+ var rsweth = "Restaked Swell ETH::RSWETH";
44080
+ var rswethFetcher = {
44081
+ label: "RSWETH",
44082
+ fetch: async () => {
44083
+ const res = await fetch(RSWETH_URL, {
44084
+ method: "GET",
44085
+ headers: { Accept: "application/json", "User-Agent": "1delta/yields" }
44086
+ }).then((r) => r.text());
44087
+ return { [rsweth]: Number(res) ?? 0 };
43943
44088
  }
43944
- return result;
43945
- }
44089
+ };
43946
44090
 
43947
- // src/lending/margin/base/borrow.ts
43948
- function computeBorrowDelta2(lender, amount4, price2, balanceData2, config, modeId, apr, yieldParams, irMode, targetMarketUid, positions) {
43949
- if (isSumerType(lender)) {
43950
- if (!positions || targetMarketUid === void 0) {
43951
- throw new Error("Sumer operations require positions and targetMarketUid");
43952
- }
43953
- return computeSumerBorrowDelta(
43954
- amount4,
43955
- price2,
43956
- targetMarketUid,
43957
- balanceData2,
43958
- positions,
43959
- apr,
43960
- yieldParams,
43961
- irMode
43962
- );
44091
+ // src/yields/intrinsic/annualizeRate.ts
44092
+ var YEAR_SECONDS3 = 365 * 24 * 60 * 60;
44093
+ var annualizeGrowthPercent = (growth, elapsedSeconds) => growth * (YEAR_SECONDS3 / elapsedSeconds) * 100;
44094
+ var annualizeRateDeltaPercent = (rateNow, rateThen, elapsedSeconds) => {
44095
+ const growth = typeof rateNow === "bigint" && typeof rateThen === "bigint" ? Number(rateNow - rateThen) / Number(rateThen) : Number(rateNow) / Number(rateThen) - 1;
44096
+ return annualizeGrowthPercent(growth, elapsedSeconds);
44097
+ };
44098
+
44099
+ // src/yields/intrinsic/fetchers/swBTC.ts
44100
+ var CHAIN_ID = "1";
44101
+ var SWBTC = "0x8db2350d78abc13f5673a411d4700bcf87864dde";
44102
+ var ONE_E8 = 10n ** 8n;
44103
+ var WINDOW_SECONDS = 7 * 24 * 60 * 60;
44104
+ var BLOCK_TIME_SECONDS = 12;
44105
+ var WINDOW_BLOCKS = BigInt(Math.floor(WINDOW_SECONDS / BLOCK_TIME_SECONDS));
44106
+ var MAX_RPC_TRIES = 5;
44107
+ var CONVERT_TO_ASSETS_ABI = [
44108
+ {
44109
+ name: "convertToAssets",
44110
+ type: "function",
44111
+ stateMutability: "view",
44112
+ inputs: [{ type: "uint256", name: "shares" }],
44113
+ outputs: [{ type: "uint256" }]
43963
44114
  }
43964
- if (!config || modeId === void 0) {
43965
- throw new Error("Standard operations require config and modeId");
44115
+ ];
44116
+ var readRateAt = (client, blockNumber) => client.readContract({
44117
+ address: SWBTC,
44118
+ abi: CONVERT_TO_ASSETS_ABI,
44119
+ functionName: "convertToAssets",
44120
+ args: [ONE_E8],
44121
+ ...blockNumber !== void 0 ? { blockNumber } : {}
44122
+ });
44123
+ var computeApr = async () => {
44124
+ let lastErr;
44125
+ for (let rpcId = 0; rpcId < MAX_RPC_TRIES; rpcId++) {
44126
+ try {
44127
+ const client = getEvmClient(CHAIN_ID, rpcId);
44128
+ const head = await client.getBlockNumber();
44129
+ const pastBlock = head > WINDOW_BLOCKS ? head - WINDOW_BLOCKS : 0n;
44130
+ const [rateNow, rateThen, headBlock, thenBlock] = await Promise.all([
44131
+ readRateAt(client),
44132
+ readRateAt(client, pastBlock),
44133
+ client.getBlock({ blockNumber: head }),
44134
+ client.getBlock({ blockNumber: pastBlock })
44135
+ ]);
44136
+ if (rateNow < ONE_E8 || rateThen < ONE_E8 || rateNow < rateThen) {
44137
+ throw new Error(
44138
+ `non-archival or invalid rates (now=${rateNow}, then=${rateThen})`
44139
+ );
44140
+ }
44141
+ const elapsed = Number(headBlock.timestamp - thenBlock.timestamp);
44142
+ if (elapsed <= 0) throw new Error(`bad elapsed ${elapsed}`);
44143
+ const apr = annualizeRateDeltaPercent(rateNow, rateThen, elapsed);
44144
+ if (!Number.isFinite(apr) || apr < 0) throw new Error(`bad apr ${apr}`);
44145
+ return apr;
44146
+ } catch (e) {
44147
+ lastErr = e;
44148
+ }
43966
44149
  }
43967
- return computeBorrowDelta(
43968
- amount4,
43969
- price2,
43970
- balanceData2,
43971
- config,
43972
- modeId,
43973
- apr,
43974
- yieldParams,
43975
- irMode
44150
+ throw new Error(
44151
+ `swBTC APR: no archival Ethereum RPC returned valid historical state (${String(lastErr)})`
43976
44152
  );
43977
- }
43978
-
43979
- // src/lending/margin/base/standard/repay.ts
43980
- function computeRepayDelta(amount4, price2, balanceData2, config, modeId, apr, yieldParams, irMode) {
43981
- const { borrowFactor } = getAssetConfig(config, modeId);
43982
- const dollarAmount = amount4 * price2;
43983
- const postTrade = {
43984
- ...balanceData2,
43985
- debt: balanceData2.debt - dollarAmount,
43986
- adjustedDebt: Math.max(0, balanceData2.adjustedDebt - borrowFactor * dollarAmount),
43987
- nav: balanceData2.nav + dollarAmount
43988
- };
43989
- const result = computePostTradeMetrics(balanceData2, postTrade);
43990
- if (apr && yieldParams) {
43991
- const mode = irMode ?? 2;
43992
- const cashFlowDeposits = balanceData2.deposits * apr.depositApr;
43993
- const cashFlowDebt = balanceData2.debt * apr.borrowApr;
43994
- const rewardFlowDeposits = balanceData2.deposits * (apr.rewardDepositApr ?? 0);
43995
- const rewardFlowDebt = balanceData2.debt * (apr.rewardBorrowApr ?? 0);
43996
- const intrinsicFlowDeposits = balanceData2.deposits * apr.intrinsicDepositApr;
43997
- const intrinsicFlowDebt = balanceData2.debt * apr.intrinsicBorrowApr;
43998
- const newApr = { ...apr };
43999
- [newApr.borrowApr, newApr.depositApr, newApr.apr] = getOrganicYieldRepay(
44000
- dollarAmount,
44001
- mode,
44002
- cashFlowDeposits,
44003
- cashFlowDebt,
44004
- balanceData2.deposits,
44005
- balanceData2.debt,
44006
- yieldParams
44007
- );
44008
- newApr.rewards = getRewardYieldRepay(
44009
- dollarAmount,
44010
- mode,
44011
- rewardFlowDeposits,
44012
- rewardFlowDebt,
44013
- balanceData2.deposits,
44014
- balanceData2.debt,
44015
- yieldParams
44016
- );
44017
- [newApr.intrinsicBorrowApr, newApr.intrinsicDepositApr, newApr.intrinsicApr] = getIntrinsicYieldRepay(
44018
- dollarAmount,
44019
- intrinsicFlowDeposits,
44020
- intrinsicFlowDebt,
44021
- balanceData2.deposits,
44022
- balanceData2.debt,
44023
- yieldParams
44024
- );
44025
- result.post.aprData = newApr;
44153
+ };
44154
+ var swBtcFetcher = {
44155
+ label: "SWBTC",
44156
+ fetch: async () => {
44157
+ try {
44158
+ return { "Swell Restaked BTC::SWBTC": await computeApr() };
44159
+ } catch {
44160
+ return { "Swell Restaked BTC::SWBTC": 0 };
44161
+ }
44026
44162
  }
44027
- return result;
44028
- }
44163
+ };
44029
44164
 
44030
- // src/lending/margin/base/repay.ts
44031
- function computeRepayDelta2(lender, amount4, price2, balanceData2, config, modeId, apr, yieldParams, irMode, targetMarketUid, positions) {
44032
- if (isSumerType(lender)) {
44033
- if (!positions || targetMarketUid === void 0) {
44034
- throw new Error("Sumer operations require positions and targetMarketUid");
44035
- }
44036
- return computeSumerRepayDelta(
44037
- amount4,
44038
- price2,
44039
- targetMarketUid,
44040
- balanceData2,
44041
- positions,
44042
- apr,
44043
- yieldParams,
44044
- irMode
44045
- );
44165
+ // src/yields/intrinsic/fetchers/puffer.ts
44166
+ var PUFETH_URL = "https://api-v2.puffer.fi/backend-for-frontend/tvl/all";
44167
+ var pufEth = "PUFETH";
44168
+ var pufethFetcher = {
44169
+ label: "PUFETH",
44170
+ fetch: async () => {
44171
+ const res = await fetch(PUFETH_URL, {
44172
+ method: "GET",
44173
+ headers: { Accept: "application/json" }
44174
+ }).then((r) => r.json());
44175
+ return { [pufEth]: apyToAprPercent(res.apy) };
44046
44176
  }
44047
- if (!config || modeId === void 0) {
44048
- throw new Error("Standard operations require config and modeId");
44177
+ };
44178
+
44179
+ // src/yields/intrinsic/fetchers/stakewise.ts
44180
+ var OSETH_URL = "https://graphs.stakewise.io/mainnet-a/subgraphs/name/stakewise/prod?opName=osTokenApy";
44181
+ var osETH = "StakeWise Staked ETH::OSETH";
44182
+ var osethFetcher = {
44183
+ label: "OSETH",
44184
+ fetch: async () => {
44185
+ const res = await fetch(OSETH_URL, {
44186
+ method: "POST",
44187
+ headers: { Accept: "application/json" },
44188
+ body: JSON.stringify({
44189
+ query: "query osTokenApy { osTokens { apy feePercent }}",
44190
+ operationName: "osTokenApy"
44191
+ })
44192
+ }).then((r) => r.json());
44193
+ const apr = apyToAprPercent(res.data?.osTokens?.[0]?.apy);
44194
+ return {
44195
+ [osETH]: apr,
44196
+ // token-lists unifies every osETH deployment (incl. bridged) to the bare `OSETH` group — emit there too.
44197
+ OSETH: apr
44198
+ };
44049
44199
  }
44050
- return computeRepayDelta(
44051
- amount4,
44052
- price2,
44053
- balanceData2,
44054
- config,
44055
- modeId,
44056
- apr,
44057
- yieldParams,
44058
- irMode
44059
- );
44060
- }
44200
+ };
44061
44201
 
44062
- // src/lending/margin/loop/utils.ts
44063
- var positivePart2 = (n) => n < 0 ? 0 : n;
44064
- function nanTo(possiblyNaN, replacement = Infinity) {
44065
- return isNaN(possiblyNaN) ? replacement : possiblyNaN;
44066
- }
44067
- function getHealthFactor2(collateral, adjustedDebt) {
44068
- if (adjustedDebt === 0) return Infinity;
44069
- const raw = collateral / adjustedDebt;
44070
- return Math.round((isNaN(raw) ? 0 : raw) * 1e4) / 1e4;
44071
- }
44072
- function keysFromMaps(a, b) {
44073
- const set = /* @__PURE__ */ new Set();
44074
- if (a) for (const k of Object.keys(a)) set.add(k);
44075
- if (b) for (const k of Object.keys(b)) set.add(k);
44076
- return [...set];
44077
- }
44078
- function rewardsToMap(rewards) {
44079
- const map = {};
44080
- if (Array.isArray(rewards)) for (const r of rewards) map[r.asset] = r;
44081
- return map;
44082
- }
44083
- function noOpResult(balance, apr) {
44084
- const hf = getHealthFactor2(balance.collateral, balance.adjustedDebt);
44085
- const bc = balance.collateral - balance.adjustedDebt;
44086
- return {
44087
- pre: { healthFactor: hf, borrowCapacity: bc },
44088
- post: { healthFactor: hf, borrowCapacity: bc, balanceData: balance, aprData: apr }
44089
- };
44090
- }
44091
- function buildLoopResult(balance, newBalance, apr, newApr, useAllActive = false) {
44092
- const collateralPost = useAllActive ? newBalance.collateralAllActive : newBalance.collateral;
44093
- return {
44094
- pre: {
44095
- healthFactor: getHealthFactor2(balance.collateral, balance.adjustedDebt),
44096
- borrowCapacity: balance.collateral - balance.adjustedDebt
44097
- },
44098
- post: {
44099
- healthFactor: newBalance.adjustedDebt === 0 ? Infinity : positivePart2(getHealthFactor2(collateralPost, newBalance.adjustedDebt)),
44100
- borrowCapacity: newBalance.collateral - newBalance.adjustedDebt,
44101
- balanceData: newBalance,
44102
- aprData: newApr
44103
- }
44104
- };
44105
- }
44202
+ // src/yields/intrinsic/fetchers/stader.ts
44203
+ var MATICX_URL = "https://universe.staderlabs.com/polygon/apy";
44204
+ var ETHX_URL = "https://universe.staderlabs.com/eth/apy";
44205
+ var ethX = "Stader ETHx::ETHx";
44206
+ var maticxFetcher = {
44207
+ label: "MATICX",
44208
+ fetch: async () => {
44209
+ const res = await fetch(MATICX_URL).then((r) => r.json());
44210
+ return { MATICX: Number(res.value) * 0.9 };
44211
+ }
44212
+ };
44213
+ var ethxFetcher = {
44214
+ label: "ETHX",
44215
+ fetch: async () => {
44216
+ const res = await fetch(ETHX_URL).then((r) => r.json());
44217
+ return { [ethX]: apyToAprPercent(res.value) };
44218
+ }
44219
+ };
44106
44220
 
44107
- // src/lending/margin/loop/yield/getOraganicYieldChange.ts
44108
- function getOrganicYieldOpen(amountInUSD, amountOutUSD, irModeIn, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
44109
- const _flowIn = amountInUSD * (irModeIn === 1 ? yieldIn.stableBorrowRate : yieldIn.variableBorrowRate);
44110
- const _flowOut = amountOutUSD * yieldOut.depositRate;
44111
- const totalCashFlowDebt = cashFlowDebt + _flowIn;
44112
- const totalCashFlowDeposits = cashFlowDeposits + _flowOut;
44113
- const newCollat = deposits + amountOutUSD;
44114
- const newDebt = debt + amountInUSD;
44115
- return [
44116
- totalCashFlowDebt / newDebt,
44117
- totalCashFlowDeposits / newCollat,
44118
- (totalCashFlowDeposits - totalCashFlowDebt) / (newCollat - newDebt)
44119
- ];
44120
- }
44121
- function getOrganicYieldClose(amountInUSD, amountOutUSD, irModeOut, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
44122
- const _flowIn = amountInUSD * yieldIn.depositRate;
44123
- const _flowOut = amountOutUSD * (irModeOut === 1 ? yieldOut.stableBorrowRate : yieldOut.variableBorrowRate);
44124
- const totalCashFlowDebt = cashFlowDebt - _flowOut;
44125
- const totalCashFlowDeposits = cashFlowDeposits - _flowIn;
44126
- const newCollat = deposits - amountInUSD;
44127
- const newDebt = debt - amountOutUSD;
44128
- return [
44129
- Math.abs(newDebt) < 0.01 ? 0 : totalCashFlowDebt / newDebt,
44130
- totalCashFlowDeposits / newCollat,
44131
- (totalCashFlowDeposits - totalCashFlowDebt) / (newCollat - newDebt)
44132
- ];
44133
- }
44134
- function getOrganicYieldDebtSwap(amountInUSD, amountOutUSD, irModeIn, irModeOut, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
44135
- const _flowIn = amountInUSD * (irModeIn === 1 ? yieldIn.stableBorrowRate : yieldIn.variableBorrowRate);
44136
- const _flowOut = amountOutUSD * (irModeOut === 1 ? yieldOut.stableBorrowRate : yieldOut.variableBorrowRate);
44137
- const totalCashFlowDebt = cashFlowDebt + _flowIn - _flowOut;
44138
- const newDebt = debt - amountOutUSD + amountInUSD;
44139
- return [
44140
- Math.abs(newDebt) < 0.01 ? 0 : totalCashFlowDebt / newDebt,
44141
- cashFlowDeposits / deposits,
44142
- (cashFlowDeposits - totalCashFlowDebt) / (deposits - newDebt)
44143
- ];
44144
- }
44145
- function getOrganicYieldCollateralSwap(amountInUSD, amountOutUSD, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
44146
- const _flowIn = amountInUSD * yieldIn.depositRate;
44147
- const _flowOut = amountOutUSD * yieldOut.depositRate;
44148
- const totalCashFlowDeposits = cashFlowDeposits + _flowOut - _flowIn;
44149
- const newCollat = deposits + amountOutUSD - amountInUSD;
44150
- return [
44151
- Math.abs(debt) < 0.01 ? 0 : cashFlowDebt / debt,
44152
- totalCashFlowDeposits / newCollat,
44153
- (totalCashFlowDeposits - cashFlowDebt) / (newCollat - debt)
44154
- ];
44155
- }
44221
+ // src/yields/intrinsic/fetchers/trufin.ts
44222
+ var APY_URL = "https://api.trufin.io/staker/apy?staker=";
44223
+ var createTruFinFetcher = (staker, yieldKey) => ({
44224
+ label: yieldKey,
44225
+ fetch: async () => {
44226
+ const res = await fetch(APY_URL + staker).then((r) => r.json());
44227
+ return { [yieldKey]: apyToAprPercent(res.apy) };
44228
+ }
44229
+ });
44230
+ var trumaticFetcher = createTruFinFetcher("MATIC", "TRUMATIC");
44231
+ var trupolFetcher = createTruFinFetcher("POL", "TRUPOL");
44156
44232
 
44157
- // src/lending/margin/loop/yield/getRewardYieldChange.ts
44158
- function getRewardYieldOpen(amountInUSD, amountOutUSD, irModeIn, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
44159
- const mapIn = rewardsToMap(yieldIn?.rewards);
44160
- const mapOut = rewardsToMap(yieldOut?.rewards);
44161
- if (!yieldIn?.rewards?.length && !yieldOut?.rewards?.length) return {};
44162
- const data = {};
44163
- for (const key3 of keysFromMaps(mapIn, mapOut)) {
44164
- const _flowIn = amountInUSD * ((irModeIn === 1 ? mapIn[key3]?.stableBorrowRate : mapIn[key3]?.variableBorrowRate) ?? 0);
44165
- const _flowOut = amountOutUSD * (mapOut[key3]?.depositRate ?? 0);
44166
- const totalCashFlowDebt = cashFlowDebt + _flowIn;
44167
- const totalCashFlowDeposits = cashFlowDeposits + _flowOut;
44168
- const newCollat = deposits + amountOutUSD;
44169
- const newDebt = debt + amountInUSD;
44170
- data[key3] = {
44171
- borrowApr: totalCashFlowDebt / newDebt,
44172
- depositApr: totalCashFlowDeposits / newCollat,
44173
- apr: (cashFlowDeposits + cashFlowDebt + _flowIn + _flowOut) / (newCollat - newDebt)
44174
- };
44233
+ // src/yields/intrinsic/fetchers/defillama.ts
44234
+ var POOLS_ENRICHED = "https://yields.llama.fi/poolsEnriched?pool=";
44235
+ var fetchDefiLlamaApy = async (poolId) => {
44236
+ const res = await fetch(POOLS_ENRICHED + poolId, {
44237
+ headers: { accept: "application/json" },
44238
+ signal: AbortSignal.timeout(8e3)
44239
+ });
44240
+ if (!res.ok) throw new Error(`DefiLlama HTTP ${res.status}`);
44241
+ const json = await res.json();
44242
+ const apy = json?.data?.[0]?.apy;
44243
+ if (typeof apy !== "number" || !Number.isFinite(apy)) {
44244
+ throw new Error(`DefiLlama: no apy for pool ${poolId}`);
44175
44245
  }
44176
- return data;
44177
- }
44178
- function getRewardYieldClose(amountInUSD, amountOutUSD, irModeOut, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
44179
- const mapIn = rewardsToMap(yieldIn?.rewards);
44180
- const mapOut = rewardsToMap(yieldOut?.rewards);
44181
- if (!yieldIn?.rewards?.length && !yieldOut?.rewards?.length) return {};
44182
- const data = {};
44183
- for (const key3 of keysFromMaps(mapIn, mapOut)) {
44184
- const _flowIn = amountInUSD * (mapIn[key3]?.depositRate ?? 0);
44185
- const _flowOut = amountOutUSD * ((irModeOut === 1 ? mapOut[key3]?.stableBorrowRate : mapOut[key3]?.variableBorrowRate) ?? 0);
44186
- const totalCashFlowDebt = cashFlowDebt - _flowOut;
44187
- const totalCashFlowDeposits = cashFlowDeposits - _flowIn;
44188
- const newCollat = deposits - amountInUSD;
44189
- const newDebt = debt - amountOutUSD;
44190
- data[key3] = {
44191
- borrowApr: Math.abs(newDebt) < 0.01 ? 0 : totalCashFlowDebt / newDebt,
44192
- depositApr: totalCashFlowDeposits / newCollat,
44193
- apr: (cashFlowDeposits + cashFlowDebt - _flowIn - _flowOut) / (newCollat - newDebt)
44194
- };
44246
+ return apy;
44247
+ };
44248
+
44249
+ // src/yields/intrinsic/fetchers/kinetiq.ts
44250
+ var KHYPE_POOL_ID = "9f25a954-db87-4bb2-a8b2-4be0b843a44c";
44251
+ var KHYPE_KEY = "Kinetiq Staked HYPE::kHYPE";
44252
+ var kinetiqKHypeFetcher = {
44253
+ label: "KHYPE",
44254
+ fetch: async () => {
44255
+ const apy = await fetchDefiLlamaApy(KHYPE_POOL_ID);
44256
+ return { [KHYPE_KEY]: apyToAprPercent(apy) };
44195
44257
  }
44196
- return data;
44197
- }
44198
- function getRewardYieldDebtSwap(amountInUSD, amountOutUSD, irModeIn, irModeOut, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
44199
- const mapIn = rewardsToMap(yieldIn?.rewards);
44200
- const mapOut = rewardsToMap(yieldOut?.rewards);
44201
- if (!yieldIn?.rewards?.length && !yieldOut?.rewards?.length) return {};
44202
- const data = {};
44203
- for (const key3 of keysFromMaps(mapIn, mapOut)) {
44204
- const _flowIn = amountInUSD * ((irModeIn === 1 ? mapIn[key3]?.stableBorrowRate : mapIn[key3]?.variableBorrowRate) ?? 0);
44205
- const _flowOut = amountOutUSD * ((irModeOut === 1 ? mapOut[key3]?.stableBorrowRate : mapOut[key3]?.variableBorrowRate) ?? 0);
44206
- const totalCashFlowDebt = cashFlowDebt + _flowIn - _flowOut;
44207
- const newDebt = debt - amountOutUSD + amountInUSD;
44208
- data[key3] = {
44209
- borrowApr: Math.abs(newDebt) < 0.01 ? 0 : totalCashFlowDebt / newDebt,
44210
- depositApr: cashFlowDeposits / deposits,
44211
- apr: (cashFlowDeposits + totalCashFlowDebt) / (deposits - newDebt)
44212
- };
44258
+ };
44259
+
44260
+ // src/yields/intrinsic/fetchers/hyperbeat.ts
44261
+ var HBHYPE_URL = "https://api.hyperbeat.org/api/v1/staking?address=0xCeaD893b162D38e714D82d06a7fe0b0dc3c38E0b";
44262
+ var HBUHYPE_URL = "https://app.hyperbeat.org/api/hyperfolio/vault-infos?vaultAddress=0x96C6cBB6251Ee1c257b2162ca0f39AA5Fa44B1FB";
44263
+ var hbhype = "hyperbeat x ether.fi HYPE::beHYPE";
44264
+ var hbuhype = "Hyperbeat Ultra Hype::hbHYPE";
44265
+ var hbhypeFetcher = {
44266
+ label: "HBHYPE",
44267
+ fetch: async () => {
44268
+ try {
44269
+ const response = await fetch(HBHYPE_URL);
44270
+ if (!response.ok) {
44271
+ throw new Error(`HTTP error! Status: ${response.status}`);
44272
+ }
44273
+ const result = await response.json();
44274
+ if (!result.success || !result.data || !Array.isArray(result.data.delegations)) {
44275
+ throw new Error("Invalid response structure");
44276
+ }
44277
+ const delegations = result.data.delegations;
44278
+ const totalApr = delegations.reduce(
44279
+ (sum3, validator) => sum3 + Number(validator.apr ?? 0),
44280
+ 0
44281
+ );
44282
+ const averageApr = totalApr / delegations.length;
44283
+ return { [hbhype]: averageApr };
44284
+ } catch (e) {
44285
+ return { [hbhype]: 0 };
44286
+ }
44213
44287
  }
44214
- return data;
44215
- }
44216
- function getRewardYieldCollateralSwap(amountInUSD, amountOutUSD, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
44217
- const mapIn = rewardsToMap(yieldIn?.rewards);
44218
- const mapOut = rewardsToMap(yieldOut?.rewards);
44219
- if (!yieldIn?.rewards?.length && !yieldOut?.rewards?.length) return {};
44220
- const data = {};
44221
- for (const key3 of keysFromMaps(mapIn, mapOut)) {
44222
- const _flowIn = amountInUSD * (mapIn[key3]?.depositRate ?? 0);
44223
- const _flowOut = amountOutUSD * (mapOut[key3]?.depositRate ?? 0);
44224
- const totalCashFlowDeposits = cashFlowDeposits + _flowOut - _flowIn;
44225
- const newCollat = deposits + amountOutUSD - amountInUSD;
44226
- data[key3] = {
44227
- borrowApr: Math.abs(debt) < 0.01 ? 0 : cashFlowDebt / debt,
44228
- depositApr: totalCashFlowDeposits / newCollat,
44229
- apr: (totalCashFlowDeposits + cashFlowDebt) / (newCollat - debt)
44230
- };
44288
+ };
44289
+ var hbuhypeFetcher = {
44290
+ label: "HBUHYPE",
44291
+ fetch: async () => {
44292
+ try {
44293
+ const response = await fetch(HBUHYPE_URL);
44294
+ if (!response.ok) {
44295
+ throw new Error(`HTTP error! Status: ${response.status}`);
44296
+ }
44297
+ const result = await response.json();
44298
+ const apy = result.currentAPY?.apy_1d ?? 0;
44299
+ return { [hbuhype]: apyToAprPercent(apy) };
44300
+ } catch (e) {
44301
+ return { [hbuhype]: 0 };
44302
+ }
44231
44303
  }
44232
- return data;
44233
- }
44304
+ };
44305
+ var HYPERBEAT_VAULTS = [
44306
+ {
44307
+ address: "0x5e105266db42f78FA814322Bce7f388B4C2e61eb",
44308
+ key: "Hyperbeat USDT::hbUSDT"
44309
+ },
44310
+ {
44311
+ address: "0x057ced81348D57Aad579A672d521d7b4396E8a61",
44312
+ key: "Hyperbeat USDC::hbUSDC"
44313
+ },
44314
+ {
44315
+ address: "0x81e064d0eB539de7c3170EDF38C1A42CBd752A76",
44316
+ key: "Hyperbeat LST Vault::lstHYPE"
44317
+ },
44318
+ {
44319
+ address: "0x441794D6a8F9A3739F5D4E98a728937b33489D29",
44320
+ key: "Liquid HYPE Yield::liquidHYPE"
44321
+ }
44322
+ ];
44323
+ var HYPERBEAT_VAULT_APY_URL = (address) => `https://api.hyperbeat.org/api/v1/vaults/apy/${address}?limit=1`;
44324
+ var hyperbeatVaultsFetcher = {
44325
+ label: "HYPERBEAT_VAULTS",
44326
+ fetch: async () => {
44327
+ const out = {};
44328
+ await Promise.all(
44329
+ HYPERBEAT_VAULTS.map(async ({ address, key: key3 }) => {
44330
+ try {
44331
+ const response = await fetch(HYPERBEAT_VAULT_APY_URL(address));
44332
+ if (!response.ok) {
44333
+ throw new Error(`HTTP error! Status: ${response.status}`);
44334
+ }
44335
+ const result = await response.json();
44336
+ const apy = Number(
44337
+ result.current_apy?.apy_7d ?? result.current_apy?.apy ?? 0
44338
+ );
44339
+ out[key3] = apyToAprPercent(apy);
44340
+ } catch (e) {
44341
+ out[key3] = 0;
44342
+ }
44343
+ })
44344
+ );
44345
+ return out;
44346
+ }
44347
+ };
44234
44348
 
44235
- // src/lending/margin/loop/yield/getIntrinsicYieldChange.ts
44236
- function getIntrinsicYieldOpen(amountInUSD, amountOutUSD, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
44237
- const _flowIn = amountInUSD * yieldIn.intrinsicYield;
44238
- const _flowOut = amountOutUSD * yieldOut.intrinsicYield;
44239
- const totalCashFlowDebt = cashFlowDebt + _flowIn;
44240
- const totalCashFlowDeposits = cashFlowDeposits + _flowOut;
44241
- const newCollat = deposits + amountOutUSD;
44242
- const newDebt = debt + amountInUSD;
44243
- return [
44244
- totalCashFlowDebt / newDebt,
44245
- totalCashFlowDeposits / newCollat,
44246
- (totalCashFlowDeposits - totalCashFlowDebt) / (newCollat - newDebt)
44247
- ];
44248
- }
44249
- function getIntrinsicYieldClose(amountInUSD, amountOutUSD, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
44250
- const _flowIn = amountInUSD * yieldIn.intrinsicYield;
44251
- const _flowOut = amountOutUSD * yieldOut.intrinsicYield;
44252
- const totalCashFlowDebt = cashFlowDebt - _flowOut;
44253
- const totalCashFlowDeposits = cashFlowDeposits - _flowIn;
44254
- const newCollat = deposits - amountInUSD;
44255
- const newDebt = debt - amountOutUSD;
44256
- return [
44257
- Math.abs(newDebt) < 0.01 ? 0 : totalCashFlowDebt / newDebt,
44258
- totalCashFlowDeposits / newCollat,
44259
- (totalCashFlowDeposits - totalCashFlowDebt) / (newCollat - newDebt)
44260
- ];
44261
- }
44262
- function getIntrinsicYieldDebtSwap(amountInUSD, amountOutUSD, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
44263
- const _flowIn = amountInUSD * yieldIn.intrinsicYield;
44264
- const _flowOut = amountOutUSD * yieldOut.intrinsicYield;
44265
- const totalCashFlowDebt = cashFlowDebt + _flowIn - _flowOut;
44266
- const newDebt = debt - amountOutUSD + amountInUSD;
44267
- return [
44268
- Math.abs(newDebt) < 0.01 ? 0 : totalCashFlowDebt / newDebt,
44269
- cashFlowDeposits / deposits,
44270
- (cashFlowDeposits - totalCashFlowDebt) / (deposits - newDebt)
44271
- ];
44272
- }
44273
- function getIntrinsicYieldCollateralSwap(amountInUSD, amountOutUSD, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
44274
- const _flowIn = amountInUSD * yieldIn.intrinsicYield;
44275
- const _flowOut = amountOutUSD * yieldOut.intrinsicYield;
44276
- const totalCashFlowDeposits = cashFlowDeposits + _flowOut - _flowIn;
44277
- const newCollat = deposits + amountOutUSD - amountInUSD;
44278
- return [
44279
- Math.abs(debt) < 0.01 ? 0 : cashFlowDebt / debt,
44280
- totalCashFlowDeposits / newCollat,
44281
- (totalCashFlowDeposits - cashFlowDebt) / (newCollat - debt)
44282
- ];
44283
- }
44349
+ // src/yields/intrinsic/fetchers/coinbase.ts
44350
+ var CBETH_URL = "https://api.exchange.coinbase.com/wrapped-assets/cbeth";
44351
+ var cbethFetcher = {
44352
+ label: "CBETH",
44353
+ fetch: async () => {
44354
+ try {
44355
+ const res = await fetch(CBETH_URL, {
44356
+ headers: {
44357
+ "User-Agent": "1delta/yields",
44358
+ "Content-Type": "application/json"
44359
+ }
44360
+ }).then((r) => r.json());
44361
+ return { CBETH: apyToAprPercent(res.apy) * 100 };
44362
+ } catch (e) {
44363
+ console.log("CBETH failed", e);
44364
+ return { CBETH: 0 };
44365
+ }
44366
+ }
44367
+ };
44284
44368
 
44285
- // src/lending/margin/loop/compute/computeCloseDeltas.ts
44286
- function computeCloseTradeDeltas(dollarIn, dollarOut, targetMode, yieldParamsIn, yieldParamsOut, balance, apr, bfOut, ltvIn, collateralLtvIn) {
44287
- if (dollarIn === 0 || dollarOut === 0) return noOpResult(balance, apr);
44288
- const cashFlowDeposits = balance.deposits * apr.depositApr;
44289
- const cashFlowDebt = balance.debt * apr.borrowApr;
44290
- const rewardFlowDeposits = balance.deposits * (apr.rewardDepositApr ?? 0);
44291
- const rewardFlowDebt = balance.debt * (apr.rewardBorrowApr ?? 0);
44292
- const intrinsicFlowDeposits = balance.deposits * apr.intrinsicDepositApr;
44293
- const intrinsicFlowDebt = balance.debt * apr.intrinsicBorrowApr;
44294
- const newBalance = { ...balance };
44295
- const newApr = { ...apr };
44296
- newBalance.debt = positivePart2(newBalance.debt - dollarOut);
44297
- newBalance.borrowDiscountedCollateral = positivePart2(
44298
- newBalance.borrowDiscountedCollateral - ltvIn * dollarIn
44299
- );
44300
- newBalance.collateral = positivePart2(
44301
- newBalance.collateral - collateralLtvIn * dollarIn
44302
- );
44303
- newBalance.deposits = positivePart2(newBalance.deposits - dollarIn);
44304
- newBalance.adjustedDebt = positivePart2(
44305
- newBalance.adjustedDebt - bfOut * dollarOut
44306
- );
44307
- newBalance.nav += dollarOut - dollarIn;
44308
- [newApr.borrowApr, newApr.depositApr, newApr.apr] = getOrganicYieldClose(
44309
- dollarIn,
44310
- dollarOut,
44311
- targetMode,
44312
- cashFlowDeposits,
44313
- cashFlowDebt,
44314
- balance.deposits,
44315
- balance.debt,
44316
- yieldParamsIn,
44317
- yieldParamsOut
44318
- );
44319
- newApr.rewards = getRewardYieldClose(
44320
- dollarIn,
44321
- dollarOut,
44322
- targetMode,
44323
- rewardFlowDeposits,
44324
- rewardFlowDebt,
44325
- balance.deposits,
44326
- balance.debt,
44327
- yieldParamsIn,
44328
- yieldParamsOut
44329
- );
44330
- [newApr.intrinsicBorrowApr, newApr.intrinsicDepositApr, newApr.intrinsicApr] = getIntrinsicYieldClose(
44331
- dollarIn,
44332
- dollarOut,
44333
- intrinsicFlowDeposits,
44334
- intrinsicFlowDebt,
44335
- balance.deposits,
44336
- balance.debt,
44337
- yieldParamsIn,
44338
- yieldParamsOut
44339
- );
44340
- return buildLoopResult(balance, newBalance, apr, newApr);
44341
- }
44342
-
44343
- // src/lending/margin/loop/compute/computeCollateralSwapDeltas.ts
44344
- function computeCollateralSwapDeltas(dollarIn, dollarOut, yieldParamsIn, yieldParamsOut, balance, apr, ltvIn, collateralLtvIn, ltvOut, collateralLtvOut) {
44345
- if (dollarIn === 0 || dollarOut === 0) return noOpResult(balance, apr);
44346
- const cashFlowDeposits = balance.deposits * apr.depositApr;
44347
- const cashFlowDebt = balance.debt * apr.borrowApr;
44348
- const rewardFlowDeposits = balance.deposits * (apr.rewardDepositApr ?? 0);
44349
- const rewardFlowDebt = balance.debt * (apr.rewardBorrowApr ?? 0);
44350
- const intrinsicFlowDeposits = balance.deposits * apr.intrinsicDepositApr;
44351
- const intrinsicFlowDebt = balance.debt * apr.intrinsicBorrowApr;
44352
- const newBalance = { ...balance };
44353
- const newApr = { ...apr };
44354
- newBalance.borrowDiscountedCollateral += ltvOut * dollarOut - ltvIn * dollarIn;
44355
- newBalance.deposits += dollarOut - dollarIn;
44356
- newBalance.collateral += collateralLtvOut * dollarOut - collateralLtvIn * dollarIn;
44357
- newBalance.nav += dollarOut - dollarIn;
44358
- [newApr.borrowApr, newApr.depositApr, newApr.apr] = getOrganicYieldCollateralSwap(
44359
- dollarIn,
44360
- dollarOut,
44361
- cashFlowDeposits,
44362
- cashFlowDebt,
44363
- balance.deposits,
44364
- balance.debt,
44365
- yieldParamsIn,
44366
- yieldParamsOut
44367
- );
44368
- newApr.rewards = getRewardYieldCollateralSwap(
44369
- dollarIn,
44370
- dollarOut,
44371
- rewardFlowDeposits,
44372
- rewardFlowDebt,
44373
- balance.deposits,
44374
- balance.debt,
44375
- yieldParamsIn,
44376
- yieldParamsOut
44377
- );
44378
- [newApr.intrinsicBorrowApr, newApr.intrinsicDepositApr, newApr.intrinsicApr] = getIntrinsicYieldCollateralSwap(
44379
- dollarIn,
44380
- dollarOut,
44381
- intrinsicFlowDeposits,
44382
- intrinsicFlowDebt,
44383
- balance.deposits,
44384
- balance.debt,
44385
- yieldParamsIn,
44386
- yieldParamsOut
44387
- );
44388
- return buildLoopResult(balance, newBalance, apr, newApr);
44389
- }
44390
-
44391
- // src/lending/margin/loop/compute/computeDebtSwapDeltas.ts
44392
- function computeDebtSwapDeltas(dollarIn, dollarOut, sourceMode, targetMode, yieldParamsIn, yieldParamsOut, balance, apr, bfInFactor, bfOutFactor) {
44393
- if (dollarIn === 0 || dollarOut === 0) return noOpResult(balance, apr);
44394
- const cashFlowDeposits = balance.deposits * apr.depositApr;
44395
- const cashFlowDebt = balance.debt * apr.borrowApr;
44396
- const rewardFlowDeposits = balance.deposits * (apr.rewardDepositApr ?? 0);
44397
- const rewardFlowDebt = balance.debt * apr.rewardBorrowApr;
44398
- const intrinsicFlowDeposits = balance.deposits * apr.intrinsicDepositApr;
44399
- const intrinsicFlowDebt = balance.debt * apr.intrinsicBorrowApr;
44400
- const newBalance = { ...balance };
44401
- const newApr = { ...apr };
44402
- newBalance.debt += dollarOut - dollarIn;
44403
- newBalance.adjustedDebt += bfOutFactor * dollarOut - bfInFactor * dollarIn;
44404
- newBalance.nav += dollarOut - dollarIn;
44405
- [newApr.borrowApr, newApr.depositApr, newApr.apr] = getOrganicYieldDebtSwap(
44406
- dollarIn,
44407
- dollarOut,
44408
- sourceMode,
44409
- targetMode,
44410
- cashFlowDeposits,
44411
- cashFlowDebt,
44412
- balance.deposits,
44413
- balance.debt,
44414
- yieldParamsIn,
44415
- yieldParamsOut
44416
- );
44417
- newApr.rewards = getRewardYieldDebtSwap(
44418
- dollarIn,
44419
- dollarOut,
44420
- sourceMode,
44421
- targetMode,
44422
- rewardFlowDeposits,
44423
- rewardFlowDebt,
44424
- balance.deposits,
44425
- balance.debt,
44426
- yieldParamsIn,
44427
- yieldParamsOut
44428
- );
44429
- [newApr.intrinsicBorrowApr, newApr.intrinsicDepositApr, newApr.intrinsicApr] = getIntrinsicYieldDebtSwap(
44430
- dollarIn,
44431
- dollarOut,
44432
- intrinsicFlowDeposits,
44433
- intrinsicFlowDebt,
44434
- balance.deposits,
44435
- balance.debt,
44436
- yieldParamsIn,
44437
- yieldParamsOut
44438
- );
44439
- return buildLoopResult(balance, newBalance, apr, newApr);
44440
- }
44441
-
44442
- // src/lending/margin/loop/compute/computeOpenDeltas.ts
44443
- function computeOpenTradeDeltas(dollarIn, dollarOut, sourceMode, yieldParamsIn, yieldParamsOut, balance, apr, bfIn, collateralLtvOut, borrowLtvOut, useAllActive = false) {
44444
- if (dollarIn === 0 || dollarOut === 0) return noOpResult(balance, apr);
44445
- const cashFlowDeposits = balance.deposits * apr.depositApr;
44446
- const cashFlowDebt = balance.debt * apr.borrowApr;
44447
- const rewardFlowDeposits = balance.deposits * (apr.rewardDepositApr ?? 0);
44448
- const rewardFlowDebt = balance.debt * (apr.rewardBorrowApr ?? 0);
44449
- const intrinsicFlowDeposits = balance.deposits * apr.intrinsicDepositApr;
44450
- const intrinsicFlowDebt = balance.debt * apr.intrinsicBorrowApr;
44451
- const newBalance = { ...balance };
44452
- const newApr = { ...apr };
44453
- newBalance.debt += dollarIn;
44454
- newBalance.borrowDiscountedCollateral += borrowLtvOut * dollarOut;
44455
- newBalance.borrowDiscountedCollateralAllActive += borrowLtvOut * dollarOut;
44456
- newBalance.collateral += collateralLtvOut * dollarOut;
44457
- newBalance.collateralAllActive += collateralLtvOut * dollarOut;
44458
- newBalance.deposits += dollarOut;
44459
- newBalance.adjustedDebt += bfIn * dollarIn;
44460
- newBalance.nav += dollarOut - dollarIn;
44461
- [newApr.borrowApr, newApr.depositApr, newApr.apr] = getOrganicYieldOpen(
44462
- dollarIn,
44463
- dollarOut,
44464
- sourceMode,
44465
- cashFlowDeposits,
44466
- cashFlowDebt,
44467
- balance.deposits,
44468
- balance.debt,
44469
- yieldParamsIn,
44470
- yieldParamsOut
44471
- );
44472
- newApr.rewards = getRewardYieldOpen(
44473
- dollarIn,
44474
- dollarOut,
44475
- sourceMode,
44476
- rewardFlowDeposits,
44477
- rewardFlowDebt,
44478
- balance.deposits,
44479
- balance.debt,
44480
- yieldParamsIn,
44481
- yieldParamsOut
44482
- );
44483
- [newApr.intrinsicBorrowApr, newApr.intrinsicDepositApr, newApr.intrinsicApr] = getIntrinsicYieldOpen(
44484
- dollarIn,
44485
- dollarOut,
44486
- intrinsicFlowDeposits,
44487
- intrinsicFlowDebt,
44488
- balance.deposits,
44489
- balance.debt,
44490
- yieldParamsIn,
44491
- yieldParamsOut
44492
- );
44493
- return buildLoopResult(balance, newBalance, apr, newApr, useAllActive);
44494
- }
44495
-
44496
- // src/lending/margin/loop/compute/computeZapDeltas.ts
44497
- function computeZapTradeDeltas(dollarIn, dollarOut, sourceMode, yieldParamsIn, yieldParamsOut, balance, apr, bfIn, collateralLtvOut, borrowLtvOut) {
44498
- if (dollarIn === 0 || dollarOut === 0) return noOpResult(balance, apr);
44499
- const cashFlowDeposits = balance.deposits * apr.depositApr;
44500
- const cashFlowDebt = balance.debt * apr.borrowApr;
44501
- const rewardFlowDeposits = balance.deposits * (apr.rewardDepositApr ?? 0);
44502
- const rewardFlowDebt = balance.debt * (apr.rewardBorrowApr ?? 0);
44503
- const intrinsicFlowDeposits = balance.deposits * apr.intrinsicDepositApr;
44504
- const intrinsicFlowDebt = balance.debt * apr.intrinsicBorrowApr;
44505
- const newBalance = { ...balance };
44506
- const newApr = { ...apr };
44507
- newBalance.debt += dollarIn;
44508
- newBalance.borrowDiscountedCollateral += borrowLtvOut * dollarOut;
44509
- newBalance.collateral += collateralLtvOut * dollarOut;
44510
- newBalance.deposits += dollarOut;
44511
- newBalance.adjustedDebt += bfIn * dollarIn;
44512
- newBalance.nav += dollarOut - dollarIn;
44513
- [newApr.borrowApr, newApr.depositApr, newApr.apr] = getOrganicYieldOpen(
44514
- dollarIn,
44515
- dollarOut,
44516
- sourceMode,
44517
- cashFlowDeposits,
44518
- cashFlowDebt,
44519
- balance.deposits,
44520
- balance.debt,
44521
- yieldParamsIn,
44522
- yieldParamsOut
44523
- );
44524
- newApr.rewards = getRewardYieldOpen(
44525
- dollarIn,
44526
- dollarOut,
44527
- sourceMode,
44528
- rewardFlowDeposits,
44529
- rewardFlowDebt,
44530
- balance.deposits,
44531
- balance.debt,
44532
- yieldParamsIn,
44533
- yieldParamsOut
44534
- );
44535
- [newApr.intrinsicBorrowApr, newApr.intrinsicDepositApr, newApr.intrinsicApr] = getIntrinsicYieldOpen(
44536
- dollarIn,
44537
- dollarOut,
44538
- intrinsicFlowDeposits,
44539
- intrinsicFlowDebt,
44540
- balance.deposits,
44541
- balance.debt,
44542
- yieldParamsIn,
44543
- yieldParamsOut
44544
- );
44545
- return buildLoopResult(balance, newBalance, apr, newApr);
44546
- }
44547
-
44548
- // src/lending/margin/loop/ranges/getMaxAmountOpen.ts
44549
- var MaxParamThresholds = /* @__PURE__ */ ((MaxParamThresholds2) => {
44550
- MaxParamThresholds2[MaxParamThresholds2["MIN_HF"] = 1] = "MIN_HF";
44551
- MaxParamThresholds2[MaxParamThresholds2["SAME_OPEN_HF"] = 1.1] = "SAME_OPEN_HF";
44552
- MaxParamThresholds2[MaxParamThresholds2["SAFE_HF"] = 1.01] = "SAFE_HF";
44553
- return MaxParamThresholds2;
44554
- })(MaxParamThresholds || {});
44555
- function getMaxAmountOpen(borrowDiscountedCollateral, collateral, debt, cfOut, bfIn, sameAsset = false) {
44556
- if (sameAsset) {
44557
- return (collateral - 1.1 /* SAME_OPEN_HF */ * debt) / (1.1 /* SAME_OPEN_HF */ * bfIn - cfOut);
44369
+ // src/yields/intrinsic/fetchers/mantle.ts
44370
+ var METH_URL = "https://meth.mantle.xyz/api/stats/apy";
44371
+ var methFetcher = {
44372
+ label: "METH",
44373
+ fetch: async () => {
44374
+ const res = await fetch(METH_URL).then((r) => r.json());
44375
+ const apr = apyToApr(Number(res.data[0]?.OneDayAPY)) * 100;
44376
+ return { METH: apr, CMETH: apr };
44558
44377
  }
44559
- return (borrowDiscountedCollateral - 1.01 /* SAFE_HF */ * debt) / (1.01 /* SAFE_HF */ * bfIn - cfOut);
44560
- }
44378
+ };
44561
44379
 
44562
- // src/lending/margin/loop/ranges/getMaxAmountCollateralSwap.ts
44563
- function getMaxAmountCollateralSwap(borrowDiscountedCollateral, adjustedDebt, ltvIn, ltvOut) {
44564
- if (ltvOut >= ltvIn) return Infinity;
44565
- const denominator = ltvIn - ltvOut;
44566
- return (borrowDiscountedCollateral - 1.01 /* SAFE_HF */ * adjustedDebt) / denominator;
44380
+ // src/yields/intrinsic/fetchers/yieldnest.ts
44381
+ var YIELDNEST_URL = "https://gateway.yieldnest.finance/api/v1/graphql";
44382
+ var YIELDNEST_GQL_QUERY = "query GetTokenMetrics($networkType: NetworkType!) { getLRTsData(networkType: $networkType) { tokens { token blockchains { chainId apr { apr31d } } } } }";
44383
+ var YN_TOKENS = [
44384
+ { symbol: "ynETHx", chainId: 1, key: "ynETH MAX::YNETHX" },
44385
+ { symbol: "ynETH", chainId: 1, key: "YieldNest Restaked ETH::YNETH" },
44386
+ {
44387
+ symbol: "ynLSDe",
44388
+ chainId: 1,
44389
+ key: "YieldNest Restaked LSD Eigenlayer::YNLSDE"
44390
+ },
44391
+ { symbol: "ynRWAx", chainId: 1, key: "YieldNest RWA MAX::YNRWAX" },
44392
+ { symbol: "ynUSDx", chainId: 1, key: "ynUSD Max::YNUSDX" },
44393
+ { symbol: "STAK", chainId: 1, key: "YieldNest STAK::STAK" },
44394
+ { symbol: "ynBNBx", chainId: 56, key: "ynBNB MAX::ynBNBx" },
44395
+ { symbol: "ynBNB", chainId: 56, key: "YieldNest Restaked BNB::ynBNB" },
44396
+ { symbol: "ynBTCk", chainId: 56, key: "YieldNest BTC Kernel::ynBTCk" }
44397
+ ];
44398
+ function findApr(tokens, symbol, chainId) {
44399
+ const apr = tokens.find((t) => t.token === symbol)?.blockchains?.find((b) => b.chainId === chainId)?.apr?.apr31d;
44400
+ return Number(apr ?? 0);
44567
44401
  }
44402
+ var yieldNestFetcher = {
44403
+ label: "YIELDNEST",
44404
+ fetch: async () => {
44405
+ const res = await fetch(YIELDNEST_URL, {
44406
+ method: "POST",
44407
+ headers: {
44408
+ Accept: "application/json",
44409
+ "Content-Type": "application/json"
44410
+ },
44411
+ body: JSON.stringify({
44412
+ operationName: "GetTokenMetrics",
44413
+ variables: { networkType: "mainnet" },
44414
+ query: YIELDNEST_GQL_QUERY
44415
+ })
44416
+ }).then((r) => r.json());
44417
+ const tokens = res?.data?.getLRTsData?.tokens ?? [];
44418
+ const result = {};
44419
+ for (const { symbol, chainId, key: key3 } of YN_TOKENS) {
44420
+ const apr = findApr(tokens, symbol, chainId);
44421
+ if (apr > 0) result[key3] = apr;
44422
+ }
44423
+ return result;
44424
+ }
44425
+ };
44568
44426
 
44569
- // src/lending/margin/loop/ranges/getMaxAmountDebtSwap.ts
44570
- function getMaxAmountDebtSwap(borrowDiscountedCollateral, adjustedDebt, bfIn, bfOut) {
44571
- if (bfOut <= bfIn) return Infinity;
44572
- const denominator = 1.01 /* SAFE_HF */ * (bfOut - bfIn);
44573
- return (borrowDiscountedCollateral - 1.01 /* SAFE_HF */ * adjustedDebt) / denominator;
44574
- }
44427
+ // src/yields/intrinsic/fetchers/stS.ts
44428
+ var BEETS_URL = "https://backend-v3.beets-ftm-node.com/";
44429
+ var stS = "Beets Staked Sonic::STS";
44430
+ var stsFetcher = {
44431
+ label: "STS",
44432
+ fetch: async () => {
44433
+ const res = await fetch(BEETS_URL, {
44434
+ method: "POST",
44435
+ headers: {
44436
+ Accept: "application/json",
44437
+ "Content-Type": "application/json"
44438
+ },
44439
+ body: JSON.stringify({
44440
+ operationName: "GetStakedSonicData",
44441
+ query: "query GetStakedSonicData { stsGetGqlStakedSonicData { stakingApr } }"
44442
+ })
44443
+ }).then((r) => r.json());
44444
+ const apr = Number(res.data?.stsGetGqlStakedSonicData?.stakingApr) * 100;
44445
+ return { [stS]: apr };
44446
+ }
44447
+ };
44575
44448
 
44576
- // src/lending/margin/loop/ranges/getMaxAmountClose.ts
44577
- function getMaxAmountClose(borrowDiscountedCollateral, adjustedDebt, ltvIn, bfOut) {
44578
- const denominator = ltvIn - 1.01 /* SAFE_HF */ * bfOut;
44579
- if (denominator <= 0) return Infinity;
44580
- return (borrowDiscountedCollateral - 1.01 /* SAFE_HF */ * adjustedDebt) / denominator;
44581
- }
44582
- function averageDataLastN(arr, n = 7) {
44583
- const last = arr.slice(-n);
44584
- if (last.length === 0) return 0;
44585
- return last.reduce((sum3, x) => sum3 + x.data, 0) / last.length;
44586
- }
44587
- var safeFetch = async (label, fn) => {
44588
- try {
44589
- return await fn();
44590
- } catch (e) {
44591
- console.error(`Error fetching ${label}:`, e);
44592
- return void 0;
44449
+ // src/yields/intrinsic/fetchers/savax.ts
44450
+ var SAVAX_URL = "https://api.benqi.fi/liquidstaking/apr";
44451
+ var savaxFetcher = {
44452
+ label: "SAVAX",
44453
+ fetch: async () => {
44454
+ const res = await fetch(SAVAX_URL).then((r) => r.json());
44455
+ return { SAVAX: Number(res.apr) * 100 };
44593
44456
  }
44594
44457
  };
44595
- async function getListsMulti(chainIds) {
44596
- const lists = await fetchTokenLists(chainIds);
44597
- let res = {};
44598
- for (const chainId of chainIds) {
44599
- res[chainId] = { list: lists[chainId] };
44458
+ var CHAIN_ID2 = "42220";
44459
+ var MANAGER = "0x0239b96d10a434a56cc9e09383077a0490cf9398";
44460
+ var ONE_E18 = 10n ** 18n;
44461
+ var WINDOW_SECONDS2 = 7 * 24 * 60 * 60;
44462
+ var BLOCK_TIME_SECONDS2 = 1;
44463
+ var WINDOW_BLOCKS2 = BigInt(Math.floor(WINDOW_SECONDS2 / BLOCK_TIME_SECONDS2));
44464
+ var MAX_RPC_TRIES2 = 5;
44465
+ var TO_CELO_ABI = [
44466
+ {
44467
+ name: "toCelo",
44468
+ type: "function",
44469
+ stateMutability: "view",
44470
+ inputs: [{ type: "uint256", name: "stCeloAmount" }],
44471
+ outputs: [{ type: "uint256" }]
44600
44472
  }
44601
- return res;
44602
- }
44603
-
44604
- // src/yields/intrinsic/fetchers/lido.ts
44605
- var WSTETH_URL = "https://eth-api.lido.fi/v1/protocol/steth/apr/sma";
44606
- var DEFILLAMA_LIDO_URL = "https://yields.llama.fi/chart/747c1d2a-c668-4682-b9f9-296708a3dd90";
44607
- var tETH = "Treehouse ETH::TETH";
44608
- var robustFetchJson = async (url, { timeoutMs = 5e3, attempts = 3 } = {}) => {
44473
+ ];
44474
+ var readRateAt2 = (client, blockNumber) => client.readContract({
44475
+ address: MANAGER,
44476
+ abi: TO_CELO_ABI,
44477
+ functionName: "toCelo",
44478
+ args: [ONE_E18],
44479
+ ...blockNumber !== void 0 ? { blockNumber } : {}
44480
+ });
44481
+ var computeApr2 = async () => {
44609
44482
  let lastErr;
44610
- for (let i = 0; i < attempts; i++) {
44483
+ for (let rpcId = 0; rpcId < MAX_RPC_TRIES2; rpcId++) {
44611
44484
  try {
44612
- const res = await fetch(url, {
44613
- headers: {
44614
- accept: "application/json",
44615
- "user-agent": "1delta-margin-fetcher"
44616
- },
44617
- signal: AbortSignal.timeout(timeoutMs)
44618
- });
44619
- if (!res.ok) throw new Error(`HTTP ${res.status}`);
44620
- return await res.json();
44485
+ const client = getEvmClient(CHAIN_ID2, rpcId);
44486
+ const head = await client.getBlockNumber();
44487
+ const pastBlock = head > WINDOW_BLOCKS2 ? head - WINDOW_BLOCKS2 : 0n;
44488
+ const [rateNow, rateThen, headBlock, thenBlock] = await Promise.all([
44489
+ readRateAt2(client),
44490
+ readRateAt2(client, pastBlock),
44491
+ client.getBlock({ blockNumber: head }),
44492
+ client.getBlock({ blockNumber: pastBlock })
44493
+ ]);
44494
+ if (rateNow < ONE_E18 || rateThen < ONE_E18 || rateNow < rateThen) {
44495
+ throw new Error(
44496
+ `non-archival or invalid rates (now=${rateNow}, then=${rateThen})`
44497
+ );
44498
+ }
44499
+ const elapsed = Number(headBlock.timestamp - thenBlock.timestamp);
44500
+ if (elapsed <= 0) throw new Error("non-positive elapsed window");
44501
+ const apr = annualizeRateDeltaPercent(rateNow, rateThen, elapsed);
44502
+ if (!Number.isFinite(apr) || apr < 0) throw new Error(`bad apr ${apr}`);
44503
+ return apr;
44621
44504
  } catch (e) {
44622
44505
  lastErr = e;
44623
- if (i < attempts - 1) {
44624
- await new Promise((r) => setTimeout(r, 250 * (i + 1)));
44625
- }
44626
44506
  }
44627
44507
  }
44628
- throw lastErr;
44629
- };
44630
- async function fetchLidoApr() {
44631
- try {
44632
- const res = await robustFetchJson(WSTETH_URL);
44633
- return Number(res.data.aprs.at(-1).apr) * 0.9;
44634
- } catch {
44635
- const res = await robustFetchJson(DEFILLAMA_LIDO_URL);
44636
- const latest = res.data.at(-1);
44637
- return Number(latest.apyBase) * 0.9;
44638
- }
44639
- }
44640
- var wstethFetcher = {
44641
- label: "WSTETH",
44642
- fetch: async () => {
44643
- const apr = await fetchLidoApr();
44644
- return {
44645
- WSTETH: apr,
44646
- [tETH]: apr
44647
- };
44648
- }
44508
+ throw new Error(
44509
+ `stCELO APR: no archival Celo RPC returned valid historical state (${String(lastErr)})`
44510
+ );
44649
44511
  };
44650
- var stmaticFetcher = {
44651
- label: "STMATIC",
44512
+ var stceloFetcher = {
44513
+ label: "STCELO",
44652
44514
  fetch: async () => {
44653
- return { STMATIC: 0 };
44515
+ const apr = await computeApr2();
44516
+ return { "Staked CELO::stCELO": apr };
44654
44517
  }
44655
44518
  };
44656
44519
 
44657
- // src/yields/intrinsic/fetchers/etherfi.ts
44658
- var WEETH_URL = "https://www.ether.fi/api/apr";
44659
- var WEETHS_URL = "https://api.sevenseas.capital/etherfi/ethereum/performance/0x917ceE801a67f933F2e6b33fC0cD1ED2d5909D88";
44660
- var weeths = "Super Symbiotic LRT::weETHs";
44661
- var EBTC_URL = "https://api.sevenseas.capital/etherfi/ethereum/performance/0x657e8C867D8B37dCC18fA4Caead9C45EB088C642";
44662
- var createWeethFetcher = (wstethPromise) => ({
44663
- label: "WEETH",
44520
+ // src/yields/intrinsic/fetchers/valantis.ts
44521
+ var VALANTIS_STHYPE_APR_URL = "https://analytics-v3.valantis-analytics.xyz/sthype/apr";
44522
+ var WSTHYPE_KEY = "Staked HYPE Shares::WSTHYPE";
44523
+ var valantisStHypeFetcher = {
44524
+ label: "VALANTIS_STHYPE",
44664
44525
  fetch: async () => {
44665
- const wstethRes = await wstethPromise;
44666
- const wstethVal = wstethRes?.WSTETH ?? 0;
44667
- let aYield = 0;
44668
- try {
44669
- const weethRes = await fetch(WEETH_URL).then((r) => r.json());
44670
- aYield = Number(weethRes.lrt2Apr);
44671
- } catch (e) {
44672
- aYield = 0.5;
44526
+ const text = await fetch(VALANTIS_STHYPE_APR_URL).then((r) => r.text());
44527
+ const apr = Number(text.trim());
44528
+ if (!Number.isFinite(apr)) {
44529
+ throw new Error(`Valantis stHYPE APR: non-numeric response "${text}"`);
44673
44530
  }
44674
- return { WEETH: aYield + wstethVal };
44675
- }
44676
- });
44677
- var weethsFetcher = {
44678
- label: "WEETHS",
44679
- fetch: async () => {
44680
- const res = await fetch(WEETHS_URL).then((r) => r.json());
44681
- return { [weeths]: apyToApr(res.Response.apy) * 100 };
44531
+ return { [WSTHYPE_KEY]: apr };
44682
44532
  }
44683
44533
  };
44684
- var ebtcFetcher = {
44685
- label: "EBTC",
44686
- fetch: async () => {
44687
- const res = await fetch(EBTC_URL).then((r) => r.json());
44688
- return {
44689
- "Ether fi Staked BTC::EBTC": apyToApr(Number(res?.Response?.apy) || 0) * 100
44690
- };
44691
- }
44692
- };
44693
-
44694
- // src/yields/intrinsic/fetchers/rocketpool.ts
44695
- var RETH_URL = "https://api.rocketpool.net/api/mainnet/payload";
44696
- var rethFetcher = {
44697
- label: "RETH",
44698
- fetch: async () => {
44699
- const res = await fetch(RETH_URL).then((r) => r.json());
44700
- return { RETH: Number(res.rethAPR) };
44701
- }
44702
- };
44703
-
44704
- // src/yields/intrinsic/fetchers/renzo.ts
44705
- var EZETH_URL = "https://app.renzoprotocol.com/api/stats?chainId=1";
44706
- var ezethFetcher = {
44707
- label: "EZETH",
44708
- fetch: async () => {
44709
- const res = await fetch(EZETH_URL).then((r) => r.json());
44710
- return { EZETH: Number(res.data.apr.data.rate) };
44711
- }
44712
- };
44713
-
44714
- // src/yields/intrinsic/fetchers/kelp.ts
44715
- var RSETH_URL = "https://universe.kelpdao.xyz/rseth/totalApy";
44716
- var rsethFetcher = {
44717
- label: "RSETH",
44718
- fetch: async () => {
44719
- const res = await fetch(RSETH_URL).then((r) => r.json());
44720
- return { RSETH: apyToAprPercent(res.totalAPY) };
44721
- }
44722
- };
44723
-
44724
- // src/yields/intrinsic/fetchers/swell.ts
44725
- var RSWETH_URL = "https://v3-lst.svc.swellnetwork.io/api/tokens/sweth/apr";
44726
- var rsweth = "Restaked Swell ETH::RSWETH";
44727
- var rswethFetcher = {
44728
- label: "RSWETH",
44729
- fetch: async () => {
44730
- const res = await fetch(RSWETH_URL, {
44731
- method: "GET",
44732
- headers: { Accept: "application/json", "User-Agent": "1delta/yields" }
44733
- }).then((r) => r.text());
44734
- return { [rsweth]: Number(res) ?? 0 };
44735
- }
44736
- };
44737
-
44738
- // src/yields/intrinsic/annualizeRate.ts
44739
- var YEAR_SECONDS3 = 365 * 24 * 60 * 60;
44740
- var annualizeGrowthPercent = (growth, elapsedSeconds) => growth * (YEAR_SECONDS3 / elapsedSeconds) * 100;
44741
- var annualizeRateDeltaPercent = (rateNow, rateThen, elapsedSeconds) => {
44742
- const growth = typeof rateNow === "bigint" && typeof rateThen === "bigint" ? Number(rateNow - rateThen) / Number(rateThen) : Number(rateNow) / Number(rateThen) - 1;
44743
- return annualizeGrowthPercent(growth, elapsedSeconds);
44744
- };
44745
-
44746
- // src/yields/intrinsic/fetchers/swBTC.ts
44747
- var CHAIN_ID = "1";
44748
- var SWBTC = "0x8db2350d78abc13f5673a411d4700bcf87864dde";
44749
- var ONE_E8 = 10n ** 8n;
44750
- var WINDOW_SECONDS = 7 * 24 * 60 * 60;
44751
- var BLOCK_TIME_SECONDS = 12;
44752
- var WINDOW_BLOCKS = BigInt(Math.floor(WINDOW_SECONDS / BLOCK_TIME_SECONDS));
44753
- var MAX_RPC_TRIES = 5;
44754
- var CONVERT_TO_ASSETS_ABI = [
44755
- {
44756
- name: "convertToAssets",
44757
- type: "function",
44758
- stateMutability: "view",
44759
- inputs: [{ type: "uint256", name: "shares" }],
44760
- outputs: [{ type: "uint256" }]
44761
- }
44762
- ];
44763
- var readRateAt = (client, blockNumber) => client.readContract({
44764
- address: SWBTC,
44765
- abi: CONVERT_TO_ASSETS_ABI,
44766
- functionName: "convertToAssets",
44767
- args: [ONE_E8],
44768
- ...blockNumber !== void 0 ? { blockNumber } : {}
44769
- });
44770
- var computeApr = async () => {
44771
- let lastErr;
44772
- for (let rpcId = 0; rpcId < MAX_RPC_TRIES; rpcId++) {
44773
- try {
44774
- const client = getEvmClient(CHAIN_ID, rpcId);
44775
- const head = await client.getBlockNumber();
44776
- const pastBlock = head > WINDOW_BLOCKS ? head - WINDOW_BLOCKS : 0n;
44777
- const [rateNow, rateThen, headBlock, thenBlock] = await Promise.all([
44778
- readRateAt(client),
44779
- readRateAt(client, pastBlock),
44780
- client.getBlock({ blockNumber: head }),
44781
- client.getBlock({ blockNumber: pastBlock })
44782
- ]);
44783
- if (rateNow < ONE_E8 || rateThen < ONE_E8 || rateNow < rateThen) {
44784
- throw new Error(
44785
- `non-archival or invalid rates (now=${rateNow}, then=${rateThen})`
44786
- );
44787
- }
44788
- const elapsed = Number(headBlock.timestamp - thenBlock.timestamp);
44789
- if (elapsed <= 0) throw new Error(`bad elapsed ${elapsed}`);
44790
- const apr = annualizeRateDeltaPercent(rateNow, rateThen, elapsed);
44791
- if (!Number.isFinite(apr) || apr < 0) throw new Error(`bad apr ${apr}`);
44792
- return apr;
44793
- } catch (e) {
44794
- lastErr = e;
44795
- }
44796
- }
44797
- throw new Error(
44798
- `swBTC APR: no archival Ethereum RPC returned valid historical state (${String(lastErr)})`
44799
- );
44800
- };
44801
- var swBtcFetcher = {
44802
- label: "SWBTC",
44803
- fetch: async () => {
44804
- try {
44805
- return { "Swell Restaked BTC::SWBTC": await computeApr() };
44806
- } catch {
44807
- return { "Swell Restaked BTC::SWBTC": 0 };
44808
- }
44809
- }
44810
- };
44811
-
44812
- // src/yields/intrinsic/fetchers/puffer.ts
44813
- var PUFETH_URL = "https://api-v2.puffer.fi/backend-for-frontend/tvl/all";
44814
- var pufEth = "PUFETH";
44815
- var pufethFetcher = {
44816
- label: "PUFETH",
44817
- fetch: async () => {
44818
- const res = await fetch(PUFETH_URL, {
44819
- method: "GET",
44820
- headers: { Accept: "application/json" }
44821
- }).then((r) => r.json());
44822
- return { [pufEth]: apyToAprPercent(res.apy) };
44823
- }
44824
- };
44825
-
44826
- // src/yields/intrinsic/fetchers/stakewise.ts
44827
- var OSETH_URL = "https://graphs.stakewise.io/mainnet-a/subgraphs/name/stakewise/prod?opName=osTokenApy";
44828
- var osETH = "StakeWise Staked ETH::OSETH";
44829
- var osethFetcher = {
44830
- label: "OSETH",
44831
- fetch: async () => {
44832
- const res = await fetch(OSETH_URL, {
44833
- method: "POST",
44834
- headers: { Accept: "application/json" },
44835
- body: JSON.stringify({
44836
- query: "query osTokenApy { osTokens { apy feePercent }}",
44837
- operationName: "osTokenApy"
44838
- })
44839
- }).then((r) => r.json());
44840
- const apr = apyToAprPercent(res.data?.osTokens?.[0]?.apy);
44841
- return {
44842
- [osETH]: apr,
44843
- // token-lists unifies every osETH deployment (incl. bridged) to the bare `OSETH` group — emit there too.
44844
- OSETH: apr
44845
- };
44846
- }
44847
- };
44848
-
44849
- // src/yields/intrinsic/fetchers/stader.ts
44850
- var MATICX_URL = "https://universe.staderlabs.com/polygon/apy";
44851
- var ETHX_URL = "https://universe.staderlabs.com/eth/apy";
44852
- var ethX = "Stader ETHx::ETHx";
44853
- var maticxFetcher = {
44854
- label: "MATICX",
44855
- fetch: async () => {
44856
- const res = await fetch(MATICX_URL).then((r) => r.json());
44857
- return { MATICX: Number(res.value) * 0.9 };
44858
- }
44859
- };
44860
- var ethxFetcher = {
44861
- label: "ETHX",
44862
- fetch: async () => {
44863
- const res = await fetch(ETHX_URL).then((r) => r.json());
44864
- return { [ethX]: apyToAprPercent(res.value) };
44865
- }
44866
- };
44867
-
44868
- // src/yields/intrinsic/fetchers/trufin.ts
44869
- var APY_URL = "https://api.trufin.io/staker/apy?staker=";
44870
- var createTruFinFetcher = (staker, yieldKey) => ({
44871
- label: yieldKey,
44872
- fetch: async () => {
44873
- const res = await fetch(APY_URL + staker).then((r) => r.json());
44874
- return { [yieldKey]: apyToAprPercent(res.apy) };
44875
- }
44876
- });
44877
- var trumaticFetcher = createTruFinFetcher("MATIC", "TRUMATIC");
44878
- var trupolFetcher = createTruFinFetcher("POL", "TRUPOL");
44879
-
44880
- // src/yields/intrinsic/fetchers/defillama.ts
44881
- var POOLS_ENRICHED = "https://yields.llama.fi/poolsEnriched?pool=";
44882
- var fetchDefiLlamaApy = async (poolId) => {
44883
- const res = await fetch(POOLS_ENRICHED + poolId, {
44884
- headers: { accept: "application/json" },
44885
- signal: AbortSignal.timeout(8e3)
44886
- });
44887
- if (!res.ok) throw new Error(`DefiLlama HTTP ${res.status}`);
44888
- const json = await res.json();
44889
- const apy = json?.data?.[0]?.apy;
44890
- if (typeof apy !== "number" || !Number.isFinite(apy)) {
44891
- throw new Error(`DefiLlama: no apy for pool ${poolId}`);
44892
- }
44893
- return apy;
44894
- };
44895
-
44896
- // src/yields/intrinsic/fetchers/kinetiq.ts
44897
- var KHYPE_POOL_ID = "9f25a954-db87-4bb2-a8b2-4be0b843a44c";
44898
- var KHYPE_KEY = "Kinetiq Staked HYPE::kHYPE";
44899
- var kinetiqKHypeFetcher = {
44900
- label: "KHYPE",
44901
- fetch: async () => {
44902
- const apy = await fetchDefiLlamaApy(KHYPE_POOL_ID);
44903
- return { [KHYPE_KEY]: apyToAprPercent(apy) };
44904
- }
44905
- };
44906
-
44907
- // src/yields/intrinsic/fetchers/hyperbeat.ts
44908
- var HBHYPE_URL = "https://api.hyperbeat.org/api/v1/staking?address=0xCeaD893b162D38e714D82d06a7fe0b0dc3c38E0b";
44909
- var HBUHYPE_URL = "https://app.hyperbeat.org/api/hyperfolio/vault-infos?vaultAddress=0x96C6cBB6251Ee1c257b2162ca0f39AA5Fa44B1FB";
44910
- var hbhype = "hyperbeat x ether.fi HYPE::beHYPE";
44911
- var hbuhype = "Hyperbeat Ultra Hype::hbHYPE";
44912
- var hbhypeFetcher = {
44913
- label: "HBHYPE",
44914
- fetch: async () => {
44915
- try {
44916
- const response = await fetch(HBHYPE_URL);
44917
- if (!response.ok) {
44918
- throw new Error(`HTTP error! Status: ${response.status}`);
44919
- }
44920
- const result = await response.json();
44921
- if (!result.success || !result.data || !Array.isArray(result.data.delegations)) {
44922
- throw new Error("Invalid response structure");
44923
- }
44924
- const delegations = result.data.delegations;
44925
- const totalApr = delegations.reduce(
44926
- (sum3, validator) => sum3 + Number(validator.apr ?? 0),
44927
- 0
44928
- );
44929
- const averageApr = totalApr / delegations.length;
44930
- return { [hbhype]: averageApr };
44931
- } catch (e) {
44932
- return { [hbhype]: 0 };
44933
- }
44934
- }
44935
- };
44936
- var hbuhypeFetcher = {
44937
- label: "HBUHYPE",
44938
- fetch: async () => {
44939
- try {
44940
- const response = await fetch(HBUHYPE_URL);
44941
- if (!response.ok) {
44942
- throw new Error(`HTTP error! Status: ${response.status}`);
44943
- }
44944
- const result = await response.json();
44945
- const apy = result.currentAPY?.apy_1d ?? 0;
44946
- return { [hbuhype]: apyToAprPercent(apy) };
44947
- } catch (e) {
44948
- return { [hbuhype]: 0 };
44949
- }
44950
- }
44951
- };
44952
- var HYPERBEAT_VAULTS = [
44953
- {
44954
- address: "0x5e105266db42f78FA814322Bce7f388B4C2e61eb",
44955
- key: "Hyperbeat USDT::hbUSDT"
44956
- },
44957
- {
44958
- address: "0x057ced81348D57Aad579A672d521d7b4396E8a61",
44959
- key: "Hyperbeat USDC::hbUSDC"
44960
- },
44961
- {
44962
- address: "0x81e064d0eB539de7c3170EDF38C1A42CBd752A76",
44963
- key: "Hyperbeat LST Vault::lstHYPE"
44964
- },
44965
- {
44966
- address: "0x441794D6a8F9A3739F5D4E98a728937b33489D29",
44967
- key: "Liquid HYPE Yield::liquidHYPE"
44968
- }
44969
- ];
44970
- var HYPERBEAT_VAULT_APY_URL = (address) => `https://api.hyperbeat.org/api/v1/vaults/apy/${address}?limit=1`;
44971
- var hyperbeatVaultsFetcher = {
44972
- label: "HYPERBEAT_VAULTS",
44973
- fetch: async () => {
44974
- const out = {};
44975
- await Promise.all(
44976
- HYPERBEAT_VAULTS.map(async ({ address, key: key3 }) => {
44977
- try {
44978
- const response = await fetch(HYPERBEAT_VAULT_APY_URL(address));
44979
- if (!response.ok) {
44980
- throw new Error(`HTTP error! Status: ${response.status}`);
44981
- }
44982
- const result = await response.json();
44983
- const apy = Number(
44984
- result.current_apy?.apy_7d ?? result.current_apy?.apy ?? 0
44985
- );
44986
- out[key3] = apyToAprPercent(apy);
44987
- } catch (e) {
44988
- out[key3] = 0;
44989
- }
44990
- })
44991
- );
44992
- return out;
44993
- }
44994
- };
44995
-
44996
- // src/yields/intrinsic/fetchers/coinbase.ts
44997
- var CBETH_URL = "https://api.exchange.coinbase.com/wrapped-assets/cbeth";
44998
- var cbethFetcher = {
44999
- label: "CBETH",
45000
- fetch: async () => {
45001
- try {
45002
- const res = await fetch(CBETH_URL, {
45003
- headers: {
45004
- "User-Agent": "1delta/yields",
45005
- "Content-Type": "application/json"
45006
- }
45007
- }).then((r) => r.json());
45008
- return { CBETH: apyToAprPercent(res.apy) * 100 };
45009
- } catch (e) {
45010
- console.log("CBETH failed", e);
45011
- return { CBETH: 0 };
45012
- }
45013
- }
45014
- };
45015
-
45016
- // src/yields/intrinsic/fetchers/mantle.ts
45017
- var METH_URL = "https://meth.mantle.xyz/api/stats/apy";
45018
- var methFetcher = {
45019
- label: "METH",
45020
- fetch: async () => {
45021
- const res = await fetch(METH_URL).then((r) => r.json());
45022
- const apr = apyToApr(Number(res.data[0]?.OneDayAPY)) * 100;
45023
- return { METH: apr, CMETH: apr };
45024
- }
45025
- };
45026
-
45027
- // src/yields/intrinsic/fetchers/yieldnest.ts
45028
- var YIELDNEST_URL = "https://gateway.yieldnest.finance/api/v1/graphql";
45029
- var YIELDNEST_GQL_QUERY = "query GetTokenMetrics($networkType: NetworkType!) { getLRTsData(networkType: $networkType) { tokens { token blockchains { chainId apr { apr31d } } } } }";
45030
- var YN_TOKENS = [
45031
- { symbol: "ynETHx", chainId: 1, key: "ynETH MAX::YNETHX" },
45032
- { symbol: "ynETH", chainId: 1, key: "YieldNest Restaked ETH::YNETH" },
45033
- {
45034
- symbol: "ynLSDe",
45035
- chainId: 1,
45036
- key: "YieldNest Restaked LSD Eigenlayer::YNLSDE"
45037
- },
45038
- { symbol: "ynRWAx", chainId: 1, key: "YieldNest RWA MAX::YNRWAX" },
45039
- { symbol: "ynUSDx", chainId: 1, key: "ynUSD Max::YNUSDX" },
45040
- { symbol: "STAK", chainId: 1, key: "YieldNest STAK::STAK" },
45041
- { symbol: "ynBNBx", chainId: 56, key: "ynBNB MAX::ynBNBx" },
45042
- { symbol: "ynBNB", chainId: 56, key: "YieldNest Restaked BNB::ynBNB" },
45043
- { symbol: "ynBTCk", chainId: 56, key: "YieldNest BTC Kernel::ynBTCk" }
45044
- ];
45045
- function findApr(tokens, symbol, chainId) {
45046
- const apr = tokens.find((t) => t.token === symbol)?.blockchains?.find((b) => b.chainId === chainId)?.apr?.apr31d;
45047
- return Number(apr ?? 0);
45048
- }
45049
- var yieldNestFetcher = {
45050
- label: "YIELDNEST",
45051
- fetch: async () => {
45052
- const res = await fetch(YIELDNEST_URL, {
45053
- method: "POST",
45054
- headers: {
45055
- Accept: "application/json",
45056
- "Content-Type": "application/json"
45057
- },
45058
- body: JSON.stringify({
45059
- operationName: "GetTokenMetrics",
45060
- variables: { networkType: "mainnet" },
45061
- query: YIELDNEST_GQL_QUERY
45062
- })
45063
- }).then((r) => r.json());
45064
- const tokens = res?.data?.getLRTsData?.tokens ?? [];
45065
- const result = {};
45066
- for (const { symbol, chainId, key: key3 } of YN_TOKENS) {
45067
- const apr = findApr(tokens, symbol, chainId);
45068
- if (apr > 0) result[key3] = apr;
45069
- }
45070
- return result;
45071
- }
45072
- };
45073
-
45074
- // src/yields/intrinsic/fetchers/stS.ts
45075
- var BEETS_URL = "https://backend-v3.beets-ftm-node.com/";
45076
- var stS = "Beets Staked Sonic::STS";
45077
- var stsFetcher = {
45078
- label: "STS",
45079
- fetch: async () => {
45080
- const res = await fetch(BEETS_URL, {
45081
- method: "POST",
45082
- headers: {
45083
- Accept: "application/json",
45084
- "Content-Type": "application/json"
45085
- },
45086
- body: JSON.stringify({
45087
- operationName: "GetStakedSonicData",
45088
- query: "query GetStakedSonicData { stsGetGqlStakedSonicData { stakingApr } }"
45089
- })
45090
- }).then((r) => r.json());
45091
- const apr = Number(res.data?.stsGetGqlStakedSonicData?.stakingApr) * 100;
45092
- return { [stS]: apr };
45093
- }
45094
- };
45095
-
45096
- // src/yields/intrinsic/fetchers/savax.ts
45097
- var SAVAX_URL = "https://api.benqi.fi/liquidstaking/apr";
45098
- var savaxFetcher = {
45099
- label: "SAVAX",
45100
- fetch: async () => {
45101
- const res = await fetch(SAVAX_URL).then((r) => r.json());
45102
- return { SAVAX: Number(res.apr) * 100 };
45103
- }
45104
- };
45105
- var CHAIN_ID2 = "42220";
45106
- var MANAGER = "0x0239b96d10a434a56cc9e09383077a0490cf9398";
45107
- var ONE_E18 = 10n ** 18n;
45108
- var WINDOW_SECONDS2 = 7 * 24 * 60 * 60;
45109
- var BLOCK_TIME_SECONDS2 = 1;
45110
- var WINDOW_BLOCKS2 = BigInt(Math.floor(WINDOW_SECONDS2 / BLOCK_TIME_SECONDS2));
45111
- var MAX_RPC_TRIES2 = 5;
45112
- var TO_CELO_ABI = [
45113
- {
45114
- name: "toCelo",
45115
- type: "function",
45116
- stateMutability: "view",
45117
- inputs: [{ type: "uint256", name: "stCeloAmount" }],
45118
- outputs: [{ type: "uint256" }]
45119
- }
45120
- ];
45121
- var readRateAt2 = (client, blockNumber) => client.readContract({
45122
- address: MANAGER,
45123
- abi: TO_CELO_ABI,
45124
- functionName: "toCelo",
45125
- args: [ONE_E18],
45126
- ...blockNumber !== void 0 ? { blockNumber } : {}
45127
- });
45128
- var computeApr2 = async () => {
45129
- let lastErr;
45130
- for (let rpcId = 0; rpcId < MAX_RPC_TRIES2; rpcId++) {
45131
- try {
45132
- const client = getEvmClient(CHAIN_ID2, rpcId);
45133
- const head = await client.getBlockNumber();
45134
- const pastBlock = head > WINDOW_BLOCKS2 ? head - WINDOW_BLOCKS2 : 0n;
45135
- const [rateNow, rateThen, headBlock, thenBlock] = await Promise.all([
45136
- readRateAt2(client),
45137
- readRateAt2(client, pastBlock),
45138
- client.getBlock({ blockNumber: head }),
45139
- client.getBlock({ blockNumber: pastBlock })
45140
- ]);
45141
- if (rateNow < ONE_E18 || rateThen < ONE_E18 || rateNow < rateThen) {
45142
- throw new Error(
45143
- `non-archival or invalid rates (now=${rateNow}, then=${rateThen})`
45144
- );
45145
- }
45146
- const elapsed = Number(headBlock.timestamp - thenBlock.timestamp);
45147
- if (elapsed <= 0) throw new Error("non-positive elapsed window");
45148
- const apr = annualizeRateDeltaPercent(rateNow, rateThen, elapsed);
45149
- if (!Number.isFinite(apr) || apr < 0) throw new Error(`bad apr ${apr}`);
45150
- return apr;
45151
- } catch (e) {
45152
- lastErr = e;
45153
- }
45154
- }
45155
- throw new Error(
45156
- `stCELO APR: no archival Celo RPC returned valid historical state (${String(lastErr)})`
45157
- );
45158
- };
45159
- var stceloFetcher = {
45160
- label: "STCELO",
45161
- fetch: async () => {
45162
- const apr = await computeApr2();
45163
- return { "Staked CELO::stCELO": apr };
45164
- }
45165
- };
45166
-
45167
- // src/yields/intrinsic/fetchers/valantis.ts
45168
- var VALANTIS_STHYPE_APR_URL = "https://analytics-v3.valantis-analytics.xyz/sthype/apr";
45169
- var WSTHYPE_KEY = "Staked HYPE Shares::WSTHYPE";
45170
- var valantisStHypeFetcher = {
45171
- label: "VALANTIS_STHYPE",
45172
- fetch: async () => {
45173
- const text = await fetch(VALANTIS_STHYPE_APR_URL).then((r) => r.text());
45174
- const apr = Number(text.trim());
45175
- if (!Number.isFinite(apr)) {
45176
- throw new Error(`Valantis stHYPE APR: non-numeric response "${text}"`);
45177
- }
45178
- return { [WSTHYPE_KEY]: apr };
45179
- }
45180
- };
45181
- var STKAIA = "0x42952b873ed6f7f0a7e4992e2a9818e3a9001995";
45182
- var GET_RATIO_ABI = [
45183
- {
45184
- name: "getRatio",
45185
- type: "function",
45186
- stateMutability: "view",
45187
- inputs: [],
45188
- outputs: [{ type: "uint256" }]
44534
+ var STKAIA = "0x42952b873ed6f7f0a7e4992e2a9818e3a9001995";
44535
+ var GET_RATIO_ABI = [
44536
+ {
44537
+ name: "getRatio",
44538
+ type: "function",
44539
+ stateMutability: "view",
44540
+ inputs: [],
44541
+ outputs: [{ type: "uint256" }]
45189
44542
  }
45190
44543
  ];
45191
44544
  var WINDOWS_BLOCKS = [604800n, 259200n, 86400n, 43200n];
@@ -45659,14 +45012,51 @@ var lombardLbtcvFetcher = createLombardVaultFetcher(
45659
45012
  "LBTCv"
45660
45013
  );
45661
45014
 
45662
- // src/yields/intrinsic/fetchers/solv.ts
45663
- var BTCPLUS_STATS_URL = "https://api.solvprotocol.org/btcplus/stats";
45664
- var solvBtcPlusFetcher = {
45665
- label: "BTC+",
45015
+ // src/yields/intrinsic/fetchers/etherfi.ts
45016
+ var WEETH_URL = "https://www.ether.fi/api/apr";
45017
+ var WEETHS_URL = "https://api.sevenseas.capital/etherfi/ethereum/performance/0x917ceE801a67f933F2e6b33fC0cD1ED2d5909D88";
45018
+ var weeths = "Super Symbiotic LRT::weETHs";
45019
+ var EBTC_URL = "https://api.sevenseas.capital/etherfi/ethereum/performance/0x657e8C867D8B37dCC18fA4Caead9C45EB088C642";
45020
+ var createWeethFetcher = (wstethPromise) => ({
45021
+ label: "WEETH",
45666
45022
  fetch: async () => {
45667
- const res = await fetch(BTCPLUS_STATS_URL, {
45668
- headers: { accept: "application/json" }
45669
- }).then((r) => r.json());
45023
+ const wstethRes = await wstethPromise;
45024
+ const wstethVal = wstethRes?.WSTETH ?? 0;
45025
+ let aYield = 0;
45026
+ try {
45027
+ const weethRes = await fetch(WEETH_URL).then((r) => r.json());
45028
+ aYield = Number(weethRes.lrt2Apr);
45029
+ } catch (e) {
45030
+ aYield = 0.5;
45031
+ }
45032
+ return { WEETH: aYield + wstethVal };
45033
+ }
45034
+ });
45035
+ var weethsFetcher = {
45036
+ label: "WEETHS",
45037
+ fetch: async () => {
45038
+ const res = await fetch(WEETHS_URL).then((r) => r.json());
45039
+ return { [weeths]: apyToApr(res.Response.apy) * 100 };
45040
+ }
45041
+ };
45042
+ var ebtcFetcher = {
45043
+ label: "EBTC",
45044
+ fetch: async () => {
45045
+ const res = await fetch(EBTC_URL).then((r) => r.json());
45046
+ return {
45047
+ "Ether fi Staked BTC::EBTC": apyToApr(Number(res?.Response?.apy) || 0) * 100
45048
+ };
45049
+ }
45050
+ };
45051
+
45052
+ // src/yields/intrinsic/fetchers/solv.ts
45053
+ var BTCPLUS_STATS_URL = "https://api.solvprotocol.org/btcplus/stats";
45054
+ var solvBtcPlusFetcher = {
45055
+ label: "BTC+",
45056
+ fetch: async () => {
45057
+ const res = await fetch(BTCPLUS_STATS_URL, {
45058
+ headers: { accept: "application/json" }
45059
+ }).then((r) => r.json());
45670
45060
  const base = Number(res?.baseApy);
45671
45061
  const reward = Number(res?.rewardApy);
45672
45062
  const apr = (Number.isFinite(base) ? base : 0) + (Number.isFinite(reward) ? reward : 0);
@@ -53535,35 +52925,1736 @@ var SAVINGS_REGISTRY = (() => {
53535
52925
  if (!out[chainId]) out[chainId] = [];
53536
52926
  out[chainId].push(...entries);
53537
52927
  }
53538
- for (const [chainId, entries] of Object.entries(BITFI_ENTRIES)) {
53539
- if (!out[chainId]) out[chainId] = [];
53540
- out[chainId].push(...entries);
52928
+ for (const [chainId, entries] of Object.entries(BITFI_ENTRIES)) {
52929
+ if (!out[chainId]) out[chainId] = [];
52930
+ out[chainId].push(...entries);
52931
+ }
52932
+ for (const [chainId, entries] of Object.entries(VESPER_ENTRIES)) {
52933
+ if (!out[chainId]) out[chainId] = [];
52934
+ out[chainId].push(...entries);
52935
+ }
52936
+ for (const [chainId, entries] of Object.entries(VENUS_HUB_ENTRIES)) {
52937
+ if (!out[chainId]) out[chainId] = [];
52938
+ out[chainId].push(...entries);
52939
+ }
52940
+ return out;
52941
+ })();
52942
+ var savingsBalanceKind = (chainId, address) => {
52943
+ const lc2 = address.toLowerCase();
52944
+ return (SAVINGS_REGISTRY[chainId] ?? []).find((e) => e.address === lc2)?.balanceKind;
52945
+ };
52946
+ var isSecondaryMarketOnly = (chainId, address) => (SAVINGS_REGISTRY[chainId] ?? []).some(
52947
+ (e) => e.address === address.toLowerCase() && e.secondaryMarketOnly === true
52948
+ );
52949
+ var secondaryMarketVault = (chainId, address) => {
52950
+ const e = (SAVINGS_REGISTRY[chainId] ?? []).find(
52951
+ (x) => x.address === address.toLowerCase() && x.secondaryMarketOnly === true
52952
+ );
52953
+ return e ? { underlying: e.underlying, symbol: e.symbol } : void 0;
52954
+ };
52955
+ var savingsAddresses = (chainId) => (SAVINGS_REGISTRY[chainId] ?? []).map((e) => e.address);
52956
+ var getSavingsRegistry = (chainId) => SAVINGS_REGISTRY[chainId] ?? [];
52957
+
52958
+ // src/lending/user-data/emitters.ts
52959
+ var lc = (a) => a ? a.toLowerCase() : void 0;
52960
+ var FLUID_VAULT_FACTORY2 = "0x324c5dc1fc42c7a4d43d92df1eba58a54d13bf2d";
52961
+ var isAddr = (a) => typeof a === "string" && /^0x[0-9a-fA-F]{40}$/.test(a);
52962
+ function enumerateEmitters(chainId) {
52963
+ const out = [];
52964
+ const seen = /* @__PURE__ */ new Set();
52965
+ const push2 = (r) => {
52966
+ if (!isAddr(r.address)) return;
52967
+ const row = { ...r, address: r.address.toLowerCase() };
52968
+ const k = `${row.address}:${row.lenderKey}:${row.role}`;
52969
+ if (seen.has(k)) return;
52970
+ seen.add(k);
52971
+ out.push(row);
52972
+ };
52973
+ const uid = (lender, ref) => createMarketUid(chainId, lender, ref);
52974
+ for (const [lender, chains] of Object.entries(aavePools() ?? {})) {
52975
+ const pool = chains?.[chainId]?.pool;
52976
+ if (!pool) continue;
52977
+ push2({
52978
+ chainId,
52979
+ address: pool,
52980
+ lenderKey: lender,
52981
+ family: "aave",
52982
+ role: "core",
52983
+ label: `${lender} pool`
52984
+ });
52985
+ for (const [underlying, t] of Object.entries(
52986
+ aaveTokens()?.[lender]?.[chainId] ?? {}
52987
+ )) {
52988
+ const m = uid(lender, underlying);
52989
+ if (isAddr(t.aToken))
52990
+ push2({
52991
+ chainId,
52992
+ address: t.aToken,
52993
+ lenderKey: lender,
52994
+ family: "aave-token",
52995
+ role: "shareToken",
52996
+ side: "supply",
52997
+ marketUid: m,
52998
+ asset: lc(underlying),
52999
+ shareEvents: "transfers"
53000
+ });
53001
+ if (isAddr(t.vToken))
53002
+ push2({
53003
+ chainId,
53004
+ address: t.vToken,
53005
+ lenderKey: lender,
53006
+ family: "aave-token",
53007
+ role: "debtToken",
53008
+ side: "borrow",
53009
+ marketUid: m,
53010
+ asset: lc(underlying),
53011
+ shareEvents: "transfers"
53012
+ });
53013
+ }
53014
+ }
53015
+ for (const [spokeLower, entry] of Object.entries(
53016
+ aaveV4Spokes()?.[chainId] ?? {}
53017
+ )) {
53018
+ const lender = `AAVE_V4_${spokeLower.replace(/^0x/, "").toUpperCase()}`;
53019
+ push2({
53020
+ chainId,
53021
+ address: entry.spoke ?? spokeLower,
53022
+ lenderKey: lender,
53023
+ family: "aave-v4",
53024
+ role: "core",
53025
+ label: entry.label
53026
+ });
53027
+ }
53028
+ for (const [lender, comet] of Object.entries(
53029
+ compoundV3Pools()?.[chainId] ?? {}
53030
+ )) {
53031
+ const base = compoundV3BaseData()?.[lender]?.[chainId]?.baseAsset;
53032
+ push2({
53033
+ chainId,
53034
+ address: comet,
53035
+ lenderKey: lender,
53036
+ family: "comet",
53037
+ role: "market",
53038
+ marketUid: base ? uid(lender, base) : void 0,
53039
+ asset: lc(base)
53040
+ });
53041
+ }
53042
+ for (const [lender, chains] of Object.entries(compoundV2TokenArray() ?? {})) {
53043
+ for (const t of chains?.[chainId] ?? []) {
53044
+ push2({
53045
+ chainId,
53046
+ address: t.cToken,
53047
+ lenderKey: lender,
53048
+ family: "compound-v2",
53049
+ role: "market",
53050
+ marketUid: uid(lender, t.cToken),
53051
+ asset: lc(t.underlying)
53052
+ });
53053
+ }
53054
+ }
53055
+ for (const [lender, chains] of Object.entries(morphoPools() ?? {})) {
53056
+ const core = chains?.[chainId];
53057
+ if (!core) continue;
53058
+ push2({
53059
+ chainId,
53060
+ address: core,
53061
+ lenderKey: lender,
53062
+ family: "morpho",
53063
+ role: "core",
53064
+ label: `${lender} singleton`
53065
+ });
53066
+ }
53067
+ for (const [protocol, chains] of Object.entries(morphoTypeVaults() ?? {})) {
53068
+ for (const v of chains?.[chainId] ?? []) {
53069
+ push2({
53070
+ chainId,
53071
+ address: v.vault,
53072
+ lenderKey: `vault.${protocol.toLowerCase()}`,
53073
+ family: "erc20-share",
53074
+ role: "shareToken",
53075
+ side: "share",
53076
+ marketUid: `vault.${protocol.toLowerCase()}:${chainId}:${v.vault.toLowerCase()}`,
53077
+ asset: lc(v.underlying),
53078
+ label: v.name
53079
+ });
53080
+ }
53081
+ }
53082
+ for (const [lender, chains] of Object.entries(eulerVaults() ?? {})) {
53083
+ for (const v of chains?.[chainId] ?? []) {
53084
+ push2({
53085
+ chainId,
53086
+ address: v.vault,
53087
+ lenderKey: lender,
53088
+ family: "euler",
53089
+ role: "market",
53090
+ marketUid: uid(lender, v.vault),
53091
+ asset: lc(v.underlying)
53092
+ });
53093
+ }
53094
+ const evc = eulerConfigs()?.[lender]?.[chainId]?.evc;
53095
+ if (evc)
53096
+ push2({
53097
+ chainId,
53098
+ address: evc,
53099
+ lenderKey: lender,
53100
+ family: "euler",
53101
+ role: "core",
53102
+ label: "EVC"
53103
+ });
53104
+ }
53105
+ const siloRows = (markets, keyOf) => {
53106
+ for (const m of markets ?? []) {
53107
+ const lender = keyOf(m.siloConfig);
53108
+ for (const side of [m.silo0, m.silo1]) {
53109
+ const mu = uid(lender, side.silo);
53110
+ push2({
53111
+ chainId,
53112
+ address: side.silo,
53113
+ lenderKey: lender,
53114
+ family: "silo",
53115
+ role: "market",
53116
+ marketUid: mu,
53117
+ asset: lc(side.token)
53118
+ });
53119
+ if (isAddr(side.protectedShareToken))
53120
+ push2({
53121
+ chainId,
53122
+ address: side.protectedShareToken,
53123
+ lenderKey: lender,
53124
+ family: "erc20-share",
53125
+ role: "shareToken",
53126
+ side: "collateral",
53127
+ marketUid: mu,
53128
+ asset: lc(side.token),
53129
+ shareEvents: "transfers"
53130
+ });
53131
+ if (isAddr(side.debtShareToken))
53132
+ push2({
53133
+ chainId,
53134
+ address: side.debtShareToken,
53135
+ lenderKey: lender,
53136
+ family: "erc20-share",
53137
+ role: "debtToken",
53138
+ side: "borrow",
53139
+ marketUid: mu,
53140
+ asset: lc(side.token),
53141
+ shareEvents: "transfers"
53142
+ });
53143
+ }
53144
+ }
53145
+ };
53146
+ siloRows(siloMarkets()?.[chainId], siloV2LenderKey);
53147
+ siloRows(siloMarketsV3()?.[chainId], siloV3LenderKey);
53148
+ const siloHooks = (markets, keyOf) => {
53149
+ for (const m of markets ?? []) {
53150
+ const hook = m.silo0?.hookReceiver ?? m.silo1?.hookReceiver;
53151
+ if (!isAddr(hook)) continue;
53152
+ const lender = keyOf(m.siloConfig);
53153
+ const legs = {};
53154
+ for (const side of [m.silo0, m.silo1])
53155
+ if (isAddr(side?.silo))
53156
+ legs[lc(side.silo)] = {
53157
+ marketUid: uid(lender, side.silo),
53158
+ asset: lc(side.token)
53159
+ };
53160
+ push2({
53161
+ chainId,
53162
+ address: hook,
53163
+ lenderKey: lender,
53164
+ family: "silo",
53165
+ role: "hook",
53166
+ markets: legs,
53167
+ label: `${m.name ?? lender} liquidation hook`
53168
+ });
53169
+ }
53170
+ };
53171
+ siloHooks(siloMarkets()?.[chainId], siloV2LenderKey);
53172
+ siloHooks(siloMarketsV3()?.[chainId], siloV3LenderKey);
53173
+ const fluidEntries = fluidVaultEntries(chainId);
53174
+ for (const [vault, meta] of fluidEntries) {
53175
+ const lender = `FLUID_${chainId}_${meta.vaultId}`;
53176
+ const markets = {};
53177
+ meta.supply?.assets?.forEach((a, i) => {
53178
+ if (isAddr(a.underlying))
53179
+ markets[i === 0 ? "supply" : `supply${i}`] = {
53180
+ marketUid: uid(lender, a.underlying),
53181
+ asset: lc(a.underlying)
53182
+ };
53183
+ });
53184
+ meta.borrow?.assets?.forEach((a, i) => {
53185
+ if (isAddr(a.underlying))
53186
+ markets[i === 0 ? "borrow" : `borrow${i}`] = {
53187
+ marketUid: uid(lender, a.underlying),
53188
+ asset: lc(a.underlying)
53189
+ };
53190
+ });
53191
+ push2({
53192
+ chainId,
53193
+ address: vault,
53194
+ lenderKey: lender,
53195
+ family: "fluid",
53196
+ role: "market",
53197
+ markets,
53198
+ label: `vault ${meta.vaultId} t${meta.type}`
53199
+ });
53200
+ for (const a of meta.supply?.assets ?? []) {
53201
+ if (isAddr(a.fToken))
53202
+ push2({
53203
+ chainId,
53204
+ address: a.fToken,
53205
+ lenderKey: `FLUID_${chainId}_LENDING`,
53206
+ family: "erc20-share",
53207
+ role: "shareToken",
53208
+ side: "supply",
53209
+ marketUid: uid(`FLUID_${chainId}_LENDING`, a.underlying),
53210
+ asset: lc(a.underlying)
53211
+ });
53212
+ }
53213
+ }
53214
+ if (fluidEntries.length) {
53215
+ push2({
53216
+ chainId,
53217
+ address: FLUID_VAULT_FACTORY2,
53218
+ lenderKey: `FLUID_${chainId}`,
53219
+ family: "fluid",
53220
+ role: "positionNft",
53221
+ label: "VaultFactory (position NFT)"
53222
+ });
53223
+ }
53224
+ for (const [addr4, name] of Object.entries(
53225
+ gearboxMarketConfigurators(chainId) ?? {}
53226
+ )) {
53227
+ push2({
53228
+ chainId,
53229
+ address: addr4,
53230
+ lenderKey: "GEARBOX_V3",
53231
+ family: "gearbox",
53232
+ role: "factory",
53233
+ label: `market configurator ${name}`
53234
+ });
53235
+ }
53236
+ const dolo = dolomiteConfigs()?.[chainId];
53237
+ if (dolo?.dolomiteMargin) {
53238
+ push2({
53239
+ chainId,
53240
+ address: dolo.dolomiteMargin,
53241
+ lenderKey: "DOLOMITE",
53242
+ family: "dolomite",
53243
+ role: "core"
53244
+ });
53245
+ for (const r of [
53246
+ dolo.depositWithdrawalRouter,
53247
+ dolo.borrowPositionRouter,
53248
+ dolo.genericTraderRouter,
53249
+ dolo.depositWithdrawalProxy,
53250
+ dolo.borrowPositionProxy,
53251
+ dolo.genericTraderProxy
53252
+ ])
53253
+ if (isAddr(r))
53254
+ push2({
53255
+ chainId,
53256
+ address: r,
53257
+ lenderKey: "DOLOMITE",
53258
+ family: "dolomite",
53259
+ role: "router"
53260
+ });
53261
+ for (const [marketId, iso] of Object.entries(
53262
+ dolomiteIsolation()?.[chainId] ?? {}
53263
+ )) {
53264
+ if (isAddr(iso.factory))
53265
+ push2({
53266
+ chainId,
53267
+ address: iso.factory,
53268
+ lenderKey: "DOLOMITE",
53269
+ family: "dolomite",
53270
+ role: "factory",
53271
+ marketUid: uid("DOLOMITE", marketId),
53272
+ asset: lc(iso.underlying),
53273
+ label: `isolation ${iso.underlyingSymbol}`
53274
+ });
53275
+ }
53276
+ }
53277
+ for (const [lender, chains] of Object.entries(initConfig() ?? {})) {
53278
+ const pools = chains?.[chainId] ?? [];
53279
+ const core = getInitCoreAddress(chainId);
53280
+ const posManager = getInitPosManagerAddress(chainId);
53281
+ if (pools.length && isAddr(core)) {
53282
+ const poolRows = {};
53283
+ for (const p of pools)
53284
+ if (isAddr(p.pool)) poolRows[p.pool.toLowerCase()] = { marketUid: uid(lender, p.pool), asset: lc(p.underlying) };
53285
+ push2({ chainId, address: core, lenderKey: lender, family: "init", role: "core", markets: poolRows });
53286
+ if (isAddr(posManager))
53287
+ push2({ chainId, address: posManager, lenderKey: lender, family: "init", role: "positionNft" });
53288
+ }
53289
+ for (const p of pools) {
53290
+ push2({
53291
+ chainId,
53292
+ address: p.pool,
53293
+ lenderKey: lender,
53294
+ family: "init",
53295
+ role: "market",
53296
+ marketUid: uid(lender, p.pool),
53297
+ asset: lc(p.underlying)
53298
+ });
53299
+ }
53300
+ }
53301
+ for (const [lender, chains] of Object.entries(liquityMarkets() ?? {})) {
53302
+ for (const b of chains?.[chainId] ?? []) {
53303
+ const m = uid(lender, b.collToken);
53304
+ push2({
53305
+ chainId,
53306
+ address: b.troveManager,
53307
+ lenderKey: lender,
53308
+ family: "liquity",
53309
+ role: "market",
53310
+ marketUid: m,
53311
+ asset: lc(b.collToken),
53312
+ label: b.name
53313
+ });
53314
+ if (isAddr(b.troveNFT))
53315
+ push2({
53316
+ chainId,
53317
+ address: b.troveNFT,
53318
+ lenderKey: lender,
53319
+ family: "liquity",
53320
+ role: "positionNft",
53321
+ marketUid: m
53322
+ });
53323
+ if (isAddr(b.borrowerOperations))
53324
+ push2({
53325
+ chainId,
53326
+ address: b.borrowerOperations,
53327
+ lenderKey: lender,
53328
+ family: "liquity",
53329
+ role: "core",
53330
+ marketUid: m
53331
+ });
53332
+ if (isAddr(b.stabilityPool))
53333
+ push2({
53334
+ chainId,
53335
+ address: b.stabilityPool,
53336
+ lenderKey: lender,
53337
+ family: "liquity",
53338
+ role: "market",
53339
+ marketUid: `${m}:sp`,
53340
+ side: "supply",
53341
+ label: "stability pool"
53342
+ });
53343
+ }
53344
+ }
53345
+ for (const [lender, chains] of Object.entries(riverMarkets() ?? {})) {
53346
+ const debtToken = riverConfigFor(lender, chainId)?.debtToken;
53347
+ for (const m of chains?.[chainId]?.markets ?? []) {
53348
+ const key3 = `${lender}_${chainId}_${m.index}`;
53349
+ push2({
53350
+ chainId,
53351
+ address: m.troveManager,
53352
+ lenderKey: key3,
53353
+ family: "river",
53354
+ role: "market",
53355
+ marketUid: uid(key3, m.collToken),
53356
+ asset: lc(m.collToken),
53357
+ // TroveUpdated carries debt AND collateral; the debt row is satUSD
53358
+ markets: isAddr(debtToken) ? { loan: { marketUid: uid(key3, debtToken), asset: lc(debtToken) } } : void 0,
53359
+ label: m.name
53360
+ });
53361
+ }
53362
+ }
53363
+ const tellerCfg = tellerConfig()?.[chainId];
53364
+ if (isAddr(tellerCfg?.tellerV2))
53365
+ push2({
53366
+ chainId,
53367
+ address: tellerCfg.tellerV2,
53368
+ lenderKey: "TELLER",
53369
+ family: "teller",
53370
+ role: "core",
53371
+ label: "TellerV2 (bid lifecycle)"
53372
+ });
53373
+ for (const p of tellerPools()?.[chainId] ?? []) {
53374
+ const lender = `TELLER_${p.pool.replace(/^0x/, "").toUpperCase()}`;
53375
+ push2({
53376
+ chainId,
53377
+ address: p.pool,
53378
+ lenderKey: lender,
53379
+ family: "teller",
53380
+ role: "market",
53381
+ marketUid: uid(lender, p.principal),
53382
+ asset: lc(p.principal),
53383
+ label: p.name
53384
+ });
53385
+ }
53386
+ const termEmitters = {
53387
+ "1": "0xf021b31282a60528b2f47d07ce353da870be78b3"
53388
+ };
53389
+ const termLoanRows = {};
53390
+ for (const m of termMarkets()?.[chainId] ?? []) {
53391
+ const lender = termLenderKey(m.termRepoId);
53392
+ if (isAddr(m.purchaseToken))
53393
+ termLoanRows[m.termRepoId.toLowerCase()] = { marketUid: uid(lender, m.purchaseToken), asset: lc(m.purchaseToken) };
53394
+ push2({
53395
+ chainId,
53396
+ address: m.servicer,
53397
+ lenderKey: lender,
53398
+ family: "term",
53399
+ role: "market",
53400
+ marketUid: uid(lender, m.purchaseToken),
53401
+ asset: lc(m.purchaseToken),
53402
+ label: m.name
53403
+ });
53404
+ if (isAddr(m.repoToken))
53405
+ push2({
53406
+ chainId,
53407
+ address: m.repoToken,
53408
+ lenderKey: lender,
53409
+ family: "erc20-share",
53410
+ role: "shareToken",
53411
+ side: "supply",
53412
+ marketUid: uid(lender, m.purchaseToken),
53413
+ asset: lc(m.purchaseToken)
53414
+ });
53415
+ if (isAddr(m.auction))
53416
+ push2({
53417
+ chainId,
53418
+ address: m.auction,
53419
+ lenderKey: lender,
53420
+ family: "term",
53421
+ role: "core",
53422
+ label: "auction"
53423
+ });
53424
+ }
53425
+ if (isAddr(termEmitters[chainId]))
53426
+ push2({
53427
+ chainId,
53428
+ address: termEmitters[chainId],
53429
+ lenderKey: "TERM",
53430
+ family: "term",
53431
+ role: "core",
53432
+ label: "event emitter",
53433
+ markets: Object.keys(termLoanRows).length ? termLoanRows : void 0
53434
+ });
53435
+ const termC = termConfig()?.[chainId];
53436
+ if (termC?.termController)
53437
+ push2({
53438
+ chainId,
53439
+ address: termC.termController,
53440
+ lenderKey: "TERM",
53441
+ family: "term",
53442
+ role: "core",
53443
+ label: "controller"
53444
+ });
53445
+ const tm = termMaxConfig()?.[chainId];
53446
+ if (tm) {
53447
+ for (const f of tm.marketFactories ?? [])
53448
+ if (isAddr(f))
53449
+ push2({
53450
+ chainId,
53451
+ address: f,
53452
+ lenderKey: "TERMMAX",
53453
+ family: "termmax",
53454
+ role: "factory"
53455
+ });
53456
+ if (isAddr(tm.routerV2))
53457
+ push2({
53458
+ chainId,
53459
+ address: tm.routerV2,
53460
+ lenderKey: "TERMMAX",
53461
+ family: "termmax",
53462
+ role: "router"
53463
+ });
53464
+ }
53465
+ const mn = midnightConfig()?.[chainId];
53466
+ if (mn?.midnight) {
53467
+ const mnMarkets = {};
53468
+ for (const m of midnightMarkets()?.[chainId] ?? []) {
53469
+ const key3 = midnightLenderKey(m.marketId);
53470
+ const id = m.marketId.toLowerCase();
53471
+ if (isAddr(m.loanToken)) mnMarkets[id] = { marketUid: uid(key3, m.loanToken), asset: lc(m.loanToken) };
53472
+ m.collateralParams?.forEach((c, i) => {
53473
+ if (isAddr(c.token))
53474
+ mnMarkets[`${id}:${c.token.toLowerCase()}`] = {
53475
+ marketUid: uid(key3, midnightCollateralRef(c.token, i)),
53476
+ asset: lc(c.token)
53477
+ };
53478
+ });
53479
+ }
53480
+ push2({
53481
+ chainId,
53482
+ address: mn.midnight,
53483
+ lenderKey: "MORPHO_MIDNIGHT",
53484
+ family: "midnight",
53485
+ role: "core",
53486
+ markets: Object.keys(mnMarkets).length ? mnMarkets : void 0
53487
+ });
53488
+ }
53489
+ for (const [lender, chains] of Object.entries(llamaLendMarkets() ?? {})) {
53490
+ for (const m of chains?.[chainId]?.markets ?? []) {
53491
+ const key3 = `LLAMALEND_${m.controller.replace(/^0x/, "").toUpperCase()}`;
53492
+ const mu = uid(key3, m.borrowedToken);
53493
+ push2({
53494
+ chainId,
53495
+ address: m.controller,
53496
+ lenderKey: key3,
53497
+ family: "llamalend",
53498
+ role: "market",
53499
+ marketUid: mu,
53500
+ asset: lc(m.borrowedToken),
53501
+ label: m.name,
53502
+ markets: {
53503
+ loan: { marketUid: mu, asset: lc(m.borrowedToken) },
53504
+ collateral: {
53505
+ marketUid: uid(key3, m.collateralToken),
53506
+ asset: lc(m.collateralToken)
53507
+ }
53508
+ }
53509
+ });
53510
+ if (isAddr(m.vault))
53511
+ push2({
53512
+ chainId,
53513
+ address: m.vault,
53514
+ lenderKey: key3,
53515
+ family: "erc20-share",
53516
+ role: "shareToken",
53517
+ side: "supply",
53518
+ marketUid: mu,
53519
+ asset: lc(m.borrowedToken)
53520
+ });
53521
+ }
53522
+ }
53523
+ for (const lender of ["FRAXLEND"]) {
53524
+ for (const p of fraxlendPairsFor(lender, chainId) ?? []) {
53525
+ const key3 = fraxlendLenderKey(lender, chainId, p.address);
53526
+ push2({
53527
+ chainId,
53528
+ address: p.address,
53529
+ lenderKey: key3,
53530
+ family: "fraxlend",
53531
+ role: "market",
53532
+ label: p.label ?? p.symbol
53533
+ });
53534
+ }
53535
+ }
53536
+ for (const [lender, chains] of Object.entries(inverseMarkets() ?? {})) {
53537
+ const dola = inverseConfigFor(lender, chainId)?.dola;
53538
+ for (const m of chains?.[chainId]?.markets ?? []) {
53539
+ const key3 = `INVERSE_${m.address.replace(/^0x/, "").toUpperCase()}`;
53540
+ push2({
53541
+ chainId,
53542
+ address: m.address,
53543
+ lenderKey: key3,
53544
+ family: "inverse",
53545
+ role: "market",
53546
+ marketUid: uid(key3, m.collToken),
53547
+ asset: lc(m.collToken),
53548
+ label: m.name,
53549
+ markets: {
53550
+ collateral: {
53551
+ marketUid: uid(key3, m.collToken),
53552
+ asset: lc(m.collToken)
53553
+ },
53554
+ ...isAddr(dola) ? { loan: { marketUid: uid(key3, dola), asset: lc(dola) } } : {}
53555
+ }
53556
+ });
53557
+ }
53558
+ }
53559
+ for (const lender of resupplyLendersByChain(chainId)) {
53560
+ const c = resupplyConfigFor(lender, chainId);
53561
+ if (!c) continue;
53562
+ if (isAddr(c.registry))
53563
+ push2({
53564
+ chainId,
53565
+ address: c.registry,
53566
+ lenderKey: lender,
53567
+ family: "resupply",
53568
+ role: "factory"
53569
+ });
53570
+ for (const p of c.pairAllowlist ?? [])
53571
+ if (isAddr(p))
53572
+ push2({
53573
+ chainId,
53574
+ address: p,
53575
+ lenderKey: lender,
53576
+ family: "resupply",
53577
+ role: "market"
53578
+ });
53579
+ }
53580
+ for (const [lender, chains] of Object.entries(curvanceConfig() ?? {})) {
53581
+ const c = chains?.[chainId];
53582
+ if (!c) continue;
53583
+ if (isAddr(c.centralRegistry))
53584
+ push2({
53585
+ chainId,
53586
+ address: c.centralRegistry,
53587
+ lenderKey: lender,
53588
+ family: "curvance",
53589
+ role: "factory"
53590
+ });
53591
+ for (const pm of Object.values(c.positionManagers ?? {}))
53592
+ for (const a of Object.values(pm))
53593
+ if (isAddr(a))
53594
+ push2({
53595
+ chainId,
53596
+ address: a,
53597
+ lenderKey: lender,
53598
+ family: "curvance",
53599
+ role: "router"
53600
+ });
53601
+ }
53602
+ for (const [lender, chains] of Object.entries(frankencoinMarkets() ?? {})) {
53603
+ for (const m of chains?.[chainId]?.markets ?? []) {
53604
+ const key3 = `FRANKENCOIN_${chainId}_${m.position.replace(/^0x/, "").toUpperCase()}`;
53605
+ push2({
53606
+ chainId,
53607
+ address: m.position,
53608
+ lenderKey: key3,
53609
+ family: "frankencoin",
53610
+ role: "market",
53611
+ marketUid: uid(key3, m.collToken),
53612
+ asset: lc(m.collToken),
53613
+ label: m.name
53614
+ });
53615
+ }
53616
+ }
53617
+ for (const lender of ["SKY", "USDD"]) {
53618
+ const cfg = dssConfigFor(lender, chainId);
53619
+ if (!cfg) continue;
53620
+ if (isAddr(cfg.cdpManager))
53621
+ push2({
53622
+ chainId,
53623
+ address: cfg.cdpManager,
53624
+ lenderKey: lender,
53625
+ family: "dss",
53626
+ role: "core",
53627
+ label: "CDP manager"
53628
+ });
53629
+ const debt = dssDebtToken(cfg);
53630
+ const ilkLegs = {};
53631
+ for (const m of dssChainData(lender, chainId)?.markets ?? []) {
53632
+ if (!m.ilk) continue;
53633
+ const key3 = `${lender}_${chainId}_${m.ilk}`;
53634
+ const ilkHex = dssIlkBytes32(m.ilk).toLowerCase();
53635
+ if (isAddr(m.collToken))
53636
+ ilkLegs[`${ilkHex}:collateral`] = { marketUid: uid(key3, m.collToken), asset: lc(m.collToken) };
53637
+ if (isAddr(debt)) ilkLegs[`${ilkHex}:loan`] = { marketUid: uid(key3, debt), asset: lc(debt) };
53638
+ }
53639
+ if (isAddr(cfg.vat))
53640
+ push2({
53641
+ chainId,
53642
+ address: cfg.vat,
53643
+ lenderKey: lender,
53644
+ family: "dss",
53645
+ role: "core",
53646
+ label: "vat",
53647
+ markets: Object.keys(ilkLegs).length ? ilkLegs : void 0
53648
+ });
53649
+ const proxyRegistry = cfg.proxyRegistry;
53650
+ if (isAddr(proxyRegistry))
53651
+ push2({
53652
+ chainId,
53653
+ address: proxyRegistry,
53654
+ lenderKey: lender,
53655
+ family: "dss",
53656
+ role: "factory",
53657
+ label: "proxy registry"
53658
+ });
53659
+ for (const m of dssChainData(lender, chainId)?.markets ?? [])
53660
+ if (isAddr(m.gemJoin))
53661
+ push2({
53662
+ chainId,
53663
+ address: m.gemJoin,
53664
+ lenderKey: `${lender}_${chainId}_${m.ilk}`,
53665
+ family: "dss",
53666
+ role: "market",
53667
+ label: m.ilk
53668
+ });
53669
+ }
53670
+ for (const lender of coolerLendersByChain(chainId)) {
53671
+ const c = coolerConfigFor(lender, chainId);
53672
+ if (c?.monoCooler)
53673
+ push2({
53674
+ chainId,
53675
+ address: c.monoCooler,
53676
+ lenderKey: lender,
53677
+ family: "cooler",
53678
+ role: "core",
53679
+ markets: {
53680
+ ...isAddr(c.gohm) ? {
53681
+ collateral: {
53682
+ marketUid: uid(lender, c.gohm),
53683
+ asset: lc(c.gohm)
53684
+ }
53685
+ } : {},
53686
+ ...isAddr(c.usds) ? { loan: { marketUid: uid(lender, c.usds), asset: lc(c.usds) } } : {}
53687
+ }
53688
+ });
53689
+ }
53690
+ for (const [lender, chains] of Object.entries(twyneMarkets() ?? {})) {
53691
+ const tc = twyneConfigFor(lender, chainId);
53692
+ if (isAddr(tc?.collateralVaultFactory))
53693
+ push2({
53694
+ chainId,
53695
+ address: tc.collateralVaultFactory,
53696
+ lenderKey: lender,
53697
+ family: "twyne",
53698
+ role: "factory",
53699
+ label: `${lender} CollateralVaultFactory`
53700
+ });
53701
+ if (isAddr(tc?.evc))
53702
+ push2({
53703
+ chainId,
53704
+ address: tc.evc,
53705
+ lenderKey: lender,
53706
+ family: "twyne",
53707
+ role: "core",
53708
+ label: `${lender} EVC`
53709
+ });
53710
+ for (const m of chains?.[chainId]?.markets ?? []) {
53711
+ const key3 = m.key.startsWith("TWYNE_") ? m.key : `TWYNE_${chainId}_${m.key}`;
53712
+ push2({
53713
+ chainId,
53714
+ address: m.intermediateVault,
53715
+ lenderKey: key3,
53716
+ family: "twyne",
53717
+ role: "market",
53718
+ marketUid: `${key3}:${chainId}:${lc(m.underlyingAsset)}`,
53719
+ asset: lc(m.underlyingAsset),
53720
+ label: m.name
53721
+ });
53722
+ }
53723
+ }
53724
+ for (const m of exactlyMarkets()?.[chainId] ?? []) {
53725
+ const key3 = EXACTLY_LENDER_KEY;
53726
+ push2({
53727
+ chainId,
53728
+ address: m.market,
53729
+ lenderKey: key3,
53730
+ family: "exactly",
53731
+ role: "market",
53732
+ marketUid: uid(key3, m.asset),
53733
+ asset: lc(m.asset),
53734
+ label: m.name
53735
+ });
53736
+ }
53737
+ for (const lender of ["FLYING_TULIP"]) {
53738
+ const c = flyingTulipConfigFor(lender, chainId);
53739
+ if (c?.positionsManager)
53740
+ push2({
53741
+ chainId,
53742
+ address: c.positionsManager,
53743
+ lenderKey: lender,
53744
+ family: "flying-tulip",
53745
+ role: "core"
53746
+ });
53747
+ }
53748
+ for (const s of getSavingsRegistry(chainId) ?? []) {
53749
+ push2({
53750
+ chainId,
53751
+ address: s.address,
53752
+ lenderKey: "vault.savings",
53753
+ family: "erc20-share",
53754
+ role: "shareToken",
53755
+ side: "share",
53756
+ marketUid: `vault.savings:${chainId}:${s.address.toLowerCase()}`,
53757
+ asset: lc(s.underlying),
53758
+ label: s.symbol
53759
+ });
53760
+ }
53761
+ for (const l of getLstRegistry(chainId) ?? []) {
53762
+ push2({
53763
+ chainId,
53764
+ address: l.address,
53765
+ lenderKey: "vault.lst",
53766
+ family: "erc20-share",
53767
+ role: "shareToken",
53768
+ side: "share",
53769
+ marketUid: `vault.lst:${chainId}:${l.address.toLowerCase()}`,
53770
+ asset: lc(l.underlying),
53771
+ label: l.symbol
53772
+ });
53773
+ }
53774
+ return out;
53775
+ }
53776
+ function emitterCoverage(chainId) {
53777
+ const rows = enumerateEmitters(chainId);
53778
+ const keys = new Set(rows.map((r) => r.lenderKey));
53779
+ const covered = [];
53780
+ const missing = [];
53781
+ for (const lender of getLendersForChain(chainId)) {
53782
+ const hit = keys.has(lender) || [...keys].some(
53783
+ (k) => lender.startsWith(k + "_") || k.startsWith(lender + "_") || k.startsWith(lender)
53784
+ );
53785
+ (hit ? covered : missing).push(lender);
53786
+ }
53787
+ return { covered, missing };
53788
+ }
53789
+
53790
+ // src/lending/margin/base/standard/deposit.ts
53791
+ function computeDepositDelta(amount4, price2, balanceData2, config, modeId, createNewSubAccount = false, apr, yieldParams) {
53792
+ const { borrowCollateralFactor, collateralFactor } = getAssetConfig(config, modeId);
53793
+ const base = createNewSubAccount ? EMPTY_BALANCE : balanceData2;
53794
+ const dollarAmount = amount4 * price2;
53795
+ const postTrade = {
53796
+ ...base,
53797
+ borrowDiscountedCollateral: base.borrowDiscountedCollateral + borrowCollateralFactor * dollarAmount,
53798
+ collateral: base.collateral + collateralFactor * dollarAmount,
53799
+ deposits: base.deposits + dollarAmount,
53800
+ nav: base.nav + dollarAmount
53801
+ };
53802
+ const result = computePostTradeMetrics(base, postTrade);
53803
+ if (apr && yieldParams) {
53804
+ const cashFlowDeposits = base.deposits * apr.depositApr;
53805
+ const cashFlowDebt = base.debt * apr.borrowApr;
53806
+ const rewardFlowDeposits = base.deposits * (apr.rewardDepositApr ?? 0);
53807
+ const rewardFlowDebt = base.debt * (apr.rewardBorrowApr ?? 0);
53808
+ const intrinsicFlowDeposits = base.deposits * apr.intrinsicDepositApr;
53809
+ const intrinsicFlowDebt = base.debt * apr.intrinsicBorrowApr;
53810
+ const newApr = { ...apr };
53811
+ [newApr.borrowApr, newApr.depositApr, newApr.apr] = getOrganicYieldDeposit(
53812
+ dollarAmount,
53813
+ cashFlowDeposits,
53814
+ cashFlowDebt,
53815
+ base.deposits,
53816
+ base.debt,
53817
+ yieldParams
53818
+ );
53819
+ newApr.rewards = getRewardYieldDeposit(
53820
+ dollarAmount,
53821
+ rewardFlowDeposits,
53822
+ rewardFlowDebt,
53823
+ base.deposits,
53824
+ base.debt,
53825
+ yieldParams
53826
+ );
53827
+ [newApr.intrinsicBorrowApr, newApr.intrinsicDepositApr, newApr.intrinsicApr] = getIntrinsicYieldDeposit(
53828
+ dollarAmount,
53829
+ intrinsicFlowDeposits,
53830
+ intrinsicFlowDebt,
53831
+ base.deposits,
53832
+ base.debt,
53833
+ yieldParams
53834
+ );
53835
+ result.post.aprData = newApr;
53836
+ }
53837
+ return result;
53838
+ }
53839
+
53840
+ // src/lending/margin/base/deposit.ts
53841
+ function computeDepositDelta2(lender, amount4, price2, balanceData2, config, modeId, createNewSubAccount, apr, yieldParams, targetMarketUid, positions) {
53842
+ if (isSumerType(lender)) {
53843
+ if (!positions || targetMarketUid === void 0) {
53844
+ throw new Error("Sumer operations require positions and targetMarketUid");
53845
+ }
53846
+ return computeSumerDepositDelta(
53847
+ amount4,
53848
+ price2,
53849
+ targetMarketUid,
53850
+ balanceData2,
53851
+ positions,
53852
+ createNewSubAccount,
53853
+ apr,
53854
+ yieldParams
53855
+ );
53856
+ }
53857
+ if (!config || modeId === void 0) {
53858
+ throw new Error("Standard operations require config and modeId");
53859
+ }
53860
+ return computeDepositDelta(
53861
+ amount4,
53862
+ price2,
53863
+ balanceData2,
53864
+ config,
53865
+ modeId,
53866
+ createNewSubAccount,
53867
+ apr,
53868
+ yieldParams
53869
+ );
53870
+ }
53871
+
53872
+ // src/lending/margin/base/standard/withdraw.ts
53873
+ function computeWithdrawDelta(amount4, price2, balanceData2, config, modeId, apr, yieldParams) {
53874
+ const { borrowCollateralFactor, collateralFactor } = getAssetConfig(config, modeId);
53875
+ const dollarAmount = amount4 * price2;
53876
+ const postTrade = {
53877
+ ...balanceData2,
53878
+ borrowDiscountedCollateral: balanceData2.borrowDiscountedCollateral - borrowCollateralFactor * dollarAmount,
53879
+ collateral: balanceData2.collateral - collateralFactor * dollarAmount,
53880
+ deposits: balanceData2.deposits - dollarAmount,
53881
+ nav: balanceData2.nav - dollarAmount
53882
+ };
53883
+ const result = computePostTradeMetrics(balanceData2, postTrade);
53884
+ if (apr && yieldParams) {
53885
+ const cashFlowDeposits = balanceData2.deposits * apr.depositApr;
53886
+ const cashFlowDebt = balanceData2.debt * apr.borrowApr;
53887
+ const rewardFlowDeposits = balanceData2.deposits * (apr.rewardDepositApr ?? 0);
53888
+ const rewardFlowDebt = balanceData2.debt * (apr.rewardBorrowApr ?? 0);
53889
+ const intrinsicFlowDeposits = balanceData2.deposits * apr.intrinsicDepositApr;
53890
+ const intrinsicFlowDebt = balanceData2.debt * apr.intrinsicBorrowApr;
53891
+ const newApr = { ...apr };
53892
+ [newApr.borrowApr, newApr.depositApr, newApr.apr] = getOrganicYieldWithdraw(
53893
+ dollarAmount,
53894
+ cashFlowDeposits,
53895
+ cashFlowDebt,
53896
+ balanceData2.deposits,
53897
+ balanceData2.debt,
53898
+ yieldParams
53899
+ );
53900
+ newApr.rewards = getRewardYieldWithdraw(
53901
+ dollarAmount,
53902
+ rewardFlowDeposits,
53903
+ rewardFlowDebt,
53904
+ balanceData2.deposits,
53905
+ balanceData2.debt,
53906
+ yieldParams
53907
+ );
53908
+ [newApr.intrinsicBorrowApr, newApr.intrinsicDepositApr, newApr.intrinsicApr] = getIntrinsicYieldWithdraw(
53909
+ dollarAmount,
53910
+ intrinsicFlowDeposits,
53911
+ intrinsicFlowDebt,
53912
+ balanceData2.deposits,
53913
+ balanceData2.debt,
53914
+ yieldParams
53915
+ );
53916
+ result.post.aprData = newApr;
53917
+ }
53918
+ return result;
53919
+ }
53920
+
53921
+ // src/lending/margin/base/withdraw.ts
53922
+ function computeWithdrawDelta2(lender, amount4, price2, balanceData2, config, modeId, apr, yieldParams, targetMarketUid, positions) {
53923
+ if (isSumerType(lender)) {
53924
+ if (!positions || targetMarketUid === void 0) {
53925
+ throw new Error("Sumer operations require positions and targetMarketUid");
53926
+ }
53927
+ return computeSumerWithdrawDelta(
53928
+ amount4,
53929
+ price2,
53930
+ targetMarketUid,
53931
+ balanceData2,
53932
+ positions,
53933
+ apr,
53934
+ yieldParams
53935
+ );
53936
+ }
53937
+ if (!config || modeId === void 0) {
53938
+ throw new Error("Standard operations require config and modeId");
53939
+ }
53940
+ return computeWithdrawDelta(
53941
+ amount4,
53942
+ price2,
53943
+ balanceData2,
53944
+ config,
53945
+ modeId,
53946
+ apr,
53947
+ yieldParams
53948
+ );
53949
+ }
53950
+
53951
+ // src/lending/margin/base/standard/borrow.ts
53952
+ function computeBorrowDelta(amount4, price2, balanceData2, config, modeId, apr, yieldParams, irMode) {
53953
+ const { borrowFactor } = getAssetConfig(config, modeId);
53954
+ const dollarAmount = amount4 * price2;
53955
+ const postTrade = {
53956
+ ...balanceData2,
53957
+ debt: balanceData2.debt + dollarAmount,
53958
+ adjustedDebt: balanceData2.adjustedDebt + borrowFactor * dollarAmount,
53959
+ nav: balanceData2.nav - dollarAmount
53960
+ };
53961
+ const result = computePostTradeMetrics(balanceData2, postTrade);
53962
+ if (apr && yieldParams) {
53963
+ const mode = irMode ?? 2;
53964
+ const cashFlowDeposits = balanceData2.deposits * apr.depositApr;
53965
+ const cashFlowDebt = balanceData2.debt * apr.borrowApr;
53966
+ const rewardFlowDeposits = balanceData2.deposits * (apr.rewardDepositApr ?? 0);
53967
+ const rewardFlowDebt = balanceData2.debt * (apr.rewardBorrowApr ?? 0);
53968
+ const intrinsicFlowDeposits = balanceData2.deposits * apr.intrinsicDepositApr;
53969
+ const intrinsicFlowDebt = balanceData2.debt * apr.intrinsicBorrowApr;
53970
+ const newApr = { ...apr };
53971
+ [newApr.borrowApr, newApr.depositApr, newApr.apr] = getOrganicYieldBorrow(
53972
+ dollarAmount,
53973
+ mode,
53974
+ cashFlowDeposits,
53975
+ cashFlowDebt,
53976
+ balanceData2.deposits,
53977
+ balanceData2.debt,
53978
+ yieldParams
53979
+ );
53980
+ newApr.rewards = getRewardYieldBorrow(
53981
+ dollarAmount,
53982
+ mode,
53983
+ rewardFlowDeposits,
53984
+ rewardFlowDebt,
53985
+ balanceData2.deposits,
53986
+ balanceData2.debt,
53987
+ yieldParams
53988
+ );
53989
+ [newApr.intrinsicBorrowApr, newApr.intrinsicDepositApr, newApr.intrinsicApr] = getIntrinsicYieldBorrow(
53990
+ dollarAmount,
53991
+ intrinsicFlowDeposits,
53992
+ intrinsicFlowDebt,
53993
+ balanceData2.deposits,
53994
+ balanceData2.debt,
53995
+ yieldParams
53996
+ );
53997
+ result.post.aprData = newApr;
53998
+ }
53999
+ return result;
54000
+ }
54001
+
54002
+ // src/lending/margin/base/borrow.ts
54003
+ function computeBorrowDelta2(lender, amount4, price2, balanceData2, config, modeId, apr, yieldParams, irMode, targetMarketUid, positions) {
54004
+ if (isSumerType(lender)) {
54005
+ if (!positions || targetMarketUid === void 0) {
54006
+ throw new Error("Sumer operations require positions and targetMarketUid");
54007
+ }
54008
+ return computeSumerBorrowDelta(
54009
+ amount4,
54010
+ price2,
54011
+ targetMarketUid,
54012
+ balanceData2,
54013
+ positions,
54014
+ apr,
54015
+ yieldParams,
54016
+ irMode
54017
+ );
54018
+ }
54019
+ if (!config || modeId === void 0) {
54020
+ throw new Error("Standard operations require config and modeId");
54021
+ }
54022
+ return computeBorrowDelta(
54023
+ amount4,
54024
+ price2,
54025
+ balanceData2,
54026
+ config,
54027
+ modeId,
54028
+ apr,
54029
+ yieldParams,
54030
+ irMode
54031
+ );
54032
+ }
54033
+
54034
+ // src/lending/margin/base/standard/repay.ts
54035
+ function computeRepayDelta(amount4, price2, balanceData2, config, modeId, apr, yieldParams, irMode) {
54036
+ const { borrowFactor } = getAssetConfig(config, modeId);
54037
+ const dollarAmount = amount4 * price2;
54038
+ const postTrade = {
54039
+ ...balanceData2,
54040
+ debt: balanceData2.debt - dollarAmount,
54041
+ adjustedDebt: Math.max(0, balanceData2.adjustedDebt - borrowFactor * dollarAmount),
54042
+ nav: balanceData2.nav + dollarAmount
54043
+ };
54044
+ const result = computePostTradeMetrics(balanceData2, postTrade);
54045
+ if (apr && yieldParams) {
54046
+ const mode = irMode ?? 2;
54047
+ const cashFlowDeposits = balanceData2.deposits * apr.depositApr;
54048
+ const cashFlowDebt = balanceData2.debt * apr.borrowApr;
54049
+ const rewardFlowDeposits = balanceData2.deposits * (apr.rewardDepositApr ?? 0);
54050
+ const rewardFlowDebt = balanceData2.debt * (apr.rewardBorrowApr ?? 0);
54051
+ const intrinsicFlowDeposits = balanceData2.deposits * apr.intrinsicDepositApr;
54052
+ const intrinsicFlowDebt = balanceData2.debt * apr.intrinsicBorrowApr;
54053
+ const newApr = { ...apr };
54054
+ [newApr.borrowApr, newApr.depositApr, newApr.apr] = getOrganicYieldRepay(
54055
+ dollarAmount,
54056
+ mode,
54057
+ cashFlowDeposits,
54058
+ cashFlowDebt,
54059
+ balanceData2.deposits,
54060
+ balanceData2.debt,
54061
+ yieldParams
54062
+ );
54063
+ newApr.rewards = getRewardYieldRepay(
54064
+ dollarAmount,
54065
+ mode,
54066
+ rewardFlowDeposits,
54067
+ rewardFlowDebt,
54068
+ balanceData2.deposits,
54069
+ balanceData2.debt,
54070
+ yieldParams
54071
+ );
54072
+ [newApr.intrinsicBorrowApr, newApr.intrinsicDepositApr, newApr.intrinsicApr] = getIntrinsicYieldRepay(
54073
+ dollarAmount,
54074
+ intrinsicFlowDeposits,
54075
+ intrinsicFlowDebt,
54076
+ balanceData2.deposits,
54077
+ balanceData2.debt,
54078
+ yieldParams
54079
+ );
54080
+ result.post.aprData = newApr;
54081
+ }
54082
+ return result;
54083
+ }
54084
+
54085
+ // src/lending/margin/base/repay.ts
54086
+ function computeRepayDelta2(lender, amount4, price2, balanceData2, config, modeId, apr, yieldParams, irMode, targetMarketUid, positions) {
54087
+ if (isSumerType(lender)) {
54088
+ if (!positions || targetMarketUid === void 0) {
54089
+ throw new Error("Sumer operations require positions and targetMarketUid");
54090
+ }
54091
+ return computeSumerRepayDelta(
54092
+ amount4,
54093
+ price2,
54094
+ targetMarketUid,
54095
+ balanceData2,
54096
+ positions,
54097
+ apr,
54098
+ yieldParams,
54099
+ irMode
54100
+ );
54101
+ }
54102
+ if (!config || modeId === void 0) {
54103
+ throw new Error("Standard operations require config and modeId");
54104
+ }
54105
+ return computeRepayDelta(
54106
+ amount4,
54107
+ price2,
54108
+ balanceData2,
54109
+ config,
54110
+ modeId,
54111
+ apr,
54112
+ yieldParams,
54113
+ irMode
54114
+ );
54115
+ }
54116
+
54117
+ // src/lending/margin/loop/utils.ts
54118
+ var positivePart2 = (n) => n < 0 ? 0 : n;
54119
+ function nanTo(possiblyNaN, replacement = Infinity) {
54120
+ return isNaN(possiblyNaN) ? replacement : possiblyNaN;
54121
+ }
54122
+ function getHealthFactor2(collateral, adjustedDebt) {
54123
+ if (adjustedDebt === 0) return Infinity;
54124
+ const raw = collateral / adjustedDebt;
54125
+ return Math.round((isNaN(raw) ? 0 : raw) * 1e4) / 1e4;
54126
+ }
54127
+ function keysFromMaps(a, b) {
54128
+ const set = /* @__PURE__ */ new Set();
54129
+ if (a) for (const k of Object.keys(a)) set.add(k);
54130
+ if (b) for (const k of Object.keys(b)) set.add(k);
54131
+ return [...set];
54132
+ }
54133
+ function rewardsToMap(rewards) {
54134
+ const map = {};
54135
+ if (Array.isArray(rewards)) for (const r of rewards) map[r.asset] = r;
54136
+ return map;
54137
+ }
54138
+ function noOpResult(balance, apr) {
54139
+ const hf = getHealthFactor2(balance.collateral, balance.adjustedDebt);
54140
+ const bc = balance.collateral - balance.adjustedDebt;
54141
+ return {
54142
+ pre: { healthFactor: hf, borrowCapacity: bc },
54143
+ post: { healthFactor: hf, borrowCapacity: bc, balanceData: balance, aprData: apr }
54144
+ };
54145
+ }
54146
+ function buildLoopResult(balance, newBalance, apr, newApr, useAllActive = false) {
54147
+ const collateralPost = useAllActive ? newBalance.collateralAllActive : newBalance.collateral;
54148
+ return {
54149
+ pre: {
54150
+ healthFactor: getHealthFactor2(balance.collateral, balance.adjustedDebt),
54151
+ borrowCapacity: balance.collateral - balance.adjustedDebt
54152
+ },
54153
+ post: {
54154
+ healthFactor: newBalance.adjustedDebt === 0 ? Infinity : positivePart2(getHealthFactor2(collateralPost, newBalance.adjustedDebt)),
54155
+ borrowCapacity: newBalance.collateral - newBalance.adjustedDebt,
54156
+ balanceData: newBalance,
54157
+ aprData: newApr
54158
+ }
54159
+ };
54160
+ }
54161
+
54162
+ // src/lending/margin/loop/yield/getOraganicYieldChange.ts
54163
+ function getOrganicYieldOpen(amountInUSD, amountOutUSD, irModeIn, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
54164
+ const _flowIn = amountInUSD * (irModeIn === 1 ? yieldIn.stableBorrowRate : yieldIn.variableBorrowRate);
54165
+ const _flowOut = amountOutUSD * yieldOut.depositRate;
54166
+ const totalCashFlowDebt = cashFlowDebt + _flowIn;
54167
+ const totalCashFlowDeposits = cashFlowDeposits + _flowOut;
54168
+ const newCollat = deposits + amountOutUSD;
54169
+ const newDebt = debt + amountInUSD;
54170
+ return [
54171
+ totalCashFlowDebt / newDebt,
54172
+ totalCashFlowDeposits / newCollat,
54173
+ (totalCashFlowDeposits - totalCashFlowDebt) / (newCollat - newDebt)
54174
+ ];
54175
+ }
54176
+ function getOrganicYieldClose(amountInUSD, amountOutUSD, irModeOut, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
54177
+ const _flowIn = amountInUSD * yieldIn.depositRate;
54178
+ const _flowOut = amountOutUSD * (irModeOut === 1 ? yieldOut.stableBorrowRate : yieldOut.variableBorrowRate);
54179
+ const totalCashFlowDebt = cashFlowDebt - _flowOut;
54180
+ const totalCashFlowDeposits = cashFlowDeposits - _flowIn;
54181
+ const newCollat = deposits - amountInUSD;
54182
+ const newDebt = debt - amountOutUSD;
54183
+ return [
54184
+ Math.abs(newDebt) < 0.01 ? 0 : totalCashFlowDebt / newDebt,
54185
+ totalCashFlowDeposits / newCollat,
54186
+ (totalCashFlowDeposits - totalCashFlowDebt) / (newCollat - newDebt)
54187
+ ];
54188
+ }
54189
+ function getOrganicYieldDebtSwap(amountInUSD, amountOutUSD, irModeIn, irModeOut, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
54190
+ const _flowIn = amountInUSD * (irModeIn === 1 ? yieldIn.stableBorrowRate : yieldIn.variableBorrowRate);
54191
+ const _flowOut = amountOutUSD * (irModeOut === 1 ? yieldOut.stableBorrowRate : yieldOut.variableBorrowRate);
54192
+ const totalCashFlowDebt = cashFlowDebt + _flowIn - _flowOut;
54193
+ const newDebt = debt - amountOutUSD + amountInUSD;
54194
+ return [
54195
+ Math.abs(newDebt) < 0.01 ? 0 : totalCashFlowDebt / newDebt,
54196
+ cashFlowDeposits / deposits,
54197
+ (cashFlowDeposits - totalCashFlowDebt) / (deposits - newDebt)
54198
+ ];
54199
+ }
54200
+ function getOrganicYieldCollateralSwap(amountInUSD, amountOutUSD, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
54201
+ const _flowIn = amountInUSD * yieldIn.depositRate;
54202
+ const _flowOut = amountOutUSD * yieldOut.depositRate;
54203
+ const totalCashFlowDeposits = cashFlowDeposits + _flowOut - _flowIn;
54204
+ const newCollat = deposits + amountOutUSD - amountInUSD;
54205
+ return [
54206
+ Math.abs(debt) < 0.01 ? 0 : cashFlowDebt / debt,
54207
+ totalCashFlowDeposits / newCollat,
54208
+ (totalCashFlowDeposits - cashFlowDebt) / (newCollat - debt)
54209
+ ];
54210
+ }
54211
+
54212
+ // src/lending/margin/loop/yield/getRewardYieldChange.ts
54213
+ function getRewardYieldOpen(amountInUSD, amountOutUSD, irModeIn, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
54214
+ const mapIn = rewardsToMap(yieldIn?.rewards);
54215
+ const mapOut = rewardsToMap(yieldOut?.rewards);
54216
+ if (!yieldIn?.rewards?.length && !yieldOut?.rewards?.length) return {};
54217
+ const data = {};
54218
+ for (const key3 of keysFromMaps(mapIn, mapOut)) {
54219
+ const _flowIn = amountInUSD * ((irModeIn === 1 ? mapIn[key3]?.stableBorrowRate : mapIn[key3]?.variableBorrowRate) ?? 0);
54220
+ const _flowOut = amountOutUSD * (mapOut[key3]?.depositRate ?? 0);
54221
+ const totalCashFlowDebt = cashFlowDebt + _flowIn;
54222
+ const totalCashFlowDeposits = cashFlowDeposits + _flowOut;
54223
+ const newCollat = deposits + amountOutUSD;
54224
+ const newDebt = debt + amountInUSD;
54225
+ data[key3] = {
54226
+ borrowApr: totalCashFlowDebt / newDebt,
54227
+ depositApr: totalCashFlowDeposits / newCollat,
54228
+ apr: (cashFlowDeposits + cashFlowDebt + _flowIn + _flowOut) / (newCollat - newDebt)
54229
+ };
54230
+ }
54231
+ return data;
54232
+ }
54233
+ function getRewardYieldClose(amountInUSD, amountOutUSD, irModeOut, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
54234
+ const mapIn = rewardsToMap(yieldIn?.rewards);
54235
+ const mapOut = rewardsToMap(yieldOut?.rewards);
54236
+ if (!yieldIn?.rewards?.length && !yieldOut?.rewards?.length) return {};
54237
+ const data = {};
54238
+ for (const key3 of keysFromMaps(mapIn, mapOut)) {
54239
+ const _flowIn = amountInUSD * (mapIn[key3]?.depositRate ?? 0);
54240
+ const _flowOut = amountOutUSD * ((irModeOut === 1 ? mapOut[key3]?.stableBorrowRate : mapOut[key3]?.variableBorrowRate) ?? 0);
54241
+ const totalCashFlowDebt = cashFlowDebt - _flowOut;
54242
+ const totalCashFlowDeposits = cashFlowDeposits - _flowIn;
54243
+ const newCollat = deposits - amountInUSD;
54244
+ const newDebt = debt - amountOutUSD;
54245
+ data[key3] = {
54246
+ borrowApr: Math.abs(newDebt) < 0.01 ? 0 : totalCashFlowDebt / newDebt,
54247
+ depositApr: totalCashFlowDeposits / newCollat,
54248
+ apr: (cashFlowDeposits + cashFlowDebt - _flowIn - _flowOut) / (newCollat - newDebt)
54249
+ };
54250
+ }
54251
+ return data;
54252
+ }
54253
+ function getRewardYieldDebtSwap(amountInUSD, amountOutUSD, irModeIn, irModeOut, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
54254
+ const mapIn = rewardsToMap(yieldIn?.rewards);
54255
+ const mapOut = rewardsToMap(yieldOut?.rewards);
54256
+ if (!yieldIn?.rewards?.length && !yieldOut?.rewards?.length) return {};
54257
+ const data = {};
54258
+ for (const key3 of keysFromMaps(mapIn, mapOut)) {
54259
+ const _flowIn = amountInUSD * ((irModeIn === 1 ? mapIn[key3]?.stableBorrowRate : mapIn[key3]?.variableBorrowRate) ?? 0);
54260
+ const _flowOut = amountOutUSD * ((irModeOut === 1 ? mapOut[key3]?.stableBorrowRate : mapOut[key3]?.variableBorrowRate) ?? 0);
54261
+ const totalCashFlowDebt = cashFlowDebt + _flowIn - _flowOut;
54262
+ const newDebt = debt - amountOutUSD + amountInUSD;
54263
+ data[key3] = {
54264
+ borrowApr: Math.abs(newDebt) < 0.01 ? 0 : totalCashFlowDebt / newDebt,
54265
+ depositApr: cashFlowDeposits / deposits,
54266
+ apr: (cashFlowDeposits + totalCashFlowDebt) / (deposits - newDebt)
54267
+ };
54268
+ }
54269
+ return data;
54270
+ }
54271
+ function getRewardYieldCollateralSwap(amountInUSD, amountOutUSD, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
54272
+ const mapIn = rewardsToMap(yieldIn?.rewards);
54273
+ const mapOut = rewardsToMap(yieldOut?.rewards);
54274
+ if (!yieldIn?.rewards?.length && !yieldOut?.rewards?.length) return {};
54275
+ const data = {};
54276
+ for (const key3 of keysFromMaps(mapIn, mapOut)) {
54277
+ const _flowIn = amountInUSD * (mapIn[key3]?.depositRate ?? 0);
54278
+ const _flowOut = amountOutUSD * (mapOut[key3]?.depositRate ?? 0);
54279
+ const totalCashFlowDeposits = cashFlowDeposits + _flowOut - _flowIn;
54280
+ const newCollat = deposits + amountOutUSD - amountInUSD;
54281
+ data[key3] = {
54282
+ borrowApr: Math.abs(debt) < 0.01 ? 0 : cashFlowDebt / debt,
54283
+ depositApr: totalCashFlowDeposits / newCollat,
54284
+ apr: (totalCashFlowDeposits + cashFlowDebt) / (newCollat - debt)
54285
+ };
53541
54286
  }
53542
- for (const [chainId, entries] of Object.entries(VESPER_ENTRIES)) {
53543
- if (!out[chainId]) out[chainId] = [];
53544
- out[chainId].push(...entries);
54287
+ return data;
54288
+ }
54289
+
54290
+ // src/lending/margin/loop/yield/getIntrinsicYieldChange.ts
54291
+ function getIntrinsicYieldOpen(amountInUSD, amountOutUSD, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
54292
+ const _flowIn = amountInUSD * yieldIn.intrinsicYield;
54293
+ const _flowOut = amountOutUSD * yieldOut.intrinsicYield;
54294
+ const totalCashFlowDebt = cashFlowDebt + _flowIn;
54295
+ const totalCashFlowDeposits = cashFlowDeposits + _flowOut;
54296
+ const newCollat = deposits + amountOutUSD;
54297
+ const newDebt = debt + amountInUSD;
54298
+ return [
54299
+ totalCashFlowDebt / newDebt,
54300
+ totalCashFlowDeposits / newCollat,
54301
+ (totalCashFlowDeposits - totalCashFlowDebt) / (newCollat - newDebt)
54302
+ ];
54303
+ }
54304
+ function getIntrinsicYieldClose(amountInUSD, amountOutUSD, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
54305
+ const _flowIn = amountInUSD * yieldIn.intrinsicYield;
54306
+ const _flowOut = amountOutUSD * yieldOut.intrinsicYield;
54307
+ const totalCashFlowDebt = cashFlowDebt - _flowOut;
54308
+ const totalCashFlowDeposits = cashFlowDeposits - _flowIn;
54309
+ const newCollat = deposits - amountInUSD;
54310
+ const newDebt = debt - amountOutUSD;
54311
+ return [
54312
+ Math.abs(newDebt) < 0.01 ? 0 : totalCashFlowDebt / newDebt,
54313
+ totalCashFlowDeposits / newCollat,
54314
+ (totalCashFlowDeposits - totalCashFlowDebt) / (newCollat - newDebt)
54315
+ ];
54316
+ }
54317
+ function getIntrinsicYieldDebtSwap(amountInUSD, amountOutUSD, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
54318
+ const _flowIn = amountInUSD * yieldIn.intrinsicYield;
54319
+ const _flowOut = amountOutUSD * yieldOut.intrinsicYield;
54320
+ const totalCashFlowDebt = cashFlowDebt + _flowIn - _flowOut;
54321
+ const newDebt = debt - amountOutUSD + amountInUSD;
54322
+ return [
54323
+ Math.abs(newDebt) < 0.01 ? 0 : totalCashFlowDebt / newDebt,
54324
+ cashFlowDeposits / deposits,
54325
+ (cashFlowDeposits - totalCashFlowDebt) / (deposits - newDebt)
54326
+ ];
54327
+ }
54328
+ function getIntrinsicYieldCollateralSwap(amountInUSD, amountOutUSD, cashFlowDeposits, cashFlowDebt, deposits, debt, yieldIn, yieldOut) {
54329
+ const _flowIn = amountInUSD * yieldIn.intrinsicYield;
54330
+ const _flowOut = amountOutUSD * yieldOut.intrinsicYield;
54331
+ const totalCashFlowDeposits = cashFlowDeposits + _flowOut - _flowIn;
54332
+ const newCollat = deposits + amountOutUSD - amountInUSD;
54333
+ return [
54334
+ Math.abs(debt) < 0.01 ? 0 : cashFlowDebt / debt,
54335
+ totalCashFlowDeposits / newCollat,
54336
+ (totalCashFlowDeposits - cashFlowDebt) / (newCollat - debt)
54337
+ ];
54338
+ }
54339
+
54340
+ // src/lending/margin/loop/compute/computeCloseDeltas.ts
54341
+ function computeCloseTradeDeltas(dollarIn, dollarOut, targetMode, yieldParamsIn, yieldParamsOut, balance, apr, bfOut, ltvIn, collateralLtvIn) {
54342
+ if (dollarIn === 0 || dollarOut === 0) return noOpResult(balance, apr);
54343
+ const cashFlowDeposits = balance.deposits * apr.depositApr;
54344
+ const cashFlowDebt = balance.debt * apr.borrowApr;
54345
+ const rewardFlowDeposits = balance.deposits * (apr.rewardDepositApr ?? 0);
54346
+ const rewardFlowDebt = balance.debt * (apr.rewardBorrowApr ?? 0);
54347
+ const intrinsicFlowDeposits = balance.deposits * apr.intrinsicDepositApr;
54348
+ const intrinsicFlowDebt = balance.debt * apr.intrinsicBorrowApr;
54349
+ const newBalance = { ...balance };
54350
+ const newApr = { ...apr };
54351
+ newBalance.debt = positivePart2(newBalance.debt - dollarOut);
54352
+ newBalance.borrowDiscountedCollateral = positivePart2(
54353
+ newBalance.borrowDiscountedCollateral - ltvIn * dollarIn
54354
+ );
54355
+ newBalance.collateral = positivePart2(
54356
+ newBalance.collateral - collateralLtvIn * dollarIn
54357
+ );
54358
+ newBalance.deposits = positivePart2(newBalance.deposits - dollarIn);
54359
+ newBalance.adjustedDebt = positivePart2(
54360
+ newBalance.adjustedDebt - bfOut * dollarOut
54361
+ );
54362
+ newBalance.nav += dollarOut - dollarIn;
54363
+ [newApr.borrowApr, newApr.depositApr, newApr.apr] = getOrganicYieldClose(
54364
+ dollarIn,
54365
+ dollarOut,
54366
+ targetMode,
54367
+ cashFlowDeposits,
54368
+ cashFlowDebt,
54369
+ balance.deposits,
54370
+ balance.debt,
54371
+ yieldParamsIn,
54372
+ yieldParamsOut
54373
+ );
54374
+ newApr.rewards = getRewardYieldClose(
54375
+ dollarIn,
54376
+ dollarOut,
54377
+ targetMode,
54378
+ rewardFlowDeposits,
54379
+ rewardFlowDebt,
54380
+ balance.deposits,
54381
+ balance.debt,
54382
+ yieldParamsIn,
54383
+ yieldParamsOut
54384
+ );
54385
+ [newApr.intrinsicBorrowApr, newApr.intrinsicDepositApr, newApr.intrinsicApr] = getIntrinsicYieldClose(
54386
+ dollarIn,
54387
+ dollarOut,
54388
+ intrinsicFlowDeposits,
54389
+ intrinsicFlowDebt,
54390
+ balance.deposits,
54391
+ balance.debt,
54392
+ yieldParamsIn,
54393
+ yieldParamsOut
54394
+ );
54395
+ return buildLoopResult(balance, newBalance, apr, newApr);
54396
+ }
54397
+
54398
+ // src/lending/margin/loop/compute/computeCollateralSwapDeltas.ts
54399
+ function computeCollateralSwapDeltas(dollarIn, dollarOut, yieldParamsIn, yieldParamsOut, balance, apr, ltvIn, collateralLtvIn, ltvOut, collateralLtvOut) {
54400
+ if (dollarIn === 0 || dollarOut === 0) return noOpResult(balance, apr);
54401
+ const cashFlowDeposits = balance.deposits * apr.depositApr;
54402
+ const cashFlowDebt = balance.debt * apr.borrowApr;
54403
+ const rewardFlowDeposits = balance.deposits * (apr.rewardDepositApr ?? 0);
54404
+ const rewardFlowDebt = balance.debt * (apr.rewardBorrowApr ?? 0);
54405
+ const intrinsicFlowDeposits = balance.deposits * apr.intrinsicDepositApr;
54406
+ const intrinsicFlowDebt = balance.debt * apr.intrinsicBorrowApr;
54407
+ const newBalance = { ...balance };
54408
+ const newApr = { ...apr };
54409
+ newBalance.borrowDiscountedCollateral += ltvOut * dollarOut - ltvIn * dollarIn;
54410
+ newBalance.deposits += dollarOut - dollarIn;
54411
+ newBalance.collateral += collateralLtvOut * dollarOut - collateralLtvIn * dollarIn;
54412
+ newBalance.nav += dollarOut - dollarIn;
54413
+ [newApr.borrowApr, newApr.depositApr, newApr.apr] = getOrganicYieldCollateralSwap(
54414
+ dollarIn,
54415
+ dollarOut,
54416
+ cashFlowDeposits,
54417
+ cashFlowDebt,
54418
+ balance.deposits,
54419
+ balance.debt,
54420
+ yieldParamsIn,
54421
+ yieldParamsOut
54422
+ );
54423
+ newApr.rewards = getRewardYieldCollateralSwap(
54424
+ dollarIn,
54425
+ dollarOut,
54426
+ rewardFlowDeposits,
54427
+ rewardFlowDebt,
54428
+ balance.deposits,
54429
+ balance.debt,
54430
+ yieldParamsIn,
54431
+ yieldParamsOut
54432
+ );
54433
+ [newApr.intrinsicBorrowApr, newApr.intrinsicDepositApr, newApr.intrinsicApr] = getIntrinsicYieldCollateralSwap(
54434
+ dollarIn,
54435
+ dollarOut,
54436
+ intrinsicFlowDeposits,
54437
+ intrinsicFlowDebt,
54438
+ balance.deposits,
54439
+ balance.debt,
54440
+ yieldParamsIn,
54441
+ yieldParamsOut
54442
+ );
54443
+ return buildLoopResult(balance, newBalance, apr, newApr);
54444
+ }
54445
+
54446
+ // src/lending/margin/loop/compute/computeDebtSwapDeltas.ts
54447
+ function computeDebtSwapDeltas(dollarIn, dollarOut, sourceMode, targetMode, yieldParamsIn, yieldParamsOut, balance, apr, bfInFactor, bfOutFactor) {
54448
+ if (dollarIn === 0 || dollarOut === 0) return noOpResult(balance, apr);
54449
+ const cashFlowDeposits = balance.deposits * apr.depositApr;
54450
+ const cashFlowDebt = balance.debt * apr.borrowApr;
54451
+ const rewardFlowDeposits = balance.deposits * (apr.rewardDepositApr ?? 0);
54452
+ const rewardFlowDebt = balance.debt * apr.rewardBorrowApr;
54453
+ const intrinsicFlowDeposits = balance.deposits * apr.intrinsicDepositApr;
54454
+ const intrinsicFlowDebt = balance.debt * apr.intrinsicBorrowApr;
54455
+ const newBalance = { ...balance };
54456
+ const newApr = { ...apr };
54457
+ newBalance.debt += dollarOut - dollarIn;
54458
+ newBalance.adjustedDebt += bfOutFactor * dollarOut - bfInFactor * dollarIn;
54459
+ newBalance.nav += dollarOut - dollarIn;
54460
+ [newApr.borrowApr, newApr.depositApr, newApr.apr] = getOrganicYieldDebtSwap(
54461
+ dollarIn,
54462
+ dollarOut,
54463
+ sourceMode,
54464
+ targetMode,
54465
+ cashFlowDeposits,
54466
+ cashFlowDebt,
54467
+ balance.deposits,
54468
+ balance.debt,
54469
+ yieldParamsIn,
54470
+ yieldParamsOut
54471
+ );
54472
+ newApr.rewards = getRewardYieldDebtSwap(
54473
+ dollarIn,
54474
+ dollarOut,
54475
+ sourceMode,
54476
+ targetMode,
54477
+ rewardFlowDeposits,
54478
+ rewardFlowDebt,
54479
+ balance.deposits,
54480
+ balance.debt,
54481
+ yieldParamsIn,
54482
+ yieldParamsOut
54483
+ );
54484
+ [newApr.intrinsicBorrowApr, newApr.intrinsicDepositApr, newApr.intrinsicApr] = getIntrinsicYieldDebtSwap(
54485
+ dollarIn,
54486
+ dollarOut,
54487
+ intrinsicFlowDeposits,
54488
+ intrinsicFlowDebt,
54489
+ balance.deposits,
54490
+ balance.debt,
54491
+ yieldParamsIn,
54492
+ yieldParamsOut
54493
+ );
54494
+ return buildLoopResult(balance, newBalance, apr, newApr);
54495
+ }
54496
+
54497
+ // src/lending/margin/loop/compute/computeOpenDeltas.ts
54498
+ function computeOpenTradeDeltas(dollarIn, dollarOut, sourceMode, yieldParamsIn, yieldParamsOut, balance, apr, bfIn, collateralLtvOut, borrowLtvOut, useAllActive = false) {
54499
+ if (dollarIn === 0 || dollarOut === 0) return noOpResult(balance, apr);
54500
+ const cashFlowDeposits = balance.deposits * apr.depositApr;
54501
+ const cashFlowDebt = balance.debt * apr.borrowApr;
54502
+ const rewardFlowDeposits = balance.deposits * (apr.rewardDepositApr ?? 0);
54503
+ const rewardFlowDebt = balance.debt * (apr.rewardBorrowApr ?? 0);
54504
+ const intrinsicFlowDeposits = balance.deposits * apr.intrinsicDepositApr;
54505
+ const intrinsicFlowDebt = balance.debt * apr.intrinsicBorrowApr;
54506
+ const newBalance = { ...balance };
54507
+ const newApr = { ...apr };
54508
+ newBalance.debt += dollarIn;
54509
+ newBalance.borrowDiscountedCollateral += borrowLtvOut * dollarOut;
54510
+ newBalance.borrowDiscountedCollateralAllActive += borrowLtvOut * dollarOut;
54511
+ newBalance.collateral += collateralLtvOut * dollarOut;
54512
+ newBalance.collateralAllActive += collateralLtvOut * dollarOut;
54513
+ newBalance.deposits += dollarOut;
54514
+ newBalance.adjustedDebt += bfIn * dollarIn;
54515
+ newBalance.nav += dollarOut - dollarIn;
54516
+ [newApr.borrowApr, newApr.depositApr, newApr.apr] = getOrganicYieldOpen(
54517
+ dollarIn,
54518
+ dollarOut,
54519
+ sourceMode,
54520
+ cashFlowDeposits,
54521
+ cashFlowDebt,
54522
+ balance.deposits,
54523
+ balance.debt,
54524
+ yieldParamsIn,
54525
+ yieldParamsOut
54526
+ );
54527
+ newApr.rewards = getRewardYieldOpen(
54528
+ dollarIn,
54529
+ dollarOut,
54530
+ sourceMode,
54531
+ rewardFlowDeposits,
54532
+ rewardFlowDebt,
54533
+ balance.deposits,
54534
+ balance.debt,
54535
+ yieldParamsIn,
54536
+ yieldParamsOut
54537
+ );
54538
+ [newApr.intrinsicBorrowApr, newApr.intrinsicDepositApr, newApr.intrinsicApr] = getIntrinsicYieldOpen(
54539
+ dollarIn,
54540
+ dollarOut,
54541
+ intrinsicFlowDeposits,
54542
+ intrinsicFlowDebt,
54543
+ balance.deposits,
54544
+ balance.debt,
54545
+ yieldParamsIn,
54546
+ yieldParamsOut
54547
+ );
54548
+ return buildLoopResult(balance, newBalance, apr, newApr, useAllActive);
54549
+ }
54550
+
54551
+ // src/lending/margin/loop/compute/computeZapDeltas.ts
54552
+ function computeZapTradeDeltas(dollarIn, dollarOut, sourceMode, yieldParamsIn, yieldParamsOut, balance, apr, bfIn, collateralLtvOut, borrowLtvOut) {
54553
+ if (dollarIn === 0 || dollarOut === 0) return noOpResult(balance, apr);
54554
+ const cashFlowDeposits = balance.deposits * apr.depositApr;
54555
+ const cashFlowDebt = balance.debt * apr.borrowApr;
54556
+ const rewardFlowDeposits = balance.deposits * (apr.rewardDepositApr ?? 0);
54557
+ const rewardFlowDebt = balance.debt * (apr.rewardBorrowApr ?? 0);
54558
+ const intrinsicFlowDeposits = balance.deposits * apr.intrinsicDepositApr;
54559
+ const intrinsicFlowDebt = balance.debt * apr.intrinsicBorrowApr;
54560
+ const newBalance = { ...balance };
54561
+ const newApr = { ...apr };
54562
+ newBalance.debt += dollarIn;
54563
+ newBalance.borrowDiscountedCollateral += borrowLtvOut * dollarOut;
54564
+ newBalance.collateral += collateralLtvOut * dollarOut;
54565
+ newBalance.deposits += dollarOut;
54566
+ newBalance.adjustedDebt += bfIn * dollarIn;
54567
+ newBalance.nav += dollarOut - dollarIn;
54568
+ [newApr.borrowApr, newApr.depositApr, newApr.apr] = getOrganicYieldOpen(
54569
+ dollarIn,
54570
+ dollarOut,
54571
+ sourceMode,
54572
+ cashFlowDeposits,
54573
+ cashFlowDebt,
54574
+ balance.deposits,
54575
+ balance.debt,
54576
+ yieldParamsIn,
54577
+ yieldParamsOut
54578
+ );
54579
+ newApr.rewards = getRewardYieldOpen(
54580
+ dollarIn,
54581
+ dollarOut,
54582
+ sourceMode,
54583
+ rewardFlowDeposits,
54584
+ rewardFlowDebt,
54585
+ balance.deposits,
54586
+ balance.debt,
54587
+ yieldParamsIn,
54588
+ yieldParamsOut
54589
+ );
54590
+ [newApr.intrinsicBorrowApr, newApr.intrinsicDepositApr, newApr.intrinsicApr] = getIntrinsicYieldOpen(
54591
+ dollarIn,
54592
+ dollarOut,
54593
+ intrinsicFlowDeposits,
54594
+ intrinsicFlowDebt,
54595
+ balance.deposits,
54596
+ balance.debt,
54597
+ yieldParamsIn,
54598
+ yieldParamsOut
54599
+ );
54600
+ return buildLoopResult(balance, newBalance, apr, newApr);
54601
+ }
54602
+
54603
+ // src/lending/margin/loop/ranges/getMaxAmountOpen.ts
54604
+ var MaxParamThresholds = /* @__PURE__ */ ((MaxParamThresholds2) => {
54605
+ MaxParamThresholds2[MaxParamThresholds2["MIN_HF"] = 1] = "MIN_HF";
54606
+ MaxParamThresholds2[MaxParamThresholds2["SAME_OPEN_HF"] = 1.1] = "SAME_OPEN_HF";
54607
+ MaxParamThresholds2[MaxParamThresholds2["SAFE_HF"] = 1.01] = "SAFE_HF";
54608
+ return MaxParamThresholds2;
54609
+ })(MaxParamThresholds || {});
54610
+ function getMaxAmountOpen(borrowDiscountedCollateral, collateral, debt, cfOut, bfIn, sameAsset = false) {
54611
+ if (sameAsset) {
54612
+ return (collateral - 1.1 /* SAME_OPEN_HF */ * debt) / (1.1 /* SAME_OPEN_HF */ * bfIn - cfOut);
53545
54613
  }
53546
- for (const [chainId, entries] of Object.entries(VENUS_HUB_ENTRIES)) {
53547
- if (!out[chainId]) out[chainId] = [];
53548
- out[chainId].push(...entries);
54614
+ return (borrowDiscountedCollateral - 1.01 /* SAFE_HF */ * debt) / (1.01 /* SAFE_HF */ * bfIn - cfOut);
54615
+ }
54616
+
54617
+ // src/lending/margin/loop/ranges/getMaxAmountCollateralSwap.ts
54618
+ function getMaxAmountCollateralSwap(borrowDiscountedCollateral, adjustedDebt, ltvIn, ltvOut) {
54619
+ if (ltvOut >= ltvIn) return Infinity;
54620
+ const denominator = ltvIn - ltvOut;
54621
+ return (borrowDiscountedCollateral - 1.01 /* SAFE_HF */ * adjustedDebt) / denominator;
54622
+ }
54623
+
54624
+ // src/lending/margin/loop/ranges/getMaxAmountDebtSwap.ts
54625
+ function getMaxAmountDebtSwap(borrowDiscountedCollateral, adjustedDebt, bfIn, bfOut) {
54626
+ if (bfOut <= bfIn) return Infinity;
54627
+ const denominator = 1.01 /* SAFE_HF */ * (bfOut - bfIn);
54628
+ return (borrowDiscountedCollateral - 1.01 /* SAFE_HF */ * adjustedDebt) / denominator;
54629
+ }
54630
+
54631
+ // src/lending/margin/loop/ranges/getMaxAmountClose.ts
54632
+ function getMaxAmountClose(borrowDiscountedCollateral, adjustedDebt, ltvIn, bfOut) {
54633
+ const denominator = ltvIn - 1.01 /* SAFE_HF */ * bfOut;
54634
+ if (denominator <= 0) return Infinity;
54635
+ return (borrowDiscountedCollateral - 1.01 /* SAFE_HF */ * adjustedDebt) / denominator;
54636
+ }
54637
+ function averageDataLastN(arr, n = 7) {
54638
+ const last = arr.slice(-n);
54639
+ if (last.length === 0) return 0;
54640
+ return last.reduce((sum3, x) => sum3 + x.data, 0) / last.length;
54641
+ }
54642
+ var safeFetch = async (label, fn) => {
54643
+ try {
54644
+ return await fn();
54645
+ } catch (e) {
54646
+ console.error(`Error fetching ${label}:`, e);
54647
+ return void 0;
53549
54648
  }
53550
- return out;
53551
- })();
53552
- var savingsBalanceKind = (chainId, address) => {
53553
- const lc = address.toLowerCase();
53554
- return (SAVINGS_REGISTRY[chainId] ?? []).find((e) => e.address === lc)?.balanceKind;
53555
- };
53556
- var isSecondaryMarketOnly = (chainId, address) => (SAVINGS_REGISTRY[chainId] ?? []).some(
53557
- (e) => e.address === address.toLowerCase() && e.secondaryMarketOnly === true
53558
- );
53559
- var secondaryMarketVault = (chainId, address) => {
53560
- const e = (SAVINGS_REGISTRY[chainId] ?? []).find(
53561
- (x) => x.address === address.toLowerCase() && x.secondaryMarketOnly === true
53562
- );
53563
- return e ? { underlying: e.underlying, symbol: e.symbol } : void 0;
53564
54649
  };
53565
- var savingsAddresses = (chainId) => (SAVINGS_REGISTRY[chainId] ?? []).map((e) => e.address);
53566
- var getSavingsRegistry = (chainId) => SAVINGS_REGISTRY[chainId] ?? [];
54650
+ async function getListsMulti(chainIds) {
54651
+ const lists = await fetchTokenLists(chainIds);
54652
+ let res = {};
54653
+ for (const chainId of chainIds) {
54654
+ res[chainId] = { list: lists[chainId] };
54655
+ }
54656
+ return res;
54657
+ }
53567
54658
 
53568
54659
  // src/yields/intrinsic/fetchers/morphoVaults.ts
53569
54660
  var MORPHO_VAULTS_URL = "https://blue-api.morpho.org/graphql";
@@ -53810,6 +54901,78 @@ var gmxFetcher = {
53810
54901
  var PENDLE_API_BASE = "https://api-v2.pendle.finance/core";
53811
54902
  var MARKETS_ENDPOINT = `${PENDLE_API_BASE}/v1/markets/all`;
53812
54903
  var PRICES_ENDPOINT = (types) => `${PENDLE_API_BASE}/v1/prices/assets${types ? `?type=${types.join(",")}` : ""}`;
54904
+ async function fetchPendleChainIds() {
54905
+ try {
54906
+ const response = await fetch(`${PENDLE_API_BASE}/v1/assets/all`);
54907
+ if (!response.ok)
54908
+ throw new Error(`Failed to fetch assets: ${response.status}`);
54909
+ const data = await response.json();
54910
+ const ids = /* @__PURE__ */ new Set();
54911
+ for (const a of data.assets ?? []) {
54912
+ if (Number.isFinite(a?.chainId)) ids.add(String(a.chainId));
54913
+ }
54914
+ return [...ids];
54915
+ } catch (error) {
54916
+ console.error("Error fetching pendle asset chains:", error);
54917
+ return [];
54918
+ }
54919
+ }
54920
+ var ORIGIN_CHAIN_BY_CODE = {
54921
+ ETH: "1",
54922
+ ARB: "42161",
54923
+ PLASMA: "9745"
54924
+ };
54925
+ var ORIGIN_SUFFIX = /-\(([A-Z0-9]+)\)$/;
54926
+ function applyBridgedPendleYields(yields, lists, now = /* @__PURE__ */ new Date()) {
54927
+ const out = { ...yields };
54928
+ for (const [chainId, { list }] of Object.entries(lists)) {
54929
+ for (const [address, entry] of Object.entries(list ?? {})) {
54930
+ const pendle = entry?.props?.pendle;
54931
+ if (!pendle?.bridgedFrom || pendle.tokenType !== "PT") continue;
54932
+ const assetKey2 = entry.assetGroup;
54933
+ if (!assetKey2 || assetKey2 in out) continue;
54934
+ if (pendle.expiry !== void 0 && pendle.expiry * 1e3 <= now.getTime()) {
54935
+ out[assetKey2] = 0;
54936
+ continue;
54937
+ }
54938
+ const originKey = resolveOriginAssetGroup(lists, entry, chainId, address);
54939
+ if (!originKey) continue;
54940
+ const originYield = yields[originKey];
54941
+ if (originYield === void 0) continue;
54942
+ out[assetKey2] = originYield;
54943
+ }
54944
+ }
54945
+ return out;
54946
+ }
54947
+ function resolveOriginAssetGroup(lists, entry, chainId, address) {
54948
+ const pendle = entry.props?.pendle;
54949
+ const origin = pendle.origin;
54950
+ if (origin) {
54951
+ const originEntry = lists[origin.chainId]?.list?.[origin.address.toLowerCase()];
54952
+ if (originEntry?.assetGroup) return originEntry.assetGroup;
54953
+ }
54954
+ const originChain = ORIGIN_CHAIN_BY_CODE[pendle.bridgedFrom];
54955
+ const stripped = entry.symbol?.replace(ORIGIN_SUFFIX, "");
54956
+ if (!originChain || !stripped || stripped === entry.symbol) return void 0;
54957
+ const candidates = [];
54958
+ for (const candidate of Object.values(lists[originChain]?.list ?? {})) {
54959
+ const cp = candidate?.props?.pendle;
54960
+ if (cp?.tokenType !== "PT" || cp.bridgedFrom || candidate.symbol !== stripped)
54961
+ continue;
54962
+ if (pendle.expiry !== void 0 && cp.expiry !== void 0 && cp.expiry !== pendle.expiry)
54963
+ continue;
54964
+ if (candidate.assetGroup) candidates.push(candidate.assetGroup);
54965
+ }
54966
+ if (candidates.length !== 1) {
54967
+ if (candidates.length > 1) {
54968
+ console.warn(
54969
+ `pendle: bridged PT ${chainId}:${address} (${entry.symbol}) matches ${candidates.length} origin PTs \u2014 not joined`
54970
+ );
54971
+ }
54972
+ return void 0;
54973
+ }
54974
+ return candidates[0];
54975
+ }
53813
54976
  async function fetchPendleMarkets() {
53814
54977
  try {
53815
54978
  const response = await fetch(MARKETS_ENDPOINT);
@@ -53901,7 +55064,7 @@ async function fetchPendleYields(lists = {}) {
53901
55064
  }
53902
55065
  });
53903
55066
  });
53904
- return yields;
55067
+ return applyBridgedPendleYields(yields, lists, now);
53905
55068
  } catch (error) {
53906
55069
  console.error("Error in fetchPendlePrices:", error);
53907
55070
  return {};
@@ -53915,21 +55078,48 @@ function yearFractionToExpiry(expiryISO, now = /* @__PURE__ */ new Date()) {
53915
55078
  }
53916
55079
 
53917
55080
  // src/yields/intrinsic/fetchers/pendle.ts
55081
+ var FALLBACK_CHAINS = [
55082
+ Chain.ETHEREUM_MAINNET,
55083
+ Chain.ARBITRUM_ONE,
55084
+ Chain.OP_MAINNET,
55085
+ Chain.BNB_SMART_CHAIN_MAINNET,
55086
+ Chain.MANTLE,
55087
+ Chain.BASE,
55088
+ Chain.SONIC_MAINNET,
55089
+ Chain.BERACHAIN,
55090
+ Chain.HYPEREVM,
55091
+ Chain.MONAD_MAINNET,
55092
+ Chain.PLASMA_MAINNET,
55093
+ Chain.UNICHAIN,
55094
+ Chain.INK,
55095
+ Chain.KATANA,
55096
+ Chain.X_LAYER_MAINNET,
55097
+ Chain.ROBINHOOD_CHAIN
55098
+ ];
55099
+ async function loadPendleLists() {
55100
+ const known = new Set(Object.values(Chain));
55101
+ const live = (await fetchPendleChainIds()).filter((c) => known.has(c));
55102
+ const chainIds = live.length ? live : FALLBACK_CHAINS;
55103
+ const settled = await Promise.allSettled(
55104
+ chainIds.map(
55105
+ async (chainId) => [chainId, await fetchTokenList(chainId)]
55106
+ )
55107
+ );
55108
+ const lists = {};
55109
+ settled.forEach((r, i) => {
55110
+ if (r.status === "fulfilled") lists[r.value[0]] = { list: r.value[1] };
55111
+ else
55112
+ console.warn(
55113
+ `[PENDLE] token list for chain ${chainIds[i]} unavailable \u2014 skipped`,
55114
+ r.reason
55115
+ );
55116
+ });
55117
+ return lists;
55118
+ }
53918
55119
  var pendleFetcher = {
53919
55120
  label: "PENDLE",
53920
55121
  fetch: async () => {
53921
- const lists = await getListsMulti([
53922
- Chain.PLASMA_MAINNET,
53923
- Chain.ETHEREUM_MAINNET,
53924
- Chain.BERACHAIN,
53925
- Chain.MANTLE,
53926
- Chain.BASE,
53927
- Chain.OP_MAINNET,
53928
- Chain.ARBITRUM_ONE,
53929
- Chain.SONIC_MAINNET,
53930
- Chain.HYPEREVM,
53931
- Chain.BNB_SMART_CHAIN_MAINNET
53932
- ]);
55122
+ const lists = await loadPendleLists();
53933
55123
  return fetchPendleYields(lists);
53934
55124
  }
53935
55125
  };
@@ -57704,9 +58894,9 @@ var SiloOracleAbi = [
57704
58894
  ];
57705
58895
  var ZERO_ADDRESS9 = "0x0000000000000000000000000000000000000000";
57706
58896
  function lookupUSD(context, asset) {
57707
- const lc = asset.toLowerCase();
57708
- const groupKey = context.tokenList?.[lc]?.assetGroup ?? `${context.chainId}-${lc}`;
57709
- return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
58897
+ const lc2 = asset.toLowerCase();
58898
+ const groupKey = context.tokenList?.[lc2]?.assetGroup ?? `${context.chainId}-${lc2}`;
58899
+ return context.usdPrices[groupKey] ?? context.usdPrices[lc2] ?? 0;
57710
58900
  }
57711
58901
  function getSiloV2Calls(chainId) {
57712
58902
  const allMarkets = siloMarkets()?.[chainId];
@@ -57873,9 +59063,9 @@ var SiloOracleAbi2 = [
57873
59063
  ];
57874
59064
  var ZERO_ADDRESS10 = "0x0000000000000000000000000000000000000000";
57875
59065
  function lookupUSD2(context, asset) {
57876
- const lc = asset.toLowerCase();
57877
- const groupKey = context.tokenList?.[lc]?.assetGroup ?? `${context.chainId}-${lc}`;
57878
- return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
59066
+ const lc2 = asset.toLowerCase();
59067
+ const groupKey = context.tokenList?.[lc2]?.assetGroup ?? `${context.chainId}-${lc2}`;
59068
+ return context.usdPrices[groupKey] ?? context.usdPrices[lc2] ?? 0;
57879
59069
  }
57880
59070
  function getSiloV3Calls(chainId) {
57881
59071
  const allMarkets = siloMarketsV3()?.[chainId];
@@ -58291,9 +59481,9 @@ function safeNumber3(v) {
58291
59481
  return Number.isFinite(n) ? n : 0;
58292
59482
  }
58293
59483
  function lookupUSD3(context, asset) {
58294
- const lc = asset.toLowerCase();
58295
- const groupKey = context.tokenList?.[lc]?.assetGroup ?? `${context.chainId}-${lc}`;
58296
- return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
59484
+ const lc2 = asset.toLowerCase();
59485
+ const groupKey = context.tokenList?.[lc2]?.assetGroup ?? `${context.chainId}-${lc2}`;
59486
+ return context.usdPrices[groupKey] ?? context.usdPrices[lc2] ?? 0;
58297
59487
  }
58298
59488
  function parseSiloV2GraphQLResults(items, context) {
58299
59489
  const ZERO_ADDRESS12 = "0x0000000000000000000000000000000000000000";
@@ -58434,9 +59624,9 @@ function safeNumber4(v) {
58434
59624
  return Number.isFinite(n) ? n : 0;
58435
59625
  }
58436
59626
  function lookupUSD4(context, asset) {
58437
- const lc = asset.toLowerCase();
58438
- const groupKey = context.tokenList?.[lc]?.assetGroup ?? `${context.chainId}-${lc}`;
58439
- return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
59627
+ const lc2 = asset.toLowerCase();
59628
+ const groupKey = context.tokenList?.[lc2]?.assetGroup ?? `${context.chainId}-${lc2}`;
59629
+ return context.usdPrices[groupKey] ?? context.usdPrices[lc2] ?? 0;
58440
59630
  }
58441
59631
  function parseSiloV3GraphQLResults(items, context) {
58442
59632
  const ZERO_ADDRESS12 = "0x0000000000000000000000000000000000000000";
@@ -60318,7 +61508,6 @@ var FlashAbi = [
60318
61508
  ];
60319
61509
  var DEFAULT_BATCH_SIZE = 4096;
60320
61510
  var isValidResult = (v) => typeof v === "bigint";
60321
- var NATIVE_DECIMALS = 18;
60322
61511
  function parseDecimalsResult(v) {
60323
61512
  const n = typeof v === "bigint" ? Number(v) : v;
60324
61513
  if (typeof n !== "number" || !Number.isInteger(n) || n < 0 || n > 36) {
@@ -60392,7 +61581,7 @@ async function fetchFlashLiquidityForChain(chain, multicallRetry, list = {}) {
60392
61581
  const uniswapV4s = RELEVANT_UNISWAP_V4_FORKS[chain] ?? [];
60393
61582
  const uniswapV4Calls = buildBalanceCalls(uniswapV4s);
60394
61583
  const decimalsByAsset = {
60395
- [zeroAddress]: NATIVE_DECIMALS
61584
+ [zeroAddress]: getNativeDecimals(chain)
60396
61585
  };
60397
61586
  for (const asset of unifiedAssets) {
60398
61587
  const fromList = list[asset]?.decimals;
@@ -73873,11 +75062,11 @@ var ConvertToAssetsAbi = [
73873
75062
  }
73874
75063
  ];
73875
75064
  var readVaultSharePrices = async (chainId, addresses, multicallRetry) => {
73876
- const lc = Array.from(new Set(addresses.map((a) => a.toLowerCase())));
73877
- if (lc.length === 0) return {};
75065
+ const lc2 = Array.from(new Set(addresses.map((a) => a.toLowerCase())));
75066
+ if (lc2.length === 0) return {};
73878
75067
  const results = await multicallRetry({
73879
75068
  chain: chainId,
73880
- calls: lc.map((address) => ({
75069
+ calls: lc2.map((address) => ({
73881
75070
  address,
73882
75071
  name: "convertToAssets",
73883
75072
  params: [VAULT_SHARE_PRICE_PROBE]
@@ -73887,9 +75076,9 @@ var readVaultSharePrices = async (chainId, addresses, multicallRetry) => {
73887
75076
  allowFailure: true
73888
75077
  });
73889
75078
  const out = {};
73890
- for (let i = 0; i < lc.length; i++) {
75079
+ for (let i = 0; i < lc2.length; i++) {
73891
75080
  const v = results[i];
73892
- if (typeof v === "bigint" && v > 0n) out[lc[i]] = v.toString();
75081
+ if (typeof v === "bigint" && v > 0n) out[lc2[i]] = v.toString();
73893
75082
  }
73894
75083
  return out;
73895
75084
  };
@@ -74067,6 +75256,15 @@ function counterpartyTags(c) {
74067
75256
  if (c.socializedLoss) push(out, "socialized-loss");
74068
75257
  return [...out];
74069
75258
  }
75259
+ function assetTags(sheet) {
75260
+ const out = /* @__PURE__ */ new Set();
75261
+ const inst = sheet.asset?.instrument;
75262
+ if (inst) {
75263
+ push(out, "asset-matures");
75264
+ if (!inst.redemption.local) push(out, "asset-bridged");
75265
+ }
75266
+ return [...out];
75267
+ }
74070
75268
  function deriveSupplyTags(supply, market = {}) {
74071
75269
  const out = /* @__PURE__ */ new Set();
74072
75270
  push(out, ...rateTags(supply.rate));
@@ -74074,6 +75272,7 @@ function deriveSupplyTags(supply, market = {}) {
74074
75272
  push(out, ...availabilityTags(supply.availability));
74075
75273
  push(out, ...counterpartyTags(supply.counterparty));
74076
75274
  push(out, ...marketTags(market));
75275
+ push(out, ...assetTags(market));
74077
75276
  switch (supply.exit.mode) {
74078
75277
  case "instant":
74079
75278
  push(out, "exit-instant");
@@ -74207,6 +75406,57 @@ function hasMatured(m, nowSecs) {
74207
75406
  if (m.kind !== "fixed-date" || !m.maturity) return false;
74208
75407
  return m.maturity <= (Math.floor(Date.now() / 1e3));
74209
75408
  }
75409
+ var CHAIN_LABEL = {
75410
+ "1": "Ethereum",
75411
+ "10": "Optimism",
75412
+ "56": "BNB Chain",
75413
+ "130": "Unichain",
75414
+ "143": "Monad",
75415
+ "146": "Sonic",
75416
+ "196": "X Layer",
75417
+ "999": "HyperEVM",
75418
+ "4663": "Robinhood Chain",
75419
+ "5000": "Mantle",
75420
+ "8453": "Base",
75421
+ "9745": "Plasma",
75422
+ "42161": "Arbitrum",
75423
+ "57073": "Ink",
75424
+ "80094": "Berachain",
75425
+ "747474": "Katana"
75426
+ };
75427
+ function chainLabel(chainId) {
75428
+ if (!chainId) return "its origin chain";
75429
+ return CHAIN_LABEL[chainId] ?? `chain ${chainId}`;
75430
+ }
75431
+ var VENUE_LABEL = {
75432
+ pendle: "Pendle",
75433
+ spectra: "Spectra"
75434
+ };
75435
+ function instrumentPhrase(inst) {
75436
+ const when = `${inst.matured ? "matured" : "matures"} ${shortDate(inst.maturity)}`;
75437
+ const where = inst.redemption.local ? "" : ` \xB7 redeem on ${chainLabel(inst.redemption.chainId)} only`;
75438
+ return `PT ${when}${where}`;
75439
+ }
75440
+ function instrumentSentences(inst) {
75441
+ const venue = VENUE_LABEL[String(inst.venue)] ?? String(inst.venue);
75442
+ const origin = chainLabel(inst.redemption.chainId);
75443
+ const out = [];
75444
+ if (inst.matured) {
75445
+ out.push(
75446
+ `This ${venue} principal token matured on ${shortDate(inst.maturity)} and earns nothing further; it is redeemable 1:1 for its underlying.`
75447
+ );
75448
+ } else {
75449
+ out.push(
75450
+ `The asset is a ${venue} principal token maturing ${shortDate(inst.maturity)} (in ${duration(inst.secondsToMaturity)}): it accrues to par and is redeemable 1:1 for its underlying from then on.`
75451
+ );
75452
+ }
75453
+ if (!inst.redemption.local) {
75454
+ out.push(
75455
+ `It is a bridged mirror and cannot be minted or redeemed on this chain \u2014 sell it here, or bridge it back to ${origin} to redeem at par.`
75456
+ );
75457
+ }
75458
+ return out;
75459
+ }
74210
75460
  function maturityPhrase(m) {
74211
75461
  if (m.kind === "fixed-date" && m.maturity)
74212
75462
  return `${hasMatured(m) ? "matured" : "until"} ${shortDate(m.maturity)}`;
@@ -74321,7 +75571,8 @@ function headlineExitFromRoutes(routes2, symbol) {
74321
75571
  }
74322
75572
  function supplyHeadline(s, sheet = {}) {
74323
75573
  if (s.role === "collateral") {
74324
- return `Collateral only \xB7 ${maturityPhrase(s.maturity)}`;
75574
+ const inst2 = sheet.asset?.instrument;
75575
+ return `Collateral only \xB7 ${inst2 ? instrumentPhrase(inst2) : maturityPhrase(s.maturity)}`;
74325
75576
  }
74326
75577
  const rate = `${rateLabel(s)} ${pct(s.rate.aprTotal)}${windowNote(s.rate)}${provenance(s.rate)}`;
74327
75578
  const exit = headlineExitFromRoutes(s.exit.routes, sheet.asset?.symbol) ?? exitPhrase[String(s.exit.mode)] ?? (s.exit.settlement === "sync" ? "withdraw any time" : "delayed withdrawal");
@@ -74331,7 +75582,9 @@ function supplyHeadline(s, sheet = {}) {
74331
75582
  }
74332
75583
  const mat = s.maturity.kind === "perpetual" ? "" : ` ${maturityPhrase(s.maturity)}`;
74333
75584
  const warmup = s.rate.warmupSecs ? ` \xB7 earns after ${duration(s.rate.warmupSecs)}` : "";
74334
- return `${rate}${mat}${warmup} \xB7 ${exit}${cooldown}`;
75585
+ const inst = sheet.asset?.instrument;
75586
+ const instrument = inst ? ` \xB7 ${instrumentPhrase(inst)}` : "";
75587
+ return `${rate}${mat}${warmup}${instrument} \xB7 ${exit}${cooldown}`;
74335
75588
  }
74336
75589
  function borrowHeadline(b) {
74337
75590
  const rate = b.rate.kind === "zero-interest" ? "No ongoing interest" : b.rate.kind === "user-set" ? (
@@ -74363,6 +75616,8 @@ function supplyDescription(s, sheet = {}) {
74363
75616
  `You earn ${pct(s.rate.aprTotal)} (${comp.join(" + ")}), ${rateBehaviour(s.rate)}.`
74364
75617
  );
74365
75618
  }
75619
+ if (sheet.asset?.instrument)
75620
+ parts.push(...instrumentSentences(sheet.asset.instrument));
74366
75621
  if (s.exit.routes && s.exit.routes.length > 1) {
74367
75622
  parts.push(routesSentence(s.exit.routes, sheet.asset?.symbol));
74368
75623
  } else if (s.exit.mode === "instant") {
@@ -75043,16 +76298,73 @@ var TERM_SHEET_SCHEMA_VERSION = 1;
75043
76298
  // src/terms/buildTermSheet.ts
75044
76299
  var isNum = (v) => typeof v === "number" && Number.isFinite(v);
75045
76300
  var clamp013 = (v) => Math.max(0, Math.min(1, v));
75046
- function assetRef(input) {
76301
+ function assetRef(input, now) {
75047
76302
  const a = input.asset ?? {};
76303
+ const chainId = String(a.chainId ?? input.chainId);
76304
+ const address = String(a.address ?? input.underlying ?? "").toLowerCase();
75048
76305
  return {
75049
- chainId: String(a.chainId ?? input.chainId),
75050
- address: String(a.address ?? input.underlying ?? "").toLowerCase(),
76306
+ chainId,
76307
+ address,
75051
76308
  symbol: a.symbol,
75052
76309
  name: a.name,
75053
76310
  decimals: a.decimals ?? input.decimals,
75054
76311
  assetGroup: a.assetGroup,
75055
- logoURI: a.logoURI
76312
+ logoURI: a.logoURI,
76313
+ instrument: instrumentOf(
76314
+ a.props,
76315
+ chainId,
76316
+ address,
76317
+ now ?? Math.floor(Date.now() / 1e3)
76318
+ )
76319
+ };
76320
+ }
76321
+ var PENDLE_ORIGIN_CHAIN_BY_CODE = {
76322
+ ETH: "1",
76323
+ ARB: "42161",
76324
+ PLASMA: "9745"
76325
+ };
76326
+ function instrumentOf(props, chainId, address, now) {
76327
+ if (!props) return void 0;
76328
+ const pendle = props.pendle;
76329
+ if (pendle?.tokenType === "PT" && isNum(pendle.expiry) && pendle.expiry > 0) {
76330
+ const bridged = typeof pendle.bridgedFrom === "string" && pendle.bridgedFrom;
76331
+ const origin = pendle.origin && typeof pendle.origin.chainId === "string" && typeof pendle.origin.address === "string" ? {
76332
+ chainId: String(pendle.origin.chainId),
76333
+ address: String(pendle.origin.address).toLowerCase()
76334
+ } : void 0;
76335
+ const originChain = origin?.chainId ?? (bridged ? PENDLE_ORIGIN_CHAIN_BY_CODE[bridged] : void 0);
76336
+ return {
76337
+ kind: "principal-token",
76338
+ venue: "pendle",
76339
+ ...maturityFields(pendle.expiry, now),
76340
+ redemption: bridged ? (
76341
+ // An unknown origin code is still a bridged token — say where it is
76342
+ // NOT redeemable rather than pretend it is here.
76343
+ {
76344
+ local: false,
76345
+ chainId: originChain ?? "unknown",
76346
+ address: origin?.address
76347
+ }
76348
+ ) : { local: true, chainId, address }
76349
+ };
76350
+ }
76351
+ const spectra = props.spectra;
76352
+ if (spectra?.tokenType === "PT" && isNum(spectra.maturity) && spectra.maturity > 0) {
76353
+ return {
76354
+ kind: "principal-token",
76355
+ venue: "spectra",
76356
+ ...maturityFields(spectra.maturity, now),
76357
+ redemption: { local: true, chainId, address }
76358
+ };
76359
+ }
76360
+ return void 0;
76361
+ }
76362
+ function maturityFields(maturity, now) {
76363
+ return {
76364
+ maturity,
76365
+ maturityIso: new Date(maturity * 1e3).toISOString(),
76366
+ secondsToMaturity: Math.max(0, maturity - now),
76367
+ matured: maturity <= now
75056
76368
  };
75057
76369
  }
75058
76370
  function defaultConfig(input) {
@@ -75513,7 +76825,11 @@ function mergeDeep(base, patch) {
75513
76825
  return out;
75514
76826
  }
75515
76827
  function finalizeInfo(sheet) {
75516
- const market = { governance: sheet.governance, oracle: sheet.oracle };
76828
+ const market = {
76829
+ governance: sheet.governance,
76830
+ oracle: sheet.oracle,
76831
+ asset: sheet.asset
76832
+ };
75517
76833
  if (sheet.supply && !sheet.supply.info)
75518
76834
  sheet.supply.info = { headline: "", description: "", tags: [] };
75519
76835
  if (sheet.borrow && !sheet.borrow.info)
@@ -75568,7 +76884,7 @@ function buildTermSheet(input, opts = {}) {
75568
76884
  marketUid: input.marketUid,
75569
76885
  lender: input.lender,
75570
76886
  chainId: input.chainId,
75571
- asset: assetRef(input),
76887
+ asset: assetRef(input, now),
75572
76888
  supply: buildSupply(input, now, siblings),
75573
76889
  borrow: buildBorrow(input, now, siblings),
75574
76890
  utilization: buildUtilization(input),
@@ -77757,8 +79073,8 @@ var SupportsInterfaceAbi = [
77757
79073
  var detectInterfaceKinds = async (addresses, chainId, multicallRetry) => {
77758
79074
  const out = {};
77759
79075
  if (addresses.length === 0) return out;
77760
- const lc = addresses.map((a) => a.toLowerCase());
77761
- const calls = lc.flatMap((address) => [
79076
+ const lc2 = addresses.map((a) => a.toLowerCase());
79077
+ const calls = lc2.flatMap((address) => [
77762
79078
  {
77763
79079
  address,
77764
79080
  name: "supportsInterface",
@@ -77776,13 +79092,13 @@ var detectInterfaceKinds = async (addresses, chainId, multicallRetry) => {
77776
79092
  allowFailure: true
77777
79093
  });
77778
79094
  } catch {
77779
- for (const a of lc) out[a] = "erc4626";
79095
+ for (const a of lc2) out[a] = "erc4626";
77780
79096
  return out;
77781
79097
  }
77782
- for (let i = 0; i < lc.length; i++) {
79098
+ for (let i = 0; i < lc2.length; i++) {
77783
79099
  const is7540 = results[i * 2] === true;
77784
79100
  const is7575 = results[i * 2 + 1] === true;
77785
- out[lc[i]] = is7540 ? "erc7540" : is7575 ? "erc7575" : "erc4626";
79101
+ out[lc2[i]] = is7540 ? "erc7540" : is7575 ? "erc7575" : "erc4626";
77786
79102
  }
77787
79103
  return out;
77788
79104
  };
@@ -78405,10 +79721,11 @@ function toTermSheetInput(row, ctx = {}) {
78405
79721
  marketUid,
78406
79722
  lender,
78407
79723
  chainId,
78408
- asset: pick2(
78409
- row,
78410
- "asset",
78411
- "underlyingInfo.asset"
79724
+ // In-package rows carry `asset` as a bare ADDRESS and the metadata under
79725
+ // `underlyingInfo.asset`; the origin's rows carry the object under both.
79726
+ // Take the first OBJECT, so a string never shadows the metadata beside it.
79727
+ asset: [pick2(row, "asset"), pick2(row, "underlyingInfo.asset")].find(
79728
+ (v) => !!v && typeof v === "object"
78412
79729
  ),
78413
79730
  underlying: pick2(row, "underlying"),
78414
79731
  decimals: num15(pick2(row, "decimals")),
@@ -78901,8 +80218,37 @@ function borrowFindings(borrow) {
78901
80218
  }
78902
80219
  return out;
78903
80220
  }
80221
+ function assetFindings(sheet) {
80222
+ const inst = sheet.asset?.instrument;
80223
+ if (!inst) return [];
80224
+ const out = [];
80225
+ const origin = chainLabel(inst.redemption.chainId);
80226
+ if (inst.matured) {
80227
+ out.push({
80228
+ severity: "warn",
80229
+ id: "asset-matured",
80230
+ side: "supply",
80231
+ message: inst.redemption.local ? `The asset is a principal token that matured on ${shortDate(inst.maturity)} \u2014 it earns nothing further and should be redeemed for its underlying.` : `The asset is a principal token that matured on ${shortDate(inst.maturity)} \u2014 it earns nothing further, and can only be redeemed by bridging it back to ${origin}.`
80232
+ });
80233
+ } else if (!inst.redemption.local) {
80234
+ out.push({
80235
+ severity: "warn",
80236
+ id: "asset-bridged-pt",
80237
+ side: "supply",
80238
+ message: `The asset is a principal token bridged from ${origin}: it cannot be minted or redeemed on this chain. At maturity (${shortDate(inst.maturity)}) it is only redeemable at par back on ${origin}; here it can be sold.`
80239
+ });
80240
+ } else {
80241
+ out.push({
80242
+ severity: "info",
80243
+ id: "asset-matures",
80244
+ side: "supply",
80245
+ message: `The asset is a principal token maturing ${shortDate(inst.maturity)}, redeemable 1:1 for its underlying from then on.`
80246
+ });
80247
+ }
80248
+ return out;
80249
+ }
78904
80250
  function findingsFor(sheet, side) {
78905
- const sideFindings = side === "supply" ? sheet.supply ? supplyFindings(sheet.supply) : [] : sheet.borrow ? borrowFindings(sheet.borrow) : [];
80251
+ const sideFindings = side === "supply" ? sheet.supply ? [...supplyFindings(sheet.supply), ...assetFindings(sheet)] : [] : sheet.borrow ? borrowFindings(sheet.borrow) : [];
78906
80252
  return rankFindings([...sideFindings, ...marketFindings(sheet)]);
78907
80253
  }
78908
80254
  function hasCritical(sheet, side) {
@@ -81413,6 +82759,6 @@ function earnPositionTotals(items) {
81413
82759
  };
81414
82760
  }
81415
82761
 
81416
- export { ApiBookSource, DEFAULT_MIDNIGHT_API, DEFAULT_OUTLIER_GUARD, DEFAULT_PROFILE_ID, DEFAULT_STALE_REJECT_SECONDS, DEFAULT_TERMMAX_API, DEFAULT_TERM_ORDER_STORE, DOLOMITE_ISO_ID_PREFIX, EARN_DESCRIPTIONS, EARN_LABELS, EARN_RATE_SOURCE_BY_PROVIDER, EMPTY_BALANCE, EXACTLY_LENDER_KEY, FLYING_TULIP_LENDER_KEY, FRACTION_RATE_PROVIDERS, GMX_API_HOSTS, GMX_READ_CONTRACTS, GMX_SUPPORTED_CHAINS, HYPERCORE_VAULT_REGISTRY, IDLE_MARKET_ID, INTERFACE_IDS, LAGOON_API_URL, LAGOON_CHAIN_IDS, MORPHO_LENS, MULTICALL_FAILURE, MaxParamThresholds, PASSTHROUGH_RATE_EPSILON, PENDLE_ASSETS_URL, PENDLE_CHAIN_IDS, PENDLE_MARKETS_URL, SDK_FRACTION_RATE_PROVIDERS, SPECTRA_NETWORKS, SPECTRA_RATE_MAX_PERCENT, SPECTRA_RATE_MIN_PERCENT, STABLECOIN_SYMBOLS, STCELO_MANAGER_ADDRESS, TELLER_CALLS_PER_BID, DECIMAL_BASE as TERMMAX_DECIMAL_BASE, TERMMAX_LIQUIDATION_PENALTY, TERMMAX_LIQUIDATION_WINDOW_SECS, TERMMAX_LIQUIDATOR_BONUS, TERMMAX_MARKETS_PER_CALL, TERMMAX_PARTIAL_CLOSE_FACTOR, TERMMAX_PARTIAL_LIQUIDATION_THRESHOLD_USD, TERM_ADAPTERS, TERM_PROFILES, TERM_SHEET_SCHEMA_VERSION, TermMaxApiSource, TermSubgraphSource, UPSHIFT_CHAIN_IDS, UPSHIFT_VAULTS_URL, VAULT_PROVIDERS, VAULT_PROVIDER_PROFILE, VAULT_PROVIDER_TRAITS, VAULT_SHARE_PRICE_PROBE, VAULT_VENUE_PREFIX, VOLATILE_VAULT_OVERRIDES, YEARN_CHAIN_IDS, YEARN_YDAEMON_BASE, __resetResupplyUserCaches, accountDepositListKey, accountWithdrawalListKey, appendSnapshot, applyEarnSanity, applyPositionDelta, attachImplications, attachPricesToFlashLiquidity, borrowDescription, borrowFindings, borrowHeadline, buildExposures2 as buildExposures, buildFluidFTokensCall, buildLendingPositionUid, buildLiquityUserCall, buildLoopResult, buildMorphoTypeCall, buildMorphoTypeUserCallWithLens, buildPortfolioTotals, buildSumerAccumulators, buildSummaries, buildTellerUserCall, buildTermMaxUserCall, buildTermSheet, buildTermSheetsForGroup, buildVaultEarnUid, buildVaultLookup, buildVaultTermSheet, calculateLeverage, calculateNetApr, calculateOverallNetApr, calculateWeightedAverage, classifyFreshness, classifyReliability, classifyVault, clearPendleMarketsCache, clearSpectraMarketsCache, collateralSymbolsByVenue, collectFeedObservations, computeBorrowDelta2 as computeBorrowDelta, computeCloseTradeDeltas, computeCollateralSwapDeltas, computeDebtSwapDeltas, computeDepositDelta2 as computeDepositDelta, computeEModeAnalysis, computeOpenTradeDeltas, computePostTradeMetrics, computeRepayDelta2 as computeRepayDelta, computeSumerBorrowDelta, computeSumerDepositDelta, computeSumerRepayDelta, computeSumerWaterfall, computeSumerWithdrawDelta, computeVaultApr, computeWithdrawDelta2 as computeWithdrawDelta, computeZapTradeDeltas, consensusReference, convertCoolerMarketsToResponse, convertDssMarketsToResponse, convertExactlyMarketsToResponse, convertFlyingTulipMarketsToResponse, convertFrankencoinMarketsToResponse, convertFraxlendPairsToResponse, convertInverseMarketsToResponse, convertLenderUserDataResult, convertLiquityMarketsToResponse, convertLlamaLendMarketsToResponse, convertResupplyMarketsToResponse, convertRiverMarketsToResponse, convertTellerMarketsToResponse, convertTermMarketsToResponse, convertTermMaxMarketsToResponse, convertUsddMarketsToResponse, createMarketUid, createMidnightBookSource, createMulticallRpcCall, createRawRpcCalls, createTermBookSource, createTermMaxDataSource, decodeListaMarkets, decodeMarkets, decodePackedListaUserDataset, decodePackedMorphoUserDataset, deriveBorrowTags, deriveSupplyTags, detectInterfaceKinds, dexResolverFor, disambiguateEarnNames, dssIlkBytes32, dssKeyParts, dssLenderKey, duration, earnDescription, earnLabel, earnMarketFromPool, earnMarketFromVault, earnMarketLabel, earnPositionFromLenderEntry, earnPositionFromVaultBalance, earnPositionTotals, earnRateAtMaturity, earnRowSubtitle, earnUidFromMarketUid, earnVaultTerms, earnVenueKind, encodeBalanceFetcherCalldata, enrichTermSheet, enrichmentIndexFromRows, exactlyPairLtv, exactlyPenaltyRateToAprPercent, exactlyWadRateToPercent, feePhrase, feedKeyOf, feedStatKey, fetchCoolerMarkets, fetchDolomiteAccountNumbers, fetchDolomiteSubAccounts, fetchDssMarkets, fetchEulerEarnVaults, fetchEulerEarnVaultsFromSubgraph, fetchEulerSubAccountIndexes, fetchExactlyMarkets, fetchFlashLiquidityForChain, fetchFluidDexState, fetchFluidFTokens, fetchFlyingTulipMarkets, fetchFrankencoinMarkets, fetchFraxlendPairs, fetchGeneralYields, fetchGeneralYieldsByMarketUid, fetchGmxExecutionFees, fetchGmxTickerPrices, fetchGmxVaults, fetchHypercoreVaults, fetchInverseMarkets, fetchLagoonApiVaults, fetchLagoonVaults, fetchLiquityMarkets, fetchListaVaultsFromChain, fetchLlamaLendMarkets, fetchMorphoUserBalances, fetchMorphoUserPositionMarkets, fetchMorphoVaults, fetchMorphoVaultsFromApi, fetchMorphoVaultsFromChain, fetchOraclePrices, fetchPendleApiAssets, fetchPendleApiMarkets, fetchPendlePrices, fetchPendlePtMarkets, fetchResupplyMarkets, fetchRiverMarkets, fetchSiloVaults, fetchSpectraApiMarkets, fetchSpectraPtMarkets, fetchTellerMarkets, fetchTermMarkets, fetchTermMaxMarkets, fetchTermStoreOrders, fetchTokenBalances, fetchTokenMetadata, fetchUpshiftApiVaults, fetchUpshiftVaults, fetchUsddMarkets, fetchYearnApiVaults, fetchYearnVaults, fillableRemaining, filterActiveLenders, filterLendersByProtocol, finalizeInfo, findingsFor, formatRaw, frankencoinKeyParts, frankencoinLenderKey, fraxlendAssetPerCollateral, fraxlendKeyParts, fraxlendLenderKey, fuseLenderData, generateLendingPools, getAavesForChain, getAssetConfig, getBalanceForMarketUid, getBorrowCapacity, getCachedFluidDexState, getCachedLiquityTroves, getCachedTellerBids, getCachedTermMaxDiscovery, getCachedTermMaxMarket, getCachedTermMaxMarkets, getCoreValidators, getFluidFTokensConverter, getGmxApiHost, getGmxReadContracts, getGmxUserPositions, getHealthFactor, getHypercoreUserPositions, getHypercoreVaultRegistry, getLenderAssets, getLenderPublicData, getLenderPublicDataAll, getLenderPublicDataViaApi, getLenderUserDataMulti, getLenderUserDataResult, getLendersForChain, getLstDelegation, getLstValidators, getLstWithdrawalRegistry, getLstWithdrawalRequests, getMaxAmountClose, getMaxAmountCollateralSwap, getMaxAmountDebtSwap, getMaxAmountOpen, getMergedUserData, getMorphoTypeMarketConverter, getReadFailurePolicy, getResolvedDolomiteAccountNumbers, getResolvedDolomiteSubAccounts, getStCeloValidatorGroups, getSubAccountAddress, getSubAccountIndex, getTermProfile, getVaultPublicDataAll, getVaultWithdrawalRequests, hasCritical, hasEulerEarnVaultSubgraph, hasLagoonVaults, hasMorphoPositionIndex, hasMorphoUserApi, hasMorphoUserSubgraph, hasPendleMarkets, hasSpectraMarkets, hasUpshiftVaults, hasYearnVaults, ilkToKeySegment, implausibleRatePercent, inverseKeyParts, inverseLenderKey, isBoundNeed, isFailedCall, isIlliquid, isLendingPosition, isLiveMarket as isLivePendleMarket, isLiveSpectraMarket, isMaturedTerm, isSecondaryMarketOnly, isStablecoinSymbol, isUnearnableEarnRate, isUnrealizableEarnRate, isVaultPosition, isVaultVenue, isYearnV3, keySegmentToIlk, keysFromMaps, lenderApiOnly, lenderFamily, liquityCandidateTroveIds, liquityKeyParts, liquityLenderKey, llamaLendKeyParts, llamaLendLenderKey, meetsLiquidityFloor, mergeDeep, multicall3Abi2 as multicall3Abi, nanTo, needsLenderApproval, needsTokenApproval, noOpResult, normalizeToBytes, organizeUserQueries, parseBalanceFetcherResult, parseDolomiteSubAccountId, parseEarnUid, parseMergedResult, parseMulticallRpcResponses, parseExpirySeconds as parsePendleExpirySeconds, parseRawRpcBatchResponses, parseRawRpcResponses, parseCurveFee as parseSpectraCurveFee, parsePtRate as parseSpectraPtRate, parseTermMaxLtv, parseTokenBalanceResult, pct, assetKey as pendleAssetKey, pickPool as pickSpectraPool, positivePart2 as positivePart, predictInverseEscrow, prepareLenderUserDataRpcCalls, prepareMergedMulticallParams, prepareMergedRpcCalls, prepareMulticallInputs, prepareTokenBalanceRpcCalls, priceGlvVaults, priceGmMarkets, probeAaveFeedTimestamps, pruneFeedStats, rankFindings, ratePercent, readVaultSharePrices, rejectOutliers as rejectPriceOutliers, repairImpossibleTvl, resolveAdapter, resolveDerivation, resolveDolomiteRowIdentity, resolveEarnIdentity, resolveModeConfig, resolveStCeloDepositGroup, resolveVaultProfileId, resupplyKeyParts, resupplyLenderKey, resupplyMarketLabel, riverKeyParts, riverLenderKey, sanePercent as saneSpectraPercent, savingsAddresses, savingsBalanceKind, secondaryMarketVault, selectAssetGroupPrices, setMysticApiKey, shortDate, spectraAddress, spectraNetwork, spectraPoolsUrl, splitChainScopedAddress as splitPendleChainScopedAddress, stampCapabilities, stampEarnSubtitles, stampVaultClassification, stampVaultTermSheets, stripLeadingBrand, supplyDescription, supplyFindings, supplyHeadline, swapRoutedProvidersArePriceConsistent, tellerBpsToPercent, tellerImpliedLtv, tellerLenderKey, tellerPoolFromLenderKey, termApiBaseUrl, termLenderKey, termMaxApiBase, borrowNif as termMaxBorrowNif, curveApr as termMaxCurveApr, curveAprNumber as termMaxCurveAprNumber, daysToMaturity as termMaxDaysToMaturity, lendNif as termMaxLendNif, mintGtFeeRatio as termMaxMintGtFeeRatio, ratioToNumber as termMaxRatioToNumber, ratioToPercent as termMaxRatioToPercent, termOfferRateToAprPct, termOrderStoreBaseUrl, tickToAprNumber, tickToPrice, toDigest, toDolomiteSubAccountId, toTermFillNow, toTermSheetInput, toVaultTermInput, trancheFromCounterparty, tryParseEarnUid, unflattenLenderData, updateFeedStats, usdValue, usddIlkBytes32, usddKeyParts, usddLenderKey, validateTermSheet, validateTermSheets, validateUserData, vaultSharesToAssets, vaultTermInputFromEarnMarket, vaultTermInputFromSourceRow, vaultTraits, vaultVenue, venueBrand, venueBrandKey, withMaturityLabel, withTrancheLabel };
82762
+ export { ApiBookSource, DEFAULT_MIDNIGHT_API, DEFAULT_OUTLIER_GUARD, DEFAULT_PROFILE_ID, DEFAULT_STALE_REJECT_SECONDS, DEFAULT_TERMMAX_API, DEFAULT_TERM_ORDER_STORE, DOLOMITE_ISO_ID_PREFIX, EARN_DESCRIPTIONS, EARN_LABELS, EARN_RATE_SOURCE_BY_PROVIDER, EMPTY_BALANCE, EXACTLY_LENDER_KEY, FLYING_TULIP_LENDER_KEY, FRACTION_RATE_PROVIDERS, GMX_API_HOSTS, GMX_READ_CONTRACTS, GMX_SUPPORTED_CHAINS, HYPERCORE_VAULT_REGISTRY, IDLE_MARKET_ID, INTERFACE_IDS, LAGOON_API_URL, LAGOON_CHAIN_IDS, MORPHO_LENS, MULTICALL_FAILURE, MaxParamThresholds, PASSTHROUGH_RATE_EPSILON, PENDLE_ASSETS_URL, PENDLE_CHAIN_IDS, PENDLE_MARKETS_URL, SDK_FRACTION_RATE_PROVIDERS, SPECTRA_NETWORKS, SPECTRA_RATE_MAX_PERCENT, SPECTRA_RATE_MIN_PERCENT, STABLECOIN_SYMBOLS, STCELO_MANAGER_ADDRESS, TELLER_CALLS_PER_BID, DECIMAL_BASE as TERMMAX_DECIMAL_BASE, TERMMAX_LIQUIDATION_PENALTY, TERMMAX_LIQUIDATION_WINDOW_SECS, TERMMAX_LIQUIDATOR_BONUS, TERMMAX_MARKETS_PER_CALL, TERMMAX_PARTIAL_CLOSE_FACTOR, TERMMAX_PARTIAL_LIQUIDATION_THRESHOLD_USD, TERM_ADAPTERS, TERM_PROFILES, TERM_SHEET_SCHEMA_VERSION, TermMaxApiSource, TermSubgraphSource, UPSHIFT_CHAIN_IDS, UPSHIFT_VAULTS_URL, VAULT_PROVIDERS, VAULT_PROVIDER_PROFILE, VAULT_PROVIDER_TRAITS, VAULT_SHARE_PRICE_PROBE, VAULT_VENUE_PREFIX, VOLATILE_VAULT_OVERRIDES, YEARN_CHAIN_IDS, YEARN_YDAEMON_BASE, __resetResupplyUserCaches, accountDepositListKey, accountWithdrawalListKey, appendSnapshot, applyEarnSanity, applyPositionDelta, attachImplications, attachPricesToFlashLiquidity, borrowDescription, borrowFindings, borrowHeadline, buildExposures2 as buildExposures, buildFluidFTokensCall, buildLendingPositionUid, buildLiquityUserCall, buildLoopResult, buildMorphoTypeCall, buildMorphoTypeUserCallWithLens, buildPortfolioTotals, buildSumerAccumulators, buildSummaries, buildTellerUserCall, buildTermMaxUserCall, buildTermSheet, buildTermSheetsForGroup, buildVaultEarnUid, buildVaultLookup, buildVaultTermSheet, calculateLeverage, calculateNetApr, calculateOverallNetApr, calculateWeightedAverage, classifyFreshness, classifyReliability, classifyVault, clearPendleMarketsCache, clearSpectraMarketsCache, collateralSymbolsByVenue, collectFeedObservations, computeBorrowDelta2 as computeBorrowDelta, computeCloseTradeDeltas, computeCollateralSwapDeltas, computeDebtSwapDeltas, computeDepositDelta2 as computeDepositDelta, computeEModeAnalysis, computeOpenTradeDeltas, computePostTradeMetrics, computeRepayDelta2 as computeRepayDelta, computeSumerBorrowDelta, computeSumerDepositDelta, computeSumerRepayDelta, computeSumerWaterfall, computeSumerWithdrawDelta, computeVaultApr, computeWithdrawDelta2 as computeWithdrawDelta, computeZapTradeDeltas, consensusReference, convertCoolerMarketsToResponse, convertDssMarketsToResponse, convertExactlyMarketsToResponse, convertFlyingTulipMarketsToResponse, convertFrankencoinMarketsToResponse, convertFraxlendPairsToResponse, convertInverseMarketsToResponse, convertLenderUserDataResult, convertLiquityMarketsToResponse, convertLlamaLendMarketsToResponse, convertResupplyMarketsToResponse, convertRiverMarketsToResponse, convertTellerMarketsToResponse, convertTermMarketsToResponse, convertTermMaxMarketsToResponse, convertUsddMarketsToResponse, createMarketUid, createMidnightBookSource, createMulticallRpcCall, createRawRpcCalls, createTermBookSource, createTermMaxDataSource, decodeListaMarkets, decodeMarkets, decodePackedListaUserDataset, decodePackedMorphoUserDataset, deriveBorrowTags, deriveSupplyTags, detectInterfaceKinds, dexResolverFor, disambiguateEarnNames, dolomiteVaultAddress, dssIlkBytes32, dssKeyParts, dssLenderKey, duration, earnDescription, earnLabel, earnMarketFromPool, earnMarketFromVault, earnMarketLabel, earnPositionFromLenderEntry, earnPositionFromVaultBalance, earnPositionTotals, earnRateAtMaturity, earnRowSubtitle, earnUidFromMarketUid, earnVaultTerms, earnVenueKind, emitterCoverage, encodeBalanceFetcherCalldata, enrichTermSheet, enrichmentIndexFromRows, enumerateEmitters, exactlyPairLtv, exactlyPenaltyRateToAprPercent, exactlyWadRateToPercent, feePhrase, feedKeyOf, feedStatKey, fetchCoolerMarkets, fetchDolomiteAccountNumbers, fetchDolomiteSubAccounts, fetchDssMarkets, fetchEulerEarnVaults, fetchEulerEarnVaultsFromSubgraph, fetchEulerSubAccountIndexes, fetchExactlyMarkets, fetchFlashLiquidityForChain, fetchFluidDexState, fetchFluidFTokens, fetchFlyingTulipMarkets, fetchFrankencoinMarkets, fetchFraxlendPairs, fetchGeneralYields, fetchGeneralYieldsByMarketUid, fetchGmxExecutionFees, fetchGmxTickerPrices, fetchGmxVaults, fetchHypercoreVaults, fetchInverseMarkets, fetchLagoonApiVaults, fetchLagoonVaults, fetchLiquityMarkets, fetchListaVaultsFromChain, fetchLlamaLendMarkets, fetchMorphoUserBalances, fetchMorphoUserPositionMarkets, fetchMorphoVaults, fetchMorphoVaultsFromApi, fetchMorphoVaultsFromChain, fetchOraclePrices, fetchPendleApiAssets, fetchPendleApiMarkets, fetchPendlePrices, fetchPendlePtMarkets, fetchResupplyMarkets, fetchRiverMarkets, fetchSiloVaults, fetchSpectraApiMarkets, fetchSpectraPtMarkets, fetchTellerMarkets, fetchTermMarkets, fetchTermMaxMarkets, fetchTermStoreOrders, fetchTokenBalances, fetchTokenMetadata, fetchUpshiftApiVaults, fetchUpshiftVaults, fetchUsddMarkets, fetchYearnApiVaults, fetchYearnVaults, fillableRemaining, filterActiveLenders, filterLendersByProtocol, finalizeInfo, findingsFor, formatRaw, frankencoinKeyParts, frankencoinLenderKey, fraxlendAssetPerCollateral, fraxlendKeyParts, fraxlendLenderKey, fuseLenderData, generateLendingPools, getAavesForChain, getAssetConfig, getBalanceForMarketUid, getBorrowCapacity, getCachedFluidDexState, getCachedLiquityTroves, getCachedTellerBids, getCachedTermMaxDiscovery, getCachedTermMaxMarket, getCachedTermMaxMarkets, getCoreValidators, getFluidFTokensConverter, getGmxApiHost, getGmxReadContracts, getGmxUserPositions, getHealthFactor, getHypercoreUserPositions, getHypercoreVaultRegistry, getLenderAssets, getLenderPublicData, getLenderPublicDataAll, getLenderPublicDataViaApi, getLenderUserDataMulti, getLenderUserDataResult, getLendersForChain, getLstDelegation, getLstValidators, getLstWithdrawalRegistry, getLstWithdrawalRequests, getMaxAmountClose, getMaxAmountCollateralSwap, getMaxAmountDebtSwap, getMaxAmountOpen, getMergedUserData, getMorphoTypeMarketConverter, getReadFailurePolicy, getResolvedDolomiteAccountNumbers, getResolvedDolomiteSubAccounts, getStCeloValidatorGroups, getSubAccountAddress, getSubAccountIndex, getTermProfile, getVaultPublicDataAll, getVaultWithdrawalRequests, hasCritical, hasEulerEarnVaultSubgraph, hasLagoonVaults, hasMorphoPositionIndex, hasMorphoUserApi, hasMorphoUserSubgraph, hasPendleMarkets, hasSpectraMarkets, hasUpshiftVaults, hasYearnVaults, ilkToKeySegment, implausibleRatePercent, inverseKeyParts, inverseLenderKey, isBoundNeed, isFailedCall, isIlliquid, isLendingPosition, isLiveMarket as isLivePendleMarket, isLiveSpectraMarket, isMaturedTerm, isSecondaryMarketOnly, isStablecoinSymbol, isUnearnableEarnRate, isUnrealizableEarnRate, isVaultPosition, isVaultVenue, isYearnV3, keySegmentToIlk, keysFromMaps, lenderApiOnly, lenderFamily, liquityCandidateTroveIds, liquityKeyParts, liquityLenderKey, llamaLendKeyParts, llamaLendLenderKey, meetsLiquidityFloor, mergeDeep, multicall3Abi2 as multicall3Abi, nanTo, needsLenderApproval, needsTokenApproval, noOpResult, normalizeToBytes, organizeUserQueries, parseBalanceFetcherResult, parseDolomiteSubAccountId, parseEarnUid, parseMergedResult, parseMulticallRpcResponses, parseExpirySeconds as parsePendleExpirySeconds, parseRawRpcBatchResponses, parseRawRpcResponses, parseCurveFee as parseSpectraCurveFee, parsePtRate as parseSpectraPtRate, parseTermMaxLtv, parseTokenBalanceResult, pct, assetKey as pendleAssetKey, pickPool as pickSpectraPool, positivePart2 as positivePart, predictInverseEscrow, prepareLenderUserDataRpcCalls, prepareMergedMulticallParams, prepareMergedRpcCalls, prepareMulticallInputs, prepareTokenBalanceRpcCalls, priceGlvVaults, priceGmMarkets, probeAaveFeedTimestamps, pruneFeedStats, rankFindings, ratePercent, readVaultSharePrices, rejectOutliers as rejectPriceOutliers, repairImpossibleTvl, resolveAdapter, resolveDerivation, resolveDolomiteRowIdentity, resolveEarnIdentity, resolveModeConfig, resolveStCeloDepositGroup, resolveVaultProfileId, resupplyKeyParts, resupplyLenderKey, resupplyMarketLabel, riverKeyParts, riverLenderKey, sanePercent as saneSpectraPercent, savingsAddresses, savingsBalanceKind, secondaryMarketVault, selectAssetGroupPrices, setMysticApiKey, shortDate, spectraAddress, spectraNetwork, spectraPoolsUrl, splitChainScopedAddress as splitPendleChainScopedAddress, stampCapabilities, stampEarnSubtitles, stampVaultClassification, stampVaultTermSheets, stripLeadingBrand, supplyDescription, supplyFindings, supplyHeadline, swapRoutedProvidersArePriceConsistent, tellerBpsToPercent, tellerImpliedLtv, tellerLenderKey, tellerPoolFromLenderKey, termApiBaseUrl, termLenderKey, termMaxApiBase, borrowNif as termMaxBorrowNif, curveApr as termMaxCurveApr, curveAprNumber as termMaxCurveAprNumber, daysToMaturity as termMaxDaysToMaturity, lendNif as termMaxLendNif, mintGtFeeRatio as termMaxMintGtFeeRatio, ratioToNumber as termMaxRatioToNumber, ratioToPercent as termMaxRatioToPercent, termOfferRateToAprPct, termOrderStoreBaseUrl, tickToAprNumber, tickToPrice, toDigest, toDolomiteSubAccountId, toTermFillNow, toTermSheetInput, toVaultTermInput, trancheFromCounterparty, tryParseEarnUid, unflattenLenderData, updateFeedStats, usdValue, usddIlkBytes32, usddKeyParts, usddLenderKey, validateTermSheet, validateTermSheets, validateUserData, vaultSharesToAssets, vaultTermInputFromEarnMarket, vaultTermInputFromSourceRow, vaultTraits, vaultVenue, venueBrand, venueBrandKey, withMaturityLabel, withTrancheLabel };
81417
82763
  //# sourceMappingURL=index.js.map
81418
82764
  //# sourceMappingURL=index.js.map