@1delta/margin-fetcher 5.0.83 → 5.0.84

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
@@ -48765,8 +48765,129 @@ var sthusdFetcher = {
48765
48765
  };
48766
48766
  }
48767
48767
  };
48768
+ var CHAIN_ID13 = Chain.ETHEREUM_MAINNET;
48769
+ var HUMA_PST_FEED = "0x4be50be32db1510240d542f77c5b36ca0d0965e6";
48770
+ var HUMA_PST_KEY = "HUMA::PST";
48771
+ var HUMA_PST_GROUP_KEY = "PayFi Strategy Token::PST";
48772
+ var HUMA_PST_WINDOW_SECONDS = 30 * 86400;
48773
+ var MIN_WINDOW_SECONDS = 7 * 86400;
48774
+ var MAX_STALENESS_SECONDS = 14 * 86400;
48775
+ var PROBE_OFFSETS = [560, 620, 680, 720, 760, 820, 900, 1e3, 1200];
48776
+ var YEAR_SECONDS12 = 365 * 86400;
48777
+ var PHASE_SHIFT = 64n;
48778
+ var ROUND_MASK = (1n << PHASE_SHIFT) - 1n;
48779
+ var FEED_ABI = [
48780
+ {
48781
+ name: "latestRoundData",
48782
+ type: "function",
48783
+ stateMutability: "view",
48784
+ inputs: [],
48785
+ outputs: [
48786
+ { name: "roundId", type: "uint80" },
48787
+ { name: "answer", type: "int256" },
48788
+ { name: "startedAt", type: "uint256" },
48789
+ { name: "updatedAt", type: "uint256" },
48790
+ { name: "answeredInRound", type: "uint80" }
48791
+ ]
48792
+ },
48793
+ {
48794
+ name: "getRoundData",
48795
+ type: "function",
48796
+ stateMutability: "view",
48797
+ inputs: [{ name: "roundId", type: "uint80" }],
48798
+ outputs: [
48799
+ { name: "roundId", type: "uint80" },
48800
+ { name: "answer", type: "int256" },
48801
+ { name: "startedAt", type: "uint256" },
48802
+ { name: "updatedAt", type: "uint256" },
48803
+ { name: "answeredInRound", type: "uint80" }
48804
+ ]
48805
+ }
48806
+ ];
48807
+ var parseRound = (raw) => {
48808
+ if (!raw) return void 0;
48809
+ const tuple = Array.isArray(raw) ? raw : [
48810
+ raw.roundId,
48811
+ raw.answer,
48812
+ raw.startedAt,
48813
+ raw.updatedAt
48814
+ ];
48815
+ const answer = tuple[1];
48816
+ const updatedAt = tuple[3];
48817
+ if (typeof answer !== "bigint" || typeof updatedAt !== "bigint")
48818
+ return void 0;
48819
+ if (answer <= 0n || updatedAt <= 0n) return void 0;
48820
+ return { answer, updatedAt: Number(updatedAt) };
48821
+ };
48822
+ var windowAprFromRounds = (latest, candidates, nowSeconds, windowSeconds = HUMA_PST_WINDOW_SECONDS) => {
48823
+ if (nowSeconds - latest.updatedAt > MAX_STALENESS_SECONDS) {
48824
+ throw new Error(
48825
+ `Huma PST: feed stale \u2014 last update ${nowSeconds - latest.updatedAt}s ago`
48826
+ );
48827
+ }
48828
+ const cutoff = latest.updatedAt - windowSeconds;
48829
+ const older = candidates.filter((c) => c.updatedAt < latest.updatedAt).sort((a, b) => b.updatedAt - a.updatedAt);
48830
+ if (older.length === 0) throw new Error("Huma PST: no historical round");
48831
+ const start = older.find((c) => c.updatedAt <= cutoff) ?? older[older.length - 1];
48832
+ const dt = latest.updatedAt - start.updatedAt;
48833
+ if (dt < MIN_WINDOW_SECONDS) {
48834
+ throw new Error(`Huma PST: window too short (${dt}s)`);
48835
+ }
48836
+ const growth = Number(latest.answer * 10n ** 18n / start.answer) / 1e18 - 1;
48837
+ const apr = growth * YEAR_SECONDS12 * 100 / dt;
48838
+ if (!Number.isFinite(apr) || Math.abs(apr) > 100) {
48839
+ throw new Error(`Huma PST: implausible rate ${apr}`);
48840
+ }
48841
+ return apr;
48842
+ };
48843
+ var fetchPstAprOnChain = async () => {
48844
+ const [latestRaw] = await multicallRetryUniversal({
48845
+ chain: CHAIN_ID13,
48846
+ abi: FEED_ABI,
48847
+ calls: [{ address: HUMA_PST_FEED, name: "latestRoundData", params: [] }],
48848
+ allowFailure: false
48849
+ });
48850
+ const latestTuple = Array.isArray(latestRaw) ? latestRaw : [latestRaw?.roundId];
48851
+ const latestRoundId = latestTuple[0];
48852
+ const latest = parseRound(latestRaw);
48853
+ if (typeof latestRoundId !== "bigint" || !latest) {
48854
+ throw new Error("Huma PST: latestRoundData unreadable");
48855
+ }
48856
+ const phase = latestRoundId >> PHASE_SHIFT;
48857
+ const aggRound = latestRoundId & ROUND_MASK;
48858
+ const probeRounds = [
48859
+ ...new Set(
48860
+ PROBE_OFFSETS.map((off) => {
48861
+ const r = aggRound - BigInt(off);
48862
+ return r < 1n ? 1n : r;
48863
+ })
48864
+ )
48865
+ ];
48866
+ const results = await multicallRetryUniversal({
48867
+ chain: CHAIN_ID13,
48868
+ abi: FEED_ABI,
48869
+ calls: probeRounds.map((r) => ({
48870
+ address: HUMA_PST_FEED,
48871
+ name: "getRoundData",
48872
+ params: [phase << PHASE_SHIFT | r]
48873
+ })),
48874
+ allowFailure: true
48875
+ });
48876
+ const candidates = results.map(parseRound).filter((r) => r !== void 0);
48877
+ return windowAprFromRounds(latest, candidates, Math.floor(Date.now() / 1e3));
48878
+ };
48879
+ var humaPstFetcher = {
48880
+ label: "HUMA_PST",
48881
+ fetch: async () => {
48882
+ const apr = await fetchPstAprOnChain();
48883
+ return {
48884
+ [HUMA_PST_KEY]: apr,
48885
+ [HUMA_PST_GROUP_KEY]: apr
48886
+ };
48887
+ }
48888
+ };
48768
48889
  var RAY9 = 10n ** 27n;
