@1delta/margin-fetcher 5.0.82 → 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 +201 -8
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
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
|
|
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 *
|
|
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": [
|
|
@@ -56596,8 +56783,15 @@ var CHAINLINK_DECIMALS = 8;
|
|
|
56596
56783
|
var USD_PRICED_OVERRIDES = {
|
|
56597
56784
|
[Lender.COMPOUND_V3_AERO]: /* @__PURE__ */ new Set(["8453"]),
|
|
56598
56785
|
// BASE - prices already in USD
|
|
56599
|
-
[Lender.COMPOUND_V3_USDBC]: /* @__PURE__ */ new Set(["8453"])
|
|
56786
|
+
[Lender.COMPOUND_V3_USDBC]: /* @__PURE__ */ new Set(["8453"]),
|
|
56600
56787
|
// BASE - prices already in USD
|
|
56788
|
+
// Ronin WRON comet quotes in USD, NOT in its WRON base. Verified on-chain
|
|
56789
|
+
// 2026-09-16 (comet 0xc0Afdb…c0c0): USDC feed reads 1.00000071, WETH
|
|
56790
|
+
// 2415.66, WRON 0.0479 — all USD. Without this override every feed gets
|
|
56791
|
+
// multiplied by WRON/USD (~0.05), which shipped WRON at 9.4e-7 USD. Do NOT
|
|
56792
|
+
// generalize from the sibling WETH comet (0x4006eD…6DFE): that one IS
|
|
56793
|
+
// base-quoted (constant feed on WETH, RON/ETH = 2e-5) and needs the scaling.
|
|
56794
|
+
[Lender.COMPOUND_V3_WRON]: /* @__PURE__ */ new Set(["2020"])
|
|
56601
56795
|
};
|
|
56602
56796
|
function getCompoundV3Calls(chainId) {
|
|
56603
56797
|
const oraclesData = compoundV3OraclesData() ?? {};
|
|
@@ -56659,9 +56853,8 @@ function parseCompoundV3Results(data, meta, context) {
|
|
|
56659
56853
|
const baseAssetLc = queryMeta.baseAsset.toLowerCase();
|
|
56660
56854
|
const baseOracleKey = tokenList?.[baseAssetLc]?.assetGroup ?? `${chainId}-${baseAssetLc}`;
|
|
56661
56855
|
const baseAssetUSD = usdPrices[baseOracleKey] ?? usdPrices[baseAssetLc];
|
|
56662
|
-
if (baseAssetUSD)
|
|
56663
|
-
|
|
56664
|
-
}
|
|
56856
|
+
if (!baseAssetUSD) return;
|
|
56857
|
+
priceUSD = rawPrice * baseAssetUSD;
|
|
56665
56858
|
}
|
|
56666
56859
|
const updatedAtRaw = Array.isArray(rawResult) ? Number(rawResult[UPDATED_AT_INDEX]) : 0;
|
|
56667
56860
|
entries.push({
|
|
@@ -73200,7 +73393,7 @@ var readVaultSharePrices = async (chainId, addresses, multicallRetry) => {
|
|
|
73200
73393
|
};
|
|
73201
73394
|
|
|
73202
73395
|
// src/vaults/yield/annualize.ts
|
|
73203
|
-
var
|
|
73396
|
+
var YEAR_SECONDS14 = 365 * 24 * 60 * 60;
|
|
73204
73397
|
var SCALE = 10n ** 18n;
|
|
73205
73398
|
var appendSnapshot = (points, snap, options) => {
|
|
73206
73399
|
const maxPoints = options?.maxPoints ?? 90;
|
|
@@ -73229,7 +73422,7 @@ var computeVaultApr = (points, options) => {
|
|
|
73229
73422
|
if (pThen === 0n) return void 0;
|
|
73230
73423
|
const ratioScaled = BigInt(now.p) * SCALE / pThen;
|
|
73231
73424
|
const ratio = Number(ratioScaled) / 1e18;
|
|
73232
|
-
const apr = (ratio - 1) * (
|
|
73425
|
+
const apr = (ratio - 1) * (YEAR_SECONDS14 / windowSeconds);
|
|
73233
73426
|
return {
|
|
73234
73427
|
apr,
|
|
73235
73428
|
sharePriceNow: now.p,
|