@1delta/margin-fetcher 5.0.27 → 5.0.29

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
@@ -9,7 +9,7 @@ import { Chain } from '@1delta/chain-registry';
9
9
  import { multicallRetryUniversal, getEvmClient, getEvmChain, getEvmClientUniversal } from '@1delta/providers';
10
10
  import { LiquityTroveManagerAbi, LiquityActivePoolAbi, LiquityStabilityPoolAbi, LiquityPriceFeedAbi, LiquitySortedTrovesAbi, RiverTroveManagerAbi, RiverStabilityPoolAbi, TellerMarketRegistryAbi, TellerV2Abi, InverseMarketAbi, InverseOracleAbi, InverseDbrAbi, Erc20Abi, LlamaLendControllerAbi, LlamaLendControllerV1Abi, LlamaLendControllerV2Abi, LlamaLendVaultAbi, LlamaLendAmmAbi, MetaMorphoAbi, ExactlyPreviewerAbi, ExactlyAuditorAbi, LenderCommitmentGroupAbi, ResupplyRegistryAbi, ResupplyPairAbi, ResupplyUtilitiesAbi, ResupplyRewardHandlerAbi, ResupplyPairEmissionsAbi, ConvexPoolUtilAbi, FraxlendPairAbi, FrankencoinPositionAbi, FluidLendingResolverAbi, FluidVaultResolverAbi, FluidLiquidityResolverAbi, MoolahVaultAbi, UsddVatAbi, UsddJugAbi, UsddSpotAbi, MorphoLensAbi, AaveV4SpokeAbi, AaveV4OracleAbi, AaveV4HubAbi, DolomiteMarginAbi, GearboxMarketCompressorV310Abi, MorphoBlueAbi, MidnightAbi, TermRepoTokenAbi, TermRepoServicerAbi, TermRepoCollateralManagerAbi, LiquityTroveNFTAbi, LiquityCollSurplusPoolAbi, TellerCollateralManagerAbi, TermMaxViewerAbi, InverseEscrowAbi, CurvanceMarketManagerAbi, CurvanceCTokenAbi, GearboxCreditAccountCompressorV310Abi, UsddCdpManagerAbi, UsddProxyRegistryAbi, CurvanceProtocolReaderAbi, CurvanceCentralRegistryAbi, TermPriceConsumerAbi, CurvanceOracleManagerAbi, TermMaxOracleAggregatorV2Abi } from '@1delta/abis';
11
11
  export { MorphoLensAbi } from '@1delta/abis';
12
- import { prepareDebitDataMulticall, prepareLenderDebitMulticall, parseDebitDataResult, parseLenderDebitResult, getPermit2ContractAddress, getCompoundV3CometAddress as getCompoundV3CometAddress$1, getMorphoAddress, getAaveCollateralTokenAddress, getSiloHalfForUnderlying, bandLtvCurve, InitMarginAddresses, getLstAcceptedInputs } from '@1delta/calldata-sdk';
12
+ import { prepareDebitDataMulticall, prepareLenderDebitMulticall, parseDebitDataResult, parseLenderDebitResult, getPermit2ContractAddress, getLstAcceptedInputs, getCompoundV3CometAddress as getCompoundV3CometAddress$1, getMorphoAddress, getAaveCollateralTokenAddress, getSiloHalfForUnderlying, bandLtvCurve, InitMarginAddresses } 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
15
 
@@ -21931,7 +21931,7 @@ async function fetchTellerMarkets(chainId) {
21931
21931
  }
21932
21932
  return null;
21933
21933
  };
