@1delta/margin-fetcher 5.0.12 → 5.0.14
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 +124 -6
- package/dist/index.js +309 -91
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -23006,6 +23006,12 @@ var bandGrid = (m) => {
|
|
|
23006
23006
|
const set = /* @__PURE__ */ new Set([...BANDS_ENDPOINTS, bandsFor(m)]);
|
|
23007
23007
|
return [...set].sort((a, b) => a - b);
|
|
23008
23008
|
};
|
|
23009
|
+
var MIN_BANDS = 4;
|
|
23010
|
+
var MAX_BANDS = 50;
|
|
23011
|
+
var LTV_CURVE_BANDS = Array.from(
|
|
23012
|
+
{ length: MAX_BANDS - MIN_BANDS + 1 },
|
|
23013
|
+
(_3, i) => MIN_BANDS + i
|
|
23014
|
+
);
|
|
23009
23015
|
var maxBorrowableCall = (m, oneUnit, n) => m.version === 1 ? {
|
|
23010
23016
|
address: m.controller,
|
|
23011
23017
|
name: "max_borrowable",
|
|
@@ -23025,7 +23031,8 @@ var buildBandLtv = (market) => {
|
|
|
23025
23031
|
// negligible at any realistic position size and converges as it grows.
|
|
23026
23032
|
collateral: 10n ** BigInt(market.collateralDecimals + 3),
|
|
23027
23033
|
collateralDecimals: market.collateralDecimals,
|
|
23028
|
-
|
|
23034
|
+
// The FULL domain, not the multicall grid — see `LTV_CURVE_BANDS`.
|
|
23035
|
+
bandCounts: LTV_CURVE_BANDS
|
|
23029
23036
|
});
|
|
23030
23037
|
return Object.keys(curve).length > 0 ? curve : null;
|
|
23031
23038
|
} catch {
|
|
@@ -24345,6 +24352,23 @@ function convertLlamaLendMarketsToResponse(raw, chainId, prices = {}, additional
|
|
|
24345
24352
|
// --- LlamaLend descriptor (consumed by the calldata builders,
|
|
24346
24353
|
// the leverage sizer and worker-api resolvers) ---
|
|
24347
24354
|
llamalend: {
|
|
24355
|
+
/**
|
|
24356
|
+
* The market's LLAMMA, and the ONLY readable oracle for it:
|
|
24357
|
+
* `price_oracle()` lives here, quoted in the BORROWED token.
|
|
24358
|
+
*
|
|
24359
|
+
* Carried on the descriptor — not only under `addresses` — because
|
|
24360
|
+
* this object is what consumers persist verbatim (yield-tracer
|
|
24361
|
+
* serialises it into the `llamalend` column of the shared isolated-
|
|
24362
|
+
* market table) and the oracle-price path resolves the AMM from it.
|
|
24363
|
+
* Omitting it does not fail loudly: the reader finds `undefined`,
|
|
24364
|
+
* skips the market, and the lender ends up with NO prices at all
|
|
24365
|
+
* while every row still looks present and correct.
|
|
24366
|
+
*
|
|
24367
|
+
* Do not "clean this up" as a duplicate of `addresses.amm` — the two
|
|
24368
|
+
* are read by different consumers, and only this one survives into
|
|
24369
|
+
* the descriptor column.
|
|
24370
|
+
*/
|
|
24371
|
+
amm: market.amm,
|
|
24348
24372
|
/** 1 = `oneway` (v1), 2 = `oneway-v2`. Branch every encoder on this. */
|
|
24349
24373
|
version: market.version,
|
|
24350
24374
|
/** FAIL CLOSED — an unknown market is not delegatable. */
|
|
@@ -42540,6 +42564,32 @@ var sreusdSavingsFetcher = {
|
|
|
42540
42564
|
return { [SREUSD_KEY]: apr, [SREUSD_GROUP_KEY]: apr };
|
|
42541
42565
|
}
|
|
42542
42566
|
};
|
|
42567
|
+
|
|
42568
|
+
// src/yields/intrinsic/fetchers/fxProtocol.ts
|
|
42569
|
+
var ALADDIN_APY_URL = "https://api.aladdin.club/api1/concentrator_aToken_tvl_apy";
|
|
42570
|
+
var FXSAVE_DEFILLAMA_POOL = "ee0b7069-f8f3-4aa2-a415-728f13e6cc3d";
|
|
42571
|
+
var FXSAVE_KEY = "FXSAVE";
|
|
42572
|
+
var FXSAVE_GROUP_KEY = "f(x) USD Saving::fxSAVE";
|
|
42573
|
+
var fetchAladdinApyPercent = async () => {
|
|
42574
|
+
const res = await fetch(ALADDIN_APY_URL, {
|
|
42575
|
+
headers: { accept: "application/json" },
|
|
42576
|
+
signal: AbortSignal.timeout(8e3)
|
|
42577
|
+
});
|
|
42578
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
42579
|
+
const apy = Number((await res.json())?.data?.fxSave?.apy);
|
|
42580
|
+
if (Number.isFinite(apy) && apy > 0) return apy;
|
|
42581
|
+
throw new Error("apy missing");
|
|
42582
|
+
};
|
|
42583
|
+
var fxSaveFetcher = {
|
|
42584
|
+
label: "FXSAVE",
|
|
42585
|
+
fetch: async () => {
|
|
42586
|
+
const apy = await fetchAladdinApyPercent().catch(
|
|
42587
|
+
() => fetchDefiLlamaApy(FXSAVE_DEFILLAMA_POOL)
|
|
42588
|
+
);
|
|
42589
|
+
const apr = apyToAprPercent(apy);
|
|
42590
|
+
return { [FXSAVE_KEY]: apr, [FXSAVE_GROUP_KEY]: apr };
|
|
42591
|
+
}
|
|
42592
|
+
};
|
|
42543
42593
|
var RATE_ABI = [
|
|
42544
42594
|
{
|
|
42545
42595
|
name: "rate",
|
|
@@ -45016,6 +45066,31 @@ var SINGLE_CHAIN_ENTRIES = {
|
|
|
45016
45066
|
yieldFetcher: sreusdSavingsFetcher,
|
|
45017
45067
|
yieldKey: "SREUSD"
|
|
45018
45068
|
},
|
|
45069
|
+
{
|
|
45070
|
+
// f(x) Protocol fxSAVE — 4626 auto-compounder over `fxSP`, the f(x)
|
|
45071
|
+
// Stability Pool share (it holds 57.4M of fxSP's 59.4M supply, i.e.
|
|
45072
|
+
// ~97% of the pool). Plain instant exit: `maxDeposit = uint.max`,
|
|
45073
|
+
// `maxRedeem == balanceOf` on a live holder, `previewRedeem ==
|
|
45074
|
+
// convertToAssets` (no fee, no cooldown) — verified on-chain 2026-08-09.
|
|
45075
|
+
//
|
|
45076
|
+
// The underlying is fxSP and NOT fxUSD: fxSP appreciates on its own
|
|
45077
|
+
// ($1.0101 vs fxUSD's $1.0000 at integration), so pricing `totalAssets`
|
|
45078
|
+
// off fxUSD would understate TVL by ~1%. The token-list row's
|
|
45079
|
+
// `props.savings.underlying: 'fxUSD'` is the classifier's economic
|
|
45080
|
+
// underlying, a different question from `asset()`.
|
|
45081
|
+
address: "0x7743e50f534a7f9f1791dde7dcd89f7783eefc39",
|
|
45082
|
+
underlying: "0x65c9a641afceb9c0e6034e558a319488fa0fa3be",
|
|
45083
|
+
// fxSP
|
|
45084
|
+
symbol: "fxSAVE",
|
|
45085
|
+
brand: "f(x) Protocol",
|
|
45086
|
+
description: "fxUSD is f(x) Protocol's stablecoin; its Stability Pool (fxSP) backstops leveraged positions and earns the protocol's rebalance and liquidation revenue. fxSAVE auto-compounds that revenue back into fxSP, so the share price appreciates. Instant permissionless exit, no fee or cooldown.",
|
|
45087
|
+
decimals: 18,
|
|
45088
|
+
isRebasing: false,
|
|
45089
|
+
isMintable: true,
|
|
45090
|
+
withdrawalMode: "instant",
|
|
45091
|
+
yieldFetcher: fxSaveFetcher,
|
|
45092
|
+
yieldKey: FXSAVE_KEY
|
|
45093
|
+
},
|
|
45019
45094
|
{
|
|
45020
45095
|
// Frax sFRAX — the pre-rename sibling of sfrxUSD, over legacy
|
|
45021
45096
|
// FRAX. Still live and roughly 2x sfrxUSD's size, so it stays a
|
|
@@ -46177,32 +46252,85 @@ var upshiftFetcher = {
|
|
|
46177
46252
|
}
|
|
46178
46253
|
};
|
|
46179
46254
|
|
|
46180
|
-
// src/
|
|
46181
|
-
var
|
|
46182
|
-
|
|
46183
|
-
"
|
|
46184
|
-
|
|
46185
|
-
"
|
|
46186
|
-
|
|
46187
|
-
|
|
46255
|
+
// src/vaults/yearn/api.ts
|
|
46256
|
+
var YEARN_YDAEMON_BASE = "https://ydaemon.yearn.fi";
|
|
46257
|
+
var YEARN_CHAIN_IDS = /* @__PURE__ */ new Set([
|
|
46258
|
+
"1",
|
|
46259
|
+
// Ethereum
|
|
46260
|
+
"137",
|
|
46261
|
+
// Polygon
|
|
46262
|
+
"8453",
|
|
46263
|
+
// Base
|
|
46264
|
+
"42161",
|
|
46265
|
+
// Arbitrum
|
|
46266
|
+
"100",
|
|
46267
|
+
// Gnosis
|
|
46268
|
+
"146",
|
|
46269
|
+
// Sonic
|
|
46270
|
+
"747474"
|
|
46271
|
+
// Katana
|
|
46272
|
+
]);
|
|
46273
|
+
var hasYearnVaults = (chainId) => YEARN_CHAIN_IDS.has(String(chainId));
|
|
46274
|
+
var isYearnV3 = (v) => typeof v?.version === "string" && v.version.startsWith("3.");
|
|
46275
|
+
var PAGE_SIZE = 2e3;
|
|
46276
|
+
async function fetchYearnApiVaults(chainId) {
|
|
46277
|
+
const out = [];
|
|
46278
|
+
const seen = /* @__PURE__ */ new Set();
|
|
46279
|
+
for (let page = 1; page <= 20; page++) {
|
|
46280
|
+
const url = `${YEARN_YDAEMON_BASE}/${chainId}/vaults/all?limit=${PAGE_SIZE}&page=${page}`;
|
|
46281
|
+
const response = await fetch(url);
|
|
46282
|
+
if (!response.ok) {
|
|
46283
|
+
throw new Error(
|
|
46284
|
+
`Yearn yDaemon API failed: ${response.status} - ${response.statusText}`
|
|
46285
|
+
);
|
|
46286
|
+
}
|
|
46287
|
+
const body = await response.text();
|
|
46288
|
+
if (!body.trim()) break;
|
|
46289
|
+
const items = JSON.parse(body);
|
|
46290
|
+
if (!Array.isArray(items)) break;
|
|
46291
|
+
for (const v of items) {
|
|
46292
|
+
const address = (v?.address ?? "").toLowerCase();
|
|
46293
|
+
if (!address || seen.has(address)) continue;
|
|
46294
|
+
if (isYearnV3(v) && v.endorsed) {
|
|
46295
|
+
seen.add(address);
|
|
46296
|
+
out.push(v);
|
|
46297
|
+
}
|
|
46298
|
+
}
|
|
46299
|
+
if (items.length < PAGE_SIZE) break;
|
|
46300
|
+
}
|
|
46301
|
+
return out;
|
|
46302
|
+
}
|
|
46188
46303
|
|
|
46189
|
-
// src/yields/intrinsic/fetchers/
|
|
46190
|
-
var
|
|
46191
|
-
var
|
|
46192
|
-
|
|
46304
|
+
// src/yields/intrinsic/fetchers/yearn.ts
|
|
46305
|
+
var toPct = (v) => typeof v === "number" && Number.isFinite(v) ? v * 100 : null;
|
|
46306
|
+
var yearnVaultApr = (v) => toPct(v.apr?.netAPR) ?? toPct(v.apr?.forwardAPR?.netAPR);
|
|
46307
|
+
var yearnFetcher = {
|
|
46308
|
+
label: "YEARN",
|
|
46193
46309
|
fetch: async () => {
|
|
46194
|
-
const
|
|
46195
|
-
|
|
46196
|
-
|
|
46197
|
-
|
|
46198
|
-
|
|
46199
|
-
|
|
46200
|
-
|
|
46201
|
-
|
|
46202
|
-
|
|
46203
|
-
|
|
46204
|
-
|
|
46205
|
-
|
|
46310
|
+
const chainIds = [...YEARN_CHAIN_IDS];
|
|
46311
|
+
const lists = await getListsMulti(chainIds);
|
|
46312
|
+
const perChain = await Promise.all(
|
|
46313
|
+
chainIds.map(async (chainId) => {
|
|
46314
|
+
const out = {};
|
|
46315
|
+
let vaults = [];
|
|
46316
|
+
try {
|
|
46317
|
+
vaults = await fetchYearnApiVaults(chainId);
|
|
46318
|
+
} catch (e) {
|
|
46319
|
+
console.error(`Error fetching YEARN vaults on chain ${chainId}:`, e);
|
|
46320
|
+
return out;
|
|
46321
|
+
}
|
|
46322
|
+
for (const v of vaults) {
|
|
46323
|
+
const address = (v.address ?? "").toLowerCase();
|
|
46324
|
+
const assetKey = lists[chainId]?.list?.[address]?.assetGroup;
|
|
46325
|
+
if (!assetKey) continue;
|
|
46326
|
+
const apr = yearnVaultApr(v);
|
|
46327
|
+
if (apr == null) continue;
|
|
46328
|
+
out[assetKey] = apr;
|
|
46329
|
+
}
|
|
46330
|
+
return out;
|
|
46331
|
+
})
|
|
46332
|
+
);
|
|
46333
|
+
return Object.assign({}, ...perChain);
|
|
46206
46334
|
}
|
|
46207
46335
|
};
|
|
46208
46336
|
|
|
@@ -46266,7 +46394,9 @@ var LENDING_ONLY_FETCHERS = [
|
|
|
46266
46394
|
nestFetcher,
|
|
46267
46395
|
accountableFetcher,
|
|
46268
46396
|
upshiftFetcher,
|
|
46269
|
-
|
|
46397
|
+
// Every endorsed Yearn V3 vault on every Yearn chain (Katana included —
|
|
46398
|
+
// it superseded the Katana-only fetcher, which double-counted).
|
|
46399
|
+
yearnFetcher,
|
|
46270
46400
|
// DefiLlama-mapped intrinsic yields for classifier assets lacking a bespoke source
|
|
46271
46401
|
lsethFetcher,
|
|
46272
46402
|
tethFetcher,
|
|
@@ -46367,6 +46497,76 @@ function extractRewardBreakdowns(opp) {
|
|
|
46367
46497
|
distributionType: b.distributionType
|
|
46368
46498
|
}));
|
|
46369
46499
|
}
|
|
46500
|
+
function unixSeconds(v) {
|
|
46501
|
+
if (v === void 0 || v === null) return void 0;
|
|
46502
|
+
const n = typeof v === "number" ? v : Number(v);
|
|
46503
|
+
return Number.isFinite(n) && n > 0 ? n : void 0;
|
|
46504
|
+
}
|
|
46505
|
+
function buildMerklStreams(opp, side, totalApr, source) {
|
|
46506
|
+
const rewardBreakdowns = opp.rewardsRecord?.breakdowns ?? [];
|
|
46507
|
+
const endsAt = unixSeconds(opp.earliestCampaignEnd ?? opp.latestCampaignEnd);
|
|
46508
|
+
const startsAt = unixSeconds(
|
|
46509
|
+
opp.earliestCampaignStart ?? opp.latestCampaignStart
|
|
46510
|
+
);
|
|
46511
|
+
const base = {
|
|
46512
|
+
side,
|
|
46513
|
+
kind: "token",
|
|
46514
|
+
claim: "merkl",
|
|
46515
|
+
endsAt,
|
|
46516
|
+
startsAt
|
|
46517
|
+
};
|
|
46518
|
+
if (!rewardBreakdowns.length) {
|
|
46519
|
+
return [{ ...base, apr: totalApr, token: void 0, source }];
|
|
46520
|
+
}
|
|
46521
|
+
const aprByCampaign = /* @__PURE__ */ new Map();
|
|
46522
|
+
for (const b of opp.aprRecord?.breakdowns ?? []) {
|
|
46523
|
+
if (b?.identifier && Number.isFinite(b.value))
|
|
46524
|
+
aprByCampaign.set(b.identifier.toLowerCase(), b.value);
|
|
46525
|
+
}
|
|
46526
|
+
const totalDaily = rewardBreakdowns.reduce((s, b) => s + (b.value || 0), 0);
|
|
46527
|
+
return rewardBreakdowns.map((b) => {
|
|
46528
|
+
const campaignApr = b.onChainCampaignId ? aprByCampaign.get(b.onChainCampaignId.toLowerCase()) : void 0;
|
|
46529
|
+
const apr = campaignApr ?? (totalDaily > 0 ? totalApr * (b.value || 0) / totalDaily : totalApr / rewardBreakdowns.length);
|
|
46530
|
+
return {
|
|
46531
|
+
...base,
|
|
46532
|
+
apr,
|
|
46533
|
+
token: {
|
|
46534
|
+
address: b.token.address.toLowerCase(),
|
|
46535
|
+
chainId: String(opp.chainId),
|
|
46536
|
+
symbol: b.token.symbol,
|
|
46537
|
+
decimals: b.token.decimals,
|
|
46538
|
+
logoURI: b.token.icon,
|
|
46539
|
+
priceUsd: b.token.price ?? void 0
|
|
46540
|
+
},
|
|
46541
|
+
dailyRewardsUsd: b.value,
|
|
46542
|
+
source: {
|
|
46543
|
+
...source,
|
|
46544
|
+
refs: {
|
|
46545
|
+
...source.refs ?? {},
|
|
46546
|
+
...b.onChainCampaignId ? { onChainCampaignId: b.onChainCampaignId } : {},
|
|
46547
|
+
...b.campaignId ? { campaignId: b.campaignId } : {},
|
|
46548
|
+
...b.distributionType ? { distributionType: b.distributionType } : {}
|
|
46549
|
+
}
|
|
46550
|
+
}
|
|
46551
|
+
};
|
|
46552
|
+
});
|
|
46553
|
+
}
|
|
46554
|
+
function merklSourceRef(opp, merklProtocolId) {
|
|
46555
|
+
const protocolName = opp.protocol?.name ?? merklProtocolId;
|
|
46556
|
+
return {
|
|
46557
|
+
id: `merkl:${merklProtocolId}`,
|
|
46558
|
+
label: `Merkl \xB7 ${protocolName}`,
|
|
46559
|
+
link: getMerkleUrl(opp),
|
|
46560
|
+
platform: "merkl",
|
|
46561
|
+
refs: {
|
|
46562
|
+
opportunityId: opp.identifier,
|
|
46563
|
+
opportunityType: opp.type,
|
|
46564
|
+
chain: opp.chain?.name ?? String(opp.chainId),
|
|
46565
|
+
...opp.name ? { opportunityName: opp.name } : {},
|
|
46566
|
+
...opp.liveCampaigns ? { liveCampaigns: opp.liveCampaigns } : {}
|
|
46567
|
+
}
|
|
46568
|
+
};
|
|
46569
|
+
}
|
|
46370
46570
|
function resolveUnderlyingFromOpportunity(opp) {
|
|
46371
46571
|
if (!opp.tokens?.length) return void 0;
|
|
46372
46572
|
if (opp.depositUrl) {
|
|
@@ -46432,6 +46632,11 @@ function createMerklRewardFetcher(config) {
|
|
|
46432
46632
|
);
|
|
46433
46633
|
const breakdowns = extractRewardBreakdowns(opp);
|
|
46434
46634
|
reward.link = getMerkleUrl(opp);
|
|
46635
|
+
const source = merklSourceRef(opp, config.merklProtocolId);
|
|
46636
|
+
if (!reward.streams) reward.streams = [];
|
|
46637
|
+
reward.streams.push(
|
|
46638
|
+
...buildMerklStreams(opp, bucket, opp.apr, source)
|
|
46639
|
+
);
|
|
46435
46640
|
if (bucket === "deposit") {
|
|
46436
46641
|
reward.deposit += opp.apr;
|
|
46437
46642
|
reward.additionalDepositData.push(...breakdowns);
|
|
@@ -46636,8 +46841,21 @@ var ABI = [
|
|
|
46636
46841
|
stateMutability: "view",
|
|
46637
46842
|
inputs: [],
|
|
46638
46843
|
outputs: [{ type: "uint8" }]
|
|
46844
|
+
},
|
|
46845
|
+
{
|
|
46846
|
+
name: "symbol",
|
|
46847
|
+
type: "function",
|
|
46848
|
+
stateMutability: "view",
|
|
46849
|
+
inputs: [],
|
|
46850
|
+
outputs: [{ type: "string" }]
|
|
46639
46851
|
}
|
|
46640
46852
|
];
|
|
46853
|
+
var DTRINITY_SOURCE = {
|
|
46854
|
+
id: "dtrinity:rebate",
|
|
46855
|
+
label: "dTRINITY borrow rebate",
|
|
46856
|
+
link: "https://docs.dtrinity.org/protocol-components/dlend",
|
|
46857
|
+
platform: "protocol"
|
|
46858
|
+
};
|
|
46641
46859
|
var isZero = (a) => !a || a.toLowerCase() === ZERO_ADDRESS5;
|
|
46642
46860
|
var scale = (raw, decimals) => Number(raw) / 10 ** decimals;
|
|
46643
46861
|
function emptyReward2() {
|
|
@@ -46751,19 +46969,25 @@ async function fetchForPool(chainId, lender, pool, nowSeconds) {
|
|
|
46751
46969
|
calls: pairs.flatMap((p) => [
|
|
46752
46970
|
call(p.leg.controller, "getRewardsData", [p.leg.balanceToken, p.reward]),
|
|
46753
46971
|
call(p.reward, "decimals"),
|
|
46754
|
-
call(oracle, "getAssetPrice", [p.reward])
|
|
46972
|
+
call(oracle, "getAssetPrice", [p.reward]),
|
|
46973
|
+
call(p.reward, "symbol")
|
|
46755
46974
|
]),
|
|
46756
46975
|
allowFailure: false
|
|
46757
46976
|
});
|
|
46977
|
+
const STRIDE = 4;
|
|
46758
46978
|
const result = {};
|
|
46759
46979
|
pairs.forEach((p, i) => {
|
|
46760
|
-
const data = round5[i *
|
|
46980
|
+
const data = round5[i * STRIDE];
|
|
46761
46981
|
if (!data) return;
|
|
46982
|
+
const rewardDecimals = Number(round5[i * STRIDE + 1] ?? 18);
|
|
46983
|
+
const rewardPrice = Number(round5[i * STRIDE + 2] ?? 0n);
|
|
46984
|
+
const rewardSymbol = round5[i * STRIDE + 3];
|
|
46985
|
+
const distributionEnd = Number(data[3] ?? 0);
|
|
46762
46986
|
const apr = rebateApr({
|
|
46763
46987
|
emissionPerSecond: BigInt(data[1] ?? 0),
|
|
46764
46988
|
distributionEnd: BigInt(data[3] ?? 0),
|
|
46765
|
-
rewardDecimals
|
|
46766
|
-
rewardPrice
|
|
46989
|
+
rewardDecimals,
|
|
46990
|
+
rewardPrice,
|
|
46767
46991
|
balanceTotalSupply: BigInt(p.leg.totalSupply ?? 0),
|
|
46768
46992
|
balanceDecimals: p.leg.decimals,
|
|
46769
46993
|
assetPrice: priceByAsset[p.leg.asset] ?? 0,
|
|
@@ -46778,9 +47002,34 @@ async function fetchForPool(chainId, lender, pool, nowSeconds) {
|
|
|
46778
47002
|
const breakdown = {
|
|
46779
47003
|
tokenAddress: p.reward.toLowerCase(),
|
|
46780
47004
|
emissionPerSecond: String(data[1]),
|
|
46781
|
-
distributionEnd
|
|
47005
|
+
distributionEnd,
|
|
46782
47006
|
distributionType: "aave-incentives"
|
|
46783
47007
|
};
|
|
47008
|
+
if (!entry.streams) entry.streams = [];
|
|
47009
|
+
entry.streams.push({
|
|
47010
|
+
side: p.leg.bucket,
|
|
47011
|
+
apr,
|
|
47012
|
+
kind: "token",
|
|
47013
|
+
token: {
|
|
47014
|
+
address: p.reward.toLowerCase(),
|
|
47015
|
+
chainId,
|
|
47016
|
+
symbol: rewardSymbol,
|
|
47017
|
+
decimals: rewardDecimals,
|
|
47018
|
+
// The pool's AaveOracle is 1e8-based on every dLEND deployment.
|
|
47019
|
+
priceUsd: rewardPrice > 0 ? rewardPrice / 1e8 : void 0
|
|
47020
|
+
},
|
|
47021
|
+
source: {
|
|
47022
|
+
...DTRINITY_SOURCE,
|
|
47023
|
+
refs: {
|
|
47024
|
+
incentivesController: p.leg.controller.toLowerCase(),
|
|
47025
|
+
balanceToken: p.leg.balanceToken.toLowerCase(),
|
|
47026
|
+
emissionPerSecond: String(data[1])
|
|
47027
|
+
}
|
|
47028
|
+
},
|
|
47029
|
+
claim: "accrual",
|
|
47030
|
+
endsAt: distributionEnd > 0 ? distributionEnd : void 0,
|
|
47031
|
+
dailyRewardsUsd: rewardPrice > 0 ? Number(data[1] ?? 0) / 10 ** rewardDecimals * 86400 * (rewardPrice / 1e8) : void 0
|
|
47032
|
+
});
|
|
46784
47033
|
if (p.leg.bucket === "deposit") {
|
|
46785
47034
|
entry.deposit += apr;
|
|
46786
47035
|
entry.additionalDepositData.push(breakdown);
|
|
@@ -51721,7 +51970,7 @@ var fetchGearboxV3Pools = async (chainId, multicallRetry, prices = {}, tokenList
|
|
|
51721
51970
|
// src/vaults/morpho/fetchFromApi.ts
|
|
51722
51971
|
var MORPHO_SHARE_DECIMALS = 18;
|
|
51723
51972
|
var MORPHO_API_URL = "https://blue-api.morpho.org/graphql";
|
|
51724
|
-
var
|
|
51973
|
+
var PAGE_SIZE2 = 200;
|
|
51725
51974
|
var vaultsQuery = (first, skip, chainId) => `
|
|
51726
51975
|
query GetVaults {
|
|
51727
51976
|
vaults(
|
|
@@ -51886,14 +52135,14 @@ async function fetchMorphoVaultsFromApi(chainId, prices = {}, tokenList = {}, ma
|
|
|
51886
52135
|
const out = {};
|
|
51887
52136
|
let skip = 0;
|
|
51888
52137
|
while (skip < maxItems) {
|
|
51889
|
-
const page = await fetchPage(chainId,
|
|
52138
|
+
const page = await fetchPage(chainId, PAGE_SIZE2, skip);
|
|
51890
52139
|
if (page.length === 0) break;
|
|
51891
52140
|
for (const v of page) {
|
|
51892
52141
|
const parsed = parseVault2(v, chainId, prices, tokenList);
|
|
51893
52142
|
if (parsed) out[parsed.address] = parsed;
|
|
51894
52143
|
}
|
|
51895
|
-
if (page.length <
|
|
51896
|
-
skip +=
|
|
52144
|
+
if (page.length < PAGE_SIZE2) break;
|
|
52145
|
+
skip += PAGE_SIZE2;
|
|
51897
52146
|
}
|
|
51898
52147
|
return out;
|
|
51899
52148
|
}
|
|
@@ -59690,7 +59939,7 @@ query LagoonVaults($where: VaultFilterInput!, $first: Int!, $skip: Int!) {
|
|
|
59690
59939
|
}
|
|
59691
59940
|
}
|
|
59692
59941
|
}`;
|
|
59693
|
-
var
|
|
59942
|
+
var PAGE_SIZE3 = 200;
|
|
59694
59943
|
async function fetchLagoonApiVaults(chainId) {
|
|
59695
59944
|
const out = [];
|
|
59696
59945
|
let skip = 0;
|
|
@@ -59702,7 +59951,7 @@ async function fetchLagoonApiVaults(chainId) {
|
|
|
59702
59951
|
query: VAULTS_QUERY,
|
|
59703
59952
|
variables: {
|
|
59704
59953
|
where: { chainId_eq: Number(chainId), isVisible_eq: true },
|
|
59705
|
-
first:
|
|
59954
|
+
first: PAGE_SIZE3,
|
|
59706
59955
|
skip
|
|
59707
59956
|
}
|
|
59708
59957
|
})
|
|
@@ -59720,8 +59969,8 @@ async function fetchLagoonApiVaults(chainId) {
|
|
|
59720
59969
|
}
|
|
59721
59970
|
const items = json?.data?.vaults?.items ?? [];
|
|
59722
59971
|
out.push(...items);
|
|
59723
|
-
if (items.length <
|
|
59724
|
-
skip +=
|
|
59972
|
+
if (items.length < PAGE_SIZE3) break;
|
|
59973
|
+
skip += PAGE_SIZE3;
|
|
59725
59974
|
}
|
|
59726
59975
|
return out;
|
|
59727
59976
|
}
|
|
@@ -59841,7 +60090,7 @@ var Erc4626TotalAssetsAbi = [
|
|
|
59841
60090
|
|
|
59842
60091
|
// src/vaults/aave-earn/api.ts
|
|
59843
60092
|
var AAVE_EARN_API_URL = "https://api.v3.aave.com/graphql";
|
|
59844
|
-
var
|
|
60093
|
+
var PAGE_SIZE4 = "FIFTY";
|
|
59845
60094
|
var VAULT_FIELDS = `
|
|
59846
60095
|
address
|
|
59847
60096
|
shareName
|
|
@@ -59899,7 +60148,7 @@ async function fetchAaveEarnApiVaults(chainId, targets) {
|
|
|
59899
60148
|
for (let page = 0; page < 20; page++) {
|
|
59900
60149
|
const request = {
|
|
59901
60150
|
criteria: { ownedBy: [owner] },
|
|
59902
|
-
pageSize:
|
|
60151
|
+
pageSize: PAGE_SIZE4
|
|
59903
60152
|
};
|
|
59904
60153
|
if (cursor) request.cursor = cursor;
|
|
59905
60154
|
const data = await postGraphql(OWNED_VAULTS_QUERY, { request });
|
|
@@ -60158,47 +60407,6 @@ var fetchUpshiftVaults = async (chainId, prices = {}, tokenList = {}) => {
|
|
|
60158
60407
|
return out;
|
|
60159
60408
|
};
|
|
60160
60409
|
|
|
60161
|
-
// src/vaults/yearn/api.ts
|
|
60162
|
-
var YEARN_YDAEMON_BASE = "https://ydaemon.yearn.fi";
|
|
60163
|
-
var YEARN_CHAIN_IDS = /* @__PURE__ */ new Set([
|
|
60164
|
-
"1",
|
|
60165
|
-
// Ethereum
|
|
60166
|
-
"137",
|
|
60167
|
-
// Polygon
|
|
60168
|
-
"8453",
|
|
60169
|
-
// Base
|
|
60170
|
-
"42161",
|
|
60171
|
-
// Arbitrum
|
|
60172
|
-
"100",
|
|
60173
|
-
// Gnosis
|
|
60174
|
-
"146",
|
|
60175
|
-
// Sonic
|
|
60176
|
-
"747474"
|
|
60177
|
-
// Katana
|
|
60178
|
-
]);
|
|
60179
|
-
var hasYearnVaults = (chainId) => YEARN_CHAIN_IDS.has(String(chainId));
|
|
60180
|
-
var isYearnV3 = (v) => typeof v?.version === "string" && v.version.startsWith("3.");
|
|
60181
|
-
var PAGE_SIZE4 = 500;
|
|
60182
|
-
async function fetchYearnApiVaults(chainId) {
|
|
60183
|
-
const out = [];
|
|
60184
|
-
for (let page = 1; page <= 20; page++) {
|
|
60185
|
-
const url = `${YEARN_YDAEMON_BASE}/${chainId}/vaults/all?limit=${PAGE_SIZE4}&page=${page}`;
|
|
60186
|
-
const response = await fetch(url);
|
|
60187
|
-
if (!response.ok) {
|
|
60188
|
-
throw new Error(
|
|
60189
|
-
`Yearn yDaemon API failed: ${response.status} - ${response.statusText}`
|
|
60190
|
-
);
|
|
60191
|
-
}
|
|
60192
|
-
const items = await response.json();
|
|
60193
|
-
if (!Array.isArray(items)) break;
|
|
60194
|
-
for (const v of items) {
|
|
60195
|
-
if (isYearnV3(v) && v.endorsed) out.push(v);
|
|
60196
|
-
}
|
|
60197
|
-
if (items.length < PAGE_SIZE4) break;
|
|
60198
|
-
}
|
|
60199
|
-
return out;
|
|
60200
|
-
}
|
|
60201
|
-
|
|
60202
60410
|
// src/vaults/yearn/fetchPublic.ts
|
|
60203
60411
|
var BRAND3 = "Yearn";
|
|
60204
60412
|
var ZERO_ADDR = "0x0000000000000000000000000000000000000000";
|
|
@@ -60244,7 +60452,7 @@ var asBig = (v) => {
|
|
|
60244
60452
|
}
|
|
60245
60453
|
};
|
|
60246
60454
|
var num9 = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
60247
|
-
var
|
|
60455
|
+
var toPct2 = (v) => {
|
|
60248
60456
|
const n = num9(v);
|
|
60249
60457
|
return n == null ? 0 : n * 100;
|
|
60250
60458
|
};
|
|
@@ -60280,9 +60488,9 @@ function parseVault9(v, chainId, prices, tokenList) {
|
|
|
60280
60488
|
const realized = num9(v.apr?.netAPR);
|
|
60281
60489
|
const forward = num9(v.apr?.forwardAPR?.netAPR);
|
|
60282
60490
|
const isForwardApr = realized == null && forward != null;
|
|
60283
|
-
const supplyRate =
|
|
60284
|
-
const rewardsRate =
|
|
60285
|
-
const fee =
|
|
60491
|
+
const supplyRate = toPct2(realized ?? forward);
|
|
60492
|
+
const rewardsRate = toPct2(v.apr?.extra?.stakingRewardsAPR);
|
|
60493
|
+
const fee = toPct2(v.apr?.fees?.performance);
|
|
60286
60494
|
const oracleKey = toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(assetAddr, chainId);
|
|
60287
60495
|
const apiPrice = num9(v.tvl?.price) ?? 0;
|
|
60288
60496
|
const priceUsd = prices[oracleKey] ?? prices[assetAddr] ?? apiPrice;
|
|
@@ -65066,11 +65274,12 @@ var llamaLendAdapter = {
|
|
|
65066
65274
|
/**
|
|
65067
65275
|
* The band count as an editable TERM, not just a curve to read.
|
|
65068
65276
|
*
|
|
65069
|
-
* `bandLtv` alone cannot drive a control: it is
|
|
65070
|
-
*
|
|
65071
|
-
*
|
|
65072
|
-
*
|
|
65073
|
-
*
|
|
65277
|
+
* `bandLtv` alone cannot drive a control: it is missing on any
|
|
65278
|
+
* market whose geometry could not be read. The domain is always
|
|
65279
|
+
* known — `MIN_TICKS`/`MAX_TICKS` are 4..50 on both generations — so
|
|
65280
|
+
* the control works even where the curve does not. Where the curve
|
|
65281
|
+
* IS present it spans the full domain, so a control can show the LTV
|
|
65282
|
+
* for every value it offers.
|
|
65074
65283
|
*
|
|
65075
65284
|
* `immutableAfterOpen` is what tells the UI to render this read-only
|
|
65076
65285
|
* on an existing loan: `_add_collateral_borrow` reuses the tick
|
|
@@ -65135,7 +65344,16 @@ var frankencoinAdapter = {
|
|
|
65135
65344
|
return {
|
|
65136
65345
|
// Not a coverage hole: the protocol has no price feed by design.
|
|
65137
65346
|
oracle: { kind: "none" },
|
|
65347
|
+
supply: {
|
|
65348
|
+
// Collateral inside a position. There is no ZCHF lending deposit at
|
|
65349
|
+
// all — the earn surface is the savings module, a separate provider —
|
|
65350
|
+
// so this side never pays interest.
|
|
65351
|
+
role: "collateral",
|
|
65352
|
+
availability: { opensWith: "both-legs" },
|
|
65353
|
+
counterparty: { kind: "cdp", solvency: "overcollateralized" }
|
|
65354
|
+
},
|
|
65138
65355
|
borrow: {
|
|
65356
|
+
availability: { opensWith: "both-legs" },
|
|
65139
65357
|
debtShape: "accruing",
|
|
65140
65358
|
maturity: expiration > 0 ? {
|
|
65141
65359
|
kind: "fixed-date",
|