48769
- var YEAR_SECONDS12 = 31536e3;
48890
+ var YEAR_SECONDS13 = 31536e3;
48770
48891
  var DSR_ABI = [
48771
48892
  {
48772
48893
  name: "dsr",
@@ -48794,7 +48915,7 @@ var SUSDD_GROUP_KEY = "Savings Usdd::sUSDD";
48794
48915
  var aprFromDsr = (dsr) => {
48795
48916
  if (dsr <= RAY9) return 0;
48796
48917
  const perSecond = Number(dsr - RAY9) / 1e27;
48797
- return perSecond * YEAR_SECONDS12 * 100;
48918
+ return perSecond * YEAR_SECONDS13 * 100;
48798
48919
  };
48799
48920
  var fetchChainDsr = async (chainId, pot) => {
48800
48921
  const [dsr] = await multicallRetryUniversal({
@@ -52675,6 +52796,72 @@ var SINGLE_CHAIN_ENTRIES = {
52675
52796
  withdrawalCooldownSeconds: 432e3,
52676
52797
  yieldFetcher: sthusdFetcher,
52677
52798
  yieldKey: STHUSD_KEY
52799
+ },
52800
+ {
52801
+ // Huma **PST** (PayFi Strategy Token), bridged. Huma 2.0 is a
52802
+ // SOLANA product: a permissionless USDC pool (no KYC) funding
52803
+ // short-dated cross-border payment receivables — originated almost
52804
+ // entirely by Arf, a Huma affiliate — whose yield is paid as a rising
52805
+ // PST price. 306.6M PST exist ($347M at 1.1325); **148.2M of them are
52806
+ // on Ethereum** through Chainlink CCIP, and 125.8M of THOSE sit as
52807
+ // collateral in Morpho Blue (84.4M, three listed markets at 86 % LLTV)
52808
+ // and Fluid (41.4M, vaults 165/166/169) — the Ethereum book is a
52809
+ // loop book, ~22M floats. Assessed + built 2026-09-16; see HUMA.md.
52810
+ //
52811
+ // This address is NOT a vault. It is Chainlink's `BurnMintERC20`,
52812
+ // whose only minter and burner is the CCIP `BurnMintTokenPool 1.6.1`
52813
+ // (`0xbe776c85…`, one lane, Solana): no `asset()`, no
52814
+ // `convertToAssets()`, no `owner()`, not verified on Sourcify. So there
52815
+ // is **no primary mint and no redemption on this chain at all** — the
52816
+ // ways in and out are the market (Fluid DEX PST-USDC: a $1M round trip
52817
+ // quoted ~4 bps total on KyberSwap at integration) or the bridge back
52818
+ // to Solana. Hence `secondaryMarketOnly`: the Re shape, but with an
52819
+ // even plainer reason — Re's mint is KYC-gated, this one does not
52820
+ // exist. `isMintable: false` states that fact, not a permission.
52821
+ //
52822
+ // Priced by Chainlink's **"PST-USDC Exchange Rate (Calculated)"**
52823
+ // proxy `0x4be50be3…` — the same feed both Morpho PST oracles wrap as
52824
+ // `BASE_FEED_1`, so the earn row and the lending rows cannot disagree
52825
+ // about what a PST is worth. It answers in **6 decimals** (hence
52826
+ // `priceOracleDecimals`), hourly, and — unlike Re's feeds — keeps its
52827
+ // FULL round history, which is where `humaPstFetcher` measures the
52828
+ // realized rate (7.7 % APR on every window since 2026-05-25). TRAP: the
52829
+ // feed's AGGREGATOR reverts `No access` for a contract caller, so any
52830
+ // multicall must target the PROXY, which is what this pins.
52831
+ //
52832
+ // `nav-attested`, asserted: the price is produced by Huma's own
52833
+ // off-chain Price Oracle and relayed by Chainlink — an operator-
52834
+ // published NAV over an off-chain receivables book with a "modest"
52835
+ // first-loss cover and no on-chain solvency invariant (the Theo /
52836
+ // Maple / Native trust class). Every consequence the label earns —
52837
+ // `nav-accrual` as the rate kind, `nav-drawdown` in the risks — is
52838
+ // true here.
52839
+ //
52840
+ // `withdrawalMode` / cooldown describe the exit a holder who BRIDGES
52841
+ // BACK gets on Solana: a redemption request the operator's autotask
52842
+ // settles "typically within 1 business day", SLA 7 days, under a global
52843
+ // daily cap that rejects further requests once hit. The pin is the SLA
52844
+ // worst case (the Re call); a bridge hop each way is on top. For a
52845
+ // holder on this chain the exit is the `market` route.
52846
+ reader: "nav-oracle",
52847
+ solvency: "nav-attested",
52848
+ address: "0x22ae3d9a738471f405169af055d31c687087d4c7",
52849
+ underlying: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
52850
+ // USDC
52851
+ priceOracle: HUMA_PST_FEED,
52852
+ priceOracleDecimals: 6,
52853
+ symbol: "PST",
52854
+ brand: "Huma",
52855
+ description: "Huma's PayFi Strategy Token, bridged from Solana over Chainlink CCIP: a share of Huma 2.0's USDC pool, funding short-dated cross-border payment receivables nearly all originated by Arf, a Huma affiliate; the fee is paid as a rising PST price set by Huma's oracle and relayed by Chainlink. There is no mint and no redemption on Ethereum: you enter and exit by TRADING PST (venue: Fluid DEX PST-USDC) against that NAV, or by bridging back to Solana, where redemption is an operator-settled request under a daily cap. Backing is unsecured receivables credit with a small first-loss cover.",
52856
+ decimals: 6,
52857
+ underlyingDecimals: 6,
52858
+ isRebasing: false,
52859
+ isMintable: false,
52860
+ secondaryMarketOnly: true,
52861
+ withdrawalMode: "request-based",
52862
+ withdrawalCooldownSeconds: 7 * 86400,
52863
+ yieldFetcher: humaPstFetcher,
52864
+ yieldKey: HUMA_PST_KEY
52678
52865
  }
52679
52866
  ],
52680
52867
  "100": [
@@ -73206,7 +73393,7 @@ var readVaultSharePrices = async (chainId, addresses, multicallRetry) => {
73206
73393
  };
73207
73394
 
73208
73395
  // src/vaults/yield/annualize.ts
73209
- var YEAR_SECONDS13 = 365 * 24 * 60 * 60;
73396
+ var YEAR_SECONDS14 = 365 * 24 * 60 * 60;
73210
73397
  var SCALE = 10n ** 18n;
73211
73398
  var appendSnapshot = (points, snap, options) => {
73212
73399
  const maxPoints = options?.maxPoints ?? 90;
@@ -73235,7 +73422,7 @@ var computeVaultApr = (points, options) => {
73235
73422
  if (pThen === 0n) return void 0;
73236
73423
  const ratioScaled = BigInt(now.p) * SCALE / pThen;
73237
73424
  const ratio = Number(ratioScaled) / 1e18;
73238
- const apr = (ratio - 1) * (YEAR_SECONDS13 / windowSeconds);
73425
+ const apr = (ratio - 1) * (YEAR_SECONDS14 / windowSeconds);
73239
73426
  return {
73240
73427
  apr,
73241
73428
  sharePriceNow: now.p,