@1delta/margin-fetcher 5.0.74 → 5.0.76
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.d.ts +58 -4
- package/dist/index.js +704 -15
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -21531,6 +21531,14 @@ function convertMidnightMarketsToResponse(raw, chainId, prices = {}, _additional
|
|
|
21531
21531
|
// Midnight is fixed-rate: expose the fixed borrow APR on stableBorrowRate
|
|
21532
21532
|
// too, so fixed-rate consumers pick it up like a term product.
|
|
21533
21533
|
stableBorrowRate: borrowAprPct,
|
|
21534
|
+
// The rate card is a BORROW-side fact, so it lives on the row that has a
|
|
21535
|
+
// borrow side — natively, not by a consumer matching `loanAddress`
|
|
21536
|
+
// against each row's asset. That match is what broke when the loan token
|
|
21537
|
+
// was also a collateral leg: the leg row carries the same token, so it
|
|
21538
|
+
// matched too and was served a "Fixed from X %" it cannot offer.
|
|
21539
|
+
// `params.market.terms` still carries the same card for readers of the
|
|
21540
|
+
// market-level shape; the collateral legs below never carry one.
|
|
21541
|
+
terms,
|
|
21534
21542
|
intrinsicYield: 0,
|
|
21535
21543
|
rewards: void 0,
|
|
21536
21544
|
decimals: config.loanDecimals,
|
|
@@ -48271,6 +48279,109 @@ var scrvusdFetcher = {
|
|
|
48271
48279
|
};
|
|
48272
48280
|
}
|
|
48273
48281
|
};
|
|
48282
|
+
var SUSDAT = "0xd166337499e176bbc38a1fbd113ab144e5bd2df7";
|
|
48283
|
+
var DEFILLAMA_POOL = "47e72726-3b2b-4fe6-b4a9-a26e1fcd9a50";
|
|
48284
|
+
var YEAR_SECONDS11 = 31536e3;
|
|
48285
|
+
var STRC_UNIT = 1e6;
|
|
48286
|
+
var SUSDAT_KEY = "Saturn sUSDat::SUSDAT";
|
|
48287
|
+
var SUSDAT_BRIDGED_KEY = "Staked Saturn USD::sUSDat";
|
|
48288
|
+
var VAULT_ABI = [
|
|
48289
|
+
{
|
|
48290
|
+
name: "vestingAmount",
|
|
48291
|
+
type: "function",
|
|
48292
|
+
stateMutability: "view",
|
|
48293
|
+
inputs: [],
|
|
48294
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
48295
|
+
},
|
|
48296
|
+
{
|
|
48297
|
+
name: "vestingPeriod",
|
|
48298
|
+
type: "function",
|
|
48299
|
+
stateMutability: "view",
|
|
48300
|
+
inputs: [],
|
|
48301
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
48302
|
+
},
|
|
48303
|
+
{
|
|
48304
|
+
name: "totalAssets",
|
|
48305
|
+
type: "function",
|
|
48306
|
+
stateMutability: "view",
|
|
48307
|
+
inputs: [],
|
|
48308
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
48309
|
+
},
|
|
48310
|
+
{
|
|
48311
|
+
name: "getStrcOracle",
|
|
48312
|
+
type: "function",
|
|
48313
|
+
stateMutability: "view",
|
|
48314
|
+
inputs: [],
|
|
48315
|
+
outputs: [{ name: "", type: "address" }]
|
|
48316
|
+
}
|
|
48317
|
+
];
|
|
48318
|
+
var STRC_ORACLE_ABI = [
|
|
48319
|
+
{
|
|
48320
|
+
name: "getPrice",
|
|
48321
|
+
type: "function",
|
|
48322
|
+
stateMutability: "view",
|
|
48323
|
+
inputs: [],
|
|
48324
|
+
outputs: [
|
|
48325
|
+
{ name: "price", type: "uint256" },
|
|
48326
|
+
{ name: "decimals", type: "uint8" }
|
|
48327
|
+
]
|
|
48328
|
+
}
|
|
48329
|
+
];
|
|
48330
|
+
var decodeStrcPrice = (cell) => {
|
|
48331
|
+
if (Array.isArray(cell) && cell.length >= 2) {
|
|
48332
|
+
return { price: BigInt(cell[0]), priceDecimals: Number(cell[1]) };
|
|
48333
|
+
}
|
|
48334
|
+
if (cell && typeof cell === "object") {
|
|
48335
|
+
const o = cell;
|
|
48336
|
+
if (o.price !== void 0 && o.decimals !== void 0) {
|
|
48337
|
+
return {
|
|
48338
|
+
price: BigInt(o.price),
|
|
48339
|
+
priceDecimals: Number(o.decimals)
|
|
48340
|
+
};
|
|
48341
|
+
}
|
|
48342
|
+
}
|
|
48343
|
+
throw new Error("sUSDat: unrecognised STRC oracle response shape");
|
|
48344
|
+
};
|
|
48345
|
+
var computeIncomeApr = async () => {
|
|
48346
|
+
const [vestingAmount, vestingPeriod, totalAssets, oracle] = await multicallRetryUniversal({
|
|
48347
|
+
chain: Chain.ETHEREUM_MAINNET,
|
|
48348
|
+
abi: VAULT_ABI,
|
|
48349
|
+
calls: [
|
|
48350
|
+
{ address: SUSDAT, name: "vestingAmount", params: [] },
|
|
48351
|
+
{ address: SUSDAT, name: "vestingPeriod", params: [] },
|
|
48352
|
+
{ address: SUSDAT, name: "totalAssets", params: [] },
|
|
48353
|
+
{ address: SUSDAT, name: "getStrcOracle", params: [] }
|
|
48354
|
+
],
|
|
48355
|
+
allowFailure: false
|
|
48356
|
+
});
|
|
48357
|
+
if (vestingPeriod <= 0n || totalAssets <= 0n) {
|
|
48358
|
+
throw new Error("sUSDat: empty vault or zero vesting period");
|
|
48359
|
+
}
|
|
48360
|
+
const [oracleCell] = await multicallRetryUniversal({
|
|
48361
|
+
chain: Chain.ETHEREUM_MAINNET,
|
|
48362
|
+
abi: STRC_ORACLE_ABI,
|
|
48363
|
+
calls: [{ address: oracle, name: "getPrice", params: [] }],
|
|
48364
|
+
allowFailure: false
|
|
48365
|
+
});
|
|
48366
|
+
const { price: price2, priceDecimals } = decodeStrcPrice(oracleCell);
|
|
48367
|
+
if (price2 <= 0n) throw new Error("sUSDat: STRC oracle returned no price");
|
|
48368
|
+
const strcPriceUsd = Number(price2) / 10 ** Number(priceDecimals);
|
|
48369
|
+
const rewardUsd = Number(vestingAmount) / STRC_UNIT * strcPriceUsd;
|
|
48370
|
+
const cyclesPerYear = YEAR_SECONDS11 / Number(vestingPeriod);
|
|
48371
|
+
const tvlUsd = Number(totalAssets) / 1e6;
|
|
48372
|
+
const apr = rewardUsd * cyclesPerYear / tvlUsd * 100;
|
|
48373
|
+
if (!Number.isFinite(apr) || apr < 0) {
|
|
48374
|
+
throw new Error("sUSDat: implausible income APR");
|
|
48375
|
+
}
|
|
48376
|
+
return apr;
|
|
48377
|
+
};
|
|
48378
|
+
var saturnFetcher = {
|
|
48379
|
+
label: "SATURN_SUSDAT",
|
|
48380
|
+
fetch: async () => {
|
|
48381
|
+
const apr = await computeIncomeApr().catch(() => fetchDefiLlamaApy(DEFILLAMA_POOL)).catch(() => 0);
|
|
48382
|
+
return { [SUSDAT_KEY]: apr, [SUSDAT_BRIDGED_KEY]: apr };
|
|
48383
|
+
}
|
|
48384
|
+
};
|
|
48274
48385
|
var thBill = "Theo Short Duration US Treasury Fund::THBILL";
|
|
48275
48386
|
var thBillBare = "thBILL::thBILL";
|
|
48276
48387
|
var THBILL_DEFILLAMA_POOL = "e17dab50-85b1-45e8-b4a5-b8ae7898c4a3";
|
|
@@ -48352,7 +48463,7 @@ var sthusdFetcher = {
|
|
|
48352
48463
|
}
|
|
48353
48464
|
};
|
|
48354
48465
|
var RAY9 = 10n ** 27n;
|
|
48355
|
-
var
|
|
48466
|
+
var YEAR_SECONDS12 = 31536e3;
|
|
48356
48467
|
var DSR_ABI = [
|
|
48357
48468
|
{
|
|
48358
48469
|
name: "dsr",
|
|
@@ -48380,7 +48491,7 @@ var SUSDD_GROUP_KEY = "Savings Usdd::sUSDD";
|
|
|
48380
48491
|
var aprFromDsr = (dsr) => {
|
|
48381
48492
|
if (dsr <= RAY9) return 0;
|
|
48382
48493
|
const perSecond = Number(dsr - RAY9) / 1e27;
|
|
48383
|
-
return perSecond *
|
|
48494
|
+
return perSecond * YEAR_SECONDS12 * 100;
|
|
48384
48495
|
};
|
|
48385
48496
|
var fetchChainDsr = async (chainId, pot) => {
|
|
48386
48497
|
const [dsr] = await multicallRetryUniversal({
|
|
@@ -50557,6 +50668,102 @@ var VESPER_ENTRIES = {
|
|
|
50557
50668
|
}
|
|
50558
50669
|
]
|
|
50559
50670
|
};
|
|
50671
|
+
var VENUS_CORE_COMPTROLLER = "0xfd36e2c2a6789db23113685031d7f16329158384";
|
|
50672
|
+
var VENUS_RESILIENT_ORACLE = "0x6592b5de802159f3e74b2486b091d11a8256ab8a";
|
|
50673
|
+
var XVS = "0xcf6bb5389c92bdda8a3747ddb454cb7a64626c63";
|
|
50674
|
+
var hubBase = {
|
|
50675
|
+
reader: "venus-hub",
|
|
50676
|
+
brand: "Venus",
|
|
50677
|
+
// Share decimals are 24 — `decimalsOffset(6)` on an 18-decimal underlying.
|
|
50678
|
+
// Getting this wrong is silent: the exchange rate reads 1e-6 of par.
|
|
50679
|
+
decimals: 24,
|
|
50680
|
+
underlyingDecimals: 18,
|
|
50681
|
+
isRebasing: false,
|
|
50682
|
+
isMintable: true,
|
|
50683
|
+
withdrawalMode: "instant-capped",
|
|
50684
|
+
// Asserted, not assumed — every leg is collateral-backed with an on-chain
|
|
50685
|
+
// liquidation threshold, incl. the FRV one whose docs read like unsecured
|
|
50686
|
+
// credit. See the note above for the live ratios and the two qualifications
|
|
50687
|
+
// that live in the descriptions instead.
|
|
50688
|
+
solvency: "overcollateralized"
|
|
50689
|
+
// No `yieldFetcher`: the rate is the groups' TVL-weighted `spotAPYBps()`,
|
|
50690
|
+
// which the reader computes from the same block's `totalAssets()` reads.
|
|
50691
|
+
// There is nothing off-chain to fall back to — the Hub publishes no APY
|
|
50692
|
+
// view by design, `api.venus.io` has no Hub route, and DefiLlama carries
|
|
50693
|
+
// only `venus-core-pool` / `venus-flux` pools.
|
|
50694
|
+
};
|
|
50695
|
+
var EXIT_PROSE = "Exits are same-transaction and free, but capped at the liquid legs: anything sitting in a Fixed-Rate Vault is locked until it matures, typically a 30-day term.";
|
|
50696
|
+
var BACKING_PROSE = "Every leg is overcollateralised, though not all of it is Venus: Flux lends through third-party Fluid, and a Fixed-Rate Vault is one institutional borrower posting custodial or real-world-asset collateral rather than a pool.";
|
|
50697
|
+
var VENUS_HUB_ENTRIES = {
|
|
50698
|
+
[Chain.BNB_SMART_CHAIN_MAINNET]: [
|
|
50699
|
+
{
|
|
50700
|
+
...hubBase,
|
|
50701
|
+
address: "0x18afdacf30f8671021dec4b78297e39d2fe87226",
|
|
50702
|
+
underlying: "0x55d398326f99059ff775485246999027b3197955",
|
|
50703
|
+
symbol: "vhUSDT",
|
|
50704
|
+
description: `Venus's USDT Liquidity Hub cascades one deposit across Venus Core lending, Fluid and Venus Fixed-Rate Vaults; the share price is the blend. ${EXIT_PROSE} ${BACKING_PROSE}`,
|
|
50705
|
+
venusHub: {
|
|
50706
|
+
yieldGroups: [
|
|
50707
|
+
"0xc9e6ced9589363f8dc5695be2c79ab4ddaecc94b",
|
|
50708
|
+
"0xe3df38e12e37ed80e1b3ccf2bdf84f9e1527ce14",
|
|
50709
|
+
"0x621ef38ce0c4e7060ff0bf3d609e3d46ec144be7"
|
|
50710
|
+
],
|
|
50711
|
+
core: {
|
|
50712
|
+
yieldGroup: "0xc9e6ced9589363f8dc5695be2c79ab4ddaecc94b",
|
|
50713
|
+
vToken: "0xfd5840cd36d94d7229439859c0112a4185bc0255",
|
|
50714
|
+
comptroller: VENUS_CORE_COMPTROLLER,
|
|
50715
|
+
oracle: VENUS_RESILIENT_ORACLE,
|
|
50716
|
+
rewardToken: XVS
|
|
50717
|
+
}
|
|
50718
|
+
}
|
|
50719
|
+
},
|
|
50720
|
+
{
|
|
50721
|
+
...hubBase,
|
|
50722
|
+
address: "0x9d2d9592cf8dfbf59107faab703d08494be14617",
|
|
50723
|
+
underlying: "0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d",
|
|
50724
|
+
symbol: "vhUSDC",
|
|
50725
|
+
description: `Venus's USDC Liquidity Hub cascades one deposit across Venus Core lending, Fluid and Venus Fixed-Rate Vaults; the share price is the blend. ${EXIT_PROSE} ${BACKING_PROSE}`,
|
|
50726
|
+
venusHub: {
|
|
50727
|
+
yieldGroups: [
|
|
50728
|
+
"0x299d9be7cefff91c68f13f267d525cfc18e965ef",
|
|
50729
|
+
"0xa65bb4b20542268b64cf08871a98d75342afe927",
|
|
50730
|
+
"0x438388847ee16850ab4f5b82dc7954c0d043b716"
|
|
50731
|
+
],
|
|
50732
|
+
core: {
|
|
50733
|
+
yieldGroup: "0x299d9be7cefff91c68f13f267d525cfc18e965ef",
|
|
50734
|
+
vToken: "0xeca88125a5adbe82614ffc12d0db554e2e2867c8",
|
|
50735
|
+
comptroller: VENUS_CORE_COMPTROLLER,
|
|
50736
|
+
oracle: VENUS_RESILIENT_ORACLE,
|
|
50737
|
+
rewardToken: XVS
|
|
50738
|
+
}
|
|
50739
|
+
}
|
|
50740
|
+
},
|
|
50741
|
+
{
|
|
50742
|
+
...hubBase,
|
|
50743
|
+
address: "0x0e5aa174d4f31b757a237eb1999de151596788b0",
|
|
50744
|
+
underlying: "0xce24439f2d9c6a2289f741120fe202248b666666",
|
|
50745
|
+
symbol: "vhU",
|
|
50746
|
+
description: `Venus's Liquidity Hub for U (United Stables) cascades one deposit across Venus Core lending, Fluid and Venus Fixed-Rate Vaults; the share price is the blend. ${EXIT_PROSE} ${BACKING_PROSE}`,
|
|
50747
|
+
venusHub: {
|
|
50748
|
+
yieldGroups: [
|
|
50749
|
+
"0x8a680f77a5367fa7cd33a02f51896cb1d55159c3",
|
|
50750
|
+
"0xe31b8851c3fa9b3dd39a04a2ed9493869a410616",
|
|
50751
|
+
"0x30908eddb9e94add7ac9944a0adda66d80b89143"
|
|
50752
|
+
],
|
|
50753
|
+
core: {
|
|
50754
|
+
yieldGroup: "0x8a680f77a5367fa7cd33a02f51896cb1d55159c3",
|
|
50755
|
+
vToken: "0x3d5e269787d562b74acc55f18bd26c5d09fa245e",
|
|
50756
|
+
comptroller: VENUS_CORE_COMPTROLLER,
|
|
50757
|
+
oracle: VENUS_RESILIENT_ORACLE,
|
|
50758
|
+
rewardToken: XVS
|
|
50759
|
+
}
|
|
50760
|
+
}
|
|
50761
|
+
}
|
|
50762
|
+
]
|
|
50763
|
+
};
|
|
50764
|
+
({
|
|
50765
|
+
[Chain.BNB_SMART_CHAIN_MAINNET]: "0x6d93fd479f2d37445cfbe132412e316a0364acc2"
|
|
50766
|
+
});
|
|
50560
50767
|
|
|
50561
50768
|
// src/vaults/savings/registry.ts
|
|
50562
50769
|
var stUsdGroup = {
|
|
@@ -51247,6 +51454,68 @@ var SINGLE_CHAIN_ENTRIES = {
|
|
|
51247
51454
|
yieldFetcher: apyxFetcher,
|
|
51248
51455
|
yieldKey: APYUSD_KEY
|
|
51249
51456
|
},
|
|
51457
|
+
// ---- Saturn (saturn.credit) — USDat / sUSDat ----------------------
|
|
51458
|
+
//
|
|
51459
|
+
// `USDat` is an M^0 extension token (a wrapped `$M` claim on tokenized
|
|
51460
|
+
// Treasuries) and `sUSDat` is the vault that stakes it into **Strategy's
|
|
51461
|
+
// STRC**, the variable-rate perpetual preferred stock, passing the
|
|
51462
|
+
// dividend through. Ethereum only: the same addresses on BNB (56) and
|
|
51463
|
+
// Monad (143) are bare LayerZero OFT mirrors whose entire 4626 surface
|
|
51464
|
+
// reverts, so staking round-trips to mainnet (the Cap / Apyx / Brix
|
|
51465
|
+
// precedent) — Monad nevertheless holds $31.1M of USDat.
|
|
51466
|
+
//
|
|
51467
|
+
// Registered `volatile`, and the reason is the whole assessment.
|
|
51468
|
+
// `totalAssets = usdatBalance + (strcBalance − unvested) × STRC price`,
|
|
51469
|
+
// and 96.5 % of NAV is STRC held outright — 723,435.68 STRC against just
|
|
51470
|
+
// $2.55M of actual USDat, with the implied $97.8893 matching Chainlink
|
|
51471
|
+
// STRC/USD to 0.01 %. So the solvency invariant is genuinely on-chain and
|
|
51472
|
+
// checkable (better than Spark V2 / Maple / Native, none of which can be),
|
|
51473
|
+
// and the share price nonetheless moves with a preferred stock. The income
|
|
51474
|
+
// leg is real and clockwork — 50 `transferInRewards` distributions over
|
|
51475
|
+
// 152.3 days at a 3.11-day cadence, 12.19 % APR, which is what DefiLlama's
|
|
51476
|
+
// 15.58 % and Saturn's "11 %+" both measure — while the vault's whole life
|
|
51477
|
+
// returned **+3.73 % with a −22.82 % max drawdown**. The rate published
|
|
51478
|
+
// here is the REALIZED one; see `saturnFetcher` for why there is no
|
|
51479
|
+
// DefiLlama fallback.
|
|
51480
|
+
//
|
|
51481
|
+
// NOT `secondaryMarketOnly`, and the fork test is why. USDat's own mint is
|
|
51482
|
+
// whitelist-gated (`isWhitelistEnabled()` true, `isAllowedToWrap(<random
|
|
51483
|
+
// EOA>)` false) — but that is a fact about the UNDERLYING, one level below
|
|
51484
|
+
// this row. STAKING is permissionless: `maxDeposit` is `uint256.max`,
|
|
51485
|
+
// `_deposit` consults no allowlist, and a fork deposit from an
|
|
51486
|
+
// unwhitelisted account mints at par. Marking the vault
|
|
51487
|
+
// `secondaryMarketOnly` made `/v1/actions/vaults/deposit` refuse a mint
|
|
51488
|
+
// that works, which is the Brix trap inverted — there a `maxDeposit` of
|
|
51489
|
+
// `uint.max` hid a gate, here a gate on a neighbouring contract hid an
|
|
51490
|
+
// open door. Acquiring the USDat is an ordinary swap (the Curve pool
|
|
51491
|
+
// round-trips 100k at −3 bps with USDat at $0.9997), i.e. a routing
|
|
51492
|
+
// question, not a property of this vault.
|
|
51493
|
+
//
|
|
51494
|
+
// Exit is `request-based` and there is exactly one protocol route:
|
|
51495
|
+
// `requestRedeem(shares, minUsdat)` escrows the shares and mints an
|
|
51496
|
+
// ERC-721 receipt, a `PROCESSOR_ROLE` batch sells STRC, then `claim`.
|
|
51497
|
+
// Measured latency ~24-25 h (Saturn documents 3-7 days) — pinned at 24 h
|
|
51498
|
+
// here and NOT read on-chain, because nothing on the queue publishes it:
|
|
51499
|
+
// it is an operator cadence, not a dial. Verified on-chain 2026-09-10.
|
|
51500
|
+
{
|
|
51501
|
+
reader: "saturn-vault",
|
|
51502
|
+
address: "0xd166337499e176bbc38a1fbd113ab144e5bd2df7",
|
|
51503
|
+
underlying: "0x23238f20b894f29041f48d88ee91131c395aaa71",
|
|
51504
|
+
// USDat
|
|
51505
|
+
symbol: "sUSDat",
|
|
51506
|
+
brand: "Saturn",
|
|
51507
|
+
solvency: "overcollateralized",
|
|
51508
|
+
description: "Saturn's staking vault: deposited USDat (a dollar backed by tokenized Treasuries) buys Strategy's STRC preferred stock, whose dividend is paid in every three days. Almost all the backing is that one stock, marked to market \u2014 so the share price falls when STRC does, and it has: a ~12% dividend over the first five months still returned only 3.7% annualised, after a 22.8% drawdown. Leaving is a request a Saturn operator settles in about a day by selling STRC, paying what that sale realises rather than the share price on the day you asked.",
|
|
51509
|
+
decimals: 18,
|
|
51510
|
+
underlyingDecimals: 6,
|
|
51511
|
+
isRebasing: false,
|
|
51512
|
+
isMintable: true,
|
|
51513
|
+
withdrawalMode: "request-based",
|
|
51514
|
+
withdrawalCooldownSeconds: 86400,
|
|
51515
|
+
withdrawQueue: "0x4bc9fec04f0f95e9b42a3ef18f3c96fb57923d2e",
|
|
51516
|
+
yieldFetcher: saturnFetcher,
|
|
51517
|
+
yieldKey: SUSDAT_KEY
|
|
51518
|
+
},
|
|
51250
51519
|
// ---- Strata (docs.strata.markets) — senior/junior risk tranches ----
|
|
51251
51520
|
//
|
|
51252
51521
|
// Six CDO markets, twelve ERC-4626 tranche tokens, all Ethereum.
|
|
@@ -51255,7 +51524,8 @@ var SINGLE_CHAIN_ENTRIES = {
|
|
|
51255
51524
|
// the senior earns a benchmark-floored rate (its `maxDeposit` is
|
|
51256
51525
|
// coverage-cap-gated), the junior takes the residual — levered
|
|
51257
51526
|
// upside AND first-loss capital (jrUSDat marked down to ~0.36
|
|
51258
|
-
// absorbing the 2026-07
|
|
51527
|
+
// absorbing the 2026-06/07 sUSDat drawdown — the SATURN VAULT fell
|
|
51528
|
+
// 22.8 %, USDat itself never lost its peg; junior redemptions pause when
|
|
51259
51529
|
// senior coverage drops below the market's minimum). Exits are
|
|
51260
51530
|
// two-legged and both escrow through the market's cooldown
|
|
51261
51531
|
// contracts, claimed via `finalize`: redeeming into the collateral
|
|
@@ -51419,7 +51689,7 @@ var SINGLE_CHAIN_ENTRIES = {
|
|
|
51419
51689
|
symbol: "srUSDat",
|
|
51420
51690
|
solvency: "tranched-senior",
|
|
51421
51691
|
brand: "Strata",
|
|
51422
|
-
description: "Strata's senior tranche over Saturn USDat (a Strategy-preferred-stock-backed dollar): fixed yield at 65% of the STRC dividend rate, junior-protected \u2014 the senior held its rate straight through the 2026-07
|
|
51692
|
+
description: "Strata's senior tranche over Saturn USDat (a Strategy-preferred-stock-backed dollar): fixed yield at 65% of the STRC dividend rate, junior-protected \u2014 the senior held its rate straight through the 2026-06/07 sUSDat drawdown that the junior absorbed. Exits claim through cooldown contracts (the sUSDat leg effectively instant) minus a 0\u20135 bps fee.",
|
|
51423
51693
|
decimals: 18,
|
|
51424
51694
|
underlyingDecimals: 6,
|
|
51425
51695
|
isRebasing: false,
|
|
@@ -51436,7 +51706,7 @@ var SINGLE_CHAIN_ENTRIES = {
|
|
|
51436
51706
|
symbol: "jrUSDat",
|
|
51437
51707
|
solvency: "tranched-junior",
|
|
51438
51708
|
brand: "Strata",
|
|
51439
|
-
description: "Strata's junior tranche over Saturn USDat \u2014 first-loss capital that proved it: the 2026-07
|
|
51709
|
+
description: "Strata's junior tranche over Saturn USDat \u2014 first-loss capital that proved it: the 2026-06/07 drawdown in the collateral \u2014 Saturn's sUSDat vault, which is marked to Strategy's STRC preferred stock and fell 22.8%; USDat itself held its peg \u2014 marked jrUSDat down to ~0.36 while the senior stayed whole, and its trailing APR is recovery-inflated. Exits claim through cooldown contracts and pause while senior coverage is below the market minimum.",
|
|
51440
51710
|
decimals: 18,
|
|
51441
51711
|
underlyingDecimals: 6,
|
|
51442
51712
|
isRebasing: false,
|
|
@@ -52433,6 +52703,10 @@ var SAVINGS_REGISTRY = (() => {
|
|
|
52433
52703
|
if (!out[chainId]) out[chainId] = [];
|
|
52434
52704
|
out[chainId].push(...entries);
|
|
52435
52705
|
}
|
|
52706
|
+
for (const [chainId, entries] of Object.entries(VENUS_HUB_ENTRIES)) {
|
|
52707
|
+
if (!out[chainId]) out[chainId] = [];
|
|
52708
|
+
out[chainId].push(...entries);
|
|
52709
|
+
}
|
|
52436
52710
|
return out;
|
|
52437
52711
|
})();
|
|
52438
52712
|
var savingsBalanceKind = (chainId, address) => {
|
|
@@ -64066,9 +64340,24 @@ var queuedRoute = (i) => ({
|
|
|
64066
64340
|
kind: "queued",
|
|
64067
64341
|
label: asyncLabel(i.withdrawalCooldownSeconds),
|
|
64068
64342
|
settlement: "async",
|
|
64069
|
-
waitSeconds: i.withdrawalCooldownSeconds
|
|
64343
|
+
waitSeconds: i.withdrawalCooldownSeconds,
|
|
64344
|
+
...i.exitMinAmount !== void 0 ? {
|
|
64345
|
+
minAmount: i.exitMinAmount,
|
|
64346
|
+
minAmountFormatted: i.exitMinAmountFormatted
|
|
64347
|
+
} : {}
|
|
64348
|
+
});
|
|
64349
|
+
var marketRoute = () => ({
|
|
64350
|
+
id: "market",
|
|
64351
|
+
kind: "market",
|
|
64352
|
+
label: "Sell on the market",
|
|
64353
|
+
settlement: "market",
|
|
64354
|
+
description: "The protocol's own mint and redeem are permissioned, so for a holder without that permission this is the route: sell the share token at whatever the book bids, with price impact that grows with size. It fills at the MARKET price, which is not the row's `exchangeRate` \u2014 that stays the NAV \u2014 so the leg must be built with a slippage bound."
|
|
64070
64355
|
});
|
|
64071
64356
|
var deriveExitRoutes = (i) => {
|
|
64357
|
+
const routes2 = deriveProtocolExitRoutes(i);
|
|
64358
|
+
return i.secondaryMarketOnly ? [...routes2, marketRoute()] : routes2;
|
|
64359
|
+
};
|
|
64360
|
+
var deriveProtocolExitRoutes = (i) => {
|
|
64072
64361
|
switch (i.withdrawalMode) {
|
|
64073
64362
|
// The instant leg pays the fee; the queue pays at par. That is the
|
|
64074
64363
|
// convention `SavingsVault.withdrawFeeBps` already documents — and
|
|
@@ -68473,6 +68762,166 @@ var YieldBasisAmmReadAbi = [
|
|
|
68473
68762
|
}
|
|
68474
68763
|
];
|
|
68475
68764
|
|
|
68765
|
+
// src/vaults/savings/abis/venusHub.ts
|
|
68766
|
+
var VenusHubReadAbi = [
|
|
68767
|
+
{
|
|
68768
|
+
name: "maxDeposit",
|
|
68769
|
+
type: "function",
|
|
68770
|
+
stateMutability: "view",
|
|
68771
|
+
inputs: [{ type: "address" }],
|
|
68772
|
+
outputs: [{ type: "uint256" }]
|
|
68773
|
+
},
|
|
68774
|
+
{
|
|
68775
|
+
name: "hubPaused",
|
|
68776
|
+
type: "function",
|
|
68777
|
+
stateMutability: "view",
|
|
68778
|
+
inputs: [],
|
|
68779
|
+
outputs: [{ type: "bool" }]
|
|
68780
|
+
},
|
|
68781
|
+
{
|
|
68782
|
+
name: "maxWithdrawalSize",
|
|
68783
|
+
type: "function",
|
|
68784
|
+
stateMutability: "view",
|
|
68785
|
+
inputs: [],
|
|
68786
|
+
outputs: [{ type: "uint256" }]
|
|
68787
|
+
},
|
|
68788
|
+
{
|
|
68789
|
+
name: "redeemFeeBps",
|
|
68790
|
+
type: "function",
|
|
68791
|
+
stateMutability: "view",
|
|
68792
|
+
inputs: [],
|
|
68793
|
+
outputs: [{ type: "uint16" }]
|
|
68794
|
+
},
|
|
68795
|
+
{
|
|
68796
|
+
name: "registeredYieldGroups",
|
|
68797
|
+
type: "function",
|
|
68798
|
+
stateMutability: "view",
|
|
68799
|
+
inputs: [],
|
|
68800
|
+
outputs: [{ type: "address[]" }]
|
|
68801
|
+
}
|
|
68802
|
+
];
|
|
68803
|
+
var VenusYieldGroupReadAbi = [
|
|
68804
|
+
{
|
|
68805
|
+
name: "maxWithdraw",
|
|
68806
|
+
type: "function",
|
|
68807
|
+
stateMutability: "view",
|
|
68808
|
+
inputs: [],
|
|
68809
|
+
outputs: [{ type: "uint256" }]
|
|
68810
|
+
},
|
|
68811
|
+
{
|
|
68812
|
+
name: "totalAssets",
|
|
68813
|
+
type: "function",
|
|
68814
|
+
stateMutability: "view",
|
|
68815
|
+
inputs: [],
|
|
68816
|
+
outputs: [{ type: "uint256" }]
|
|
68817
|
+
},
|
|
68818
|
+
{
|
|
68819
|
+
name: "spotAPYBps",
|
|
68820
|
+
type: "function",
|
|
68821
|
+
stateMutability: "view",
|
|
68822
|
+
inputs: [],
|
|
68823
|
+
outputs: [{ type: "uint64" }]
|
|
68824
|
+
},
|
|
68825
|
+
{
|
|
68826
|
+
name: "blocksPerYear",
|
|
68827
|
+
type: "function",
|
|
68828
|
+
stateMutability: "view",
|
|
68829
|
+
inputs: [],
|
|
68830
|
+
outputs: [{ type: "uint256" }]
|
|
68831
|
+
},
|
|
68832
|
+
{
|
|
68833
|
+
name: "resources",
|
|
68834
|
+
type: "function",
|
|
68835
|
+
stateMutability: "view",
|
|
68836
|
+
inputs: [],
|
|
68837
|
+
outputs: [{ type: "address[]" }]
|
|
68838
|
+
}
|
|
68839
|
+
];
|
|
68840
|
+
var VenusComptrollerRewardsAbi = [
|
|
68841
|
+
{
|
|
68842
|
+
name: "venusSupplySpeeds",
|
|
68843
|
+
type: "function",
|
|
68844
|
+
stateMutability: "view",
|
|
68845
|
+
inputs: [{ type: "address" }],
|
|
68846
|
+
outputs: [{ type: "uint256" }]
|
|
68847
|
+
},
|
|
68848
|
+
{
|
|
68849
|
+
name: "oracle",
|
|
68850
|
+
type: "function",
|
|
68851
|
+
stateMutability: "view",
|
|
68852
|
+
inputs: [],
|
|
68853
|
+
outputs: [{ type: "address" }]
|
|
68854
|
+
}
|
|
68855
|
+
];
|
|
68856
|
+
var VenusResilientOracleAbi = [
|
|
68857
|
+
{
|
|
68858
|
+
name: "getPrice",
|
|
68859
|
+
type: "function",
|
|
68860
|
+
stateMutability: "view",
|
|
68861
|
+
inputs: [{ type: "address" }],
|
|
68862
|
+
outputs: [{ type: "uint256" }]
|
|
68863
|
+
},
|
|
68864
|
+
{
|
|
68865
|
+
name: "getUnderlyingPrice",
|
|
68866
|
+
type: "function",
|
|
68867
|
+
stateMutability: "view",
|
|
68868
|
+
inputs: [{ type: "address" }],
|
|
68869
|
+
outputs: [{ type: "uint256" }]
|
|
68870
|
+
}
|
|
68871
|
+
];
|
|
68872
|
+
var VTokenSizeReadAbi = [
|
|
68873
|
+
{
|
|
68874
|
+
name: "totalSupply",
|
|
68875
|
+
type: "function",
|
|
68876
|
+
stateMutability: "view",
|
|
68877
|
+
inputs: [],
|
|
68878
|
+
outputs: [{ type: "uint256" }]
|
|
68879
|
+
},
|
|
68880
|
+
{
|
|
68881
|
+
name: "exchangeRateStored",
|
|
68882
|
+
type: "function",
|
|
68883
|
+
stateMutability: "view",
|
|
68884
|
+
inputs: [],
|
|
68885
|
+
outputs: [{ type: "uint256" }]
|
|
68886
|
+
},
|
|
68887
|
+
{
|
|
68888
|
+
name: "comptroller",
|
|
68889
|
+
type: "function",
|
|
68890
|
+
stateMutability: "view",
|
|
68891
|
+
inputs: [],
|
|
68892
|
+
outputs: [{ type: "address" }]
|
|
68893
|
+
}
|
|
68894
|
+
];
|
|
68895
|
+
|
|
68896
|
+
// src/vaults/savings/abis/saturn.ts
|
|
68897
|
+
var SaturnMinWithdrawalAbi = [
|
|
68898
|
+
{
|
|
68899
|
+
name: "MIN_WITHDRAWAL",
|
|
68900
|
+
type: "function",
|
|
68901
|
+
stateMutability: "view",
|
|
68902
|
+
inputs: [],
|
|
68903
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
68904
|
+
}
|
|
68905
|
+
];
|
|
68906
|
+
var SaturnDepositFeeAbi = [
|
|
68907
|
+
{
|
|
68908
|
+
name: "depositFeeBps",
|
|
68909
|
+
type: "function",
|
|
68910
|
+
stateMutability: "view",
|
|
68911
|
+
inputs: [],
|
|
68912
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
68913
|
+
}
|
|
68914
|
+
];
|
|
68915
|
+
var SaturnPreviewDepositAbi = [
|
|
68916
|
+
{
|
|
68917
|
+
name: "previewDeposit",
|
|
68918
|
+
type: "function",
|
|
68919
|
+
stateMutability: "view",
|
|
68920
|
+
inputs: [{ name: "assets", type: "uint256" }],
|
|
68921
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
68922
|
+
}
|
|
68923
|
+
];
|
|
68924
|
+
|
|
68476
68925
|
// src/vaults/savings/readers/erc4626Idle.ts
|
|
68477
68926
|
var readerErc4626Idle = (entry) => {
|
|
68478
68927
|
const shareUnit = 10n ** BigInt(entry.decimals);
|
|
@@ -68905,6 +69354,208 @@ var readerNativeWnlp = (entry) => {
|
|
|
68905
69354
|
};
|
|
68906
69355
|
};
|
|
68907
69356
|
|
|
69357
|
+
// src/vaults/savings/readers/saturn.ts
|
|
69358
|
+
var readerSaturnVault = (entry) => {
|
|
69359
|
+
const shareUnit = 10n ** BigInt(entry.decimals);
|
|
69360
|
+
const underlyingUnit = 10n ** BigInt(entry.underlyingDecimals ?? entry.decimals);
|
|
69361
|
+
return {
|
|
69362
|
+
calls: [
|
|
69363
|
+
{ address: entry.address, name: "totalAssets", params: [] },
|
|
69364
|
+
{ address: entry.address, name: "totalSupply", params: [] },
|
|
69365
|
+
{ address: entry.address, name: "convertToAssets", params: [shareUnit] },
|
|
69366
|
+
{
|
|
69367
|
+
address: entry.address,
|
|
69368
|
+
name: "previewDeposit",
|
|
69369
|
+
params: [underlyingUnit]
|
|
69370
|
+
},
|
|
69371
|
+
{ address: entry.address, name: "depositFeeBps", params: [] },
|
|
69372
|
+
{ address: entry.address, name: "MIN_WITHDRAWAL", params: [] }
|
|
69373
|
+
],
|
|
69374
|
+
abis: [
|
|
69375
|
+
Erc4626ReadAbi2,
|
|
69376
|
+
TotalSupplyAbi2,
|
|
69377
|
+
Erc4626ReadAbi2,
|
|
69378
|
+
SaturnPreviewDepositAbi,
|
|
69379
|
+
SaturnDepositFeeAbi,
|
|
69380
|
+
SaturnMinWithdrawalAbi
|
|
69381
|
+
],
|
|
69382
|
+
parse: ([assets, supply, rate, previewShares, feeBps, minWithdrawal]) => {
|
|
69383
|
+
const totalAssets = toBigInt15(assets);
|
|
69384
|
+
const totalSupply = toBigInt15(supply);
|
|
69385
|
+
const convertToAssetsRaw = toBigInt15(rate);
|
|
69386
|
+
if (totalAssets === void 0 || totalSupply === void 0 || convertToAssetsRaw === void 0) {
|
|
69387
|
+
return void 0;
|
|
69388
|
+
}
|
|
69389
|
+
const entryShares = toBigInt15(previewShares);
|
|
69390
|
+
const depositFeeBps = toBigInt15(feeBps);
|
|
69391
|
+
const exitMinAmount = toBigInt15(minWithdrawal);
|
|
69392
|
+
return {
|
|
69393
|
+
totalAssets,
|
|
69394
|
+
totalSupply,
|
|
69395
|
+
exchangeRate: convertToAssetsRaw * ONE_E1814 / underlyingUnit,
|
|
69396
|
+
// Shares minted for ONE underlying unit, net of the fee. Equals the
|
|
69397
|
+
// derived `1/exchangeRate` while the dial is 0, and diverges the
|
|
69398
|
+
// moment it is not.
|
|
69399
|
+
convertToShares: entryShares,
|
|
69400
|
+
depositFeeBps: depositFeeBps !== void 0 ? Number(depositFeeBps) : void 0,
|
|
69401
|
+
exitMinAmount
|
|
69402
|
+
};
|
|
69403
|
+
}
|
|
69404
|
+
};
|
|
69405
|
+
};
|
|
69406
|
+
|
|
69407
|
+
// src/vaults/savings/readers/venusHub.ts
|
|
69408
|
+
var NEUTRAL_PROBE2 = "0x000000000000000000000000000000000000dead";
|
|
69409
|
+
var BPS_TO_PCT = 100;
|
|
69410
|
+
var readerVenusHub = (entry) => {
|
|
69411
|
+
const shareUnit = 10n ** BigInt(entry.decimals);
|
|
69412
|
+
const underlyingUnit = 10n ** BigInt(entry.underlyingDecimals ?? entry.decimals);
|
|
69413
|
+
const cfg = entry.venusHub;
|
|
69414
|
+
const groups = cfg?.yieldGroups ?? [];
|
|
69415
|
+
const coreGroup = cfg?.core?.yieldGroup;
|
|
69416
|
+
const calls = [
|
|
69417
|
+
{ address: entry.address, name: "totalAssets", params: [] },
|
|
69418
|
+
{ address: entry.address, name: "totalSupply", params: [] },
|
|
69419
|
+
{ address: entry.address, name: "convertToAssets", params: [shareUnit] },
|
|
69420
|
+
{ address: entry.address, name: "maxDeposit", params: [NEUTRAL_PROBE2] },
|
|
69421
|
+
{ address: entry.address, name: "hubPaused", params: [] },
|
|
69422
|
+
{ address: entry.address, name: "maxWithdrawalSize", params: [] },
|
|
69423
|
+
{ address: entry.address, name: "redeemFeeBps", params: [] },
|
|
69424
|
+
{ address: entry.underlying, name: "balanceOf", params: [entry.address] }
|
|
69425
|
+
];
|
|
69426
|
+
const abis = [
|
|
69427
|
+
Erc4626ReadAbi2,
|
|
69428
|
+
TotalSupplyAbi2,
|
|
69429
|
+
Erc4626ReadAbi2,
|
|
69430
|
+
VenusHubReadAbi,
|
|
69431
|
+
VenusHubReadAbi,
|
|
69432
|
+
VenusHubReadAbi,
|
|
69433
|
+
VenusHubReadAbi,
|
|
69434
|
+
BalanceOfAbi
|
|
69435
|
+
];
|
|
69436
|
+
for (const group of groups) {
|
|
69437
|
+
calls.push({ address: group, name: "maxWithdraw", params: [] });
|
|
69438
|
+
calls.push({ address: group, name: "totalAssets", params: [] });
|
|
69439
|
+
calls.push({ address: group, name: "spotAPYBps", params: [] });
|
|
69440
|
+
abis.push(
|
|
69441
|
+
VenusYieldGroupReadAbi,
|
|
69442
|
+
VenusYieldGroupReadAbi,
|
|
69443
|
+
VenusYieldGroupReadAbi
|
|
69444
|
+
);
|
|
69445
|
+
}
|
|
69446
|
+
const emissionCallCount = cfg?.core ? 6 : 0;
|
|
69447
|
+
if (cfg?.core) {
|
|
69448
|
+
const { yieldGroup, vToken, comptroller, oracle, rewardToken } = cfg.core;
|
|
69449
|
+
calls.push({ address: yieldGroup, name: "blocksPerYear", params: [] });
|
|
69450
|
+
calls.push({
|
|
69451
|
+
address: comptroller,
|
|
69452
|
+
name: "venusSupplySpeeds",
|
|
69453
|
+
params: [vToken]
|
|
69454
|
+
});
|
|
69455
|
+
calls.push({ address: oracle, name: "getPrice", params: [rewardToken] });
|
|
69456
|
+
calls.push({
|
|
69457
|
+
address: oracle,
|
|
69458
|
+
name: "getUnderlyingPrice",
|
|
69459
|
+
params: [vToken]
|
|
69460
|
+
});
|
|
69461
|
+
calls.push({ address: vToken, name: "totalSupply", params: [] });
|
|
69462
|
+
calls.push({ address: vToken, name: "exchangeRateStored", params: [] });
|
|
69463
|
+
abis.push(
|
|
69464
|
+
VenusYieldGroupReadAbi,
|
|
69465
|
+
VenusComptrollerRewardsAbi,
|
|
69466
|
+
VenusResilientOracleAbi,
|
|
69467
|
+
VenusResilientOracleAbi,
|
|
69468
|
+
VTokenSizeReadAbi,
|
|
69469
|
+
VTokenSizeReadAbi
|
|
69470
|
+
);
|
|
69471
|
+
}
|
|
69472
|
+
return {
|
|
69473
|
+
calls,
|
|
69474
|
+
abis,
|
|
69475
|
+
parse: (slice2) => {
|
|
69476
|
+
const totalAssets = toBigInt15(slice2[0]);
|
|
69477
|
+
const totalSupply = toBigInt15(slice2[1]);
|
|
69478
|
+
const convertToAssetsRaw = toBigInt15(slice2[2]);
|
|
69479
|
+
if (totalAssets === void 0 || totalSupply === void 0 || convertToAssetsRaw === void 0) {
|
|
69480
|
+
return void 0;
|
|
69481
|
+
}
|
|
69482
|
+
const paused = slice2[4] === true;
|
|
69483
|
+
const maxWithdrawalSize = toBigInt15(slice2[5]);
|
|
69484
|
+
const redeemFeeBps = toBigInt15(slice2[6]);
|
|
69485
|
+
const idle = toBigInt15(slice2[7]);
|
|
69486
|
+
const depositCapacity = toBigInt15(slice2[3]);
|
|
69487
|
+
let groupLiquid = 0n;
|
|
69488
|
+
let weightedBps = 0n;
|
|
69489
|
+
let rateWeight = 0n;
|
|
69490
|
+
let coreGroupAssets = 0n;
|
|
69491
|
+
let groupsOk = groups.length > 0;
|
|
69492
|
+
for (let i = 0; i < groups.length; i++) {
|
|
69493
|
+
const base = 8 + i * 3;
|
|
69494
|
+
const liquid = toBigInt15(slice2[base]);
|
|
69495
|
+
const assets = toBigInt15(slice2[base + 1]);
|
|
69496
|
+
const apyBps = toBigInt15(slice2[base + 2]);
|
|
69497
|
+
if (liquid === void 0 || assets === void 0 || apyBps === void 0) {
|
|
69498
|
+
groupsOk = false;
|
|
69499
|
+
continue;
|
|
69500
|
+
}
|
|
69501
|
+
if (groups[i] === coreGroup) coreGroupAssets = assets;
|
|
69502
|
+
groupLiquid += liquid;
|
|
69503
|
+
weightedBps += apyBps * assets;
|
|
69504
|
+
rateWeight += assets;
|
|
69505
|
+
}
|
|
69506
|
+
let instantRedeemCapacity;
|
|
69507
|
+
if (groupsOk && idle !== void 0) {
|
|
69508
|
+
const aggregate = groupLiquid + idle;
|
|
69509
|
+
instantRedeemCapacity = maxWithdrawalSize !== void 0 && maxWithdrawalSize < aggregate ? maxWithdrawalSize : aggregate;
|
|
69510
|
+
}
|
|
69511
|
+
const supplyRate = rateWeight > 0n ? Number(weightedBps * 1000000n / rateWeight) / 1e6 / BPS_TO_PCT : void 0;
|
|
69512
|
+
return {
|
|
69513
|
+
totalAssets,
|
|
69514
|
+
totalSupply,
|
|
69515
|
+
exchangeRate: convertToAssetsRaw * ONE_E1814 / underlyingUnit,
|
|
69516
|
+
...supplyRate !== void 0 ? { supplyRate } : {},
|
|
69517
|
+
...instantRedeemCapacity !== void 0 ? {
|
|
69518
|
+
instantRedeemCapacity: paused ? 0n : instantRedeemCapacity,
|
|
69519
|
+
instantRedeemEnabled: !paused,
|
|
69520
|
+
// Retained in the vault rather than paid out, and 0 on every
|
|
69521
|
+
// live Hub — but it IS deducted from a redeemer's payout, so
|
|
69522
|
+
// it belongs on the same field every other two-legged row uses.
|
|
69523
|
+
withdrawFeeBps: redeemFeeBps !== void 0 ? Number(redeemFeeBps) : 0
|
|
69524
|
+
} : {},
|
|
69525
|
+
...depositCapacity !== void 0 ? { depositCapacity } : {},
|
|
69526
|
+
...cfg?.core ? {
|
|
69527
|
+
strandedRewardsRate: parseStrandedRewards(
|
|
69528
|
+
slice2,
|
|
69529
|
+
calls.length - emissionCallCount,
|
|
69530
|
+
coreGroupAssets,
|
|
69531
|
+
totalAssets
|
|
69532
|
+
)
|
|
69533
|
+
} : {}
|
|
69534
|
+
};
|
|
69535
|
+
}
|
|
69536
|
+
};
|
|
69537
|
+
};
|
|
69538
|
+
var parseStrandedRewards = (slice2, base, coreGroupAssets, hubTotalAssets) => {
|
|
69539
|
+
const blocksPerYear = toBigInt15(slice2[base]);
|
|
69540
|
+
const supplySpeed = toBigInt15(slice2[base + 1]);
|
|
69541
|
+
const rewardPrice = toBigInt15(slice2[base + 2]);
|
|
69542
|
+
const underlyingPrice = toBigInt15(slice2[base + 3]);
|
|
69543
|
+
const vTokenSupply = toBigInt15(slice2[base + 4]);
|
|
69544
|
+
const exchangeRateStored = toBigInt15(slice2[base + 5]);
|
|
69545
|
+
if (blocksPerYear === void 0 || supplySpeed === void 0 || rewardPrice === void 0 || underlyingPrice === void 0 || vTokenSupply === void 0 || exchangeRateStored === void 0) {
|
|
69546
|
+
return void 0;
|
|
69547
|
+
}
|
|
69548
|
+
if (supplySpeed === 0n) return 0;
|
|
69549
|
+
const rewardsPerYearUsd = supplySpeed * blocksPerYear * rewardPrice;
|
|
69550
|
+
const suppliedRaw = vTokenSupply * exchangeRateStored / ONE_E1814;
|
|
69551
|
+
const suppliedUsd = suppliedRaw * underlyingPrice;
|
|
69552
|
+
if (suppliedUsd === 0n || hubTotalAssets === 0n) return void 0;
|
|
69553
|
+
const marketAprPct = Number(rewardsPerYearUsd * 1000000000n / suppliedUsd) / 1e9;
|
|
69554
|
+
const hubShare = Number(coreGroupAssets * 1000000000n / hubTotalAssets) / 1e9;
|
|
69555
|
+
const scale3 = hubShare > 1 ? 1 : hubShare;
|
|
69556
|
+
return marketAprPct * scale3 * 100;
|
|
69557
|
+
};
|
|
69558
|
+
|
|
68908
69559
|
// src/vaults/savings/readers/vesperPool.ts
|
|
68909
69560
|
var readerVesperPool = (entry) => {
|
|
68910
69561
|
const underlyingUnit = 10n ** BigInt(entry.underlyingDecimals ?? entry.decimals);
|
|
@@ -69038,6 +69689,10 @@ var buildReader2 = (entry) => {
|
|
|
69038
69689
|
return readerWrenNav(entry);
|
|
69039
69690
|
case "vesper-pool":
|
|
69040
69691
|
return readerVesperPool(entry);
|
|
69692
|
+
case "venus-hub":
|
|
69693
|
+
return readerVenusHub(entry);
|
|
69694
|
+
case "saturn-vault":
|
|
69695
|
+
return readerSaturnVault(entry);
|
|
69041
69696
|
case "erc4626-cooldown":
|
|
69042
69697
|
return readerErc4626Cooldown(entry);
|
|
69043
69698
|
case "erc4626-idle":
|
|
@@ -69090,7 +69745,7 @@ var fetchSavingsVaults = async (chainId, multicallRetry, prices = {}, tokenList
|
|
|
69090
69745
|
const underlyingLc = entry.underlying.toLowerCase();
|
|
69091
69746
|
const asset = tokenList[underlyingLc];
|
|
69092
69747
|
const priceUsd = prices[underlyingLc];
|
|
69093
|
-
const supplyRate = aprByAddress[addressLc] ?? 0;
|
|
69748
|
+
const supplyRate = state.supplyRate ?? aprByAddress[addressLc] ?? 0;
|
|
69094
69749
|
const rewardsRate = 0;
|
|
69095
69750
|
const depositRate = supplyRate + rewardsRate;
|
|
69096
69751
|
const shareDec = entry.decimals;
|
|
@@ -69112,7 +69767,7 @@ var fetchSavingsVaults = async (chainId, multicallRetry, prices = {}, tokenList
|
|
|
69112
69767
|
Number(liquidityAmount * 1000000n / state.totalAssets) / 1e6
|
|
69113
69768
|
) : 1;
|
|
69114
69769
|
const convertToAssets = state.exchangeRate * underlyingUnit / ONE_E1815;
|
|
69115
|
-
const convertToShares = state.exchangeRate > 0n ? ONE_E1815 * shareUnit / state.exchangeRate : 0n;
|
|
69770
|
+
const convertToShares = state.convertToShares ?? (state.exchangeRate > 0n ? ONE_E1815 * shareUnit / state.exchangeRate : 0n);
|
|
69116
69771
|
const depositCapacity = state.depositCapacity?.toString();
|
|
69117
69772
|
const depositCapacityFormatted = state.depositCapacity !== void 0 ? Number(state.depositCapacity) / 10 ** underlyingDec : void 0;
|
|
69118
69773
|
const depositCapacityUsd = depositCapacityFormatted !== void 0 && priceUsd !== void 0 ? depositCapacityFormatted * priceUsd : void 0;
|
|
@@ -69148,6 +69803,9 @@ var fetchSavingsVaults = async (chainId, multicallRetry, prices = {}, tokenList
|
|
|
69148
69803
|
supplyRate,
|
|
69149
69804
|
rewardsRate,
|
|
69150
69805
|
depositRate,
|
|
69806
|
+
// NOT part of `depositRate` — it is the incentive the vault's position
|
|
69807
|
+
// earns and the depositor does not. See the field's docstring.
|
|
69808
|
+
strandedRewardsRate: state.strandedRewardsRate,
|
|
69151
69809
|
// Opt-IN, not opt-out: a new bespoke reader exists precisely
|
|
69152
69810
|
// because its token is not a conforming vault, so the default for
|
|
69153
69811
|
// an unlisted reader must be `false`. `erc4626-idle`,
|
|
@@ -69156,7 +69814,11 @@ var fetchSavingsVaults = async (chainId, multicallRetry, prices = {}, tokenList
|
|
|
69156
69814
|
// limit view / the exit lock), so they count; Native's wNLP and Re's
|
|
69157
69815
|
// NAV-oracle tokens revert on
|
|
69158
69816
|
// `asset()`/`totalAssets()`/`convertToAssets()` and do not.
|
|
69159
|
-
isErc4626: entry.reader === void 0 || entry.reader === "erc4626" || entry.reader === "erc4626-cooldown" || entry.reader === "erc4626-idle" || entry.reader === "erc4626-withdraw-limit" || //
|
|
69817
|
+
isErc4626: entry.reader === void 0 || entry.reader === "erc4626" || entry.reader === "erc4626-cooldown" || entry.reader === "erc4626-idle" || entry.reader === "erc4626-withdraw-limit" || // Venus's Liquidity Hub IS a conforming 4626 on every leg
|
|
69818
|
+
// (`deposit(assets, receiver)`, `redeem(shares, receiver, owner)`);
|
|
69819
|
+
// the bespoke reader exists for the FRV lock, the rate blend and the
|
|
69820
|
+
// emission read, not because the standard surface is missing.
|
|
69821
|
+
entry.reader === "venus-hub" || // hbfUSD / pbfUSD ARE conforming 4626 — the bespoke reader exists for
|
|
69160
69822
|
// the epoch ledger and the share-denominated supply cap, not because
|
|
69161
69823
|
// the standard surface is missing. bfBTC (`bitfi-bfbtc`) is the
|
|
69162
69824
|
// opposite and correctly falls through to `false`.
|
|
@@ -69172,6 +69834,7 @@ var fetchSavingsVaults = async (chainId, multicallRetry, prices = {}, tokenList
|
|
|
69172
69834
|
// queue window is per-asset and governance-mutable.
|
|
69173
69835
|
withdrawalCooldownSeconds: state.withdrawalCooldownSeconds ?? entry.withdrawalCooldownSeconds,
|
|
69174
69836
|
withdrawFeeBps: state.withdrawFeeBps,
|
|
69837
|
+
depositFeeBps: state.depositFeeBps,
|
|
69175
69838
|
// Term-sheet inputs that no reader can derive — see the registry's
|
|
69176
69839
|
// docstrings. Passed through verbatim so the sheet can stop hardcoding
|
|
69177
69840
|
// "compounds per second" and "needs an approval" for every vault.
|
|
@@ -69196,7 +69859,13 @@ var fetchSavingsVaults = async (chainId, multicallRetry, prices = {}, tokenList
|
|
|
69196
69859
|
withdrawalCooldownSeconds: state.withdrawalCooldownSeconds ?? entry.withdrawalCooldownSeconds,
|
|
69197
69860
|
liquidity: liquidityRaw,
|
|
69198
69861
|
liquidityFormatted,
|
|
69199
|
-
liquidityUsd
|
|
69862
|
+
liquidityUsd,
|
|
69863
|
+
// The floor that decides whether a single-route exit is reachable.
|
|
69864
|
+
exitMinAmount: state.exitMinAmount?.toString(),
|
|
69865
|
+
exitMinAmountFormatted: state.exitMinAmount !== void 0 ? Number(state.exitMinAmount) / 10 ** underlyingDec : void 0,
|
|
69866
|
+
// Adds the `market` leg — the only route a holder without the
|
|
69867
|
+
// protocol's mint/redeem permission actually has.
|
|
69868
|
+
secondaryMarketOnly: entry.secondaryMarketOnly
|
|
69200
69869
|
}),
|
|
69201
69870
|
resolveSelfOnly(chainId, entry.address)
|
|
69202
69871
|
),
|
|
@@ -70251,8 +70920,20 @@ var VOLATILE_VAULT_OVERRIDES = /* @__PURE__ */ new Set([
|
|
|
70251
70920
|
// yb-cbBTC
|
|
70252
70921
|
"1-0x771f7290428d830ecd41e980745c327e507823ec",
|
|
70253
70922
|
// yb-tBTC
|
|
70254
|
-
"1-0x2b9c9f3bdceb5d8e36a4704f08a78fca53343cea"
|
|
70923
|
+
"1-0x2b9c9f3bdceb5d8e36a4704f08a78fca53343cea",
|
|
70255
70924
|
// yb-WETH
|
|
70925
|
+
// Saturn sUSDat — a savings vault whose assets are 96.5 % Strategy's STRC
|
|
70926
|
+
// preferred stock, held outright and MARKED to an oracle
|
|
70927
|
+
// (`totalAssets = usdatBalance + (strcBalance − unvested) × price`). Unlike
|
|
70928
|
+
// Yield Basis this one has a real, clockwork income leg — 50
|
|
70929
|
+
// `transferInRewards` distributions on a 3.11-day cadence, 12.19 % APR
|
|
70930
|
+
// measured over 152 days, which is what DefiLlama's 15.58 % reports — and it
|
|
70931
|
+
// is still not a yield-bearing row, because the mark moves further than the
|
|
70932
|
+
// coupon does. Over the vault's whole life: +3.73 % realized APR, −22.82 %
|
|
70933
|
+
// max drawdown (1.00954 on 2026-05-15 → 0.77915 on 2026-06-28), 33 % of
|
|
70934
|
+
// two-day samples negative. See SATURN.md.
|
|
70935
|
+
"1-0xd166337499e176bbc38a1fbd113ab144e5bd2df7"
|
|
70936
|
+
// sUSDat
|
|
70256
70937
|
]);
|
|
70257
70938
|
var STABLECOIN_SYMBOLS = /* @__PURE__ */ new Set([
|
|
70258
70939
|
// USD majors
|
|
@@ -70348,6 +71029,12 @@ var STABLECOIN_SYMBOLS = /* @__PURE__ */ new Set([
|
|
|
70348
71029
|
"USG",
|
|
70349
71030
|
"BOB"
|
|
70350
71031
|
]);
|
|
71032
|
+
var STABLECOIN_UNDERLYING_OVERRIDES = /* @__PURE__ */ new Set([
|
|
71033
|
+
// United Stables (`U`) — a USD stablecoin on BNB Chain, a Venus Core market
|
|
71034
|
+
// and the underlying of the vhU Liquidity Hub. Priced at $0.999 by Venus's
|
|
71035
|
+
// own ResilientOracle.
|
|
71036
|
+
"56-0xce24439f2d9c6a2289f741120fe202248b666666"
|
|
71037
|
+
]);
|
|
70351
71038
|
var normalizeSymbol = (s) => (s ?? "").trim().toUpperCase();
|
|
70352
71039
|
var isStablecoinSymbol = (symbol) => {
|
|
70353
71040
|
const s = normalizeSymbol(symbol);
|
|
@@ -70358,7 +71045,8 @@ var isStablecoinSymbol = (symbol) => {
|
|
|
70358
71045
|
var classifyVault = (input) => {
|
|
70359
71046
|
const key3 = `${input.chainId}-${input.address.toLowerCase()}`;
|
|
70360
71047
|
const yieldProfile2 = VOLATILE_VAULT_OVERRIDES.has(key3) || VOLATILE_PROVIDERS.has(input.provider) ? "volatile" : "yield-bearing";
|
|
70361
|
-
const
|
|
71048
|
+
const underlyingKey = input.underlyingAddress !== void 0 ? `${input.chainId}-${input.underlyingAddress.toLowerCase()}` : void 0;
|
|
71049
|
+
const denomination2 = underlyingKey !== void 0 && STABLECOIN_UNDERLYING_OVERRIDES.has(underlyingKey) || isStablecoinSymbol(input.underlyingSymbol) ? "stable" : "volatile";
|
|
70362
71050
|
return { yieldProfile: yieldProfile2, denomination: denomination2 };
|
|
70363
71051
|
};
|
|
70364
71052
|
var stampVaultClassification = (data, chainId, tokenList = {}) => {
|
|
@@ -70379,7 +71067,8 @@ var stampVaultClassification = (data, chainId, tokenList = {}) => {
|
|
|
70379
71067
|
provider,
|
|
70380
71068
|
chainId,
|
|
70381
71069
|
address: v.address,
|
|
70382
|
-
underlyingSymbol: v.asset?.symbol ?? v.symbol
|
|
71070
|
+
underlyingSymbol: v.asset?.symbol ?? v.symbol,
|
|
71071
|
+
underlyingAddress: v.underlying
|
|
70383
71072
|
});
|
|
70384
71073
|
v.yieldProfile = c.yieldProfile;
|
|
70385
71074
|
v.denomination = c.denomination;
|
|
@@ -72110,7 +72799,7 @@ var readVaultSharePrices = async (chainId, addresses, multicallRetry) => {
|
|
|
72110
72799
|
};
|
|
72111
72800
|
|
|
72112
72801
|
// src/vaults/yield/annualize.ts
|
|
72113
|
-
var
|
|
72802
|
+
var YEAR_SECONDS13 = 365 * 24 * 60 * 60;
|
|
72114
72803
|
var SCALE = 10n ** 18n;
|
|
72115
72804
|
var appendSnapshot = (points, snap, options) => {
|
|
72116
72805
|
const maxPoints = options?.maxPoints ?? 90;
|
|
@@ -72139,7 +72828,7 @@ var computeVaultApr = (points, options) => {
|
|
|
72139
72828
|
if (pThen === 0n) return void 0;
|
|
72140
72829
|
const ratioScaled = BigInt(now.p) * SCALE / pThen;
|
|
72141
72830
|
const ratio = Number(ratioScaled) / 1e18;
|
|
72142
|
-
const apr = (ratio - 1) * (
|
|
72831
|
+
const apr = (ratio - 1) * (YEAR_SECONDS13 / windowSeconds);
|
|
72143
72832
|
return {
|
|
72144
72833
|
apr,
|
|
72145
72834
|
sharePriceNow: now.p,
|