21934
- const num15 = (i) => {
21934
+ const num16 = (i) => {
21935
21935
  const b = big18(i);
21936
21936
  return b === null ? null : Number(b);
21937
21937
  };
@@ -21941,9 +21941,9 @@ async function fetchTellerMarkets(chainId) {
21941
21941
  config,
21942
21942
  available: big18(base),
21943
21943
  committed: big18(base + 1),
21944
- minRateBps: num15(base + 2),
21944
+ minRateBps: num16(base + 2),
21945
21945
  collateralPerPrincipal: big18(base + 3),
21946
- maxLoanDuration: num15(base + 4),
21946
+ maxLoanDuration: num16(base + 4),
21947
21947
  marketId: big18(base + 5),
21948
21948
  totalAssets: big18(base + 6)
21949
21949
  };
@@ -22906,20 +22906,20 @@ async function fetchInverseMarkets(lender, chainId) {
22906
22906
  if (Object.keys(byAddr).length > 0) {
22907
22907
  const rows = markets.map((market) => {
22908
22908
  const m = byAddr[market.address.toLowerCase()];
22909
- const num15 = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
22909
+ const num16 = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
22910
22910
  return {
22911
22911
  market,
22912
- totalDebt: num15(m?.totalDebt),
22913
- dolaLiquidity: num15(m?.dolaLiquidity),
22914
- leftToBorrow: num15(m?.leftToBorrow),
22915
- price: num15(m?.price),
22912
+ totalDebt: num16(m?.totalDebt),
22913
+ dolaLiquidity: num16(m?.dolaLiquidity),
22914
+ leftToBorrow: num16(m?.leftToBorrow),
22915
+ price: num16(m?.price),
22916
22916
  borrowPaused: typeof m?.borrowPaused === "boolean" ? m.borrowPaused : null,
22917
- dailyBorrows: num15(m?.dailyBorrows),
22917
+ dailyBorrows: num16(m?.dailyBorrows),
22918
22918
  // The API serves it as a DECIMAL (`replenishmentIncentive: 0.1`),
22919
22919
  // unlike the on-chain bps — normalize here, and fall back to the
22920
22920
  // curated metadata value when the field is missing.
22921
22921
  replenishmentIncentiveBps: (() => {
22922
- const dec2 = num15(m?.replenishmentIncentive);
22922
+ const dec2 = num16(m?.replenishmentIncentive);
22923
22923
  if (dec2 !== null) return Math.round(dec2 * 1e4);
22924
22924
  const meta = Number(market.replenishmentIncentiveBps);
22925
22925
  return Number.isFinite(meta) ? meta : null;
@@ -64138,8 +64138,9 @@ function marketTags(sheet) {
64138
64138
  if (g) {
64139
64139
  if (g.mutability === "immutable") push(out, "immutable");
64140
64140
  if (g.mutability === "governed") {
64141
+ const contractEnforced = (g.timelockSecs ?? 0) > 0 && g.timelockSource === "on-chain";
64141
64142
  const isTimelockRoot = g.controllerKind === "TIMELOCK";
64142
- if (!isTimelockRoot) push(out, "no-timelock");
64143
+ if (contractEnforced) ; else if (!isTimelockRoot) push(out, "no-timelock");
64143
64144
  else if (!g.timelockSecs && !g.timelockUnknown) push(out, "no-timelock");
64144
64145
  if (g.controllerKind === "EOA") push(out, "eoa-controlled");
64145
64146
  }
@@ -64915,7 +64916,8 @@ var TERM_PROFILES = [
64915
64916
  "There is NO deposit or redemption before maturity \u2014 you enter and exit by TRADING on an AMM, so both legs move against you with size and need a slippage tolerance.",
64916
64917
  "The quoted liquidity is pool DEPTH, not idle cash waiting to be withdrawn.",
64917
64918
  "The rate is fixed at purchase. Selling early realizes whatever the market pays that block, which can be above or below your entry.",
64918
- "Buying gives up the underlying\u2019s own floating yield for the term \u2014 that is the trade, not an extra return on top."
64919
+ "Buying gives up the underlying\u2019s own floating yield for the term \u2014 that is the trade, not an extra return on top.",
64920
+ "Redemption is 1:1 in the underlying, so the fixed rate itself carries no credit risk \u2014 but you are paid in that underlying, and whatever risk it carries (a depeg, a failure of the protocol behind it) passes straight through to you."
64919
64921
  ]
64920
64922
  }
64921
64923
  }),
@@ -65561,6 +65563,11 @@ function buildTermSheet(input, opts = {}) {
65561
65563
  var LENDING_VAULT = {
65562
65564
  rateKind: "variable-curve",
65563
65565
  rateSource: "utilization-curve",
65566
+ // Structural, not curated: these vaults can only reach markets that require
65567
+ // collateral. A shortfall is possible (bad debt socializes to depositors, and
65568
+ // `principal.risks` carries that), but the loan book itself is collateralized
65569
+ // by construction — which is a different statement from Maple's or Native's.
65570
+ solvency: "overcollateralized",
65564
65571
  defaultExitMode: "instant-capped",
65565
65572
  priceRisk: "none",
65566
65573
  counterpartyKind: "vault-strategy",
@@ -65600,13 +65607,19 @@ var VAULT_PROVIDER_TRAITS = {
65600
65607
  },
65601
65608
  // The only provider that publishes a real debt accumulator on the row
65602
65609
  // (`totalBorrowed` / `expectedLiquidity`), so utilization is exact here.
65610
+ // Lends to leveraged credit accounts, which post collateral and carry a
65611
+ // health factor — collateralized, like the rest of this class.
65603
65612
  gearbox: { ...LENDING_VAULT, reportsGovernance: false },
65604
65613
  // A thin 4626 wrapper over an Aave v3 supply position: the rate IS the
65605
65614
  // reserve's supply curve. Publishes no liquidity field of its own.
65606
65615
  "aave-earn": {
65607
65616
  ...LENDING_VAULT,
65608
65617
  counterpartyKind: "pool",
65609
- reportsGovernance: false
65618
+ reportsGovernance: false,
65619
+ // The ONLY provider reporting `fee` as a fraction. Its own type documents
65620
+ // it (`0.1` = 10 %) while morpho / silo / euler-earn / termmax / yearn all
65621
+ // document percent.
65622
+ feeIsFraction: true
65610
65623
  },
65611
65624
  // The VAULT is perpetual and its rate floats with what the curator earns
65612
65625
  // rolling FT positions — it is NOT itself a fixed-term instrument, which
@@ -65631,6 +65644,10 @@ var VAULT_PROVIDER_TRAITS = {
65631
65644
  },
65632
65645
  lst: {
65633
65646
  rateKind: "variable-managed",
65647
+ // A pro-rata claim on real staked capital — fully backed, no borrower.
65648
+ // The residual risk is slashing and the exit queue, both of which the
65649
+ // exit terms and the profile state; neither is a solvency question.
65650
+ solvency: "overcollateralized",
65634
65651
  // Staking rewards are neither a curve nor a governance dial — the rate is
65635
65652
  // reconstructed from the share/asset ratio moving.
65636
65653
  rateSource: "derived",
@@ -65647,6 +65664,15 @@ var VAULT_PROVIDER_TRAITS = {
65647
65664
  // the TermMax FT promise reached by an AMM discount instead of a quote.
65648
65665
  pendle: {
65649
65666
  rateKind: "fixed-term",
65667
+ // A PT redeems 1:1 for the accounting asset at maturity — there is no
65668
+ // borrower, no leverage and no tranching on the Pendle side, so the
65669
+ // fixed-rate promise itself carries no credit risk.
65670
+ //
65671
+ // What it does NOT mean: the SY it redeems into is only as good as the
65672
+ // protocol behind it, and that risk passes straight through to the PT
65673
+ // holder. That is a property of the underlying, stated in the profile's
65674
+ // implications, not a defect in this classification.
65675
+ solvency: "overcollateralized",
65650
65676
  rateSource: "derived",
65651
65677
  rateWindow: { kind: "forward" },
65652
65678
  defaultExitMode: "market-sale",
@@ -65757,12 +65783,15 @@ function windowFromAprWindow(aprWindow) {
65757
65783
  var isNum2 = (v) => typeof v === "number" && Number.isFinite(v);
65758
65784
  var clamp012 = (v) => Math.max(0, Math.min(1, v));
65759
65785
  function buildRate2(input, t, maturity) {
65760
- const base = input.supplyRate ?? 0;
65786
+ const hasLegs = input.supplyRate != null || input.rewardsRate != null;
65787
+ const base = hasLegs ? input.supplyRate ?? 0 : input.totalRate ?? 0;
65761
65788
  const rewards = input.rewardsRate ?? 0;
65762
- const total = input.totalRate ?? base + rewards;
65789
+ const total = base + rewards;
65763
65790
  const isNav = input.navOracle != null || input.solvency === "nav-attested";
65764
65791
  const termIsBacked = maturity.kind === "fixed-date";
65765
- const kind = isNav ? "nav-accrual" : t.rateKind === "fixed-term" && !termIsBacked ? "variable-managed" : t.rateKind;
65792
+ const window = resolveRateWindow(input, t);
65793
+ const measured = window?.kind === "trailing" || input.yieldProfile === "volatile";
65794
+ const kind = isNav ? "nav-accrual" : measured && t.rateKind !== "fixed-term" ? "realized" : t.rateKind === "fixed-term" && !termIsBacked ? "variable-managed" : t.rateKind;
65766
65795
  const source = isNav ? "oracle" : t.rateSource;
65767
65796
  return {
65768
65797
  kind,
@@ -65782,7 +65811,7 @@ function buildRate2(input, t, maturity) {
65782
65811
  source,
65783
65812
  // A PT's discount is fixed at purchase; every other vault floats.
65784
65813
  isLocked: kind === "fixed-term" && termIsBacked,
65785
- window: resolveRateWindow(input, t)
65814
+ window
65786
65815
  };
65787
65816
  }
65788
65817
  function resolveRateWindow(input, t) {
@@ -65790,7 +65819,9 @@ function resolveRateWindow(input, t) {
65790
65819
  if (input.isForwardApr === false) return { kind: "trailing" };
65791
65820
  const fromAprWindow = windowFromAprWindow(input.aprWindow);
65792
65821
  if (fromAprWindow) return fromAprWindow;
65793
- return t.rateWindow;
65822
+ if (t.rateWindow) return t.rateWindow;
65823
+ if (input.yieldProfile === "volatile") return { kind: "trailing" };
65824
+ return void 0;
65794
65825
  }
65795
65826
  function buildMaturity2(input, now) {
65796
65827
  const expiry = input.expiry;
@@ -65814,10 +65845,12 @@ function buildFees2(input, t) {
65814
65845
  id: "performance",
65815
65846
  label: "Performance fee",
65816
65847
  when: "performance",
65817
- // Every provider that reports `fee` reports it as a PERCENT of yield.
65818
65848
  unit: "percent",
65819
65849
  basis: "yield",
65820
- value: input.fee,
65850
+ // Normalized to PERCENT here, because the providers disagree: `aave-earn`
65851
+ // publishes a fraction and the other five publish percent, so a uniform
65852
+ // read renders a 10 % curator cut as "0.1 %".
65853
+ value: t.feeIsFraction ? input.fee * 100 : input.fee,
65821
65854
  payee: "curator",
65822
65855
  mutable: true,
65823
65856
  description: "Taken from the yield the vault earns, not from your principal. The published rate is already net of it."
@@ -65990,11 +66023,11 @@ function buildCounterparty(input, t) {
65990
66023
  return {
65991
66024
  kind: t.counterpartyKind,
65992
66025
  address: input.address,
65993
- // Absent curation means we do not know, and the honest default is the
65994
- // structurally true one for an on-chain lending vault. `coverage` records
65995
- // which of the two it was, so a consumer can tell an asserted
65996
- // `overcollateralized` from an assumed one.
65997
- solvency: input.solvency ?? "overcollateralized",
66026
+ // Three tiers, most specific first: a CURATED per-vault classification, then
66027
+ // the provider's STRUCTURAL answer where one exists, then an assumption.
66028
+ // `coverage` records which tier answered, so a consumer can always tell an
66029
+ // asserted `overcollateralized` from an assumed one.
66030
+ solvency: input.solvency ?? t.solvency ?? "overcollateralized",
65998
66031
  socializedLoss: input.solvency === "tranched-junior" ? true : void 0,
65999
66032
  curator: input.curatorName ?? input.curator
66000
66033
  };
@@ -66032,7 +66065,10 @@ function buildGovernance(input, t) {
66032
66065
  // `0` is REAL on the providers that run no timelock pattern (Lista earn) —
66033
66066
  // it means no notice period, which is exactly what a holder needs told.
66034
66067
  timelockSecs: input.timelock,
66035
- timelockSource: "metadata",
66068
+ // Read off the VAULT, not inferred from a governance screen — and the vault
66069
+ // enforces the queue itself, which is why this delay stands even though the
66070
+ // controller above is an unscreened curator address.
66071
+ timelockSource: "on-chain",
66036
66072
  powers: ["set-caps", "change-fees", "pause-withdrawals"],
66037
66073
  roles: hasRole ? roles : void 0
66038
66074
  };
@@ -66092,6 +66128,7 @@ function buildCoverage2(sheet, input, t) {
66092
66128
  else if (!t.reportsPerformanceFee)
66093
66129
  pending.fees = "provider-publishes-no-fee-schedule";
66094
66130
  if (input.solvency) present.push("counterparty");
66131
+ else if (t.solvency) present.push("counterparty");
66095
66132
  else pending.counterparty = "solvency-not-curated-default-assumed";
66096
66133
  if (sheet.supply?.exit.liquidity) present.push("exitLiquidity");
66097
66134
  else pending.exitLiquidity = "provider-does-not-publish-liquidity";
@@ -66105,7 +66142,7 @@ function buildVaultTermSheet(input, opts = {}) {
66105
66142
  const now = opts.now ?? Math.floor(Date.now() / 1e3);
66106
66143
  const t = vaultTraits(input.provider) ?? FALLBACK_TRAITS;
66107
66144
  const maturity = buildMaturity2(input, now);
66108
- const fees = buildFees2(input);
66145
+ const fees = buildFees2(input, t);
66109
66146
  const supply = {
66110
66147
  // A vault share is never collateral IN the vault — it earns, full stop.
66111
66148
  // (It may be collateral somewhere else; that is the other market's sheet.)
@@ -66244,9 +66281,501 @@ function splitUid(uid) {
66244
66281
  if (!venue || !chainId || !ref) return void 0;
66245
66282
  return { venue, chainId, ref };
66246
66283
  }
66284
+ var VENUE_KIND_LABELS = {
66285
+ lending: "Lending markets",
66286
+ vault: "Vaults"
66287
+ };
66288
+ var VENUE_KIND_DESCRIPTIONS = {
66289
+ lending: "Supply into a lending market. Same-block exit, bounded by liquidity.",
66290
+ vault: "Deposit into a yield vault. Exit terms vary per vault."
66291
+ };
66292
+ var EXIT_MODE_LABELS = {
66293
+ instant: "Instant",
66294
+ "instant-capped": "Instant (capped)",
66295
+ "instant-or-queued": "Instant or queue",
66296
+ "fee-or-queued": "Fee or queue",
66297
+ "fixed-cooldown": "Cooldown",
66298
+ queued: "Queued",
66299
+ "request-based": "Request",
66300
+ "market-sale": "Market sale",
66301
+ "at-maturity": "At maturity",
66302
+ "off-chain": "Off-chain",
66303
+ "dex-only": "DEX only"
66304
+ };
66305
+ var EXIT_MODE_DESCRIPTIONS = {
66306
+ instant: "Withdraw any time.",
66307
+ "instant-capped": "Withdraw up to the available liquidity.",
66308
+ "instant-or-queued": "Withdraw instantly, or queue for the rest.",
66309
+ "fee-or-queued": "Instant exit for a fee, or queue for free.",
66310
+ "fixed-cooldown": "Request, wait out a cooldown, then claim.",
66311
+ queued: "Withdrawals are queued.",
66312
+ "request-based": "Withdrawals need a request and a later claim.",
66313
+ "market-sale": "Exit by selling the position on a market.",
66314
+ "at-maturity": "Locked until maturity.",
66315
+ "off-chain": "Exit is settled off-chain.",
66316
+ "dex-only": "Exit only by selling on a DEX."
66317
+ };
66318
+ var ACTION_LABELS = {
66319
+ deposit: "Deposit",
66320
+ withdraw: "Withdraw",
66321
+ "request-withdraw": "Request withdrawal",
66322
+ claim: "Claim",
66323
+ cancel: "Cancel request"
66324
+ };
66325
+ var GATING_LABELS = {
66326
+ "allowlist-contract": "Permissioned",
66327
+ kyc: "KYC required",
66328
+ "cap-full": "Cap full",
66329
+ paused: "Paused",
66330
+ frozen: "Frozen",
66331
+ "collateral-only": "No yield",
66332
+ matured: "Matured"
66333
+ };
66334
+ var RATE_KIND_LABELS = {
66335
+ "variable-curve": "Variable (utilization)",
66336
+ "variable-managed": "Variable (managed)",
66337
+ "user-set": "Borrower-set",
66338
+ "fixed-term": "Fixed term",
66339
+ "fixed-open": "Fixed",
66340
+ "zero-interest": "Interest-free",
66341
+ prepaid: "Prepaid",
66342
+ "nav-accrual": "NAV accrual",
66343
+ none: "No rate"
66344
+ };
66345
+ var RATE_SOURCE_LABELS = {
66346
+ chain: "On-chain",
66347
+ api: "Protocol API",
66348
+ oracle: "Oracle",
66349
+ realized: "Realized"
66350
+ };
66351
+ var SYNTHETIC_FAMILIES = ["AAVE_V4", "COMPOUND_V3", "SWAYLEND"];
66352
+ var FAMILY_KEYS = [
66353
+ .../* @__PURE__ */ new Set([
66354
+ ...Object.values(Lender),
66355
+ ...SYNTHETIC_FAMILIES
66356
+ ])
66357
+ ].sort((a, b) => a.length - b.length || a.localeCompare(b));
66358
+ var BRAND_OVERRIDES = {
66359
+ LISTA_DAO: "Lista",
66360
+ FLUX_FINANCE: "Flux",
66361
+ TERMMAX: "TermMax",
66362
+ LLAMALEND: "LlamaLend",
66363
+ USDD: "USDD",
66364
+ USDAF: "USDaf",
66365
+ DTRINITY: "dTRINITY",
66366
+ DFORCE: "dForce",
66367
+ OVIX: "0VIX",
66368
+ WE_PIGGY: "WePiggy",
66369
+ ZEROLEND: "ZeroLend",
66370
+ HYPERLEND: "HyperLend",
66371
+ HYPURRFI: "HypurrFi",
66372
+ HYPERYIELD: "HyperYield",
66373
+ LAYERBANK_V3: "LayerBank V3",
66374
+ TAKOTAKO: "TakoTako",
66375
+ SWAYLEND: "Swaylend",
66376
+ BENQI: "BENQI",
66377
+ YLDR: "YLDR",
66378
+ YEI: "YEI",
66379
+ RMM: "RMM",
66380
+ PAC: "PAC"
66381
+ };
66382
+ function titleCaseKey(key3) {
66383
+ return key3.split(/[_-]/).filter(Boolean).map((s) => s.charAt(0).toUpperCase() + s.slice(1).toLowerCase()).join(" ");
66384
+ }
66385
+ var VAULT_PROVIDER_BRANDS = {
66386
+ fluid: "Fluid",
66387
+ gearbox: "Gearbox",
66388
+ morpho: "Morpho",
66389
+ lista: "Lista",
66390
+ silo: "Silo",
66391
+ "euler-earn": "Euler",
66392
+ termmax: "TermMax",
66393
+ lst: "Liquid staking",
66394
+ savings: "Savings",
66395
+ lagoon: "Lagoon",
66396
+ "aave-earn": "Aave",
66397
+ upshift: "Upshift",
66398
+ yearn: "Yearn",
66399
+ hypercore: "HyperLiquid",
66400
+ gmx: "GMX",
66401
+ pendle: "Pendle"
66402
+ };
66403
+ function isInstanceSegment(seg) {
66404
+ if (/^\d+$/.test(seg)) return true;
66405
+ if (/^0X[0-9A-F]+$/i.test(seg)) return true;
66406
+ return seg.length >= 8 && /^[0-9A-F]+$/i.test(seg);
66407
+ }
66408
+ function venueBrandKey(venue) {
66409
+ if (venue.startsWith(VAULT_VENUE_PREFIX)) return venue;
66410
+ const key3 = venue.toUpperCase();
66411
+ for (const family of FAMILY_KEYS) {
66412
+ if (key3 === family || key3.startsWith(family + "_")) return family;
66413
+ }
66414
+ const segments = key3.split("_");
66415
+ const cut = segments.findIndex(isInstanceSegment);
66416
+ return (cut > 0 ? segments.slice(0, cut) : segments).join("_");
66417
+ }
66418
+ function venueBrand(venue) {
66419
+ if (venue.startsWith(VAULT_VENUE_PREFIX)) {
66420
+ const provider = venue.slice(VAULT_VENUE_PREFIX.length);
66421
+ return VAULT_PROVIDER_BRANDS[provider] ?? titleCaseKey(provider);
66422
+ }
66423
+ const family = venueBrandKey(venue);
66424
+ return BRAND_OVERRIDES[family] ?? titleCaseKey(family);
66425
+ }
66426
+ var EARN_LABELS = {
66427
+ venueKind: VENUE_KIND_LABELS,
66428
+ exitMode: EXIT_MODE_LABELS,
66429
+ action: ACTION_LABELS,
66430
+ gating: GATING_LABELS,
66431
+ rateKind: RATE_KIND_LABELS,
66432
+ rateSource: RATE_SOURCE_LABELS
66433
+ };
66434
+ var EARN_DESCRIPTIONS = {
66435
+ venueKind: VENUE_KIND_DESCRIPTIONS,
66436
+ exitMode: EXIT_MODE_DESCRIPTIONS
66437
+ };
66438
+ function earnLabel(dimension, key3) {
66439
+ return EARN_LABELS[dimension][key3] ?? key3;
66440
+ }
66441
+ function earnDescription(dimension, key3) {
66442
+ return EARN_DESCRIPTIONS[dimension][key3];
66443
+ }
66444
+ function earnMarketLabel(input) {
66445
+ const asset = input.assetSymbol?.trim();
66446
+ if (!asset) return input.fallbackName ?? "";
66447
+ const collaterals = (input.collateralSymbols ?? []).map((c) => c?.trim()).filter((c) => !!c);
66448
+ const distinct = [...new Set(collaterals)];
66449
+ if (distinct.length === 1) return `${asset} \xB7 vs ${distinct[0]}`;
66450
+ return asset;
66451
+ }
66452
+ var SAME_BLOCK_EXIT_MODES = /* @__PURE__ */ new Set([
66453
+ "instant",
66454
+ "instant-capped"
66455
+ ]);
66456
+ function isIlliquid(input) {
66457
+ if (!input.exitMode || !SAME_BLOCK_EXIT_MODES.has(input.exitMode))
66458
+ return false;
66459
+ if (!input.tvlUsd || input.tvlUsd <= 0) return false;
66460
+ if (input.liquidityUsd === void 0) return false;
66461
+ return input.liquidityUsd <= 0;
66462
+ }
66463
+ var CATEGORY_PROVIDERS = /* @__PURE__ */ new Set(["savings", "lst"]);
66464
+ function resolveEarnIdentity(venue, brand) {
66465
+ const isVault = venue.startsWith(VAULT_VENUE_PREFIX);
66466
+ const provider = isVault ? venue.slice(VAULT_VENUE_PREFIX.length) : venue;
66467
+ const providerBrand = venueBrand(venue);
66468
+ const key3 = venueBrandKey(venue);
66469
+ if (isVault && CATEGORY_PROVIDERS.has(provider)) {
66470
+ return { protocol: { key: key3, name: brand?.trim() || providerBrand } };
66471
+ }
66472
+ const name = brand?.trim();
66473
+ if (!name || name.toLowerCase() === providerBrand.toLowerCase()) {
66474
+ return { protocol: { key: key3, name: providerBrand } };
66475
+ }
66476
+ return { protocol: { key: key3, name: providerBrand }, curator: { name } };
66477
+ }
66478
+
66479
+ // src/earn/normalize.ts
66480
+ function num12(v) {
66481
+ if (v == null || v === "") return void 0;
66482
+ const n = typeof v === "number" ? v : Number(v);
66483
+ return Number.isFinite(n) ? n : void 0;
66484
+ }
66485
+ function str5(v) {
66486
+ if (typeof v === "string") return v.length > 0 ? v : void 0;
66487
+ if (typeof v === "number" && Number.isFinite(v)) return String(v);
66488
+ return void 0;
66489
+ }
66490
+ function addr2(v) {
66491
+ return str5(v)?.toLowerCase();
66492
+ }
66493
+ function yieldProfile(v) {
66494
+ return v === "yield-bearing" || v === "volatile" ? v : void 0;
66495
+ }
66496
+ function denomination(v) {
66497
+ return v === "stable" || v === "volatile" ? v : void 0;
66498
+ }
66499
+ function usdValue(formatted, priceUsd) {
66500
+ if (formatted === void 0 || priceUsd === void 0) return void 0;
66501
+ const v = formatted * priceUsd;
66502
+ return Number.isFinite(v) ? v : void 0;
66503
+ }
66504
+ function formatRaw(raw, decimals) {
66505
+ if (raw == null || raw === "") return void 0;
66506
+ let value;
66507
+ try {
66508
+ value = BigInt(raw);
66509
+ } catch {
66510
+ return void 0;
66511
+ }
66512
+ if (decimals <= 0) return Number(value);
66513
+ const base = 10n ** BigInt(decimals);
66514
+ const whole = value / base;
66515
+ const frac = value % base;
66516
+ const n = Number(whole) + Number(frac) / Number(base);
66517
+ return Number.isFinite(n) ? n : void 0;
66518
+ }
66519
+
66520
+ // src/earn/fromVault.ts
66521
+ var FRACTION_RATE_PROVIDERS = /* @__PURE__ */ new Set();
66522
+ var SDK_FRACTION_RATE_PROVIDERS = /* @__PURE__ */ new Set([
66523
+ "hypercore",
66524
+ "gmx"
66525
+ ]);
66526
+ var RATE_SOURCE = {
66527
+ morpho: "api",
66528
+ silo: "api",
66529
+ lagoon: "api",
66530
+ hypercore: "api",
66531
+ gmx: "api",
66532
+ upshift: "api",
66533
+ yearn: "api",
66534
+ "aave-earn": "api",
66535
+ pendle: "api",
66536
+ lista: "chain",
66537
+ fluid: "chain",
66538
+ gearbox: "chain",
66539
+ "euler-earn": "chain",
66540
+ termmax: "chain",
66541
+ lst: "chain",
66542
+ savings: "chain"
66543
+ };
66544
+ var RATE_KIND = {
66545
+ morpho: "variable-curve",
66546
+ lista: "variable-curve",
66547
+ silo: "variable-curve",
66548
+ "euler-earn": "variable-curve",
66549
+ fluid: "variable-curve",
66550
+ gearbox: "variable-curve",
66551
+ "aave-earn": "variable-curve",
66552
+ // The TermMax VAULT is a perpetual curated 4626 whose curator rolls
66553
+ // fixed-term FT positions — the vault itself has no maturity and no locked
66554
+ // rate. `fixed-term` here claimed both, producing a "fixed" rate with no date
66555
+ // attached to it. The LENDER `TERMMAX_*` is fixed-term; this is not.
66556
+ termmax: "variable-managed",
66557
+ // A PT's implied APY is locked in at purchase and realized only by holding
66558
+ // to maturity — the same promise TermMax's FT makes, reached by a different
66559
+ // mechanism (an AMM discount rather than a quoted curve).
66560
+ pendle: "fixed-term",
66561
+ savings: "variable-managed",
66562
+ lst: "variable-managed",
66563
+ lagoon: "variable-managed",
66564
+ upshift: "variable-managed",
66565
+ yearn: "variable-managed",
66566
+ hypercore: "realized",
66567
+ gmx: "realized"
66568
+ };
66569
+ function resolveExitMode2(provider, meta, tvl, liq) {
66570
+ const declared = str5(meta.withdrawalMode);
66571
+ if (declared) return declared;
66572
+ const fallback = vaultTraits(provider)?.defaultExitMode ?? "instant";
66573
+ if (fallback !== "instant-capped") return fallback;
66574
+ const total = num12(tvl?.totalAssetsFormatted) ?? num12(tvl?.totalAssetsUsd);
66575
+ const available = num12(liq?.liquidityFormatted) ?? num12(liq?.liquidityUsd);
66576
+ if (total === void 0 || available === void 0) return "instant-capped";
66577
+ if (total <= 0) return "instant";
66578
+ return available >= total ? "instant" : "instant-capped";
66579
+ }
66580
+ function earnMarketFromVault(row, chainId, opts = {}) {
66581
+ const provider = str5(row.provider);
66582
+ const address = str5(row.vaultAddress)?.toLowerCase();
66583
+ const underlying = str5(row.underlying)?.toLowerCase();
66584
+ if (!provider || !address || !underlying) return void 0;
66585
+ const meta = row.providerMeta ?? {};
66586
+ const info = row.vaultInfo ?? {};
66587
+ const rates = row.rates ?? {};
66588
+ const tvl = row.tvl ?? {};
66589
+ const liq = row.liquidity ?? {};
66590
+ const shareDecimals = num12(row.decimals) ?? 18;
66591
+ const assetDecimals = num12(row.assetDecimals) ?? num12(row.underlyingInfo?.asset?.decimals) ?? shareDecimals;
66592
+ const toPercent2 = (v) => ratePercent(v, provider, opts.fractionRateProviders);
66593
+ const rewards = toPercent2(rates.rewardsRate);
66594
+ const deposit = toPercent2(rates.depositRate);
66595
+ const base = toPercent2(rates.supplyRate) ?? (deposit !== void 0 && rewards !== void 0 ? deposit - rewards : deposit);
66596
+ const total = toPercent2(rates.totalRate) ?? deposit ?? sum(base, rewards) ?? 0;
66597
+ const rate = {
66598
+ total,
66599
+ base,
66600
+ rewards,
66601
+ // A vault has no separate intrinsic leg — whatever it pays IS the venue's
66602
+ // own yield. Leaving this undefined rendered an empty "Venue APR" on every
66603
+ // vault row, which read as "this vault pays nothing".
66604
+ marketOwn: total,
66605
+ // ...and for the same reason it can never be pass-through.
66606
+ passthrough: false,
66607
+ kind: resolveRateKind(provider, meta),
66608
+ source: RATE_SOURCE[provider] ?? "api",
66609
+ // The curator's cut. Dropped entirely until now, which left the earn row
66610
+ // unable to say why its net rate sits below the gross one — and left the
66611
+ // term sheet built from this row with no fee schedule at all.
66612
+ fee: toPercent2(rates.fee)
66613
+ };
66614
+ const maturity = resolveMaturity(meta);
66615
+ const availability = resolveAvailability(meta, maturity);
66616
+ const exitMode = resolveExitMode2(provider, meta, tvl, liq);
66617
+ const market = {
66618
+ earnUid: buildVaultEarnUid(provider, chainId, address),
66619
+ chainId,
66620
+ venue: vaultVenue(provider),
66621
+ venueKind: "vault",
66622
+ // Curator first (it names the actual operator), then the provider brand.
66623
+ brand: str5(row.curatorName) ?? venueBrand(vaultVenue(provider)),
66624
+ // What the vault is BUILT ON, kept apart from who runs it — see
66625
+ // `resolveEarnIdentity` for why this is not simply provider-vs-brand.
66626
+ ...withCuratorEntity(
66627
+ resolveEarnIdentity(
66628
+ vaultVenue(provider),
66629
+ str5(row.curatorName)
66630
+ ),
66631
+ str5(row.curatorEntity)
66632
+ ),
66633
+ name: str5(info.name) ?? str5(row.displayName) ?? str5(row.name),
66634
+ ref: address,
66635
+ logoURI: str5(info.logoURI) ?? str5(row.underlyingInfo?.asset?.logoURI),
66636
+ asset: {
66637
+ address: underlying,
66638
+ symbol: str5(row.underlyingInfo?.asset?.symbol) ?? "",
66639
+ decimals: assetDecimals,
66640
+ assetGroup: str5(info.assetGroup),
66641
+ priceUsd: num12(row.underlyingInfo?.prices?.priceUsd)
66642
+ },
66643
+ // The vault IS a share token by construction; carry it so a withdraw in
66644
+ // share units can be built without a second lookup.
66645
+ shareToken: {
66646
+ address,
66647
+ symbol: str5(info.symbol) ?? str5(row.symbol) ?? "",
66648
+ decimals: shareDecimals
66649
+ },
66650
+ rate,
66651
+ // The vault origin reports RAW base units + a pre-formatted convenience
66652
+ // field. Carry both; fall back to formatting the raw amount ourselves so
66653
+ // `formatted` — the field consumers sort on — is never silently absent.
66654
+ tvl: amount(
66655
+ tvl.totalAssets,
66656
+ tvl.totalAssetsFormatted,
66657
+ tvl.totalAssetsUsd,
66658
+ assetDecimals
66659
+ ),
66660
+ liquidity: liq.liquidity != null || liq.liquidityUsd != null ? amount(
66661
+ liq.liquidity,
66662
+ liq.liquidityFormatted,
66663
+ liq.liquidityUsd,
66664
+ assetDecimals
66665
+ ) : void 0,
66666
+ depositCapacity: str5(meta.depositCapacity) ?? str5(meta.maxDeposit),
66667
+ maturity,
66668
+ exit: {
66669
+ mode: exitMode,
66670
+ settlement: str5(meta.redemptionType),
66671
+ cooldownSecs: num12(meta.withdrawalCooldownSeconds),
66672
+ feeBps: num12(meta.withdrawFeeBps)
66673
+ },
66674
+ availability,
66675
+ risk: {
66676
+ yieldProfile: yieldProfile(info.yieldProfile),
66677
+ denomination: denomination(info.denomination),
66678
+ // The curated trust classification, where one exists. Typed on `EarnRisk`
66679
+ // since the surface was written and never populated — a tranche's
66680
+ // first-loss position is the term most worth surfacing on a rate list.
66681
+ counterparty: str5(meta.solvency),
66682
+ score: num12(row.rating?.score),
66683
+ label: str5(row.rating?.level),
66684
+ illiquid: isIlliquid({
66685
+ exitMode,
66686
+ tvlUsd: num12(tvl.totalAssetsUsd),
66687
+ liquidityUsd: num12(liq.liquidityUsd)
66688
+ })
66689
+ },
66690
+ // Filled by `capabilities.ts` — kept required on the type so a normalizer
66691
+ // that forgets to stamp them is a compile error, not an empty CTA.
66692
+ capabilities: [],
66693
+ providerMeta: row.providerMeta
66694
+ };
66695
+ return market;
66696
+ }
66697
+ function ratePercent(value, provider, fractionProviders = FRACTION_RATE_PROVIDERS) {
66698
+ const n = num12(value);
66699
+ if (n === void 0) return void 0;
66700
+ return fractionProviders.has(provider) ? n * 100 : n;
66701
+ }
66702
+ function implausibleRatePercent(percent) {
66703
+ return !Number.isFinite(percent) || percent < 0 || percent > 1e4;
66704
+ }
66705
+ function resolveRateKind(provider, meta) {
66706
+ if (meta.navOracle || meta.solvency === "nav-attested") return "nav-accrual";
66707
+ return RATE_KIND[provider] ?? "variable-managed";
66708
+ }
66709
+ function resolveAvailability(meta, maturity) {
66710
+ const isMintable = meta.isMintable;
66711
+ const capacity = str5(meta.depositCapacity) ?? str5(meta.maxDeposit);
66712
+ const capFull = capacity === "0";
66713
+ let gating;
66714
+ let reason;
66715
+ if (isMatured(maturity)) {
66716
+ gating = "matured";
66717
+ reason = "This market has reached maturity";
66718
+ } else if (isMintable === false) {
66719
+ gating = "allowlist-contract";
66720
+ reason = "Deposits are permissioned for this vault";
66721
+ } else if (capFull) {
66722
+ gating = "cap-full";
66723
+ reason = "Deposit cap is full";
66724
+ } else if (meta.paused === true) {
66725
+ gating = "paused";
66726
+ reason = "Vault is paused";
66727
+ }
66728
+ return {
66729
+ canDeposit: gating === void 0,
66730
+ // Exits stay open under a deposit cap, a mint allowlist or a maturity —
66731
+ // every wind-down we have integrated (Lista, dTRINITY/Sonic) keeps the
66732
+ // door open outward, and a matured bond is precisely the case where the
66733
+ // holder still needs out. An explicit pause is the one thing that shuts
66734
+ // both.
66735
+ canWithdraw: meta.paused !== true,
66736
+ gating,
66737
+ reason
66738
+ };
66739
+ }
66740
+ function resolveMaturity(meta) {
66741
+ const expiry = num12(meta.expiry) ?? num12(meta.maturity);
66742
+ if (expiry === void 0 || expiry <= 0) return void 0;
66743
+ const nowSecs = Math.floor(Date.now() / 1e3);
66744
+ return {
66745
+ kind: "fixed-date",
66746
+ maturity: expiry,
66747
+ maturityIso: str5(meta.expiryIso) ?? new Date(expiry * 1e3).toISOString(),
66748
+ // A SNAPSHOT — a cached listing ages, so a countdown must be recomputed
66749
+ // from `maturity` rather than ticked down from this.
66750
+ secondsToMaturity: Math.max(expiry - nowSecs, 0),
66751
+ // A PT simply stops earning: it redeems for the underlying at par and
66752
+ // sits there. No penalty, no liquidation, no auto-roll.
66753
+ atMaturity: str5(meta.atMaturity) ?? "stops-earning"
66754
+ };
66755
+ }
66756
+ function isMatured(maturity) {
66757
+ if (!maturity?.maturity) return false;
66758
+ return maturity.maturity <= Math.floor(Date.now() / 1e3);
66759
+ }
66760
+ function amount(raw, formatted, usd, decimals) {
66761
+ const rawStr = raw != null ? String(raw) : void 0;
66762
+ return {
66763
+ raw: rawStr,
66764
+ formatted: num12(formatted) ?? formatRaw(rawStr, decimals),
66765
+ usd: num12(usd)
66766
+ };
66767
+ }
66768
+ function withCuratorEntity(id, entity) {
66769
+ if (!id.curator || !entity) return id;
66770
+ return { ...id, curator: { ...id.curator, entity } };
66771
+ }
66772
+ function sum(a, b) {
66773
+ if (a === void 0 && b === void 0) return void 0;
66774
+ return (a ?? 0) + (b ?? 0);
66775
+ }
66247
66776
 
66248
66777
  // src/terms/vault/input.ts
66249
- var num12 = (v) => {
66778
+ var num13 = (v) => {
66250
66779
  if (typeof v === "number") return Number.isFinite(v) ? v : void 0;
66251
66780
  if (typeof v === "string" && v.trim() !== "") {
66252
66781
  const n = Number(v);
@@ -66254,7 +66783,7 @@ var num12 = (v) => {
66254
66783
  }
66255
66784
  return void 0;
66256
66785
  };
66257
- var str5 = (v) => typeof v === "string" && v.trim() !== "" ? v : void 0;
66786
+ var str6 = (v) => typeof v === "string" && v.trim() !== "" ? v : void 0;
66258
66787
  var bool2 = (v) => typeof v === "boolean" ? v : void 0;
66259
66788
  var fromRaw = (raw, decimals) => {
66260
66789
  const s = raw == null ? void 0 : String(raw);
@@ -66262,69 +66791,86 @@ var fromRaw = (raw, decimals) => {
66262
66791
  const n = Number(s) / 10 ** decimals;
66263
66792
  return Number.isFinite(n) ? n : void 0;
66264
66793
  };
66794
+ function sdkRates(row, provider) {
66795
+ if (!SDK_FRACTION_RATE_PROVIDERS.has(provider)) {
66796
+ return {
66797
+ supplyRate: num13(row.supplyRate),
66798
+ rewardsRate: num13(row.rewardsRate),
66799
+ totalRate: num13(row.depositRate)
66800
+ };
66801
+ }
66802
+ const pct2 = (v) => {
66803
+ const n = num13(v);
66804
+ return n === void 0 ? void 0 : n * 100;
66805
+ };
66806
+ return {
66807
+ // GMX splits fee APY from incentive APR; HyperCore reports one number.
66808
+ supplyRate: pct2(row.baseApy ?? row.apr),
66809
+ rewardsRate: pct2(row.bonusApr),
66810
+ totalRate: pct2(row.apy ?? row.apr)
66811
+ };
66812
+ }
66265
66813
  function toVaultTermInput(vault, provider, chainId) {
66266
66814
  const row = vault;
66267
- const address = str5(row.address)?.toLowerCase();
66815
+ const address = str6(row.address)?.toLowerCase();
66268
66816
  if (!address) return void 0;
66269
- const assetDecimals = num12(row.assetDecimals) ?? num12(row.decimals);
66817
+ const assetDecimals = num13(row.assetDecimals) ?? num13(row.decimals);
66270
66818
  const asset = row.asset;
66271
66819
  return {
66272
66820
  provider,
66273
66821
  chainId,
66274
66822
  address,
66275
66823
  vaultUid: `vault.${provider}:${chainId}:${address}`,
66276
- name: str5(row.displayName) ?? str5(row.name),
66277
- brand: str5(row.brand),
66278
- curatorName: str5(row.curatorName),
66279
- description: str5(row.description),
66824
+ name: str6(row.displayName) ?? str6(row.name),
66825
+ brand: str6(row.brand),
66826
+ curatorName: str6(row.curatorName),
66827
+ description: str6(row.description),
66280
66828
  asset: {
66281
66829
  chainId,
66282
- address: str5(row.underlying)?.toLowerCase() ?? "",
66283
- symbol: str5(asset?.symbol),
66284
- name: str5(asset?.name),
66830
+ address: str6(row.underlying)?.toLowerCase() ?? "",
66831
+ symbol: str6(asset?.symbol),
66832
+ name: str6(asset?.name),
66285
66833
  decimals: assetDecimals,
66286
- assetGroup: str5(asset?.assetGroup),
66287
- logoURI: str5(asset?.logoURI)
66834
+ assetGroup: str6(asset?.assetGroup),
66835
+ logoURI: str6(asset?.logoURI)
66288
66836
  },
66289
- supplyRate: num12(row.supplyRate),
66290
- rewardsRate: num12(row.rewardsRate),
66291
- totalRate: num12(row.depositRate),
66837
+ ...sdkRates(row, provider),
66292
66838
  isForwardApr: bool2(row.isForwardApr),
66293
- aprWindow: str5(row.aprWindow),
66839
+ aprWindow: str6(row.aprWindow),
66294
66840
  // GMX / HyperCore / Pendle report USD only and set the token-denominated
66295
66841
  // fields to their USD figure — `totalAssetsFormatted` is the cross-provider
66296
66842
  // magnitude either way, so prefer it over re-deriving from raw.
66297
- totalAssets: num12(row.totalAssetsFormatted) ?? fromRaw(row.totalAssets, assetDecimals),
66298
- totalAssetsUsd: num12(row.totalAssetsUsd) ?? num12(row.tvlUsd),
66299
- liquidity: num12(row.liquidityFormatted) ?? fromRaw(row.liquidity, assetDecimals),
66300
- liquidityUsd: num12(row.liquidityUsd),
66301
- instantLiquidityRatio: num12(row.instantLiquidityRatio),
66843
+ totalAssets: num13(row.totalAssetsFormatted) ?? fromRaw(row.totalAssets, assetDecimals),
66844
+ totalAssetsUsd: num13(row.totalAssetsUsd) ?? num13(row.tvlUsd),
66845
+ liquidity: num13(row.liquidityFormatted) ?? fromRaw(row.liquidity, assetDecimals),
66846
+ liquidityUsd: num13(row.liquidityUsd),
66847
+ instantLiquidityRatio: num13(row.instantLiquidityRatio),
66302
66848
  totalBorrowed: fromRaw(row.totalBorrowed, assetDecimals),
66303
66849
  expectedLiquidity: fromRaw(row.expectedLiquidity, assetDecimals),
66304
- withdrawalMode: str5(row.withdrawalMode),
66305
- withdrawalCooldownSeconds: num12(row.withdrawalCooldownSeconds),
66306
- withdrawFeeBps: num12(row.withdrawFeeBps),
66307
- fee: num12(row.fee),
66308
- swapFeeRate: num12(row.feeRate),
66309
- redemptionDiscountBps: num12(row.redemptionDiscountBps),
66850
+ withdrawalMode: str6(row.withdrawalMode),
66851
+ withdrawalCooldownSeconds: num13(row.withdrawalCooldownSeconds),
66852
+ withdrawFeeBps: num13(row.withdrawFeeBps),
66853
+ fee: num13(row.fee),
66854
+ swapFeeRate: num13(row.feeRate),
66855
+ redemptionDiscountBps: num13(row.redemptionDiscountBps),
66310
66856
  instantRedeemEnabled: bool2(row.instantRedeemEnabled),
66311
66857
  isMintable: bool2(row.isMintable),
66312
- depositCapacity: str5(row.depositCapacity),
66313
- supplyCap: str5(row.supplyCap),
66858
+ depositCapacity: str6(row.depositCapacity),
66859
+ supplyCap: str6(row.supplyCap),
66314
66860
  paused: bool2(row.isPaused),
66315
66861
  depositsPaused: bool2(row.isDepositPaused),
66316
66862
  withdrawalsPaused: bool2(row.isWithdrawalPaused),
66317
66863
  isClosed: bool2(row.isClosed),
66318
66864
  whitelisted: bool2(row.whitelisted),
66319
- expiry: num12(row.expiry),
66320
- timelock: num12(row.timelock),
66321
- owner: str5(row.owner),
66322
- curator: str5(row.curator),
66323
- guardian: str5(row.guardian),
66324
- feeRecipient: str5(row.feeRecipient),
66325
- solvency: str5(row.solvency),
66326
- navOracle: str5(row.navOracle),
66327
- yieldProfile: str5(row.yieldProfile),
66865
+ expiry: num13(row.expiry),
66866
+ timelock: num13(row.timelock),
66867
+ owner: str6(row.owner),
66868
+ curator: str6(row.curator),
66869
+ guardian: str6(row.guardian),
66870
+ feeRecipient: str6(row.feeRecipient),
66871
+ solvency: str6(row.solvency),
66872
+ navOracle: str6(row.navOracle),
66873
+ yieldProfile: str6(row.yieldProfile),
66328
66874
  exposures: Array.isArray(row.exposures) ? row.exposures : void 0
66329
66875
  };
66330
66876
  }
@@ -66341,7 +66887,7 @@ function vaultTermInputFromEarnMarket(m) {
66341
66887
  name: m.name,
66342
66888
  brand: m.brand,
66343
66889
  curatorName: m.brand,
66344
- description: str5(meta.description),
66890
+ description: str6(meta.description),
66345
66891
  asset: {
66346
66892
  chainId: m.chainId,
66347
66893
  address: m.asset.address,
@@ -66354,46 +66900,56 @@ function vaultTermInputFromEarnMarket(m) {
66354
66900
  rewardsRate: m.rate.rewards,
66355
66901
  totalRate: m.rate.total,
66356
66902
  isForwardApr: bool2(meta.isForwardApr),
66357
- aprWindow: str5(meta.aprWindow),
66903
+ aprWindow: str6(meta.aprWindow),
66358
66904
  totalAssets: m.tvl.formatted,
66359
66905
  totalAssetsUsd: m.tvl.usd,
66360
66906
  liquidity: m.liquidity?.formatted,
66361
66907
  liquidityUsd: m.liquidity?.usd,
66362
- instantLiquidityRatio: num12(meta.instantLiquidityRatio),
66363
- totalBorrowed: num12(meta.totalBorrowed),
66364
- expectedLiquidity: num12(meta.expectedLiquidity),
66908
+ instantLiquidityRatio: num13(meta.instantLiquidityRatio),
66909
+ totalBorrowed: num13(meta.totalBorrowed),
66910
+ expectedLiquidity: num13(meta.expectedLiquidity),
66365
66911
  withdrawalMode: m.exit.mode,
66366
66912
  withdrawalCooldownSeconds: m.exit.cooldownSecs,
66367
66913
  withdrawFeeBps: m.exit.feeBps,
66368
66914
  fee: m.rate.fee,
66369
- swapFeeRate: num12(meta.feeRate),
66370
- redemptionDiscountBps: num12(meta.redemptionDiscountBps),
66915
+ swapFeeRate: num13(meta.feeRate),
66916
+ redemptionDiscountBps: num13(meta.redemptionDiscountBps),
66371
66917
  instantRedeemEnabled: bool2(meta.instantRedeemEnabled),
66372
66918
  // `canDeposit` already folds in the cap, the pause and the gate, so it is
66373
66919
  // the authoritative answer — but the REASON is what a disabled CTA renders,
66374
66920
  // and that only survives in the raw fields.
66375
66921
  isMintable: m.availability.canDeposit ? void 0 : false,
66376
66922
  depositCapacity: m.depositCapacity,
66377
- supplyCap: str5(meta.supplyCap),
66923
+ supplyCap: str6(meta.supplyCap),
66378
66924
  paused: m.availability.gating === "paused" ? true : void 0,
66379
66925
  withdrawalsPaused: m.availability.canWithdraw ? void 0 : true,
66380
66926
  isClosed: bool2(meta.isClosed),
66381
66927
  whitelisted: bool2(meta.whitelisted),
66382
66928
  expiry: m.maturity?.maturity,
66383
- timelock: num12(meta.timelock),
66384
- owner: str5(meta.owner),
66385
- curator: str5(meta.curator),
66386
- guardian: str5(meta.guardian),
66387
- feeRecipient: str5(meta.feeRecipient),
66929
+ timelock: num13(meta.timelock),
66930
+ owner: str6(meta.owner),
66931
+ curator: str6(meta.curator),
66932
+ guardian: str6(meta.guardian),
66933
+ feeRecipient: str6(meta.feeRecipient),
66388
66934
  solvency: m.risk?.counterparty,
66389
- navOracle: str5(meta.navOracle),
66935
+ navOracle: str6(meta.navOracle),
66390
66936
  yieldProfile: m.risk?.yieldProfile,
66391
66937
  exposures: m.refs?.exposures
66392
66938
  };
66393
66939
  }
66940
+ function originRates(rates) {
66941
+ const supply = num13(rates.supplyRate);
66942
+ const rewards = num13(rates.rewardsRate);
66943
+ const deposit = num13(rates.depositRate);
66944
+ return {
66945
+ supplyRate: supply ?? (deposit !== void 0 && rewards !== void 0 ? deposit - rewards : deposit),
66946
+ rewardsRate: rewards,
66947
+ totalRate: num13(rates.totalRate) ?? deposit
66948
+ };
66949
+ }
66394
66950
  function vaultTermInputFromSourceRow(row, chainId) {
66395
- const provider = str5(row.provider);
66396
- const address = str5(row.vaultAddress)?.toLowerCase();
66951
+ const provider = str6(row.provider);
66952
+ const address = str6(row.vaultAddress)?.toLowerCase();
66397
66953
  if (!provider || !address) return void 0;
66398
66954
  const meta = row.providerMeta ?? {};
66399
66955
  const rates = row.rates ?? {};
@@ -66401,60 +66957,58 @@ function vaultTermInputFromSourceRow(row, chainId) {
66401
66957
  const liq = row.liquidity ?? {};
66402
66958
  const info = row.vaultInfo ?? {};
66403
66959
  const assetInfo = row.underlyingInfo?.asset;
66404
- const assetDecimals = num12(row.assetDecimals) ?? num12(assetInfo?.decimals) ?? num12(row.decimals);
66960
+ const assetDecimals = num13(row.assetDecimals) ?? num13(assetInfo?.decimals) ?? num13(row.decimals);
66405
66961
  return {
66406
66962
  provider,
66407
66963
  chainId,
66408
66964
  address,
66409
66965
  vaultUid: `vault.${provider}:${chainId}:${address}`,
66410
- name: str5(info.name) ?? str5(row.displayName) ?? str5(row.name),
66411
- brand: str5(row.curatorName) ?? str5(meta.brand),
66412
- curatorName: str5(row.curatorName),
66413
- description: str5(meta.description),
66966
+ name: str6(info.name) ?? str6(row.displayName) ?? str6(row.name),
66967
+ brand: str6(row.curatorName) ?? str6(meta.brand),
66968
+ curatorName: str6(row.curatorName),
66969
+ description: str6(meta.description),
66414
66970
  asset: {
66415
66971
  chainId,
66416
- address: str5(row.underlying)?.toLowerCase() ?? "",
66417
- symbol: str5(assetInfo?.symbol),
66972
+ address: str6(row.underlying)?.toLowerCase() ?? "",
66973
+ symbol: str6(assetInfo?.symbol),
66418
66974
  decimals: assetDecimals,
66419
- assetGroup: str5(info.assetGroup),
66420
- logoURI: str5(assetInfo?.logoURI)
66975
+ assetGroup: str6(info.assetGroup),
66976
+ logoURI: str6(assetInfo?.logoURI)
66421
66977
  },
66422
- supplyRate: num12(rates.depositRate) ?? num12(rates.supplyRate),
66423
- rewardsRate: num12(rates.rewardsRate),
66424
- totalRate: num12(rates.totalRate),
66978
+ ...originRates(rates),
66425
66979
  isForwardApr: bool2(meta.isForwardApr),
66426
- aprWindow: str5(meta.aprWindow),
66427
- totalAssets: num12(tvl.totalAssetsFormatted) ?? fromRaw(tvl.totalAssets, assetDecimals),
66428
- totalAssetsUsd: num12(tvl.totalAssetsUsd),
66429
- liquidity: num12(liq.liquidityFormatted) ?? fromRaw(liq.liquidity, assetDecimals),
66430
- liquidityUsd: num12(liq.liquidityUsd),
66431
- instantLiquidityRatio: num12(meta.instantLiquidityRatio),
66980
+ aprWindow: str6(meta.aprWindow),
66981
+ totalAssets: num13(tvl.totalAssetsFormatted) ?? fromRaw(tvl.totalAssets, assetDecimals),
66982
+ totalAssetsUsd: num13(tvl.totalAssetsUsd),
66983
+ liquidity: num13(liq.liquidityFormatted) ?? fromRaw(liq.liquidity, assetDecimals),
66984
+ liquidityUsd: num13(liq.liquidityUsd),
66985
+ instantLiquidityRatio: num13(meta.instantLiquidityRatio),
66432
66986
  totalBorrowed: fromRaw(meta.totalBorrowed, assetDecimals),
66433
66987
  expectedLiquidity: fromRaw(meta.expectedLiquidity, assetDecimals),
66434
- withdrawalMode: str5(meta.withdrawalMode),
66435
- withdrawalCooldownSeconds: num12(meta.withdrawalCooldownSeconds),
66436
- withdrawFeeBps: num12(meta.withdrawFeeBps),
66437
- fee: num12(rates.fee),
66438
- swapFeeRate: num12(meta.feeRate),
66439
- redemptionDiscountBps: num12(meta.redemptionDiscountBps),
66988
+ withdrawalMode: str6(meta.withdrawalMode),
66989
+ withdrawalCooldownSeconds: num13(meta.withdrawalCooldownSeconds),
66990
+ withdrawFeeBps: num13(meta.withdrawFeeBps),
66991
+ fee: num13(rates.fee),
66992
+ swapFeeRate: num13(meta.feeRate),
66993
+ redemptionDiscountBps: num13(meta.redemptionDiscountBps),
66440
66994
  instantRedeemEnabled: bool2(meta.instantRedeemEnabled),
66441
66995
  isMintable: bool2(meta.isMintable),
66442
- depositCapacity: str5(meta.depositCapacity) ?? str5(meta.maxDeposit),
66443
- supplyCap: str5(meta.supplyCap),
66996
+ depositCapacity: str6(meta.depositCapacity) ?? str6(meta.maxDeposit),
66997
+ supplyCap: str6(meta.supplyCap),
66444
66998
  paused: bool2(meta.paused) ?? bool2(meta.isPaused),
66445
66999
  depositsPaused: bool2(meta.isDepositPaused),
66446
67000
  withdrawalsPaused: bool2(meta.isWithdrawalPaused),
66447
67001
  isClosed: bool2(meta.isClosed),
66448
67002
  whitelisted: bool2(meta.whitelisted),
66449
- expiry: num12(meta.expiry) ?? num12(meta.maturity),
66450
- timelock: num12(meta.timelock),
66451
- owner: str5(meta.owner),
66452
- curator: str5(meta.curator),
66453
- guardian: str5(meta.guardian),
66454
- feeRecipient: str5(meta.feeRecipient),
66455
- solvency: str5(meta.solvency),
66456
- navOracle: str5(meta.navOracle),
66457
- yieldProfile: str5(info.yieldProfile),
67003
+ expiry: num13(meta.expiry) ?? num13(meta.maturity),
67004
+ timelock: num13(meta.timelock),
67005
+ owner: str6(meta.owner),
67006
+ curator: str6(meta.curator),
67007
+ guardian: str6(meta.guardian),
67008
+ feeRecipient: str6(meta.feeRecipient),
67009
+ solvency: str6(meta.solvency),
67010
+ navOracle: str6(meta.navOracle),
67011
+ yieldProfile: str6(info.yieldProfile),
66458
67012
  exposures: Array.isArray(row.exposures) ? row.exposures : Array.isArray(meta.exposures) ? meta.exposures : void 0
66459
67013
  };
66460
67014
  }
@@ -67252,7 +67806,7 @@ async function fetchTokenBalances(chainId, account, tokens, options = {}) {
67252
67806
  }
67253
67807
 
67254
67808
  // src/terms/input.ts
67255
- var num13 = (v) => {
67809
+ var num14 = (v) => {
67256
67810
  if (v == null) return void 0;
67257
67811
  const n = typeof v === "string" ? Number(v) : v;
67258
67812
  return Number.isFinite(n) ? n : void 0;
@@ -67283,12 +67837,12 @@ function toTermSheetInput(row, ctx = {}) {
67283
67837
  {
67284
67838
  category: v?.category ?? k,
67285
67839
  label: v?.label,
67286
- borrowCollateralFactor: num13(v?.borrowCollateralFactor),
67287
- collateralFactor: num13(v?.collateralFactor),
67288
- borrowFactor: num13(v?.borrowFactor),
67289
- liquidationPenalty: num13(v?.liquidationPenalty),
67290
- closeFactor: num13(v?.closeFactor),
67291
- targetHealthFactor: num13(v?.targetHealthFactor),
67840
+ borrowCollateralFactor: num14(v?.borrowCollateralFactor),
67841
+ collateralFactor: num14(v?.collateralFactor),
67842
+ borrowFactor: num14(v?.borrowFactor),
67843
+ liquidationPenalty: num14(v?.liquidationPenalty),
67844
+ closeFactor: num14(v?.closeFactor),
67845
+ targetHealthFactor: num14(v?.targetHealthFactor),
67292
67846
  collateralDisabled: v?.collateralDisabled === true,
67293
67847
  debtDisabled: v?.debtDisabled === true
67294
67848
  }
@@ -67296,11 +67850,11 @@ function toTermSheetInput(row, ctx = {}) {
67296
67850
  ) : void 0;
67297
67851
  const rewards = pick2(row, "rewards")?.map((r) => ({
67298
67852
  asset: r?.asset,
67299
- depositRate: num13(r?.depositRate),
67300
- variableBorrowRate: num13(r?.variableBorrowRate),
67301
- stableBorrowRate: num13(r?.stableBorrowRate),
67853
+ depositRate: num14(r?.depositRate),
67854
+ variableBorrowRate: num14(r?.variableBorrowRate),
67855
+ stableBorrowRate: num14(r?.stableBorrowRate),
67302
67856
  kind: r?.kind,
67303
- endsAt: num13(r?.endsAt),
67857
+ endsAt: num14(r?.endsAt),
67304
67858
  claim: r?.claim
67305
67859
  }));
67306
67860
  return {
@@ -67313,29 +67867,29 @@ function toTermSheetInput(row, ctx = {}) {
67313
67867
  "underlyingInfo.asset"
67314
67868
  ),
67315
67869
  underlying: pick2(row, "underlying"),
67316
- decimals: num13(pick2(row, "decimals")),
67317
- depositRate: num13(pick2(row, "depositRate")),
67318
- variableBorrowRate: num13(pick2(row, "variableBorrowRate")),
67319
- stableBorrowRate: num13(pick2(row, "stableBorrowRate")),
67320
- intrinsicYield: num13(pick2(row, "intrinsicYield")),
67870
+ decimals: num14(pick2(row, "decimals")),
67871
+ depositRate: num14(pick2(row, "depositRate")),
67872
+ variableBorrowRate: num14(pick2(row, "variableBorrowRate")),
67873
+ stableBorrowRate: num14(pick2(row, "stableBorrowRate")),
67874
+ intrinsicYield: num14(pick2(row, "intrinsicYield")),
67321
67875
  rewards,
67322
67876
  rateModel: pick2(row, "rateModel"),
67323
- originationFee: num13(pick2(row, "originationFee")),
67324
- totalDeposits: num13(pick2(row, "totalDeposits")),
67325
- totalDebt: num13(pick2(row, "totalDebt")),
67326
- totalDebtStable: num13(pick2(row, "totalDebtStable")),
67327
- totalLiquidity: num13(pick2(row, "totalLiquidity")),
67328
- borrowLiquidity: num13(pick2(row, "borrowLiquidity")),
67329
- totalDepositsUsd: num13(pick2(row, "totalDepositsUSD", "totalDepositsUsd")),
67330
- totalDebtUsd: num13(pick2(row, "totalDebtUSD", "totalDebtUsd")),
67331
- totalLiquidityUsd: num13(pick2(row, "totalLiquidityUSD", "totalLiquidityUsd")),
67332
- utilization: num13(pick2(row, "utilization")),
67333
- irmTotalDeposits: num13(pick2(row, "irmTotalDeposits")),
67334
- irmTotalDebt: num13(pick2(row, "irmTotalDebt")),
67335
- lockupRatio: num13(pick2(row, "lockupRatio")),
67877
+ originationFee: num14(pick2(row, "originationFee")),
67878
+ totalDeposits: num14(pick2(row, "totalDeposits")),
67879
+ totalDebt: num14(pick2(row, "totalDebt")),
67880
+ totalDebtStable: num14(pick2(row, "totalDebtStable")),
67881
+ totalLiquidity: num14(pick2(row, "totalLiquidity")),
67882
+ borrowLiquidity: num14(pick2(row, "borrowLiquidity")),
67883
+ totalDepositsUsd: num14(pick2(row, "totalDepositsUSD", "totalDepositsUsd")),
67884
+ totalDebtUsd: num14(pick2(row, "totalDebtUSD", "totalDebtUsd")),
67885
+ totalLiquidityUsd: num14(pick2(row, "totalLiquidityUSD", "totalLiquidityUsd")),
67886
+ utilization: num14(pick2(row, "utilization")),
67887
+ irmTotalDeposits: num14(pick2(row, "irmTotalDeposits")),
67888
+ irmTotalDebt: num14(pick2(row, "irmTotalDebt")),
67889
+ lockupRatio: num14(pick2(row, "lockupRatio")),
67336
67890
  minBorrow: pick2(row, "minBorrow", "caps.minBorrow") ?? void 0,
67337
- supplyCap: num13(pick2(row, "supplyCap", "caps.supplyCap")),
67338
- borrowCap: num13(pick2(row, "borrowCap", "caps.borrowCap")),
67891
+ supplyCap: num14(pick2(row, "supplyCap", "caps.supplyCap")),
67892
+ borrowCap: num14(pick2(row, "borrowCap", "caps.borrowCap")),
67339
67893
  debtCeiling: pick2(row, "debtCeiling", "caps.debtCeiling"),
67340
67894
  isActive: pick2(row, "isActive", "flags.isActive"),
67341
67895
  isFrozen: pick2(row, "isFrozen", "flags.isFrozen"),
@@ -67361,8 +67915,8 @@ function toTermSheetInput(row, ctx = {}) {
67361
67915
  "flags.variableBorrowDisabled"
67362
67916
  ),
67363
67917
  config,
67364
- closeFactor: num13(pick2(row, "closeFactor")),
67365
- targetHealthFactor: num13(pick2(row, "targetHealthFactor")),
67918
+ closeFactor: num14(pick2(row, "closeFactor")),
67919
+ targetHealthFactor: num14(pick2(row, "targetHealthFactor")),
67366
67920
  fixedTerm: pick2(row, "fixedTerm") ?? ctx.fixedTerm,
67367
67921
  terms: pick2(row, "terms"),
67368
67922
  market: resolveMarketDescriptors(row, ctx.market)
@@ -69071,7 +69625,7 @@ function validateTermSheet(sheet) {
69071
69625
  if (g.powers?.length)
69072
69626
  fail("immutable-powers", "immutable governance must not carry powers");
69073
69627
  }
69074
- if (g.timelockSecs && g.controllerKind && g.controllerKind !== "TIMELOCK")
69628
+ if (g.timelockSecs && g.controllerKind && g.controllerKind !== "TIMELOCK" && g.timelockSource !== "on-chain")
69075
69629
  fail(
69076
69630
  "timelock-without-timelock-root",
69077
69631
  `timelockSecs set but controllerKind is ${g.controllerKind}`
@@ -69089,466 +69643,6 @@ function validateTermSheets(sheets) {
69089
69643
  return sheets.flatMap((s) => validateTermSheet(s));
69090
69644
  }
69091
69645
 
69092
- // src/earn/labels.ts
69093
- var VENUE_KIND_LABELS = {
69094
- lending: "Lending markets",
69095
- vault: "Vaults"
69096
- };
69097
- var VENUE_KIND_DESCRIPTIONS = {
69098
- lending: "Supply into a lending market. Same-block exit, bounded by liquidity.",
69099
- vault: "Deposit into a yield vault. Exit terms vary per vault."
69100
- };
69101
- var EXIT_MODE_LABELS = {
69102
- instant: "Instant",
69103
- "instant-capped": "Instant (capped)",
69104
- "instant-or-queued": "Instant or queue",
69105
- "fee-or-queued": "Fee or queue",
69106
- "fixed-cooldown": "Cooldown",
69107
- queued: "Queued",
69108
- "request-based": "Request",
69109
- "market-sale": "Market sale",
69110
- "at-maturity": "At maturity",
69111
- "off-chain": "Off-chain",
69112
- "dex-only": "DEX only"
69113
- };
69114
- var EXIT_MODE_DESCRIPTIONS = {
69115
- instant: "Withdraw any time.",
69116
- "instant-capped": "Withdraw up to the available liquidity.",
69117
- "instant-or-queued": "Withdraw instantly, or queue for the rest.",
69118
- "fee-or-queued": "Instant exit for a fee, or queue for free.",
69119
- "fixed-cooldown": "Request, wait out a cooldown, then claim.",
69120
- queued: "Withdrawals are queued.",
69121
- "request-based": "Withdrawals need a request and a later claim.",
69122
- "market-sale": "Exit by selling the position on a market.",
69123
- "at-maturity": "Locked until maturity.",
69124
- "off-chain": "Exit is settled off-chain.",
69125
- "dex-only": "Exit only by selling on a DEX."
69126
- };
69127
- var ACTION_LABELS = {
69128
- deposit: "Deposit",
69129
- withdraw: "Withdraw",
69130
- "request-withdraw": "Request withdrawal",
69131
- claim: "Claim",
69132
- cancel: "Cancel request"
69133
- };
69134
- var GATING_LABELS = {
69135
- "allowlist-contract": "Permissioned",
69136
- kyc: "KYC required",
69137
- "cap-full": "Cap full",
69138
- paused: "Paused",
69139
- frozen: "Frozen",
69140
- "collateral-only": "No yield",
69141
- matured: "Matured"
69142
- };
69143
- var RATE_KIND_LABELS = {
69144
- "variable-curve": "Variable (utilization)",
69145
- "variable-managed": "Variable (managed)",
69146
- "user-set": "Borrower-set",
69147
- "fixed-term": "Fixed term",
69148
- "fixed-open": "Fixed",
69149
- "zero-interest": "Interest-free",
69150
- prepaid: "Prepaid",
69151
- "nav-accrual": "NAV accrual",
69152
- none: "No rate"
69153
- };
69154
- var RATE_SOURCE_LABELS = {
69155
- chain: "On-chain",
69156
- api: "Protocol API",
69157
- oracle: "Oracle",
69158
- realized: "Realized"
69159
- };
69160
- var VENUE_BRANDS = {
69161
- MORPHO_BLUE: "Morpho Blue",
69162
- MORPHO_MIDNIGHT: "Morpho Midnight",
69163
- FLUID: "Fluid",
69164
- GEARBOX_V3: "Gearbox V3",
69165
- AAVE_V4: "Aave V4",
69166
- AAVE_V3: "Aave V3",
69167
- AAVE_V2: "Aave V2",
69168
- SKY: "Sky",
69169
- USDD: "USDD",
69170
- LIQUITY_V2: "Liquity V2",
69171
- SILO_V2: "Silo V2",
69172
- SILO_V3: "Silo V3",
69173
- EXACTLY: "Exactly",
69174
- TELLER: "Teller",
69175
- TERM_FINANCE: "Term Finance",
69176
- TERMMAX: "TermMax",
69177
- LLAMALEND: "LlamaLend",
69178
- CURVANCE: "Curvance",
69179
- INVERSE: "Inverse",
69180
- FRANKENCOIN: "Frankencoin",
69181
- RIVER: "River",
69182
- RESUPPLY: "Resupply",
69183
- TANGENT: "Tangent",
69184
- DOLOMITE: "Dolomite",
69185
- LISTA_DAO: "Lista",
69186
- FLUX_FINANCE: "Flux",
69187
- COMPOUND_V2: "Compound V2",
69188
- COMPOUND_V3: "Compound V3",
69189
- EULER_V2: "Euler V2",
69190
- INIT: "Init"
69191
- };
69192
- var VAULT_PROVIDER_BRANDS = {
69193
- fluid: "Fluid",
69194
- gearbox: "Gearbox",
69195
- morpho: "Morpho",
69196
- lista: "Lista",
69197
- silo: "Silo",
69198
- "euler-earn": "Euler",
69199
- termmax: "TermMax",
69200
- lst: "Liquid staking",
69201
- savings: "Savings",
69202
- lagoon: "Lagoon",
69203
- "aave-earn": "Aave",
69204
- upshift: "Upshift",
69205
- yearn: "Yearn",
69206
- hypercore: "HyperLiquid",
69207
- gmx: "GMX",
69208
- pendle: "Pendle"
69209
- };
69210
- function isInstanceSegment(seg) {
69211
- if (/^\d+$/.test(seg)) return true;
69212
- if (/^0X[0-9A-F]+$/i.test(seg)) return true;
69213
- return seg.length >= 8 && /^[0-9A-F]+$/i.test(seg);
69214
- }
69215
- function venueBrand(venue) {
69216
- if (venue.startsWith("vault.")) {
69217
- const provider = venue.slice("vault.".length);
69218
- return VAULT_PROVIDER_BRANDS[provider] ?? provider;
69219
- }
69220
- const segments = venue.split("_");
69221
- const cut = segments.findIndex(isInstanceSegment);
69222
- const family = (cut > 0 ? segments.slice(0, cut) : segments).join("_");
69223
- if (VENUE_BRANDS[family]) return VENUE_BRANDS[family];
69224
- let best;
69225
- for (const key3 of Object.keys(VENUE_BRANDS)) {
69226
- if (family.startsWith(key3) && (!best || key3.length > best.length))
69227
- best = key3;
69228
- }
69229
- return best ? VENUE_BRANDS[best] : family;
69230
- }
69231
- var EARN_LABELS = {
69232
- venueKind: VENUE_KIND_LABELS,
69233
- exitMode: EXIT_MODE_LABELS,
69234
- action: ACTION_LABELS,
69235
- gating: GATING_LABELS,
69236
- rateKind: RATE_KIND_LABELS,
69237
- rateSource: RATE_SOURCE_LABELS
69238
- };
69239
- var EARN_DESCRIPTIONS = {
69240
- venueKind: VENUE_KIND_DESCRIPTIONS,
69241
- exitMode: EXIT_MODE_DESCRIPTIONS
69242
- };
69243
- function earnLabel(dimension, key3) {
69244
- return EARN_LABELS[dimension][key3] ?? key3;
69245
- }
69246
- function earnDescription(dimension, key3) {
69247
- return EARN_DESCRIPTIONS[dimension][key3];
69248
- }
69249
- function earnMarketLabel(input) {
69250
- const asset = input.assetSymbol?.trim();
69251
- if (!asset) return input.fallbackName ?? "";
69252
- const collaterals = (input.collateralSymbols ?? []).map((c) => c?.trim()).filter((c) => !!c);
69253
- const distinct = [...new Set(collaterals)];
69254
- if (distinct.length === 1) return `${asset} \xB7 vs ${distinct[0]}`;
69255
- return asset;
69256
- }
69257
- var SAME_BLOCK_EXIT_MODES = /* @__PURE__ */ new Set([
69258
- "instant",
69259
- "instant-capped"
69260
- ]);
69261
- function isIlliquid(input) {
69262
- if (!input.exitMode || !SAME_BLOCK_EXIT_MODES.has(input.exitMode))
69263
- return false;
69264
- if (!input.tvlUsd || input.tvlUsd <= 0) return false;
69265
- if (input.liquidityUsd === void 0) return false;
69266
- return input.liquidityUsd <= 0;
69267
- }
69268
-
69269
- // src/earn/normalize.ts
69270
- function num14(v) {
69271
- if (v == null || v === "") return void 0;
69272
- const n = typeof v === "number" ? v : Number(v);
69273
- return Number.isFinite(n) ? n : void 0;
69274
- }
69275
- function str6(v) {
69276
- if (typeof v === "string") return v.length > 0 ? v : void 0;
69277
- if (typeof v === "number" && Number.isFinite(v)) return String(v);
69278
- return void 0;
69279
- }
69280
- function addr2(v) {
69281
- return str6(v)?.toLowerCase();
69282
- }
69283
- function yieldProfile(v) {
69284
- return v === "yield-bearing" || v === "volatile" ? v : void 0;
69285
- }
69286
- function denomination(v) {
69287
- return v === "stable" || v === "volatile" ? v : void 0;
69288
- }
69289
- function usdValue(formatted, priceUsd) {
69290
- if (formatted === void 0 || priceUsd === void 0) return void 0;
69291
- const v = formatted * priceUsd;
69292
- return Number.isFinite(v) ? v : void 0;
69293
- }
69294
- function formatRaw(raw, decimals) {
69295
- if (raw == null || raw === "") return void 0;
69296
- let value;
69297
- try {
69298
- value = BigInt(raw);
69299
- } catch {
69300
- return void 0;
69301
- }
69302
- if (decimals <= 0) return Number(value);
69303
- const base = 10n ** BigInt(decimals);
69304
- const whole = value / base;
69305
- const frac = value % base;
69306
- const n = Number(whole) + Number(frac) / Number(base);
69307
- return Number.isFinite(n) ? n : void 0;
69308
- }
69309
-
69310
- // src/earn/fromVault.ts
69311
- var FRACTION_RATE_PROVIDERS = /* @__PURE__ */ new Set();
69312
- var SDK_FRACTION_RATE_PROVIDERS = /* @__PURE__ */ new Set([
69313
- "hypercore",
69314
- "gmx"
69315
- ]);
69316
- var RATE_SOURCE = {
69317
- morpho: "api",
69318
- silo: "api",
69319
- lagoon: "api",
69320
- hypercore: "api",
69321
- gmx: "api",
69322
- upshift: "api",
69323
- yearn: "api",
69324
- "aave-earn": "api",
69325
- pendle: "api",
69326
- lista: "chain",
69327
- fluid: "chain",
69328
- gearbox: "chain",
69329
- "euler-earn": "chain",
69330
- termmax: "chain",
69331
- lst: "chain",
69332
- savings: "chain"
69333
- };
69334
- var RATE_KIND = {
69335
- morpho: "variable-curve",
69336
- lista: "variable-curve",
69337
- silo: "variable-curve",
69338
- "euler-earn": "variable-curve",
69339
- fluid: "variable-curve",
69340
- gearbox: "variable-curve",
69341
- "aave-earn": "variable-curve",
69342
- // The TermMax VAULT is a perpetual curated 4626 whose curator rolls
69343
- // fixed-term FT positions — the vault itself has no maturity and no locked
69344
- // rate. `fixed-term` here claimed both, producing a "fixed" rate with no date
69345
- // attached to it. The LENDER `TERMMAX_*` is fixed-term; this is not.
69346
- termmax: "variable-managed",
69347
- // A PT's implied APY is locked in at purchase and realized only by holding
69348
- // to maturity — the same promise TermMax's FT makes, reached by a different
69349
- // mechanism (an AMM discount rather than a quoted curve).
69350
- pendle: "fixed-term",
69351
- savings: "variable-managed",
69352
- lst: "variable-managed",
69353
- lagoon: "variable-managed",
69354
- upshift: "variable-managed",
69355
- yearn: "variable-managed",
69356
- hypercore: "realized",
69357
- gmx: "realized"
69358
- };
69359
- function resolveExitMode2(provider, meta, tvl, liq) {
69360
- const declared = str6(meta.withdrawalMode);
69361
- if (declared) return declared;
69362
- const fallback = vaultTraits(provider)?.defaultExitMode ?? "instant";
69363
- if (fallback !== "instant-capped") return fallback;
69364
- const total = num14(tvl?.totalAssetsFormatted) ?? num14(tvl?.totalAssetsUsd);
69365
- const available = num14(liq?.liquidityFormatted) ?? num14(liq?.liquidityUsd);
69366
- if (total === void 0 || available === void 0) return "instant-capped";
69367
- if (total <= 0) return "instant";
69368
- return available >= total ? "instant" : "instant-capped";
69369
- }
69370
- function earnMarketFromVault(row, chainId, opts = {}) {
69371
- const provider = str6(row.provider);
69372
- const address = str6(row.vaultAddress)?.toLowerCase();
69373
- const underlying = str6(row.underlying)?.toLowerCase();
69374
- if (!provider || !address || !underlying) return void 0;
69375
- const meta = row.providerMeta ?? {};
69376
- const info = row.vaultInfo ?? {};
69377
- const rates = row.rates ?? {};
69378
- const tvl = row.tvl ?? {};
69379
- const liq = row.liquidity ?? {};
69380
- const shareDecimals = num14(row.decimals) ?? 18;
69381
- const assetDecimals = num14(row.assetDecimals) ?? num14(row.underlyingInfo?.asset?.decimals) ?? shareDecimals;
69382
- const toPercent2 = (v) => ratePercent(v, provider, opts.fractionRateProviders);
69383
- const base = toPercent2(rates.depositRate ?? rates.supplyRate);
69384
- const rewards = toPercent2(rates.rewardsRate);
69385
- const total = toPercent2(rates.totalRate) ?? sum(base, rewards) ?? 0;
69386
- const rate = {
69387
- total,
69388
- base,
69389
- rewards,
69390
- // A vault has no separate intrinsic leg — whatever it pays IS the venue's
69391
- // own yield. Leaving this undefined rendered an empty "Venue APR" on every
69392
- // vault row, which read as "this vault pays nothing".
69393
- marketOwn: total,
69394
- // ...and for the same reason it can never be pass-through.
69395
- passthrough: false,
69396
- kind: resolveRateKind(provider, meta),
69397
- source: RATE_SOURCE[provider] ?? "api",
69398
- // The curator's cut. Dropped entirely until now, which left the earn row
69399
- // unable to say why its net rate sits below the gross one — and left the
69400
- // term sheet built from this row with no fee schedule at all.
69401
- fee: toPercent2(rates.fee)
69402
- };
69403
- const maturity = resolveMaturity(meta);
69404
- const availability = resolveAvailability(meta, maturity);
69405
- const exitMode = resolveExitMode2(provider, meta, tvl, liq);
69406
- return {
69407
- earnUid: buildVaultEarnUid(provider, chainId, address),
69408
- chainId,
69409
- venue: vaultVenue(provider),
69410
- venueKind: "vault",
69411
- // Curator first (it names the actual operator), then the provider brand.
69412
- brand: str6(row.curatorName) ?? venueBrand(vaultVenue(provider)),
69413
- name: str6(info.name) ?? str6(row.displayName) ?? str6(row.name),
69414
- ref: address,
69415
- logoURI: str6(info.logoURI) ?? str6(row.underlyingInfo?.asset?.logoURI),
69416
- asset: {
69417
- address: underlying,
69418
- symbol: str6(row.underlyingInfo?.asset?.symbol) ?? "",
69419
- decimals: assetDecimals,
69420
- assetGroup: str6(info.assetGroup),
69421
- priceUsd: num14(row.underlyingInfo?.prices?.priceUsd)
69422
- },
69423
- // The vault IS a share token by construction; carry it so a withdraw in
69424
- // share units can be built without a second lookup.
69425
- shareToken: {
69426
- address,
69427
- symbol: str6(info.symbol) ?? str6(row.symbol) ?? "",
69428
- decimals: shareDecimals
69429
- },
69430
- rate,
69431
- // The vault origin reports RAW base units + a pre-formatted convenience
69432
- // field. Carry both; fall back to formatting the raw amount ourselves so
69433
- // `formatted` — the field consumers sort on — is never silently absent.
69434
- tvl: amount(
69435
- tvl.totalAssets,
69436
- tvl.totalAssetsFormatted,
69437
- tvl.totalAssetsUsd,
69438
- assetDecimals
69439
- ),
69440
- liquidity: liq.liquidity != null || liq.liquidityUsd != null ? amount(
69441
- liq.liquidity,
69442
- liq.liquidityFormatted,
69443
- liq.liquidityUsd,
69444
- assetDecimals
69445
- ) : void 0,
69446
- depositCapacity: str6(meta.depositCapacity) ?? str6(meta.maxDeposit),
69447
- maturity,
69448
- exit: {
69449
- mode: exitMode,
69450
- settlement: str6(meta.redemptionType),
69451
- cooldownSecs: num14(meta.withdrawalCooldownSeconds),
69452
- feeBps: num14(meta.withdrawFeeBps)
69453
- },
69454
- availability,
69455
- risk: {
69456
- yieldProfile: yieldProfile(info.yieldProfile),
69457
- denomination: denomination(info.denomination),
69458
- // The curated trust classification, where one exists. Typed on `EarnRisk`
69459
- // since the surface was written and never populated — a tranche's
69460
- // first-loss position is the term most worth surfacing on a rate list.
69461
- counterparty: str6(meta.solvency),
69462
- score: num14(row.rating?.score),
69463
- label: str6(row.rating?.level),
69464
- illiquid: isIlliquid({
69465
- exitMode,
69466
- tvlUsd: num14(tvl.totalAssetsUsd),
69467
- liquidityUsd: num14(liq.liquidityUsd)
69468
- })
69469
- },
69470
- // Filled by `capabilities.ts` — kept required on the type so a normalizer
69471
- // that forgets to stamp them is a compile error, not an empty CTA.
69472
- capabilities: [],
69473
- providerMeta: row.providerMeta
69474
- };
69475
- }
69476
- function ratePercent(value, provider, fractionProviders = FRACTION_RATE_PROVIDERS) {
69477
- const n = num14(value);
69478
- if (n === void 0) return void 0;
69479
- return fractionProviders.has(provider) ? n * 100 : n;
69480
- }
69481
- function implausibleRatePercent(percent) {
69482
- return !Number.isFinite(percent) || percent < 0 || percent > 1e4;
69483
- }
69484
- function resolveRateKind(provider, meta) {
69485
- if (meta.navOracle || meta.solvency === "nav-attested") return "nav-accrual";
69486
- return RATE_KIND[provider] ?? "variable-managed";
69487
- }
69488
- function resolveAvailability(meta, maturity) {
69489
- const isMintable = meta.isMintable;
69490
- const capacity = str6(meta.depositCapacity) ?? str6(meta.maxDeposit);
69491
- const capFull = capacity === "0";
69492
- let gating;
69493
- let reason;
69494
- if (isMatured(maturity)) {
69495
- gating = "matured";
69496
- reason = "This market has reached maturity";
69497
- } else if (isMintable === false) {
69498
- gating = "allowlist-contract";
69499
- reason = "Deposits are permissioned for this vault";
69500
- } else if (capFull) {
69501
- gating = "cap-full";
69502
- reason = "Deposit cap is full";
69503
- } else if (meta.paused === true) {
69504
- gating = "paused";
69505
- reason = "Vault is paused";
69506
- }
69507
- return {
69508
- canDeposit: gating === void 0,
69509
- // Exits stay open under a deposit cap, a mint allowlist or a maturity —
69510
- // every wind-down we have integrated (Lista, dTRINITY/Sonic) keeps the
69511
- // door open outward, and a matured bond is precisely the case where the
69512
- // holder still needs out. An explicit pause is the one thing that shuts
69513
- // both.
69514
- canWithdraw: meta.paused !== true,
69515
- gating,
69516
- reason
69517
- };
69518
- }
69519
- function resolveMaturity(meta) {
69520
- const expiry = num14(meta.expiry) ?? num14(meta.maturity);
69521
- if (expiry === void 0 || expiry <= 0) return void 0;
69522
- const nowSecs = Math.floor(Date.now() / 1e3);
69523
- return {
69524
- kind: "fixed-date",
69525
- maturity: expiry,
69526
- maturityIso: str6(meta.expiryIso) ?? new Date(expiry * 1e3).toISOString(),
69527
- // A SNAPSHOT — a cached listing ages, so a countdown must be recomputed
69528
- // from `maturity` rather than ticked down from this.
69529
- secondsToMaturity: Math.max(expiry - nowSecs, 0),
69530
- // A PT simply stops earning: it redeems for the underlying at par and
69531
- // sits there. No penalty, no liquidation, no auto-roll.
69532
- atMaturity: str6(meta.atMaturity) ?? "stops-earning"
69533
- };
69534
- }
69535
- function isMatured(maturity) {
69536
- if (!maturity?.maturity) return false;
69537
- return maturity.maturity <= Math.floor(Date.now() / 1e3);
69538
- }
69539
- function amount(raw, formatted, usd, decimals) {
69540
- const rawStr = raw != null ? String(raw) : void 0;
69541
- return {
69542
- raw: rawStr,
69543
- formatted: num14(formatted) ?? formatRaw(rawStr, decimals),
69544
- usd: num14(usd)
69545
- };
69546
- }
69547
- function sum(a, b) {
69548
- if (a === void 0 && b === void 0) return void 0;
69549
- return (a ?? 0) + (b ?? 0);
69550
- }
69551
-
69552
69646
  // src/earn/fromPool.ts
69553
69647
  var FIXED_TERM_PREFIXES = [
69554
69648
  "EXACTLY",
@@ -69568,7 +69662,7 @@ var USER_SET_RATE_PREFIXES = [
69568
69662
  "EBISU"
69569
69663
  ];
69570
69664
  function earnMarketFromPool(row, fallbackChainId) {
69571
- const marketUid = str6(row.marketUid);
69665
+ const marketUid = str5(row.marketUid);
69572
69666
  if (!marketUid) return void 0;
69573
69667
  let earnUid;
69574
69668
  try {
@@ -69576,24 +69670,24 @@ function earnMarketFromPool(row, fallbackChainId) {
69576
69670
  } catch {
69577
69671
  return void 0;
69578
69672
  }
69579
- const chainId = str6(row.chainId) ?? fallbackChainId;
69580
- const venue = str6(row.lender) ?? str6(row.lenderKey);
69673
+ const chainId = str5(row.chainId) ?? fallbackChainId;
69674
+ const venue = str5(row.lender) ?? str5(row.lenderKey);
69581
69675
  if (!chainId || !venue) return void 0;
69582
69676
  const flags = row.flags ?? {};
69583
69677
  const assetInfo = row.underlyingInfo?.asset ?? row.asset ?? {};
69584
69678
  const underlying = addr2(assetInfo.address) ?? addr2(row.underlying) ?? addr2(row.poolId);
69585
69679
  if (!underlying) return void 0;
69586
- const decimals = num14(assetInfo.decimals) ?? num14(row.decimals) ?? 18;
69587
- const priceUsd = num14(row.underlyingInfo?.prices?.priceUsd) ?? num14(row.price);
69588
- const base = num14(row.depositRate);
69589
- const intrinsic = num14(row.intrinsicYield);
69680
+ const decimals = num12(assetInfo.decimals) ?? num12(row.decimals) ?? 18;
69681
+ const priceUsd = num12(row.underlyingInfo?.prices?.priceUsd) ?? num12(row.price);
69682
+ const base = num12(row.depositRate);
69683
+ const intrinsic = num12(row.intrinsicYield);
69590
69684
  const rewards = sumRewardAprs(row.rewards);
69591
69685
  const marketOwn = sum2(base, rewards);
69592
69686
  const rate = {
69593
69687
  // Prefer our own sum over the origin's `apr`, because `apr` is documented
69594
69688
  // as `depositRate + intrinsicYield` and therefore EXCLUDES incentives —
69595
69689
  // using it as the headline would under-report every incentivized market.
69596
- total: sum2(base, intrinsic, rewards) ?? num14(row.apr) ?? 0,
69690
+ total: sum2(base, intrinsic, rewards) ?? num12(row.apr) ?? 0,
69597
69691
  base,
69598
69692
  rewards,
69599
69693
  intrinsic,
@@ -69611,15 +69705,19 @@ function earnMarketFromPool(row, fallbackChainId) {
69611
69705
  // The family brand ('Morpho Blue'), not the per-market key. The specific
69612
69706
  // market identity survives on `name`.
69613
69707
  brand: venueBrand(venue),
69614
- name: str6(row.name),
69708
+ // Same resolver as the vault half, so `protocol.key` means one thing
69709
+ // across the listing: the STABLE family key, never the per-market venue.
69710
+ // No lender publishes a curator today, hence the undefined.
69711
+ ...resolveEarnIdentity(venue, void 0),
69712
+ name: str5(row.name),
69615
69713
  // Never re-derived — the uid's third segment as the origin minted it.
69616
69714
  ref: marketUid.split(":")[2],
69617
- logoURI: str6(assetInfo.logoURI),
69715
+ logoURI: str5(assetInfo.logoURI),
69618
69716
  asset: {
69619
69717
  address: underlying,
69620
- symbol: str6(assetInfo.symbol) ?? "",
69718
+ symbol: str5(assetInfo.symbol) ?? "",
69621
69719
  decimals,
69622
- assetGroup: str6(row.underlyingInfo?.assetGroup) ?? str6(row.asset?.assetGroup),
69720
+ assetGroup: str5(row.underlyingInfo?.assetGroup) ?? str5(row.asset?.assetGroup),
69623
69721
  priceUsd
69624
69722
  },
69625
69723
  // A lending supply position is an aToken/cToken/eToken balance, but the
@@ -69640,7 +69738,7 @@ function earnMarketFromPool(row, fallbackChainId) {
69640
69738
  row.totalLiquidityUSD ?? row.totalLiquidityUsd
69641
69739
  ),
69642
69740
  depositCapacity: void 0,
69643
- utilization: num14(row.utilization),
69741
+ utilization: num12(row.utilization),
69644
69742
  // Lending withdrawals are same-block, bounded by available liquidity —
69645
69743
  // which is exactly `instant-capped`, not `instant`. A pool at 100 %
69646
69744
  // utilization cannot be exited, and calling that `instant` is the kind of
@@ -69648,12 +69746,12 @@ function earnMarketFromPool(row, fallbackChainId) {
69648
69746
  exit: { mode: "instant-capped", settlement: "sync" },
69649
69747
  availability,
69650
69748
  risk: {
69651
- score: num14(row.risk?.score),
69652
- label: str6(row.risk?.label),
69749
+ score: num12(row.risk?.score),
69750
+ label: str5(row.risk?.label),
69653
69751
  illiquid: isIlliquid({
69654
69752
  exitMode: "instant-capped",
69655
- tvlUsd: num14(row.totalDepositsUSD ?? row.totalDepositsUsd),
69656
- liquidityUsd: num14(row.totalLiquidityUSD ?? row.totalLiquidityUsd)
69753
+ tvlUsd: num12(row.totalDepositsUSD ?? row.totalDepositsUsd),
69754
+ liquidityUsd: num12(row.totalLiquidityUSD ?? row.totalLiquidityUsd)
69657
69755
  })
69658
69756
  },
69659
69757
  capabilities: [],
@@ -69708,9 +69806,9 @@ function resolveAvailability2(row, flags, totalRate) {
69708
69806
  };
69709
69807
  }
69710
69808
  function isSupplyCapFull(row) {
69711
- const cap = num14(row.caps?.supplyCap) ?? num14(row.supplyCap);
69809
+ const cap = num12(row.caps?.supplyCap) ?? num12(row.supplyCap);
69712
69810
  if (cap === void 0 || cap <= 0) return false;
69713
- const deposits = num14(row.totalDeposits);
69811
+ const deposits = num12(row.totalDeposits);
69714
69812
  if (deposits === void 0) return false;
69715
69813
  return deposits >= cap;
69716
69814
  }
@@ -69719,7 +69817,7 @@ function sumRewardAprs(rewards) {
69719
69817
  let total = 0;
69720
69818
  let seen = false;
69721
69819
  for (const r of rewards) {
69722
- const apr = num14(r?.depositRate);
69820
+ const apr = num12(r?.depositRate);
69723
69821
  if (apr === void 0) continue;
69724
69822
  total += apr;
69725
69823
  seen = true;
@@ -69727,14 +69825,12 @@ function sumRewardAprs(rewards) {
69727
69825
  return seen ? total : void 0;
69728
69826
  }
69729
69827
  function amount2(formatted, usd) {
69730
- return { formatted: num14(formatted), usd: num14(usd) };
69828
+ return { formatted: num12(formatted), usd: num12(usd) };
69731
69829
  }
69732
69830
  function sum2(...parts) {
69733
69831
  const present = parts.filter((p) => p !== void 0);
69734
69832
  return present.length ? present.reduce((a, b) => a + b, 0) : void 0;
69735
69833
  }
69736
-
69737
- // src/earn/capabilities.ts
69738
69834
  var ASYNC_EXIT_MODES = /* @__PURE__ */ new Set([
69739
69835
  "fixed-cooldown",
69740
69836
  "request-based",
@@ -69789,9 +69885,11 @@ function vaultCapabilities(row) {
69789
69885
  const caps = [];
69790
69886
  if (SWAP_ROUTED_PROVIDERS.has(provider)) return swapRoutedCapabilities(row);
69791
69887
  if (row.availability.canDeposit) {
69888
+ const inputs = depositInputs(row, provider);
69792
69889
  caps.push({
69793
69890
  action: "deposit",
69794
- requires: depositRequires(provider, meta),
69891
+ inputs,
69892
+ requires: depositRequires(provider, meta, inputs),
69795
69893
  // Phase 3 flips this to `true` once the `vault.*` venues are registered
69796
69894
  // with the conversion solver. Advertising it before the route can serve
69797
69895
  // it would be worse than the current gap — a client would build a zap
@@ -69803,13 +69901,14 @@ function vaultCapabilities(row) {
69803
69901
  const mode = row.exit.mode;
69804
69902
  const isAsync = ASYNC_PROVIDERS.has(provider) || ASYNC_EXIT_MODES.has(mode);
69805
69903
  if (!isAsync) {
69806
- caps.push({ action: "withdraw" });
69904
+ caps.push({ action: "withdraw", requires: withdrawRequires(provider) });
69807
69905
  return caps;
69808
69906
  }
69809
69907
  if (mode === "fee-or-queued" && meta.instantRedeemEnabled !== false) {
69810
69908
  caps.push({
69811
69909
  action: "withdraw",
69812
- feeBps: num14(meta.withdrawFeeBps) ?? row.exit.feeBps
69910
+ requires: withdrawRequires(provider),
69911
+ feeBps: num12(meta.withdrawFeeBps) ?? row.exit.feeBps
69813
69912
  });
69814
69913
  }
69815
69914
  caps.push({
@@ -69827,14 +69926,58 @@ function vaultCapabilities(row) {
69827
69926
  }
69828
69927
  return caps;
69829
69928
  }
69830
- function depositRequires(provider, meta) {
69929
+ function isBookPriced(provider) {
69930
+ const risk = vaultTraits(provider)?.priceRisk;
69931
+ return risk === "market-price" || risk === "may-be-impossible";
69932
+ }
69933
+ function swapRoutedProvidersArePriceConsistent() {
69934
+ return [...SWAP_ROUTED_PROVIDERS].filter((p) => !isBookPriced(p));
69935
+ }
69936
+ function depositInputs(row, provider) {
69937
+ if (provider !== "lst") return void 0;
69938
+ const share = row.shareToken?.address ?? row.ref;
69939
+ if (!share) return void 0;
69940
+ try {
69941
+ const accepted = getLstAcceptedInputs(row.chainId, share);
69942
+ if (!accepted?.length) return void 0;
69943
+ return accepted.map((a) => ({
69944
+ asset: String(a.asset),
69945
+ symbol: a.symbol,
69946
+ mode: a.mode,
69947
+ needs: a.needs,
69948
+ optional: a.optional
69949
+ }));
69950
+ } catch {
69951
+ return void 0;
69952
+ }
69953
+ }
69954
+ function isBoundNeed(need) {
69955
+ return /^min/i.test(need);
69956
+ }
69957
+ function depositRequires(provider, meta, inputs) {
69831
69958
  const requires = [];
69832
69959
  if (meta.delegation) requires.push("validator");
69833
69960
  if (provider === "gmx") requires.push("executionFee");
69961
+ if (isBookPriced(provider)) requires.push("slippage");
69962
+ if (inputs?.length) {
69963
+ const common = inputs[0].needs?.filter(
69964
+ (n) => inputs.every((i) => i.needs?.includes(n))
69965
+ );
69966
+ for (const n of common ?? []) if (!requires.includes(n)) requires.push(n);
69967
+ }
69968
+ return requires.length ? requires : void 0;
69969
+ }
69970
+ function withdrawRequires(provider) {
69971
+ const requires = [];
69972
+ if (isBookPriced(provider)) requires.push("slippage");
69973
+ if (provider === "gmx") requires.push("executionFee");
69834
69974
  return requires.length ? requires : void 0;
69835
69975
  }
69836
69976
  function requestRequires(provider) {
69837
- return provider === "gmx" ? ["executionFee"] : void 0;
69977
+ const requires = [];
69978
+ if (provider === "gmx") requires.push("executionFee");
69979
+ if (isBookPriced(provider)) requires.push("slippage");
69980
+ return requires.length ? requires : void 0;
69838
69981
  }
69839
69982
  function claimRequires(provider) {
69840
69983
  return void 0;
@@ -69844,6 +69987,191 @@ function supportsCancel(provider, meta) {
69844
69987
  return typeof meta.withdrawQueue === "string" && meta.withdrawQueue.length > 0;
69845
69988
  }
69846
69989
 
69847
- export { ApiBookSource, DEFAULT_MIDNIGHT_API, DEFAULT_OUTLIER_GUARD, DEFAULT_PROFILE_ID, DEFAULT_STALE_REJECT_SECONDS, DEFAULT_TERMMAX_API, EARN_DESCRIPTIONS, EARN_LABELS, EMPTY_BALANCE, EXACTLY_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, STABLECOIN_SYMBOLS, STCELO_MANAGER_ADDRESS, TELLER_CALLS_PER_BID, TERMMAX_CALLS_PER_ACCOUNT, DECIMAL_BASE as TERMMAX_DECIMAL_BASE, TERMMAX_LIQUIDATION_PENALTY, TERMMAX_LIQUIDATION_WINDOW_SECS, TERMMAX_LIQUIDATOR_BONUS, 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_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, applyPositionDelta, attachImplications, attachPricesToFlashLiquidity, borrowDescription, borrowFindings, borrowHeadline, buildExposures2 as buildExposures, buildFluidFTokensCall, buildLiquityUserCall, buildLoopResult, buildMorphoTypeCall, buildMorphoTypeUserCallWithLens, buildPortfolioTotals, buildSumerAccumulators, buildSummaries, buildTellerUserCall, buildTermMaxUserCall, buildTermSheet, buildTermSheetsForGroup, buildVaultEarnUid, buildVaultLookup, buildVaultTermSheet, calculateLeverage, calculateNetApr, calculateOverallNetApr, calculateWeightedAverage, classifyFreshness, classifyReliability, classifyVault, clearPendleMarketsCache, 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, convertDssMarketsToResponse, convertExactlyMarketsToResponse, 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, dssIlkBytes32, dssKeyParts, dssLenderKey, duration, earnDescription, earnLabel, earnMarketFromPool, earnMarketFromVault, earnMarketLabel, earnUidFromMarketUid, earnVenueKind, encodeBalanceFetcherCalldata, enrichTermSheet, enrichmentIndexFromRows, exactlyPairLtv, exactlyPenaltyRateToAprPercent, exactlyWadRateToPercent, feePhrase, feedKeyOf, feedStatKey, fetchDolomiteAccountNumbers, fetchDssMarkets, fetchEulerEarnVaults, fetchEulerEarnVaultsFromSubgraph, fetchEulerSubAccountIndexes, fetchExactlyMarkets, fetchFlashLiquidityForChain, fetchFluidFTokens, 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, fetchTellerMarkets, fetchTermMarkets, fetchTermMaxMarkets, fetchTokenBalances, fetchTokenMetadata, fetchUpshiftApiVaults, fetchUpshiftVaults, fetchUsddMarkets, fetchYearnApiVaults, fetchYearnVaults, filterActiveLenders, filterLendersByProtocol, finalizeInfo, findingsFor, formatRaw, frankencoinKeyParts, frankencoinLenderKey, fraxlendAssetPerCollateral, fraxlendKeyParts, fraxlendLenderKey, fuseLenderData, generateLendingPools, getAavesForChain, getAssetConfig, getBalanceForMarketUid, getBorrowCapacity, 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, getStCeloValidatorGroups, getSubAccountAddress, getSubAccountIndex, getTermProfile, getVaultPublicDataAll, getVaultWithdrawalRequests, hasCritical, hasEulerEarnVaultSubgraph, hasLagoonVaults, hasMorphoPositionIndex, hasMorphoUserApi, hasMorphoUserSubgraph, hasPendleMarkets, hasUpshiftVaults, hasYearnVaults, ilkToKeySegment, implausibleRatePercent, inverseKeyParts, inverseLenderKey, isFailedCall, isIlliquid, isLiveMarket as isLivePendleMarket, isStablecoinSymbol, isVaultVenue, isYearnV3, keySegmentToIlk, keysFromMaps, lenderApiOnly, lenderFamily, liquityCandidateTroveIds, liquityKeyParts, liquityLenderKey, llamaLendKeyParts, llamaLendLenderKey, mergeDeep, multicall3Abi2 as multicall3Abi, nanTo, needsLenderApproval, needsTokenApproval, noOpResult, normalizeToBytes, parseBalanceFetcherResult, parseEarnUid, parseMergedResult, parseMulticallRpcResponses, parseExpirySeconds as parsePendleExpirySeconds, parseRawRpcBatchResponses, parseRawRpcResponses, parseTermMaxLtv, parseTokenBalanceResult, pct, assetKey as pendleAssetKey, positivePart2 as positivePart, predictInverseEscrow, prepareLenderUserDataRpcCalls, prepareMergedMulticallParams, prepareMergedRpcCalls, prepareMulticallInputs, prepareTokenBalanceRpcCalls, priceGlvVaults, priceGmMarkets, probeAaveFeedTimestamps, pruneFeedStats, rankFindings, ratePercent, readVaultSharePrices, rejectOutliers as rejectPriceOutliers, resolveAdapter, resolveDerivation, resolveStCeloDepositGroup, resolveVaultProfileId, resupplyKeyParts, resupplyLenderKey, resupplyMarketLabel, riverKeyParts, riverLenderKey, selectAssetGroupPrices, shortDate, splitChainScopedAddress as splitPendleChainScopedAddress, stampCapabilities, stampVaultClassification, stampVaultTermSheets, supplyDescription, supplyFindings, supplyHeadline, tellerBpsToPercent, tellerImpliedLtv, tellerLenderKey, tellerPoolFromLenderKey, 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, tickToAprNumber, tickToPrice, toDigest, toTermSheetInput, toVaultTermInput, tryParseEarnUid, unflattenLenderData, updateFeedStats, usdValue, usddIlkBytes32, usddKeyParts, usddLenderKey, validateTermSheet, validateTermSheets, validateUserData, vaultTermInputFromEarnMarket, vaultTermInputFromSourceRow, vaultTraits, vaultVenue, venueBrand };
69990
+ // src/earn/positions.ts
69991
+ function buildLendingPositionUid(lender, chainId) {
69992
+ if (!lender || !chainId) {
69993
+ throw new Error(
69994
+ `Invalid lending positionUid parameters: lender=${lender}, chainId=${chainId}`
69995
+ );
69996
+ }
69997
+ if (isVaultVenue(lender)) {
69998
+ throw new Error(
69999
+ `Lender '${lender}' uses the reserved vault venue namespace`
70000
+ );
70001
+ }
70002
+ return `${lender}:${chainId}`;
70003
+ }
70004
+ function isVaultPosition(p) {
70005
+ return p.venueKind === "vault";
70006
+ }
70007
+ function isLendingPosition(p) {
70008
+ return p.venueKind === "lending";
70009
+ }
70010
+ function legEarnUid(marketUid) {
70011
+ if (!marketUid) return void 0;
70012
+ const parts = marketUid.split(":");
70013
+ if (parts.length !== 3 || parts.some((p) => !p)) return void 0;
70014
+ if (isVaultVenue(parts[0])) return void 0;
70015
+ return marketUid;
70016
+ }
70017
+ function num15(v) {
70018
+ const n = typeof v === "number" ? v : Number(v);
70019
+ return Number.isFinite(n) ? n : 0;
70020
+ }
70021
+ function legAsset(pos) {
70022
+ const asset = pos.underlyingInfo?.asset ?? {};
70023
+ const address = typeof asset.address === "string" ? asset.address.toLowerCase() : (
70024
+ // Fall back to the uid's third segment, which IS the underlying for
70025
+ // the default-format lenders and merely a harmless label for the rest.
70026
+ pos.marketUid?.split(":")[2] ?? ""
70027
+ );
70028
+ const decimals = typeof asset.decimals === "number" ? asset.decimals : void 0;
70029
+ const symbol = typeof asset.symbol === "string" ? asset.symbol : void 0;
70030
+ return { address, symbol, decimals };
70031
+ }
70032
+ function toLeg(pos) {
70033
+ const depositsUsd = num15(pos.depositsUSD);
70034
+ const debtUsd = num15(pos.debtUSD) + num15(pos.debtStableUSD);
70035
+ const hasSupply = depositsUsd !== 0 || num15(pos.deposits) !== 0;
70036
+ const hasDebt = debtUsd !== 0 || num15(pos.debt) !== 0 || num15(pos.debtStable) !== 0;
70037
+ return {
70038
+ earnUid: legEarnUid(pos.marketUid),
70039
+ marketUid: pos.marketUid,
70040
+ ...pos.loanId ? { loanId: pos.loanId } : {},
70041
+ asset: legAsset(pos),
70042
+ side: hasSupply && hasDebt ? "both" : hasDebt ? "borrow" : "supply",
70043
+ deposits: pos.deposits ?? "0",
70044
+ depositsUsd,
70045
+ debt: pos.debt ?? "0",
70046
+ debtUsd,
70047
+ collateralEnabled: pos.collateralEnabled ?? false,
70048
+ ...pos.withdrawable !== void 0 ? { withdrawable: pos.withdrawable } : {}
70049
+ };
70050
+ }
70051
+ function isCountable(leg) {
70052
+ return leg.loanId === void 0;
70053
+ }
70054
+ function earnPositionFromLenderEntry(entry) {
70055
+ const subs = entry.data ?? [];
70056
+ const subAccounts = subs.map((sub) => {
70057
+ const legs = (sub.positions ?? []).map(toLeg);
70058
+ const counted = legs.filter(isCountable);
70059
+ const suppliedUsd2 = counted.reduce((a, l) => a + l.depositsUsd, 0);
70060
+ const borrowedUsd2 = counted.reduce((a, l) => a + l.debtUsd, 0);
70061
+ return {
70062
+ accountId: sub.accountId,
70063
+ health: sub.health ?? null,
70064
+ suppliedUsd: suppliedUsd2,
70065
+ borrowedUsd: borrowedUsd2,
70066
+ netUsd: suppliedUsd2 - borrowedUsd2,
70067
+ legs
70068
+ };
70069
+ });
70070
+ const active = subAccounts.filter((s) => s.legs.length > 0 || s.netUsd !== 0);
70071
+ const crossMargin = active.length <= 1;
70072
+ const suppliedUsd = num15(entry.balanceData?.deposits);
70073
+ const borrowedUsd = num15(entry.balanceData?.debt);
70074
+ return {
70075
+ positionUid: buildLendingPositionUid(entry.lender, entry.chainId),
70076
+ chainId: entry.chainId,
70077
+ venue: entry.lender,
70078
+ venueKind: "lending",
70079
+ lender: entry.lender,
70080
+ account: entry.account,
70081
+ brand: entry.lenderInfo?.name,
70082
+ name: entry.lenderInfo?.name,
70083
+ ...entry.lenderInfo?.logoUri ? { logoURI: entry.lenderInfo.logoUri } : {},
70084
+ suppliedUsd,
70085
+ borrowedUsd,
70086
+ netUsd: num15(entry.balanceData?.nav),
70087
+ apr: num15(entry.aprData?.apr),
70088
+ depositApr: num15(entry.aprData?.depositApr),
70089
+ borrowApr: num15(entry.aprData?.borrowApr),
70090
+ // Only a cross-margin account HAS one health factor. Publishing the first
70091
+ // sub-account's as the row's would be a number about a different position.
70092
+ health: crossMargin ? active[0]?.health ?? null : null,
70093
+ leverage: num15(entry.leverage),
70094
+ crossMargin,
70095
+ legs: subAccounts.flatMap((s) => s.legs),
70096
+ subAccounts: active,
70097
+ ...entry.incomplete ? { incomplete: true } : {},
70098
+ ...entry.stale ? { stale: true, staleAgeMs: entry.staleAgeMs } : {}
70099
+ };
70100
+ }
70101
+ function vaultSharesToAssets(sharesRaw, meta) {
70102
+ if (sharesRaw === 0n) return 0n;
70103
+ const totalSupply = BigInt(meta.totalSupply || "0");
70104
+ if (totalSupply === 0n) return 0n;
70105
+ return sharesRaw * BigInt(meta.totalAssets || "0") / totalSupply;
70106
+ }
70107
+ function earnPositionFromVaultBalance(meta, chainId, input, format) {
70108
+ const assetsRaw = vaultSharesToAssets(input.sharesRaw, meta);
70109
+ const assetDecimals = meta.assetDecimals ?? meta.decimals;
70110
+ const assets = format(assetsRaw, assetDecimals);
70111
+ const priceUsd = input.priceUsd ?? 0;
70112
+ const suppliedUsd = priceUsd * parseFloat(assets);
70113
+ const market = input.market;
70114
+ const uid = buildVaultEarnUid(meta.provider, chainId, meta.address);
70115
+ return {
70116
+ positionUid: uid,
70117
+ earnUid: uid,
70118
+ chainId,
70119
+ venue: `vault.${meta.provider}`,
70120
+ venueKind: "vault",
70121
+ provider: meta.provider,
70122
+ vault: meta.address,
70123
+ // The catalogue's identity resolution (curator, brand, branded icon) beats
70124
+ // the raw share-token name where it resolved.
70125
+ name: market?.name ?? meta.name,
70126
+ ...market?.brand ? { brand: market.brand } : {},
70127
+ ...market?.logoURI ?? meta.logoURI ? { logoURI: market?.logoURI ?? meta.logoURI } : {},
70128
+ asset: {
70129
+ address: meta.underlying,
70130
+ ...market?.asset.symbol ? { symbol: market.asset.symbol } : {},
70131
+ decimals: assetDecimals,
70132
+ priceUsd
70133
+ },
70134
+ sharesRaw: input.sharesRaw.toString(),
70135
+ shares: format(input.sharesRaw, meta.decimals),
70136
+ assetsRaw: assetsRaw.toString(),
70137
+ assets,
70138
+ shareDecimals: meta.decimals,
70139
+ suppliedUsd,
70140
+ // A vault share is a supply-only instrument — there is no borrow leg to
70141
+ // report, and `0` here is a fact rather than a missing read.
70142
+ borrowedUsd: 0,
70143
+ netUsd: suppliedUsd,
70144
+ // For a vault the position's APR IS the venue's rate — there is no borrow
70145
+ // leg to net off, so unlike the lending half the two never diverge.
70146
+ ...market?.rate?.total !== void 0 ? { apr: market.rate.total } : {},
70147
+ ...market?.rate ? { rate: market.rate } : {},
70148
+ ...market?.exit ? { exit: market.exit } : {},
70149
+ ...market?.availability ? { availability: market.availability } : {},
70150
+ ...market?.capabilities ? { capabilities: market.capabilities } : {},
70151
+ ...meta.yieldProfile ? { yieldProfile: meta.yieldProfile } : {},
70152
+ ...meta.denomination ? { denomination: meta.denomination } : {}
70153
+ };
70154
+ }
70155
+ function earnPositionTotals(items) {
70156
+ let suppliedUsd = 0;
70157
+ let borrowedUsd = 0;
70158
+ let lendingUsd = 0;
70159
+ let vaultUsd = 0;
70160
+ for (const it of items) {
70161
+ suppliedUsd += it.suppliedUsd;
70162
+ borrowedUsd += it.borrowedUsd;
70163
+ if (it.venueKind === "vault") vaultUsd += it.netUsd;
70164
+ else lendingUsd += it.netUsd;
70165
+ }
70166
+ return {
70167
+ suppliedUsd,
70168
+ borrowedUsd,
70169
+ netUsd: suppliedUsd - borrowedUsd,
70170
+ lendingUsd,
70171
+ vaultUsd
70172
+ };
70173
+ }
70174
+
70175
+ export { ApiBookSource, DEFAULT_MIDNIGHT_API, DEFAULT_OUTLIER_GUARD, DEFAULT_PROFILE_ID, DEFAULT_STALE_REJECT_SECONDS, DEFAULT_TERMMAX_API, EARN_DESCRIPTIONS, EARN_LABELS, EMPTY_BALANCE, EXACTLY_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, STABLECOIN_SYMBOLS, STCELO_MANAGER_ADDRESS, TELLER_CALLS_PER_BID, TERMMAX_CALLS_PER_ACCOUNT, DECIMAL_BASE as TERMMAX_DECIMAL_BASE, TERMMAX_LIQUIDATION_PENALTY, TERMMAX_LIQUIDATION_WINDOW_SECS, TERMMAX_LIQUIDATOR_BONUS, 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_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, 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, 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, convertDssMarketsToResponse, convertExactlyMarketsToResponse, 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, dssIlkBytes32, dssKeyParts, dssLenderKey, duration, earnDescription, earnLabel, earnMarketFromPool, earnMarketFromVault, earnMarketLabel, earnPositionFromLenderEntry, earnPositionFromVaultBalance, earnPositionTotals, earnUidFromMarketUid, earnVenueKind, encodeBalanceFetcherCalldata, enrichTermSheet, enrichmentIndexFromRows, exactlyPairLtv, exactlyPenaltyRateToAprPercent, exactlyWadRateToPercent, feePhrase, feedKeyOf, feedStatKey, fetchDolomiteAccountNumbers, fetchDssMarkets, fetchEulerEarnVaults, fetchEulerEarnVaultsFromSubgraph, fetchEulerSubAccountIndexes, fetchExactlyMarkets, fetchFlashLiquidityForChain, fetchFluidFTokens, 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, fetchTellerMarkets, fetchTermMarkets, fetchTermMaxMarkets, fetchTokenBalances, fetchTokenMetadata, fetchUpshiftApiVaults, fetchUpshiftVaults, fetchUsddMarkets, fetchYearnApiVaults, fetchYearnVaults, filterActiveLenders, filterLendersByProtocol, finalizeInfo, findingsFor, formatRaw, frankencoinKeyParts, frankencoinLenderKey, fraxlendAssetPerCollateral, fraxlendKeyParts, fraxlendLenderKey, fuseLenderData, generateLendingPools, getAavesForChain, getAssetConfig, getBalanceForMarketUid, getBorrowCapacity, 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, getStCeloValidatorGroups, getSubAccountAddress, getSubAccountIndex, getTermProfile, getVaultPublicDataAll, getVaultWithdrawalRequests, hasCritical, hasEulerEarnVaultSubgraph, hasLagoonVaults, hasMorphoPositionIndex, hasMorphoUserApi, hasMorphoUserSubgraph, hasPendleMarkets, hasUpshiftVaults, hasYearnVaults, ilkToKeySegment, implausibleRatePercent, inverseKeyParts, inverseLenderKey, isBoundNeed, isFailedCall, isIlliquid, isLendingPosition, isLiveMarket as isLivePendleMarket, isStablecoinSymbol, isVaultPosition, isVaultVenue, isYearnV3, keySegmentToIlk, keysFromMaps, lenderApiOnly, lenderFamily, liquityCandidateTroveIds, liquityKeyParts, liquityLenderKey, llamaLendKeyParts, llamaLendLenderKey, mergeDeep, multicall3Abi2 as multicall3Abi, nanTo, needsLenderApproval, needsTokenApproval, noOpResult, normalizeToBytes, parseBalanceFetcherResult, parseEarnUid, parseMergedResult, parseMulticallRpcResponses, parseExpirySeconds as parsePendleExpirySeconds, parseRawRpcBatchResponses, parseRawRpcResponses, parseTermMaxLtv, parseTokenBalanceResult, pct, assetKey as pendleAssetKey, positivePart2 as positivePart, predictInverseEscrow, prepareLenderUserDataRpcCalls, prepareMergedMulticallParams, prepareMergedRpcCalls, prepareMulticallInputs, prepareTokenBalanceRpcCalls, priceGlvVaults, priceGmMarkets, probeAaveFeedTimestamps, pruneFeedStats, rankFindings, ratePercent, readVaultSharePrices, rejectOutliers as rejectPriceOutliers, resolveAdapter, resolveDerivation, resolveEarnIdentity, resolveStCeloDepositGroup, resolveVaultProfileId, resupplyKeyParts, resupplyLenderKey, resupplyMarketLabel, riverKeyParts, riverLenderKey, selectAssetGroupPrices, shortDate, splitChainScopedAddress as splitPendleChainScopedAddress, stampCapabilities, stampVaultClassification, stampVaultTermSheets, supplyDescription, supplyFindings, supplyHeadline, swapRoutedProvidersArePriceConsistent, tellerBpsToPercent, tellerImpliedLtv, tellerLenderKey, tellerPoolFromLenderKey, 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, tickToAprNumber, tickToPrice, toDigest, toTermSheetInput, toVaultTermInput, tryParseEarnUid, unflattenLenderData, updateFeedStats, usdValue, usddIlkBytes32, usddKeyParts, usddLenderKey, validateTermSheet, validateTermSheets, validateUserData, vaultSharesToAssets, vaultTermInputFromEarnMarket, vaultTermInputFromSourceRow, vaultTraits, vaultVenue, venueBrand, venueBrandKey };
69848
70176
  //# sourceMappingURL=index.js.map
69849
70177
  //# sourceMappingURL=index.js.map