@1delta/margin-fetcher 5.0.52 → 5.0.54
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 +11 -0
- package/dist/index.js +166 -124
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -12179,12 +12179,23 @@ interface EarnExclusions {
|
|
|
12179
12179
|
lowTvl: number;
|
|
12180
12180
|
/** Above the risk ceiling the rest of the API also applies. */
|
|
12181
12181
|
highRisk: number;
|
|
12182
|
+
/**
|
|
12183
|
+
* Rows whose position is a multi-token LP (`basket`), hidden by default.
|
|
12184
|
+
*
|
|
12185
|
+
* Excluded unasked because the row names ONE token while the position holds
|
|
12186
|
+
* several in a split the pool keeps moving — so a depositor reading it as
|
|
12187
|
+
* "USDC at 10 %" ends up carrying the other leg's price risk. Reported here
|
|
12188
|
+
* so a UI can offer `?lp=include` rather than let the rows vanish silently.
|
|
12189
|
+
*/
|
|
12190
|
+
lp: number;
|
|
12182
12191
|
}
|
|
12183
12192
|
interface EarnAppliedDefaults {
|
|
12184
12193
|
minTvlUsd: number;
|
|
12185
12194
|
maxRiskScore: number;
|
|
12186
12195
|
excludePassthrough: boolean;
|
|
12187
12196
|
excludeIlliquid: boolean;
|
|
12197
|
+
/** LP / auto-rebalancing positions are hidden unless `?lp=include`. */
|
|
12198
|
+
excludeLp: boolean;
|
|
12188
12199
|
}
|
|
12189
12200
|
/**
|
|
12190
12201
|
* The filter vocabulary, published rather than hard-coded.
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import './chunk-BYTNVMX7.js';
|
|
|
3
3
|
import './chunk-PR4QN5HX.js';
|
|
4
4
|
import { Lender, isExactly, isMidnight, isTerm, isTermMax, isTeller, isListaDao, isLiquityFamily, isRiver, isInverse, isDssType, isCompoundV3Type, isFluid, isGearboxV3, isLlamaLend, isFrankencoin, isResupply, isCurvance, isTwyne, isFraxlend, LIQUITY_FAMILY_LENDERS, isAaveType, isCompoundV3, isMultiMarket, isSiloV2Type, isSiloV3Type, isDolomite, hasCrossMarginRisk, isEulerType, isAaveV4Type, isInit, isMorphoType, isCompoundV2Type, isVenusType, isSumerType, AAVE_V3_LENDERS, AAVE_V2_LENDERS, isMorphoBlue, isAaveV2Type, isAaveV32Type, isAaveV3Type, isUsdd, isSky, isYLDR, isLista, hasSubAccounts, isTectonicType, isKineticType, isBenqiType } from '@1delta/lender-registry';
|
|
5
5
|
export { hasCrossMarginRisk, isAaveType, isAaveV2Type, isAaveV32Type, isAaveV3Type, isCompoundV3, isCompoundV3Type, isInit, isMorphoType, isMultiMarket, isYLDR } from '@1delta/lender-registry';
|
|
6
|
-
import { fetchTokenLists, fetchTokenList, aavePools, compoundV3Pools, initConfig, morphoPools, compoundV2Pools, eulerVaults, siloMarkets, siloV2LenderKey, siloMarketsV3, siloV3LenderKey, aaveV4Spokes, aaveV4SpokeLenderKey, fluidResolvers, gearboxResolvers, dolomiteConfigs, midnightConfig, termConfig, termMarketsByChain, exactlyConfig, liquityLendersByChain, riverLendersByChain, inverseLendersByChain, llamaLendLendersByChain, usddLendersByChain, skyLendersByChain, frankencoinLendersByChain, resupplyLendersByChain, curvanceLendersByChain, fraxlendLendersByChain, tellerConfigByChain, tellerPoolsByChain, termMaxConfigByChain, aaveReserves, compoundV3Reserves, liquityConfigFor, liquityBranchesByChain, riverConfigFor, riverChainData, termMaxApiBaseUrl, termMaxLenderKey, inverseConfigFor, inverseChainData, llamaLendConfigFor, llamaLendChainData, llamaLendApiBaseUrl, resupplyConfigFor, fraxlendConfigFor, dssConfigFor, dssChainData, dssDebtToken, dssDebtJoin, frankencoinConfigFor, frankencoinChainData, aaveOracles, morphoTypeMarkets, resolveMidnightApiBase, resolveTermApiBase, llamaLendMarketByVault, getSiloV2MarketEntry, getSiloV3MarketEntry, dolomiteEmode, curvanceConfigFor, aaveTokens, morphoTypeVaults, listaCollateralProvider, eulerConfigs, gearboxMarketCompressor, gearboxMarketConfigurators, gearboxV3LenderKey, midnightMarketsByChain, twyneConfigFor, twyneChainData, parseAaveV4SpokeLenderKey, fraxlendPairsFor, gearboxAccountCompressor, compoundV2Tokens, exactlyMarketsByChain, aaveOraclesConfig, compoundV2Oracles, compoundV2TokenArray, compoundV2OraclesConfig, compoundV3OraclesData, compoundV3BaseData, compoundV2Reserves, aaveV4Oracles } from '@1delta/data-sdk';
|
|
6
|
+
import { fetchTokenLists, fetchTokenList, aavePools, compoundV3Pools, initConfig, morphoPools, compoundV2Pools, eulerVaults, siloMarkets, siloV2LenderKey, siloMarketsV3, siloV3LenderKey, aaveV4Spokes, aaveV4SpokeLenderKey, fluidResolvers, gearboxResolvers, dolomiteConfigs, midnightConfig, termConfig, termMarketsByChain, exactlyConfig, liquityLendersByChain, riverLendersByChain, inverseLendersByChain, llamaLendLendersByChain, usddLendersByChain, skyLendersByChain, frankencoinLendersByChain, resupplyLendersByChain, curvanceLendersByChain, fraxlendLendersByChain, twyneLendersByChain, tellerConfigByChain, tellerPoolsByChain, termMaxConfigByChain, aaveReserves, compoundV3Reserves, liquityConfigFor, liquityBranchesByChain, riverConfigFor, riverChainData, termMaxApiBaseUrl, termMaxLenderKey, inverseConfigFor, inverseChainData, llamaLendConfigFor, llamaLendChainData, llamaLendApiBaseUrl, resupplyConfigFor, fraxlendConfigFor, dssConfigFor, dssChainData, dssDebtToken, dssDebtJoin, frankencoinConfigFor, frankencoinChainData, aaveOracles, morphoTypeMarkets, resolveMidnightApiBase, resolveTermApiBase, llamaLendMarketByVault, getSiloV2MarketEntry, getSiloV3MarketEntry, dolomiteEmode, curvanceConfigFor, aaveTokens, morphoTypeVaults, listaCollateralProvider, eulerConfigs, gearboxMarketCompressor, gearboxMarketConfigurators, gearboxV3LenderKey, midnightMarketsByChain, twyneConfigFor, twyneChainData, parseAaveV4SpokeLenderKey, fraxlendPairsFor, gearboxAccountCompressor, compoundV2Tokens, exactlyMarketsByChain, aaveOraclesConfig, compoundV2Oracles, compoundV2TokenArray, compoundV2OraclesConfig, compoundV3OraclesData, compoundV3BaseData, compoundV2Reserves, aaveV4Oracles } from '@1delta/data-sdk';
|
|
7
7
|
import lodash from 'lodash';
|
|
8
8
|
import { Chain } from '@1delta/chain-registry';
|
|
9
9
|
import { multicallRetryUniversal, getEvmClient, getEvmChain, getEvmClientUniversal } from '@1delta/providers';
|
|
@@ -6439,6 +6439,9 @@ var getLendersForChain = (c) => {
|
|
|
6439
6439
|
for (const l of fraxlendLendersByChain(c)) {
|
|
6440
6440
|
lenders.push(l);
|
|
6441
6441
|
}
|
|
6442
|
+
for (const l of twyneLendersByChain(c)) {
|
|
6443
|
+
lenders.push(l);
|
|
6444
|
+
}
|
|
6442
6445
|
if (tellerConfigByChain(c)?.tellerV2 && tellerPoolsByChain(c).length > 0) {
|
|
6443
6446
|
lenders.push(Lender.TELLER);
|
|
6444
6447
|
}
|
|
@@ -19473,6 +19476,10 @@ function parseVault(vault, chainId, prices, additionalYields, tokenList, liquidi
|
|
|
19473
19476
|
}
|
|
19474
19477
|
return value > 0 ? weighted / value : legs[0]?.rate ?? 0;
|
|
19475
19478
|
};
|
|
19479
|
+
const smartLegTokens = /* @__PURE__ */ new Set([
|
|
19480
|
+
...isSmartCol ? colLegs.map((l) => l.token.toLowerCase()) : [],
|
|
19481
|
+
...isSmartDebt ? debtLegs.map((l) => l.token.toLowerCase()) : []
|
|
19482
|
+
]);
|
|
19476
19483
|
const basketSupplyRate = isSmartCol ? basketRate(colLegs) : void 0;
|
|
19477
19484
|
const basketBorrowRate = isSmartDebt ? basketRate(debtLegs) : void 0;
|
|
19478
19485
|
const irmTotals = (state, decimals) => state ? {
|
|
@@ -19561,7 +19568,7 @@ function parseVault(vault, chainId, prices, additionalYields, tokenList, liquidi
|
|
|
19561
19568
|
* NOT the position's rate (use the basket rate); and an exit has to be
|
|
19562
19569
|
* sized in shares rather than in this token.
|
|
19563
19570
|
*/
|
|
19564
|
-
...
|
|
19571
|
+
...smartLegTokens.has(leg.token.toLowerCase()) ? { autoBalanced: true } : {},
|
|
19565
19572
|
fluid: isSmartVault ? {
|
|
19566
19573
|
vaultType,
|
|
19567
19574
|
/**
|
|
@@ -24644,6 +24651,7 @@ async function fetchTwyneMarkets(lender, chainId) {
|
|
|
24644
24651
|
allowFailure: true
|
|
24645
24652
|
});
|
|
24646
24653
|
const out = [];
|
|
24654
|
+
const pendingDebtBalances = [];
|
|
24647
24655
|
markets.forEach((m, i) => {
|
|
24648
24656
|
const c = i * 8;
|
|
24649
24657
|
const creditTotalAssets = big3(creditReads[c]);
|
|
@@ -24657,6 +24665,7 @@ async function fetchTwyneMarkets(lender, chainId) {
|
|
|
24657
24665
|
let externalSupplyRate;
|
|
24658
24666
|
let externalBorrowRate;
|
|
24659
24667
|
let externalBorrowLiquidity;
|
|
24668
|
+
let debtAToken;
|
|
24660
24669
|
if (aaveIdx >= 0) {
|
|
24661
24670
|
const emode = aaveEmode[aaveIdx];
|
|
24662
24671
|
const collReserve = aaveReserves6[aaveIdx * 2];
|
|
@@ -24666,6 +24675,12 @@ async function fetchTwyneMarkets(lender, chainId) {
|
|
|
24666
24675
|
externalSupplyRate = Number(collReserve.currentLiquidityRate) / RAY4;
|
|
24667
24676
|
if (ok(debtReserve) && debtReserve?.currentVariableBorrowRate !== void 0)
|
|
24668
24677
|
externalBorrowRate = Number(debtReserve.currentVariableBorrowRate) / RAY4;
|
|
24678
|
+
if (ok(debtReserve)) {
|
|
24679
|
+
const virtual = big3(debtReserve.virtualUnderlyingBalance);
|
|
24680
|
+
if (virtual !== void 0 && virtual > 0n) externalBorrowLiquidity = virtual;
|
|
24681
|
+
else if (typeof debtReserve.aTokenAddress === "string")
|
|
24682
|
+
debtAToken = debtReserve.aTokenAddress;
|
|
24683
|
+
}
|
|
24669
24684
|
} else if (eulerIdx >= 0) {
|
|
24670
24685
|
const e = eulerIdx * 7;
|
|
24671
24686
|
externalLiqLtv = big3(eulerReads[e]);
|
|
@@ -24682,7 +24697,10 @@ async function fetchTwyneMarkets(lender, chainId) {
|
|
|
24682
24697
|
}
|
|
24683
24698
|
}
|
|
24684
24699
|
const s = i * 3;
|
|
24685
|
-
if (externalBorrowLiquidity === void 0
|
|
24700
|
+
if (externalBorrowLiquidity === void 0 && !debtAToken) {
|
|
24701
|
+
externalBorrowLiquidity = big3(scaleReads[s + 2]);
|
|
24702
|
+
}
|
|
24703
|
+
if (debtAToken) pendingDebtBalances.push({ index: out.length, token: m.targetAsset, holder: debtAToken });
|
|
24686
24704
|
out.push({
|
|
24687
24705
|
market: m,
|
|
24688
24706
|
creditTotalAssets,
|
|
@@ -24708,6 +24726,22 @@ async function fetchTwyneMarkets(lender, chainId) {
|
|
|
24708
24726
|
paused
|
|
24709
24727
|
});
|
|
24710
24728
|
});
|
|
24729
|
+
if (pendingDebtBalances.length > 0) {
|
|
24730
|
+
const balances = await multicallRetryUniversal({
|
|
24731
|
+
chain: chainId,
|
|
24732
|
+
calls: pendingDebtBalances.map((p) => ({
|
|
24733
|
+
address: p.token,
|
|
24734
|
+
name: "balanceOf",
|
|
24735
|
+
args: [p.holder]
|
|
24736
|
+
})),
|
|
24737
|
+
abi: ERC20_ABI,
|
|
24738
|
+
allowFailure: true
|
|
24739
|
+
});
|
|
24740
|
+
pendingDebtBalances.forEach((p, i) => {
|
|
24741
|
+
const v = big3(balances[i]);
|
|
24742
|
+
if (v !== void 0 && out[p.index]) out[p.index].externalBorrowLiquidity = v;
|
|
24743
|
+
});
|
|
24744
|
+
}
|
|
24711
24745
|
if (out.length === 0) return void 0;
|
|
24712
24746
|
return { lender, chainId, config, markets: out };
|
|
24713
24747
|
}
|
|
@@ -55610,16 +55644,116 @@ var fetchGearboxV3Pools = async (chainId, multicallRetry, prices = {}, tokenList
|
|
|
55610
55644
|
return converter(raw) ?? {};
|
|
55611
55645
|
};
|
|
55612
55646
|
|
|
55647
|
+
// src/vaults/curatorName.ts
|
|
55648
|
+
var STOP_WORDS = /* @__PURE__ */ new Set([
|
|
55649
|
+
"vault",
|
|
55650
|
+
"vaults",
|
|
55651
|
+
"savings",
|
|
55652
|
+
"yield",
|
|
55653
|
+
"exclusive",
|
|
55654
|
+
"dao",
|
|
55655
|
+
"x",
|
|
55656
|
+
"pt",
|
|
55657
|
+
"prime",
|
|
55658
|
+
"staked",
|
|
55659
|
+
"core",
|
|
55660
|
+
"rwa",
|
|
55661
|
+
"lista",
|
|
55662
|
+
// protocol brand; a bare "Lista …" vault has no distinct curator
|
|
55663
|
+
"moolah"
|
|
55664
|
+
]);
|
|
55665
|
+
var ASSET_TOKENS = /* @__PURE__ */ new Set([
|
|
55666
|
+
"usdc",
|
|
55667
|
+
"usdt",
|
|
55668
|
+
"usd1",
|
|
55669
|
+
"usds",
|
|
55670
|
+
"dai",
|
|
55671
|
+
"usde",
|
|
55672
|
+
"susde",
|
|
55673
|
+
"lisusd",
|
|
55674
|
+
"gho",
|
|
55675
|
+
"frax",
|
|
55676
|
+
"pyusd",
|
|
55677
|
+
"rusd",
|
|
55678
|
+
"usr",
|
|
55679
|
+
"rlp",
|
|
55680
|
+
"eth",
|
|
55681
|
+
"weth",
|
|
55682
|
+
"wsteth",
|
|
55683
|
+
"reth",
|
|
55684
|
+
"steth",
|
|
55685
|
+
"cbeth",
|
|
55686
|
+
"weeth",
|
|
55687
|
+
"ezeth",
|
|
55688
|
+
"btc",
|
|
55689
|
+
"wbtc",
|
|
55690
|
+
"btcb",
|
|
55691
|
+
"cbbtc",
|
|
55692
|
+
"tbtc",
|
|
55693
|
+
"xaut",
|
|
55694
|
+
"xrp",
|
|
55695
|
+
"bnb",
|
|
55696
|
+
"wbnb",
|
|
55697
|
+
"sol",
|
|
55698
|
+
"op",
|
|
55699
|
+
"arb",
|
|
55700
|
+
"avax",
|
|
55701
|
+
"pol",
|
|
55702
|
+
"matic",
|
|
55703
|
+
"sei",
|
|
55704
|
+
"celo",
|
|
55705
|
+
"hype",
|
|
55706
|
+
"plume",
|
|
55707
|
+
"s"
|
|
55708
|
+
]);
|
|
55709
|
+
var isAssetToken = (tl, asset) => {
|
|
55710
|
+
if (asset && tl === asset || ASSET_TOKENS.has(tl) || tl.includes("usd")) {
|
|
55711
|
+
return true;
|
|
55712
|
+
}
|
|
55713
|
+
const unwrapped = tl.replace(/^(cb|wst|ws|w|st)/, "");
|
|
55714
|
+
return unwrapped !== tl && ASSET_TOKENS.has(unwrapped);
|
|
55715
|
+
};
|
|
55716
|
+
function curatorNameFromVaultName(name, assetSymbol) {
|
|
55717
|
+
if (!name) return void 0;
|
|
55718
|
+
if (/\b(test|testing|fake)\b/i.test(name)) return void 0;
|
|
55719
|
+
const by = /\bby\s+(.{2,})$/i.exec(name);
|
|
55720
|
+
if (by) {
|
|
55721
|
+
const suffix = by[1].trim().split(/\s+/).slice(0, 3).join(" ");
|
|
55722
|
+
if (suffix.length >= 2 && !isAssetToken(suffix.toLowerCase(), (assetSymbol ?? "").toLowerCase())) {
|
|
55723
|
+
return suffix;
|
|
55724
|
+
}
|
|
55725
|
+
}
|
|
55726
|
+
const cleaned = name.replace(/\([^)]*\)\s*$/, "").split(":")[0].trim();
|
|
55727
|
+
if (!cleaned) return void 0;
|
|
55728
|
+
const tokens = cleaned.split(/[\s/]+/).flatMap((t) => t.split("-")).filter(Boolean);
|
|
55729
|
+
const asset = (assetSymbol ?? "").toLowerCase();
|
|
55730
|
+
const out = [];
|
|
55731
|
+
let terminated = false;
|
|
55732
|
+
for (const tok of tokens) {
|
|
55733
|
+
const tl = tok.toLowerCase();
|
|
55734
|
+
if (STOP_WORDS.has(tl) || isAssetToken(tl, asset)) {
|
|
55735
|
+
terminated = true;
|
|
55736
|
+
break;
|
|
55737
|
+
}
|
|
55738
|
+
out.push(tok);
|
|
55739
|
+
if (out.length >= 3) break;
|
|
55740
|
+
}
|
|
55741
|
+
if (!terminated || out.length === tokens.length) return void 0;
|
|
55742
|
+
const curator = out.join(" ").trim();
|
|
55743
|
+
return curator.length >= 2 ? curator : void 0;
|
|
55744
|
+
}
|
|
55745
|
+
|
|
55613
55746
|
// src/vaults/morpho/fetchFromApi.ts
|
|
55614
55747
|
var MORPHO_SHARE_DECIMALS = 18;
|
|
55615
55748
|
var MORPHO_API_URL = "https://blue-api.morpho.org/graphql";
|
|
55616
55749
|
var PAGE_SIZE2 = 200;
|
|
55750
|
+
var MIN_TOTAL_ASSETS_USD = 100;
|
|
55617
55751
|
var vaultsQuery = (first, skip, chainId) => `
|
|
55618
55752
|
query GetVaults {
|
|
55619
55753
|
vaults(
|
|
55620
55754
|
first: ${first},
|
|
55621
55755
|
skip: ${skip},
|
|
55622
|
-
where: { chainId_in: [${chainId}],
|
|
55756
|
+
where: { chainId_in: [${chainId}], totalAssetsUsd_gte: ${MIN_TOTAL_ASSETS_USD} },
|
|
55623
55757
|
orderBy: TotalAssetsUsd,
|
|
55624
55758
|
orderDirection: Desc
|
|
55625
55759
|
) {
|
|
@@ -55738,6 +55872,7 @@ function parseVault2(v, chainId, prices, tokenList) {
|
|
|
55738
55872
|
const totalAssetsUsd = apiTotalAssetsUsd || totalAssetsFormatted * resolvedPriceUsd;
|
|
55739
55873
|
const curators = parseCurators(state.curators);
|
|
55740
55874
|
const primaryCurator = curators?.[0];
|
|
55875
|
+
const curatorName = primaryCurator?.name ?? curatorNameFromVaultName(v.name, v.asset?.symbol ?? assetMeta?.symbol);
|
|
55741
55876
|
return {
|
|
55742
55877
|
address,
|
|
55743
55878
|
underlying: assetAddr,
|
|
@@ -55745,7 +55880,7 @@ function parseVault2(v, chainId, prices, tokenList) {
|
|
|
55745
55880
|
name: v.name ?? "",
|
|
55746
55881
|
displayName: composeVaultDisplayName(
|
|
55747
55882
|
"Morpho",
|
|
55748
|
-
|
|
55883
|
+
curatorName,
|
|
55749
55884
|
assetMeta,
|
|
55750
55885
|
v.name ?? void 0
|
|
55751
55886
|
),
|
|
@@ -55758,11 +55893,13 @@ function parseVault2(v, chainId, prices, tokenList) {
|
|
|
55758
55893
|
depositRate: supplyRate + rewardsRate,
|
|
55759
55894
|
fee: Number(state.fee ?? 0) * 100,
|
|
55760
55895
|
timelock: Number(state.timelock ?? 0),
|
|
55896
|
+
// Since Aug-2026 `listed` means "listed in the Morpho app" (a far smaller
|
|
55897
|
+
// set than the old curated flag) — informational only, never a row filter.
|
|
55761
55898
|
whitelisted: v.whitelisted ?? true,
|
|
55762
55899
|
owner: state.owner?.toLowerCase() || void 0,
|
|
55763
55900
|
curator: state.curator?.toLowerCase() || void 0,
|
|
55764
55901
|
guardian: state.guardian?.toLowerCase() || void 0,
|
|
55765
|
-
curatorName
|
|
55902
|
+
curatorName,
|
|
55766
55903
|
curatorImage: primaryCurator?.image,
|
|
55767
55904
|
curators,
|
|
55768
55905
|
asset: assetMeta,
|
|
@@ -55774,7 +55911,7 @@ function parseVault2(v, chainId, prices, tokenList) {
|
|
|
55774
55911
|
liquidityUsd: liquidityUsd || liquidityFormatted * resolvedPriceUsd
|
|
55775
55912
|
};
|
|
55776
55913
|
}
|
|
55777
|
-
async function fetchMorphoVaultsFromApi(chainId, prices = {}, tokenList = {}, maxItems =
|
|
55914
|
+
async function fetchMorphoVaultsFromApi(chainId, prices = {}, tokenList = {}, maxItems = 1e3) {
|
|
55778
55915
|
const out = {};
|
|
55779
55916
|
let skip = 0;
|
|
55780
55917
|
while (skip < maxItems) {
|
|
@@ -56415,107 +56552,6 @@ var fetchMorphoVaults = async (chainId, multicallRetry, prices = {}, tokenList =
|
|
|
56415
56552
|
}
|
|
56416
56553
|
return fetchMorphoVaultsFromApi(chainId, prices, tokenList);
|
|
56417
56554
|
};
|
|
56418
|
-
|
|
56419
|
-
// src/vaults/curatorName.ts
|
|
56420
|
-
var STOP_WORDS = /* @__PURE__ */ new Set([
|
|
56421
|
-
"vault",
|
|
56422
|
-
"vaults",
|
|
56423
|
-
"savings",
|
|
56424
|
-
"yield",
|
|
56425
|
-
"exclusive",
|
|
56426
|
-
"dao",
|
|
56427
|
-
"x",
|
|
56428
|
-
"pt",
|
|
56429
|
-
"prime",
|
|
56430
|
-
"staked",
|
|
56431
|
-
"core",
|
|
56432
|
-
"rwa",
|
|
56433
|
-
"lista",
|
|
56434
|
-
// protocol brand; a bare "Lista …" vault has no distinct curator
|
|
56435
|
-
"moolah"
|
|
56436
|
-
]);
|
|
56437
|
-
var ASSET_TOKENS = /* @__PURE__ */ new Set([
|
|
56438
|
-
"usdc",
|
|
56439
|
-
"usdt",
|
|
56440
|
-
"usd1",
|
|
56441
|
-
"usds",
|
|
56442
|
-
"dai",
|
|
56443
|
-
"usde",
|
|
56444
|
-
"susde",
|
|
56445
|
-
"lisusd",
|
|
56446
|
-
"gho",
|
|
56447
|
-
"frax",
|
|
56448
|
-
"pyusd",
|
|
56449
|
-
"rusd",
|
|
56450
|
-
"usr",
|
|
56451
|
-
"rlp",
|
|
56452
|
-
"eth",
|
|
56453
|
-
"weth",
|
|
56454
|
-
"wsteth",
|
|
56455
|
-
"reth",
|
|
56456
|
-
"steth",
|
|
56457
|
-
"cbeth",
|
|
56458
|
-
"weeth",
|
|
56459
|
-
"ezeth",
|
|
56460
|
-
"btc",
|
|
56461
|
-
"wbtc",
|
|
56462
|
-
"btcb",
|
|
56463
|
-
"cbbtc",
|
|
56464
|
-
"tbtc",
|
|
56465
|
-
"xaut",
|
|
56466
|
-
"xrp",
|
|
56467
|
-
"bnb",
|
|
56468
|
-
"wbnb",
|
|
56469
|
-
"sol",
|
|
56470
|
-
"op",
|
|
56471
|
-
"arb",
|
|
56472
|
-
"avax",
|
|
56473
|
-
"pol",
|
|
56474
|
-
"matic",
|
|
56475
|
-
"sei",
|
|
56476
|
-
"celo",
|
|
56477
|
-
"hype",
|
|
56478
|
-
"plume",
|
|
56479
|
-
"s"
|
|
56480
|
-
]);
|
|
56481
|
-
var isAssetToken = (tl, asset) => {
|
|
56482
|
-
if (asset && tl === asset || ASSET_TOKENS.has(tl) || tl.includes("usd")) {
|
|
56483
|
-
return true;
|
|
56484
|
-
}
|
|
56485
|
-
const unwrapped = tl.replace(/^(cb|wst|ws|w|st)/, "");
|
|
56486
|
-
return unwrapped !== tl && ASSET_TOKENS.has(unwrapped);
|
|
56487
|
-
};
|
|
56488
|
-
function curatorNameFromVaultName(name, assetSymbol) {
|
|
56489
|
-
if (!name) return void 0;
|
|
56490
|
-
if (/\b(test|testing|fake)\b/i.test(name)) return void 0;
|
|
56491
|
-
const by = /\bby\s+(.{2,})$/i.exec(name);
|
|
56492
|
-
if (by) {
|
|
56493
|
-
const suffix = by[1].trim().split(/\s+/).slice(0, 3).join(" ");
|
|
56494
|
-
if (suffix.length >= 2 && !isAssetToken(suffix.toLowerCase(), (assetSymbol ?? "").toLowerCase())) {
|
|
56495
|
-
return suffix;
|
|
56496
|
-
}
|
|
56497
|
-
}
|
|
56498
|
-
const cleaned = name.replace(/\([^)]*\)\s*$/, "").split(":")[0].trim();
|
|
56499
|
-
if (!cleaned) return void 0;
|
|
56500
|
-
const tokens = cleaned.split(/[\s/]+/).flatMap((t) => t.split("-")).filter(Boolean);
|
|
56501
|
-
const asset = (assetSymbol ?? "").toLowerCase();
|
|
56502
|
-
const out = [];
|
|
56503
|
-
let terminated = false;
|
|
56504
|
-
for (const tok of tokens) {
|
|
56505
|
-
const tl = tok.toLowerCase();
|
|
56506
|
-
if (STOP_WORDS.has(tl) || isAssetToken(tl, asset)) {
|
|
56507
|
-
terminated = true;
|
|
56508
|
-
break;
|
|
56509
|
-
}
|
|
56510
|
-
out.push(tok);
|
|
56511
|
-
if (out.length >= 3) break;
|
|
56512
|
-
}
|
|
56513
|
-
if (!terminated || out.length === tokens.length) return void 0;
|
|
56514
|
-
const curator = out.join(" ").trim();
|
|
56515
|
-
return curator.length >= 2 ? curator : void 0;
|
|
56516
|
-
}
|
|
56517
|
-
|
|
56518
|
-
// src/vaults/morpho/fetchListaFromChain.ts
|
|
56519
56555
|
var { chunk: chunk6 } = lodash;
|
|
56520
56556
|
var LISTA_PROTOCOL = "LISTA_DAO";
|
|
56521
56557
|
var LISTA_LENS_ABI = parseAbi([
|
|
@@ -72451,7 +72487,10 @@ var twyneAdapter = {
|
|
|
72451
72487
|
description: [
|
|
72452
72488
|
`Your collateral stays in ${externalName}; Twyne only reserves other lenders\u2019 unused borrowing power so the same collateral supports a larger loan.`,
|
|
72453
72489
|
bandNote,
|
|
72454
|
-
creditApr != null ? `On top of ${externalName}\u2019s borrow rate you pay ${creditApr.toFixed(3)} % a year on the RESERVED CREDIT only \u2014 not on your debt \u2014 and it is charged in the collateral asset.` : void 0
|
|
72490
|
+
creditApr != null ? `On top of ${externalName}\u2019s borrow rate you pay ${creditApr.toFixed(3)} % a year on the RESERVED CREDIT only \u2014 not on your debt \u2014 and it is charged in the collateral asset.` : void 0,
|
|
72491
|
+
// The loan is perpetual; the COLLATERAL is what expires. Said here
|
|
72492
|
+
// rather than in `maturity`, which would mis-type the loan itself.
|
|
72493
|
+
maturity != null && matured ? "This market\u2019s collateral has already matured. Existing positions can still be repaid and closed, but nothing new should be opened against it." : maturity != null ? `Your loan has no end date, but the collateral is a fixed-maturity token that stops accreting on ${new Date(maturity * 1e3).toISOString().slice(0, 10)}, and ${externalName}\u2019s risk parameters move as that date approaches.` : void 0
|
|
72455
72494
|
].filter(Boolean).join(" ")
|
|
72456
72495
|
},
|
|
72457
72496
|
availability: {
|
|
@@ -72485,21 +72524,20 @@ var twyneAdapter = {
|
|
|
72485
72524
|
description: `Twyne liquidates first, above your chosen LTV. ${externalName}\u2019s own threshold of ${pct2(externalLiqLtv)} is the backstop, and reaching it is the bad case.`
|
|
72486
72525
|
} : {}
|
|
72487
72526
|
},
|
|
72488
|
-
//
|
|
72489
|
-
//
|
|
72490
|
-
//
|
|
72491
|
-
|
|
72492
|
-
|
|
72493
|
-
|
|
72494
|
-
|
|
72495
|
-
|
|
72496
|
-
|
|
72497
|
-
|
|
72498
|
-
|
|
72499
|
-
|
|
72500
|
-
|
|
72501
|
-
|
|
72502
|
-
} : {}
|
|
72527
|
+
// THE LOAN IS PERPETUAL. Only the COLLATERAL expires.
|
|
72528
|
+
//
|
|
72529
|
+
// The first version of this adapter put the PT's expiry on
|
|
72530
|
+
// `borrow.maturity` with `kind: 'fixed-date'`, and that is wrong in a
|
|
72531
|
+
// way that shows up immediately in a UI: every consumer reads that field
|
|
72532
|
+
// as "this is a fixed-TERM loan", so the market rendered with a `Fixed`
|
|
72533
|
+
// borrow-rate badge and no APR — a fixed-rate product Twyne does not
|
|
72534
|
+
// offer. A Twyne loan has no end date, no rollover and no settlement;
|
|
72535
|
+
// it accrues at the external market's variable rate until repaid.
|
|
72536
|
+
//
|
|
72537
|
+
// What the collateral's expiry actually means is carried where it
|
|
72538
|
+
// belongs: `twyne.collateralMaturity` / `collateralMatured` on the
|
|
72539
|
+
// market descriptor (computed at read time), and stated in prose here.
|
|
72540
|
+
maturity: { kind: "perpetual" }
|
|
72503
72541
|
}
|
|
72504
72542
|
};
|
|
72505
72543
|
}
|
|
@@ -73104,6 +73142,10 @@ function resolveBasket(row) {
|
|
|
73104
73142
|
const f = row.fluid;
|
|
73105
73143
|
if (f && f.isSmartCol !== true) return void 0;
|
|
73106
73144
|
const legs = (f?.collateralPair ?? []).map((a) => addr3(a)).filter((a) => !!a).map((address) => ({ address }));
|
|
73145
|
+
if (legs.length > 0) {
|
|
73146
|
+
const rowAsset = addr3(row.underlying) ?? addr3(row.asset?.address);
|
|
73147
|
+
if (!rowAsset || !legs.some((l) => l.address === rowAsset)) return void 0;
|
|
73148
|
+
}
|
|
73107
73149
|
return {
|
|
73108
73150
|
// Fluid emits one row PER LEG of the pool, so this row is a leg and a
|
|
73109
73151
|
// consumer that sums the listing without deduping counts the position
|