@1delta/margin-fetcher 0.0.272 → 0.0.274
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 +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +727 -187
- package/dist/index.js.map +1 -1
- package/dist/vaults/classification.d.ts.map +1 -1
- package/dist/vaults/curatorName.d.ts +20 -0
- package/dist/vaults/curatorName.d.ts.map +1 -0
- package/dist/vaults/euler-earn/fetchFromSubgraph.d.ts.map +1 -1
- package/dist/vaults/euler-earn/types.d.ts +4 -0
- package/dist/vaults/euler-earn/types.d.ts.map +1 -1
- package/dist/vaults/fetchVaultsAll.d.ts +5 -1
- package/dist/vaults/fetchVaultsAll.d.ts.map +1 -1
- package/dist/vaults/gmx/abis.d.ts +15 -0
- package/dist/vaults/gmx/abis.d.ts.map +1 -1
- package/dist/vaults/gmx/fetchPublic.d.ts.map +1 -1
- package/dist/vaults/gmx/index.d.ts +1 -1
- package/dist/vaults/gmx/index.d.ts.map +1 -1
- package/dist/vaults/gmx/keys.d.ts +20 -0
- package/dist/vaults/gmx/keys.d.ts.map +1 -1
- package/dist/vaults/gmx/pricing.d.ts +30 -3
- package/dist/vaults/gmx/pricing.d.ts.map +1 -1
- package/dist/vaults/gmx/types.d.ts +17 -0
- package/dist/vaults/gmx/types.d.ts.map +1 -1
- package/dist/vaults/index.d.ts +1 -0
- package/dist/vaults/index.d.ts.map +1 -1
- package/dist/vaults/lagoon/api.d.ts +5 -0
- package/dist/vaults/lagoon/api.d.ts.map +1 -1
- package/dist/vaults/lagoon/fetchPublic.d.ts.map +1 -1
- package/dist/vaults/lookup.d.ts.map +1 -1
- package/dist/vaults/morpho/allocationWalk.d.ts +11 -0
- package/dist/vaults/morpho/allocationWalk.d.ts.map +1 -1
- package/dist/vaults/morpho/fetchFromChain.d.ts +4 -3
- package/dist/vaults/morpho/fetchFromChain.d.ts.map +1 -1
- package/dist/vaults/morpho/fetchListaFromChain.d.ts.map +1 -1
- package/dist/vaults/morpho/fetchPublic.d.ts +8 -5
- package/dist/vaults/morpho/fetchPublic.d.ts.map +1 -1
- package/dist/vaults/morpho/index.d.ts +0 -1
- package/dist/vaults/morpho/index.d.ts.map +1 -1
- package/dist/vaults/savings/fetchPublic.d.ts.map +1 -1
- package/dist/vaults/savings/types.d.ts +12 -0
- package/dist/vaults/savings/types.d.ts.map +1 -1
- package/dist/vaults/silo/fetchPublic.d.ts.map +1 -1
- package/dist/vaults/yearn/api.d.ts +93 -0
- package/dist/vaults/yearn/api.d.ts.map +1 -0
- package/dist/vaults/yearn/fetchPublic.d.ts +21 -0
- package/dist/vaults/yearn/fetchPublic.d.ts.map +1 -0
- package/dist/vaults/yearn/index.d.ts +4 -0
- package/dist/vaults/yearn/index.d.ts.map +1 -0
- package/dist/vaults/yearn/types.d.ts +104 -0
- package/dist/vaults/yearn/types.d.ts.map +1 -0
- package/package.json +3 -3
- package/dist/vaults/morpho/fetchFromSubgraph.d.ts +0 -12
- package/dist/vaults/morpho/fetchFromSubgraph.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -36110,115 +36110,6 @@ async function fetchMorphoVaultsFromApi(chainId, prices = {}, tokenList = {}, ma
|
|
|
36110
36110
|
}
|
|
36111
36111
|
return out;
|
|
36112
36112
|
}
|
|
36113
|
-
|
|
36114
|
-
// src/vaults/morpho/fetchFromSubgraph.ts
|
|
36115
|
-
var MORPHO_VAULT_SUBGRAPH_URLS = {
|
|
36116
|
-
[Chain.SEI_NETWORK]: "https://api.goldsky.com/api/public/project_cmiergfbv4vma01vb642yaeam/subgraphs/morphoblue-sei/1.0.1/gn",
|
|
36117
|
-
[Chain.CELO_MAINNET]: "https://api.goldsky.com/api/public/project_cmiergfbv4vma01vb642yaeam/subgraphs/morphoblue-celo/1.0.4/gn",
|
|
36118
|
-
[Chain.LISK]: "https://api.goldsky.com/api/public/project_cmiergfbv4vma01vb642yaeam/subgraphs/morphobluelisk/1.0.1/gn",
|
|
36119
|
-
[Chain.SONEIUM]: "https://api.goldsky.com/api/public/project_cmiergfbv4vma01vb642yaeam/subgraphs/morphobluesoneium/1.0.2/gn",
|
|
36120
|
-
[Chain.TAC_MAINNET]: "https://api.goldsky.com/api/public/project_cmiergfbv4vma01vb642yaeam/subgraphs/morphoblue-tac/1.0.0/gn",
|
|
36121
|
-
[Chain.HEMI_NETWORK]: "https://feather.securesecrets.org/hemi-mopho-blue/"
|
|
36122
|
-
};
|
|
36123
|
-
var hasMorphoVaultSubgraph = (chainId) => chainId in MORPHO_VAULT_SUBGRAPH_URLS;
|
|
36124
|
-
var META_MORPHOS_QUERY = `
|
|
36125
|
-
{
|
|
36126
|
-
metaMorphos(first: 100, skip: 0) {
|
|
36127
|
-
id
|
|
36128
|
-
name
|
|
36129
|
-
symbol
|
|
36130
|
-
decimals
|
|
36131
|
-
asset { id }
|
|
36132
|
-
curator { id }
|
|
36133
|
-
owner { id }
|
|
36134
|
-
guardian { id }
|
|
36135
|
-
timelock
|
|
36136
|
-
fee
|
|
36137
|
-
rate { id rate }
|
|
36138
|
-
lastTotalAssets
|
|
36139
|
-
totalShares
|
|
36140
|
-
}
|
|
36141
|
-
}
|
|
36142
|
-
`;
|
|
36143
|
-
function parseVaultRate(rate) {
|
|
36144
|
-
if (!rate) return 0;
|
|
36145
|
-
const numeric = Number(rate.rate) * 100;
|
|
36146
|
-
return Number.isFinite(numeric) ? numeric : 0;
|
|
36147
|
-
}
|
|
36148
|
-
function parseVault3(v, chainId, prices, tokenList) {
|
|
36149
|
-
const address = (v?.id ?? "").toLowerCase();
|
|
36150
|
-
const assetAddr = (v?.asset?.id ?? "").toLowerCase();
|
|
36151
|
-
if (!address || !assetAddr) return null;
|
|
36152
|
-
const assetMeta = tokenList[assetAddr];
|
|
36153
|
-
const decimals = Number(v.decimals ?? assetMeta?.decimals ?? 18);
|
|
36154
|
-
const totalAssetsRaw = v.lastTotalAssets?.toString() ?? "0";
|
|
36155
|
-
const totalAssetsFormatted = Number(parseRawAmount(totalAssetsRaw, decimals));
|
|
36156
|
-
const oracleKey = toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(assetAddr, chainId);
|
|
36157
|
-
const priceUsd = prices[oracleKey] ?? prices[assetAddr] ?? 0;
|
|
36158
|
-
const supplyRate = parseVaultRate(v.rate);
|
|
36159
|
-
const feeRaw = Number(v.fee ?? 0);
|
|
36160
|
-
const fee = Number.isFinite(feeRaw) ? feeRaw * 100 : 0;
|
|
36161
|
-
return {
|
|
36162
|
-
address,
|
|
36163
|
-
underlying: assetAddr,
|
|
36164
|
-
symbol: v.symbol ?? "",
|
|
36165
|
-
name: v.name ?? "",
|
|
36166
|
-
displayName: composeVaultDisplayName(
|
|
36167
|
-
"Morpho",
|
|
36168
|
-
void 0,
|
|
36169
|
-
assetMeta,
|
|
36170
|
-
v.name ?? void 0
|
|
36171
|
-
),
|
|
36172
|
-
decimals,
|
|
36173
|
-
totalAssets: totalAssetsRaw,
|
|
36174
|
-
totalSupply: v.totalShares?.toString() ?? "0",
|
|
36175
|
-
supplyRate,
|
|
36176
|
-
// Rewards APR is not carried in the subgraph schema — surface 0 so
|
|
36177
|
-
// downstream math still works; callers that need rewards on
|
|
36178
|
-
// Goldsky-sourced chains must layer them in separately.
|
|
36179
|
-
rewardsRate: 0,
|
|
36180
|
-
depositRate: supplyRate,
|
|
36181
|
-
fee,
|
|
36182
|
-
timelock: Number(v.timelock ?? 0),
|
|
36183
|
-
whitelisted: true,
|
|
36184
|
-
owner: v.owner?.id?.toLowerCase() || void 0,
|
|
36185
|
-
curator: v.curator?.id?.toLowerCase() || void 0,
|
|
36186
|
-
guardian: v.guardian?.id?.toLowerCase() || void 0,
|
|
36187
|
-
asset: assetMeta,
|
|
36188
|
-
priceUsd: priceUsd || void 0,
|
|
36189
|
-
totalAssetsFormatted,
|
|
36190
|
-
totalAssetsUsd: totalAssetsFormatted * priceUsd,
|
|
36191
|
-
// Subgraph does not expose current withdrawable liquidity — default
|
|
36192
|
-
// to totalAssets as an optimistic upper bound so callers still get a
|
|
36193
|
-
// value. Users on Goldsky-sourced chains should not rely on this for
|
|
36194
|
-
// hard withdraw validation.
|
|
36195
|
-
liquidity: totalAssetsRaw,
|
|
36196
|
-
liquidityFormatted: totalAssetsFormatted,
|
|
36197
|
-
liquidityUsd: totalAssetsFormatted * priceUsd
|
|
36198
|
-
};
|
|
36199
|
-
}
|
|
36200
|
-
async function fetchMorphoVaultsFromSubgraph(chainId, prices = {}, tokenList = {}) {
|
|
36201
|
-
const url = MORPHO_VAULT_SUBGRAPH_URLS[chainId];
|
|
36202
|
-
if (!url) return {};
|
|
36203
|
-
const response = await fetch(url, {
|
|
36204
|
-
method: "POST",
|
|
36205
|
-
headers: { "Content-Type": "application/json" },
|
|
36206
|
-
body: JSON.stringify({ query: META_MORPHOS_QUERY })
|
|
36207
|
-
});
|
|
36208
|
-
if (!response.ok) {
|
|
36209
|
-
throw new Error(
|
|
36210
|
-
`Morpho vaults subgraph failed for chain ${chainId}: ${response.status} - ${response.statusText}`
|
|
36211
|
-
);
|
|
36212
|
-
}
|
|
36213
|
-
const json = await response.json();
|
|
36214
|
-
const items = json?.data?.metaMorphos ?? [];
|
|
36215
|
-
const out = {};
|
|
36216
|
-
for (const v of items) {
|
|
36217
|
-
const parsed = parseVault3(v, chainId, prices, tokenList);
|
|
36218
|
-
if (parsed) out[parsed.address] = parsed;
|
|
36219
|
-
}
|
|
36220
|
-
return out;
|
|
36221
|
-
}
|
|
36222
36113
|
var marketUidFor = (ctx, marketId) => {
|
|
36223
36114
|
if (!ctx?.underlying) return void 0;
|
|
36224
36115
|
try {
|
|
@@ -36262,15 +36153,18 @@ async function fetchVaultSupplyShares(chainId, core, entries, marketIdsByVault,
|
|
|
36262
36153
|
}
|
|
36263
36154
|
function computeVaultAllocation(vaultAddress, decimals, totalAssetsFormatted, feePercent, priceUsd, marketIds, rateMap, positionMap, tokenList, uidCtx) {
|
|
36264
36155
|
if (totalAssetsFormatted <= 0) {
|
|
36265
|
-
return { depositRate: 0, exposures: [] };
|
|
36156
|
+
return { depositRate: 0, exposures: [], liquidityFormatted: 0 };
|
|
36266
36157
|
}
|
|
36267
36158
|
if (marketIds.length === 0) {
|
|
36268
36159
|
return {
|
|
36269
36160
|
depositRate: 0,
|
|
36270
|
-
exposures: withIdleExposure([], totalAssetsFormatted, priceUsd)
|
|
36161
|
+
exposures: withIdleExposure([], totalAssetsFormatted, priceUsd),
|
|
36162
|
+
liquidityFormatted: totalAssetsFormatted
|
|
36271
36163
|
};
|
|
36272
36164
|
}
|
|
36273
36165
|
let weighted = 0;
|
|
36166
|
+
let allocated = 0;
|
|
36167
|
+
let withdrawable = 0;
|
|
36274
36168
|
const exposures = [];
|
|
36275
36169
|
for (const id of marketIds) {
|
|
36276
36170
|
const rate = rateMap.get(id);
|
|
@@ -36283,6 +36177,9 @@ function computeVaultAllocation(vaultAddress, decimals, totalAssetsFormatted, fe
|
|
|
36283
36177
|
);
|
|
36284
36178
|
if (allocAssets <= 0) continue;
|
|
36285
36179
|
weighted += allocAssets * rate.supplyApr;
|
|
36180
|
+
allocated += allocAssets;
|
|
36181
|
+
const marketLiquidity = rate.liquidity != null ? Number(parseRawAmount(rate.liquidity.toString(), decimals)) : allocAssets;
|
|
36182
|
+
withdrawable += Math.min(allocAssets, Math.max(0, marketLiquidity));
|
|
36286
36183
|
const marketUid = marketUidFor(uidCtx, id);
|
|
36287
36184
|
exposures.push({
|
|
36288
36185
|
marketId: id,
|
|
@@ -36297,10 +36194,12 @@ function computeVaultAllocation(vaultAddress, decimals, totalAssetsFormatted, fe
|
|
|
36297
36194
|
}
|
|
36298
36195
|
exposures.sort((a, b) => b.weightPct - a.weightPct);
|
|
36299
36196
|
const grossApr = weighted / totalAssetsFormatted;
|
|
36197
|
+
const idle = Math.max(0, totalAssetsFormatted - allocated);
|
|
36300
36198
|
return {
|
|
36301
36199
|
depositRate: grossApr * (1 - feePercent / 100),
|
|
36302
36200
|
// Tag uninvested deposits as an idle entry so the breakdown sums to ~100%.
|
|
36303
|
-
exposures: withIdleExposure(exposures, totalAssetsFormatted, priceUsd)
|
|
36201
|
+
exposures: withIdleExposure(exposures, totalAssetsFormatted, priceUsd),
|
|
36202
|
+
liquidityFormatted: Math.min(totalAssetsFormatted, idle + withdrawable)
|
|
36304
36203
|
};
|
|
36305
36204
|
}
|
|
36306
36205
|
|
|
@@ -36339,6 +36238,13 @@ var toStringSafe = (raw, fallback = "") => {
|
|
|
36339
36238
|
if (raw === void 0 || raw === null) return fallback;
|
|
36340
36239
|
return String(raw);
|
|
36341
36240
|
};
|
|
36241
|
+
var toRawAmount = (formatted, decimals) => {
|
|
36242
|
+
try {
|
|
36243
|
+
return parseUnits(formatted.toFixed(decimals), decimals).toString();
|
|
36244
|
+
} catch {
|
|
36245
|
+
return "0";
|
|
36246
|
+
}
|
|
36247
|
+
};
|
|
36342
36248
|
var DEFAULT_SKIP_PROTOCOLS = /* @__PURE__ */ new Set(["LISTA_DAO"]);
|
|
36343
36249
|
var collectEntries = (chainId, protocols, skip) => {
|
|
36344
36250
|
const all = morphoTypeVaults() ?? {};
|
|
@@ -36416,7 +36322,7 @@ var fetchMorphoVaultsFromChain = async (chainId, multicallRetry, prices = {}, to
|
|
|
36416
36322
|
const { entry } = entries[i];
|
|
36417
36323
|
const base = i * PHASE1_PER_VAULT;
|
|
36418
36324
|
const slice = phase1.slice(base, base + CALLS_PER_VAULT);
|
|
36419
|
-
const parsed =
|
|
36325
|
+
const parsed = parseVault3(
|
|
36420
36326
|
entry,
|
|
36421
36327
|
slice,
|
|
36422
36328
|
chainId,
|
|
@@ -36473,17 +36379,19 @@ async function fetchMorphoMarketRates(chainId, core, marketIds, multicallRetry)
|
|
|
36473
36379
|
supplyApy = MathLib.getSupplyApy(borrowApy, utilization, mkt.fee);
|
|
36474
36380
|
} catch {
|
|
36475
36381
|
}
|
|
36382
|
+
const liquidity = mkt.totalSupplyAssets > mkt.totalBorrowAssets ? mkt.totalSupplyAssets - mkt.totalBorrowAssets : 0n;
|
|
36476
36383
|
map.set(id, {
|
|
36477
36384
|
supplyApr: apyToApr2(Number(formatEther(supplyApy))) * 100,
|
|
36478
36385
|
totalSupplyAssets: mkt.totalSupplyAssets,
|
|
36479
36386
|
totalSupplyShares: mkt.totalSupplyShares,
|
|
36480
|
-
collateralAddress: (mkt.collateralToken ?? "").toLowerCase()
|
|
36387
|
+
collateralAddress: (mkt.collateralToken ?? "").toLowerCase(),
|
|
36388
|
+
liquidity
|
|
36481
36389
|
});
|
|
36482
36390
|
});
|
|
36483
36391
|
});
|
|
36484
36392
|
return map;
|
|
36485
36393
|
}
|
|
36486
|
-
function
|
|
36394
|
+
function parseVault3(entry, results, chainId, prices, tokenList, marketIds, rateMap, positionMap) {
|
|
36487
36395
|
const address = entry?.vault?.toLowerCase();
|
|
36488
36396
|
const underlying = entry?.underlying?.toLowerCase();
|
|
36489
36397
|
if (!address || !underlying) return null;
|
|
@@ -36511,7 +36419,7 @@ function parseVault4(entry, results, chainId, prices, tokenList, marketIds, rate
|
|
|
36511
36419
|
const symbol = toStringSafe(symbolRaw);
|
|
36512
36420
|
const fee = toNumberSafe(feeRaw) / FEE_SCALE * 100;
|
|
36513
36421
|
const timelock = toNumberSafe(timelockRaw);
|
|
36514
|
-
const { depositRate, exposures } = computeVaultAllocation(
|
|
36422
|
+
const { depositRate, exposures, liquidityFormatted } = computeVaultAllocation(
|
|
36515
36423
|
address,
|
|
36516
36424
|
decimals,
|
|
36517
36425
|
totalAssetsFormatted,
|
|
@@ -36551,12 +36459,13 @@ function parseVault4(entry, results, chainId, prices, tokenList, marketIds, rate
|
|
|
36551
36459
|
priceUsd: priceUsd || void 0,
|
|
36552
36460
|
totalAssetsFormatted,
|
|
36553
36461
|
totalAssetsUsd: totalAssetsFormatted * priceUsd,
|
|
36554
|
-
//
|
|
36555
|
-
//
|
|
36556
|
-
//
|
|
36557
|
-
|
|
36558
|
-
liquidityFormatted:
|
|
36559
|
-
|
|
36462
|
+
// Real withdrawable from the allocation walk: idle + Σ min(allocation,
|
|
36463
|
+
// market liquidity) across the vault's markets. Degrades to `totalAssets`
|
|
36464
|
+
// only when no lens/core is available (rateMap empty). Fully-liquid case
|
|
36465
|
+
// reuses the exact raw total to avoid float round-trip drift.
|
|
36466
|
+
liquidity: liquidityFormatted >= totalAssetsFormatted ? totalAssets : toRawAmount(liquidityFormatted, decimals),
|
|
36467
|
+
liquidityFormatted,
|
|
36468
|
+
liquidityUsd: liquidityFormatted * priceUsd
|
|
36560
36469
|
};
|
|
36561
36470
|
}
|
|
36562
36471
|
|
|
@@ -36571,11 +36480,89 @@ var fetchMorphoVaults = async (chainId, multicallRetry, prices = {}, tokenList =
|
|
|
36571
36480
|
tokenList
|
|
36572
36481
|
);
|
|
36573
36482
|
}
|
|
36574
|
-
if (hasMorphoVaultSubgraph(chainId)) {
|
|
36575
|
-
return fetchMorphoVaultsFromSubgraph(chainId, prices, tokenList);
|
|
36576
|
-
}
|
|
36577
36483
|
return fetchMorphoVaultsFromApi(chainId, prices, tokenList);
|
|
36578
36484
|
};
|
|
36485
|
+
|
|
36486
|
+
// src/vaults/curatorName.ts
|
|
36487
|
+
var STOP_WORDS = /* @__PURE__ */ new Set([
|
|
36488
|
+
"vault",
|
|
36489
|
+
"vaults",
|
|
36490
|
+
"savings",
|
|
36491
|
+
"yield",
|
|
36492
|
+
"exclusive",
|
|
36493
|
+
"dao",
|
|
36494
|
+
"x",
|
|
36495
|
+
"pt",
|
|
36496
|
+
"prime",
|
|
36497
|
+
"staked",
|
|
36498
|
+
"core",
|
|
36499
|
+
"lista",
|
|
36500
|
+
// protocol brand; a bare "Lista …" vault has no distinct curator
|
|
36501
|
+
"moolah"
|
|
36502
|
+
]);
|
|
36503
|
+
var ASSET_TOKENS = /* @__PURE__ */ new Set([
|
|
36504
|
+
"usdc",
|
|
36505
|
+
"usdt",
|
|
36506
|
+
"usd1",
|
|
36507
|
+
"usds",
|
|
36508
|
+
"dai",
|
|
36509
|
+
"usde",
|
|
36510
|
+
"susde",
|
|
36511
|
+
"lisusd",
|
|
36512
|
+
"gho",
|
|
36513
|
+
"frax",
|
|
36514
|
+
"pyusd",
|
|
36515
|
+
"rusd",
|
|
36516
|
+
"usr",
|
|
36517
|
+
"rlp",
|
|
36518
|
+
"eth",
|
|
36519
|
+
"weth",
|
|
36520
|
+
"wsteth",
|
|
36521
|
+
"reth",
|
|
36522
|
+
"steth",
|
|
36523
|
+
"cbeth",
|
|
36524
|
+
"weeth",
|
|
36525
|
+
"ezeth",
|
|
36526
|
+
"btc",
|
|
36527
|
+
"wbtc",
|
|
36528
|
+
"btcb",
|
|
36529
|
+
"cbbtc",
|
|
36530
|
+
"tbtc",
|
|
36531
|
+
"xaut",
|
|
36532
|
+
"xrp",
|
|
36533
|
+
"bnb",
|
|
36534
|
+
"wbnb",
|
|
36535
|
+
"sol",
|
|
36536
|
+
"op",
|
|
36537
|
+
"arb",
|
|
36538
|
+
"avax",
|
|
36539
|
+
"pol",
|
|
36540
|
+
"matic",
|
|
36541
|
+
"sei",
|
|
36542
|
+
"celo",
|
|
36543
|
+
"hype",
|
|
36544
|
+
"plume",
|
|
36545
|
+
"s"
|
|
36546
|
+
]);
|
|
36547
|
+
function curatorNameFromVaultName(name, assetSymbol) {
|
|
36548
|
+
if (!name) return void 0;
|
|
36549
|
+
const cleaned = name.replace(/\([^)]*\)\s*$/, "").trim();
|
|
36550
|
+
if (!cleaned) return void 0;
|
|
36551
|
+
const tokens = cleaned.split(/[\s/]+/).flatMap((t) => t.split("-")).filter(Boolean);
|
|
36552
|
+
const asset = (assetSymbol ?? "").toLowerCase();
|
|
36553
|
+
const out = [];
|
|
36554
|
+
for (const tok of tokens) {
|
|
36555
|
+
const tl = tok.toLowerCase();
|
|
36556
|
+
if (STOP_WORDS.has(tl)) break;
|
|
36557
|
+
if (asset && tl === asset || ASSET_TOKENS.has(tl)) break;
|
|
36558
|
+
out.push(tok);
|
|
36559
|
+
if (out.length >= 3) break;
|
|
36560
|
+
}
|
|
36561
|
+
const curator = out.join(" ").trim();
|
|
36562
|
+
return curator.length >= 2 ? curator : void 0;
|
|
36563
|
+
}
|
|
36564
|
+
|
|
36565
|
+
// src/vaults/morpho/fetchListaFromChain.ts
|
|
36579
36566
|
var { chunk: chunk6 } = lodash;
|
|
36580
36567
|
var LISTA_PROTOCOL = "LISTA_DAO";
|
|
36581
36568
|
var LISTA_LENS_ABI = parseAbi([
|
|
@@ -36612,6 +36599,13 @@ var toStringSafe2 = (raw, fallback = "") => {
|
|
|
36612
36599
|
if (raw === void 0 || raw === null) return fallback;
|
|
36613
36600
|
return String(raw);
|
|
36614
36601
|
};
|
|
36602
|
+
var toRawAmount2 = (formatted, decimals) => {
|
|
36603
|
+
try {
|
|
36604
|
+
return parseUnits(formatted.toFixed(decimals), decimals).toString();
|
|
36605
|
+
} catch {
|
|
36606
|
+
return "0";
|
|
36607
|
+
}
|
|
36608
|
+
};
|
|
36615
36609
|
var collectEntries2 = (chainId) => {
|
|
36616
36610
|
const list = morphoTypeVaults()?.[LISTA_PROTOCOL]?.[chainId] ?? [];
|
|
36617
36611
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -36699,7 +36693,7 @@ var fetchListaVaultsFromChain = async (chainId, multicallRetry, prices = {}, tok
|
|
|
36699
36693
|
for (let i = 0; i < entries.length; i++) {
|
|
36700
36694
|
const entry = entries[i];
|
|
36701
36695
|
const slice = phase1.slice(i * PHASE1_PER_VAULT2, (i + 1) * PHASE1_PER_VAULT2);
|
|
36702
|
-
const parsed =
|
|
36696
|
+
const parsed = parseVault4(
|
|
36703
36697
|
entry,
|
|
36704
36698
|
slice,
|
|
36705
36699
|
curatorAddrByVault[i],
|
|
@@ -36759,17 +36753,19 @@ async function fetchListaMarketRates(chainId, moolah, marketIds, multicallRetry)
|
|
|
36759
36753
|
supplyApy = MathLib.getSupplyApy(borrowApy, utilization, mkt.fee);
|
|
36760
36754
|
} catch {
|
|
36761
36755
|
}
|
|
36756
|
+
const liquidity = mkt.totalSupplyAssets > mkt.totalBorrowAssets ? mkt.totalSupplyAssets - mkt.totalBorrowAssets : 0n;
|
|
36762
36757
|
map.set(id, {
|
|
36763
36758
|
supplyApr: apyToApr(Number(formatEther(supplyApy))) * 100,
|
|
36764
36759
|
totalSupplyAssets: mkt.totalSupplyAssets,
|
|
36765
36760
|
totalSupplyShares: mkt.totalSupplyShares,
|
|
36766
|
-
collateralAddress: (mkt.collateralToken ?? "").toLowerCase()
|
|
36761
|
+
collateralAddress: (mkt.collateralToken ?? "").toLowerCase(),
|
|
36762
|
+
liquidity
|
|
36767
36763
|
});
|
|
36768
36764
|
});
|
|
36769
36765
|
});
|
|
36770
36766
|
return map;
|
|
36771
36767
|
}
|
|
36772
|
-
function
|
|
36768
|
+
function parseVault4(entry, results, curatorAddrRaw, chainId, prices, tokenList, marketIds, rateMap, positionMap) {
|
|
36773
36769
|
const address = entry?.vault?.toLowerCase();
|
|
36774
36770
|
const underlying = entry?.underlying?.toLowerCase();
|
|
36775
36771
|
if (!address || !underlying) return null;
|
|
@@ -36796,7 +36792,7 @@ function parseVault5(entry, results, curatorAddrRaw, chainId, prices, tokenList,
|
|
|
36796
36792
|
const fallbackName = onchainName || (entry.name ?? "").trim();
|
|
36797
36793
|
const symbol = toStringSafe2(symbolRaw);
|
|
36798
36794
|
const fee = toNumberSafe2(feeRaw) / FEE_SCALE2 * 100;
|
|
36799
|
-
const { depositRate, exposures } = computeVaultAllocation(
|
|
36795
|
+
const { depositRate, exposures, liquidityFormatted } = computeVaultAllocation(
|
|
36800
36796
|
address,
|
|
36801
36797
|
decimals,
|
|
36802
36798
|
totalAssetsFormatted,
|
|
@@ -36830,14 +36826,20 @@ function parseVault5(entry, results, curatorAddrRaw, chainId, prices, tokenList,
|
|
|
36830
36826
|
whitelisted: true,
|
|
36831
36827
|
owner: void 0,
|
|
36832
36828
|
curator: lcOrUndefined2(curatorAddrRaw),
|
|
36829
|
+
// Moolah exposes only the curator address; derive a display name from the
|
|
36830
|
+
// (curator-branded) vault name as a best-effort fallback.
|
|
36831
|
+
curatorName: curatorNameFromVaultName(fallbackName, assetMeta?.symbol),
|
|
36833
36832
|
guardian: void 0,
|
|
36834
36833
|
asset: assetMeta,
|
|
36835
36834
|
priceUsd: priceUsd || void 0,
|
|
36836
36835
|
totalAssetsFormatted,
|
|
36837
36836
|
totalAssetsUsd: totalAssetsFormatted * priceUsd,
|
|
36838
|
-
|
|
36839
|
-
|
|
36840
|
-
|
|
36837
|
+
// Real withdrawable: idle + Σ min(allocation, market liquidity) across the
|
|
36838
|
+
// vault's Moolah markets (see `computeVaultAllocation`). Fully-liquid case
|
|
36839
|
+
// reuses the exact raw total to avoid float round-trip drift.
|
|
36840
|
+
liquidity: liquidityFormatted >= totalAssetsFormatted ? totalAssets : toRawAmount2(liquidityFormatted, decimals),
|
|
36841
|
+
liquidityFormatted,
|
|
36842
|
+
liquidityUsd: liquidityFormatted * priceUsd,
|
|
36841
36843
|
exposures: exposures.length > 0 ? exposures : void 0
|
|
36842
36844
|
};
|
|
36843
36845
|
}
|
|
@@ -36882,6 +36884,7 @@ query GetSiloVaults {
|
|
|
36882
36884
|
depositRate
|
|
36883
36885
|
collateralSharesSupply
|
|
36884
36886
|
collateralAssetsSupply
|
|
36887
|
+
liquidity
|
|
36885
36888
|
otherMarket { inputToken { id } }
|
|
36886
36889
|
}
|
|
36887
36890
|
}
|
|
@@ -36918,8 +36921,28 @@ function buildExposures(vaultId, totalAssetsFormatted, pricePerUnit, positionsBy
|
|
|
36918
36921
|
);
|
|
36919
36922
|
return withIdle.length > 0 ? withIdle : void 0;
|
|
36920
36923
|
}
|
|
36924
|
+
function computeSiloLiquidityFormatted(vaultId, totalAssetsFormatted, positionsByVault, marketMeta) {
|
|
36925
|
+
if (totalAssetsFormatted <= 0) return 0;
|
|
36926
|
+
const rows = positionsByVault.get(vaultId) ?? [];
|
|
36927
|
+
let allocated = 0;
|
|
36928
|
+
let withdrawable = 0;
|
|
36929
|
+
for (const row of rows) {
|
|
36930
|
+
const marketId = (row.marketId ?? "").toLowerCase();
|
|
36931
|
+
if (!marketId) continue;
|
|
36932
|
+
const meta = marketMeta.get(marketId);
|
|
36933
|
+
if (!meta || meta.collateralShares <= 0) continue;
|
|
36934
|
+
const shares = Number(row.sTokenBalance ?? 0);
|
|
36935
|
+
if (!Number.isFinite(shares) || shares <= 0) continue;
|
|
36936
|
+
const assets = shares * meta.collateralAssets / meta.collateralShares;
|
|
36937
|
+
if (!(assets > 0) || assets > totalAssetsFormatted * 1.01) continue;
|
|
36938
|
+
allocated += assets;
|
|
36939
|
+
withdrawable += Math.min(assets, meta.liquidity);
|
|
36940
|
+
}
|
|
36941
|
+
const idle = Math.max(0, totalAssetsFormatted - allocated);
|
|
36942
|
+
return Math.min(totalAssetsFormatted, idle + withdrawable);
|
|
36943
|
+
}
|
|
36921
36944
|
var PERFORMANCE_FEE_SCALE = 1e16;
|
|
36922
|
-
var
|
|
36945
|
+
var toRawAmount3 = (decimalString, decimals) => {
|
|
36923
36946
|
if (!decimalString) return "0";
|
|
36924
36947
|
try {
|
|
36925
36948
|
return parseUnits(decimalString, decimals).toString();
|
|
@@ -36927,7 +36950,7 @@ var toRawAmount = (decimalString, decimals) => {
|
|
|
36927
36950
|
return "0";
|
|
36928
36951
|
}
|
|
36929
36952
|
};
|
|
36930
|
-
function
|
|
36953
|
+
function parseVault5(v, chainId, prices, tokenList, exposures, liquidityFormatted) {
|
|
36931
36954
|
const address = (v?.id ?? "").toLowerCase();
|
|
36932
36955
|
const assetAddr = (v?.asset?.id ?? "").toLowerCase();
|
|
36933
36956
|
if (!address || !assetAddr) return null;
|
|
@@ -36936,8 +36959,8 @@ function parseVault6(v, chainId, prices, tokenList, exposures) {
|
|
|
36936
36959
|
v.decimals ?? v.asset?.decimals ?? assetMeta?.decimals ?? 18
|
|
36937
36960
|
);
|
|
36938
36961
|
const totalAssetsFormatted = Number(v.totalAssets ?? 0) || 0;
|
|
36939
|
-
const totalAssetsRaw =
|
|
36940
|
-
const totalSupplyRaw =
|
|
36962
|
+
const totalAssetsRaw = toRawAmount3(v.totalAssets, decimals);
|
|
36963
|
+
const totalSupplyRaw = toRawAmount3(v.totalSupply, decimals);
|
|
36941
36964
|
const oracleKey = toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(assetAddr, chainId);
|
|
36942
36965
|
const priceUsd = prices[oracleKey] ?? prices[assetAddr] ?? 0;
|
|
36943
36966
|
const supplyRate = Number(v.userApr ?? 0) || 0;
|
|
@@ -36976,14 +36999,14 @@ function parseVault6(v, chainId, prices, tokenList, exposures) {
|
|
|
36976
36999
|
priceUsd: priceUsd || void 0,
|
|
36977
37000
|
totalAssetsFormatted,
|
|
36978
37001
|
totalAssetsUsd,
|
|
36979
|
-
//
|
|
36980
|
-
//
|
|
36981
|
-
//
|
|
36982
|
-
//
|
|
36983
|
-
//
|
|
36984
|
-
liquidity: totalAssetsRaw,
|
|
36985
|
-
liquidityFormatted
|
|
36986
|
-
liquidityUsd: totalAssetsUsd,
|
|
37002
|
+
// Real immediately-withdrawable liquidity: idle + Σ min(allocation,
|
|
37003
|
+
// market.liquidity) across the vault's silos (see
|
|
37004
|
+
// `computeSiloLiquidityFormatted`). Degrades to `totalAssets` only when
|
|
37005
|
+
// allocation data is absent. When fully liquid, reuse the exact
|
|
37006
|
+
// `totalAssetsRaw` to avoid float round-trip drift.
|
|
37007
|
+
liquidity: liquidityFormatted >= totalAssetsFormatted ? totalAssetsRaw : toRawAmount3(liquidityFormatted.toFixed(decimals), decimals),
|
|
37008
|
+
liquidityFormatted,
|
|
37009
|
+
liquidityUsd: totalAssetsFormatted > 0 ? liquidityFormatted * (totalAssetsUsd / totalAssetsFormatted) : 0,
|
|
36987
37010
|
exposures
|
|
36988
37011
|
};
|
|
36989
37012
|
}
|
|
@@ -37026,7 +37049,8 @@ var fetchSiloVaults = async (chainId, prices = {}, tokenList = {}, options) => {
|
|
|
37026
37049
|
collateralAddress: (m.otherMarket?.inputToken?.id ?? "").toLowerCase(),
|
|
37027
37050
|
supplyApr: Number.isFinite(apr) ? apr : 0,
|
|
37028
37051
|
collateralShares: Number(m.collateralSharesSupply ?? 0) || 0,
|
|
37029
|
-
collateralAssets: Number(m.collateralAssetsSupply ?? 0) || 0
|
|
37052
|
+
collateralAssets: Number(m.collateralAssetsSupply ?? 0) || 0,
|
|
37053
|
+
liquidity: Number(m.liquidity ?? 0) || 0
|
|
37030
37054
|
});
|
|
37031
37055
|
}
|
|
37032
37056
|
const out = {};
|
|
@@ -37046,7 +37070,20 @@ var fetchSiloVaults = async (chainId, prices = {}, tokenList = {}, options) => {
|
|
|
37046
37070
|
marketMeta,
|
|
37047
37071
|
tokenList
|
|
37048
37072
|
);
|
|
37049
|
-
const
|
|
37073
|
+
const liquidityFormatted = computeSiloLiquidityFormatted(
|
|
37074
|
+
vaultId,
|
|
37075
|
+
totalAssetsFormatted,
|
|
37076
|
+
positionsByVault,
|
|
37077
|
+
marketMeta
|
|
37078
|
+
);
|
|
37079
|
+
const parsed = parseVault5(
|
|
37080
|
+
v,
|
|
37081
|
+
chainId,
|
|
37082
|
+
prices,
|
|
37083
|
+
tokenList,
|
|
37084
|
+
exposures,
|
|
37085
|
+
liquidityFormatted
|
|
37086
|
+
);
|
|
37050
37087
|
if (parsed) out[parsed.address] = parsed;
|
|
37051
37088
|
}
|
|
37052
37089
|
return out;
|
|
@@ -37167,7 +37204,7 @@ function computeRealLiquidity(strategies, totalAssetsRaw, evkIndex) {
|
|
|
37167
37204
|
const result = idle + withdrawable;
|
|
37168
37205
|
return result > totalAssets ? totalAssets : result;
|
|
37169
37206
|
}
|
|
37170
|
-
function
|
|
37207
|
+
function parseVault6(v, chainId, prices, tokenList, evkIndex) {
|
|
37171
37208
|
const address = (v?.id ?? "").toLowerCase();
|
|
37172
37209
|
const assetAddr = (v?.asset ?? "").toLowerCase();
|
|
37173
37210
|
if (!address || !assetAddr) return null;
|
|
@@ -37208,6 +37245,7 @@ function parseVault7(v, chainId, prices, tokenList, evkIndex) {
|
|
|
37208
37245
|
fee,
|
|
37209
37246
|
owner: readAddress2(v.owner),
|
|
37210
37247
|
curator: readAddress2(v.curator),
|
|
37248
|
+
curatorName: curatorNameFromVaultName(v.name, assetMeta?.symbol),
|
|
37211
37249
|
guardian: readAddress2(v.guardian),
|
|
37212
37250
|
feeRecipient: v.feeReceiver?.toLowerCase() || void 0,
|
|
37213
37251
|
asset: assetMeta,
|
|
@@ -37282,7 +37320,7 @@ async function fetchEulerEarnVaultsFromSubgraph(chainId, prices = {}, tokenList
|
|
|
37282
37320
|
const evkIndex = await fetchEvkIndex(url, [...assets]);
|
|
37283
37321
|
const out = {};
|
|
37284
37322
|
for (const v of items) {
|
|
37285
|
-
const parsed =
|
|
37323
|
+
const parsed = parseVault6(v, chainId, prices, tokenList, evkIndex);
|
|
37286
37324
|
if (parsed) out[parsed.address] = parsed;
|
|
37287
37325
|
}
|
|
37288
37326
|
return out;
|
|
@@ -43419,6 +43457,10 @@ var fetchSavingsVaults = async (chainId, multicallRetry, prices = {}, tokenList
|
|
|
43419
43457
|
const underlyingUnit = 10n ** BigInt(underlyingDec);
|
|
43420
43458
|
const totalAssetsFormatted = Number(state.totalAssets) / 10 ** underlyingDec;
|
|
43421
43459
|
const totalAssetsUsd = priceUsd !== void 0 ? totalAssetsFormatted * priceUsd : 0;
|
|
43460
|
+
const isInstant = entry.withdrawalMode === "instant";
|
|
43461
|
+
const liquidityRaw = isInstant ? state.totalAssets.toString() : "0";
|
|
43462
|
+
const liquidityFormatted = isInstant ? totalAssetsFormatted : 0;
|
|
43463
|
+
const liquidityUsd = isInstant ? totalAssetsUsd : 0;
|
|
43422
43464
|
const convertToAssets = state.exchangeRate * underlyingUnit / ONE_E1810;
|
|
43423
43465
|
const convertToShares = state.exchangeRate > 0n ? ONE_E1810 * shareUnit / state.exchangeRate : 0n;
|
|
43424
43466
|
const displayName = composeVaultDisplayName(
|
|
@@ -43456,7 +43498,10 @@ var fetchSavingsVaults = async (chainId, multicallRetry, prices = {}, tokenList
|
|
|
43456
43498
|
asset,
|
|
43457
43499
|
priceUsd,
|
|
43458
43500
|
totalAssetsFormatted,
|
|
43459
|
-
totalAssetsUsd
|
|
43501
|
+
totalAssetsUsd,
|
|
43502
|
+
liquidity: liquidityRaw,
|
|
43503
|
+
liquidityFormatted,
|
|
43504
|
+
liquidityUsd
|
|
43460
43505
|
};
|
|
43461
43506
|
out[addressLc] = vault;
|
|
43462
43507
|
}
|
|
@@ -43500,6 +43545,10 @@ query LagoonVaults($where: VaultFilterInput!, $first: Int!, $skip: Int!) {
|
|
|
43500
43545
|
name
|
|
43501
43546
|
symbol
|
|
43502
43547
|
decimals
|
|
43548
|
+
curators {
|
|
43549
|
+
id
|
|
43550
|
+
name
|
|
43551
|
+
}
|
|
43503
43552
|
isVisible
|
|
43504
43553
|
asset {
|
|
43505
43554
|
address
|
|
@@ -43572,12 +43621,11 @@ var pickApr = (apr) => {
|
|
|
43572
43621
|
if (apr.monthly != null) return { rate: apr.monthly, window: "monthly" };
|
|
43573
43622
|
if (apr.weekly != null) return { rate: apr.weekly, window: "weekly" };
|
|
43574
43623
|
if (apr.yearly != null) return { rate: apr.yearly, window: "yearly" };
|
|
43575
|
-
if (apr.inception != null)
|
|
43576
|
-
return { rate: apr.inception, window: "inception" };
|
|
43624
|
+
if (apr.inception != null) return { rate: apr.inception, window: "inception" };
|
|
43577
43625
|
return { rate: 0, window: "none" };
|
|
43578
43626
|
};
|
|
43579
43627
|
var num = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
43580
|
-
function
|
|
43628
|
+
function parseVault7(v, chainId, prices, tokenList) {
|
|
43581
43629
|
const address = (v?.address ?? "").toLowerCase();
|
|
43582
43630
|
const assetAddr = (v?.asset?.address ?? "").toLowerCase();
|
|
43583
43631
|
if (!address || !assetAddr) return null;
|
|
@@ -43606,12 +43654,14 @@ function parseVault8(v, chainId, prices, tokenList) {
|
|
|
43606
43654
|
const name = (v.name ?? "").trim();
|
|
43607
43655
|
const symbol = (v.symbol ?? "").trim();
|
|
43608
43656
|
const displayName = name || composeVaultDisplayName(BRAND, void 0, assetMeta, symbol);
|
|
43657
|
+
const curatorName = v.curators?.find((c) => c?.name)?.name ?? void 0;
|
|
43609
43658
|
return {
|
|
43610
43659
|
address,
|
|
43611
43660
|
underlying: assetAddr,
|
|
43612
43661
|
symbol,
|
|
43613
43662
|
name: name || symbol,
|
|
43614
43663
|
displayName,
|
|
43664
|
+
...curatorName ? { curatorName } : {},
|
|
43615
43665
|
decimals,
|
|
43616
43666
|
assetDecimals,
|
|
43617
43667
|
totalAssets: totalAssetsRaw,
|
|
@@ -43635,10 +43685,249 @@ var fetchLagoonVaults = async (chainId, prices = {}, tokenList = {}) => {
|
|
|
43635
43685
|
if (!hasLagoonVaults(chainId)) return {};
|
|
43636
43686
|
const items = await fetchLagoonApiVaults(chainId);
|
|
43637
43687
|
const out = {};
|
|
43688
|
+
for (const item of items) {
|
|
43689
|
+
const parsed = parseVault7(item, chainId, prices, tokenList);
|
|
43690
|
+
if (parsed) out[parsed.address] = parsed;
|
|
43691
|
+
}
|
|
43692
|
+
return out;
|
|
43693
|
+
};
|
|
43694
|
+
|
|
43695
|
+
// src/vaults/yearn/api.ts
|
|
43696
|
+
var YEARN_YDAEMON_BASE = "https://ydaemon.yearn.fi";
|
|
43697
|
+
var YEARN_CHAIN_IDS = /* @__PURE__ */ new Set([
|
|
43698
|
+
"1",
|
|
43699
|
+
// Ethereum
|
|
43700
|
+
"137",
|
|
43701
|
+
// Polygon
|
|
43702
|
+
"8453",
|
|
43703
|
+
// Base
|
|
43704
|
+
"42161",
|
|
43705
|
+
// Arbitrum
|
|
43706
|
+
"100",
|
|
43707
|
+
// Gnosis
|
|
43708
|
+
"146",
|
|
43709
|
+
// Sonic
|
|
43710
|
+
"747474"
|
|
43711
|
+
// Katana
|
|
43712
|
+
]);
|
|
43713
|
+
var hasYearnVaults = (chainId) => YEARN_CHAIN_IDS.has(String(chainId));
|
|
43714
|
+
var isYearnV3 = (v) => typeof v?.version === "string" && v.version.startsWith("3.");
|
|
43715
|
+
var PAGE_SIZE3 = 500;
|
|
43716
|
+
async function fetchYearnApiVaults(chainId) {
|
|
43717
|
+
const out = [];
|
|
43718
|
+
for (let page = 1; page <= 20; page++) {
|
|
43719
|
+
const url = `${YEARN_YDAEMON_BASE}/${chainId}/vaults/all?limit=${PAGE_SIZE3}&page=${page}`;
|
|
43720
|
+
const response = await fetch(url);
|
|
43721
|
+
if (!response.ok) {
|
|
43722
|
+
throw new Error(
|
|
43723
|
+
`Yearn yDaemon API failed: ${response.status} - ${response.statusText}`
|
|
43724
|
+
);
|
|
43725
|
+
}
|
|
43726
|
+
const items = await response.json();
|
|
43727
|
+
if (!Array.isArray(items)) break;
|
|
43728
|
+
for (const v of items) {
|
|
43729
|
+
if (isYearnV3(v) && v.endorsed) out.push(v);
|
|
43730
|
+
}
|
|
43731
|
+
if (items.length < PAGE_SIZE3) break;
|
|
43732
|
+
}
|
|
43733
|
+
return out;
|
|
43734
|
+
}
|
|
43735
|
+
|
|
43736
|
+
// src/vaults/yearn/fetchPublic.ts
|
|
43737
|
+
var BRAND2 = "Yearn";
|
|
43738
|
+
var ZERO_ADDR = "0x0000000000000000000000000000000000000000";
|
|
43739
|
+
var YearnLiquidityAbi = [
|
|
43740
|
+
{
|
|
43741
|
+
type: "function",
|
|
43742
|
+
name: "availableWithdrawLimit",
|
|
43743
|
+
stateMutability: "view",
|
|
43744
|
+
inputs: [{ name: "owner", type: "address" }],
|
|
43745
|
+
outputs: [{ type: "uint256" }]
|
|
43746
|
+
},
|
|
43747
|
+
{
|
|
43748
|
+
type: "function",
|
|
43749
|
+
name: "totalIdle",
|
|
43750
|
+
stateMutability: "view",
|
|
43751
|
+
inputs: [],
|
|
43752
|
+
outputs: [{ type: "uint256" }]
|
|
43753
|
+
},
|
|
43754
|
+
{
|
|
43755
|
+
type: "function",
|
|
43756
|
+
name: "get_default_queue",
|
|
43757
|
+
stateMutability: "view",
|
|
43758
|
+
inputs: [],
|
|
43759
|
+
outputs: [{ type: "address[]" }]
|
|
43760
|
+
},
|
|
43761
|
+
{
|
|
43762
|
+
type: "function",
|
|
43763
|
+
name: "maxWithdraw",
|
|
43764
|
+
stateMutability: "view",
|
|
43765
|
+
inputs: [{ name: "owner", type: "address" }],
|
|
43766
|
+
outputs: [{ type: "uint256" }]
|
|
43767
|
+
}
|
|
43768
|
+
];
|
|
43769
|
+
var asBig = (v) => {
|
|
43770
|
+
try {
|
|
43771
|
+
if (typeof v === "bigint") return v;
|
|
43772
|
+
if (typeof v === "number" && Number.isFinite(v))
|
|
43773
|
+
return BigInt(Math.trunc(v));
|
|
43774
|
+
if (typeof v === "string" && /^\d+$/.test(v)) return BigInt(v);
|
|
43775
|
+
return null;
|
|
43776
|
+
} catch {
|
|
43777
|
+
return null;
|
|
43778
|
+
}
|
|
43779
|
+
};
|
|
43780
|
+
var num2 = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
43781
|
+
var toPct = (v) => {
|
|
43782
|
+
const n = num2(v);
|
|
43783
|
+
return n == null ? 0 : n * 100;
|
|
43784
|
+
};
|
|
43785
|
+
var deriveTotalSupply = (totalAssetsRaw, pricePerShareRaw, decimals) => {
|
|
43786
|
+
try {
|
|
43787
|
+
const assets = BigInt(totalAssetsRaw || "0");
|
|
43788
|
+
if (assets === 0n) return "0";
|
|
43789
|
+
const pps = BigInt(pricePerShareRaw || "0");
|
|
43790
|
+
if (pps <= 0n) return totalAssetsRaw;
|
|
43791
|
+
const scale = 10n ** BigInt(decimals);
|
|
43792
|
+
return (assets * scale / pps).toString();
|
|
43793
|
+
} catch {
|
|
43794
|
+
return totalAssetsRaw || "0";
|
|
43795
|
+
}
|
|
43796
|
+
};
|
|
43797
|
+
function parseVault8(v, chainId, prices, tokenList) {
|
|
43798
|
+
const address = (v?.address ?? "").toLowerCase();
|
|
43799
|
+
const assetAddr = (v?.token?.address ?? "").toLowerCase();
|
|
43800
|
+
if (!address || !assetAddr) return null;
|
|
43801
|
+
const assetMeta = tokenList[assetAddr];
|
|
43802
|
+
const decimals = Number(v.decimals ?? 18);
|
|
43803
|
+
const assetDecimals = Number(v.token?.decimals ?? assetMeta?.decimals ?? 18);
|
|
43804
|
+
const totalAssetsRaw = v.tvl?.totalAssets?.toString() ?? "0";
|
|
43805
|
+
const pricePerShare = v.pricePerShare?.toString() ?? "0";
|
|
43806
|
+
const totalSupplyRaw = deriveTotalSupply(
|
|
43807
|
+
totalAssetsRaw,
|
|
43808
|
+
pricePerShare,
|
|
43809
|
+
decimals
|
|
43810
|
+
);
|
|
43811
|
+
const totalAssetsFormatted = Number(
|
|
43812
|
+
parseRawAmount(totalAssetsRaw, assetDecimals)
|
|
43813
|
+
);
|
|
43814
|
+
const realized = num2(v.apr?.netAPR);
|
|
43815
|
+
const forward = num2(v.apr?.forwardAPR?.netAPR);
|
|
43816
|
+
const isForwardApr = realized == null && forward != null;
|
|
43817
|
+
const supplyRate = toPct(realized ?? forward);
|
|
43818
|
+
const rewardsRate = toPct(v.apr?.extra?.stakingRewardsAPR);
|
|
43819
|
+
const fee = toPct(v.apr?.fees?.performance);
|
|
43820
|
+
const oracleKey = toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(assetAddr, chainId);
|
|
43821
|
+
const apiPrice = num2(v.tvl?.price) ?? 0;
|
|
43822
|
+
const priceUsd = prices[oracleKey] ?? prices[assetAddr] ?? apiPrice;
|
|
43823
|
+
const apiTvlUsd = num2(v.tvl?.tvl) ?? 0;
|
|
43824
|
+
const totalAssetsUsd = apiTvlUsd || totalAssetsFormatted * priceUsd;
|
|
43825
|
+
const name = (v.name ?? "").trim();
|
|
43826
|
+
const symbol = (v.symbol ?? "").trim();
|
|
43827
|
+
const displayName = composeVaultDisplayName(BRAND2, BRAND2, assetMeta, name);
|
|
43828
|
+
return {
|
|
43829
|
+
address,
|
|
43830
|
+
underlying: assetAddr,
|
|
43831
|
+
symbol,
|
|
43832
|
+
name: name || symbol,
|
|
43833
|
+
displayName,
|
|
43834
|
+
curatorName: BRAND2,
|
|
43835
|
+
decimals,
|
|
43836
|
+
assetDecimals,
|
|
43837
|
+
totalAssets: totalAssetsRaw,
|
|
43838
|
+
totalSupply: totalSupplyRaw,
|
|
43839
|
+
pricePerShare,
|
|
43840
|
+
supplyRate,
|
|
43841
|
+
rewardsRate,
|
|
43842
|
+
depositRate: supplyRate + rewardsRate,
|
|
43843
|
+
fee,
|
|
43844
|
+
isForwardApr,
|
|
43845
|
+
kind: v.kind ?? "Multi Strategy",
|
|
43846
|
+
version: v.version ?? "",
|
|
43847
|
+
...v.category ? { category: v.category } : {},
|
|
43848
|
+
asset: assetMeta,
|
|
43849
|
+
priceUsd,
|
|
43850
|
+
totalAssetsFormatted,
|
|
43851
|
+
totalAssetsUsd
|
|
43852
|
+
};
|
|
43853
|
+
}
|
|
43854
|
+
var setLiquidity = (v, liq) => {
|
|
43855
|
+
v.liquidity = liq.toString();
|
|
43856
|
+
v.liquidityFormatted = Number(parseRawAmount(v.liquidity, v.assetDecimals));
|
|
43857
|
+
v.liquidityUsd = v.priceUsd != null ? v.liquidityFormatted * v.priceUsd : v.liquidityFormatted;
|
|
43858
|
+
};
|
|
43859
|
+
var attachYearnLiquidity = async (chainId, multicallRetry, out) => {
|
|
43860
|
+
const vaults = Object.values(out);
|
|
43861
|
+
if (vaults.length === 0) return;
|
|
43862
|
+
const r1Calls = vaults.flatMap((v) => [
|
|
43863
|
+
{ address: v.address, name: "availableWithdrawLimit", params: [ZERO_ADDR] },
|
|
43864
|
+
{ address: v.address, name: "get_default_queue", params: [] },
|
|
43865
|
+
{ address: v.address, name: "totalIdle", params: [] }
|
|
43866
|
+
]);
|
|
43867
|
+
const r1 = await multicallRetry({
|
|
43868
|
+
chain: chainId,
|
|
43869
|
+
calls: r1Calls,
|
|
43870
|
+
abi: r1Calls.map(() => YearnLiquidityAbi),
|
|
43871
|
+
maxRetries: 2,
|
|
43872
|
+
allowFailure: true
|
|
43873
|
+
});
|
|
43874
|
+
const pending = [];
|
|
43875
|
+
for (let i = 0; i < vaults.length; i++) {
|
|
43876
|
+
const v = vaults[i];
|
|
43877
|
+
const totalAssets = asBig(v.totalAssets) ?? 0n;
|
|
43878
|
+
const awl = asBig(r1[i * 3]);
|
|
43879
|
+
const queueRaw = r1[i * 3 + 1];
|
|
43880
|
+
const idle = asBig(r1[i * 3 + 2]) ?? 0n;
|
|
43881
|
+
if (awl != null) {
|
|
43882
|
+
setLiquidity(v, awl >= totalAssets ? totalAssets : awl);
|
|
43883
|
+
} else if (Array.isArray(queueRaw) && queueRaw.length > 0) {
|
|
43884
|
+
pending.push({
|
|
43885
|
+
v,
|
|
43886
|
+
idle,
|
|
43887
|
+
queue: queueRaw.map((a) => String(a).toLowerCase()),
|
|
43888
|
+
totalAssets
|
|
43889
|
+
});
|
|
43890
|
+
} else if (asBig(r1[i * 3 + 2]) != null) {
|
|
43891
|
+
setLiquidity(v, idle >= totalAssets ? totalAssets : idle);
|
|
43892
|
+
}
|
|
43893
|
+
}
|
|
43894
|
+
if (pending.length === 0) return;
|
|
43895
|
+
const r2Calls = pending.flatMap(
|
|
43896
|
+
(p) => p.queue.map((s) => ({
|
|
43897
|
+
address: s,
|
|
43898
|
+
name: "maxWithdraw",
|
|
43899
|
+
params: [p.v.address]
|
|
43900
|
+
}))
|
|
43901
|
+
);
|
|
43902
|
+
const r2 = await multicallRetry({
|
|
43903
|
+
chain: chainId,
|
|
43904
|
+
calls: r2Calls,
|
|
43905
|
+
abi: r2Calls.map(() => YearnLiquidityAbi),
|
|
43906
|
+
maxRetries: 2,
|
|
43907
|
+
allowFailure: true
|
|
43908
|
+
});
|
|
43909
|
+
let idx = 0;
|
|
43910
|
+
for (const p of pending) {
|
|
43911
|
+
let sum = p.idle;
|
|
43912
|
+
for (let j = 0; j < p.queue.length; j++) {
|
|
43913
|
+
const w = asBig(r2[idx++]);
|
|
43914
|
+
if (w != null) sum += w;
|
|
43915
|
+
}
|
|
43916
|
+
setLiquidity(p.v, sum >= p.totalAssets ? p.totalAssets : sum);
|
|
43917
|
+
}
|
|
43918
|
+
};
|
|
43919
|
+
var fetchYearnVaults = async (chainId, multicallRetry, prices = {}, tokenList = {}) => {
|
|
43920
|
+
if (!hasYearnVaults(chainId)) return {};
|
|
43921
|
+
const items = await fetchYearnApiVaults(chainId);
|
|
43922
|
+
const out = {};
|
|
43638
43923
|
for (const item of items) {
|
|
43639
43924
|
const parsed = parseVault8(item, chainId, prices, tokenList);
|
|
43640
43925
|
if (parsed) out[parsed.address] = parsed;
|
|
43641
43926
|
}
|
|
43927
|
+
try {
|
|
43928
|
+
await attachYearnLiquidity(chainId, multicallRetry, out);
|
|
43929
|
+
} catch {
|
|
43930
|
+
}
|
|
43642
43931
|
return out;
|
|
43643
43932
|
};
|
|
43644
43933
|
|
|
@@ -43925,6 +44214,7 @@ var stampVaultClassification = (data, chainId) => {
|
|
|
43925
44214
|
stampBag(data.lst, "lst");
|
|
43926
44215
|
stampBag(data.savings, "savings");
|
|
43927
44216
|
stampBag(data.lagoon, "lagoon");
|
|
44217
|
+
stampBag(data.yearn, "yearn");
|
|
43928
44218
|
};
|
|
43929
44219
|
|
|
43930
44220
|
// src/vaults/gmx/registry.ts
|
|
@@ -44187,10 +44477,13 @@ var GmxDataStoreAbi = [
|
|
|
44187
44477
|
outputs: [{ name: "", type: "bytes32[]" }]
|
|
44188
44478
|
}
|
|
44189
44479
|
];
|
|
44190
|
-
var priceProps = {
|
|
44191
|
-
|
|
44192
|
-
|
|
44193
|
-
|
|
44480
|
+
var priceProps = {
|
|
44481
|
+
type: "tuple",
|
|
44482
|
+
components: [
|
|
44483
|
+
{ name: "min", type: "uint256" },
|
|
44484
|
+
{ name: "max", type: "uint256" }
|
|
44485
|
+
]
|
|
44486
|
+
};
|
|
44194
44487
|
var GmxPricingAbi = [
|
|
44195
44488
|
{
|
|
44196
44489
|
name: "getMarketTokenPrice",
|
|
@@ -44303,6 +44596,15 @@ var GmxErc20BalanceAbi = [
|
|
|
44303
44596
|
outputs: [{ name: "", type: "uint256" }]
|
|
44304
44597
|
}
|
|
44305
44598
|
];
|
|
44599
|
+
var GmxGlvTokenBalancesAbi = [
|
|
44600
|
+
{
|
|
44601
|
+
name: "tokenBalances",
|
|
44602
|
+
type: "function",
|
|
44603
|
+
stateMutability: "view",
|
|
44604
|
+
inputs: [{ name: "token", type: "address" }],
|
|
44605
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
44606
|
+
}
|
|
44607
|
+
];
|
|
44306
44608
|
|
|
44307
44609
|
// src/vaults/gmx/contracts.ts
|
|
44308
44610
|
var GMX_READ_CONTRACTS = {
|
|
@@ -44331,7 +44633,9 @@ var accountListKey = (listConstant, account) => keccak256(
|
|
|
44331
44633
|
);
|
|
44332
44634
|
var accountDepositListKey = (account) => accountListKey(ACCOUNT_DEPOSIT_LIST, account);
|
|
44333
44635
|
var accountWithdrawalListKey = (account) => accountListKey(ACCOUNT_WITHDRAWAL_LIST, account);
|
|
44334
|
-
var MAX_PNL_FACTOR_FOR_TRADERS = hashString(
|
|
44636
|
+
var MAX_PNL_FACTOR_FOR_TRADERS = hashString(
|
|
44637
|
+
"MAX_PNL_FACTOR_FOR_TRADERS"
|
|
44638
|
+
);
|
|
44335
44639
|
var GMX_GAS_KEYS = {
|
|
44336
44640
|
estimatedGasFeeBaseAmount: hashString("EXECUTION_GAS_FEE_BASE_AMOUNT_V2_1"),
|
|
44337
44641
|
estimatedGasFeeMultiplierFactor: hashString(
|
|
@@ -44343,9 +44647,50 @@ var GMX_GAS_KEYS = {
|
|
|
44343
44647
|
glvWithdrawalGasLimit: hashString("GLV_WITHDRAWAL_GAS_LIMIT"),
|
|
44344
44648
|
glvPerMarketGasLimit: hashString("GLV_PER_MARKET_GAS_LIMIT")
|
|
44345
44649
|
};
|
|
44650
|
+
var MAX_POOL_AMOUNT = hashString("MAX_POOL_AMOUNT");
|
|
44651
|
+
var MAX_POOL_USD_FOR_DEPOSIT = hashString("MAX_POOL_USD_FOR_DEPOSIT");
|
|
44652
|
+
var GLV_MAX_MARKET_TOKEN_BALANCE_USD = hashString(
|
|
44653
|
+
"GLV_MAX_MARKET_TOKEN_BALANCE_USD"
|
|
44654
|
+
);
|
|
44655
|
+
var GLV_MAX_MARKET_TOKEN_BALANCE_AMOUNT = hashString(
|
|
44656
|
+
"GLV_MAX_MARKET_TOKEN_BALANCE_AMOUNT"
|
|
44657
|
+
);
|
|
44658
|
+
var marketTokenKey = (base, market, token) => keccak256(
|
|
44659
|
+
encodeAbiParameters(
|
|
44660
|
+
[{ type: "bytes32" }, { type: "address" }, { type: "address" }],
|
|
44661
|
+
[base, market, token]
|
|
44662
|
+
)
|
|
44663
|
+
);
|
|
44664
|
+
var maxPoolAmountKey = (market, token) => marketTokenKey(MAX_POOL_AMOUNT, market, token);
|
|
44665
|
+
var maxPoolUsdForDepositKey = (market, token) => marketTokenKey(MAX_POOL_USD_FOR_DEPOSIT, market, token);
|
|
44666
|
+
var glvMaxMarketTokenBalanceUsdKey = (glv, market) => marketTokenKey(GLV_MAX_MARKET_TOKEN_BALANCE_USD, glv, market);
|
|
44667
|
+
var glvMaxMarketTokenBalanceAmountKey = (glv, market) => marketTokenKey(GLV_MAX_MARKET_TOKEN_BALANCE_AMOUNT, glv, market);
|
|
44668
|
+
var OPEN_INTEREST = hashString("OPEN_INTEREST");
|
|
44669
|
+
var OPEN_INTEREST_IN_TOKENS = hashString("OPEN_INTEREST_IN_TOKENS");
|
|
44670
|
+
var RESERVE_FACTOR = hashString("RESERVE_FACTOR");
|
|
44671
|
+
var marketCollateralKey = (base, market, collateralToken, isLong) => keccak256(
|
|
44672
|
+
encodeAbiParameters(
|
|
44673
|
+
[
|
|
44674
|
+
{ type: "bytes32" },
|
|
44675
|
+
{ type: "address" },
|
|
44676
|
+
{ type: "address" },
|
|
44677
|
+
{ type: "bool" }
|
|
44678
|
+
],
|
|
44679
|
+
[base, market, collateralToken, isLong]
|
|
44680
|
+
)
|
|
44681
|
+
);
|
|
44682
|
+
var openInterestKey = (market, collateralToken, isLong) => marketCollateralKey(OPEN_INTEREST, market, collateralToken, isLong);
|
|
44683
|
+
var openInterestInTokensKey = (market, collateralToken, isLong) => marketCollateralKey(OPEN_INTEREST_IN_TOKENS, market, collateralToken, isLong);
|
|
44684
|
+
var reserveFactorKey = (market, isLong) => keccak256(
|
|
44685
|
+
encodeAbiParameters(
|
|
44686
|
+
[{ type: "bytes32" }, { type: "address" }, { type: "bool" }],
|
|
44687
|
+
[RESERVE_FACTOR, market, isLong]
|
|
44688
|
+
)
|
|
44689
|
+
);
|
|
44346
44690
|
|
|
44347
44691
|
// src/vaults/gmx/pricing.ts
|
|
44348
44692
|
var USD_1E30 = 1e30;
|
|
44693
|
+
var USD_1E30N = 10n ** 30n;
|
|
44349
44694
|
var GLV_NOMINAL_MARKET_COUNT = 20n;
|
|
44350
44695
|
var toUsd = (v) => typeof v === "bigint" ? Number(v) / USD_1E30 : 0;
|
|
44351
44696
|
var fetchGmxTickerPrices = async (chainId, apiUrlOverride) => {
|
|
@@ -44395,36 +44740,124 @@ var priceGmMarkets = async (chainId, multicallRetry, markets, prices) => {
|
|
|
44395
44740
|
false
|
|
44396
44741
|
]
|
|
44397
44742
|
}));
|
|
44398
|
-
|
|
44399
|
-
|
|
44400
|
-
|
|
44743
|
+
const SLOTS = 10;
|
|
44744
|
+
const dsCalls = priced.flatMap((m) => {
|
|
44745
|
+
const market = m.marketToken;
|
|
44746
|
+
const long = m.longToken;
|
|
44747
|
+
const short = m.shortToken;
|
|
44748
|
+
const get = (key) => ({
|
|
44749
|
+
address: c.dataStore,
|
|
44750
|
+
name: "getUint",
|
|
44751
|
+
params: [key]
|
|
44752
|
+
});
|
|
44753
|
+
return [
|
|
44754
|
+
get(maxPoolAmountKey(market, long)),
|
|
44755
|
+
get(maxPoolAmountKey(market, short)),
|
|
44756
|
+
get(maxPoolUsdForDepositKey(market, long)),
|
|
44757
|
+
get(maxPoolUsdForDepositKey(market, short)),
|
|
44758
|
+
get(openInterestInTokensKey(market, long, true)),
|
|
44759
|
+
get(openInterestInTokensKey(market, short, true)),
|
|
44760
|
+
get(openInterestKey(market, long, false)),
|
|
44761
|
+
get(openInterestKey(market, short, false)),
|
|
44762
|
+
get(reserveFactorKey(market, true)),
|
|
44763
|
+
get(reserveFactorKey(market, false))
|
|
44764
|
+
];
|
|
44765
|
+
});
|
|
44766
|
+
const [res, dsRes] = await Promise.all([
|
|
44767
|
+
multicallRetry({
|
|
44401
44768
|
chain: chainId,
|
|
44402
44769
|
calls,
|
|
44403
44770
|
abi: GmxPricingAbi,
|
|
44404
44771
|
maxRetries: 3,
|
|
44405
44772
|
allowFailure: true
|
|
44406
|
-
})
|
|
44407
|
-
|
|
44408
|
-
|
|
44409
|
-
|
|
44773
|
+
}).catch(() => null),
|
|
44774
|
+
multicallRetry({
|
|
44775
|
+
chain: chainId,
|
|
44776
|
+
calls: dsCalls,
|
|
44777
|
+
abi: GmxDataStoreUintAbi,
|
|
44778
|
+
maxRetries: 3,
|
|
44779
|
+
allowFailure: true
|
|
44780
|
+
}).catch(() => null)
|
|
44781
|
+
]);
|
|
44782
|
+
if (!Array.isArray(res)) return out;
|
|
44410
44783
|
priced.forEach((m, i) => {
|
|
44411
44784
|
const r = res[i];
|
|
44412
44785
|
if (!Array.isArray(r)) return;
|
|
44786
|
+
const info = r[1];
|
|
44413
44787
|
const tokenPrice = r[0];
|
|
44414
|
-
const poolValue =
|
|
44788
|
+
const poolValue = info?.poolValue;
|
|
44415
44789
|
if (typeof tokenPrice !== "bigint") return;
|
|
44416
|
-
|
|
44790
|
+
const value = {
|
|
44417
44791
|
priceUsd: toUsd(tokenPrice),
|
|
44418
44792
|
tvlUsd: toUsd(poolValue)
|
|
44419
|
-
}
|
|
44793
|
+
};
|
|
44794
|
+
const longMax = price(prices, m.longToken)?.max;
|
|
44795
|
+
const shortMax = price(prices, m.shortToken)?.max;
|
|
44796
|
+
const indexMax = price(prices, m.indexToken)?.max;
|
|
44797
|
+
if (Array.isArray(dsRes) && longMax != null && shortMax != null) {
|
|
44798
|
+
const base = i * SLOTS;
|
|
44799
|
+
const big = (j) => typeof dsRes[base + j] === "bigint" ? dsRes[base + j] : 0n;
|
|
44800
|
+
const cap = computeDepositCapacityUsd(
|
|
44801
|
+
[info?.longTokenAmount, longMax, big(0), big(2)],
|
|
44802
|
+
[info?.shortTokenAmount, shortMax, big(1), big(3)]
|
|
44803
|
+
);
|
|
44804
|
+
if (cap != null) value.depositCapacityUsd = cap;
|
|
44805
|
+
if (indexMax != null) {
|
|
44806
|
+
const divisor = m.longToken.toLowerCase() === m.shortToken.toLowerCase() ? 2n : 1n;
|
|
44807
|
+
const reservedUsdLong = (big(4) + big(5)) / divisor * indexMax;
|
|
44808
|
+
const reservedUsdShort = (big(6) + big(7)) / divisor;
|
|
44809
|
+
const liq = computeLiquidityUsd(
|
|
44810
|
+
info?.longTokenUsd,
|
|
44811
|
+
info?.shortTokenUsd,
|
|
44812
|
+
reservedUsdLong,
|
|
44813
|
+
reservedUsdShort,
|
|
44814
|
+
big(8),
|
|
44815
|
+
big(9)
|
|
44816
|
+
);
|
|
44817
|
+
if (liq != null)
|
|
44818
|
+
value.liquidityUsd = Math.max(0, Math.min(liq, value.tvlUsd));
|
|
44819
|
+
}
|
|
44820
|
+
}
|
|
44821
|
+
out.set(m.marketToken.toLowerCase(), value);
|
|
44420
44822
|
});
|
|
44421
44823
|
return out;
|
|
44422
44824
|
};
|
|
44825
|
+
var computeLiquidityUsd = (poolUsdLong, poolUsdShort, reservedUsdLong, reservedUsdShort, reserveFactorLong, reserveFactorShort) => {
|
|
44826
|
+
if (typeof poolUsdLong !== "bigint" || typeof poolUsdShort !== "bigint")
|
|
44827
|
+
return void 0;
|
|
44828
|
+
const side = (pool, reserved, rf) => {
|
|
44829
|
+
const floor = rf > 0n ? reserved * USD_1E30N / rf : 0n;
|
|
44830
|
+
const avail = pool - floor;
|
|
44831
|
+
return avail > 0n ? avail : 0n;
|
|
44832
|
+
};
|
|
44833
|
+
const total = side(poolUsdLong, reservedUsdLong, reserveFactorLong) + side(poolUsdShort, reservedUsdShort, reserveFactorShort);
|
|
44834
|
+
return toUsd(total);
|
|
44835
|
+
};
|
|
44836
|
+
var computeDepositCapacityUsd = (long, short) => {
|
|
44837
|
+
const INF = -1n;
|
|
44838
|
+
const side = ([poolAmount, priceMax, maxAmount, maxUsd]) => {
|
|
44839
|
+
if (typeof poolAmount !== "bigint") return void 0;
|
|
44840
|
+
const poolUsd = poolAmount * priceMax;
|
|
44841
|
+
const amountRoom = maxAmount > 0n ? (maxAmount > poolAmount ? maxAmount - poolAmount : 0n) * priceMax : INF;
|
|
44842
|
+
const usdRoom = maxUsd > 0n ? maxUsd > poolUsd ? maxUsd - poolUsd : 0n : INF;
|
|
44843
|
+
if (amountRoom === INF && usdRoom === INF) return void 0;
|
|
44844
|
+
if (amountRoom === INF) return usdRoom;
|
|
44845
|
+
if (usdRoom === INF) return amountRoom;
|
|
44846
|
+
return amountRoom < usdRoom ? amountRoom : usdRoom;
|
|
44847
|
+
};
|
|
44848
|
+
const l = side(long);
|
|
44849
|
+
const s = side(short);
|
|
44850
|
+
if (l == null && s == null) return void 0;
|
|
44851
|
+
return toUsd((l ?? 0n) + (s ?? 0n));
|
|
44852
|
+
};
|
|
44423
44853
|
var priceGlvVaults = async (chainId, multicallRetry, glvTokens, prices, marketIndexToken) => {
|
|
44424
44854
|
const values = /* @__PURE__ */ new Map();
|
|
44855
|
+
const glvMarkets = /* @__PURE__ */ new Map();
|
|
44856
|
+
const glvCaps = /* @__PURE__ */ new Map();
|
|
44425
44857
|
let maxMarketCount = 0;
|
|
44426
44858
|
const c = getGmxReadContracts(chainId);
|
|
44427
|
-
if (!c || glvTokens.length === 0)
|
|
44859
|
+
if (!c || glvTokens.length === 0)
|
|
44860
|
+
return { values, maxMarketCount, glvMarkets, glvCaps };
|
|
44428
44861
|
let infos;
|
|
44429
44862
|
try {
|
|
44430
44863
|
infos = await multicallRetry({
|
|
@@ -44439,7 +44872,7 @@ var priceGlvVaults = async (chainId, multicallRetry, glvTokens, prices, marketIn
|
|
|
44439
44872
|
allowFailure: true
|
|
44440
44873
|
});
|
|
44441
44874
|
} catch {
|
|
44442
|
-
return { values, maxMarketCount };
|
|
44875
|
+
return { values, maxMarketCount, glvMarkets, glvCaps };
|
|
44443
44876
|
}
|
|
44444
44877
|
const calls = [];
|
|
44445
44878
|
const priceable = [];
|
|
@@ -44450,6 +44883,10 @@ var priceGlvVaults = async (chainId, multicallRetry, glvTokens, prices, marketIn
|
|
|
44450
44883
|
const markets = Array.isArray(info?.markets) ? info.markets : [];
|
|
44451
44884
|
if (!long || !short || markets.length === 0) return;
|
|
44452
44885
|
maxMarketCount = Math.max(maxMarketCount, markets.length);
|
|
44886
|
+
glvMarkets.set(
|
|
44887
|
+
glv.toLowerCase(),
|
|
44888
|
+
markets.map((m) => m.toLowerCase())
|
|
44889
|
+
);
|
|
44453
44890
|
const lp = price(prices, long);
|
|
44454
44891
|
const sp = price(prices, short);
|
|
44455
44892
|
if (!lp || !sp) return;
|
|
@@ -44472,19 +44909,62 @@ var priceGlvVaults = async (chainId, multicallRetry, glvTokens, prices, marketIn
|
|
|
44472
44909
|
});
|
|
44473
44910
|
priceable.push(glv);
|
|
44474
44911
|
});
|
|
44475
|
-
if (calls.length === 0) return { values, maxMarketCount };
|
|
44476
|
-
|
|
44477
|
-
|
|
44478
|
-
|
|
44912
|
+
if (calls.length === 0) return { values, maxMarketCount, glvMarkets, glvCaps };
|
|
44913
|
+
const pairs = [];
|
|
44914
|
+
for (const [glv, markets] of glvMarkets)
|
|
44915
|
+
for (const market of markets) pairs.push({ glv, market });
|
|
44916
|
+
const [res, capRes, balRes] = await Promise.all([
|
|
44917
|
+
multicallRetry({
|
|
44479
44918
|
chain: chainId,
|
|
44480
44919
|
calls,
|
|
44481
44920
|
abi: GmxGlvPricingAbi,
|
|
44482
44921
|
maxRetries: 3,
|
|
44483
44922
|
allowFailure: true
|
|
44484
|
-
})
|
|
44485
|
-
|
|
44486
|
-
|
|
44487
|
-
|
|
44923
|
+
}).catch(() => null),
|
|
44924
|
+
// Two caps per pair, interleaved: [maxBalUsd, maxBalAmount].
|
|
44925
|
+
pairs.length ? multicallRetry({
|
|
44926
|
+
chain: chainId,
|
|
44927
|
+
calls: pairs.flatMap(({ glv, market }) => [
|
|
44928
|
+
{
|
|
44929
|
+
address: c.dataStore,
|
|
44930
|
+
name: "getUint",
|
|
44931
|
+
params: [
|
|
44932
|
+
glvMaxMarketTokenBalanceUsdKey(
|
|
44933
|
+
glv,
|
|
44934
|
+
market
|
|
44935
|
+
)
|
|
44936
|
+
]
|
|
44937
|
+
},
|
|
44938
|
+
{
|
|
44939
|
+
address: c.dataStore,
|
|
44940
|
+
name: "getUint",
|
|
44941
|
+
params: [
|
|
44942
|
+
glvMaxMarketTokenBalanceAmountKey(
|
|
44943
|
+
glv,
|
|
44944
|
+
market
|
|
44945
|
+
)
|
|
44946
|
+
]
|
|
44947
|
+
}
|
|
44948
|
+
]),
|
|
44949
|
+
abi: GmxDataStoreUintAbi,
|
|
44950
|
+
maxRetries: 3,
|
|
44951
|
+
allowFailure: true
|
|
44952
|
+
}).catch(() => null) : Promise.resolve(null),
|
|
44953
|
+
// GLV's internally-tracked GM balance for each market (`tokenBalances`).
|
|
44954
|
+
pairs.length ? multicallRetry({
|
|
44955
|
+
chain: chainId,
|
|
44956
|
+
calls: pairs.map(({ glv, market }) => ({
|
|
44957
|
+
address: glv,
|
|
44958
|
+
name: "tokenBalances",
|
|
44959
|
+
params: [market]
|
|
44960
|
+
})),
|
|
44961
|
+
abi: GmxGlvTokenBalancesAbi,
|
|
44962
|
+
maxRetries: 3,
|
|
44963
|
+
allowFailure: true
|
|
44964
|
+
}).catch(() => null) : Promise.resolve(null)
|
|
44965
|
+
]);
|
|
44966
|
+
if (!Array.isArray(res))
|
|
44967
|
+
return { values, maxMarketCount, glvMarkets, glvCaps };
|
|
44488
44968
|
priceable.forEach((glv, i) => {
|
|
44489
44969
|
const r = res[i];
|
|
44490
44970
|
if (!Array.isArray(r) || typeof r[0] !== "bigint") return;
|
|
@@ -44493,7 +44973,15 @@ var priceGlvVaults = async (chainId, multicallRetry, glvTokens, prices, marketIn
|
|
|
44493
44973
|
tvlUsd: toUsd(r[1])
|
|
44494
44974
|
});
|
|
44495
44975
|
});
|
|
44496
|
-
|
|
44976
|
+
pairs.forEach(({ glv, market }, i) => {
|
|
44977
|
+
const maxBalUsd = Array.isArray(capRes) && typeof capRes[i * 2] === "bigint" ? capRes[i * 2] : 0n;
|
|
44978
|
+
const maxBalAmount = Array.isArray(capRes) && typeof capRes[i * 2 + 1] === "bigint" ? capRes[i * 2 + 1] : 0n;
|
|
44979
|
+
const balanceAmount = Array.isArray(balRes) && typeof balRes[i] === "bigint" ? balRes[i] : 0n;
|
|
44980
|
+
const list = glvCaps.get(glv) ?? [];
|
|
44981
|
+
list.push({ market, maxBalUsd, maxBalAmount, balanceAmount });
|
|
44982
|
+
glvCaps.set(glv, list);
|
|
44983
|
+
});
|
|
44984
|
+
return { values, maxMarketCount, glvMarkets, glvCaps };
|
|
44497
44985
|
};
|
|
44498
44986
|
var fetchGmxExecutionFees = async (chainId, multicallRetry, gasPriceWei) => {
|
|
44499
44987
|
const c = getGmxReadContracts(chainId);
|
|
@@ -44511,7 +44999,11 @@ var fetchGmxExecutionFees = async (chainId, multicallRetry, gasPriceWei) => {
|
|
|
44511
44999
|
try {
|
|
44512
45000
|
res = await multicallRetry({
|
|
44513
45001
|
chain: chainId,
|
|
44514
|
-
calls: keys.map((key) => ({
|
|
45002
|
+
calls: keys.map((key) => ({
|
|
45003
|
+
address: c.dataStore,
|
|
45004
|
+
name: "getUint",
|
|
45005
|
+
params: [key]
|
|
45006
|
+
})),
|
|
44515
45007
|
abi: GmxDataStoreUintAbi,
|
|
44516
45008
|
maxRetries: 3,
|
|
44517
45009
|
allowFailure: true
|
|
@@ -44540,7 +45032,14 @@ var fetchGmxExecutionFees = async (chainId, multicallRetry, gasPriceWei) => {
|
|
|
44540
45032
|
// src/vaults/gmx/fetchPublic.ts
|
|
44541
45033
|
var GMX_TOKEN_DECIMALS = 18;
|
|
44542
45034
|
var DEFAULT_PERIOD = "90d";
|
|
44543
|
-
var
|
|
45035
|
+
var num3 = (n) => typeof n === "number" && Number.isFinite(n) ? n : 0;
|
|
45036
|
+
var minDefined = (a, b) => a == null ? b : b == null ? a : Math.min(a, b);
|
|
45037
|
+
var glvMarketRoomUsd = (cap, priceUsd) => {
|
|
45038
|
+
const currentUsd = Number(cap.balanceAmount) / 1e18 * priceUsd;
|
|
45039
|
+
const usdRoom = cap.maxBalUsd > 0n ? Math.max(0, Number(cap.maxBalUsd) / 1e30 - currentUsd) : void 0;
|
|
45040
|
+
const amountRoom = cap.maxBalAmount > 0n ? Math.max(0, Number(cap.maxBalAmount - cap.balanceAmount) / 1e18) * priceUsd : void 0;
|
|
45041
|
+
return minDefined(usdRoom, amountRoom);
|
|
45042
|
+
};
|
|
44544
45043
|
var denominationFor = (longSymbol, shortSymbol) => isStablecoinSymbol(longSymbol) && isStablecoinSymbol(shortSymbol) ? "stable" : "volatile";
|
|
44545
45044
|
var fetchGmxVaults = async (chainId, multicallRetry, options) => {
|
|
44546
45045
|
if (!options?.apiUrl && !getGmxApiHost(chainId)) return {};
|
|
@@ -44567,9 +45066,9 @@ var fetchGmxVaults = async (chainId, multicallRetry, options) => {
|
|
|
44567
45066
|
indexToken: indexToken ? indexToken.toLowerCase() : void 0,
|
|
44568
45067
|
longSymbol,
|
|
44569
45068
|
shortSymbol,
|
|
44570
|
-
apy:
|
|
44571
|
-
baseApy:
|
|
44572
|
-
bonusApr:
|
|
45069
|
+
apy: num3(entry?.apy),
|
|
45070
|
+
baseApy: num3(entry?.baseApy),
|
|
45071
|
+
bonusApr: num3(entry?.bonusApr),
|
|
44573
45072
|
yieldProfile: "volatile",
|
|
44574
45073
|
denomination: denominationFor(longSymbol, shortSymbol)
|
|
44575
45074
|
};
|
|
@@ -44633,14 +45132,42 @@ var fetchGmxVaults = async (chainId, multicallRetry, options) => {
|
|
|
44633
45132
|
if (e) {
|
|
44634
45133
|
e.priceUsd = v.priceUsd;
|
|
44635
45134
|
e.tvlUsd = v.tvlUsd;
|
|
45135
|
+
e.liquidityUsd = v.liquidityUsd;
|
|
45136
|
+
e.depositCapacityUsd = v.depositCapacityUsd;
|
|
44636
45137
|
}
|
|
44637
45138
|
}
|
|
44638
45139
|
for (const [addr, v] of glv.values) {
|
|
44639
45140
|
const e = out[addr];
|
|
44640
|
-
if (e)
|
|
44641
|
-
|
|
44642
|
-
|
|
45141
|
+
if (!e) continue;
|
|
45142
|
+
e.priceUsd = v.priceUsd;
|
|
45143
|
+
e.tvlUsd = v.tvlUsd;
|
|
45144
|
+
const markets2 = glv.glvMarkets.get(addr) ?? [];
|
|
45145
|
+
let liqSum = 0;
|
|
45146
|
+
let tvlSum = 0;
|
|
45147
|
+
for (const m of markets2) {
|
|
45148
|
+
const gv = gmValues.get(m);
|
|
45149
|
+
if (gv?.liquidityUsd != null && gv.tvlUsd != null) {
|
|
45150
|
+
liqSum += gv.liquidityUsd;
|
|
45151
|
+
tvlSum += gv.tvlUsd;
|
|
45152
|
+
}
|
|
44643
45153
|
}
|
|
45154
|
+
if (tvlSum > 0 && v.tvlUsd != null)
|
|
45155
|
+
e.liquidityUsd = v.tvlUsd * (liqSum / tvlSum);
|
|
45156
|
+
const caps = glv.glvCaps.get(addr) ?? [];
|
|
45157
|
+
let capacity = 0;
|
|
45158
|
+
let known = false;
|
|
45159
|
+
for (const cap of caps) {
|
|
45160
|
+
const gv = gmValues.get(cap.market);
|
|
45161
|
+
if (!gv) continue;
|
|
45162
|
+
const marketRoom = gv.depositCapacityUsd;
|
|
45163
|
+
const glvRoom = glvMarketRoomUsd(cap, gv.priceUsd);
|
|
45164
|
+
const room = minDefined(marketRoom, glvRoom);
|
|
45165
|
+
if (room != null) {
|
|
45166
|
+
capacity += room;
|
|
45167
|
+
known = true;
|
|
45168
|
+
}
|
|
45169
|
+
}
|
|
45170
|
+
if (known) e.depositCapacityUsd = capacity;
|
|
44644
45171
|
}
|
|
44645
45172
|
}
|
|
44646
45173
|
} catch {
|
|
@@ -44961,6 +45488,7 @@ function buildVaultLookup(data) {
|
|
|
44961
45488
|
addEntries(data.lst, "lst");
|
|
44962
45489
|
addEntries(data.savings, "savings");
|
|
44963
45490
|
addEntries(data.lagoon, "lagoon");
|
|
45491
|
+
addEntries(data.yearn, "yearn");
|
|
44964
45492
|
return map;
|
|
44965
45493
|
}
|
|
44966
45494
|
var warn4 = (...args) => {
|
|
@@ -45082,6 +45610,18 @@ var getVaultPublicDataAll = async (chainId, providers, multicallRetry, prices =
|
|
|
45082
45610
|
})
|
|
45083
45611
|
);
|
|
45084
45612
|
}
|
|
45613
|
+
if (requested.has("yearn")) {
|
|
45614
|
+
tasks.push(
|
|
45615
|
+
fetchYearnVaults(chainId, multicallRetry, prices, tokenList).then((res) => {
|
|
45616
|
+
out.yearn = res;
|
|
45617
|
+
}).catch((e) => {
|
|
45618
|
+
warn4(
|
|
45619
|
+
`[vaults] yearn fetch failed for chain ${chainId}:`,
|
|
45620
|
+
e?.message ?? e
|
|
45621
|
+
);
|
|
45622
|
+
})
|
|
45623
|
+
);
|
|
45624
|
+
}
|
|
45085
45625
|
if (requested.has("hypercore") && chainId === HYPERCORE_PROVIDER_CHAIN) {
|
|
45086
45626
|
tasks.push(
|
|
45087
45627
|
fetchHypercoreVaults().then((res) => {
|
|
@@ -45662,6 +46202,6 @@ async function fetchTokenBalances(chainId, account, tokens, options = {}) {
|
|
|
45662
46202
|
return parseTokenBalanceResult(rawResult, prepared.query);
|
|
45663
46203
|
}
|
|
45664
46204
|
|
|
45665
|
-
export { EMPTY_BALANCE, GMX_API_HOSTS, GMX_READ_CONTRACTS, GMX_SUPPORTED_CHAINS, HYPERCORE_VAULT_REGISTRY, IDLE_MARKET_ID, INTERFACE_IDS, LAGOON_API_URL, LAGOON_CHAIN_IDS, MORPHO_LENS, MaxParamThresholds, STABLECOIN_SYMBOLS, VAULT_SHARE_PRICE_PROBE, VOLATILE_VAULT_OVERRIDES, accountDepositListKey, accountWithdrawalListKey, appendSnapshot, applyPositionDelta, attachPricesToFlashLiquidity, buildFluidFTokensCall, buildLoopResult, buildMorphoTypeCall, buildMorphoTypeUserCallWithLens, buildPortfolioTotals, buildSumerAccumulators, buildSummaries, buildVaultLookup, calculateLeverage, calculateNetApr, calculateOverallNetApr, calculateWeightedAverage, classifyVault, computeBorrowDelta2 as computeBorrowDelta, computeCloseTradeDeltas, computeCollateralSwapDeltas, computeDebtSwapDeltas, computeDepositDelta2 as computeDepositDelta, computeEModeAnalysis, computeOpenTradeDeltas, computePostTradeMetrics, computeRepayDelta2 as computeRepayDelta, computeSumerBorrowDelta, computeSumerDepositDelta, computeSumerRepayDelta, computeSumerWaterfall, computeSumerWithdrawDelta, computeVaultApr, computeWithdrawDelta2 as computeWithdrawDelta, computeZapTradeDeltas, convertLenderUserDataResult, createMarketUid, createMulticallRpcCall, createRawRpcCalls, decodeListaMarkets, decodeMarkets, decodePackedListaUserDataset, decodePackedMorphoUserDataset, detectInterfaceKinds, encodeBalanceFetcherCalldata, fetchDolomiteAccountNumbers, fetchEulerEarnVaults, fetchEulerEarnVaultsFromSubgraph, fetchEulerSubAccountIndexes, fetchFlashLiquidityForChain, fetchFluidFTokens, fetchGeneralYields, fetchGeneralYieldsByMarketUid, fetchGmxExecutionFees, fetchGmxTickerPrices, fetchGmxVaults, fetchHypercoreVaults, fetchLagoonApiVaults, fetchLagoonVaults, fetchListaVaultsFromChain, fetchMorphoUserBalances, fetchMorphoUserPositionMarkets, fetchMorphoVaults, fetchMorphoVaultsFromApi, fetchMorphoVaultsFromChain,
|
|
46205
|
+
export { EMPTY_BALANCE, GMX_API_HOSTS, GMX_READ_CONTRACTS, GMX_SUPPORTED_CHAINS, HYPERCORE_VAULT_REGISTRY, IDLE_MARKET_ID, INTERFACE_IDS, LAGOON_API_URL, LAGOON_CHAIN_IDS, MORPHO_LENS, MaxParamThresholds, STABLECOIN_SYMBOLS, VAULT_SHARE_PRICE_PROBE, VOLATILE_VAULT_OVERRIDES, YEARN_CHAIN_IDS, YEARN_YDAEMON_BASE, accountDepositListKey, accountWithdrawalListKey, appendSnapshot, applyPositionDelta, attachPricesToFlashLiquidity, buildFluidFTokensCall, buildLoopResult, buildMorphoTypeCall, buildMorphoTypeUserCallWithLens, buildPortfolioTotals, buildSumerAccumulators, buildSummaries, buildVaultLookup, calculateLeverage, calculateNetApr, calculateOverallNetApr, calculateWeightedAverage, classifyVault, computeBorrowDelta2 as computeBorrowDelta, computeCloseTradeDeltas, computeCollateralSwapDeltas, computeDebtSwapDeltas, computeDepositDelta2 as computeDepositDelta, computeEModeAnalysis, computeOpenTradeDeltas, computePostTradeMetrics, computeRepayDelta2 as computeRepayDelta, computeSumerBorrowDelta, computeSumerDepositDelta, computeSumerRepayDelta, computeSumerWaterfall, computeSumerWithdrawDelta, computeVaultApr, computeWithdrawDelta2 as computeWithdrawDelta, computeZapTradeDeltas, convertLenderUserDataResult, createMarketUid, createMulticallRpcCall, createRawRpcCalls, decodeListaMarkets, decodeMarkets, decodePackedListaUserDataset, decodePackedMorphoUserDataset, detectInterfaceKinds, encodeBalanceFetcherCalldata, fetchDolomiteAccountNumbers, fetchEulerEarnVaults, fetchEulerEarnVaultsFromSubgraph, fetchEulerSubAccountIndexes, fetchFlashLiquidityForChain, fetchFluidFTokens, fetchGeneralYields, fetchGeneralYieldsByMarketUid, fetchGmxExecutionFees, fetchGmxTickerPrices, fetchGmxVaults, fetchHypercoreVaults, fetchLagoonApiVaults, fetchLagoonVaults, fetchListaVaultsFromChain, fetchMorphoUserBalances, fetchMorphoUserPositionMarkets, fetchMorphoVaults, fetchMorphoVaultsFromApi, fetchMorphoVaultsFromChain, fetchOraclePrices, fetchPendlePrices, fetchSiloVaults, fetchTokenBalances, fetchTokenMetadata, fetchYearnApiVaults, fetchYearnVaults, filterActiveLenders, filterLendersByProtocol, fuseLenderData, generateLendingPools, getAavesForChain, getAssetConfig, getBalanceForMarketUid, getBorrowCapacity, getFluidFTokensConverter, getGmxApiHost, getGmxReadContracts, getGmxUserPositions, getHealthFactor, getHypercoreUserPositions, getHypercoreVaultRegistry, getLenderAssets, getLenderPublicData, getLenderPublicDataAll, getLenderPublicDataViaApi, getLenderUserDataMulti, getLenderUserDataResult, getLendersForChain, getLstWithdrawalRegistry, getLstWithdrawalRequests, getMaxAmountClose, getMaxAmountCollateralSwap, getMaxAmountDebtSwap, getMaxAmountOpen, getMergedUserData, getMorphoTypeMarketConverter, getResolvedDolomiteAccountNumbers, getSubAccountAddress, getSubAccountIndex, getVaultPublicDataAll, getVaultWithdrawalRequests, hasEulerEarnVaultSubgraph, hasLagoonVaults, hasMorphoPositionIndex, hasMorphoUserApi, hasMorphoUserSubgraph, hasYearnVaults, isStablecoinSymbol, isYearnV3, keysFromMaps, multicall3Abi, nanTo, needsLenderApproval, needsTokenApproval, noOpResult, normalizeToBytes, parseBalanceFetcherResult, parseMergedResult, parseMulticallRpcResponses, parseRawRpcBatchResponses, parseRawRpcResponses, parseTokenBalanceResult, positivePart2 as positivePart, prepareLenderUserDataRpcCalls, prepareMergedMulticallParams, prepareMergedRpcCalls, prepareMulticallInputs, prepareTokenBalanceRpcCalls, priceGlvVaults, priceGmMarkets, readVaultSharePrices, selectAssetGroupPrices, stampVaultClassification, unflattenLenderData };
|
|
45666
46206
|
//# sourceMappingURL=index.js.map
|
|
45667
46207
|
//# sourceMappingURL=index.js.map
|