@1delta/margin-fetcher 0.0.271 → 0.0.273
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +350 -114
- package/dist/index.js.map +1 -1
- package/dist/lending/user-data/morpho/userCallBuild.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/exposure.d.ts +7 -0
- package/dist/vaults/exposure.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/morpho/allocationWalk.d.ts +51 -0
- package/dist/vaults/morpho/allocationWalk.d.ts.map +1 -0
- 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 +12 -11
- package/dist/vaults/morpho/fetchPublic.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { Lender, isAaveType, isCompoundV3, isMultiMarket, isSiloV2Type, isSiloV3
|
|
|
5
5
|
export { isAaveType, isAaveV2Type, isAaveV32Type, isAaveV3Type, isCompoundV3, isCompoundV3Type, isInit, isMorphoType, isMultiMarket, isYLDR } from '@1delta/lender-registry';
|
|
6
6
|
import lodash from 'lodash';
|
|
7
7
|
import { getEvmChain, getEvmClient, getEvmClientUniversal, multicallRetryUniversal, getEvmClientWithCustomRpcsUniversal } from '@1delta/providers';
|
|
8
|
-
import { FluidLendingResolverAbi, FluidVaultResolverAbi, MetaMorphoAbi, MoolahVaultAbi,
|
|
8
|
+
import { FluidLendingResolverAbi, FluidVaultResolverAbi, MetaMorphoAbi, MoolahVaultAbi, MorphoLensAbi, AaveV4SpokeAbi, AaveV4OracleAbi, AaveV4HubAbi, DolomiteMarginAbi, GearboxMarketCompressorV310Abi, MorphoBlueAbi, GearboxCreditAccountCompressorV310Abi } from '@1delta/abis';
|
|
9
9
|
export { MorphoLensAbi } from '@1delta/abis';
|
|
10
10
|
import { prepareDebitDataMulticall, prepareLenderDebitMulticall, parseDebitDataResult, parseLenderDebitResult, getPermit2ContractAddress, getCompoundV3CometAddress as getCompoundV3CometAddress$1, getMorphoAddress, getAaveCollateralTokenAddress, getSiloHalfForUnderlying, InitMarginAddresses, getLstAcceptedInputs } from '@1delta/calldata-sdk';
|
|
11
11
|
import { proxyNativeFetch } from '@1delta/proxy-fetch';
|
|
@@ -11123,7 +11123,8 @@ var MORPHO_LENS = {
|
|
|
11123
11123
|
[Chain.CORN]: "0x8E24CfC19c6C00c524353CB8816f5f1c2F33c201",
|
|
11124
11124
|
[Chain.LISK]: "0x8E24CfC19c6C00c524353CB8816f5f1c2F33c201",
|
|
11125
11125
|
[Chain.ABSTRACT]: "0x8e24cfc19c6c00c524353cb8816f5f1c2f33c201",
|
|
11126
|
-
[Chain.INK]: "0x0bd7473CbBf81d9dD936c61117eD230d95006CA2"
|
|
11126
|
+
[Chain.INK]: "0x0bd7473CbBf81d9dD936c61117eD230d95006CA2",
|
|
11127
|
+
[Chain.KAIA_MAINNET]: "0x925716D57c842B50806884EDb295bA3E3A8EBdFE"
|
|
11127
11128
|
};
|
|
11128
11129
|
var buildMorphoUserCallWithLens = (chainId, account, lender, marketsToQuery) => {
|
|
11129
11130
|
const marketSlices = chunk(marketsToQuery, 100);
|
|
@@ -36218,14 +36219,93 @@ async function fetchMorphoVaultsFromSubgraph(chainId, prices = {}, tokenList = {
|
|
|
36218
36219
|
}
|
|
36219
36220
|
return out;
|
|
36220
36221
|
}
|
|
36221
|
-
|
|
36222
|
-
|
|
36223
|
-
|
|
36224
|
-
|
|
36225
|
-
|
|
36222
|
+
var marketUidFor = (ctx, marketId) => {
|
|
36223
|
+
if (!ctx?.underlying) return void 0;
|
|
36224
|
+
try {
|
|
36225
|
+
return createMarketUid(
|
|
36226
|
+
ctx.chainId,
|
|
36227
|
+
`${ctx.protocol}_${marketId.slice(2).toUpperCase()}`,
|
|
36228
|
+
ctx.underlying
|
|
36229
|
+
);
|
|
36230
|
+
} catch {
|
|
36231
|
+
return void 0;
|
|
36226
36232
|
}
|
|
36227
|
-
return fetchMorphoVaultsFromApi(chainId, prices, tokenList);
|
|
36228
36233
|
};
|
|
36234
|
+
async function fetchVaultSupplyShares(chainId, core, entries, marketIdsByVault, multicallRetry) {
|
|
36235
|
+
const map = /* @__PURE__ */ new Map();
|
|
36236
|
+
if (!core) return map;
|
|
36237
|
+
const calls = [];
|
|
36238
|
+
const keys = [];
|
|
36239
|
+
entries.forEach((entry, i) => {
|
|
36240
|
+
const vault = entry.vault.toLowerCase();
|
|
36241
|
+
for (const id of marketIdsByVault[i]) {
|
|
36242
|
+
calls.push({ address: core, name: "position", params: [id, entry.vault] });
|
|
36243
|
+
keys.push(`${vault}:${id}`);
|
|
36244
|
+
}
|
|
36245
|
+
});
|
|
36246
|
+
if (calls.length === 0) return map;
|
|
36247
|
+
const res = await multicallRetry({
|
|
36248
|
+
chain: chainId,
|
|
36249
|
+
calls,
|
|
36250
|
+
abi: calls.map(() => MorphoBlueAbi),
|
|
36251
|
+
allowFailure: true
|
|
36252
|
+
});
|
|
36253
|
+
res.forEach((r, k) => {
|
|
36254
|
+
const supplyShares = Array.isArray(r) ? r[0] : r?.supplyShares;
|
|
36255
|
+
if (supplyShares == null) return;
|
|
36256
|
+
try {
|
|
36257
|
+
map.set(keys[k], BigInt(supplyShares));
|
|
36258
|
+
} catch {
|
|
36259
|
+
}
|
|
36260
|
+
});
|
|
36261
|
+
return map;
|
|
36262
|
+
}
|
|
36263
|
+
function computeVaultAllocation(vaultAddress, decimals, totalAssetsFormatted, feePercent, priceUsd, marketIds, rateMap, positionMap, tokenList, uidCtx) {
|
|
36264
|
+
if (totalAssetsFormatted <= 0) {
|
|
36265
|
+
return { depositRate: 0, exposures: [] };
|
|
36266
|
+
}
|
|
36267
|
+
if (marketIds.length === 0) {
|
|
36268
|
+
return {
|
|
36269
|
+
depositRate: 0,
|
|
36270
|
+
exposures: withIdleExposure([], totalAssetsFormatted, priceUsd)
|
|
36271
|
+
};
|
|
36272
|
+
}
|
|
36273
|
+
let weighted = 0;
|
|
36274
|
+
const exposures = [];
|
|
36275
|
+
for (const id of marketIds) {
|
|
36276
|
+
const rate = rateMap.get(id);
|
|
36277
|
+
if (!rate || rate.totalSupplyShares === 0n) continue;
|
|
36278
|
+
const shares = positionMap.get(`${vaultAddress}:${id}`);
|
|
36279
|
+
if (!shares || shares === 0n) continue;
|
|
36280
|
+
const allocAssetsRaw = shares * rate.totalSupplyAssets / rate.totalSupplyShares;
|
|
36281
|
+
const allocAssets = Number(
|
|
36282
|
+
parseRawAmount(allocAssetsRaw.toString(), decimals)
|
|
36283
|
+
);
|
|
36284
|
+
if (allocAssets <= 0) continue;
|
|
36285
|
+
weighted += allocAssets * rate.supplyApr;
|
|
36286
|
+
const marketUid = marketUidFor(uidCtx, id);
|
|
36287
|
+
exposures.push({
|
|
36288
|
+
marketId: id,
|
|
36289
|
+
...marketUid ? { marketUid } : {},
|
|
36290
|
+
collateralAddress: rate.collateralAddress,
|
|
36291
|
+
collateral: tokenList[rate.collateralAddress],
|
|
36292
|
+
assets: allocAssets,
|
|
36293
|
+
assetsUsd: allocAssets * priceUsd,
|
|
36294
|
+
weightPct: allocAssets / totalAssetsFormatted * 100,
|
|
36295
|
+
supplyApr: rate.supplyApr
|
|
36296
|
+
});
|
|
36297
|
+
}
|
|
36298
|
+
exposures.sort((a, b) => b.weightPct - a.weightPct);
|
|
36299
|
+
const grossApr = weighted / totalAssetsFormatted;
|
|
36300
|
+
return {
|
|
36301
|
+
depositRate: grossApr * (1 - feePercent / 100),
|
|
36302
|
+
// Tag uninvested deposits as an idle entry so the breakdown sums to ~100%.
|
|
36303
|
+
exposures: withIdleExposure(exposures, totalAssetsFormatted, priceUsd)
|
|
36304
|
+
};
|
|
36305
|
+
}
|
|
36306
|
+
|
|
36307
|
+
// src/vaults/morpho/fetchFromChain.ts
|
|
36308
|
+
var { chunk: chunk5 } = lodash;
|
|
36229
36309
|
var VAULT_CALLS = [
|
|
36230
36310
|
"name",
|
|
36231
36311
|
"symbol",
|
|
@@ -36239,8 +36319,16 @@ var VAULT_CALLS = [
|
|
|
36239
36319
|
"guardian"
|
|
36240
36320
|
];
|
|
36241
36321
|
var CALLS_PER_VAULT = VAULT_CALLS.length;
|
|
36322
|
+
var PHASE1_CALLS = [...VAULT_CALLS, "withdrawQueueLength"];
|
|
36323
|
+
var PHASE1_PER_VAULT = PHASE1_CALLS.length;
|
|
36324
|
+
var WITHDRAW_QUEUE_LENGTH_INDEX = CALLS_PER_VAULT;
|
|
36325
|
+
var MORPHO_LENS_ABI = parseAbi([
|
|
36326
|
+
"function getMarketDataCompact(address morpho, bytes32[] calldata marketsIds) external view returns (bytes memory data)"
|
|
36327
|
+
]);
|
|
36328
|
+
var MARKET_CHUNK = 100;
|
|
36242
36329
|
var FEE_SCALE = 1e18;
|
|
36243
36330
|
var isHex40 = (addr) => typeof addr === "string" && /^0x[0-9a-f]{40}$/i.test(addr);
|
|
36331
|
+
var isHex64 = (v) => typeof v === "string" && /^0x[0-9a-f]{64}$/i.test(v);
|
|
36244
36332
|
var lcOrUndefined = (addr) => isHex40(addr) ? addr.toLowerCase() : void 0;
|
|
36245
36333
|
var toNumberSafe = (raw, fallback = 0) => {
|
|
36246
36334
|
if (raw === void 0 || raw === null) return fallback;
|
|
@@ -36272,30 +36360,130 @@ var collectEntries = (chainId, protocols, skip) => {
|
|
|
36272
36360
|
var fetchMorphoVaultsFromChain = async (chainId, multicallRetry, prices = {}, tokenList = {}, opts = {}) => {
|
|
36273
36361
|
const entries = opts.vaultsOverride ? opts.vaultsOverride.map((entry) => ({ protocol: "", entry })) : collectEntries(chainId, opts.protocols, DEFAULT_SKIP_PROTOCOLS);
|
|
36274
36362
|
if (entries.length === 0) return {};
|
|
36275
|
-
const
|
|
36276
|
-
({ entry }) =>
|
|
36363
|
+
const phase1Calls = entries.flatMap(
|
|
36364
|
+
({ entry }) => PHASE1_CALLS.map((name) => ({
|
|
36277
36365
|
address: entry.vault,
|
|
36278
36366
|
name,
|
|
36279
36367
|
params: []
|
|
36280
36368
|
}))
|
|
36281
36369
|
);
|
|
36282
|
-
const
|
|
36370
|
+
const phase1 = await multicallRetry({
|
|
36283
36371
|
chain: chainId,
|
|
36284
|
-
calls,
|
|
36285
|
-
abi:
|
|
36372
|
+
calls: phase1Calls,
|
|
36373
|
+
abi: phase1Calls.map(() => MetaMorphoAbi),
|
|
36286
36374
|
allowFailure: true
|
|
36287
36375
|
});
|
|
36376
|
+
const queueLens = entries.map((_3, i) => {
|
|
36377
|
+
const n = Number(phase1[i * PHASE1_PER_VAULT + WITHDRAW_QUEUE_LENGTH_INDEX]);
|
|
36378
|
+
return Number.isFinite(n) && n > 0 ? n : 0;
|
|
36379
|
+
});
|
|
36380
|
+
const phase2Calls = [];
|
|
36381
|
+
const phase2Vault = [];
|
|
36382
|
+
entries.forEach(({ entry }, i) => {
|
|
36383
|
+
for (let q = 0; q < queueLens[i]; q++) {
|
|
36384
|
+
phase2Calls.push({
|
|
36385
|
+
address: entry.vault,
|
|
36386
|
+
name: "withdrawQueue",
|
|
36387
|
+
params: [BigInt(q)]
|
|
36388
|
+
});
|
|
36389
|
+
phase2Vault.push(i);
|
|
36390
|
+
}
|
|
36391
|
+
});
|
|
36392
|
+
const phase2 = phase2Calls.length ? await multicallRetry({
|
|
36393
|
+
chain: chainId,
|
|
36394
|
+
calls: phase2Calls,
|
|
36395
|
+
abi: phase2Calls.map(() => MetaMorphoAbi),
|
|
36396
|
+
allowFailure: true
|
|
36397
|
+
}) : [];
|
|
36398
|
+
const marketIdsByVault = entries.map(() => []);
|
|
36399
|
+
phase2.forEach((res, k) => {
|
|
36400
|
+
if (isHex64(res)) marketIdsByVault[phase2Vault[k]].push(res.toLowerCase());
|
|
36401
|
+
});
|
|
36402
|
+
const core = morphoPools()?.MORPHO_BLUE?.[chainId];
|
|
36403
|
+
const allMarketIds = [...new Set(marketIdsByVault.flat())];
|
|
36404
|
+
const [rateMap, positionMap] = await Promise.all([
|
|
36405
|
+
fetchMorphoMarketRates(chainId, core, allMarketIds, multicallRetry),
|
|
36406
|
+
fetchVaultSupplyShares(
|
|
36407
|
+
chainId,
|
|
36408
|
+
core,
|
|
36409
|
+
entries.map((e) => e.entry),
|
|
36410
|
+
marketIdsByVault,
|
|
36411
|
+
multicallRetry
|
|
36412
|
+
)
|
|
36413
|
+
]);
|
|
36288
36414
|
const out = {};
|
|
36289
36415
|
for (let i = 0; i < entries.length; i++) {
|
|
36290
36416
|
const { entry } = entries[i];
|
|
36291
|
-
const base = i *
|
|
36292
|
-
const slice =
|
|
36293
|
-
const parsed = parseVault4(
|
|
36417
|
+
const base = i * PHASE1_PER_VAULT;
|
|
36418
|
+
const slice = phase1.slice(base, base + CALLS_PER_VAULT);
|
|
36419
|
+
const parsed = parseVault4(
|
|
36420
|
+
entry,
|
|
36421
|
+
slice,
|
|
36422
|
+
chainId,
|
|
36423
|
+
prices,
|
|
36424
|
+
tokenList,
|
|
36425
|
+
marketIdsByVault[i],
|
|
36426
|
+
rateMap,
|
|
36427
|
+
positionMap
|
|
36428
|
+
);
|
|
36294
36429
|
if (parsed) out[parsed.address] = parsed;
|
|
36295
36430
|
}
|
|
36296
36431
|
return out;
|
|
36297
36432
|
};
|
|
36298
|
-
function
|
|
36433
|
+
async function fetchMorphoMarketRates(chainId, core, marketIds, multicallRetry) {
|
|
36434
|
+
const map = /* @__PURE__ */ new Map();
|
|
36435
|
+
const lens = MORPHO_LENS[chainId];
|
|
36436
|
+
if (!core || !lens || marketIds.length === 0) return map;
|
|
36437
|
+
const groups = chunk5(marketIds, MARKET_CHUNK);
|
|
36438
|
+
const calls = groups.map((group) => ({
|
|
36439
|
+
address: lens,
|
|
36440
|
+
name: "getMarketDataCompact",
|
|
36441
|
+
params: [core, group]
|
|
36442
|
+
}));
|
|
36443
|
+
const raw = await multicallRetry({
|
|
36444
|
+
chain: chainId,
|
|
36445
|
+
calls,
|
|
36446
|
+
abi: calls.map(() => MORPHO_LENS_ABI),
|
|
36447
|
+
allowFailure: true
|
|
36448
|
+
});
|
|
36449
|
+
groups.forEach((group, c) => {
|
|
36450
|
+
const bytes = raw[c];
|
|
36451
|
+
if (!bytes || bytes === "0x") return;
|
|
36452
|
+
let decoded;
|
|
36453
|
+
try {
|
|
36454
|
+
decoded = decodeMarkets(bytes);
|
|
36455
|
+
} catch {
|
|
36456
|
+
return;
|
|
36457
|
+
}
|
|
36458
|
+
decoded.forEach((mkt, j) => {
|
|
36459
|
+
const id = group[j]?.toLowerCase();
|
|
36460
|
+
if (!id) return;
|
|
36461
|
+
const utilization = MathLib.getUtilization({
|
|
36462
|
+
totalSupplyAssets: mkt.totalSupplyAssets,
|
|
36463
|
+
totalBorrowAssets: mkt.totalBorrowAssets
|
|
36464
|
+
});
|
|
36465
|
+
let supplyApy = 0n;
|
|
36466
|
+
try {
|
|
36467
|
+
const borrowApy = MathLib.getBorrowApy(
|
|
36468
|
+
mkt.rateAtTarget,
|
|
36469
|
+
utilization,
|
|
36470
|
+
void 0,
|
|
36471
|
+
Number(mkt.lastUpdate)
|
|
36472
|
+
);
|
|
36473
|
+
supplyApy = MathLib.getSupplyApy(borrowApy, utilization, mkt.fee);
|
|
36474
|
+
} catch {
|
|
36475
|
+
}
|
|
36476
|
+
map.set(id, {
|
|
36477
|
+
supplyApr: apyToApr2(Number(formatEther(supplyApy))) * 100,
|
|
36478
|
+
totalSupplyAssets: mkt.totalSupplyAssets,
|
|
36479
|
+
totalSupplyShares: mkt.totalSupplyShares,
|
|
36480
|
+
collateralAddress: (mkt.collateralToken ?? "").toLowerCase()
|
|
36481
|
+
});
|
|
36482
|
+
});
|
|
36483
|
+
});
|
|
36484
|
+
return map;
|
|
36485
|
+
}
|
|
36486
|
+
function parseVault4(entry, results, chainId, prices, tokenList, marketIds, rateMap, positionMap) {
|
|
36299
36487
|
const address = entry?.vault?.toLowerCase();
|
|
36300
36488
|
const underlying = entry?.underlying?.toLowerCase();
|
|
36301
36489
|
if (!address || !underlying) return null;
|
|
@@ -36323,22 +36511,36 @@ function parseVault4(entry, results, chainId, prices, tokenList) {
|
|
|
36323
36511
|
const symbol = toStringSafe(symbolRaw);
|
|
36324
36512
|
const fee = toNumberSafe(feeRaw) / FEE_SCALE * 100;
|
|
36325
36513
|
const timelock = toNumberSafe(timelockRaw);
|
|
36514
|
+
const { depositRate, exposures } = computeVaultAllocation(
|
|
36515
|
+
address,
|
|
36516
|
+
decimals,
|
|
36517
|
+
totalAssetsFormatted,
|
|
36518
|
+
fee,
|
|
36519
|
+
priceUsd,
|
|
36520
|
+
marketIds,
|
|
36521
|
+
rateMap,
|
|
36522
|
+
positionMap,
|
|
36523
|
+
tokenList,
|
|
36524
|
+
{ chainId, underlying, protocol: "MORPHO_BLUE" }
|
|
36525
|
+
);
|
|
36326
36526
|
return {
|
|
36327
36527
|
address,
|
|
36328
36528
|
underlying,
|
|
36329
36529
|
symbol,
|
|
36330
36530
|
name: fallbackName,
|
|
36331
|
-
displayName: composeVaultDisplayName(
|
|
36531
|
+
displayName: composeVaultDisplayName(
|
|
36532
|
+
"Morpho",
|
|
36533
|
+
void 0,
|
|
36534
|
+
assetMeta,
|
|
36535
|
+
fallbackName
|
|
36536
|
+
),
|
|
36332
36537
|
decimals,
|
|
36333
36538
|
totalAssets,
|
|
36334
36539
|
totalSupply,
|
|
36335
|
-
|
|
36336
|
-
// walking the underlying market list — surface 0 like the Goldsky path
|
|
36337
|
-
// does for rewards. Callers that need APR on these vaults should layer
|
|
36338
|
-
// it in separately or fall back to the API/subgraph fetchers.
|
|
36339
|
-
supplyRate: 0,
|
|
36540
|
+
supplyRate: depositRate,
|
|
36340
36541
|
rewardsRate: 0,
|
|
36341
|
-
depositRate
|
|
36542
|
+
depositRate,
|
|
36543
|
+
exposures,
|
|
36342
36544
|
fee,
|
|
36343
36545
|
timelock,
|
|
36344
36546
|
whitelisted: true,
|
|
@@ -36357,13 +36559,111 @@ function parseVault4(entry, results, chainId, prices, tokenList) {
|
|
|
36357
36559
|
liquidityUsd: totalAssetsFormatted * priceUsd
|
|
36358
36560
|
};
|
|
36359
36561
|
}
|
|
36360
|
-
|
|
36562
|
+
|
|
36563
|
+
// src/vaults/morpho/fetchPublic.ts
|
|
36564
|
+
var hasMorphoOnChainVaults = (chainId) => (morphoTypeVaults()?.MORPHO_BLUE?.[chainId]?.length ?? 0) > 0;
|
|
36565
|
+
var fetchMorphoVaults = async (chainId, multicallRetry, prices = {}, tokenList = {}) => {
|
|
36566
|
+
if (hasMorphoOnChainVaults(chainId)) {
|
|
36567
|
+
return fetchMorphoVaultsFromChain(
|
|
36568
|
+
chainId,
|
|
36569
|
+
multicallRetry,
|
|
36570
|
+
prices,
|
|
36571
|
+
tokenList
|
|
36572
|
+
);
|
|
36573
|
+
}
|
|
36574
|
+
if (hasMorphoVaultSubgraph(chainId)) {
|
|
36575
|
+
return fetchMorphoVaultsFromSubgraph(chainId, prices, tokenList);
|
|
36576
|
+
}
|
|
36577
|
+
return fetchMorphoVaultsFromApi(chainId, prices, tokenList);
|
|
36578
|
+
};
|
|
36579
|
+
|
|
36580
|
+
// src/vaults/curatorName.ts
|
|
36581
|
+
var STOP_WORDS = /* @__PURE__ */ new Set([
|
|
36582
|
+
"vault",
|
|
36583
|
+
"vaults",
|
|
36584
|
+
"savings",
|
|
36585
|
+
"yield",
|
|
36586
|
+
"exclusive",
|
|
36587
|
+
"dao",
|
|
36588
|
+
"x",
|
|
36589
|
+
"pt",
|
|
36590
|
+
"prime",
|
|
36591
|
+
"staked",
|
|
36592
|
+
"core",
|
|
36593
|
+
"lista",
|
|
36594
|
+
// protocol brand; a bare "Lista …" vault has no distinct curator
|
|
36595
|
+
"moolah"
|
|
36596
|
+
]);
|
|
36597
|
+
var ASSET_TOKENS = /* @__PURE__ */ new Set([
|
|
36598
|
+
"usdc",
|
|
36599
|
+
"usdt",
|
|
36600
|
+
"usd1",
|
|
36601
|
+
"usds",
|
|
36602
|
+
"dai",
|
|
36603
|
+
"usde",
|
|
36604
|
+
"susde",
|
|
36605
|
+
"lisusd",
|
|
36606
|
+
"gho",
|
|
36607
|
+
"frax",
|
|
36608
|
+
"pyusd",
|
|
36609
|
+
"rusd",
|
|
36610
|
+
"usr",
|
|
36611
|
+
"rlp",
|
|
36612
|
+
"eth",
|
|
36613
|
+
"weth",
|
|
36614
|
+
"wsteth",
|
|
36615
|
+
"reth",
|
|
36616
|
+
"steth",
|
|
36617
|
+
"cbeth",
|
|
36618
|
+
"weeth",
|
|
36619
|
+
"ezeth",
|
|
36620
|
+
"btc",
|
|
36621
|
+
"wbtc",
|
|
36622
|
+
"btcb",
|
|
36623
|
+
"cbbtc",
|
|
36624
|
+
"tbtc",
|
|
36625
|
+
"xaut",
|
|
36626
|
+
"xrp",
|
|
36627
|
+
"bnb",
|
|
36628
|
+
"wbnb",
|
|
36629
|
+
"sol",
|
|
36630
|
+
"op",
|
|
36631
|
+
"arb",
|
|
36632
|
+
"avax",
|
|
36633
|
+
"pol",
|
|
36634
|
+
"matic",
|
|
36635
|
+
"sei",
|
|
36636
|
+
"celo",
|
|
36637
|
+
"hype",
|
|
36638
|
+
"plume",
|
|
36639
|
+
"s"
|
|
36640
|
+
]);
|
|
36641
|
+
function curatorNameFromVaultName(name, assetSymbol) {
|
|
36642
|
+
if (!name) return void 0;
|
|
36643
|
+
const cleaned = name.replace(/\([^)]*\)\s*$/, "").trim();
|
|
36644
|
+
if (!cleaned) return void 0;
|
|
36645
|
+
const tokens = cleaned.split(/[\s/]+/).flatMap((t) => t.split("-")).filter(Boolean);
|
|
36646
|
+
const asset = (assetSymbol ?? "").toLowerCase();
|
|
36647
|
+
const out = [];
|
|
36648
|
+
for (const tok of tokens) {
|
|
36649
|
+
const tl = tok.toLowerCase();
|
|
36650
|
+
if (STOP_WORDS.has(tl)) break;
|
|
36651
|
+
if (asset && tl === asset || ASSET_TOKENS.has(tl)) break;
|
|
36652
|
+
out.push(tok);
|
|
36653
|
+
if (out.length >= 3) break;
|
|
36654
|
+
}
|
|
36655
|
+
const curator = out.join(" ").trim();
|
|
36656
|
+
return curator.length >= 2 ? curator : void 0;
|
|
36657
|
+
}
|
|
36658
|
+
|
|
36659
|
+
// src/vaults/morpho/fetchListaFromChain.ts
|
|
36660
|
+
var { chunk: chunk6 } = lodash;
|
|
36361
36661
|
var LISTA_PROTOCOL = "LISTA_DAO";
|
|
36362
36662
|
var LISTA_LENS_ABI = parseAbi([
|
|
36363
36663
|
"function getListaMarketDataCompact(address morpho, bytes32[] calldata marketsIds) external view returns (bytes memory data)"
|
|
36364
36664
|
]);
|
|
36365
36665
|
var LISTA_MARKET_CHUNK = 100;
|
|
36366
|
-
var
|
|
36666
|
+
var PHASE1_CALLS2 = [
|
|
36367
36667
|
"name",
|
|
36368
36668
|
"symbol",
|
|
36369
36669
|
"decimals",
|
|
@@ -36374,8 +36674,8 @@ var PHASE1_CALLS = [
|
|
|
36374
36674
|
"CURATOR",
|
|
36375
36675
|
"withdrawQueueLength"
|
|
36376
36676
|
];
|
|
36377
|
-
var
|
|
36378
|
-
var
|
|
36677
|
+
var PHASE1_PER_VAULT2 = PHASE1_CALLS2.length;
|
|
36678
|
+
var WITHDRAW_QUEUE_LENGTH_INDEX2 = 8;
|
|
36379
36679
|
var FEE_SCALE2 = 1e18;
|
|
36380
36680
|
var isHex402 = (addr) => typeof addr === "string" && /^0x[0-9a-f]{40}$/i.test(addr);
|
|
36381
36681
|
var lcOrUndefined2 = (addr) => {
|
|
@@ -36383,7 +36683,7 @@ var lcOrUndefined2 = (addr) => {
|
|
|
36383
36683
|
const lower = addr.toLowerCase();
|
|
36384
36684
|
return lower === zeroAddress ? void 0 : lower;
|
|
36385
36685
|
};
|
|
36386
|
-
var
|
|
36686
|
+
var isHex642 = (val) => typeof val === "string" && /^0x[0-9a-f]{64}$/i.test(val);
|
|
36387
36687
|
var toNumberSafe2 = (raw, fallback = 0) => {
|
|
36388
36688
|
if (raw === void 0 || raw === null) return fallback;
|
|
36389
36689
|
const n = Number(raw);
|
|
@@ -36409,7 +36709,7 @@ var fetchListaVaultsFromChain = async (chainId, multicallRetry, prices = {}, tok
|
|
|
36409
36709
|
const entries = opts.vaultsOverride ?? collectEntries2(chainId);
|
|
36410
36710
|
if (entries.length === 0) return {};
|
|
36411
36711
|
const phase1Calls = entries.flatMap(
|
|
36412
|
-
(entry) =>
|
|
36712
|
+
(entry) => PHASE1_CALLS2.map((name) => ({
|
|
36413
36713
|
address: entry.vault,
|
|
36414
36714
|
name,
|
|
36415
36715
|
params: []
|
|
@@ -36424,10 +36724,10 @@ var fetchListaVaultsFromChain = async (chainId, multicallRetry, prices = {}, tok
|
|
|
36424
36724
|
const curatorRoleByVault = [];
|
|
36425
36725
|
const queueLenByVault = [];
|
|
36426
36726
|
for (let i = 0; i < entries.length; i++) {
|
|
36427
|
-
const role = phase1[i *
|
|
36428
|
-
curatorRoleByVault.push(
|
|
36727
|
+
const role = phase1[i * PHASE1_PER_VAULT2 + 7];
|
|
36728
|
+
curatorRoleByVault.push(isHex642(role) ? role : void 0);
|
|
36429
36729
|
queueLenByVault.push(
|
|
36430
|
-
toNumberSafe2(phase1[i *
|
|
36730
|
+
toNumberSafe2(phase1[i * PHASE1_PER_VAULT2 + WITHDRAW_QUEUE_LENGTH_INDEX2])
|
|
36431
36731
|
);
|
|
36432
36732
|
}
|
|
36433
36733
|
const phase2Calls = [];
|
|
@@ -36460,7 +36760,7 @@ var fetchListaVaultsFromChain = async (chainId, multicallRetry, prices = {}, tok
|
|
|
36460
36760
|
const meta = phase2Meta[k];
|
|
36461
36761
|
if (meta.kind === "curator") {
|
|
36462
36762
|
if (curatorRoleByVault[meta.vault]) curatorAddrByVault[meta.vault] = res;
|
|
36463
|
-
} else if (
|
|
36763
|
+
} else if (isHex642(res)) {
|
|
36464
36764
|
marketIdsByVault[meta.vault].push(res.toLowerCase());
|
|
36465
36765
|
}
|
|
36466
36766
|
});
|
|
@@ -36479,7 +36779,7 @@ var fetchListaVaultsFromChain = async (chainId, multicallRetry, prices = {}, tok
|
|
|
36479
36779
|
const out = {};
|
|
36480
36780
|
for (let i = 0; i < entries.length; i++) {
|
|
36481
36781
|
const entry = entries[i];
|
|
36482
|
-
const slice = phase1.slice(i *
|
|
36782
|
+
const slice = phase1.slice(i * PHASE1_PER_VAULT2, (i + 1) * PHASE1_PER_VAULT2);
|
|
36483
36783
|
const parsed = parseVault5(
|
|
36484
36784
|
entry,
|
|
36485
36785
|
slice,
|
|
@@ -36499,7 +36799,7 @@ async function fetchListaMarketRates(chainId, moolah, marketIds, multicallRetry)
|
|
|
36499
36799
|
const map = /* @__PURE__ */ new Map();
|
|
36500
36800
|
const lens = MORPHO_LENS[chainId];
|
|
36501
36801
|
if (!moolah || !lens || marketIds.length === 0) return map;
|
|
36502
|
-
const groups =
|
|
36802
|
+
const groups = chunk6(marketIds, LISTA_MARKET_CHUNK);
|
|
36503
36803
|
const calls = groups.map((group) => ({
|
|
36504
36804
|
address: lens,
|
|
36505
36805
|
name: "getListaMarketDataCompact",
|
|
@@ -36550,80 +36850,6 @@ async function fetchListaMarketRates(chainId, moolah, marketIds, multicallRetry)
|
|
|
36550
36850
|
});
|
|
36551
36851
|
return map;
|
|
36552
36852
|
}
|
|
36553
|
-
async function fetchVaultSupplyShares(chainId, moolah, entries, marketIdsByVault, multicallRetry) {
|
|
36554
|
-
const map = /* @__PURE__ */ new Map();
|
|
36555
|
-
if (!moolah) return map;
|
|
36556
|
-
const calls = [];
|
|
36557
|
-
const keys = [];
|
|
36558
|
-
entries.forEach((entry, i) => {
|
|
36559
|
-
const vault = entry.vault.toLowerCase();
|
|
36560
|
-
for (const id of marketIdsByVault[i]) {
|
|
36561
|
-
calls.push({
|
|
36562
|
-
address: moolah,
|
|
36563
|
-
name: "position",
|
|
36564
|
-
params: [id, entry.vault]
|
|
36565
|
-
});
|
|
36566
|
-
keys.push(`${vault}:${id}`);
|
|
36567
|
-
}
|
|
36568
|
-
});
|
|
36569
|
-
if (calls.length === 0) return map;
|
|
36570
|
-
const res = await multicallRetry({
|
|
36571
|
-
chain: chainId,
|
|
36572
|
-
calls,
|
|
36573
|
-
abi: calls.map(() => MorphoBlueAbi),
|
|
36574
|
-
allowFailure: true
|
|
36575
|
-
});
|
|
36576
|
-
res.forEach((r, k) => {
|
|
36577
|
-
const supplyShares = Array.isArray(r) ? r[0] : r?.supplyShares;
|
|
36578
|
-
if (supplyShares == null) return;
|
|
36579
|
-
try {
|
|
36580
|
-
map.set(keys[k], BigInt(supplyShares));
|
|
36581
|
-
} catch {
|
|
36582
|
-
}
|
|
36583
|
-
});
|
|
36584
|
-
return map;
|
|
36585
|
-
}
|
|
36586
|
-
function computeVaultAllocation(vaultAddress, decimals, totalAssetsFormatted, feePercent, priceUsd, marketIds, rateMap, positionMap, tokenList) {
|
|
36587
|
-
if (totalAssetsFormatted <= 0) {
|
|
36588
|
-
return { depositRate: 0, exposures: [] };
|
|
36589
|
-
}
|
|
36590
|
-
if (marketIds.length === 0) {
|
|
36591
|
-
return {
|
|
36592
|
-
depositRate: 0,
|
|
36593
|
-
exposures: withIdleExposure([], totalAssetsFormatted, priceUsd)
|
|
36594
|
-
};
|
|
36595
|
-
}
|
|
36596
|
-
let weighted = 0;
|
|
36597
|
-
const exposures = [];
|
|
36598
|
-
for (const id of marketIds) {
|
|
36599
|
-
const rate = rateMap.get(id);
|
|
36600
|
-
if (!rate || rate.totalSupplyShares === 0n) continue;
|
|
36601
|
-
const shares = positionMap.get(`${vaultAddress}:${id}`);
|
|
36602
|
-
if (!shares || shares === 0n) continue;
|
|
36603
|
-
const allocAssetsRaw = shares * rate.totalSupplyAssets / rate.totalSupplyShares;
|
|
36604
|
-
const allocAssets = Number(
|
|
36605
|
-
parseRawAmount(allocAssetsRaw.toString(), decimals)
|
|
36606
|
-
);
|
|
36607
|
-
if (allocAssets <= 0) continue;
|
|
36608
|
-
weighted += allocAssets * rate.supplyApr;
|
|
36609
|
-
exposures.push({
|
|
36610
|
-
marketId: id,
|
|
36611
|
-
collateralAddress: rate.collateralAddress,
|
|
36612
|
-
collateral: tokenList[rate.collateralAddress],
|
|
36613
|
-
assets: allocAssets,
|
|
36614
|
-
assetsUsd: allocAssets * priceUsd,
|
|
36615
|
-
weightPct: allocAssets / totalAssetsFormatted * 100,
|
|
36616
|
-
supplyApr: rate.supplyApr
|
|
36617
|
-
});
|
|
36618
|
-
}
|
|
36619
|
-
exposures.sort((a, b) => b.weightPct - a.weightPct);
|
|
36620
|
-
const grossApr = weighted / totalAssetsFormatted;
|
|
36621
|
-
return {
|
|
36622
|
-
depositRate: grossApr * (1 - feePercent / 100),
|
|
36623
|
-
// Tag uninvested deposits as an idle entry so the breakdown sums to ~100%.
|
|
36624
|
-
exposures: withIdleExposure(exposures, totalAssetsFormatted, priceUsd)
|
|
36625
|
-
};
|
|
36626
|
-
}
|
|
36627
36853
|
function parseVault5(entry, results, curatorAddrRaw, chainId, prices, tokenList, marketIds, rateMap, positionMap) {
|
|
36628
36854
|
const address = entry?.vault?.toLowerCase();
|
|
36629
36855
|
const underlying = entry?.underlying?.toLowerCase();
|
|
@@ -36660,7 +36886,8 @@ function parseVault5(entry, results, curatorAddrRaw, chainId, prices, tokenList,
|
|
|
36660
36886
|
marketIds,
|
|
36661
36887
|
rateMap,
|
|
36662
36888
|
positionMap,
|
|
36663
|
-
tokenList
|
|
36889
|
+
tokenList,
|
|
36890
|
+
{ chainId, underlying, protocol: "LISTA_DAO" }
|
|
36664
36891
|
);
|
|
36665
36892
|
return {
|
|
36666
36893
|
address,
|
|
@@ -36684,6 +36911,9 @@ function parseVault5(entry, results, curatorAddrRaw, chainId, prices, tokenList,
|
|
|
36684
36911
|
whitelisted: true,
|
|
36685
36912
|
owner: void 0,
|
|
36686
36913
|
curator: lcOrUndefined2(curatorAddrRaw),
|
|
36914
|
+
// Moolah exposes only the curator address; derive a display name from the
|
|
36915
|
+
// (curator-branded) vault name as a best-effort fallback.
|
|
36916
|
+
curatorName: curatorNameFromVaultName(fallbackName, assetMeta?.symbol),
|
|
36687
36917
|
guardian: void 0,
|
|
36688
36918
|
asset: assetMeta,
|
|
36689
36919
|
priceUsd: priceUsd || void 0,
|
|
@@ -37062,6 +37292,7 @@ function parseVault7(v, chainId, prices, tokenList, evkIndex) {
|
|
|
37062
37292
|
fee,
|
|
37063
37293
|
owner: readAddress2(v.owner),
|
|
37064
37294
|
curator: readAddress2(v.curator),
|
|
37295
|
+
curatorName: curatorNameFromVaultName(v.name, assetMeta?.symbol),
|
|
37065
37296
|
guardian: readAddress2(v.guardian),
|
|
37066
37297
|
feeRecipient: v.feeReceiver?.toLowerCase() || void 0,
|
|
37067
37298
|
asset: assetMeta,
|
|
@@ -43354,6 +43585,10 @@ query LagoonVaults($where: VaultFilterInput!, $first: Int!, $skip: Int!) {
|
|
|
43354
43585
|
name
|
|
43355
43586
|
symbol
|
|
43356
43587
|
decimals
|
|
43588
|
+
curators {
|
|
43589
|
+
id
|
|
43590
|
+
name
|
|
43591
|
+
}
|
|
43357
43592
|
isVisible
|
|
43358
43593
|
asset {
|
|
43359
43594
|
address
|
|
@@ -43426,8 +43661,7 @@ var pickApr = (apr) => {
|
|
|
43426
43661
|
if (apr.monthly != null) return { rate: apr.monthly, window: "monthly" };
|
|
43427
43662
|
if (apr.weekly != null) return { rate: apr.weekly, window: "weekly" };
|
|
43428
43663
|
if (apr.yearly != null) return { rate: apr.yearly, window: "yearly" };
|
|
43429
|
-
if (apr.inception != null)
|
|
43430
|
-
return { rate: apr.inception, window: "inception" };
|
|
43664
|
+
if (apr.inception != null) return { rate: apr.inception, window: "inception" };
|
|
43431
43665
|
return { rate: 0, window: "none" };
|
|
43432
43666
|
};
|
|
43433
43667
|
var num = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
@@ -43460,12 +43694,14 @@ function parseVault8(v, chainId, prices, tokenList) {
|
|
|
43460
43694
|
const name = (v.name ?? "").trim();
|
|
43461
43695
|
const symbol = (v.symbol ?? "").trim();
|
|
43462
43696
|
const displayName = name || composeVaultDisplayName(BRAND, void 0, assetMeta, symbol);
|
|
43697
|
+
const curatorName = v.curators?.find((c) => c?.name)?.name ?? void 0;
|
|
43463
43698
|
return {
|
|
43464
43699
|
address,
|
|
43465
43700
|
underlying: assetAddr,
|
|
43466
43701
|
symbol,
|
|
43467
43702
|
name: name || symbol,
|
|
43468
43703
|
displayName,
|
|
43704
|
+
...curatorName ? { curatorName } : {},
|
|
43469
43705
|
decimals,
|
|
43470
43706
|
assetDecimals,
|
|
43471
43707
|
totalAssets: totalAssetsRaw,
|
|
@@ -44851,7 +45087,7 @@ var getVaultPublicDataAll = async (chainId, providers, multicallRetry, prices =
|
|
|
44851
45087
|
}
|
|
44852
45088
|
if (requested.has("morpho")) {
|
|
44853
45089
|
tasks.push(
|
|
44854
|
-
fetchMorphoVaults(chainId, prices, tokenList).then((res) => {
|
|
45090
|
+
fetchMorphoVaults(chainId, multicallRetry, prices, tokenList).then((res) => {
|
|
44855
45091
|
out.morpho = res;
|
|
44856
45092
|
}).catch((e) => {
|
|
44857
45093
|
warn4(
|