@1delta/margin-fetcher 0.0.273 → 0.0.275
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 +895 -202
- package/dist/index.js.map +1 -1
- package/dist/vaults/assetDecimals.d.ts +14 -0
- package/dist/vaults/assetDecimals.d.ts.map +1 -0
- package/dist/vaults/classification.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/fluid/fetchPublic.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/lookup.d.ts.map +1 -1
- package/dist/vaults/lst/abis/etherfi.d.ts +14 -1
- package/dist/vaults/lst/abis/etherfi.d.ts.map +1 -1
- package/dist/vaults/lst/fetchPublic.d.ts.map +1 -1
- package/dist/vaults/lst/readers/etherfi.d.ts +8 -6
- package/dist/vaults/lst/readers/etherfi.d.ts.map +1 -1
- package/dist/vaults/lst/readers/shared.d.ts +20 -0
- package/dist/vaults/lst/readers/shared.d.ts.map +1 -1
- package/dist/vaults/lst/types.d.ts +13 -7
- package/dist/vaults/lst/types.d.ts.map +1 -1
- package/dist/vaults/lst/withdrawals/registry.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 +4 -4
- package/dist/vaults/morpho/fetchFromSubgraph.d.ts +0 -12
- package/dist/vaults/morpho/fetchFromSubgraph.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -35740,6 +35740,32 @@ function parseFTokens(fTokens, chainId, prices, tokenList) {
|
|
|
35740
35740
|
}
|
|
35741
35741
|
return out;
|
|
35742
35742
|
}
|
|
35743
|
+
|
|
35744
|
+
// src/vaults/assetDecimals.ts
|
|
35745
|
+
var ERC20_DECIMALS_ABI = parseAbi([
|
|
35746
|
+
"function decimals() view returns (uint8)"
|
|
35747
|
+
]);
|
|
35748
|
+
async function fetchAssetDecimals(chainId, underlyings, multicallRetry) {
|
|
35749
|
+
const map = /* @__PURE__ */ new Map();
|
|
35750
|
+
if (underlyings.length === 0) return map;
|
|
35751
|
+
const raw = await multicallRetry({
|
|
35752
|
+
chain: chainId,
|
|
35753
|
+
calls: underlyings.map((address) => ({
|
|
35754
|
+
address,
|
|
35755
|
+
name: "decimals",
|
|
35756
|
+
params: []
|
|
35757
|
+
})),
|
|
35758
|
+
abi: underlyings.map(() => ERC20_DECIMALS_ABI),
|
|
35759
|
+
allowFailure: true
|
|
35760
|
+
});
|
|
35761
|
+
underlyings.forEach((address, i) => {
|
|
35762
|
+
const d = Number(raw[i]);
|
|
35763
|
+
if (Number.isFinite(d) && d > 0 && d <= 36) map.set(address, d);
|
|
35764
|
+
});
|
|
35765
|
+
return map;
|
|
35766
|
+
}
|
|
35767
|
+
|
|
35768
|
+
// src/vaults/fluid/fetchPublic.ts
|
|
35743
35769
|
var fetchFluidFTokens = async (chainId, multicallRetry, prices = {}, tokenList = {}) => {
|
|
35744
35770
|
const calls = buildFluidFTokensCall(chainId);
|
|
35745
35771
|
if (calls.length === 0) return {};
|
|
@@ -35750,6 +35776,25 @@ var fetchFluidFTokens = async (chainId, multicallRetry, prices = {}, tokenList =
|
|
|
35750
35776
|
});
|
|
35751
35777
|
const [converter] = getFluidFTokensConverter(chainId, prices, tokenList);
|
|
35752
35778
|
const fTokens = converter(raw) ?? {};
|
|
35779
|
+
try {
|
|
35780
|
+
const underlyings = Object.values(fTokens).map((f) => f.underlying).filter((a) => !!a && a !== zeroAddress);
|
|
35781
|
+
const assetDec = await fetchAssetDecimals(
|
|
35782
|
+
chainId,
|
|
35783
|
+
[...new Set(underlyings)],
|
|
35784
|
+
multicallRetry
|
|
35785
|
+
);
|
|
35786
|
+
for (const f of Object.values(fTokens)) {
|
|
35787
|
+
const dec = assetDec.get(f.underlying);
|
|
35788
|
+
if (dec == null || dec === f.decimals) continue;
|
|
35789
|
+
const price2 = f.priceUsd ?? 0;
|
|
35790
|
+
f.decimals = dec;
|
|
35791
|
+
f.totalAssetsFormatted = Number(parseRawAmount(f.totalAssets, dec));
|
|
35792
|
+
f.totalAssetsUsd = f.totalAssetsFormatted * price2;
|
|
35793
|
+
f.liquidityFormatted = Number(parseRawAmount(f.liquidity, dec));
|
|
35794
|
+
f.liquidityUsd = f.liquidityFormatted * price2;
|
|
35795
|
+
}
|
|
35796
|
+
} catch {
|
|
35797
|
+
}
|
|
35753
35798
|
try {
|
|
35754
35799
|
const exposuresByUnderlying = await fetchFluidExposures(
|
|
35755
35800
|
chainId,
|
|
@@ -36110,115 +36155,6 @@ async function fetchMorphoVaultsFromApi(chainId, prices = {}, tokenList = {}, ma
|
|
|
36110
36155
|
}
|
|
36111
36156
|
return out;
|
|
36112
36157
|
}
|
|
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
36158
|
var marketUidFor = (ctx, marketId) => {
|
|
36223
36159
|
if (!ctx?.underlying) return void 0;
|
|
36224
36160
|
try {
|
|
@@ -36262,15 +36198,18 @@ async function fetchVaultSupplyShares(chainId, core, entries, marketIdsByVault,
|
|
|
36262
36198
|
}
|
|
36263
36199
|
function computeVaultAllocation(vaultAddress, decimals, totalAssetsFormatted, feePercent, priceUsd, marketIds, rateMap, positionMap, tokenList, uidCtx) {
|
|
36264
36200
|
if (totalAssetsFormatted <= 0) {
|
|
36265
|
-
return { depositRate: 0, exposures: [] };
|
|
36201
|
+
return { depositRate: 0, exposures: [], liquidityFormatted: 0 };
|
|
36266
36202
|
}
|
|
36267
36203
|
if (marketIds.length === 0) {
|
|
36268
36204
|
return {
|
|
36269
36205
|
depositRate: 0,
|
|
36270
|
-
exposures: withIdleExposure([], totalAssetsFormatted, priceUsd)
|
|
36206
|
+
exposures: withIdleExposure([], totalAssetsFormatted, priceUsd),
|
|
36207
|
+
liquidityFormatted: totalAssetsFormatted
|
|
36271
36208
|
};
|
|
36272
36209
|
}
|
|
36273
36210
|
let weighted = 0;
|
|
36211
|
+
let allocated = 0;
|
|
36212
|
+
let withdrawable = 0;
|
|
36274
36213
|
const exposures = [];
|
|
36275
36214
|
for (const id of marketIds) {
|
|
36276
36215
|
const rate = rateMap.get(id);
|
|
@@ -36283,6 +36222,9 @@ function computeVaultAllocation(vaultAddress, decimals, totalAssetsFormatted, fe
|
|
|
36283
36222
|
);
|
|
36284
36223
|
if (allocAssets <= 0) continue;
|
|
36285
36224
|
weighted += allocAssets * rate.supplyApr;
|
|
36225
|
+
allocated += allocAssets;
|
|
36226
|
+
const marketLiquidity = rate.liquidity != null ? Number(parseRawAmount(rate.liquidity.toString(), decimals)) : allocAssets;
|
|
36227
|
+
withdrawable += Math.min(allocAssets, Math.max(0, marketLiquidity));
|
|
36286
36228
|
const marketUid = marketUidFor(uidCtx, id);
|
|
36287
36229
|
exposures.push({
|
|
36288
36230
|
marketId: id,
|
|
@@ -36297,10 +36239,12 @@ function computeVaultAllocation(vaultAddress, decimals, totalAssetsFormatted, fe
|
|
|
36297
36239
|
}
|
|
36298
36240
|
exposures.sort((a, b) => b.weightPct - a.weightPct);
|
|
36299
36241
|
const grossApr = weighted / totalAssetsFormatted;
|
|
36242
|
+
const idle = Math.max(0, totalAssetsFormatted - allocated);
|
|
36300
36243
|
return {
|
|
36301
36244
|
depositRate: grossApr * (1 - feePercent / 100),
|
|
36302
36245
|
// Tag uninvested deposits as an idle entry so the breakdown sums to ~100%.
|
|
36303
|
-
exposures: withIdleExposure(exposures, totalAssetsFormatted, priceUsd)
|
|
36246
|
+
exposures: withIdleExposure(exposures, totalAssetsFormatted, priceUsd),
|
|
36247
|
+
liquidityFormatted: Math.min(totalAssetsFormatted, idle + withdrawable)
|
|
36304
36248
|
};
|
|
36305
36249
|
}
|
|
36306
36250
|
|
|
@@ -36339,6 +36283,13 @@ var toStringSafe = (raw, fallback = "") => {
|
|
|
36339
36283
|
if (raw === void 0 || raw === null) return fallback;
|
|
36340
36284
|
return String(raw);
|
|
36341
36285
|
};
|
|
36286
|
+
var toRawAmount = (formatted, decimals) => {
|
|
36287
|
+
try {
|
|
36288
|
+
return parseUnits(formatted.toFixed(decimals), decimals).toString();
|
|
36289
|
+
} catch {
|
|
36290
|
+
return "0";
|
|
36291
|
+
}
|
|
36292
|
+
};
|
|
36342
36293
|
var DEFAULT_SKIP_PROTOCOLS = /* @__PURE__ */ new Set(["LISTA_DAO"]);
|
|
36343
36294
|
var collectEntries = (chainId, protocols, skip) => {
|
|
36344
36295
|
const all = morphoTypeVaults() ?? {};
|
|
@@ -36401,7 +36352,12 @@ var fetchMorphoVaultsFromChain = async (chainId, multicallRetry, prices = {}, to
|
|
|
36401
36352
|
});
|
|
36402
36353
|
const core = morphoPools()?.MORPHO_BLUE?.[chainId];
|
|
36403
36354
|
const allMarketIds = [...new Set(marketIdsByVault.flat())];
|
|
36404
|
-
const
|
|
36355
|
+
const underlyings = [
|
|
36356
|
+
...new Set(
|
|
36357
|
+
entries.map(({ entry }) => entry.underlying?.toLowerCase()).filter((a) => !!a)
|
|
36358
|
+
)
|
|
36359
|
+
];
|
|
36360
|
+
const [rateMap, positionMap, assetDecimals] = await Promise.all([
|
|
36405
36361
|
fetchMorphoMarketRates(chainId, core, allMarketIds, multicallRetry),
|
|
36406
36362
|
fetchVaultSupplyShares(
|
|
36407
36363
|
chainId,
|
|
@@ -36409,14 +36365,15 @@ var fetchMorphoVaultsFromChain = async (chainId, multicallRetry, prices = {}, to
|
|
|
36409
36365
|
entries.map((e) => e.entry),
|
|
36410
36366
|
marketIdsByVault,
|
|
36411
36367
|
multicallRetry
|
|
36412
|
-
)
|
|
36368
|
+
),
|
|
36369
|
+
fetchAssetDecimals(chainId, underlyings, multicallRetry)
|
|
36413
36370
|
]);
|
|
36414
36371
|
const out = {};
|
|
36415
36372
|
for (let i = 0; i < entries.length; i++) {
|
|
36416
36373
|
const { entry } = entries[i];
|
|
36417
36374
|
const base = i * PHASE1_PER_VAULT;
|
|
36418
36375
|
const slice = phase1.slice(base, base + CALLS_PER_VAULT);
|
|
36419
|
-
const parsed =
|
|
36376
|
+
const parsed = parseVault3(
|
|
36420
36377
|
entry,
|
|
36421
36378
|
slice,
|
|
36422
36379
|
chainId,
|
|
@@ -36424,7 +36381,8 @@ var fetchMorphoVaultsFromChain = async (chainId, multicallRetry, prices = {}, to
|
|
|
36424
36381
|
tokenList,
|
|
36425
36382
|
marketIdsByVault[i],
|
|
36426
36383
|
rateMap,
|
|
36427
|
-
positionMap
|
|
36384
|
+
positionMap,
|
|
36385
|
+
assetDecimals
|
|
36428
36386
|
);
|
|
36429
36387
|
if (parsed) out[parsed.address] = parsed;
|
|
36430
36388
|
}
|
|
@@ -36473,17 +36431,19 @@ async function fetchMorphoMarketRates(chainId, core, marketIds, multicallRetry)
|
|
|
36473
36431
|
supplyApy = MathLib.getSupplyApy(borrowApy, utilization, mkt.fee);
|
|
36474
36432
|
} catch {
|
|
36475
36433
|
}
|
|
36434
|
+
const liquidity = mkt.totalSupplyAssets > mkt.totalBorrowAssets ? mkt.totalSupplyAssets - mkt.totalBorrowAssets : 0n;
|
|
36476
36435
|
map.set(id, {
|
|
36477
36436
|
supplyApr: apyToApr2(Number(formatEther(supplyApy))) * 100,
|
|
36478
36437
|
totalSupplyAssets: mkt.totalSupplyAssets,
|
|
36479
36438
|
totalSupplyShares: mkt.totalSupplyShares,
|
|
36480
|
-
collateralAddress: (mkt.collateralToken ?? "").toLowerCase()
|
|
36439
|
+
collateralAddress: (mkt.collateralToken ?? "").toLowerCase(),
|
|
36440
|
+
liquidity
|
|
36481
36441
|
});
|
|
36482
36442
|
});
|
|
36483
36443
|
});
|
|
36484
36444
|
return map;
|
|
36485
36445
|
}
|
|
36486
|
-
function
|
|
36446
|
+
function parseVault3(entry, results, chainId, prices, tokenList, marketIds, rateMap, positionMap, assetDecimals) {
|
|
36487
36447
|
const address = entry?.vault?.toLowerCase();
|
|
36488
36448
|
const underlying = entry?.underlying?.toLowerCase();
|
|
36489
36449
|
if (!address || !underlying) return null;
|
|
@@ -36500,7 +36460,7 @@ function parseVault4(entry, results, chainId, prices, tokenList, marketIds, rate
|
|
|
36500
36460
|
guardianRaw
|
|
36501
36461
|
] = results;
|
|
36502
36462
|
const assetMeta = tokenList[underlying];
|
|
36503
|
-
const decimals =
|
|
36463
|
+
const decimals = assetDecimals.get(underlying) ?? assetMeta?.decimals ?? Number(decimalsRaw ?? 18);
|
|
36504
36464
|
const totalAssets = toStringSafe(totalAssetsRaw, "0");
|
|
36505
36465
|
const totalSupply = toStringSafe(totalSupplyRaw, "0");
|
|
36506
36466
|
const totalAssetsFormatted = Number(parseRawAmount(totalAssets, decimals));
|
|
@@ -36511,7 +36471,7 @@ function parseVault4(entry, results, chainId, prices, tokenList, marketIds, rate
|
|
|
36511
36471
|
const symbol = toStringSafe(symbolRaw);
|
|
36512
36472
|
const fee = toNumberSafe(feeRaw) / FEE_SCALE * 100;
|
|
36513
36473
|
const timelock = toNumberSafe(timelockRaw);
|
|
36514
|
-
const { depositRate, exposures } = computeVaultAllocation(
|
|
36474
|
+
const { depositRate, exposures, liquidityFormatted } = computeVaultAllocation(
|
|
36515
36475
|
address,
|
|
36516
36476
|
decimals,
|
|
36517
36477
|
totalAssetsFormatted,
|
|
@@ -36551,12 +36511,13 @@ function parseVault4(entry, results, chainId, prices, tokenList, marketIds, rate
|
|
|
36551
36511
|
priceUsd: priceUsd || void 0,
|
|
36552
36512
|
totalAssetsFormatted,
|
|
36553
36513
|
totalAssetsUsd: totalAssetsFormatted * priceUsd,
|
|
36554
|
-
//
|
|
36555
|
-
//
|
|
36556
|
-
//
|
|
36557
|
-
|
|
36558
|
-
liquidityFormatted:
|
|
36559
|
-
|
|
36514
|
+
// Real withdrawable from the allocation walk: idle + Σ min(allocation,
|
|
36515
|
+
// market liquidity) across the vault's markets. Degrades to `totalAssets`
|
|
36516
|
+
// only when no lens/core is available (rateMap empty). Fully-liquid case
|
|
36517
|
+
// reuses the exact raw total to avoid float round-trip drift.
|
|
36518
|
+
liquidity: liquidityFormatted >= totalAssetsFormatted ? totalAssets : toRawAmount(liquidityFormatted, decimals),
|
|
36519
|
+
liquidityFormatted,
|
|
36520
|
+
liquidityUsd: liquidityFormatted * priceUsd
|
|
36560
36521
|
};
|
|
36561
36522
|
}
|
|
36562
36523
|
|
|
@@ -36571,9 +36532,6 @@ var fetchMorphoVaults = async (chainId, multicallRetry, prices = {}, tokenList =
|
|
|
36571
36532
|
tokenList
|
|
36572
36533
|
);
|
|
36573
36534
|
}
|
|
36574
|
-
if (hasMorphoVaultSubgraph(chainId)) {
|
|
36575
|
-
return fetchMorphoVaultsFromSubgraph(chainId, prices, tokenList);
|
|
36576
|
-
}
|
|
36577
36535
|
return fetchMorphoVaultsFromApi(chainId, prices, tokenList);
|
|
36578
36536
|
};
|
|
36579
36537
|
|
|
@@ -36693,6 +36651,13 @@ var toStringSafe2 = (raw, fallback = "") => {
|
|
|
36693
36651
|
if (raw === void 0 || raw === null) return fallback;
|
|
36694
36652
|
return String(raw);
|
|
36695
36653
|
};
|
|
36654
|
+
var toRawAmount2 = (formatted, decimals) => {
|
|
36655
|
+
try {
|
|
36656
|
+
return parseUnits(formatted.toFixed(decimals), decimals).toString();
|
|
36657
|
+
} catch {
|
|
36658
|
+
return "0";
|
|
36659
|
+
}
|
|
36660
|
+
};
|
|
36696
36661
|
var collectEntries2 = (chainId) => {
|
|
36697
36662
|
const list = morphoTypeVaults()?.[LISTA_PROTOCOL]?.[chainId] ?? [];
|
|
36698
36663
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -36766,7 +36731,12 @@ var fetchListaVaultsFromChain = async (chainId, multicallRetry, prices = {}, tok
|
|
|
36766
36731
|
});
|
|
36767
36732
|
const moolah = morphoPools()?.[LISTA_PROTOCOL]?.[chainId];
|
|
36768
36733
|
const allMarketIds = [...new Set(marketIdsByVault.flat())];
|
|
36769
|
-
const
|
|
36734
|
+
const underlyings = [
|
|
36735
|
+
...new Set(
|
|
36736
|
+
entries.map((entry) => entry.underlying?.toLowerCase()).filter((a) => !!a)
|
|
36737
|
+
)
|
|
36738
|
+
];
|
|
36739
|
+
const [rateMap, positionMap, assetDecimals] = await Promise.all([
|
|
36770
36740
|
fetchListaMarketRates(chainId, moolah, allMarketIds, multicallRetry),
|
|
36771
36741
|
fetchVaultSupplyShares(
|
|
36772
36742
|
chainId,
|
|
@@ -36774,13 +36744,14 @@ var fetchListaVaultsFromChain = async (chainId, multicallRetry, prices = {}, tok
|
|
|
36774
36744
|
entries,
|
|
36775
36745
|
marketIdsByVault,
|
|
36776
36746
|
multicallRetry
|
|
36777
|
-
)
|
|
36747
|
+
),
|
|
36748
|
+
fetchAssetDecimals(chainId, underlyings, multicallRetry)
|
|
36778
36749
|
]);
|
|
36779
36750
|
const out = {};
|
|
36780
36751
|
for (let i = 0; i < entries.length; i++) {
|
|
36781
36752
|
const entry = entries[i];
|
|
36782
36753
|
const slice = phase1.slice(i * PHASE1_PER_VAULT2, (i + 1) * PHASE1_PER_VAULT2);
|
|
36783
|
-
const parsed =
|
|
36754
|
+
const parsed = parseVault4(
|
|
36784
36755
|
entry,
|
|
36785
36756
|
slice,
|
|
36786
36757
|
curatorAddrByVault[i],
|
|
@@ -36789,7 +36760,8 @@ var fetchListaVaultsFromChain = async (chainId, multicallRetry, prices = {}, tok
|
|
|
36789
36760
|
tokenList,
|
|
36790
36761
|
marketIdsByVault[i],
|
|
36791
36762
|
rateMap,
|
|
36792
|
-
positionMap
|
|
36763
|
+
positionMap,
|
|
36764
|
+
assetDecimals
|
|
36793
36765
|
);
|
|
36794
36766
|
if (parsed) out[parsed.address] = parsed;
|
|
36795
36767
|
}
|
|
@@ -36840,17 +36812,19 @@ async function fetchListaMarketRates(chainId, moolah, marketIds, multicallRetry)
|
|
|
36840
36812
|
supplyApy = MathLib.getSupplyApy(borrowApy, utilization, mkt.fee);
|
|
36841
36813
|
} catch {
|
|
36842
36814
|
}
|
|
36815
|
+
const liquidity = mkt.totalSupplyAssets > mkt.totalBorrowAssets ? mkt.totalSupplyAssets - mkt.totalBorrowAssets : 0n;
|
|
36843
36816
|
map.set(id, {
|
|
36844
36817
|
supplyApr: apyToApr(Number(formatEther(supplyApy))) * 100,
|
|
36845
36818
|
totalSupplyAssets: mkt.totalSupplyAssets,
|
|
36846
36819
|
totalSupplyShares: mkt.totalSupplyShares,
|
|
36847
|
-
collateralAddress: (mkt.collateralToken ?? "").toLowerCase()
|
|
36820
|
+
collateralAddress: (mkt.collateralToken ?? "").toLowerCase(),
|
|
36821
|
+
liquidity
|
|
36848
36822
|
});
|
|
36849
36823
|
});
|
|
36850
36824
|
});
|
|
36851
36825
|
return map;
|
|
36852
36826
|
}
|
|
36853
|
-
function
|
|
36827
|
+
function parseVault4(entry, results, curatorAddrRaw, chainId, prices, tokenList, marketIds, rateMap, positionMap, assetDecimals) {
|
|
36854
36828
|
const address = entry?.vault?.toLowerCase();
|
|
36855
36829
|
const underlying = entry?.underlying?.toLowerCase();
|
|
36856
36830
|
if (!address || !underlying) return null;
|
|
@@ -36867,7 +36841,7 @@ function parseVault5(entry, results, curatorAddrRaw, chainId, prices, tokenList,
|
|
|
36867
36841
|
,
|
|
36868
36842
|
] = results;
|
|
36869
36843
|
const assetMeta = tokenList[underlying];
|
|
36870
|
-
const decimals =
|
|
36844
|
+
const decimals = assetDecimals.get(underlying) ?? assetMeta?.decimals ?? Number(decimalsRaw ?? 18);
|
|
36871
36845
|
const totalAssets = toStringSafe2(totalAssetsRaw, "0");
|
|
36872
36846
|
const totalSupply = toStringSafe2(totalSupplyRaw, "0");
|
|
36873
36847
|
const totalAssetsFormatted = Number(parseRawAmount(totalAssets, decimals));
|
|
@@ -36877,7 +36851,7 @@ function parseVault5(entry, results, curatorAddrRaw, chainId, prices, tokenList,
|
|
|
36877
36851
|
const fallbackName = onchainName || (entry.name ?? "").trim();
|
|
36878
36852
|
const symbol = toStringSafe2(symbolRaw);
|
|
36879
36853
|
const fee = toNumberSafe2(feeRaw) / FEE_SCALE2 * 100;
|
|
36880
|
-
const { depositRate, exposures } = computeVaultAllocation(
|
|
36854
|
+
const { depositRate, exposures, liquidityFormatted } = computeVaultAllocation(
|
|
36881
36855
|
address,
|
|
36882
36856
|
decimals,
|
|
36883
36857
|
totalAssetsFormatted,
|
|
@@ -36919,9 +36893,12 @@ function parseVault5(entry, results, curatorAddrRaw, chainId, prices, tokenList,
|
|
|
36919
36893
|
priceUsd: priceUsd || void 0,
|
|
36920
36894
|
totalAssetsFormatted,
|
|
36921
36895
|
totalAssetsUsd: totalAssetsFormatted * priceUsd,
|
|
36922
|
-
|
|
36923
|
-
|
|
36924
|
-
|
|
36896
|
+
// Real withdrawable: idle + Σ min(allocation, market liquidity) across the
|
|
36897
|
+
// vault's Moolah markets (see `computeVaultAllocation`). Fully-liquid case
|
|
36898
|
+
// reuses the exact raw total to avoid float round-trip drift.
|
|
36899
|
+
liquidity: liquidityFormatted >= totalAssetsFormatted ? totalAssets : toRawAmount2(liquidityFormatted, decimals),
|
|
36900
|
+
liquidityFormatted,
|
|
36901
|
+
liquidityUsd: liquidityFormatted * priceUsd,
|
|
36925
36902
|
exposures: exposures.length > 0 ? exposures : void 0
|
|
36926
36903
|
};
|
|
36927
36904
|
}
|
|
@@ -36966,6 +36943,7 @@ query GetSiloVaults {
|
|
|
36966
36943
|
depositRate
|
|
36967
36944
|
collateralSharesSupply
|
|
36968
36945
|
collateralAssetsSupply
|
|
36946
|
+
liquidity
|
|
36969
36947
|
otherMarket { inputToken { id } }
|
|
36970
36948
|
}
|
|
36971
36949
|
}
|
|
@@ -37002,8 +36980,28 @@ function buildExposures(vaultId, totalAssetsFormatted, pricePerUnit, positionsBy
|
|
|
37002
36980
|
);
|
|
37003
36981
|
return withIdle.length > 0 ? withIdle : void 0;
|
|
37004
36982
|
}
|
|
36983
|
+
function computeSiloLiquidityFormatted(vaultId, totalAssetsFormatted, positionsByVault, marketMeta) {
|
|
36984
|
+
if (totalAssetsFormatted <= 0) return 0;
|
|
36985
|
+
const rows = positionsByVault.get(vaultId) ?? [];
|
|
36986
|
+
let allocated = 0;
|
|
36987
|
+
let withdrawable = 0;
|
|
36988
|
+
for (const row of rows) {
|
|
36989
|
+
const marketId = (row.marketId ?? "").toLowerCase();
|
|
36990
|
+
if (!marketId) continue;
|
|
36991
|
+
const meta = marketMeta.get(marketId);
|
|
36992
|
+
if (!meta || meta.collateralShares <= 0) continue;
|
|
36993
|
+
const shares = Number(row.sTokenBalance ?? 0);
|
|
36994
|
+
if (!Number.isFinite(shares) || shares <= 0) continue;
|
|
36995
|
+
const assets = shares * meta.collateralAssets / meta.collateralShares;
|
|
36996
|
+
if (!(assets > 0) || assets > totalAssetsFormatted * 1.01) continue;
|
|
36997
|
+
allocated += assets;
|
|
36998
|
+
withdrawable += Math.min(assets, meta.liquidity);
|
|
36999
|
+
}
|
|
37000
|
+
const idle = Math.max(0, totalAssetsFormatted - allocated);
|
|
37001
|
+
return Math.min(totalAssetsFormatted, idle + withdrawable);
|
|
37002
|
+
}
|
|
37005
37003
|
var PERFORMANCE_FEE_SCALE = 1e16;
|
|
37006
|
-
var
|
|
37004
|
+
var toRawAmount3 = (decimalString, decimals) => {
|
|
37007
37005
|
if (!decimalString) return "0";
|
|
37008
37006
|
try {
|
|
37009
37007
|
return parseUnits(decimalString, decimals).toString();
|
|
@@ -37011,7 +37009,7 @@ var toRawAmount = (decimalString, decimals) => {
|
|
|
37011
37009
|
return "0";
|
|
37012
37010
|
}
|
|
37013
37011
|
};
|
|
37014
|
-
function
|
|
37012
|
+
function parseVault5(v, chainId, prices, tokenList, exposures, liquidityFormatted) {
|
|
37015
37013
|
const address = (v?.id ?? "").toLowerCase();
|
|
37016
37014
|
const assetAddr = (v?.asset?.id ?? "").toLowerCase();
|
|
37017
37015
|
if (!address || !assetAddr) return null;
|
|
@@ -37020,8 +37018,8 @@ function parseVault6(v, chainId, prices, tokenList, exposures) {
|
|
|
37020
37018
|
v.decimals ?? v.asset?.decimals ?? assetMeta?.decimals ?? 18
|
|
37021
37019
|
);
|
|
37022
37020
|
const totalAssetsFormatted = Number(v.totalAssets ?? 0) || 0;
|
|
37023
|
-
const totalAssetsRaw =
|
|
37024
|
-
const totalSupplyRaw =
|
|
37021
|
+
const totalAssetsRaw = toRawAmount3(v.totalAssets, decimals);
|
|
37022
|
+
const totalSupplyRaw = toRawAmount3(v.totalSupply, decimals);
|
|
37025
37023
|
const oracleKey = toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(assetAddr, chainId);
|
|
37026
37024
|
const priceUsd = prices[oracleKey] ?? prices[assetAddr] ?? 0;
|
|
37027
37025
|
const supplyRate = Number(v.userApr ?? 0) || 0;
|
|
@@ -37060,14 +37058,14 @@ function parseVault6(v, chainId, prices, tokenList, exposures) {
|
|
|
37060
37058
|
priceUsd: priceUsd || void 0,
|
|
37061
37059
|
totalAssetsFormatted,
|
|
37062
37060
|
totalAssetsUsd,
|
|
37063
|
-
//
|
|
37064
|
-
//
|
|
37065
|
-
//
|
|
37066
|
-
//
|
|
37067
|
-
//
|
|
37068
|
-
liquidity: totalAssetsRaw,
|
|
37069
|
-
liquidityFormatted
|
|
37070
|
-
liquidityUsd: totalAssetsUsd,
|
|
37061
|
+
// Real immediately-withdrawable liquidity: idle + Σ min(allocation,
|
|
37062
|
+
// market.liquidity) across the vault's silos (see
|
|
37063
|
+
// `computeSiloLiquidityFormatted`). Degrades to `totalAssets` only when
|
|
37064
|
+
// allocation data is absent. When fully liquid, reuse the exact
|
|
37065
|
+
// `totalAssetsRaw` to avoid float round-trip drift.
|
|
37066
|
+
liquidity: liquidityFormatted >= totalAssetsFormatted ? totalAssetsRaw : toRawAmount3(liquidityFormatted.toFixed(decimals), decimals),
|
|
37067
|
+
liquidityFormatted,
|
|
37068
|
+
liquidityUsd: totalAssetsFormatted > 0 ? liquidityFormatted * (totalAssetsUsd / totalAssetsFormatted) : 0,
|
|
37071
37069
|
exposures
|
|
37072
37070
|
};
|
|
37073
37071
|
}
|
|
@@ -37110,7 +37108,8 @@ var fetchSiloVaults = async (chainId, prices = {}, tokenList = {}, options) => {
|
|
|
37110
37108
|
collateralAddress: (m.otherMarket?.inputToken?.id ?? "").toLowerCase(),
|
|
37111
37109
|
supplyApr: Number.isFinite(apr) ? apr : 0,
|
|
37112
37110
|
collateralShares: Number(m.collateralSharesSupply ?? 0) || 0,
|
|
37113
|
-
collateralAssets: Number(m.collateralAssetsSupply ?? 0) || 0
|
|
37111
|
+
collateralAssets: Number(m.collateralAssetsSupply ?? 0) || 0,
|
|
37112
|
+
liquidity: Number(m.liquidity ?? 0) || 0
|
|
37114
37113
|
});
|
|
37115
37114
|
}
|
|
37116
37115
|
const out = {};
|
|
@@ -37130,7 +37129,20 @@ var fetchSiloVaults = async (chainId, prices = {}, tokenList = {}, options) => {
|
|
|
37130
37129
|
marketMeta,
|
|
37131
37130
|
tokenList
|
|
37132
37131
|
);
|
|
37133
|
-
const
|
|
37132
|
+
const liquidityFormatted = computeSiloLiquidityFormatted(
|
|
37133
|
+
vaultId,
|
|
37134
|
+
totalAssetsFormatted,
|
|
37135
|
+
positionsByVault,
|
|
37136
|
+
marketMeta
|
|
37137
|
+
);
|
|
37138
|
+
const parsed = parseVault5(
|
|
37139
|
+
v,
|
|
37140
|
+
chainId,
|
|
37141
|
+
prices,
|
|
37142
|
+
tokenList,
|
|
37143
|
+
exposures,
|
|
37144
|
+
liquidityFormatted
|
|
37145
|
+
);
|
|
37134
37146
|
if (parsed) out[parsed.address] = parsed;
|
|
37135
37147
|
}
|
|
37136
37148
|
return out;
|
|
@@ -37251,7 +37263,7 @@ function computeRealLiquidity(strategies, totalAssetsRaw, evkIndex) {
|
|
|
37251
37263
|
const result = idle + withdrawable;
|
|
37252
37264
|
return result > totalAssets ? totalAssets : result;
|
|
37253
37265
|
}
|
|
37254
|
-
function
|
|
37266
|
+
function parseVault6(v, chainId, prices, tokenList, evkIndex) {
|
|
37255
37267
|
const address = (v?.id ?? "").toLowerCase();
|
|
37256
37268
|
const assetAddr = (v?.asset ?? "").toLowerCase();
|
|
37257
37269
|
if (!address || !assetAddr) return null;
|
|
@@ -37367,7 +37379,7 @@ async function fetchEulerEarnVaultsFromSubgraph(chainId, prices = {}, tokenList
|
|
|
37367
37379
|
const evkIndex = await fetchEvkIndex(url, [...assets]);
|
|
37368
37380
|
const out = {};
|
|
37369
37381
|
for (const v of items) {
|
|
37370
|
-
const parsed =
|
|
37382
|
+
const parsed = parseVault6(v, chainId, prices, tokenList, evkIndex);
|
|
37371
37383
|
if (parsed) out[parsed.address] = parsed;
|
|
37372
37384
|
}
|
|
37373
37385
|
return out;
|
|
@@ -38869,6 +38881,16 @@ var Erc4626PreviewRedeemAbi = [
|
|
|
38869
38881
|
|
|
38870
38882
|
// src/vaults/lst/readers/shared.ts
|
|
38871
38883
|
var ONE_E187 = 10n ** 18n;
|
|
38884
|
+
var MULTICALL3_ADDRESS = "0xcA11bde05977b3631167028862bE2a173976CA11";
|
|
38885
|
+
var Multicall3BalanceAbi = [
|
|
38886
|
+
{
|
|
38887
|
+
name: "getEthBalance",
|
|
38888
|
+
type: "function",
|
|
38889
|
+
stateMutability: "view",
|
|
38890
|
+
inputs: [{ name: "addr", type: "address" }],
|
|
38891
|
+
outputs: [{ type: "uint256" }]
|
|
38892
|
+
}
|
|
38893
|
+
];
|
|
38872
38894
|
var toBigInt10 = (v) => {
|
|
38873
38895
|
if (v === void 0 || v === null) return void 0;
|
|
38874
38896
|
if (typeof v === "bigint") return v;
|
|
@@ -39053,6 +39075,13 @@ var EtherFiLiquidityPoolAbi = [
|
|
|
39053
39075
|
stateMutability: "view",
|
|
39054
39076
|
inputs: [],
|
|
39055
39077
|
outputs: [{ type: "uint256" }]
|
|
39078
|
+
},
|
|
39079
|
+
{
|
|
39080
|
+
name: "ethAmountLockedForWithdrawal",
|
|
39081
|
+
type: "function",
|
|
39082
|
+
stateMutability: "view",
|
|
39083
|
+
inputs: [],
|
|
39084
|
+
outputs: [{ type: "uint256" }]
|
|
39056
39085
|
}
|
|
39057
39086
|
];
|
|
39058
39087
|
|
|
@@ -39065,8 +39094,17 @@ var readerEtherFiWeEth = (entry) => {
|
|
|
39065
39094
|
];
|
|
39066
39095
|
const abis = [TotalSupplyAbi, EtherFiWeEthAbi];
|
|
39067
39096
|
if (lp) {
|
|
39068
|
-
calls.push({
|
|
39069
|
-
|
|
39097
|
+
calls.push({
|
|
39098
|
+
address: MULTICALL3_ADDRESS,
|
|
39099
|
+
name: "getEthBalance",
|
|
39100
|
+
params: [lp]
|
|
39101
|
+
});
|
|
39102
|
+
calls.push({
|
|
39103
|
+
address: lp,
|
|
39104
|
+
name: "ethAmountLockedForWithdrawal",
|
|
39105
|
+
params: []
|
|
39106
|
+
});
|
|
39107
|
+
abis.push(Multicall3BalanceAbi, EtherFiLiquidityPoolAbi);
|
|
39070
39108
|
}
|
|
39071
39109
|
return {
|
|
39072
39110
|
calls,
|
|
@@ -39077,7 +39115,14 @@ var readerEtherFiWeEth = (entry) => {
|
|
|
39077
39115
|
if (totalSupply === void 0 || exchangeRate === void 0) {
|
|
39078
39116
|
return void 0;
|
|
39079
39117
|
}
|
|
39080
|
-
|
|
39118
|
+
let liquidity;
|
|
39119
|
+
if (lp) {
|
|
39120
|
+
const lpBalance = toBigInt10(slice[2]);
|
|
39121
|
+
const locked = toBigInt10(slice[3]);
|
|
39122
|
+
if (lpBalance !== void 0 && locked !== void 0) {
|
|
39123
|
+
liquidity = lpBalance > locked ? lpBalance - locked : 0n;
|
|
39124
|
+
}
|
|
39125
|
+
}
|
|
39081
39126
|
return {
|
|
39082
39127
|
totalAssets: totalSupply * exchangeRate / ONE_E187,
|
|
39083
39128
|
totalSupply,
|
|
@@ -40109,6 +40154,11 @@ var resolveYieldApr = async (entries) => {
|
|
|
40109
40154
|
|
|
40110
40155
|
// src/vaults/lst/fetchPublic.ts
|
|
40111
40156
|
var ONE_E188 = 10n ** 18n;
|
|
40157
|
+
var ERC20_BALANCE_ABI = parseAbi([
|
|
40158
|
+
"function balanceOf(address) view returns (uint256)"
|
|
40159
|
+
]);
|
|
40160
|
+
var INSTANT_MODES = /* @__PURE__ */ new Set(["instant-or-queued", "fee-or-queued"]);
|
|
40161
|
+
var IDLE_READER_KINDS = /* @__PURE__ */ new Set(["erc4626", "erc4626PreviewRedeem"]);
|
|
40112
40162
|
var resolveAcceptedInputs = (chainId, shareToken, entry) => {
|
|
40113
40163
|
const enriched = getLstAcceptedInputs(chainId, shareToken);
|
|
40114
40164
|
if (enriched) return enriched;
|
|
@@ -40126,6 +40176,20 @@ var fetchLstShareTokens = async (chainId, multicallRetry, prices = {}, tokenList
|
|
|
40126
40176
|
const readers = entries.map(buildReader);
|
|
40127
40177
|
const allCalls = readers.flatMap((r) => r.calls);
|
|
40128
40178
|
const allAbis = readers.flatMap((r) => r.abis);
|
|
40179
|
+
const idleEntries = entries.filter(
|
|
40180
|
+
(e) => INSTANT_MODES.has(e.withdrawalMode) && IDLE_READER_KINDS.has(e.reader)
|
|
40181
|
+
);
|
|
40182
|
+
const idleIsNative = (e) => e.underlying.toLowerCase() === zeroAddress;
|
|
40183
|
+
const idleCalls = idleEntries.map(
|
|
40184
|
+
(e) => idleIsNative(e) ? {
|
|
40185
|
+
address: MULTICALL3_ADDRESS,
|
|
40186
|
+
name: "getEthBalance",
|
|
40187
|
+
params: [e.address]
|
|
40188
|
+
} : { address: e.underlying, name: "balanceOf", params: [e.address] }
|
|
40189
|
+
);
|
|
40190
|
+
const idleAbis = idleEntries.map(
|
|
40191
|
+
(e) => idleIsNative(e) ? Multicall3BalanceAbi : ERC20_BALANCE_ABI
|
|
40192
|
+
);
|
|
40129
40193
|
const groups = {};
|
|
40130
40194
|
for (let i = 0; i < allCalls.length; i++) {
|
|
40131
40195
|
const target = allCalls[i].chainId ?? chainId;
|
|
@@ -40135,7 +40199,7 @@ var fetchLstShareTokens = async (chainId, multicallRetry, prices = {}, tokenList
|
|
|
40135
40199
|
g.positions.push(i);
|
|
40136
40200
|
}
|
|
40137
40201
|
const chainEntries = Object.entries(groups);
|
|
40138
|
-
const [perChainResults, aprByAddress] = await Promise.all([
|
|
40202
|
+
const [perChainResults, aprByAddress, idleResults] = await Promise.all([
|
|
40139
40203
|
chainEntries.length > 0 ? Promise.all(
|
|
40140
40204
|
chainEntries.map(async ([chain, { calls, abis }]) => ({
|
|
40141
40205
|
chain,
|
|
@@ -40146,8 +40210,19 @@ var fetchLstShareTokens = async (chainId, multicallRetry, prices = {}, tokenList
|
|
|
40146
40210
|
})
|
|
40147
40211
|
}))
|
|
40148
40212
|
) : Promise.resolve([]),
|
|
40149
|
-
resolveYieldApr(entries)
|
|
40213
|
+
resolveYieldApr(entries),
|
|
40214
|
+
idleEntries.length > 0 ? multicallRetry({
|
|
40215
|
+
chain: chainId,
|
|
40216
|
+
calls: idleCalls,
|
|
40217
|
+
abi: idleAbis,
|
|
40218
|
+
allowFailure: true
|
|
40219
|
+
}) : Promise.resolve([])
|
|
40150
40220
|
]);
|
|
40221
|
+
const idleByAddress = /* @__PURE__ */ new Map();
|
|
40222
|
+
idleEntries.forEach((e, i) => {
|
|
40223
|
+
const bal = toBigInt10(idleResults[i]);
|
|
40224
|
+
if (bal !== void 0) idleByAddress.set(e.address.toLowerCase(), bal);
|
|
40225
|
+
});
|
|
40151
40226
|
const rawResults = new Array(allCalls.length);
|
|
40152
40227
|
for (const { chain, results } of perChainResults) {
|
|
40153
40228
|
const positions = groups[chain].positions;
|
|
@@ -40176,9 +40251,15 @@ var fetchLstShareTokens = async (chainId, multicallRetry, prices = {}, tokenList
|
|
|
40176
40251
|
const totalAssetsUsd = priceUsd !== void 0 ? totalAssetsFormatted * priceUsd : 0;
|
|
40177
40252
|
const convertToAssets = state.exchangeRate;
|
|
40178
40253
|
const convertToShares = state.exchangeRate > 0n ? ONE_E188 * ONE_E188 / state.exchangeRate : 0n;
|
|
40179
|
-
|
|
40180
|
-
|
|
40181
|
-
|
|
40254
|
+
let liquidityRaw;
|
|
40255
|
+
if (state.liquidity !== void 0) {
|
|
40256
|
+
liquidityRaw = state.liquidity;
|
|
40257
|
+
} else {
|
|
40258
|
+
const idle = idleByAddress.get(addressLc);
|
|
40259
|
+
liquidityRaw = idle !== void 0 ? idle > state.totalAssets ? state.totalAssets : idle : 0n;
|
|
40260
|
+
}
|
|
40261
|
+
const liquidityFormatted = Number(liquidityRaw) / decimalsFactor;
|
|
40262
|
+
const liquidityUsd = priceUsd !== void 0 ? liquidityFormatted * priceUsd : 0;
|
|
40182
40263
|
const displayName = composeVaultDisplayName(
|
|
40183
40264
|
entry.brand,
|
|
40184
40265
|
entry.brand,
|
|
@@ -40218,7 +40299,7 @@ var fetchLstShareTokens = async (chainId, multicallRetry, prices = {}, tokenList
|
|
|
40218
40299
|
priceUsd,
|
|
40219
40300
|
totalAssetsFormatted,
|
|
40220
40301
|
totalAssetsUsd,
|
|
40221
|
-
liquidity:
|
|
40302
|
+
liquidity: liquidityRaw.toString(),
|
|
40222
40303
|
liquidityFormatted,
|
|
40223
40304
|
liquidityUsd
|
|
40224
40305
|
};
|
|
@@ -42632,6 +42713,71 @@ var buildWithdrawalReader = (entry) => {
|
|
|
42632
42713
|
// src/vaults/lst/withdrawals/registry.ts
|
|
42633
42714
|
var LST_WITHDRAWAL_REGISTRY = {
|
|
42634
42715
|
"1": [
|
|
42716
|
+
// Ankr ankrETH — Ankr unstake queue; reader not yet implemented.
|
|
42717
|
+
{
|
|
42718
|
+
lst: "0xe95a203b1a91a908f9b9ce46459d101078c2c3cb",
|
|
42719
|
+
brand: "Ankr",
|
|
42720
|
+
symbol: "ankrETH",
|
|
42721
|
+
reader: "unverified"
|
|
42722
|
+
},
|
|
42723
|
+
// BTC LSTs — exits via issuer/DEX or a protocol queue; per-protocol
|
|
42724
|
+
// readers not yet implemented. Listed as `unverified` placeholders so the
|
|
42725
|
+
// orchestrator surfaces the asset (returns [] requests) instead of
|
|
42726
|
+
// silently omitting it.
|
|
42727
|
+
{
|
|
42728
|
+
lst: "0x8db2350d78abc13f5673a411d4700bcf87864dde",
|
|
42729
|
+
brand: "Swell",
|
|
42730
|
+
symbol: "swBTC",
|
|
42731
|
+
reader: "unverified"
|
|
42732
|
+
},
|
|
42733
|
+
{
|
|
42734
|
+
lst: "0x8236a87084f8b84306f72007f36f2618a5634494",
|
|
42735
|
+
brand: "Lombard",
|
|
42736
|
+
symbol: "LBTC",
|
|
42737
|
+
reader: "unverified"
|
|
42738
|
+
},
|
|
42739
|
+
{
|
|
42740
|
+
lst: "0x657e8c867d8b37dcc18fa4caead9c45eb088c642",
|
|
42741
|
+
brand: "ether.fi",
|
|
42742
|
+
symbol: "eBTC",
|
|
42743
|
+
reader: "unverified"
|
|
42744
|
+
},
|
|
42745
|
+
{
|
|
42746
|
+
lst: "0x004e9c3ef86bc1ca1f0bb5c7662861ee93350568",
|
|
42747
|
+
brand: "Bedrock",
|
|
42748
|
+
symbol: "uniBTC",
|
|
42749
|
+
reader: "unverified"
|
|
42750
|
+
},
|
|
42751
|
+
{
|
|
42752
|
+
lst: "0x2ec37d45fcae65d9787ecf71dc85a444968f6646",
|
|
42753
|
+
brand: "Bedrock",
|
|
42754
|
+
symbol: "brBTC",
|
|
42755
|
+
reader: "unverified"
|
|
42756
|
+
},
|
|
42757
|
+
{
|
|
42758
|
+
lst: "0xf469fbd2abcd6b9de8e169d128226c0fc90a012e",
|
|
42759
|
+
brand: "PumpBTC",
|
|
42760
|
+
symbol: "pumpBTC",
|
|
42761
|
+
reader: "unverified"
|
|
42762
|
+
},
|
|
42763
|
+
{
|
|
42764
|
+
lst: "0x7a56e1c57c7475ccf742a1832b028f0456652f97",
|
|
42765
|
+
brand: "Solv",
|
|
42766
|
+
symbol: "SolvBTC",
|
|
42767
|
+
reader: "unverified"
|
|
42768
|
+
},
|
|
42769
|
+
{
|
|
42770
|
+
lst: "0xd9d920aa40f578ab794426f5c90f6c731d159def",
|
|
42771
|
+
brand: "Solv",
|
|
42772
|
+
symbol: "xSolvBTC",
|
|
42773
|
+
reader: "unverified"
|
|
42774
|
+
},
|
|
42775
|
+
{
|
|
42776
|
+
lst: "0xcea2daf93617b97504e05affc5bcf9b3922d3034",
|
|
42777
|
+
brand: "Solv",
|
|
42778
|
+
symbol: "BTC+",
|
|
42779
|
+
reader: "unverified"
|
|
42780
|
+
},
|
|
42635
42781
|
{
|
|
42636
42782
|
lst: "0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0",
|
|
42637
42783
|
brand: "Lido",
|
|
@@ -42795,6 +42941,13 @@ var LST_WITHDRAWAL_REGISTRY = {
|
|
|
42795
42941
|
}
|
|
42796
42942
|
],
|
|
42797
42943
|
"56": [
|
|
42944
|
+
// Ankr ankrBNB — Ankr unstake queue; reader not yet implemented.
|
|
42945
|
+
{
|
|
42946
|
+
lst: "0x52f24a5e03aee338da5fd9df68d2b6fae1178827",
|
|
42947
|
+
brand: "Ankr",
|
|
42948
|
+
symbol: "ankrBNB",
|
|
42949
|
+
reader: "unverified"
|
|
42950
|
+
},
|
|
42798
42951
|
{
|
|
42799
42952
|
// slisBNB — ListaStakeManager withdrawal queue. Per-user
|
|
42800
42953
|
// requests via getUserWithdrawalRequests; claimability + BNB
|
|
@@ -42823,6 +42976,13 @@ var LST_WITHDRAWAL_REGISTRY = {
|
|
|
42823
42976
|
}
|
|
42824
42977
|
],
|
|
42825
42978
|
"137": [
|
|
42979
|
+
// Ankr ankrMATIC — bridged, non-mintable on Polygon; exit via DEX only.
|
|
42980
|
+
{
|
|
42981
|
+
lst: "0x0e9b89007eee9c958c0eda24ef70723c2c93dd58",
|
|
42982
|
+
brand: "Ankr",
|
|
42983
|
+
symbol: "ankrMATIC",
|
|
42984
|
+
reader: "noQueue"
|
|
42985
|
+
},
|
|
42826
42986
|
{
|
|
42827
42987
|
// Polygon-side MaticX is a bridged ERC-20 — users bridge to
|
|
42828
42988
|
// Ethereum and claim from the L1 home contract.
|
|
@@ -42833,6 +42993,13 @@ var LST_WITHDRAWAL_REGISTRY = {
|
|
|
42833
42993
|
}
|
|
42834
42994
|
],
|
|
42835
42995
|
"43114": [
|
|
42996
|
+
// Ankr ankrAVAX — Ankr unstake queue; reader not yet implemented.
|
|
42997
|
+
{
|
|
42998
|
+
lst: "0xc3344870d52688874b06d844e0c36cc39fc727f6",
|
|
42999
|
+
brand: "Ankr",
|
|
43000
|
+
symbol: "ankrAVAX",
|
|
43001
|
+
reader: "unverified"
|
|
43002
|
+
},
|
|
42836
43003
|
{
|
|
42837
43004
|
lst: "0x2b2c81e08f1af8835a78bb2a90ae924ace0ea4be",
|
|
42838
43005
|
brand: "BENQI",
|
|
@@ -43016,6 +43183,35 @@ var LST_WITHDRAWAL_REGISTRY = {
|
|
|
43016
43183
|
reader: "stellaUnbondQueue",
|
|
43017
43184
|
withdrawalContract: "0xbc7e02c4178a7df7d3e564323a5c359dc96c4db4"
|
|
43018
43185
|
}
|
|
43186
|
+
],
|
|
43187
|
+
"1116": [
|
|
43188
|
+
// Core DAO LSTs — CoreDAO stakers unbond via the Earn / staking
|
|
43189
|
+
// contracts; per-protocol queue readers not yet implemented.
|
|
43190
|
+
{
|
|
43191
|
+
lst: "0xb3a8f0f0da9ffc65318aa39e55079796093029ad",
|
|
43192
|
+
brand: "Core",
|
|
43193
|
+
symbol: "stCORE",
|
|
43194
|
+
reader: "unverified"
|
|
43195
|
+
},
|
|
43196
|
+
{
|
|
43197
|
+
lst: "0xc5555ea27e63cd89f8b227dece2a3916800c0f4f",
|
|
43198
|
+
brand: "b14g",
|
|
43199
|
+
symbol: "dualCORE",
|
|
43200
|
+
reader: "unverified"
|
|
43201
|
+
},
|
|
43202
|
+
{
|
|
43203
|
+
lst: "0xa20b3b97df3a02f9185175760300a06b4e0a2c05",
|
|
43204
|
+
brand: "StakedCore",
|
|
43205
|
+
symbol: "SCORE",
|
|
43206
|
+
reader: "unverified"
|
|
43207
|
+
},
|
|
43208
|
+
// pumpBTC on Core — bridged, non-mintable; exit via DEX only.
|
|
43209
|
+
{
|
|
43210
|
+
lst: "0x5a2aa871954ebdf89b1547e75d032598356caad5",
|
|
43211
|
+
brand: "PumpBTC",
|
|
43212
|
+
symbol: "pumpBTC",
|
|
43213
|
+
reader: "noQueue"
|
|
43214
|
+
}
|
|
43019
43215
|
]
|
|
43020
43216
|
};
|
|
43021
43217
|
var getLstWithdrawalRegistry = (chainId, extraEntries) => {
|
|
@@ -43504,6 +43700,10 @@ var fetchSavingsVaults = async (chainId, multicallRetry, prices = {}, tokenList
|
|
|
43504
43700
|
const underlyingUnit = 10n ** BigInt(underlyingDec);
|
|
43505
43701
|
const totalAssetsFormatted = Number(state.totalAssets) / 10 ** underlyingDec;
|
|
43506
43702
|
const totalAssetsUsd = priceUsd !== void 0 ? totalAssetsFormatted * priceUsd : 0;
|
|
43703
|
+
const isInstant = entry.withdrawalMode === "instant";
|
|
43704
|
+
const liquidityRaw = isInstant ? state.totalAssets.toString() : "0";
|
|
43705
|
+
const liquidityFormatted = isInstant ? totalAssetsFormatted : 0;
|
|
43706
|
+
const liquidityUsd = isInstant ? totalAssetsUsd : 0;
|
|
43507
43707
|
const convertToAssets = state.exchangeRate * underlyingUnit / ONE_E1810;
|
|
43508
43708
|
const convertToShares = state.exchangeRate > 0n ? ONE_E1810 * shareUnit / state.exchangeRate : 0n;
|
|
43509
43709
|
const displayName = composeVaultDisplayName(
|
|
@@ -43541,7 +43741,10 @@ var fetchSavingsVaults = async (chainId, multicallRetry, prices = {}, tokenList
|
|
|
43541
43741
|
asset,
|
|
43542
43742
|
priceUsd,
|
|
43543
43743
|
totalAssetsFormatted,
|
|
43544
|
-
totalAssetsUsd
|
|
43744
|
+
totalAssetsUsd,
|
|
43745
|
+
liquidity: liquidityRaw,
|
|
43746
|
+
liquidityFormatted,
|
|
43747
|
+
liquidityUsd
|
|
43545
43748
|
};
|
|
43546
43749
|
out[addressLc] = vault;
|
|
43547
43750
|
}
|
|
@@ -43665,7 +43868,7 @@ var pickApr = (apr) => {
|
|
|
43665
43868
|
return { rate: 0, window: "none" };
|
|
43666
43869
|
};
|
|
43667
43870
|
var num = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
43668
|
-
function
|
|
43871
|
+
function parseVault7(v, chainId, prices, tokenList) {
|
|
43669
43872
|
const address = (v?.address ?? "").toLowerCase();
|
|
43670
43873
|
const assetAddr = (v?.asset?.address ?? "").toLowerCase();
|
|
43671
43874
|
if (!address || !assetAddr) return null;
|
|
@@ -43725,10 +43928,249 @@ var fetchLagoonVaults = async (chainId, prices = {}, tokenList = {}) => {
|
|
|
43725
43928
|
if (!hasLagoonVaults(chainId)) return {};
|
|
43726
43929
|
const items = await fetchLagoonApiVaults(chainId);
|
|
43727
43930
|
const out = {};
|
|
43931
|
+
for (const item of items) {
|
|
43932
|
+
const parsed = parseVault7(item, chainId, prices, tokenList);
|
|
43933
|
+
if (parsed) out[parsed.address] = parsed;
|
|
43934
|
+
}
|
|
43935
|
+
return out;
|
|
43936
|
+
};
|
|
43937
|
+
|
|
43938
|
+
// src/vaults/yearn/api.ts
|
|
43939
|
+
var YEARN_YDAEMON_BASE = "https://ydaemon.yearn.fi";
|
|
43940
|
+
var YEARN_CHAIN_IDS = /* @__PURE__ */ new Set([
|
|
43941
|
+
"1",
|
|
43942
|
+
// Ethereum
|
|
43943
|
+
"137",
|
|
43944
|
+
// Polygon
|
|
43945
|
+
"8453",
|
|
43946
|
+
// Base
|
|
43947
|
+
"42161",
|
|
43948
|
+
// Arbitrum
|
|
43949
|
+
"100",
|
|
43950
|
+
// Gnosis
|
|
43951
|
+
"146",
|
|
43952
|
+
// Sonic
|
|
43953
|
+
"747474"
|
|
43954
|
+
// Katana
|
|
43955
|
+
]);
|
|
43956
|
+
var hasYearnVaults = (chainId) => YEARN_CHAIN_IDS.has(String(chainId));
|
|
43957
|
+
var isYearnV3 = (v) => typeof v?.version === "string" && v.version.startsWith("3.");
|
|
43958
|
+
var PAGE_SIZE3 = 500;
|
|
43959
|
+
async function fetchYearnApiVaults(chainId) {
|
|
43960
|
+
const out = [];
|
|
43961
|
+
for (let page = 1; page <= 20; page++) {
|
|
43962
|
+
const url = `${YEARN_YDAEMON_BASE}/${chainId}/vaults/all?limit=${PAGE_SIZE3}&page=${page}`;
|
|
43963
|
+
const response = await fetch(url);
|
|
43964
|
+
if (!response.ok) {
|
|
43965
|
+
throw new Error(
|
|
43966
|
+
`Yearn yDaemon API failed: ${response.status} - ${response.statusText}`
|
|
43967
|
+
);
|
|
43968
|
+
}
|
|
43969
|
+
const items = await response.json();
|
|
43970
|
+
if (!Array.isArray(items)) break;
|
|
43971
|
+
for (const v of items) {
|
|
43972
|
+
if (isYearnV3(v) && v.endorsed) out.push(v);
|
|
43973
|
+
}
|
|
43974
|
+
if (items.length < PAGE_SIZE3) break;
|
|
43975
|
+
}
|
|
43976
|
+
return out;
|
|
43977
|
+
}
|
|
43978
|
+
|
|
43979
|
+
// src/vaults/yearn/fetchPublic.ts
|
|
43980
|
+
var BRAND2 = "Yearn";
|
|
43981
|
+
var ZERO_ADDR = "0x0000000000000000000000000000000000000000";
|
|
43982
|
+
var YearnLiquidityAbi = [
|
|
43983
|
+
{
|
|
43984
|
+
type: "function",
|
|
43985
|
+
name: "availableWithdrawLimit",
|
|
43986
|
+
stateMutability: "view",
|
|
43987
|
+
inputs: [{ name: "owner", type: "address" }],
|
|
43988
|
+
outputs: [{ type: "uint256" }]
|
|
43989
|
+
},
|
|
43990
|
+
{
|
|
43991
|
+
type: "function",
|
|
43992
|
+
name: "totalIdle",
|
|
43993
|
+
stateMutability: "view",
|
|
43994
|
+
inputs: [],
|
|
43995
|
+
outputs: [{ type: "uint256" }]
|
|
43996
|
+
},
|
|
43997
|
+
{
|
|
43998
|
+
type: "function",
|
|
43999
|
+
name: "get_default_queue",
|
|
44000
|
+
stateMutability: "view",
|
|
44001
|
+
inputs: [],
|
|
44002
|
+
outputs: [{ type: "address[]" }]
|
|
44003
|
+
},
|
|
44004
|
+
{
|
|
44005
|
+
type: "function",
|
|
44006
|
+
name: "maxWithdraw",
|
|
44007
|
+
stateMutability: "view",
|
|
44008
|
+
inputs: [{ name: "owner", type: "address" }],
|
|
44009
|
+
outputs: [{ type: "uint256" }]
|
|
44010
|
+
}
|
|
44011
|
+
];
|
|
44012
|
+
var asBig = (v) => {
|
|
44013
|
+
try {
|
|
44014
|
+
if (typeof v === "bigint") return v;
|
|
44015
|
+
if (typeof v === "number" && Number.isFinite(v))
|
|
44016
|
+
return BigInt(Math.trunc(v));
|
|
44017
|
+
if (typeof v === "string" && /^\d+$/.test(v)) return BigInt(v);
|
|
44018
|
+
return null;
|
|
44019
|
+
} catch {
|
|
44020
|
+
return null;
|
|
44021
|
+
}
|
|
44022
|
+
};
|
|
44023
|
+
var num2 = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
44024
|
+
var toPct = (v) => {
|
|
44025
|
+
const n = num2(v);
|
|
44026
|
+
return n == null ? 0 : n * 100;
|
|
44027
|
+
};
|
|
44028
|
+
var deriveTotalSupply = (totalAssetsRaw, pricePerShareRaw, decimals) => {
|
|
44029
|
+
try {
|
|
44030
|
+
const assets = BigInt(totalAssetsRaw || "0");
|
|
44031
|
+
if (assets === 0n) return "0";
|
|
44032
|
+
const pps = BigInt(pricePerShareRaw || "0");
|
|
44033
|
+
if (pps <= 0n) return totalAssetsRaw;
|
|
44034
|
+
const scale = 10n ** BigInt(decimals);
|
|
44035
|
+
return (assets * scale / pps).toString();
|
|
44036
|
+
} catch {
|
|
44037
|
+
return totalAssetsRaw || "0";
|
|
44038
|
+
}
|
|
44039
|
+
};
|
|
44040
|
+
function parseVault8(v, chainId, prices, tokenList) {
|
|
44041
|
+
const address = (v?.address ?? "").toLowerCase();
|
|
44042
|
+
const assetAddr = (v?.token?.address ?? "").toLowerCase();
|
|
44043
|
+
if (!address || !assetAddr) return null;
|
|
44044
|
+
const assetMeta = tokenList[assetAddr];
|
|
44045
|
+
const decimals = Number(v.decimals ?? 18);
|
|
44046
|
+
const assetDecimals = Number(v.token?.decimals ?? assetMeta?.decimals ?? 18);
|
|
44047
|
+
const totalAssetsRaw = v.tvl?.totalAssets?.toString() ?? "0";
|
|
44048
|
+
const pricePerShare = v.pricePerShare?.toString() ?? "0";
|
|
44049
|
+
const totalSupplyRaw = deriveTotalSupply(
|
|
44050
|
+
totalAssetsRaw,
|
|
44051
|
+
pricePerShare,
|
|
44052
|
+
decimals
|
|
44053
|
+
);
|
|
44054
|
+
const totalAssetsFormatted = Number(
|
|
44055
|
+
parseRawAmount(totalAssetsRaw, assetDecimals)
|
|
44056
|
+
);
|
|
44057
|
+
const realized = num2(v.apr?.netAPR);
|
|
44058
|
+
const forward = num2(v.apr?.forwardAPR?.netAPR);
|
|
44059
|
+
const isForwardApr = realized == null && forward != null;
|
|
44060
|
+
const supplyRate = toPct(realized ?? forward);
|
|
44061
|
+
const rewardsRate = toPct(v.apr?.extra?.stakingRewardsAPR);
|
|
44062
|
+
const fee = toPct(v.apr?.fees?.performance);
|
|
44063
|
+
const oracleKey = toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(assetAddr, chainId);
|
|
44064
|
+
const apiPrice = num2(v.tvl?.price) ?? 0;
|
|
44065
|
+
const priceUsd = prices[oracleKey] ?? prices[assetAddr] ?? apiPrice;
|
|
44066
|
+
const apiTvlUsd = num2(v.tvl?.tvl) ?? 0;
|
|
44067
|
+
const totalAssetsUsd = apiTvlUsd || totalAssetsFormatted * priceUsd;
|
|
44068
|
+
const name = (v.name ?? "").trim();
|
|
44069
|
+
const symbol = (v.symbol ?? "").trim();
|
|
44070
|
+
const displayName = composeVaultDisplayName(BRAND2, BRAND2, assetMeta, name);
|
|
44071
|
+
return {
|
|
44072
|
+
address,
|
|
44073
|
+
underlying: assetAddr,
|
|
44074
|
+
symbol,
|
|
44075
|
+
name: name || symbol,
|
|
44076
|
+
displayName,
|
|
44077
|
+
curatorName: BRAND2,
|
|
44078
|
+
decimals,
|
|
44079
|
+
assetDecimals,
|
|
44080
|
+
totalAssets: totalAssetsRaw,
|
|
44081
|
+
totalSupply: totalSupplyRaw,
|
|
44082
|
+
pricePerShare,
|
|
44083
|
+
supplyRate,
|
|
44084
|
+
rewardsRate,
|
|
44085
|
+
depositRate: supplyRate + rewardsRate,
|
|
44086
|
+
fee,
|
|
44087
|
+
isForwardApr,
|
|
44088
|
+
kind: v.kind ?? "Multi Strategy",
|
|
44089
|
+
version: v.version ?? "",
|
|
44090
|
+
...v.category ? { category: v.category } : {},
|
|
44091
|
+
asset: assetMeta,
|
|
44092
|
+
priceUsd,
|
|
44093
|
+
totalAssetsFormatted,
|
|
44094
|
+
totalAssetsUsd
|
|
44095
|
+
};
|
|
44096
|
+
}
|
|
44097
|
+
var setLiquidity = (v, liq) => {
|
|
44098
|
+
v.liquidity = liq.toString();
|
|
44099
|
+
v.liquidityFormatted = Number(parseRawAmount(v.liquidity, v.assetDecimals));
|
|
44100
|
+
v.liquidityUsd = v.priceUsd != null ? v.liquidityFormatted * v.priceUsd : v.liquidityFormatted;
|
|
44101
|
+
};
|
|
44102
|
+
var attachYearnLiquidity = async (chainId, multicallRetry, out) => {
|
|
44103
|
+
const vaults = Object.values(out);
|
|
44104
|
+
if (vaults.length === 0) return;
|
|
44105
|
+
const r1Calls = vaults.flatMap((v) => [
|
|
44106
|
+
{ address: v.address, name: "availableWithdrawLimit", params: [ZERO_ADDR] },
|
|
44107
|
+
{ address: v.address, name: "get_default_queue", params: [] },
|
|
44108
|
+
{ address: v.address, name: "totalIdle", params: [] }
|
|
44109
|
+
]);
|
|
44110
|
+
const r1 = await multicallRetry({
|
|
44111
|
+
chain: chainId,
|
|
44112
|
+
calls: r1Calls,
|
|
44113
|
+
abi: r1Calls.map(() => YearnLiquidityAbi),
|
|
44114
|
+
maxRetries: 2,
|
|
44115
|
+
allowFailure: true
|
|
44116
|
+
});
|
|
44117
|
+
const pending = [];
|
|
44118
|
+
for (let i = 0; i < vaults.length; i++) {
|
|
44119
|
+
const v = vaults[i];
|
|
44120
|
+
const totalAssets = asBig(v.totalAssets) ?? 0n;
|
|
44121
|
+
const awl = asBig(r1[i * 3]);
|
|
44122
|
+
const queueRaw = r1[i * 3 + 1];
|
|
44123
|
+
const idle = asBig(r1[i * 3 + 2]) ?? 0n;
|
|
44124
|
+
if (awl != null) {
|
|
44125
|
+
setLiquidity(v, awl >= totalAssets ? totalAssets : awl);
|
|
44126
|
+
} else if (Array.isArray(queueRaw) && queueRaw.length > 0) {
|
|
44127
|
+
pending.push({
|
|
44128
|
+
v,
|
|
44129
|
+
idle,
|
|
44130
|
+
queue: queueRaw.map((a) => String(a).toLowerCase()),
|
|
44131
|
+
totalAssets
|
|
44132
|
+
});
|
|
44133
|
+
} else if (asBig(r1[i * 3 + 2]) != null) {
|
|
44134
|
+
setLiquidity(v, idle >= totalAssets ? totalAssets : idle);
|
|
44135
|
+
}
|
|
44136
|
+
}
|
|
44137
|
+
if (pending.length === 0) return;
|
|
44138
|
+
const r2Calls = pending.flatMap(
|
|
44139
|
+
(p) => p.queue.map((s) => ({
|
|
44140
|
+
address: s,
|
|
44141
|
+
name: "maxWithdraw",
|
|
44142
|
+
params: [p.v.address]
|
|
44143
|
+
}))
|
|
44144
|
+
);
|
|
44145
|
+
const r2 = await multicallRetry({
|
|
44146
|
+
chain: chainId,
|
|
44147
|
+
calls: r2Calls,
|
|
44148
|
+
abi: r2Calls.map(() => YearnLiquidityAbi),
|
|
44149
|
+
maxRetries: 2,
|
|
44150
|
+
allowFailure: true
|
|
44151
|
+
});
|
|
44152
|
+
let idx = 0;
|
|
44153
|
+
for (const p of pending) {
|
|
44154
|
+
let sum = p.idle;
|
|
44155
|
+
for (let j = 0; j < p.queue.length; j++) {
|
|
44156
|
+
const w = asBig(r2[idx++]);
|
|
44157
|
+
if (w != null) sum += w;
|
|
44158
|
+
}
|
|
44159
|
+
setLiquidity(p.v, sum >= p.totalAssets ? p.totalAssets : sum);
|
|
44160
|
+
}
|
|
44161
|
+
};
|
|
44162
|
+
var fetchYearnVaults = async (chainId, multicallRetry, prices = {}, tokenList = {}) => {
|
|
44163
|
+
if (!hasYearnVaults(chainId)) return {};
|
|
44164
|
+
const items = await fetchYearnApiVaults(chainId);
|
|
44165
|
+
const out = {};
|
|
43728
44166
|
for (const item of items) {
|
|
43729
44167
|
const parsed = parseVault8(item, chainId, prices, tokenList);
|
|
43730
44168
|
if (parsed) out[parsed.address] = parsed;
|
|
43731
44169
|
}
|
|
44170
|
+
try {
|
|
44171
|
+
await attachYearnLiquidity(chainId, multicallRetry, out);
|
|
44172
|
+
} catch {
|
|
44173
|
+
}
|
|
43732
44174
|
return out;
|
|
43733
44175
|
};
|
|
43734
44176
|
|
|
@@ -44015,6 +44457,7 @@ var stampVaultClassification = (data, chainId) => {
|
|
|
44015
44457
|
stampBag(data.lst, "lst");
|
|
44016
44458
|
stampBag(data.savings, "savings");
|
|
44017
44459
|
stampBag(data.lagoon, "lagoon");
|
|
44460
|
+
stampBag(data.yearn, "yearn");
|
|
44018
44461
|
};
|
|
44019
44462
|
|
|
44020
44463
|
// src/vaults/gmx/registry.ts
|
|
@@ -44277,10 +44720,13 @@ var GmxDataStoreAbi = [
|
|
|
44277
44720
|
outputs: [{ name: "", type: "bytes32[]" }]
|
|
44278
44721
|
}
|
|
44279
44722
|
];
|
|
44280
|
-
var priceProps = {
|
|
44281
|
-
|
|
44282
|
-
|
|
44283
|
-
|
|
44723
|
+
var priceProps = {
|
|
44724
|
+
type: "tuple",
|
|
44725
|
+
components: [
|
|
44726
|
+
{ name: "min", type: "uint256" },
|
|
44727
|
+
{ name: "max", type: "uint256" }
|
|
44728
|
+
]
|
|
44729
|
+
};
|
|
44284
44730
|
var GmxPricingAbi = [
|
|
44285
44731
|
{
|
|
44286
44732
|
name: "getMarketTokenPrice",
|
|
@@ -44393,6 +44839,15 @@ var GmxErc20BalanceAbi = [
|
|
|
44393
44839
|
outputs: [{ name: "", type: "uint256" }]
|
|
44394
44840
|
}
|
|
44395
44841
|
];
|
|
44842
|
+
var GmxGlvTokenBalancesAbi = [
|
|
44843
|
+
{
|
|
44844
|
+
name: "tokenBalances",
|
|
44845
|
+
type: "function",
|
|
44846
|
+
stateMutability: "view",
|
|
44847
|
+
inputs: [{ name: "token", type: "address" }],
|
|
44848
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
44849
|
+
}
|
|
44850
|
+
];
|
|
44396
44851
|
|
|
44397
44852
|
// src/vaults/gmx/contracts.ts
|
|
44398
44853
|
var GMX_READ_CONTRACTS = {
|
|
@@ -44421,7 +44876,9 @@ var accountListKey = (listConstant, account) => keccak256(
|
|
|
44421
44876
|
);
|
|
44422
44877
|
var accountDepositListKey = (account) => accountListKey(ACCOUNT_DEPOSIT_LIST, account);
|
|
44423
44878
|
var accountWithdrawalListKey = (account) => accountListKey(ACCOUNT_WITHDRAWAL_LIST, account);
|
|
44424
|
-
var MAX_PNL_FACTOR_FOR_TRADERS = hashString(
|
|
44879
|
+
var MAX_PNL_FACTOR_FOR_TRADERS = hashString(
|
|
44880
|
+
"MAX_PNL_FACTOR_FOR_TRADERS"
|
|
44881
|
+
);
|
|
44425
44882
|
var GMX_GAS_KEYS = {
|
|
44426
44883
|
estimatedGasFeeBaseAmount: hashString("EXECUTION_GAS_FEE_BASE_AMOUNT_V2_1"),
|
|
44427
44884
|
estimatedGasFeeMultiplierFactor: hashString(
|
|
@@ -44433,9 +44890,50 @@ var GMX_GAS_KEYS = {
|
|
|
44433
44890
|
glvWithdrawalGasLimit: hashString("GLV_WITHDRAWAL_GAS_LIMIT"),
|
|
44434
44891
|
glvPerMarketGasLimit: hashString("GLV_PER_MARKET_GAS_LIMIT")
|
|
44435
44892
|
};
|
|
44893
|
+
var MAX_POOL_AMOUNT = hashString("MAX_POOL_AMOUNT");
|
|
44894
|
+
var MAX_POOL_USD_FOR_DEPOSIT = hashString("MAX_POOL_USD_FOR_DEPOSIT");
|
|
44895
|
+
var GLV_MAX_MARKET_TOKEN_BALANCE_USD = hashString(
|
|
44896
|
+
"GLV_MAX_MARKET_TOKEN_BALANCE_USD"
|
|
44897
|
+
);
|
|
44898
|
+
var GLV_MAX_MARKET_TOKEN_BALANCE_AMOUNT = hashString(
|
|
44899
|
+
"GLV_MAX_MARKET_TOKEN_BALANCE_AMOUNT"
|
|
44900
|
+
);
|
|
44901
|
+
var marketTokenKey = (base, market, token) => keccak256(
|
|
44902
|
+
encodeAbiParameters(
|
|
44903
|
+
[{ type: "bytes32" }, { type: "address" }, { type: "address" }],
|
|
44904
|
+
[base, market, token]
|
|
44905
|
+
)
|
|
44906
|
+
);
|
|
44907
|
+
var maxPoolAmountKey = (market, token) => marketTokenKey(MAX_POOL_AMOUNT, market, token);
|
|
44908
|
+
var maxPoolUsdForDepositKey = (market, token) => marketTokenKey(MAX_POOL_USD_FOR_DEPOSIT, market, token);
|
|
44909
|
+
var glvMaxMarketTokenBalanceUsdKey = (glv, market) => marketTokenKey(GLV_MAX_MARKET_TOKEN_BALANCE_USD, glv, market);
|
|
44910
|
+
var glvMaxMarketTokenBalanceAmountKey = (glv, market) => marketTokenKey(GLV_MAX_MARKET_TOKEN_BALANCE_AMOUNT, glv, market);
|
|
44911
|
+
var OPEN_INTEREST = hashString("OPEN_INTEREST");
|
|
44912
|
+
var OPEN_INTEREST_IN_TOKENS = hashString("OPEN_INTEREST_IN_TOKENS");
|
|
44913
|
+
var RESERVE_FACTOR = hashString("RESERVE_FACTOR");
|
|
44914
|
+
var marketCollateralKey = (base, market, collateralToken, isLong) => keccak256(
|
|
44915
|
+
encodeAbiParameters(
|
|
44916
|
+
[
|
|
44917
|
+
{ type: "bytes32" },
|
|
44918
|
+
{ type: "address" },
|
|
44919
|
+
{ type: "address" },
|
|
44920
|
+
{ type: "bool" }
|
|
44921
|
+
],
|
|
44922
|
+
[base, market, collateralToken, isLong]
|
|
44923
|
+
)
|
|
44924
|
+
);
|
|
44925
|
+
var openInterestKey = (market, collateralToken, isLong) => marketCollateralKey(OPEN_INTEREST, market, collateralToken, isLong);
|
|
44926
|
+
var openInterestInTokensKey = (market, collateralToken, isLong) => marketCollateralKey(OPEN_INTEREST_IN_TOKENS, market, collateralToken, isLong);
|
|
44927
|
+
var reserveFactorKey = (market, isLong) => keccak256(
|
|
44928
|
+
encodeAbiParameters(
|
|
44929
|
+
[{ type: "bytes32" }, { type: "address" }, { type: "bool" }],
|
|
44930
|
+
[RESERVE_FACTOR, market, isLong]
|
|
44931
|
+
)
|
|
44932
|
+
);
|
|
44436
44933
|
|
|
44437
44934
|
// src/vaults/gmx/pricing.ts
|
|
44438
44935
|
var USD_1E30 = 1e30;
|
|
44936
|
+
var USD_1E30N = 10n ** 30n;
|
|
44439
44937
|
var GLV_NOMINAL_MARKET_COUNT = 20n;
|
|
44440
44938
|
var toUsd = (v) => typeof v === "bigint" ? Number(v) / USD_1E30 : 0;
|
|
44441
44939
|
var fetchGmxTickerPrices = async (chainId, apiUrlOverride) => {
|
|
@@ -44485,36 +44983,124 @@ var priceGmMarkets = async (chainId, multicallRetry, markets, prices) => {
|
|
|
44485
44983
|
false
|
|
44486
44984
|
]
|
|
44487
44985
|
}));
|
|
44488
|
-
|
|
44489
|
-
|
|
44490
|
-
|
|
44986
|
+
const SLOTS = 10;
|
|
44987
|
+
const dsCalls = priced.flatMap((m) => {
|
|
44988
|
+
const market = m.marketToken;
|
|
44989
|
+
const long = m.longToken;
|
|
44990
|
+
const short = m.shortToken;
|
|
44991
|
+
const get = (key) => ({
|
|
44992
|
+
address: c.dataStore,
|
|
44993
|
+
name: "getUint",
|
|
44994
|
+
params: [key]
|
|
44995
|
+
});
|
|
44996
|
+
return [
|
|
44997
|
+
get(maxPoolAmountKey(market, long)),
|
|
44998
|
+
get(maxPoolAmountKey(market, short)),
|
|
44999
|
+
get(maxPoolUsdForDepositKey(market, long)),
|
|
45000
|
+
get(maxPoolUsdForDepositKey(market, short)),
|
|
45001
|
+
get(openInterestInTokensKey(market, long, true)),
|
|
45002
|
+
get(openInterestInTokensKey(market, short, true)),
|
|
45003
|
+
get(openInterestKey(market, long, false)),
|
|
45004
|
+
get(openInterestKey(market, short, false)),
|
|
45005
|
+
get(reserveFactorKey(market, true)),
|
|
45006
|
+
get(reserveFactorKey(market, false))
|
|
45007
|
+
];
|
|
45008
|
+
});
|
|
45009
|
+
const [res, dsRes] = await Promise.all([
|
|
45010
|
+
multicallRetry({
|
|
44491
45011
|
chain: chainId,
|
|
44492
45012
|
calls,
|
|
44493
45013
|
abi: GmxPricingAbi,
|
|
44494
45014
|
maxRetries: 3,
|
|
44495
45015
|
allowFailure: true
|
|
44496
|
-
})
|
|
44497
|
-
|
|
44498
|
-
|
|
44499
|
-
|
|
45016
|
+
}).catch(() => null),
|
|
45017
|
+
multicallRetry({
|
|
45018
|
+
chain: chainId,
|
|
45019
|
+
calls: dsCalls,
|
|
45020
|
+
abi: GmxDataStoreUintAbi,
|
|
45021
|
+
maxRetries: 3,
|
|
45022
|
+
allowFailure: true
|
|
45023
|
+
}).catch(() => null)
|
|
45024
|
+
]);
|
|
45025
|
+
if (!Array.isArray(res)) return out;
|
|
44500
45026
|
priced.forEach((m, i) => {
|
|
44501
45027
|
const r = res[i];
|
|
44502
45028
|
if (!Array.isArray(r)) return;
|
|
45029
|
+
const info = r[1];
|
|
44503
45030
|
const tokenPrice = r[0];
|
|
44504
|
-
const poolValue =
|
|
45031
|
+
const poolValue = info?.poolValue;
|
|
44505
45032
|
if (typeof tokenPrice !== "bigint") return;
|
|
44506
|
-
|
|
45033
|
+
const value = {
|
|
44507
45034
|
priceUsd: toUsd(tokenPrice),
|
|
44508
45035
|
tvlUsd: toUsd(poolValue)
|
|
44509
|
-
}
|
|
45036
|
+
};
|
|
45037
|
+
const longMax = price(prices, m.longToken)?.max;
|
|
45038
|
+
const shortMax = price(prices, m.shortToken)?.max;
|
|
45039
|
+
const indexMax = price(prices, m.indexToken)?.max;
|
|
45040
|
+
if (Array.isArray(dsRes) && longMax != null && shortMax != null) {
|
|
45041
|
+
const base = i * SLOTS;
|
|
45042
|
+
const big = (j) => typeof dsRes[base + j] === "bigint" ? dsRes[base + j] : 0n;
|
|
45043
|
+
const cap = computeDepositCapacityUsd(
|
|
45044
|
+
[info?.longTokenAmount, longMax, big(0), big(2)],
|
|
45045
|
+
[info?.shortTokenAmount, shortMax, big(1), big(3)]
|
|
45046
|
+
);
|
|
45047
|
+
if (cap != null) value.depositCapacityUsd = cap;
|
|
45048
|
+
if (indexMax != null) {
|
|
45049
|
+
const divisor = m.longToken.toLowerCase() === m.shortToken.toLowerCase() ? 2n : 1n;
|
|
45050
|
+
const reservedUsdLong = (big(4) + big(5)) / divisor * indexMax;
|
|
45051
|
+
const reservedUsdShort = (big(6) + big(7)) / divisor;
|
|
45052
|
+
const liq = computeLiquidityUsd(
|
|
45053
|
+
info?.longTokenUsd,
|
|
45054
|
+
info?.shortTokenUsd,
|
|
45055
|
+
reservedUsdLong,
|
|
45056
|
+
reservedUsdShort,
|
|
45057
|
+
big(8),
|
|
45058
|
+
big(9)
|
|
45059
|
+
);
|
|
45060
|
+
if (liq != null)
|
|
45061
|
+
value.liquidityUsd = Math.max(0, Math.min(liq, value.tvlUsd));
|
|
45062
|
+
}
|
|
45063
|
+
}
|
|
45064
|
+
out.set(m.marketToken.toLowerCase(), value);
|
|
44510
45065
|
});
|
|
44511
45066
|
return out;
|
|
44512
45067
|
};
|
|
45068
|
+
var computeLiquidityUsd = (poolUsdLong, poolUsdShort, reservedUsdLong, reservedUsdShort, reserveFactorLong, reserveFactorShort) => {
|
|
45069
|
+
if (typeof poolUsdLong !== "bigint" || typeof poolUsdShort !== "bigint")
|
|
45070
|
+
return void 0;
|
|
45071
|
+
const side = (pool, reserved, rf) => {
|
|
45072
|
+
const floor = rf > 0n ? reserved * USD_1E30N / rf : 0n;
|
|
45073
|
+
const avail = pool - floor;
|
|
45074
|
+
return avail > 0n ? avail : 0n;
|
|
45075
|
+
};
|
|
45076
|
+
const total = side(poolUsdLong, reservedUsdLong, reserveFactorLong) + side(poolUsdShort, reservedUsdShort, reserveFactorShort);
|
|
45077
|
+
return toUsd(total);
|
|
45078
|
+
};
|
|
45079
|
+
var computeDepositCapacityUsd = (long, short) => {
|
|
45080
|
+
const INF = -1n;
|
|
45081
|
+
const side = ([poolAmount, priceMax, maxAmount, maxUsd]) => {
|
|
45082
|
+
if (typeof poolAmount !== "bigint") return void 0;
|
|
45083
|
+
const poolUsd = poolAmount * priceMax;
|
|
45084
|
+
const amountRoom = maxAmount > 0n ? (maxAmount > poolAmount ? maxAmount - poolAmount : 0n) * priceMax : INF;
|
|
45085
|
+
const usdRoom = maxUsd > 0n ? maxUsd > poolUsd ? maxUsd - poolUsd : 0n : INF;
|
|
45086
|
+
if (amountRoom === INF && usdRoom === INF) return void 0;
|
|
45087
|
+
if (amountRoom === INF) return usdRoom;
|
|
45088
|
+
if (usdRoom === INF) return amountRoom;
|
|
45089
|
+
return amountRoom < usdRoom ? amountRoom : usdRoom;
|
|
45090
|
+
};
|
|
45091
|
+
const l = side(long);
|
|
45092
|
+
const s = side(short);
|
|
45093
|
+
if (l == null && s == null) return void 0;
|
|
45094
|
+
return toUsd((l ?? 0n) + (s ?? 0n));
|
|
45095
|
+
};
|
|
44513
45096
|
var priceGlvVaults = async (chainId, multicallRetry, glvTokens, prices, marketIndexToken) => {
|
|
44514
45097
|
const values = /* @__PURE__ */ new Map();
|
|
45098
|
+
const glvMarkets = /* @__PURE__ */ new Map();
|
|
45099
|
+
const glvCaps = /* @__PURE__ */ new Map();
|
|
44515
45100
|
let maxMarketCount = 0;
|
|
44516
45101
|
const c = getGmxReadContracts(chainId);
|
|
44517
|
-
if (!c || glvTokens.length === 0)
|
|
45102
|
+
if (!c || glvTokens.length === 0)
|
|
45103
|
+
return { values, maxMarketCount, glvMarkets, glvCaps };
|
|
44518
45104
|
let infos;
|
|
44519
45105
|
try {
|
|
44520
45106
|
infos = await multicallRetry({
|
|
@@ -44529,7 +45115,7 @@ var priceGlvVaults = async (chainId, multicallRetry, glvTokens, prices, marketIn
|
|
|
44529
45115
|
allowFailure: true
|
|
44530
45116
|
});
|
|
44531
45117
|
} catch {
|
|
44532
|
-
return { values, maxMarketCount };
|
|
45118
|
+
return { values, maxMarketCount, glvMarkets, glvCaps };
|
|
44533
45119
|
}
|
|
44534
45120
|
const calls = [];
|
|
44535
45121
|
const priceable = [];
|
|
@@ -44540,6 +45126,10 @@ var priceGlvVaults = async (chainId, multicallRetry, glvTokens, prices, marketIn
|
|
|
44540
45126
|
const markets = Array.isArray(info?.markets) ? info.markets : [];
|
|
44541
45127
|
if (!long || !short || markets.length === 0) return;
|
|
44542
45128
|
maxMarketCount = Math.max(maxMarketCount, markets.length);
|
|
45129
|
+
glvMarkets.set(
|
|
45130
|
+
glv.toLowerCase(),
|
|
45131
|
+
markets.map((m) => m.toLowerCase())
|
|
45132
|
+
);
|
|
44543
45133
|
const lp = price(prices, long);
|
|
44544
45134
|
const sp = price(prices, short);
|
|
44545
45135
|
if (!lp || !sp) return;
|
|
@@ -44562,19 +45152,62 @@ var priceGlvVaults = async (chainId, multicallRetry, glvTokens, prices, marketIn
|
|
|
44562
45152
|
});
|
|
44563
45153
|
priceable.push(glv);
|
|
44564
45154
|
});
|
|
44565
|
-
if (calls.length === 0) return { values, maxMarketCount };
|
|
44566
|
-
|
|
44567
|
-
|
|
44568
|
-
|
|
45155
|
+
if (calls.length === 0) return { values, maxMarketCount, glvMarkets, glvCaps };
|
|
45156
|
+
const pairs = [];
|
|
45157
|
+
for (const [glv, markets] of glvMarkets)
|
|
45158
|
+
for (const market of markets) pairs.push({ glv, market });
|
|
45159
|
+
const [res, capRes, balRes] = await Promise.all([
|
|
45160
|
+
multicallRetry({
|
|
44569
45161
|
chain: chainId,
|
|
44570
45162
|
calls,
|
|
44571
45163
|
abi: GmxGlvPricingAbi,
|
|
44572
45164
|
maxRetries: 3,
|
|
44573
45165
|
allowFailure: true
|
|
44574
|
-
})
|
|
44575
|
-
|
|
44576
|
-
|
|
44577
|
-
|
|
45166
|
+
}).catch(() => null),
|
|
45167
|
+
// Two caps per pair, interleaved: [maxBalUsd, maxBalAmount].
|
|
45168
|
+
pairs.length ? multicallRetry({
|
|
45169
|
+
chain: chainId,
|
|
45170
|
+
calls: pairs.flatMap(({ glv, market }) => [
|
|
45171
|
+
{
|
|
45172
|
+
address: c.dataStore,
|
|
45173
|
+
name: "getUint",
|
|
45174
|
+
params: [
|
|
45175
|
+
glvMaxMarketTokenBalanceUsdKey(
|
|
45176
|
+
glv,
|
|
45177
|
+
market
|
|
45178
|
+
)
|
|
45179
|
+
]
|
|
45180
|
+
},
|
|
45181
|
+
{
|
|
45182
|
+
address: c.dataStore,
|
|
45183
|
+
name: "getUint",
|
|
45184
|
+
params: [
|
|
45185
|
+
glvMaxMarketTokenBalanceAmountKey(
|
|
45186
|
+
glv,
|
|
45187
|
+
market
|
|
45188
|
+
)
|
|
45189
|
+
]
|
|
45190
|
+
}
|
|
45191
|
+
]),
|
|
45192
|
+
abi: GmxDataStoreUintAbi,
|
|
45193
|
+
maxRetries: 3,
|
|
45194
|
+
allowFailure: true
|
|
45195
|
+
}).catch(() => null) : Promise.resolve(null),
|
|
45196
|
+
// GLV's internally-tracked GM balance for each market (`tokenBalances`).
|
|
45197
|
+
pairs.length ? multicallRetry({
|
|
45198
|
+
chain: chainId,
|
|
45199
|
+
calls: pairs.map(({ glv, market }) => ({
|
|
45200
|
+
address: glv,
|
|
45201
|
+
name: "tokenBalances",
|
|
45202
|
+
params: [market]
|
|
45203
|
+
})),
|
|
45204
|
+
abi: GmxGlvTokenBalancesAbi,
|
|
45205
|
+
maxRetries: 3,
|
|
45206
|
+
allowFailure: true
|
|
45207
|
+
}).catch(() => null) : Promise.resolve(null)
|
|
45208
|
+
]);
|
|
45209
|
+
if (!Array.isArray(res))
|
|
45210
|
+
return { values, maxMarketCount, glvMarkets, glvCaps };
|
|
44578
45211
|
priceable.forEach((glv, i) => {
|
|
44579
45212
|
const r = res[i];
|
|
44580
45213
|
if (!Array.isArray(r) || typeof r[0] !== "bigint") return;
|
|
@@ -44583,7 +45216,15 @@ var priceGlvVaults = async (chainId, multicallRetry, glvTokens, prices, marketIn
|
|
|
44583
45216
|
tvlUsd: toUsd(r[1])
|
|
44584
45217
|
});
|
|
44585
45218
|
});
|
|
44586
|
-
|
|
45219
|
+
pairs.forEach(({ glv, market }, i) => {
|
|
45220
|
+
const maxBalUsd = Array.isArray(capRes) && typeof capRes[i * 2] === "bigint" ? capRes[i * 2] : 0n;
|
|
45221
|
+
const maxBalAmount = Array.isArray(capRes) && typeof capRes[i * 2 + 1] === "bigint" ? capRes[i * 2 + 1] : 0n;
|
|
45222
|
+
const balanceAmount = Array.isArray(balRes) && typeof balRes[i] === "bigint" ? balRes[i] : 0n;
|
|
45223
|
+
const list = glvCaps.get(glv) ?? [];
|
|
45224
|
+
list.push({ market, maxBalUsd, maxBalAmount, balanceAmount });
|
|
45225
|
+
glvCaps.set(glv, list);
|
|
45226
|
+
});
|
|
45227
|
+
return { values, maxMarketCount, glvMarkets, glvCaps };
|
|
44587
45228
|
};
|
|
44588
45229
|
var fetchGmxExecutionFees = async (chainId, multicallRetry, gasPriceWei) => {
|
|
44589
45230
|
const c = getGmxReadContracts(chainId);
|
|
@@ -44601,7 +45242,11 @@ var fetchGmxExecutionFees = async (chainId, multicallRetry, gasPriceWei) => {
|
|
|
44601
45242
|
try {
|
|
44602
45243
|
res = await multicallRetry({
|
|
44603
45244
|
chain: chainId,
|
|
44604
|
-
calls: keys.map((key) => ({
|
|
45245
|
+
calls: keys.map((key) => ({
|
|
45246
|
+
address: c.dataStore,
|
|
45247
|
+
name: "getUint",
|
|
45248
|
+
params: [key]
|
|
45249
|
+
})),
|
|
44605
45250
|
abi: GmxDataStoreUintAbi,
|
|
44606
45251
|
maxRetries: 3,
|
|
44607
45252
|
allowFailure: true
|
|
@@ -44630,7 +45275,14 @@ var fetchGmxExecutionFees = async (chainId, multicallRetry, gasPriceWei) => {
|
|
|
44630
45275
|
// src/vaults/gmx/fetchPublic.ts
|
|
44631
45276
|
var GMX_TOKEN_DECIMALS = 18;
|
|
44632
45277
|
var DEFAULT_PERIOD = "90d";
|
|
44633
|
-
var
|
|
45278
|
+
var num3 = (n) => typeof n === "number" && Number.isFinite(n) ? n : 0;
|
|
45279
|
+
var minDefined = (a, b) => a == null ? b : b == null ? a : Math.min(a, b);
|
|
45280
|
+
var glvMarketRoomUsd = (cap, priceUsd) => {
|
|
45281
|
+
const currentUsd = Number(cap.balanceAmount) / 1e18 * priceUsd;
|
|
45282
|
+
const usdRoom = cap.maxBalUsd > 0n ? Math.max(0, Number(cap.maxBalUsd) / 1e30 - currentUsd) : void 0;
|
|
45283
|
+
const amountRoom = cap.maxBalAmount > 0n ? Math.max(0, Number(cap.maxBalAmount - cap.balanceAmount) / 1e18) * priceUsd : void 0;
|
|
45284
|
+
return minDefined(usdRoom, amountRoom);
|
|
45285
|
+
};
|
|
44634
45286
|
var denominationFor = (longSymbol, shortSymbol) => isStablecoinSymbol(longSymbol) && isStablecoinSymbol(shortSymbol) ? "stable" : "volatile";
|
|
44635
45287
|
var fetchGmxVaults = async (chainId, multicallRetry, options) => {
|
|
44636
45288
|
if (!options?.apiUrl && !getGmxApiHost(chainId)) return {};
|
|
@@ -44657,9 +45309,9 @@ var fetchGmxVaults = async (chainId, multicallRetry, options) => {
|
|
|
44657
45309
|
indexToken: indexToken ? indexToken.toLowerCase() : void 0,
|
|
44658
45310
|
longSymbol,
|
|
44659
45311
|
shortSymbol,
|
|
44660
|
-
apy:
|
|
44661
|
-
baseApy:
|
|
44662
|
-
bonusApr:
|
|
45312
|
+
apy: num3(entry?.apy),
|
|
45313
|
+
baseApy: num3(entry?.baseApy),
|
|
45314
|
+
bonusApr: num3(entry?.bonusApr),
|
|
44663
45315
|
yieldProfile: "volatile",
|
|
44664
45316
|
denomination: denominationFor(longSymbol, shortSymbol)
|
|
44665
45317
|
};
|
|
@@ -44723,14 +45375,42 @@ var fetchGmxVaults = async (chainId, multicallRetry, options) => {
|
|
|
44723
45375
|
if (e) {
|
|
44724
45376
|
e.priceUsd = v.priceUsd;
|
|
44725
45377
|
e.tvlUsd = v.tvlUsd;
|
|
45378
|
+
e.liquidityUsd = v.liquidityUsd;
|
|
45379
|
+
e.depositCapacityUsd = v.depositCapacityUsd;
|
|
44726
45380
|
}
|
|
44727
45381
|
}
|
|
44728
45382
|
for (const [addr, v] of glv.values) {
|
|
44729
45383
|
const e = out[addr];
|
|
44730
|
-
if (e)
|
|
44731
|
-
|
|
44732
|
-
|
|
45384
|
+
if (!e) continue;
|
|
45385
|
+
e.priceUsd = v.priceUsd;
|
|
45386
|
+
e.tvlUsd = v.tvlUsd;
|
|
45387
|
+
const markets2 = glv.glvMarkets.get(addr) ?? [];
|
|
45388
|
+
let liqSum = 0;
|
|
45389
|
+
let tvlSum = 0;
|
|
45390
|
+
for (const m of markets2) {
|
|
45391
|
+
const gv = gmValues.get(m);
|
|
45392
|
+
if (gv?.liquidityUsd != null && gv.tvlUsd != null) {
|
|
45393
|
+
liqSum += gv.liquidityUsd;
|
|
45394
|
+
tvlSum += gv.tvlUsd;
|
|
45395
|
+
}
|
|
44733
45396
|
}
|
|
45397
|
+
if (tvlSum > 0 && v.tvlUsd != null)
|
|
45398
|
+
e.liquidityUsd = v.tvlUsd * (liqSum / tvlSum);
|
|
45399
|
+
const caps = glv.glvCaps.get(addr) ?? [];
|
|
45400
|
+
let capacity = 0;
|
|
45401
|
+
let known = false;
|
|
45402
|
+
for (const cap of caps) {
|
|
45403
|
+
const gv = gmValues.get(cap.market);
|
|
45404
|
+
if (!gv) continue;
|
|
45405
|
+
const marketRoom = gv.depositCapacityUsd;
|
|
45406
|
+
const glvRoom = glvMarketRoomUsd(cap, gv.priceUsd);
|
|
45407
|
+
const room = minDefined(marketRoom, glvRoom);
|
|
45408
|
+
if (room != null) {
|
|
45409
|
+
capacity += room;
|
|
45410
|
+
known = true;
|
|
45411
|
+
}
|
|
45412
|
+
}
|
|
45413
|
+
if (known) e.depositCapacityUsd = capacity;
|
|
44734
45414
|
}
|
|
44735
45415
|
}
|
|
44736
45416
|
} catch {
|
|
@@ -45051,6 +45731,7 @@ function buildVaultLookup(data) {
|
|
|
45051
45731
|
addEntries(data.lst, "lst");
|
|
45052
45732
|
addEntries(data.savings, "savings");
|
|
45053
45733
|
addEntries(data.lagoon, "lagoon");
|
|
45734
|
+
addEntries(data.yearn, "yearn");
|
|
45054
45735
|
return map;
|
|
45055
45736
|
}
|
|
45056
45737
|
var warn4 = (...args) => {
|
|
@@ -45172,6 +45853,18 @@ var getVaultPublicDataAll = async (chainId, providers, multicallRetry, prices =
|
|
|
45172
45853
|
})
|
|
45173
45854
|
);
|
|
45174
45855
|
}
|
|
45856
|
+
if (requested.has("yearn")) {
|
|
45857
|
+
tasks.push(
|
|
45858
|
+
fetchYearnVaults(chainId, multicallRetry, prices, tokenList).then((res) => {
|
|
45859
|
+
out.yearn = res;
|
|
45860
|
+
}).catch((e) => {
|
|
45861
|
+
warn4(
|
|
45862
|
+
`[vaults] yearn fetch failed for chain ${chainId}:`,
|
|
45863
|
+
e?.message ?? e
|
|
45864
|
+
);
|
|
45865
|
+
})
|
|
45866
|
+
);
|
|
45867
|
+
}
|
|
45175
45868
|
if (requested.has("hypercore") && chainId === HYPERCORE_PROVIDER_CHAIN) {
|
|
45176
45869
|
tasks.push(
|
|
45177
45870
|
fetchHypercoreVaults().then((res) => {
|
|
@@ -45752,6 +46445,6 @@ async function fetchTokenBalances(chainId, account, tokens, options = {}) {
|
|
|
45752
46445
|
return parseTokenBalanceResult(rawResult, prepared.query);
|
|
45753
46446
|
}
|
|
45754
46447
|
|
|
45755
|
-
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,
|
|
46448
|
+
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 };
|
|
45756
46449
|
//# sourceMappingURL=index.js.map
|
|
45757
46450
|
//# sourceMappingURL=index.js.map
|