@1delta/margin-fetcher 5.0.91 → 5.0.93
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 +190 -9
- package/dist/index.js +1079 -57
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { parseAbi, keccak256, encodeAbiParameters, formatEther, BaseError, erc20Abi, isAddress, stringToHex, pad, encodeFunctionData, decodeFunctionResult, decodeAbiParameters, formatUnits, getAddress, toBytes, slice, concat, AbiEncodingLengthMismatchError, concatHex, parseAbiParameters, hexToString, InvalidAddressError, boolToHex, integerRegex, numberToHex, bytesRegex, BytesSizeMismatchError, arrayRegex, UnsupportedPackedAbiType } from './chunk-JUYF2XLF.js';
|
|
2
2
|
import './chunk-BYTNVMX7.js';
|
|
3
3
|
import './chunk-PR4QN5HX.js';
|
|
4
|
-
import { Lender, isExactly, isMidnight, isTerm, isTermMax, isTeller, isListaDao, isLiquityFamily, isRiver, isInverse, isCooler, isDssType, isCompoundV3Type, isFluid, isGearboxV3, isLlamaLend, isFrankencoin, isResupply, isCurvance, isFlyingTulip, isTwyne, isFraxlend, isAaveV4Type, LIQUITY_FAMILY_LENDERS, isAaveType, isCompoundV3, isCompoundV2Type, isMultiMarket, isSiloV2Type, isSiloV3Type, isDolomite, isMorphoType, isUsdd, isSky, hasCrossMarginRisk, isEulerType, isInit, isVenusType, isSumerType, AAVE_V3_LENDERS, AAVE_V2_LENDERS, isMorphoBlue, isAaveV2Type, isAaveV32Type, isAaveV3Type, isYLDR, isLista, hasSubAccounts, isTectonicType, isKineticType, isBenqiType } from '@1delta/lender-registry';
|
|
4
|
+
import { Lender, isExactly, isMidnight, isTerm, isTermMax, isTeller, isListaDao, isLiquityFamily, isRiver, isInverse, isCooler, isDssType, isCompoundV3Type, isFluid, isGearboxV3, isLlamaLend, isFrankencoin, isResupply, isCurvance, isFlyingTulip, isTwyne, isFraxlend, isAaveV4Type, isKamino, isJupiterLend, isSave, isLoopscale, isProject0, LIQUITY_FAMILY_LENDERS, isAaveType, isCompoundV3, isCompoundV2Type, isMultiMarket, isSiloV2Type, isSiloV3Type, isDolomite, isMorphoType, isUsdd, isSky, hasCrossMarginRisk, isEulerType, isInit, isVenusType, normalizeLenderKey, isSumerType, AAVE_V3_LENDERS, AAVE_V2_LENDERS, isMorphoBlue, kaminoMarketFromKey, jupiterLendVaultFromKey, saveMarketFromKey, loopscaleMarketFromKey, project0GroupFromKey, isAaveV2Type, isAaveV32Type, isAaveV3Type, 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
6
|
import { fetchTokenLists, fetchTokenList, aavePools, compoundV3Pools, initConfig, morphoPools, compoundV2Pools, eulerVaults, siloMarkets, siloV2LenderKey, siloMarketsV3, siloV3LenderKey, aaveV4Spokes, aaveV4SpokeLenderKey, fluidResolvers, gearboxResolvers, dolomiteConfigs, midnightConfig, termConfig, termMarketsByChain, exactlyConfig, flyingTulipLendersByChain, liquityLendersByChain, riverLendersByChain, inverseLendersByChain, coolerLendersByChain, llamaLendLendersByChain, usddLendersByChain, skyLendersByChain, frankencoinLendersByChain, resupplyLendersByChain, curvanceLendersByChain, fraxlendLendersByChain, twyneLendersByChain, tellerConfigByChain, tellerPoolsByChain, termMaxConfigByChain, aaveReserves, compoundV3Reserves, dolomiteIsolationMarket, morphoTypeMarkets, resolveTermApiBase, flyingTulipConfigFor, flyingTulipAssetsFor, liquityConfigFor, liquityBranchesByChain, riverConfigFor, riverChainData, termMaxApiBaseUrl, termMaxLenderKey, inverseConfigFor, inverseChainData, coolerConfigFor, llamaLendConfigFor, llamaLendChainData, llamaLendApiBaseUrl, resupplyConfigFor, fraxlendConfigFor, dssConfigFor, dssChainData, dssDebtToken, dssDebtJoin, frankencoinConfigFor, frankencoinChainData, aaveTokens, compoundV3BaseData, compoundV2TokenArray, morphoTypeVaults, eulerConfigs, fluidVaultEntries, gearboxMarketConfigurators, dolomiteIsolation, liquityMarkets, riverMarkets, tellerConfig, tellerPools, termMarkets, termMaxConfig, midnightMarkets, midnightCollateralRef, llamaLendMarkets, fraxlendPairsFor, inverseMarkets, curvanceConfig, frankencoinMarkets, twyneMarkets, twyneConfigFor, exactlyMarkets, aaveOracles, resolveMidnightApiBase, llamaLendMarketByVault, getSiloV2MarketEntry, getSiloV3MarketEntry, dolomiteEmode, curvanceConfigFor, listaCollateralProvider, gearboxMarketCompressor, gearboxV3LenderKey, midnightMarketsByChain, twyneChainData, parseAaveV4SpokeLenderKey, gearboxAccountCompressor, compoundV2Tokens, exactlyMarketsByChain, aaveOraclesConfig, compoundV2Oracles, compoundV2OraclesConfig, compoundV3OraclesData, compoundV2Reserves, aaveV4Oracles, morphoTypeOracles } from '@1delta/data-sdk';
|
|
7
7
|
import lodash from 'lodash';
|
|
@@ -12,7 +12,7 @@ export { MorphoLensAbi } from '@1delta/abis';
|
|
|
12
12
|
import { prepareDebitDataMulticall, prepareLenderDebitMulticall, parseDebitDataResult, parseLenderDebitResult, getPermit2ContractAddress, getLstAcceptedInputs, savingsVerbRequires, savingsSupportsVerb, getCompoundV2Comptroller as getCompoundV2Comptroller$1, getCompoundV3CometAddress as getCompoundV3CometAddress$1, getMorphoAddress, FLUID_VAULT_FACTORY, getAaveStyleLenderTokenAddress, LendingMode, getAaveCollateralTokenAddress, getSiloHalfForUnderlying, findSavingsWithdrawEntry, bandLtvCurve, InitMarginAddresses, ignoresReceiver, buildLstWithdrawRequest, SAVINGS_RECEIVER_CAPABILITY } from '@1delta/calldata-sdk';
|
|
13
13
|
import { proxyNativeFetch } from '@1delta/proxy-fetch';
|
|
14
14
|
import { BALANCER_V2_FORKS, BALANCER_V3_FORKS, UNISWAP_V4_FORKS, isFlashLoanSourceExcluded, FLASH_LOAN_IDS } from '@1delta/dex-registry';
|
|
15
|
-
import { getNativeDecimals } from '@1delta/wnative';
|
|
15
|
+
import { getNativeDecimals, getWrappedNativeAddressSafe, isNativeWrapOneToOne } from '@1delta/wnative';
|
|
16
16
|
|
|
17
17
|
// src/abis/aave-v2/ProtocolDataProvider.ts
|
|
18
18
|
var ProtocolDataProviderAbi = [
|
|
@@ -7436,6 +7436,7 @@ var getAaveV3ReservesDataConverter = (lender, chainId, prices, additionalYields,
|
|
|
7436
7436
|
const asset = assetsToQuery[i];
|
|
7437
7437
|
const reserveData = data[i * stride];
|
|
7438
7438
|
const configData = data[i * stride + 1];
|
|
7439
|
+
const siloedBorrowing = data[i * stride + 2] === true;
|
|
7439
7440
|
const reserveCaps = data[i * stride + 3];
|
|
7440
7441
|
const debtCeiling = data[i * stride + 4];
|
|
7441
7442
|
const reserveEMode = data[i * stride + 5];
|
|
@@ -7542,6 +7543,7 @@ var getAaveV3ReservesDataConverter = (lender, chainId, prices, additionalYields,
|
|
|
7542
7543
|
collateralActive: usageAsCollateralEnabled,
|
|
7543
7544
|
borrowingEnabled,
|
|
7544
7545
|
depositsEnabled: true,
|
|
7546
|
+
...siloedBorrowing ? { siloedBorrowing: true } : {},
|
|
7545
7547
|
hasStable: configData?.[7 /* stableBorrowRateEnabled */],
|
|
7546
7548
|
isActive: configData?.[8 /* isActive */],
|
|
7547
7549
|
isFrozen: configData?.[9 /* isFrozen */],
|
|
@@ -7875,6 +7877,7 @@ function parseAave32(chainId, lender, prices, additionalYields, tokenList) {
|
|
|
7875
7877
|
const asset = assetsToQuery[i];
|
|
7876
7878
|
const reserveData = data[i * stride];
|
|
7877
7879
|
const configData = data[i * stride + 1];
|
|
7880
|
+
const siloedBorrowing = data[i * stride + 2] === true;
|
|
7878
7881
|
const reserveCaps = data[i * stride + 3];
|
|
7879
7882
|
const debtCeiling = data[i * stride + 4];
|
|
7880
7883
|
const aTokenBalanceRaw = data[i * stride + 5];
|
|
@@ -7981,6 +7984,7 @@ function parseAave32(chainId, lender, prices, additionalYields, tokenList) {
|
|
|
7981
7984
|
collateralActive: usageAsCollateralEnabled,
|
|
7982
7985
|
borrowingEnabled,
|
|
7983
7986
|
depositsEnabled: true,
|
|
7987
|
+
...siloedBorrowing ? { siloedBorrowing: true } : {},
|
|
7984
7988
|
hasStable: configData?.[7 /* stableBorrowRateEnabled */],
|
|
7985
7989
|
isActive: configData?.[8 /* isActive */],
|
|
7986
7990
|
isFrozen: configData?.[9 /* isFrozen */],
|
|
@@ -12043,6 +12047,9 @@ function createMultiAccountTypeUserState(payload, lenderData, histData, accountA
|
|
|
12043
12047
|
let collateral = 0;
|
|
12044
12048
|
let borrowDiscountedCollateral = 0;
|
|
12045
12049
|
let adjustedDebt = 0;
|
|
12050
|
+
let liquidationAdjustedDebt = 0;
|
|
12051
|
+
let hasLiquidationWeights = false;
|
|
12052
|
+
let collateralDebtCapacity = Infinity;
|
|
12046
12053
|
for (let i = 0; i < marketUids2.length; i++) {
|
|
12047
12054
|
const marketUid = marketUids2[i];
|
|
12048
12055
|
if (!lenderData?.[marketUid] || !payload.lendingPositions[posId][marketUid])
|
|
@@ -12070,6 +12077,13 @@ function createMultiAccountTypeUserState(payload, lenderData, histData, accountA
|
|
|
12070
12077
|
collateral += (config?.collateralFactor ?? 1) * depositsUSDOracle;
|
|
12071
12078
|
borrowDiscountedCollateral += (config?.borrowCollateralFactor ?? 1) * depositsUSDOracle;
|
|
12072
12079
|
adjustedDebt += (config?.borrowFactor ?? 1) * debtUSDOracle;
|
|
12080
|
+
if (config?.liquidationBorrowFactor != null) hasLiquidationWeights = true;
|
|
12081
|
+
liquidationAdjustedDebt += (config?.liquidationBorrowFactor ?? config?.borrowFactor ?? 1) * debtUSDOracle;
|
|
12082
|
+
if (config?.collateralDebtCapacity != null && Number(pos.deposits) > 0 && !config.collateralDisabled)
|
|
12083
|
+
collateralDebtCapacity = Math.min(
|
|
12084
|
+
collateralDebtCapacity,
|
|
12085
|
+
config.collateralDebtCapacity
|
|
12086
|
+
);
|
|
12073
12087
|
depositInterest += depositRate * depositsUSD;
|
|
12074
12088
|
borrowInterest += debtUSD * variableBorrowRate;
|
|
12075
12089
|
}
|
|
@@ -12082,6 +12096,7 @@ function createMultiAccountTypeUserState(payload, lenderData, histData, accountA
|
|
|
12082
12096
|
deposits,
|
|
12083
12097
|
debt,
|
|
12084
12098
|
adjustedDebt,
|
|
12099
|
+
...hasLiquidationWeights ? { liquidationAdjustedDebt } : {},
|
|
12085
12100
|
nav,
|
|
12086
12101
|
deposits24h: histData[posId]?.totalDeposits24h,
|
|
12087
12102
|
debt24h: histData[posId]?.totalDebt24h,
|
|
@@ -12139,6 +12154,11 @@ function createMultiAccountTypeUserState(payload, lenderData, histData, accountA
|
|
|
12139
12154
|
if (borrowLiquidity != null) {
|
|
12140
12155
|
borrowable = String(Math.min(Number(borrowable), borrowLiquidity));
|
|
12141
12156
|
}
|
|
12157
|
+
borrowable = capByModeDebtCapacity(
|
|
12158
|
+
borrowable,
|
|
12159
|
+
config?.debtCapacity,
|
|
12160
|
+
collateralDebtCapacity
|
|
12161
|
+
);
|
|
12142
12162
|
pos.withdrawable = withdrawable;
|
|
12143
12163
|
pos.borrowable = borrowable;
|
|
12144
12164
|
pos.underlyingInfo = buildUnderlyingInfo(
|
|
@@ -12149,6 +12169,11 @@ function createMultiAccountTypeUserState(payload, lenderData, histData, accountA
|
|
|
12149
12169
|
if (borrowLiquidity != null) {
|
|
12150
12170
|
borrowable = String(Math.min(Number(borrowable), borrowLiquidity));
|
|
12151
12171
|
}
|
|
12172
|
+
borrowable = capByModeDebtCapacity(
|
|
12173
|
+
borrowable,
|
|
12174
|
+
config?.debtCapacity,
|
|
12175
|
+
collateralDebtCapacity
|
|
12176
|
+
);
|
|
12152
12177
|
payload.lendingPositions[posId][marketUid] = {
|
|
12153
12178
|
marketUid,
|
|
12154
12179
|
deposits: "0",
|
|
@@ -12167,6 +12192,9 @@ function createMultiAccountTypeUserState(payload, lenderData, histData, accountA
|
|
|
12167
12192
|
accountId: posId,
|
|
12168
12193
|
...accountAddresses?.[posId] ? { accountAddress: accountAddresses[posId] } : {},
|
|
12169
12194
|
health: balanceData2.debt === 0 ? null : balanceData2.adjustedDebt > 0 ? balanceData2.borrowDiscountedCollateral / balanceData2.adjustedDebt : balanceData2.collateral / balanceData2.debt,
|
|
12195
|
+
...hasLiquidationWeights ? {
|
|
12196
|
+
liquidationHealth: balanceData2.debt === 0 ? null : balanceData2.collateral / liquidationAdjustedDebt
|
|
12197
|
+
} : {},
|
|
12170
12198
|
borrowCapacityUSD: creditLine,
|
|
12171
12199
|
userConfig,
|
|
12172
12200
|
// aggregated balance data
|
|
@@ -12183,6 +12211,13 @@ function createMultiAccountTypeUserState(payload, lenderData, histData, accountA
|
|
|
12183
12211
|
data
|
|
12184
12212
|
};
|
|
12185
12213
|
}
|
|
12214
|
+
function capByModeDebtCapacity(borrowable, debtCapacity, collateralDebtCapacity) {
|
|
12215
|
+
let cap = Infinity;
|
|
12216
|
+
if (debtCapacity != null) cap = Math.min(cap, Math.max(0, debtCapacity));
|
|
12217
|
+
if (Number.isFinite(collateralDebtCapacity))
|
|
12218
|
+
cap = Math.min(cap, Math.max(0, collateralDebtCapacity));
|
|
12219
|
+
return Number.isFinite(cap) ? String(Math.min(Number(borrowable), cap)) : borrowable;
|
|
12220
|
+
}
|
|
12186
12221
|
|
|
12187
12222
|
// src/lending/user-data/utils/readContext.ts
|
|
12188
12223
|
var blockNumberFromTag = (blockTag) => {
|
|
@@ -44152,15 +44187,19 @@ function fuseLenderData(userDataResult, summary) {
|
|
|
44152
44187
|
);
|
|
44153
44188
|
return entries;
|
|
44154
44189
|
}
|
|
44155
|
-
|
|
44156
|
-
// src/lending/user-data/read/select.ts
|
|
44157
44190
|
var PREFIX_LENDERS = /* @__PURE__ */ new Set([
|
|
44158
44191
|
"MORPHO_BLUE",
|
|
44159
44192
|
"LISTA_DAO",
|
|
44160
44193
|
"COMPOUND_V3",
|
|
44161
|
-
"CURVANCE"
|
|
44194
|
+
"CURVANCE",
|
|
44195
|
+
// Solana families — every one fans out to per-market keys
|
|
44196
|
+
"KAMINO",
|
|
44197
|
+
"JUPITER_LEND",
|
|
44198
|
+
"SAVE",
|
|
44199
|
+
"LOOPSCALE",
|
|
44200
|
+
"PROJECT_0"
|
|
44162
44201
|
]);
|
|
44163
|
-
var parseLenderKey = (raw) => raw
|
|
44202
|
+
var parseLenderKey = (raw) => normalizeLenderKey(raw);
|
|
44164
44203
|
function filterLenderMeta(meta, filter) {
|
|
44165
44204
|
const lenders = filter?.lenders;
|
|
44166
44205
|
if (!lenders?.length) return meta;
|
|
@@ -50765,7 +50804,7 @@ var BITWAY_LEGS2 = [
|
|
|
50765
50804
|
"USDT",
|
|
50766
50805
|
"0x5c4a6903732532eeb3ae0803e062d8ae25d52bd1",
|
|
50767
50806
|
"0x2b8464ffb2b77de64cfefdeb00ad925576f157cb",
|
|
50768
|
-
"
|
|
50807
|
+
"Absolute Return strategy (0.5% instant-exit fee)"
|
|
50769
50808
|
],
|
|
50770
50809
|
[
|
|
50771
50810
|
"bwU",
|
|
@@ -50775,7 +50814,7 @@ var BITWAY_LEGS2 = [
|
|
|
50775
50814
|
"U",
|
|
50776
50815
|
"0x5c4a6903732532eeb3ae0803e062d8ae25d52bd1",
|
|
50777
50816
|
"0x2b8464ffb2b77de64cfefdeb00ad925576f157cb",
|
|
50778
|
-
"
|
|
50817
|
+
"Absolute Return strategy (0.5% instant-exit fee)"
|
|
50779
50818
|
],
|
|
50780
50819
|
[
|
|
50781
50820
|
"bwBTW",
|
|
@@ -50785,7 +50824,7 @@ var BITWAY_LEGS2 = [
|
|
|
50785
50824
|
"BTW",
|
|
50786
50825
|
"0x5c4a6903732532eeb3ae0803e062d8ae25d52bd1",
|
|
50787
50826
|
"0x2b8464ffb2b77de64cfefdeb00ad925576f157cb",
|
|
50788
|
-
"
|
|
50827
|
+
"Absolute Return strategy (0.5% instant-exit fee). The rate is denominated in BTW, Bitway's own volatile token \u2014 not in dollars"
|
|
50789
50828
|
],
|
|
50790
50829
|
[
|
|
50791
50830
|
"BTWUSDT",
|
|
@@ -50795,7 +50834,7 @@ var BITWAY_LEGS2 = [
|
|
|
50795
50834
|
"USDT",
|
|
50796
50835
|
"0xb82e32062c773c7748776c06fdb11b92edae3b63",
|
|
50797
50836
|
"0xfc8e6b1ab1a4c37724f8bc797730afa8d01d04ef",
|
|
50798
|
-
"
|
|
50837
|
+
"Core Alpha strategy (no instant-exit fee live; ~1M per-user stake cap)"
|
|
50799
50838
|
],
|
|
50800
50839
|
[
|
|
50801
50840
|
"BTWUSD1",
|
|
@@ -50805,7 +50844,7 @@ var BITWAY_LEGS2 = [
|
|
|
50805
50844
|
"USD1",
|
|
50806
50845
|
"0xb82e32062c773c7748776c06fdb11b92edae3b63",
|
|
50807
50846
|
"0xfc8e6b1ab1a4c37724f8bc797730afa8d01d04ef",
|
|
50808
|
-
"
|
|
50847
|
+
"Core Alpha strategy (no instant-exit fee live; ~1M per-user stake cap)"
|
|
50809
50848
|
],
|
|
50810
50849
|
[
|
|
50811
50850
|
"BTWU",
|
|
@@ -50815,7 +50854,7 @@ var BITWAY_LEGS2 = [
|
|
|
50815
50854
|
"U",
|
|
50816
50855
|
"0xb82e32062c773c7748776c06fdb11b92edae3b63",
|
|
50817
50856
|
"0xfc8e6b1ab1a4c37724f8bc797730afa8d01d04ef",
|
|
50818
|
-
"
|
|
50857
|
+
"Core Alpha strategy (no instant-exit fee live; ~1M per-user stake cap)"
|
|
50819
50858
|
]
|
|
50820
50859
|
];
|
|
50821
50860
|
var BITWAY_ENTRIES = {
|
|
@@ -63491,15 +63530,20 @@ function parseVault3(entry, results, chainId, prices, tokenList, marketIds, rate
|
|
|
63491
63530
|
// src/vaults/morpho/rateSanity.ts
|
|
63492
63531
|
var IMPLAUSIBLE_APR_PERCENT = 100;
|
|
63493
63532
|
var PINNED_LIQUIDITY_FRACTION = 1e-3;
|
|
63533
|
+
var DEAD_LIQUIDITY_FRACTION = 1e-6;
|
|
63534
|
+
var DEAD_APR_PERCENT = 25;
|
|
63494
63535
|
var isUnrealizableRate = (v) => isPinnedMarketRate({
|
|
63495
63536
|
aprPercent: v.depositRate,
|
|
63496
63537
|
totalAssets: v.totalAssetsFormatted,
|
|
63497
63538
|
liquidity: v.liquidityFormatted
|
|
63498
63539
|
});
|
|
63499
63540
|
var isPinnedMarketRate = (args) => {
|
|
63500
|
-
if (!(args.aprPercent > IMPLAUSIBLE_APR_PERCENT)) return false;
|
|
63501
63541
|
if (!(args.totalAssets > 0)) return false;
|
|
63502
|
-
|
|
63542
|
+
const withdrawableShare = args.liquidity / args.totalAssets;
|
|
63543
|
+
if (args.aprPercent > IMPLAUSIBLE_APR_PERCENT && withdrawableShare < PINNED_LIQUIDITY_FRACTION) {
|
|
63544
|
+
return true;
|
|
63545
|
+
}
|
|
63546
|
+
return args.aprPercent > DEAD_APR_PERCENT && withdrawableShare < DEAD_LIQUIDITY_FRACTION;
|
|
63503
63547
|
};
|
|
63504
63548
|
var dropUnrealizableRates = (vaults) => {
|
|
63505
63549
|
const entries = Object.entries(vaults);
|
|
@@ -74592,7 +74636,7 @@ var fetchGmxVaults = async (chainId, multicallRetry, options) => {
|
|
|
74592
74636
|
const symbolOf = /* @__PURE__ */ new Map();
|
|
74593
74637
|
for (const t of tokens) symbolOf.set(t.address.toLowerCase(), t.symbol);
|
|
74594
74638
|
const out = {};
|
|
74595
|
-
const
|
|
74639
|
+
const build6 = (address, name, kind, longToken, shortToken, indexToken, entry) => {
|
|
74596
74640
|
const longSymbol = symbolOf.get(longToken.toLowerCase());
|
|
74597
74641
|
const shortSymbol = symbolOf.get(shortToken.toLowerCase());
|
|
74598
74642
|
return {
|
|
@@ -74616,7 +74660,7 @@ var fetchGmxVaults = async (chainId, multicallRetry, options) => {
|
|
|
74616
74660
|
for (const m of markets) {
|
|
74617
74661
|
if (!m.isListed) continue;
|
|
74618
74662
|
const key3 = m.marketToken.toLowerCase();
|
|
74619
|
-
out[key3] =
|
|
74663
|
+
out[key3] = build6(
|
|
74620
74664
|
m.marketToken,
|
|
74621
74665
|
m.name,
|
|
74622
74666
|
"gm",
|
|
@@ -74629,7 +74673,7 @@ var fetchGmxVaults = async (chainId, multicallRetry, options) => {
|
|
|
74629
74673
|
for (const g of glvs) {
|
|
74630
74674
|
if (!g.isListed) continue;
|
|
74631
74675
|
const key3 = g.glvToken.toLowerCase();
|
|
74632
|
-
out[key3] =
|
|
74676
|
+
out[key3] = build6(
|
|
74633
74677
|
g.glvToken,
|
|
74634
74678
|
g.name,
|
|
74635
74679
|
"glv",
|
|
@@ -74984,10 +75028,10 @@ async function getJson4(url, label) {
|
|
|
74984
75028
|
}
|
|
74985
75029
|
return response.json();
|
|
74986
75030
|
}
|
|
74987
|
-
function cache4(slot,
|
|
75031
|
+
function cache4(slot, build6, store) {
|
|
74988
75032
|
const now = Date.now();
|
|
74989
75033
|
if (slot && now - slot.at < CACHE_TTL_MS6) return slot.promise;
|
|
74990
|
-
const promise =
|
|
75034
|
+
const promise = build6();
|
|
74991
75035
|
const entry = { at: now, promise };
|
|
74992
75036
|
store(entry);
|
|
74993
75037
|
promise.catch(() => store(void 0));
|
|
@@ -76519,6 +76563,134 @@ var TERM_PROFILES = [
|
|
|
76519
76563
|
},
|
|
76520
76564
|
docsUrl: "https://docs.morpho.org/morpho/concepts/markets"
|
|
76521
76565
|
}),
|
|
76566
|
+
// ── Solana lenders ───────────────────────────────────────────────────────
|
|
76567
|
+
// Ported from margin-fetcher-sol's profiles; the facts behind each line are
|
|
76568
|
+
// verified against the deployed programs in UNIFIED_API_AUDIT.md §9.
|
|
76569
|
+
// Kamino is a crossing of Morpho and Aave V3: a market is PERMISSIONLESSLY
|
|
76570
|
+
// deployed and typically lends one asset against a set of collaterals (the
|
|
76571
|
+
// Morpho half), while inside the market a multi-asset pool with elevation
|
|
76572
|
+
// groups prices the pairs (the Aave half).
|
|
76573
|
+
P({
|
|
76574
|
+
id: "kamino.klend@v1",
|
|
76575
|
+
name: "Kamino Lend market (variable-rate pool)",
|
|
76576
|
+
family: "kamino",
|
|
76577
|
+
docsUrl: "https://docs.kamino.finance/",
|
|
76578
|
+
supply: {
|
|
76579
|
+
description: "A shared liquidity pool inside one Kamino lending market. Markets are deployed permissionlessly and run by their owner \u2014 Kamino for the primary market, a third-party curator for the others \u2014 who sets every reserve's parameters. Deposits earn interest paid by borrowers, at a rate that moves with utilization, minus the protocol take rate. Withdrawals are instant up to the cash left in the pool, and a reserve can additionally rate-limit them with a rolling net-withdrawal cap.",
|
|
76580
|
+
implications: [
|
|
76581
|
+
"Your yield is not fixed \u2014 it rises and falls with borrowing demand.",
|
|
76582
|
+
"If utilization reaches 100 %, withdrawals are blocked until borrowers repay or new deposits arrive.",
|
|
76583
|
+
"A reserve may rate-limit withdrawals with a rolling net-withdrawal cap.",
|
|
76584
|
+
"Your deposit is exposed to every collateral asset THIS market accepts, not just one \u2014 and the market owner, not Kamino, decides what that set is."
|
|
76585
|
+
]
|
|
76586
|
+
},
|
|
76587
|
+
borrow: {
|
|
76588
|
+
description: "Borrow the market's loan asset against the collaterals it accepts, at a rate that moves with utilization. Most markets lend one asset; the primary market lends many. The debt accrues continuously and can be repaid at any time. Positions are obligations \u2014 a wallet can hold several per market, each with its own health. Elevation groups raise the LTV for specific collateral/debt pairs, and an obligation sits in at most one group.",
|
|
76589
|
+
implications: [
|
|
76590
|
+
"The rate can change slot to slot \u2014 a cheap borrow can become expensive.",
|
|
76591
|
+
"If the collateral value falls past the liquidation threshold, a liquidator repays part of your debt (a close factor per call) and takes collateral plus a bonus that scales with how far past the threshold you are; a deeply unhealthy or very small position is liquidated whole.",
|
|
76592
|
+
"Inside an elevation group only the group\u2019s debt asset can be borrowed, every deposit must be one of the group\u2019s collaterals, and the number of collaterals is capped.",
|
|
76593
|
+
"Some reserves count as collateral ONLY inside an elevation group: holding one in an obligation outside every group disables all new borrowing on that obligation.",
|
|
76594
|
+
"Markets with auto-deleverage enabled can lower the liquidation threshold over time and unwind positions without a price move.",
|
|
76595
|
+
"Parameters are set by the market owner and can change without a protocol-wide vote."
|
|
76596
|
+
]
|
|
76597
|
+
}
|
|
76598
|
+
}),
|
|
76599
|
+
P({
|
|
76600
|
+
id: "jupiter-lend.vault@v1",
|
|
76601
|
+
name: "Jupiter Lend vault (Fluid T1 on Solana)",
|
|
76602
|
+
family: "jupiter-lend",
|
|
76603
|
+
docsUrl: "https://developers.jup.ag/docs/lend",
|
|
76604
|
+
supply: {
|
|
76605
|
+
description: "Collateral posted to a Jupiter Lend vault sits on the shared Liquidity Layer, where every vault and earn token that touches the same asset draws from one pool. Collateral earns the layer's supply rate only when that asset is also lent out (SOL does; JLP, JupSOL and the LST collaterals do not). Withdrawals are bounded by a per-position limit that expands over six hours.",
|
|
76606
|
+
implications: [
|
|
76607
|
+
"A withdrawal larger than the current limit cannot clear in one transaction \u2014 the limit grows toward the position over ~6 hours.",
|
|
76608
|
+
"Your collateral shares one liquidity pool with every other vault and earn token on that asset."
|
|
76609
|
+
]
|
|
76610
|
+
},
|
|
76611
|
+
borrow: {
|
|
76612
|
+
description: "Borrow one asset against one collateral at a rate set per ASSET at the Liquidity Layer, plus a per-vault additive offset (the magnifier, in bps \u2014 e.g. vault 101 pays the layer rate minus 2 %), so two vaults lending the same asset can charge different rates. Debt accrues continuously and can be repaid at any time. Positions are NFTs, one collateral/debt pair each.",
|
|
76613
|
+
implications: [
|
|
76614
|
+
"The rate moves with the layer's utilization of the borrowed asset, block to block.",
|
|
76615
|
+
"Past the liquidation threshold a liquidator repays part of the debt and takes collateral plus a penalty; past the max liquidation limit the position is liquidated ENTIRELY.",
|
|
76616
|
+
"Borrowing is capped by an expanding per-vault ceiling on the layer, so a large borrow may need to wait for the ceiling to grow."
|
|
76617
|
+
]
|
|
76618
|
+
}
|
|
76619
|
+
}),
|
|
76620
|
+
P({
|
|
76621
|
+
id: "save.pool@v1",
|
|
76622
|
+
name: "Save (ex-Solend) lending pool",
|
|
76623
|
+
family: "save",
|
|
76624
|
+
docsUrl: "https://docs.save.finance/",
|
|
76625
|
+
supply: {
|
|
76626
|
+
description: "A shared liquidity pool inside one Save lending market \u2014 the Main pool is run by Save's own key; other pools are deployed permissionlessly by third parties who set every parameter. Deposits mint cTokens that appreciate as borrowers pay interest, at a rate that moves with utilization along a three-legged curve, minus a protocol take rate. Withdrawals are instant up to the cash left in the reserve and the market's outflow limit.",
|
|
76627
|
+
implications: [
|
|
76628
|
+
"Your yield is not fixed \u2014 it moves with borrowing demand, slot to slot.",
|
|
76629
|
+
"If the reserve is fully lent out, withdrawals wait for repayments or new deposits; permissionless pools have been left pinned there permanently.",
|
|
76630
|
+
"A market-wide outflow limiter can cap how much leaves the whole pool in a rolling window.",
|
|
76631
|
+
"Bad debt in the market is socialised to its depositors; the pool owner decides which collaterals the pool accepts."
|
|
76632
|
+
]
|
|
76633
|
+
},
|
|
76634
|
+
borrow: {
|
|
76635
|
+
description: "Borrow any borrowable reserve against the collaterals the market accepts, at a variable rate accrued every slot. Liquid-staked SOL collateral can be valued off the SOL price times an owner-set ratio rather than an LST oracle. Debt accrues continuously and can be repaid at any time; one obligation holds up to six positions.",
|
|
76636
|
+
implications: [
|
|
76637
|
+
"The rate can change every slot, and is quoted on a slot-year \u2014 the wall-clock rate runs about a quarter higher than the curve.",
|
|
76638
|
+
"Past the liquidation threshold a liquidator repays at most 20 % of your debt per call (and at most $500k at once) and takes collateral plus a bonus that scales with how far past the threshold you are, plus a protocol fee; a borrow worth $1 or less is liquidated whole.",
|
|
76639
|
+
"Isolated reserves can only be borrowed on their own: an obligation that borrows one may hold no other borrow, and they never count as collateral.",
|
|
76640
|
+
"A borrow or withdrawal needs fresh oracle prices for EVERY asset in the obligation; a stale long-tail feed blocks the whole account until a price is posted.",
|
|
76641
|
+
"Parameters are set by the market owner and can change without a protocol-wide vote."
|
|
76642
|
+
]
|
|
76643
|
+
}
|
|
76644
|
+
}),
|
|
76645
|
+
P({
|
|
76646
|
+
id: "loopscale.creditbook@v1",
|
|
76647
|
+
name: "Loopscale credit order book (fixed-rate, fixed-duration)",
|
|
76648
|
+
family: "loopscale",
|
|
76649
|
+
docsUrl: "https://docs.loopscale.com/",
|
|
76650
|
+
supply: {
|
|
76651
|
+
description: "A fixed-rate loan filled from an order book of resting lender offers rather than a pool \u2014 Morpho Midnight's product on Solana. A lender rests a rate per collateral and per duration (1 day, 1 week, 1 month, 3 months); a borrower fills the best one and a repayment ledger is opened against escrowed collateral. Passive lenders deposit into a curated vault that rests the offers for them.",
|
|
76652
|
+
implications: [
|
|
76653
|
+
"Your rate is fixed for the term \u2014 it does not move with utilization, because there is no pool.",
|
|
76654
|
+
"Before maturity your claim can only leave by selling the ledger to another lender at a negotiated price; there may be no buyer.",
|
|
76655
|
+
"A curated vault charges a fee on the interest it earns for you, and can park idle deposits in a third-party pool.",
|
|
76656
|
+
"Vault curators choose the accepted collateral and its LTV (behind a 24-hour timelock) and set rates and fees immediately."
|
|
76657
|
+
]
|
|
76658
|
+
},
|
|
76659
|
+
borrow: {
|
|
76660
|
+
description: "Borrow one asset against one collateral at a rate fixed for the chosen duration. At maturity a healthy loan is refinanced into a new 1-day term from any matching offer; if none matches, a 48-hour grace period runs at the same rate and then the loan may be partially liquidated. Repay at any time with interest to date; a loan can hold up to five collaterals and five ledgers.",
|
|
76661
|
+
implications: [
|
|
76662
|
+
"Health counts the interest owed at MATURITY as debt, so a longer term is riskier on day one than the same principal for a day.",
|
|
76663
|
+
"Liquidation is partial first \u2014 the minimum collateral to restore the max LTV \u2014 and the fee is how far past the liquidation LTV the loan was, not a flat bonus.",
|
|
76664
|
+
"The LTV and liquidation threshold are the OFFER's, pinned into your ledger at origination; a better or worse offer next to it has different ones.",
|
|
76665
|
+
"Auto-refinance is a best effort: if no lender rests an offer at maturity, the grace period is your only cover before liquidation."
|
|
76666
|
+
]
|
|
76667
|
+
}
|
|
76668
|
+
}),
|
|
76669
|
+
P({
|
|
76670
|
+
id: "project0.group@v1",
|
|
76671
|
+
name: "Project 0 (marginfi v2) lending group",
|
|
76672
|
+
family: "project0",
|
|
76673
|
+
docsUrl: "https://docs.0.xyz/",
|
|
76674
|
+
supply: {
|
|
76675
|
+
description: "A shared pool per asset (a 'bank') inside one cross-margined group run by the Project 0 foundation \u2014 the marginfi v2 program, rebranded. Deposits earn the bank's lending rate, which moves with utilization along a multi-point curve and is settled into the deposit's share value whenever the bank is touched. Some banks are wrappers: they hold a Kamino, Drift or Jupiter Lend position, or a validator's native stake, and earn THAT venue's yield rather than an interest rate here.",
|
|
76676
|
+
implications: [
|
|
76677
|
+
"Your yield is not fixed \u2014 it moves with borrowing demand, and accrues as simple interest between touches of the bank.",
|
|
76678
|
+
"Withdrawals are instant up to the cash left in the bank, and can be capped by a per-bank hourly and daily outflow limit shared with borrows.",
|
|
76679
|
+
"On a wrapped bank you hold shares of another venue; its risks, rates and exits apply on top.",
|
|
76680
|
+
"Bad debt in the group is socialised to depositors of the affected bank after the insurance fund; banks can be paused, set reduce-only or killed by the group admins."
|
|
76681
|
+
]
|
|
76682
|
+
},
|
|
76683
|
+
borrow: {
|
|
76684
|
+
description: "Borrow any borrowable bank against every collateral bank the account holds, cross-margined across up to 16 balances per account. Collateral is valued at an initial weight to open a borrow and a higher maintenance weight for liquidation; debt is inflated by a liability weight, which is higher for opening than for liquidation. When everything the account borrows is in the same e-mode class as its collateral (stables against stables, SOL against liquid staking tokens), the collateral counts at a lifted weight.",
|
|
76685
|
+
implications: [
|
|
76686
|
+
"The rate can change at any touch of the bank and is quoted on a 365-day year, simple interest.",
|
|
76687
|
+
"Past the maintenance threshold a liquidator repays debt and takes collateral plus a premium set on the debt bank \u2014 2.5 % to the liquidator and 2.5 % to the insurance fund by default \u2014 only as far as restoring health to zero.",
|
|
76688
|
+
"Borrowing another asset can switch e-mode off and drop your collateral weights at once; check what the new borrow does to the whole account.",
|
|
76689
|
+
"A reduce-only bank takes no new deposits or borrows, and \u2014 unless it is the variant that keeps borrowing power \u2014 its collateral stops counting toward a NEW borrow; a paused bank blocks withdrawals, repayments and liquidations too.",
|
|
76690
|
+
"Isolated-tier assets can be borrowed only on their own and never count as collateral; parameters are set by the foundation and its delegate admins without a protocol-wide vote."
|
|
76691
|
+
]
|
|
76692
|
+
}
|
|
76693
|
+
}),
|
|
76522
76694
|
// ── Vaults ───────────────────────────────────────────────────────────────
|
|
76523
76695
|
P({
|
|
76524
76696
|
id: "vault.lending@v1",
|
|
@@ -76698,6 +76870,7 @@ function resolveVaultProfileId(provider, solvency) {
|
|
|
76698
76870
|
|
|
76699
76871
|
// src/terms/types.ts
|
|
76700
76872
|
var TERM_SHEET_SCHEMA_VERSION = 1;
|
|
76873
|
+
var termAddressKey = (chainId, address) => chainId === void 0 || isEvmChainId(String(chainId)) ? address.toLowerCase() : address;
|
|
76701
76874
|
|
|
76702
76875
|
// src/terms/buildTermSheet.ts
|
|
76703
76876
|
var isNum = (v) => typeof v === "number" && Number.isFinite(v);
|
|
@@ -76705,7 +76878,10 @@ var clamp013 = (v) => Math.max(0, Math.min(1, v));
|
|
|
76705
76878
|
function assetRef(input, now) {
|
|
76706
76879
|
const a = input.asset ?? {};
|
|
76707
76880
|
const chainId = String(a.chainId ?? input.chainId);
|
|
76708
|
-
const address =
|
|
76881
|
+
const address = termAddressKey(
|
|
76882
|
+
chainId,
|
|
76883
|
+
String(a.address ?? input.underlying ?? "")
|
|
76884
|
+
);
|
|
76709
76885
|
return {
|
|
76710
76886
|
chainId,
|
|
76711
76887
|
address,
|
|
@@ -76734,7 +76910,10 @@ function instrumentOf(props, chainId, address, now) {
|
|
|
76734
76910
|
const bridged = typeof pendle.bridgedFrom === "string" && pendle.bridgedFrom;
|
|
76735
76911
|
const origin = pendle.origin && typeof pendle.origin.chainId === "string" && typeof pendle.origin.address === "string" ? {
|
|
76736
76912
|
chainId: String(pendle.origin.chainId),
|
|
76737
|
-
address:
|
|
76913
|
+
address: termAddressKey(
|
|
76914
|
+
String(pendle.origin.chainId),
|
|
76915
|
+
String(pendle.origin.address)
|
|
76916
|
+
)
|
|
76738
76917
|
} : void 0;
|
|
76739
76918
|
const originChain = origin?.chainId ?? (bridged ? PENDLE_ORIGIN_CHAIN_BY_CODE[bridged] : void 0);
|
|
76740
76919
|
return {
|
|
@@ -76796,7 +76975,10 @@ function rewardTerms(input, side) {
|
|
|
76796
76975
|
if (!apr) continue;
|
|
76797
76976
|
const isPoints = r.kind === "points" || !r.asset;
|
|
76798
76977
|
out.push({
|
|
76799
|
-
asset: r.asset ? {
|
|
76978
|
+
asset: r.asset ? {
|
|
76979
|
+
chainId: input.chainId,
|
|
76980
|
+
address: termAddressKey(input.chainId, String(r.asset))
|
|
76981
|
+
} : void 0,
|
|
76800
76982
|
kind: isPoints ? "points" : "token",
|
|
76801
76983
|
apr,
|
|
76802
76984
|
side,
|
|
@@ -77278,6 +77460,26 @@ function buildCoverage(sheet) {
|
|
|
77278
77460
|
pending: Object.keys(pending).length ? pending : void 0
|
|
77279
77461
|
};
|
|
77280
77462
|
}
|
|
77463
|
+
function mergeAdapterCoverage(base, patch) {
|
|
77464
|
+
if (!patch) return base;
|
|
77465
|
+
const present = new Set(base.present);
|
|
77466
|
+
const pending = { ...base.pending ?? {} };
|
|
77467
|
+
const notApplicable = {
|
|
77468
|
+
...base.notApplicable ?? {}
|
|
77469
|
+
};
|
|
77470
|
+
for (const [k, v] of Object.entries(patch.pending ?? {}))
|
|
77471
|
+
if (typeof v === "string" && !present.has(k)) pending[k] = v;
|
|
77472
|
+
for (const [k, v] of Object.entries(patch.notApplicable ?? {}))
|
|
77473
|
+
if (typeof v === "string" && !present.has(k)) {
|
|
77474
|
+
notApplicable[k] = v;
|
|
77475
|
+
delete pending[k];
|
|
77476
|
+
}
|
|
77477
|
+
return {
|
|
77478
|
+
present: base.present,
|
|
77479
|
+
notApplicable: Object.keys(notApplicable).length ? notApplicable : void 0,
|
|
77480
|
+
pending: Object.keys(pending).length ? pending : void 0
|
|
77481
|
+
};
|
|
77482
|
+
}
|
|
77281
77483
|
function buildTermSheet(input, opts = {}) {
|
|
77282
77484
|
const now = opts.now ?? Math.floor(Date.now() / 1e3);
|
|
77283
77485
|
const siblings = opts.siblings ?? [];
|
|
@@ -77304,7 +77506,10 @@ function buildTermSheet(input, opts = {}) {
|
|
|
77304
77506
|
if (merged[side] && !base[side]) merged[side] = void 0;
|
|
77305
77507
|
}
|
|
77306
77508
|
const withInfo = finalizeInfo(merged);
|
|
77307
|
-
withInfo.coverage =
|
|
77509
|
+
withInfo.coverage = mergeAdapterCoverage(
|
|
77510
|
+
buildCoverage(withInfo),
|
|
77511
|
+
opts.patch?.coverage
|
|
77512
|
+
);
|
|
77308
77513
|
return withInfo;
|
|
77309
77514
|
}
|
|
77310
77515
|
|
|
@@ -78058,8 +78263,6 @@ var FALLBACK_TRAITS = {
|
|
|
78058
78263
|
hasDecomposableBacking: false,
|
|
78059
78264
|
hasUtilization: false
|
|
78060
78265
|
};
|
|
78061
|
-
|
|
78062
|
-
// src/earn/uid.ts
|
|
78063
78266
|
var VAULT_VENUE_PREFIX = "vault.";
|
|
78064
78267
|
function isVaultVenue(uidOrVenue) {
|
|
78065
78268
|
return uidOrVenue.startsWith(VAULT_VENUE_PREFIX);
|
|
@@ -78073,7 +78276,7 @@ function buildVaultEarnUid(provider, chainId, address) {
|
|
|
78073
78276
|
`Invalid earnUid parameters: provider=${provider}, chainId=${chainId}, address=${address}`
|
|
78074
78277
|
);
|
|
78075
78278
|
}
|
|
78076
|
-
return `${vaultVenue(provider)}:${chainId}:${address
|
|
78279
|
+
return `${vaultVenue(provider)}:${chainId}:${refKey(chainId, address)}`;
|
|
78077
78280
|
}
|
|
78078
78281
|
function earnUidFromMarketUid(marketUid) {
|
|
78079
78282
|
const parts = splitUid(marketUid);
|
|
@@ -78102,9 +78305,10 @@ function parseEarnUid(earnUid, knownProviders) {
|
|
|
78102
78305
|
kind: "lending",
|
|
78103
78306
|
venue,
|
|
78104
78307
|
chainId,
|
|
78105
|
-
//
|
|
78106
|
-
//
|
|
78107
|
-
ref
|
|
78308
|
+
// Canonicalized like `normalizeMarketUid` / `createMarketUid`: lower-cased
|
|
78309
|
+
// on EVM (harmless for Dolomite's integer id), VERBATIM elsewhere — a
|
|
78310
|
+
// base58 ref is case-significant.
|
|
78311
|
+
ref: refKey(chainId, ref),
|
|
78108
78312
|
marketUid: earnUid
|
|
78109
78313
|
};
|
|
78110
78314
|
}
|
|
@@ -78122,7 +78326,7 @@ function parseEarnUid(earnUid, knownProviders) {
|
|
|
78122
78326
|
venue,
|
|
78123
78327
|
provider,
|
|
78124
78328
|
chainId,
|
|
78125
|
-
address: ref
|
|
78329
|
+
address: refKey(chainId, ref)
|
|
78126
78330
|
};
|
|
78127
78331
|
}
|
|
78128
78332
|
function tryParseEarnUid(earnUid, knownProviders) {
|
|
@@ -78143,6 +78347,7 @@ function splitUid(uid) {
|
|
|
78143
78347
|
if (!venue || !chainId || !ref) return void 0;
|
|
78144
78348
|
return { venue, chainId, ref };
|
|
78145
78349
|
}
|
|
78350
|
+
var refKey = (chainId, ref) => isEvmChainId(chainId) ? ref.toLowerCase() : ref;
|
|
78146
78351
|
var VENUE_KIND_LABELS = {
|
|
78147
78352
|
lending: "Lending markets",
|
|
78148
78353
|
vault: "Vaults"
|
|
@@ -79020,11 +79225,27 @@ function toVaultTermInput(vault, provider, chainId) {
|
|
|
79020
79225
|
exposures: Array.isArray(row.exposures) ? row.exposures : void 0
|
|
79021
79226
|
};
|
|
79022
79227
|
}
|
|
79228
|
+
function savingsCuration(provider, chainId, address) {
|
|
79229
|
+
if (provider !== "savings") return {};
|
|
79230
|
+
const lc2 = address.toLowerCase();
|
|
79231
|
+
const e = getSavingsRegistry(chainId).find((x) => x.address === lc2);
|
|
79232
|
+
if (!e) return {};
|
|
79233
|
+
return {
|
|
79234
|
+
// `''` is how an entry says "no curated copy"; it must not beat the
|
|
79235
|
+
// template, so it is normalized to absent.
|
|
79236
|
+
description: e.description || void 0,
|
|
79237
|
+
solvency: e.solvency,
|
|
79238
|
+
accrual: e.accrual,
|
|
79239
|
+
yieldWarmupSeconds: e.yieldWarmupSeconds,
|
|
79240
|
+
needsDepositApproval: e.needsDepositApproval
|
|
79241
|
+
};
|
|
79242
|
+
}
|
|
79023
79243
|
function vaultTermInputFromEarnMarket(m) {
|
|
79024
79244
|
if (m.venueKind !== "vault") return void 0;
|
|
79025
79245
|
const provider = m.venue.startsWith(VAULT_VENUE_PREFIX) ? m.venue.slice(VAULT_VENUE_PREFIX.length) : void 0;
|
|
79026
79246
|
if (!provider) return void 0;
|
|
79027
79247
|
const meta = m.providerMeta ?? {};
|
|
79248
|
+
const curated = savingsCuration(provider, m.chainId, m.ref);
|
|
79028
79249
|
return {
|
|
79029
79250
|
provider,
|
|
79030
79251
|
chainId: m.chainId,
|
|
@@ -79033,7 +79254,7 @@ function vaultTermInputFromEarnMarket(m) {
|
|
|
79033
79254
|
name: m.name,
|
|
79034
79255
|
brand: m.brand,
|
|
79035
79256
|
curatorName: m.brand,
|
|
79036
|
-
description: str7(meta.description),
|
|
79257
|
+
description: str7(meta.description) ?? curated.description,
|
|
79037
79258
|
asset: {
|
|
79038
79259
|
chainId: m.chainId,
|
|
79039
79260
|
address: m.asset.address,
|
|
@@ -79063,9 +79284,9 @@ function vaultTermInputFromEarnMarket(m) {
|
|
|
79063
79284
|
swapFeeRate: num14(meta.feeRate),
|
|
79064
79285
|
redemptionDiscountBps: num14(meta.redemptionDiscountBps),
|
|
79065
79286
|
instantRedeemEnabled: bool2(meta.instantRedeemEnabled),
|
|
79066
|
-
yieldWarmupSeconds: num14(meta.yieldWarmupSeconds),
|
|
79067
|
-
accrual: str7(meta.accrual),
|
|
79068
|
-
needsDepositApproval: bool2(meta.needsDepositApproval),
|
|
79287
|
+
yieldWarmupSeconds: num14(meta.yieldWarmupSeconds) ?? curated.yieldWarmupSeconds,
|
|
79288
|
+
accrual: str7(meta.accrual) ?? curated.accrual,
|
|
79289
|
+
needsDepositApproval: bool2(meta.needsDepositApproval) ?? curated.needsDepositApproval,
|
|
79069
79290
|
// `canDeposit` already folds in the cap, the pause and the gate, so it is
|
|
79070
79291
|
// the authoritative answer — but the REASON is what a disabled CTA renders,
|
|
79071
79292
|
// and that only survives in the raw fields.
|
|
@@ -79083,7 +79304,7 @@ function vaultTermInputFromEarnMarket(m) {
|
|
|
79083
79304
|
curator: str7(meta.curator),
|
|
79084
79305
|
guardian: str7(meta.guardian),
|
|
79085
79306
|
feeRecipient: str7(meta.feeRecipient),
|
|
79086
|
-
solvency: m.risk?.counterparty,
|
|
79307
|
+
solvency: m.risk?.counterparty ?? curated.solvency,
|
|
79087
79308
|
navOracle: str7(meta.navOracle),
|
|
79088
79309
|
yieldProfile: m.risk?.yieldProfile,
|
|
79089
79310
|
exposures: m.refs?.exposures
|
|
@@ -79110,6 +79331,7 @@ function vaultTermInputFromSourceRow(row, chainId) {
|
|
|
79110
79331
|
const info = row.vaultInfo ?? {};
|
|
79111
79332
|
const assetInfo = row.underlyingInfo?.asset;
|
|
79112
79333
|
const assetDecimals = num14(row.assetDecimals) ?? num14(assetInfo?.decimals) ?? num14(row.decimals);
|
|
79334
|
+
const curated = savingsCuration(provider, chainId, address);
|
|
79113
79335
|
return {
|
|
79114
79336
|
provider,
|
|
79115
79337
|
chainId,
|
|
@@ -79118,7 +79340,7 @@ function vaultTermInputFromSourceRow(row, chainId) {
|
|
|
79118
79340
|
name: str7(info.name) ?? str7(row.displayName) ?? str7(row.name),
|
|
79119
79341
|
brand: str7(row.curatorName) ?? str7(meta.brand),
|
|
79120
79342
|
curatorName: str7(row.curatorName),
|
|
79121
|
-
description: str7(meta.description),
|
|
79343
|
+
description: str7(meta.description) ?? curated.description,
|
|
79122
79344
|
asset: {
|
|
79123
79345
|
chainId,
|
|
79124
79346
|
address: str7(row.underlying)?.toLowerCase() ?? "",
|
|
@@ -79146,9 +79368,9 @@ function vaultTermInputFromSourceRow(row, chainId) {
|
|
|
79146
79368
|
swapFeeRate: num14(meta.feeRate),
|
|
79147
79369
|
redemptionDiscountBps: num14(meta.redemptionDiscountBps),
|
|
79148
79370
|
instantRedeemEnabled: bool2(meta.instantRedeemEnabled),
|
|
79149
|
-
yieldWarmupSeconds: num14(meta.yieldWarmupSeconds),
|
|
79150
|
-
accrual: str7(meta.accrual),
|
|
79151
|
-
needsDepositApproval: bool2(meta.needsDepositApproval),
|
|
79371
|
+
yieldWarmupSeconds: num14(meta.yieldWarmupSeconds) ?? curated.yieldWarmupSeconds,
|
|
79372
|
+
accrual: str7(meta.accrual) ?? curated.accrual,
|
|
79373
|
+
needsDepositApproval: bool2(meta.needsDepositApproval) ?? curated.needsDepositApproval,
|
|
79152
79374
|
isMintable: bool2(meta.isMintable),
|
|
79153
79375
|
depositCapacity: str7(meta.depositCapacity) ?? str7(meta.maxDeposit),
|
|
79154
79376
|
supplyCap: str7(meta.supplyCap),
|
|
@@ -79164,7 +79386,7 @@ function vaultTermInputFromSourceRow(row, chainId) {
|
|
|
79164
79386
|
curator: str7(meta.curator),
|
|
79165
79387
|
guardian: str7(meta.guardian),
|
|
79166
79388
|
feeRecipient: str7(meta.feeRecipient),
|
|
79167
|
-
solvency: str7(meta.solvency),
|
|
79389
|
+
solvency: str7(meta.solvency) ?? curated.solvency,
|
|
79168
79390
|
navOracle: str7(meta.navOracle),
|
|
79169
79391
|
yieldProfile: str7(info.yieldProfile),
|
|
79170
79392
|
exposures: Array.isArray(row.exposures) ? row.exposures : Array.isArray(meta.exposures) ? meta.exposures : void 0
|
|
@@ -80001,7 +80223,15 @@ function toTermSheetInput(row, ctx = {}) {
|
|
|
80001
80223
|
closeFactor: num15(v?.closeFactor),
|
|
80002
80224
|
targetHealthFactor: num15(v?.targetHealthFactor),
|
|
80003
80225
|
collateralDisabled: v?.collateralDisabled === true,
|
|
80004
|
-
debtDisabled: v?.debtDisabled === true
|
|
80226
|
+
debtDisabled: v?.debtDisabled === true,
|
|
80227
|
+
// the mode-level position fields (UNIFIED_API_AUDIT §11) — set
|
|
80228
|
+
// only where the row carries them, so EVM inputs are unchanged
|
|
80229
|
+
...v?.liquidationBorrowFactor != null ? { liquidationBorrowFactor: num15(v.liquidationBorrowFactor) } : {},
|
|
80230
|
+
...v?.debtCapacity != null ? { debtCapacity: num15(v.debtCapacity) } : {},
|
|
80231
|
+
...v?.collateralDebtCapacity != null ? { collateralDebtCapacity: num15(v.collateralDebtCapacity) } : {},
|
|
80232
|
+
...v?.maxCollateralAssets != null ? { maxCollateralAssets: num15(v.maxCollateralAssets) } : {},
|
|
80233
|
+
...v?.exclusiveCollateral != null ? { exclusiveCollateral: v.exclusiveCollateral === true } : {},
|
|
80234
|
+
...v?.openParameter ? { openParameter: v.openParameter } : {}
|
|
80005
80235
|
}
|
|
80006
80236
|
])
|
|
80007
80237
|
) : void 0;
|
|
@@ -80072,6 +80302,9 @@ function toTermSheetInput(row, ctx = {}) {
|
|
|
80072
80302
|
"variableBorrowDisabled",
|
|
80073
80303
|
"flags.variableBorrowDisabled"
|
|
80074
80304
|
),
|
|
80305
|
+
...pick2(row, "siloedBorrowing", "flags.siloedBorrowing") != null ? {
|
|
80306
|
+
siloedBorrowing: pick2(row, "siloedBorrowing", "flags.siloedBorrowing") === true
|
|
80307
|
+
} : {},
|
|
80075
80308
|
config,
|
|
80076
80309
|
// `caps.` is NOT optional here. `/pools/latest` serializes both of these as
|
|
80077
80310
|
// TOP-LEVEL row fields, while `/lending/latest` — the endpoint the lending
|
|
@@ -81818,6 +82051,753 @@ function num17(v) {
|
|
|
81818
82051
|
const n = typeof v === "string" ? Number(v) : v;
|
|
81819
82052
|
return Number.isFinite(n) && n > 0 ? n : void 0;
|
|
81820
82053
|
}
|
|
82054
|
+
var KLEND_PROGRAM_ID = "KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD";
|
|
82055
|
+
var KAMINO_MAIN_MARKET = "7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF";
|
|
82056
|
+
var KAMINO_PROFILE_ID = "kamino.klend@v1";
|
|
82057
|
+
var MAIN_MARKET_FULL_LIQUIDATION = {
|
|
82058
|
+
aboveLtv: 0.95,
|
|
82059
|
+
belowDebtValueUsd: 2,
|
|
82060
|
+
maxPerLiquidationUsd: 25e5,
|
|
82061
|
+
verifiedAt: "2026-09-28"
|
|
82062
|
+
};
|
|
82063
|
+
var OBLIGATION_MAX_DEPOSITS = 8;
|
|
82064
|
+
var OBLIGATION_MAX_BORROWS = 5;
|
|
82065
|
+
var isNum3 = (v) => typeof v === "number" && Number.isFinite(v);
|
|
82066
|
+
function elevationGroups(input) {
|
|
82067
|
+
const out = [];
|
|
82068
|
+
for (const [id, raw] of Object.entries(input.config ?? {})) {
|
|
82069
|
+
if (id === "0") continue;
|
|
82070
|
+
const c = raw;
|
|
82071
|
+
const role = !c.collateralDisabled ? "collateral" : !c.debtDisabled ? "debt" : "none";
|
|
82072
|
+
out.push({
|
|
82073
|
+
id,
|
|
82074
|
+
label: c.label,
|
|
82075
|
+
role,
|
|
82076
|
+
...role === "collateral" ? {
|
|
82077
|
+
ltv: c.borrowCollateralFactor,
|
|
82078
|
+
liquidationLtv: c.collateralFactor
|
|
82079
|
+
} : {},
|
|
82080
|
+
...isNum3(c.maxCollateralAssets) ? { maxCollateralAssets: c.maxCollateralAssets } : {},
|
|
82081
|
+
...typeof c.exclusiveCollateral === "boolean" ? { exclusiveCollateral: c.exclusiveCollateral } : {},
|
|
82082
|
+
...role === "collateral" && isNum3(c.collateralDebtCapacity) ? { collateralDebtCapacity: c.collateralDebtCapacity } : {}
|
|
82083
|
+
});
|
|
82084
|
+
}
|
|
82085
|
+
return out;
|
|
82086
|
+
}
|
|
82087
|
+
function build(input) {
|
|
82088
|
+
const market = kaminoMarketFromKey(input.lender);
|
|
82089
|
+
const isMain = market === KAMINO_MAIN_MARKET;
|
|
82090
|
+
const base = input.config?.["0"];
|
|
82091
|
+
const groups = elevationGroups(input);
|
|
82092
|
+
const address = input.asset?.address ?? input.underlying;
|
|
82093
|
+
const pending = {
|
|
82094
|
+
"borrow.liquidation.maxBonus": "the reserve's max liquidation bonus and each group's max bonus are not served; `penalty` is the reserve MIN bonus \u2014 the bonus scales with how far past the threshold the obligation is",
|
|
82095
|
+
"borrow.liquidation.autoDeleverage": "auto-deleverage (reserve / market flags, margin-call period, per-day threshold decay) is not served; when armed the trigger is price-and-time",
|
|
82096
|
+
"supply.fees": "the protocol take rate (already netted out of the supply APR) is not served",
|
|
82097
|
+
"supply.exit.withdrawalCap": "the reserve's net-withdrawal cap (capacity, interval, current total) is not served",
|
|
82098
|
+
"borrow.availability.debtWithdrawalCap": "the reserve's net-borrow cap (`debtWithdrawalCap`) is not served",
|
|
82099
|
+
"borrow.fees.flash-loan": "the flash-loan fee is not served",
|
|
82100
|
+
"constraints.collateralRules": "`disableUsageAsCollOutsideEmode` is a reserve flag the origin does not serve; an LTV-0 default entry cannot tell it from a plain LTV of 0",
|
|
82101
|
+
"governance.controller": "the market owner (Kamino, or a third-party curator) is not served",
|
|
82102
|
+
oracle: "Scope / Pyth / Switchboard per reserve (`config.tokenInfo`) \u2014 not served and not classified"
|
|
82103
|
+
};
|
|
82104
|
+
if (!isMain)
|
|
82105
|
+
pending["borrow.liquidation.fullLiquidation"] = "this market's insolvency-risk LTV, minimum full-liquidation value and per-liquidation cap are LendingMarket fields the origin does not serve (verified values exist for the main market only)";
|
|
82106
|
+
if (!isNum3(input.closeFactor) && !isNum3(base?.closeFactor))
|
|
82107
|
+
pending["borrow.liquidation.closeFactor"] = "the market's liquidationMaxDebtCloseFactorPct is not on the row; the builder's 1 is a placeholder, not the market's value";
|
|
82108
|
+
if (!isNum3(input.originationFee))
|
|
82109
|
+
pending["borrow.fees"] = "the origination fee lives in the reserve account, which this row was not built from";
|
|
82110
|
+
if (!isNum3(base?.debtCapacity))
|
|
82111
|
+
pending["borrow.availability.debtCapacityOutsideGroups"] = "the remaining outside-group borrow limit (`config.debtCapacity`) is not on the input";
|
|
82112
|
+
if (groups.some(
|
|
82113
|
+
(g) => g.maxCollateralAssets === void 0 || g.exclusiveCollateral === void 0
|
|
82114
|
+
))
|
|
82115
|
+
pending["borrow.modes.constraints"] = "maxCollateralAssets / exclusiveCollateral per elevation group are served on `config` but not on the input";
|
|
82116
|
+
if (groups.some(
|
|
82117
|
+
(g) => g.role === "collateral" && g.collateralDebtCapacity === void 0
|
|
82118
|
+
))
|
|
82119
|
+
pending["borrow.modes.collateralDebtCapacity"] = "the per-group cap on new debt against this collateral (`config[g].collateralDebtCapacity`) is not on the input; a cap of 0 closes the group to NEW debt only";
|
|
82120
|
+
const originationFee = isNum3(input.originationFee) && input.originationFee > 0 ? [
|
|
82121
|
+
{
|
|
82122
|
+
id: "origination",
|
|
82123
|
+
label: "Borrow origination fee",
|
|
82124
|
+
when: "entry",
|
|
82125
|
+
unit: "percent",
|
|
82126
|
+
basis: "principal",
|
|
82127
|
+
value: input.originationFee,
|
|
82128
|
+
payee: "protocol",
|
|
82129
|
+
mutable: true,
|
|
82130
|
+
description: "Taken out of the borrowed amount: the wallet receives the borrow less this fee."
|
|
82131
|
+
}
|
|
82132
|
+
] : void 0;
|
|
82133
|
+
const collateralOnlyInGroups = base?.borrowCollateralFactor === 0 && (base.collateralFactor ?? 0) > 0;
|
|
82134
|
+
return {
|
|
82135
|
+
...address ? { asset: { address: String(address) } } : {},
|
|
82136
|
+
supply: {
|
|
82137
|
+
// klend accrues and compounds interest per slot.
|
|
82138
|
+
rate: { compounding: "per-slot" },
|
|
82139
|
+
ext: {
|
|
82140
|
+
kamino: {
|
|
82141
|
+
...collateralOnlyInGroups ? {
|
|
82142
|
+
noBorrowingPowerOutsideGroups: "LTV 0 outside every elevation group: this deposit adds no borrowing power there but still counts at its liquidation threshold"
|
|
82143
|
+
} : {},
|
|
82144
|
+
elevationGroups: groups.filter((g) => g.role === "collateral")
|
|
82145
|
+
}
|
|
82146
|
+
}
|
|
82147
|
+
},
|
|
82148
|
+
borrow: {
|
|
82149
|
+
rate: { compounding: "per-slot" },
|
|
82150
|
+
liquidation: {
|
|
82151
|
+
model: "repay-seize",
|
|
82152
|
+
absorber: "liquidator",
|
|
82153
|
+
reversible: false,
|
|
82154
|
+
// Auto-deleverage would make it price-and-time; it is not served, so
|
|
82155
|
+
// the ordinary price trigger stands and the rest is pending.
|
|
82156
|
+
trigger: "price",
|
|
82157
|
+
seizure: "proportional",
|
|
82158
|
+
...isNum3(base?.liquidationPenalty) ? {
|
|
82159
|
+
penalties: [
|
|
82160
|
+
{
|
|
82161
|
+
id: "bonus-min",
|
|
82162
|
+
label: "Liquidation bonus (at the threshold)",
|
|
82163
|
+
value: base.liquidationPenalty,
|
|
82164
|
+
description: "The reserve's minimum bonus. It scales with how far the obligation sits past its liquidation threshold, up to the reserve maximum (capped at the group maximum inside an elevation group)."
|
|
82165
|
+
}
|
|
82166
|
+
]
|
|
82167
|
+
} : {}
|
|
82168
|
+
},
|
|
82169
|
+
...originationFee ? { fees: originationFee } : {},
|
|
82170
|
+
ext: {
|
|
82171
|
+
kamino: {
|
|
82172
|
+
closeFactorSource: "LendingMarket.liquidationMaxDebtCloseFactorPct",
|
|
82173
|
+
fullLiquidationRule: "The close factor rises to 100 % above the market's insolvency-risk LTV; a debt worth less than the market's minimum full-liquidation value is liquidated whole; one liquidation repays at most the market's per-liquidation USD cap.",
|
|
82174
|
+
...isMain ? { fullLiquidation: MAIN_MARKET_FULL_LIQUIDATION } : {},
|
|
82175
|
+
...isNum3(base?.debtCapacity) ? { debtCapacityOutsideGroups: base.debtCapacity } : {},
|
|
82176
|
+
elevationGroups: groups,
|
|
82177
|
+
elevationGroupRules: {
|
|
82178
|
+
oneGroupPerObligation: true,
|
|
82179
|
+
onlyDebtReserveBorrowable: true,
|
|
82180
|
+
everyDepositMustBeMember: true,
|
|
82181
|
+
debtReserveCannotBeDeposit: true,
|
|
82182
|
+
borrowFactorInsideGroup: 1,
|
|
82183
|
+
allowNewLoansGatesRequestAndBorrow: true,
|
|
82184
|
+
zeroGroupCapClosesNewDebtOnly: true,
|
|
82185
|
+
selection: "per obligation (`request_elevation_group`)"
|
|
82186
|
+
}
|
|
82187
|
+
}
|
|
82188
|
+
}
|
|
82189
|
+
},
|
|
82190
|
+
constraints: {
|
|
82191
|
+
crossMargin: true,
|
|
82192
|
+
positionModel: "sub-account",
|
|
82193
|
+
positionIdMeaning: `The obligation pubkey \u2014 a PDA over [tag, id, owner, market, seed1, seed2]: tag 0 vanilla lending (both seeds default), 1 Multiply and 3 Leverage (the pair's mints), 2 Lending (one mint, seed1 = seed2); up to 256 ids per (tag, seed pair) per market. Each obligation is its own position with its own elevation group and health, at most ${OBLIGATION_MAX_DEPOSITS} deposits and ${OBLIGATION_MAX_BORROWS} borrows. The hosted builder addresses vanilla #0 only.`
|
|
82194
|
+
},
|
|
82195
|
+
ext: {
|
|
82196
|
+
kamino: {
|
|
82197
|
+
program: KLEND_PROGRAM_ID,
|
|
82198
|
+
...market ? { market } : {},
|
|
82199
|
+
isMainMarket: isMain,
|
|
82200
|
+
/** The marketUid ref is the RESERVE pubkey, not the mint. */
|
|
82201
|
+
marketUidRef: "reserve"
|
|
82202
|
+
}
|
|
82203
|
+
},
|
|
82204
|
+
coverage: { pending }
|
|
82205
|
+
};
|
|
82206
|
+
}
|
|
82207
|
+
var kaminoAdapter = {
|
|
82208
|
+
id: "kamino",
|
|
82209
|
+
matches: isKamino,
|
|
82210
|
+
profileId: () => KAMINO_PROFILE_ID,
|
|
82211
|
+
build
|
|
82212
|
+
};
|
|
82213
|
+
var JUPITER_LEND_PROFILE_ID = "jupiter-lend.vault@v1";
|
|
82214
|
+
var FLUID_VAULT_TYPE_T1 = 1e4;
|
|
82215
|
+
var JL_MAX_BORROW_FEE_PERCENT = 2.55;
|
|
82216
|
+
var JL_MAIN_PROGRAMS = {
|
|
82217
|
+
liquidity: "jupeiUmn818Jg1ekPURTpr4mFo29p46vygyykFJ3wZC",
|
|
82218
|
+
vaults: "jupr81YtYssSyPt8jbnGuiWon5f6x9TcDEFxYe3Bdzi",
|
|
82219
|
+
oracle: "jupnw4B6Eqs7ft6rxpzYLJZYSnrpRgPcr589n5Kv4oc",
|
|
82220
|
+
flashloan: "jupgfSgfuAXv4B6R2Uxu85Z1qdzgju79s6MfZekN6XS"
|
|
82221
|
+
};
|
|
82222
|
+
var isNum4 = (v) => typeof v === "number" && Number.isFinite(v);
|
|
82223
|
+
function build2(input) {
|
|
82224
|
+
const vault = jupiterLendVaultFromKey(input.lender);
|
|
82225
|
+
const address = input.asset?.address ?? input.underlying;
|
|
82226
|
+
const pending = {
|
|
82227
|
+
"borrow.liquidation.liquidationMaxLimit": "the max liquidation limit (the LTV past which a position is liquidated ENTIRELY) is not served",
|
|
82228
|
+
"borrow.availability.cap": "the layer's EXPANDING borrow limit (current, hard max, expand percent and duration) is not served \u2014 it is not a cap, so the row carries none",
|
|
82229
|
+
"supply.exit.withdrawalLimit": "the expanding per-position withdrawal limit and the vault's withdrawal gap are not served",
|
|
82230
|
+
"borrow.availability.minSize": "the vault's minimum borrow is not served",
|
|
82231
|
+
"borrow.fees.flash-loan": "the market flashloan program's fee and flashable set are not served",
|
|
82232
|
+
"borrow.ext.rateMagnifiers": "the vault's additive supply / borrow magnifiers are not served (the row's rates already include them)",
|
|
82233
|
+
oracle: "the vault's oracle (sources, hops) is not served; its price is borrow-per-supply in HUMAN units \xD7 1e15",
|
|
82234
|
+
"governance.controller": "the vault admin / rate-model authority is not on the public API"
|
|
82235
|
+
};
|
|
82236
|
+
if (!isNum4(input.originationFee) && input.borrowingEnabled === true)
|
|
82237
|
+
pending["borrow.fees"] = "the vault's borrow fee is not on the row";
|
|
82238
|
+
const fees = isNum4(input.originationFee) && input.originationFee > 0 ? [
|
|
82239
|
+
{
|
|
82240
|
+
id: "origination",
|
|
82241
|
+
label: "Borrow fee",
|
|
82242
|
+
when: "entry",
|
|
82243
|
+
unit: "percent",
|
|
82244
|
+
basis: "principal",
|
|
82245
|
+
value: input.originationFee,
|
|
82246
|
+
payee: "protocol",
|
|
82247
|
+
mutable: true,
|
|
82248
|
+
cap: JL_MAX_BORROW_FEE_PERCENT,
|
|
82249
|
+
description: "Charged once on the amount borrowed; the vault stores it as a u8 at 1e4, so it can never exceed 2.55 %."
|
|
82250
|
+
}
|
|
82251
|
+
] : void 0;
|
|
82252
|
+
return {
|
|
82253
|
+
...address ? { asset: { address: String(address) } } : {},
|
|
82254
|
+
// Rates are set on the Liquidity Layer — claim that basis only when the
|
|
82255
|
+
// layer totals are actually on the row (the fluid adapter's rule). Only
|
|
82256
|
+
// REFINES a block the builder made: a patch with no base would become a
|
|
82257
|
+
// utilization block without a utilization.
|
|
82258
|
+
...isNum4(input.utilization) ? {
|
|
82259
|
+
utilization: input.irmTotalDeposits != null && input.irmTotalDebt != null ? { basis: "liquidity-layer", lockupRatio: input.lockupRatio } : { lockupRatio: input.lockupRatio }
|
|
82260
|
+
} : {},
|
|
82261
|
+
borrow: {
|
|
82262
|
+
liquidation: {
|
|
82263
|
+
model: "repay-seize",
|
|
82264
|
+
absorber: "liquidator",
|
|
82265
|
+
reversible: false,
|
|
82266
|
+
trigger: "price",
|
|
82267
|
+
seizure: "proportional"
|
|
82268
|
+
},
|
|
82269
|
+
...fees ? { fees } : {},
|
|
82270
|
+
ext: {
|
|
82271
|
+
jupiterLend: {
|
|
82272
|
+
fullLiquidationRule: "Past the liquidation threshold a liquidator repays part of the debt and takes collateral plus the penalty; past the max liquidation limit the position is liquidated entirely.",
|
|
82273
|
+
rateMagnifier: {
|
|
82274
|
+
additive: true,
|
|
82275
|
+
unit: "bps",
|
|
82276
|
+
includedInRowRates: true,
|
|
82277
|
+
note: "A signed APR offset ADDED to the layer's per-token rate (vault 101: \u2212200) \u2014 not EVM Fluid's multiplier."
|
|
82278
|
+
},
|
|
82279
|
+
borrowLimit: "An EXPANDING ceiling on the layer, not a cap: a borrow above the current limit waits for it to grow toward the vault's hard maximum."
|
|
82280
|
+
}
|
|
82281
|
+
}
|
|
82282
|
+
},
|
|
82283
|
+
constraints: {
|
|
82284
|
+
crossMargin: false,
|
|
82285
|
+
positionModel: "nft",
|
|
82286
|
+
positionIdMeaning: "The vault position NFT id (per vault; one collateral / debt pair each). positionId 0 MINTS a new position \u2014 only an opening deposit may pass 0; any other action sent with 0 acts on a fresh empty position and reports success."
|
|
82287
|
+
},
|
|
82288
|
+
ext: {
|
|
82289
|
+
jupiterLend: {
|
|
82290
|
+
...vault ? { market: vault.market, vaultId: vault.vaultId } : {},
|
|
82291
|
+
fluidVaultType: FLUID_VAULT_TYPE_T1,
|
|
82292
|
+
...vault?.market === "main" ? { programs: JL_MAIN_PROGRAMS } : {},
|
|
82293
|
+
/** The marketUid ref is the leg's MINT. */
|
|
82294
|
+
marketUidRef: "mint"
|
|
82295
|
+
}
|
|
82296
|
+
},
|
|
82297
|
+
coverage: { pending }
|
|
82298
|
+
};
|
|
82299
|
+
}
|
|
82300
|
+
var jupiterLendAdapter = {
|
|
82301
|
+
id: "jupiter-lend",
|
|
82302
|
+
matches: isJupiterLend,
|
|
82303
|
+
profileId: () => JUPITER_LEND_PROFILE_ID,
|
|
82304
|
+
build: build2
|
|
82305
|
+
};
|
|
82306
|
+
var SAVE_PROGRAM_ID = "So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo";
|
|
82307
|
+
var SAVE_PROFILE_ID = "save.pool@v1";
|
|
82308
|
+
var SAVE_LIQUIDATION_CLOSE_FACTOR = 0.2;
|
|
82309
|
+
var SAVE_MAX_LIQUIDATABLE_VALUE_USD = 5e5;
|
|
82310
|
+
var SAVE_FULL_LIQUIDATION_VALUE_USD = 1;
|
|
82311
|
+
var SAVE_MAX_PENALTY = 0.25;
|
|
82312
|
+
var SAVE_SLOTS_PER_YEAR = 63072e3;
|
|
82313
|
+
var SAVE_MAX_OBLIGATION_RESERVES = 10;
|
|
82314
|
+
var SAVE_POSITION_LIMIT = 6;
|
|
82315
|
+
var isNum5 = (v) => typeof v === "number" && Number.isFinite(v);
|
|
82316
|
+
function build3(input) {
|
|
82317
|
+
const market = saveMarketFromKey(input.lender);
|
|
82318
|
+
const base = input.config?.["0"];
|
|
82319
|
+
const siloed = input.siloedBorrowing;
|
|
82320
|
+
const address = input.asset?.address ?? input.underlying;
|
|
82321
|
+
const pending = {
|
|
82322
|
+
"borrow.liquidation.maxBonus": "the max liquidation bonus and the max liquidation threshold it is reached at are not served; `penalty` is what the borrower pays AT the threshold",
|
|
82323
|
+
"borrow.liquidation.penaltySplit": "the row carries bonus + protocol fee as one figure; the split is not served",
|
|
82324
|
+
"supply.fees": "the protocol take rate on interest is not served (it is already netted out of the supply APR)",
|
|
82325
|
+
"borrow.fees.flash-loan": "the flash-loan fee is not served",
|
|
82326
|
+
"borrow.fees.host": "the host (referrer) share of the origination fee is not served",
|
|
82327
|
+
"supply.exit.rateLimiter": "the market-wide outflow limiter (window, max outflow) is in the LendingMarket account and not served \u2014 read on-chain before stating exit capacity",
|
|
82328
|
+
"borrow.rate.bounds": "the three-segment curve (min / optimal / max / super-max rates) is not served",
|
|
82329
|
+
"governance.controller": "the market owner (Save's key for Main, a third party elsewhere) is not served",
|
|
82330
|
+
oracle: "Pyth pull / Switchboard per reserve, and the owner-set SOL-price ratio some LST reserves are valued with, are not served",
|
|
82331
|
+
"borrow.liquidation.oracleStaleness": "Pyth pull \u2264 120 s, Switchboard \u2264 240 slots; a stale long-tail feed blocks every borrow or withdrawal of an obligation holding it"
|
|
82332
|
+
};
|
|
82333
|
+
if (typeof siloed !== "boolean")
|
|
82334
|
+
pending["constraints.siloedBorrowing"] = "the isolated-reserve flag (`siloedBorrowing`) is served on the row but not on the input";
|
|
82335
|
+
if (!isNum5(input.originationFee))
|
|
82336
|
+
pending["borrow.fees"] = "the origination fee is not on the row";
|
|
82337
|
+
const originationFee = isNum5(input.originationFee) && input.originationFee > 0 ? [
|
|
82338
|
+
{
|
|
82339
|
+
id: "origination",
|
|
82340
|
+
label: "Borrow (origination) fee",
|
|
82341
|
+
when: "entry",
|
|
82342
|
+
unit: "percent",
|
|
82343
|
+
basis: "principal",
|
|
82344
|
+
value: input.originationFee,
|
|
82345
|
+
payee: "protocol",
|
|
82346
|
+
mutable: true,
|
|
82347
|
+
description: "Deducted from the amount received; part of it goes to the referring host account when one is named."
|
|
82348
|
+
}
|
|
82349
|
+
] : void 0;
|
|
82350
|
+
return {
|
|
82351
|
+
...address ? { asset: { address: String(address) } } : {},
|
|
82352
|
+
supply: {
|
|
82353
|
+
rate: { compounding: "per-slot" },
|
|
82354
|
+
counterparty: {
|
|
82355
|
+
kind: "pool",
|
|
82356
|
+
solvency: "overcollateralized",
|
|
82357
|
+
socializedLoss: true
|
|
82358
|
+
},
|
|
82359
|
+
principal: { protected: false, risks: ["bad-debt"] }
|
|
82360
|
+
},
|
|
82361
|
+
borrow: {
|
|
82362
|
+
rate: { compounding: "per-slot" },
|
|
82363
|
+
liquidation: {
|
|
82364
|
+
model: "repay-seize",
|
|
82365
|
+
absorber: "liquidator",
|
|
82366
|
+
reversible: false,
|
|
82367
|
+
trigger: "price",
|
|
82368
|
+
// A program constant — the row carries the same 0.2.
|
|
82369
|
+
closeFactor: SAVE_LIQUIDATION_CLOSE_FACTOR,
|
|
82370
|
+
seizure: "proportional",
|
|
82371
|
+
permissioned: false,
|
|
82372
|
+
badDebt: "socialized",
|
|
82373
|
+
...isNum5(base?.liquidationPenalty) ? {
|
|
82374
|
+
penalties: [
|
|
82375
|
+
{
|
|
82376
|
+
id: "bonus-plus-protocol-fee",
|
|
82377
|
+
label: "Liquidator bonus + protocol fee (at the threshold)",
|
|
82378
|
+
value: base.liquidationPenalty,
|
|
82379
|
+
description: `What the borrower pays at the liquidation threshold: the liquidator bonus plus the protocol liquidation fee (the liquidator seizes both and pays the fee on). The bonus scales linearly toward the reserve maximum as the obligation approaches its max liquidation threshold; bonus + fee is capped at ${SAVE_MAX_PENALTY * 100} %.`
|
|
82380
|
+
}
|
|
82381
|
+
]
|
|
82382
|
+
} : {}
|
|
82383
|
+
},
|
|
82384
|
+
counterparty: {
|
|
82385
|
+
kind: "pool",
|
|
82386
|
+
solvency: "overcollateralized",
|
|
82387
|
+
socializedLoss: true
|
|
82388
|
+
},
|
|
82389
|
+
...originationFee ? { fees: originationFee } : {},
|
|
82390
|
+
ext: {
|
|
82391
|
+
save: {
|
|
82392
|
+
closeFactor: {
|
|
82393
|
+
fraction: SAVE_LIQUIDATION_CLOSE_FACTOR,
|
|
82394
|
+
basis: "the obligation's WEIGHTED borrow value",
|
|
82395
|
+
maxPerCallUsd: SAVE_MAX_LIQUIDATABLE_VALUE_USD,
|
|
82396
|
+
fullLiquidationAtOrBelowUsd: SAVE_FULL_LIQUIDATION_VALUE_USD
|
|
82397
|
+
},
|
|
82398
|
+
maxPenalty: SAVE_MAX_PENALTY,
|
|
82399
|
+
/** The row's `borrowFactor`: the debt multiplier (`borrowed_value += value × borrow_weight`). */
|
|
82400
|
+
...isNum5(base?.borrowFactor) ? { borrowWeight: base.borrowFactor } : {},
|
|
82401
|
+
isolatedRule: "Isolated reserves are borrow-side only: an obligation borrowing one may hold no other borrow (and one holding a regular borrow may not add it); deposits are unrestricted; LTV and LT are forced to 0.",
|
|
82402
|
+
...typeof siloed === "boolean" ? { isolated: siloed } : {},
|
|
82403
|
+
slotYear: {
|
|
82404
|
+
slotsPerYear: SAVE_SLOTS_PER_YEAR,
|
|
82405
|
+
note: "The curve compounds per slot on a 0.5 s slot-year; the row publishes it scaled to the measured slot time."
|
|
82406
|
+
}
|
|
82407
|
+
}
|
|
82408
|
+
}
|
|
82409
|
+
},
|
|
82410
|
+
constraints: {
|
|
82411
|
+
crossMargin: true,
|
|
82412
|
+
positionModel: "sub-account",
|
|
82413
|
+
positionIdMeaning: `The obligation pubkey, derived with createWithSeed(wallet, seed, program): #0 seeds with market[0:32], #n with market[0:24] + n (6 digits) + "m" \u2014 no index account needed. One obligation holds up to ${SAVE_MAX_OBLIGATION_RESERVES} reserves (the SDK caps a position at ${SAVE_POSITION_LIMIT}).`,
|
|
82414
|
+
...typeof siloed === "boolean" ? { siloedBorrowing: siloed } : {}
|
|
82415
|
+
},
|
|
82416
|
+
ext: {
|
|
82417
|
+
save: {
|
|
82418
|
+
program: SAVE_PROGRAM_ID,
|
|
82419
|
+
...market ? { market } : {},
|
|
82420
|
+
/** The marketUid ref is the RESERVE pubkey, not the mint. */
|
|
82421
|
+
marketUidRef: "reserve"
|
|
82422
|
+
}
|
|
82423
|
+
},
|
|
82424
|
+
coverage: { pending }
|
|
82425
|
+
};
|
|
82426
|
+
}
|
|
82427
|
+
var saveAdapter = {
|
|
82428
|
+
id: "save",
|
|
82429
|
+
matches: isSave,
|
|
82430
|
+
profileId: () => SAVE_PROFILE_ID,
|
|
82431
|
+
build: build3
|
|
82432
|
+
};
|
|
82433
|
+
var LOOPSCALE_PROFILE_ID = "loopscale.creditbook@v1";
|
|
82434
|
+
var LOOPSCALE_PROGRAM_ID = "1oopBoJG58DgkUVKkEzKgyG9dvRmpgeEm1AVjoHkF78";
|
|
82435
|
+
var LOOPSCALE_BEAM_ORACLE_PROGRAM_ID = "beamVVkNmKeXcuZ6zLpC9eM5YgVyAn4Z9xdPrz3gCW2";
|
|
82436
|
+
var LOOPSCALE_GRACE_PERIOD_SECS = 172800;
|
|
82437
|
+
var LOOPSCALE_REFINANCE_TERM_DAYS = 1;
|
|
82438
|
+
var LOOPSCALE_MAX_COLLATERALS = 5;
|
|
82439
|
+
var LOOPSCALE_MAX_LEDGERS = 5;
|
|
82440
|
+
var LS_NO_ACCOUNT = "11111111111111111111111111111111";
|
|
82441
|
+
var DAY2 = 86400;
|
|
82442
|
+
var isNum6 = (v) => typeof v === "number" && Number.isFinite(v);
|
|
82443
|
+
function menuOf(input) {
|
|
82444
|
+
if (!input.terms?.length) return void 0;
|
|
82445
|
+
return input.terms.map((t) => ({
|
|
82446
|
+
...t,
|
|
82447
|
+
durationSecs: isNum6(t.durationSecs) ? t.durationSecs : Math.round(t.durationDays * DAY2)
|
|
82448
|
+
}));
|
|
82449
|
+
}
|
|
82450
|
+
function build4(input) {
|
|
82451
|
+
const pair = loopscaleMarketFromKey(input.lender);
|
|
82452
|
+
const m = input.market ?? {};
|
|
82453
|
+
const cfg = input.config?.["0"];
|
|
82454
|
+
const address = input.asset?.address ?? input.underlying;
|
|
82455
|
+
const menu = menuOf(input);
|
|
82456
|
+
const durations = (menu ?? []).map((t) => t.durationSecs).filter(isNum6);
|
|
82457
|
+
const tenor = durations.length ? {
|
|
82458
|
+
minDurationSecs: Math.min(...durations),
|
|
82459
|
+
maxDurationSecs: Math.max(...durations)
|
|
82460
|
+
} : {};
|
|
82461
|
+
const oracleAccount = typeof m.oracle === "string" && m.oracle !== LS_NO_ACCOUNT ? m.oracle : void 0;
|
|
82462
|
+
const lltvRaw = m.lltv != null ? Number(m.lltv) : void 0;
|
|
82463
|
+
const bestOneDayLqt = lltvRaw != null && Number.isFinite(lltvRaw) && lltvRaw > 0 ? lltvRaw / 1e18 : void 0;
|
|
82464
|
+
const openParameter = cfg?.openParameter;
|
|
82465
|
+
const pending = {
|
|
82466
|
+
"borrow.liquidation.penalty": "distance-based \u2014 the fee is how far past the liquidation LTV the loan was (80.5 % on an 80 % threshold \u21D2 0.5 %); there is no flat figure to state",
|
|
82467
|
+
"borrow.rate.menu.ltv": "each tenor's best-offer LTV / LQT and its depth ladder are not served (`terms` carry the rate only); the row's factors are the best 1-day offer's",
|
|
82468
|
+
"supply.fees": "the curated vault's interest fee (0\u201325 %) is not served; the row's depositRate is already net of the fee the converter attributed",
|
|
82469
|
+
"borrow.counterparty.curator": "which strategy rests the best offer (and its vault) is not served",
|
|
82470
|
+
"governance.controller": "per strategy: the curator (24 h timelock on collateral / LTV, rates and fees immediate) and the protocol admin are not on the public API"
|
|
82471
|
+
};
|
|
82472
|
+
if (!oracleAccount)
|
|
82473
|
+
pending.oracle = "no oracle account is on params.market for this collateral (the MarketInformation read did not name one)";
|
|
82474
|
+
else
|
|
82475
|
+
pending.oracle = `the program reads ${oracleAccount} (BEAM: Pyth / Switchboard / Chainlink / RedStone + component pricing); not classified`;
|
|
82476
|
+
if (!isNum6(input.originationFee) && input.borrowingEnabled === true)
|
|
82477
|
+
pending["borrow.fees"] = "no curated vault offers this pair \u2014 the resting strategy\u2019s fees are not on the public API";
|
|
82478
|
+
if (!cfg?.openParameter && cfg?.collateralDisabled === false)
|
|
82479
|
+
pending["supply.ext.openParameter"] = "the per-loan threshold domain (`config['0'].openParameter`, kind `loan-lqt`) is served on the collateral row but not on the input";
|
|
82480
|
+
const isLoanLeg = cfg?.debtDisabled === false || input.rateModel === "fixedTerm" || !!input.terms?.length;
|
|
82481
|
+
const originationFee = isNum6(input.originationFee) ? input.originationFee > 0 ? [
|
|
82482
|
+
{
|
|
82483
|
+
id: "origination",
|
|
82484
|
+
label: "Origination fee",
|
|
82485
|
+
when: "entry",
|
|
82486
|
+
unit: "percent",
|
|
82487
|
+
basis: "principal",
|
|
82488
|
+
value: input.originationFee,
|
|
82489
|
+
payee: "curator",
|
|
82490
|
+
mutable: true,
|
|
82491
|
+
description: "Set by the strategy (vault) resting the offer; taken at origination. The row's figure is the best offer's vault, else the highest among the pair's vaults."
|
|
82492
|
+
}
|
|
82493
|
+
] : [] : void 0;
|
|
82494
|
+
const fixedRate = {
|
|
82495
|
+
kind: "fixed-term",
|
|
82496
|
+
source: "orderbook",
|
|
82497
|
+
isLocked: true,
|
|
82498
|
+
compounding: "none",
|
|
82499
|
+
...menu ? { menu } : {}
|
|
82500
|
+
};
|
|
82501
|
+
return {
|
|
82502
|
+
...address ? { asset: { address: String(address) } } : {},
|
|
82503
|
+
// An order book has no pool utilization; the row's 0 is a placeholder.
|
|
82504
|
+
// `null`, not `undefined`: the deep merge skips `undefined`, so only
|
|
82505
|
+
// `null` removes the builder's block (the type has no "remove" spelling).
|
|
82506
|
+
utilization: null,
|
|
82507
|
+
supply: isLoanLeg ? {
|
|
82508
|
+
// What an advanced lender resting at the best 1-day rate earns.
|
|
82509
|
+
rate: fixedRate,
|
|
82510
|
+
maturity: {
|
|
82511
|
+
kind: "rolling-duration",
|
|
82512
|
+
...tenor,
|
|
82513
|
+
// The ledger is repaid out of the refinancing offer, or runs the
|
|
82514
|
+
// grace period at the same rate.
|
|
82515
|
+
atMaturity: "refinanced",
|
|
82516
|
+
graceSecs: LOOPSCALE_GRACE_PERIOD_SECS
|
|
82517
|
+
},
|
|
82518
|
+
exit: {
|
|
82519
|
+
// Before maturity a ledger leaves only by being sold to another
|
|
82520
|
+
// strategy at a negotiated price — and there may be no buyer.
|
|
82521
|
+
mode: "market-sale",
|
|
82522
|
+
settlement: "sync",
|
|
82523
|
+
priceRisk: "may-be-impossible",
|
|
82524
|
+
partialAllowed: true
|
|
82525
|
+
},
|
|
82526
|
+
counterparty: { kind: "orderbook", solvency: "overcollateralized" },
|
|
82527
|
+
principal: { protected: false, risks: ["bad-debt"] },
|
|
82528
|
+
ext: {
|
|
82529
|
+
loopscale: {
|
|
82530
|
+
exitBeforeMaturity: "sell-ledger",
|
|
82531
|
+
passiveLenders: "Deposit into a curated vault (its own earn row), which rests the offers and charges a fee on the interest"
|
|
82532
|
+
}
|
|
82533
|
+
}
|
|
82534
|
+
} : {
|
|
82535
|
+
...openParameter ? {
|
|
82536
|
+
ext: {
|
|
82537
|
+
loopscale: {
|
|
82538
|
+
// Each loan pins the LTV / LQT of the offer it filled;
|
|
82539
|
+
// `modes[<loan pubkey>]` carries the value per position.
|
|
82540
|
+
openParameter
|
|
82541
|
+
}
|
|
82542
|
+
}
|
|
82543
|
+
} : {}
|
|
82544
|
+
},
|
|
82545
|
+
borrow: {
|
|
82546
|
+
rate: fixedRate,
|
|
82547
|
+
maturity: {
|
|
82548
|
+
kind: "rolling-duration",
|
|
82549
|
+
...tenor,
|
|
82550
|
+
atMaturity: "refinanced",
|
|
82551
|
+
graceSecs: LOOPSCALE_GRACE_PERIOD_SECS
|
|
82552
|
+
},
|
|
82553
|
+
// Interest accrues to date; repaying early costs the interest so far.
|
|
82554
|
+
debtShape: "accruing",
|
|
82555
|
+
exit: {
|
|
82556
|
+
earlyRepay: "free",
|
|
82557
|
+
atMaturityCost: "accrued",
|
|
82558
|
+
// Not refinanced and past the grace period: liquidatable whatever
|
|
82559
|
+
// the health.
|
|
82560
|
+
lateBehaviour: "liquidatable",
|
|
82561
|
+
partialAllowed: true
|
|
82562
|
+
},
|
|
82563
|
+
liquidation: {
|
|
82564
|
+
model: "repay-seize",
|
|
82565
|
+
absorber: "liquidator",
|
|
82566
|
+
reversible: false,
|
|
82567
|
+
trigger: "price-and-time",
|
|
82568
|
+
seizure: "proportional",
|
|
82569
|
+
// Distance-based: there is no headline penalty. The row's 0 is the
|
|
82570
|
+
// converter's placeholder; `null` removes it (see `utilization`).
|
|
82571
|
+
penalty: null,
|
|
82572
|
+
penalties: [
|
|
82573
|
+
{
|
|
82574
|
+
id: "distance-past-threshold",
|
|
82575
|
+
label: "Distance past the liquidation LTV",
|
|
82576
|
+
value: 0,
|
|
82577
|
+
description: "Partial first: the minimum collateral to bring the loan back under its MAX LTV is sold, and the fee equals how far past the liquidation LTV the loan was (80.5 % on an 80 % threshold \u21D2 0.5 %). 0 is its value AT the threshold. Health counts the interest owed at maturity as debt."
|
|
82578
|
+
}
|
|
82579
|
+
]
|
|
82580
|
+
},
|
|
82581
|
+
counterparty: { kind: "orderbook", solvency: "overcollateralized" },
|
|
82582
|
+
...originationFee ? { fees: originationFee } : {},
|
|
82583
|
+
ext: {
|
|
82584
|
+
loopscale: {
|
|
82585
|
+
autoRefinance: {
|
|
82586
|
+
termDays: LOOPSCALE_REFINANCE_TERM_DAYS,
|
|
82587
|
+
bestEffort: true,
|
|
82588
|
+
fallback: "no matching offer \u21D2 a 48-hour grace period at the same rate, then partial liquidation"
|
|
82589
|
+
},
|
|
82590
|
+
gracePeriodSecs: LOOPSCALE_GRACE_PERIOD_SECS,
|
|
82591
|
+
healthCountsInterestToMaturity: true,
|
|
82592
|
+
ltvPinnedAtOrigination: true,
|
|
82593
|
+
...bestOneDayLqt !== void 0 ? {
|
|
82594
|
+
bestOneDayLiquidationLtv: bestOneDayLqt,
|
|
82595
|
+
bestOneDayLiquidationLtvNote: "params.market.lltv: the best 1-day offer's threshold today \u2014 a moving proxy, not a market constant"
|
|
82596
|
+
} : {}
|
|
82597
|
+
}
|
|
82598
|
+
}
|
|
82599
|
+
},
|
|
82600
|
+
constraints: {
|
|
82601
|
+
crossMargin: true,
|
|
82602
|
+
positionModel: "loan-id",
|
|
82603
|
+
positionIdMeaning: `The Loan account pubkey \u2014 one per loan, opened by the venue's builder; up to ${LOOPSCALE_MAX_COLLATERALS} collaterals and ${LOOPSCALE_MAX_LEDGERS} ledgers each, cross-margined inside the loan.`
|
|
82604
|
+
},
|
|
82605
|
+
ext: {
|
|
82606
|
+
loopscale: {
|
|
82607
|
+
program: LOOPSCALE_PROGRAM_ID,
|
|
82608
|
+
oracleProgram: LOOPSCALE_BEAM_ORACLE_PROGRAM_ID,
|
|
82609
|
+
...pair ? { pair } : {},
|
|
82610
|
+
...oracleAccount ? { oracleAccount } : {},
|
|
82611
|
+
/** The marketUid ref is the leg's MINT. */
|
|
82612
|
+
marketUidRef: "mint"
|
|
82613
|
+
}
|
|
82614
|
+
},
|
|
82615
|
+
coverage: {
|
|
82616
|
+
pending,
|
|
82617
|
+
notApplicable: { utilization: "order book \u2014 no pool utilization" }
|
|
82618
|
+
}
|
|
82619
|
+
};
|
|
82620
|
+
}
|
|
82621
|
+
var loopscaleAdapter = {
|
|
82622
|
+
id: "loopscale",
|
|
82623
|
+
matches: isLoopscale,
|
|
82624
|
+
profileId: () => LOOPSCALE_PROFILE_ID,
|
|
82625
|
+
build: build4
|
|
82626
|
+
};
|
|
82627
|
+
var PROJECT_0_PROFILE_ID = "project0.group@v1";
|
|
82628
|
+
var P0_PROGRAM_ID = "MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA";
|
|
82629
|
+
var P0_MAIN_GROUP = "4qp6Fx6tnZkY5Wropq9wUYgtFxXKwE6viZxFHg3rdAG8";
|
|
82630
|
+
var P0_DEFAULT_LIQUIDATION_FEE = 0.025;
|
|
82631
|
+
var P0_LIQUIDATION_CLOSEOUT_USD = 5;
|
|
82632
|
+
var P0_MAX_BALANCES = 16;
|
|
82633
|
+
var P0_SECONDS_PER_YEAR = 365 * 24 * 60 * 60;
|
|
82634
|
+
var isNum7 = (v) => typeof v === "number" && Number.isFinite(v);
|
|
82635
|
+
function derivedModes(input) {
|
|
82636
|
+
const cfg = input.config;
|
|
82637
|
+
if (!cfg || Object.keys(cfg).length <= 1) return void 0;
|
|
82638
|
+
return Object.entries(cfg).map(([key3, c]) => {
|
|
82639
|
+
const isDefault = key3 === "0";
|
|
82640
|
+
return {
|
|
82641
|
+
modeId: key3,
|
|
82642
|
+
label: c.label,
|
|
82643
|
+
isDefault,
|
|
82644
|
+
entry: isDefault ? void 0 : "automatic",
|
|
82645
|
+
liquidation: {
|
|
82646
|
+
ltv: c.borrowCollateralFactor,
|
|
82647
|
+
liquidationLtv: c.collateralFactor,
|
|
82648
|
+
penalty: c.liquidationPenalty,
|
|
82649
|
+
closeFactor: c.closeFactor ?? input.closeFactor ?? 1,
|
|
82650
|
+
targetHealthFactor: c.targetHealthFactor ?? input.targetHealthFactor
|
|
82651
|
+
},
|
|
82652
|
+
...c.debtDisabled ? { availability: { canOpen: false } } : {}
|
|
82653
|
+
};
|
|
82654
|
+
});
|
|
82655
|
+
}
|
|
82656
|
+
function build5(input) {
|
|
82657
|
+
const group = project0GroupFromKey(input.lender);
|
|
82658
|
+
const base = input.config?.["0"];
|
|
82659
|
+
const siloed = input.siloedBorrowing;
|
|
82660
|
+
const address = input.asset?.address ?? input.underlying;
|
|
82661
|
+
const penalty = base?.liquidationPenalty;
|
|
82662
|
+
const defaultFees = isNum7(penalty) && Math.abs(penalty - 2 * P0_DEFAULT_LIQUIDATION_FEE) < 1e-9;
|
|
82663
|
+
const liabilityWeightMaint = base?.liquidationBorrowFactor;
|
|
82664
|
+
const pending = {
|
|
82665
|
+
"ext.project0.operationalState": "the bank's operational state (Operational / Paused / ReduceOnly / ReduceOnlyWithBorrowingPower, or a circuit-breaker halt) is not served; the flags carry its effect on opening only",
|
|
82666
|
+
"borrow.fees.interest": "the group, insurance and program fee legs on interest (and their fixed APRs) are not served",
|
|
82667
|
+
"supply.exit.rateLimiter": "the bank's hourly / daily outflow limiter (shared by withdrawals and borrows) and the group's USD limiter are not served",
|
|
82668
|
+
"supply.rate.wrapped": "whether this bank wraps a Kamino / Drift / Jupiter Lend position or native stake is not served; a wrapped bank's yield is the venue's (on intrinsicYield when the fetcher supplies it)",
|
|
82669
|
+
"borrow.liquidation.receivership": "the receivership path (a liquidator controls the account for one transaction, at a higher premium) is not modelled",
|
|
82670
|
+
"borrow.modes.sameAsset": "the group's same-asset e-mode leverage (and the 20\xD7 / 40\xD7 caps) is not served",
|
|
82671
|
+
oracle: "the oracle setup (Pyth push / Switchboard / fixed / Kamino Scope / staked), max age and confidence cap are not served",
|
|
82672
|
+
"governance.roles": "the group admin and its delegates (e-mode, curve, limit, risk admins) are not served; multisig status unverified"
|
|
82673
|
+
};
|
|
82674
|
+
if (!isNum7(liabilityWeightMaint) && base?.debtDisabled === false)
|
|
82675
|
+
pending["borrow.liquidation.liquidationBorrowFactor"] = "the maintenance liability weight (`config.liquidationBorrowFactor`) is served on the row but not on the input; `borrowFactor` is the INITIAL weight, which overstates the debt for liquidation";
|
|
82676
|
+
if (typeof siloed !== "boolean")
|
|
82677
|
+
pending["constraints.siloedBorrowing"] = "the isolated-tier flag (`siloedBorrowing`) is served on the row but not on the input";
|
|
82678
|
+
if (isNum7(penalty) && !defaultFees)
|
|
82679
|
+
pending["borrow.liquidation.penaltySplit"] = "the row carries liquidator + insurance fee as one figure; the split is not served";
|
|
82680
|
+
if (!isNum7(input.originationFee))
|
|
82681
|
+
pending["borrow.fees"] = "the origination fee is not on the row";
|
|
82682
|
+
const penalties = !isNum7(penalty) ? void 0 : defaultFees ? [
|
|
82683
|
+
{
|
|
82684
|
+
id: "liquidator-fee",
|
|
82685
|
+
label: "Liquidator premium",
|
|
82686
|
+
value: P0_DEFAULT_LIQUIDATION_FEE,
|
|
82687
|
+
description: "Read from the LIABILITY bank being repaid (a stored 0 is this 2.5 % default); it goes to the liquidator."
|
|
82688
|
+
},
|
|
82689
|
+
{
|
|
82690
|
+
id: "insurance-fee",
|
|
82691
|
+
label: "Insurance fund fee",
|
|
82692
|
+
value: P0_DEFAULT_LIQUIDATION_FEE,
|
|
82693
|
+
description: "Also read from the liability bank; the liquidatee pays both, the insurance fund keeps this one. `penalty` is the total the liquidatee loses."
|
|
82694
|
+
}
|
|
82695
|
+
] : [
|
|
82696
|
+
{
|
|
82697
|
+
id: "liquidation-fees",
|
|
82698
|
+
label: "Liquidator premium + insurance fee",
|
|
82699
|
+
value: penalty,
|
|
82700
|
+
description: "Both read from the LIABILITY bank being repaid; the liquidatee pays the total."
|
|
82701
|
+
}
|
|
82702
|
+
];
|
|
82703
|
+
const originationFee = isNum7(input.originationFee) && input.originationFee > 0 ? [
|
|
82704
|
+
{
|
|
82705
|
+
id: "origination",
|
|
82706
|
+
label: "Borrow origination fee",
|
|
82707
|
+
when: "entry",
|
|
82708
|
+
unit: "percent",
|
|
82709
|
+
basis: "principal",
|
|
82710
|
+
value: input.originationFee,
|
|
82711
|
+
payee: "protocol",
|
|
82712
|
+
mutable: true
|
|
82713
|
+
}
|
|
82714
|
+
] : void 0;
|
|
82715
|
+
const modes = derivedModes(input);
|
|
82716
|
+
return {
|
|
82717
|
+
...address ? { asset: { address: String(address) } } : {},
|
|
82718
|
+
supply: {
|
|
82719
|
+
// Simple interest settled into the share value at every touch.
|
|
82720
|
+
rate: { compounding: "on-touch" },
|
|
82721
|
+
counterparty: {
|
|
82722
|
+
kind: "pool",
|
|
82723
|
+
solvency: "overcollateralized",
|
|
82724
|
+
socializedLoss: true
|
|
82725
|
+
},
|
|
82726
|
+
principal: { protected: false, risks: ["bad-debt"] },
|
|
82727
|
+
...modes ? { modes } : {}
|
|
82728
|
+
},
|
|
82729
|
+
borrow: {
|
|
82730
|
+
rate: { compounding: "on-touch" },
|
|
82731
|
+
liquidation: {
|
|
82732
|
+
model: "repay-seize",
|
|
82733
|
+
absorber: "liquidator",
|
|
82734
|
+
reversible: false,
|
|
82735
|
+
trigger: "price",
|
|
82736
|
+
seizure: "proportional",
|
|
82737
|
+
permissioned: false,
|
|
82738
|
+
// The insurance fund absorbs first; the rest is socialised to the
|
|
82739
|
+
// bank's depositors (`counterparty.socializedLoss`).
|
|
82740
|
+
badDebt: "insurance-fund",
|
|
82741
|
+
...penalties ? { penalties } : {}
|
|
82742
|
+
},
|
|
82743
|
+
counterparty: {
|
|
82744
|
+
kind: "pool",
|
|
82745
|
+
solvency: "overcollateralized",
|
|
82746
|
+
socializedLoss: true
|
|
82747
|
+
},
|
|
82748
|
+
...originationFee ? { fees: originationFee } : {},
|
|
82749
|
+
...modes ? { modes } : {},
|
|
82750
|
+
ext: {
|
|
82751
|
+
project0: {
|
|
82752
|
+
liquidation: {
|
|
82753
|
+
partialToHealthZero: true,
|
|
82754
|
+
closeoutBelowEquityUsd: P0_LIQUIDATION_CLOSEOUT_USD,
|
|
82755
|
+
feesReadFrom: "the liability bank",
|
|
82756
|
+
defaultFeeEach: P0_DEFAULT_LIQUIDATION_FEE
|
|
82757
|
+
},
|
|
82758
|
+
liabilityWeights: {
|
|
82759
|
+
/** `borrowFactor`: the weight a NEW borrow is checked against. */
|
|
82760
|
+
...isNum7(base?.borrowFactor) ? { init: base.borrowFactor } : {},
|
|
82761
|
+
/** `liquidationBorrowFactor`: the weight liquidation health uses. */
|
|
82762
|
+
...isNum7(liabilityWeightMaint) ? { maint: liabilityWeightMaint } : {}
|
|
82763
|
+
},
|
|
82764
|
+
emodeModel: "Derived, never selected: an account's mode follows the e-mode tags of everything it borrows \u2014 the program takes the least favourable lift per collateral tag across the liabilities, and a liability with no entry for a collateral tag removes that lift.",
|
|
82765
|
+
operationalStates: {
|
|
82766
|
+
Operational: "every action",
|
|
82767
|
+
ReduceOnly: "no deposits or borrows; withdrawals and repayments work; the collateral counts toward liquidation health only (initial weight 0)",
|
|
82768
|
+
ReduceOnlyWithBorrowingPower: "no deposits or borrows; the collateral keeps both weights",
|
|
82769
|
+
Paused: "no deposits, withdrawals, borrows, repayments or liquidations",
|
|
82770
|
+
accrual: "interest accrues at the curve rate in every state"
|
|
82771
|
+
},
|
|
82772
|
+
isolatedRule: "An isolated-tier bank can be borrowed only on its own and never counts as collateral.",
|
|
82773
|
+
...typeof siloed === "boolean" ? { isolated: siloed } : {},
|
|
82774
|
+
secondsPerYear: P0_SECONDS_PER_YEAR
|
|
82775
|
+
}
|
|
82776
|
+
}
|
|
82777
|
+
},
|
|
82778
|
+
constraints: {
|
|
82779
|
+
crossMargin: true,
|
|
82780
|
+
positionModel: "sub-account",
|
|
82781
|
+
positionIdMeaning: `The marginfi account pubkey \u2014 a keypair account (older) or the PDA ["marginfi_account", group, authority, u16 index, u16 third-party id]; any number per wallet, up to ${P0_MAX_BALANCES} balances each, one health per account.`,
|
|
82782
|
+
...typeof siloed === "boolean" ? { siloedBorrowing: siloed } : {}
|
|
82783
|
+
},
|
|
82784
|
+
ext: {
|
|
82785
|
+
project0: {
|
|
82786
|
+
program: P0_PROGRAM_ID,
|
|
82787
|
+
...group ? { group, isMainGroup: group === P0_MAIN_GROUP } : {},
|
|
82788
|
+
/** The marketUid ref is the BANK pubkey, not the mint. */
|
|
82789
|
+
marketUidRef: "bank"
|
|
82790
|
+
}
|
|
82791
|
+
},
|
|
82792
|
+
coverage: { pending }
|
|
82793
|
+
};
|
|
82794
|
+
}
|
|
82795
|
+
var project0Adapter = {
|
|
82796
|
+
id: "project0",
|
|
82797
|
+
matches: isProject0,
|
|
82798
|
+
profileId: () => PROJECT_0_PROFILE_ID,
|
|
82799
|
+
build: build5
|
|
82800
|
+
};
|
|
81821
82801
|
|
|
81822
82802
|
// src/terms/adapters/index.ts
|
|
81823
82803
|
var TERM_ADAPTERS = [
|
|
@@ -81843,7 +82823,14 @@ var TERM_ADAPTERS = [
|
|
|
81843
82823
|
twyneAdapter,
|
|
81844
82824
|
fraxlendAdapter,
|
|
81845
82825
|
morphoBlueAdapter,
|
|
81846
|
-
aaveV4Adapter
|
|
82826
|
+
aaveV4Adapter,
|
|
82827
|
+
// Solana families — predicates match `<FAMILY>` / `<FAMILY>_<base58>` on an
|
|
82828
|
+
// `_` boundary, disjoint from every EVM key above.
|
|
82829
|
+
kaminoAdapter,
|
|
82830
|
+
jupiterLendAdapter,
|
|
82831
|
+
saveAdapter,
|
|
82832
|
+
loopscaleAdapter,
|
|
82833
|
+
project0Adapter
|
|
81847
82834
|
];
|
|
81848
82835
|
function resolveAdapter(lender) {
|
|
81849
82836
|
return TERM_ADAPTERS.find((a) => a.matches(lender));
|
|
@@ -81927,9 +82914,10 @@ function enrichmentIndexFromRows(rows) {
|
|
|
81927
82914
|
}
|
|
81928
82915
|
const token = breakdown.find((b) => b?.category === "token");
|
|
81929
82916
|
const chainId = String(row?.chainId ?? uid.split(":")[1] ?? "");
|
|
81930
|
-
const address =
|
|
81931
|
-
|
|
81932
|
-
|
|
82917
|
+
const address = termAddressKey(
|
|
82918
|
+
chainId,
|
|
82919
|
+
String(row?.asset?.address ?? row?.underlying ?? uid.split(":")[2] ?? "")
|
|
82920
|
+
);
|
|
81933
82921
|
if (token?.score != null && chainId && address) {
|
|
81934
82922
|
assetRisk[chainId] ??= {};
|
|
81935
82923
|
assetRisk[chainId][address] = {
|
|
@@ -81955,6 +82943,7 @@ function toDigest(sheet) {
|
|
|
81955
82943
|
settlement: sheet.supply.exit.settlement,
|
|
81956
82944
|
canOpen: sheet.supply.availability.canOpen,
|
|
81957
82945
|
headline: sheet.supply.info.headline,
|
|
82946
|
+
description: sheet.supply.info.description,
|
|
81958
82947
|
tags: sheet.supply.info.tags,
|
|
81959
82948
|
backedBy: strip(sheet.supply.backedBy)
|
|
81960
82949
|
} : void 0,
|
|
@@ -81968,6 +82957,7 @@ function toDigest(sheet) {
|
|
|
81968
82957
|
liquidationTrigger: sheet.borrow.liquidation.trigger,
|
|
81969
82958
|
canOpen: sheet.borrow.availability.canOpen,
|
|
81970
82959
|
headline: sheet.borrow.info.headline,
|
|
82960
|
+
description: sheet.borrow.info.description,
|
|
81971
82961
|
tags: sheet.borrow.info.tags,
|
|
81972
82962
|
acceptedCollateral: strip(sheet.borrow.acceptedCollateral)
|
|
81973
82963
|
} : void 0,
|
|
@@ -81994,7 +82984,7 @@ function enrichTermSheet(sheet, index) {
|
|
|
81994
82984
|
sheet.oracle = {
|
|
81995
82985
|
...sheet.oracle,
|
|
81996
82986
|
kind: "price-feed",
|
|
81997
|
-
address: oracleRow.oracle
|
|
82987
|
+
address: termAddressKey(sheet.chainId, oracleRow.oracle),
|
|
81998
82988
|
provider: oracleRow.provider,
|
|
81999
82989
|
priceDescription: oracleRow.priceDescription,
|
|
82000
82990
|
intendedPair: oracleRow.intendedPair,
|
|
@@ -82059,7 +83049,7 @@ function enrichTermSheet(sheet, index) {
|
|
|
82059
83049
|
if (itemOracle?.oracle) {
|
|
82060
83050
|
item.oracle = {
|
|
82061
83051
|
kind: "price-feed",
|
|
82062
|
-
address: itemOracle.oracle
|
|
83052
|
+
address: termAddressKey(sheet.chainId, itemOracle.oracle),
|
|
82063
83053
|
provider: itemOracle.provider,
|
|
82064
83054
|
band: itemOracle.band,
|
|
82065
83055
|
score: itemOracle.score,
|
|
@@ -82249,8 +83239,8 @@ function validateTermSheet(sheet) {
|
|
|
82249
83239
|
`oracle.kind none but liquidation.trigger is ${t} with model ${m ?? "unset"}`
|
|
82250
83240
|
);
|
|
82251
83241
|
}
|
|
82252
|
-
if (o.address && o.address !== o.address
|
|
82253
|
-
fail("oracle-lowercase", "oracle.address must be lowercased");
|
|
83242
|
+
if (o.address && o.address !== termAddressKey(sheet.chainId, o.address))
|
|
83243
|
+
fail("oracle-lowercase", "oracle.address must be lowercased (EVM)");
|
|
82254
83244
|
}
|
|
82255
83245
|
const g = sheet.governance;
|
|
82256
83246
|
if (g) {
|
|
@@ -82629,13 +83619,28 @@ function stampCapabilities(row) {
|
|
|
82629
83619
|
row.capabilities = row.venueKind === "lending" ? lendingCapabilities(row) : vaultCapabilities(row);
|
|
82630
83620
|
return row;
|
|
82631
83621
|
}
|
|
83622
|
+
function nativeStandsIn(row) {
|
|
83623
|
+
const wrapped = getWrappedNativeAddressSafe(row.chainId);
|
|
83624
|
+
return !!wrapped && wrapped.toLowerCase() === String(row.asset?.address ?? "").toLowerCase() && isNativeWrapOneToOne(row.chainId);
|
|
83625
|
+
}
|
|
83626
|
+
var NO_NATIVE_PROVIDERS = /* @__PURE__ */ new Set(["gmx", "hypercore"]);
|
|
82632
83627
|
function lendingCapabilities(row) {
|
|
82633
83628
|
const caps = [];
|
|
83629
|
+
const native = nativeStandsIn(row) && !isLiquityFamily(row.venue) && !isFluid(row.venue);
|
|
83630
|
+
const fixedLendExit = isTermMax(row.venue) || isTerm(row.venue);
|
|
82634
83631
|
if (row.availability.canDeposit) {
|
|
82635
|
-
caps.push({
|
|
83632
|
+
caps.push({
|
|
83633
|
+
action: "deposit",
|
|
83634
|
+
acceptsPayAsset: true,
|
|
83635
|
+
acceptsNative: native
|
|
83636
|
+
});
|
|
82636
83637
|
}
|
|
82637
83638
|
if (row.availability.canWithdraw) {
|
|
82638
|
-
caps.push({
|
|
83639
|
+
caps.push({
|
|
83640
|
+
action: "withdraw",
|
|
83641
|
+
acceptsReceiveAsset: true,
|
|
83642
|
+
acceptsNative: native && !fixedLendExit
|
|
83643
|
+
});
|
|
82639
83644
|
}
|
|
82640
83645
|
return caps;
|
|
82641
83646
|
}
|
|
@@ -82653,6 +83658,9 @@ var NON_4626_DEPOSIT_KINDS = /* @__PURE__ */ new Set([
|
|
|
82653
83658
|
"frankencoin",
|
|
82654
83659
|
"yieldbasis",
|
|
82655
83660
|
"wren",
|
|
83661
|
+
// Vesper va* pools — `deposit(amount)` credits msg.sender only (mirrors the
|
|
83662
|
+
// worker's list, which had it and this one did not)
|
|
83663
|
+
"vesper",
|
|
82656
83664
|
"hyperbeat",
|
|
82657
83665
|
"native-wnlp",
|
|
82658
83666
|
"bitway"
|
|
@@ -82693,7 +83701,8 @@ function swapRoutedCapabilities(row, opts) {
|
|
|
82693
83701
|
action: "deposit",
|
|
82694
83702
|
via: "swap",
|
|
82695
83703
|
requires: ["slippage"],
|
|
82696
|
-
acceptsPayAsset: true
|
|
83704
|
+
acceptsPayAsset: true,
|
|
83705
|
+
acceptsNative: nativeStandsIn(row)
|
|
82697
83706
|
});
|
|
82698
83707
|
}
|
|
82699
83708
|
if (row.availability.canWithdraw) {
|
|
@@ -82701,7 +83710,8 @@ function swapRoutedCapabilities(row, opts) {
|
|
|
82701
83710
|
action: "withdraw",
|
|
82702
83711
|
via: "swap",
|
|
82703
83712
|
requires: ["slippage"],
|
|
82704
|
-
acceptsReceiveAsset: true
|
|
83713
|
+
acceptsReceiveAsset: true,
|
|
83714
|
+
acceptsNative: nativeStandsIn(row)
|
|
82705
83715
|
});
|
|
82706
83716
|
}
|
|
82707
83717
|
return caps;
|
|
@@ -82724,21 +83734,33 @@ function vaultCapabilities(row) {
|
|
|
82724
83734
|
// deposit — but ONLY for rows whose deposit is a plain synchronous
|
|
82725
83735
|
// ERC-4626 call. Advertising it anywhere else builds a zap input that
|
|
82726
83736
|
// 400s at submit, which is exactly what this flag existed to prevent.
|
|
82727
|
-
acceptsPayAsset: acceptsVaultZap(row, provider)
|
|
83737
|
+
acceptsPayAsset: acceptsVaultZap(row, provider),
|
|
83738
|
+
// native for a wrapped-native deposit token is NOT a zap: the 4626 rows
|
|
83739
|
+
// take it through the composer, every single-token builder (Lagoon,
|
|
83740
|
+
// the non-4626 savings kinds, ERC-20-only LST mints) as a leading wrap
|
|
83741
|
+
acceptsNative: !NO_NATIVE_PROVIDERS.has(provider) && nativeStandsIn(row)
|
|
82728
83742
|
});
|
|
82729
83743
|
}
|
|
82730
83744
|
if (!row.availability.canWithdraw) return caps;
|
|
82731
83745
|
const mode = row.exit.mode;
|
|
82732
83746
|
const isAsync = provider !== "hypercore" && (ASYNC_PROVIDERS.has(provider) || ASYNC_EXIT_MODES.has(mode));
|
|
82733
83747
|
if (!isAsync) {
|
|
82734
|
-
caps.push({
|
|
83748
|
+
caps.push({
|
|
83749
|
+
action: "withdraw",
|
|
83750
|
+
requires: withdrawRequires(provider),
|
|
83751
|
+
// the unwrap rides the composer's 4626 withdraw — the same rows the
|
|
83752
|
+
// deposit zap serves; the single-token exits have no unwrap leg yet
|
|
83753
|
+
acceptsNative: acceptsVaultZap(row, provider) && nativeStandsIn(row)
|
|
83754
|
+
});
|
|
82735
83755
|
return caps;
|
|
82736
83756
|
}
|
|
82737
83757
|
if (mode === "fee-or-queued" && meta.instantRedeemEnabled !== false) {
|
|
82738
83758
|
caps.push({
|
|
82739
83759
|
action: "withdraw",
|
|
82740
83760
|
requires: withdrawRequires(provider),
|
|
82741
|
-
feeBps: num13(meta.withdrawFeeBps) ?? row.exit.feeBps
|
|
83761
|
+
feeBps: num13(meta.withdrawFeeBps) ?? row.exit.feeBps,
|
|
83762
|
+
// a fee-paying single-token exit: pays the vault's token only
|
|
83763
|
+
acceptsNative: false
|
|
82742
83764
|
});
|
|
82743
83765
|
}
|
|
82744
83766
|
caps.push({
|
|
@@ -83056,6 +84078,6 @@ function earnPositionTotals(items) {
|
|
|
83056
84078
|
};
|
|
83057
84079
|
}
|
|
83058
84080
|
|
|
83059
|
-
export { ApiBookSource, DEFAULT_MIDNIGHT_API, DEFAULT_OUTLIER_GUARD, DEFAULT_PROFILE_ID, DEFAULT_STALE_REJECT_SECONDS, DEFAULT_TERMMAX_API, DEFAULT_TERM_ORDER_STORE, DOLOMITE_ISO_ID_PREFIX, EARN_DESCRIPTIONS, EARN_LABELS, EARN_RATE_SOURCE_BY_PROVIDER, EMPTY_BALANCE, EXACTLY_LENDER_KEY, FLYING_TULIP_LENDER_KEY, FRACTION_RATE_PROVIDERS, 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, MULTICALL_FAILURE, MaxParamThresholds, PASSTHROUGH_RATE_EPSILON, PENDLE_ASSETS_URL, PENDLE_CHAIN_IDS, PENDLE_MARKETS_URL, PREFIX_LENDERS, SDK_FRACTION_RATE_PROVIDERS, SPECTRA_NETWORKS, SPECTRA_RATE_MAX_PERCENT, SPECTRA_RATE_MIN_PERCENT, STABLECOIN_SYMBOLS, STCELO_MANAGER_ADDRESS, TELLER_CALLS_PER_BID, DECIMAL_BASE as TERMMAX_DECIMAL_BASE, TERMMAX_LIQUIDATION_PENALTY, TERMMAX_LIQUIDATION_WINDOW_SECS, TERMMAX_LIQUIDATOR_BONUS, TERMMAX_MARKETS_PER_CALL, TERMMAX_PARTIAL_CLOSE_FACTOR, TERMMAX_PARTIAL_LIQUIDATION_THRESHOLD_USD, TERM_ADAPTERS, TERM_PROFILES, TERM_SHEET_SCHEMA_VERSION, TermMaxApiSource, TermSubgraphSource, UPSHIFT_CHAIN_IDS, UPSHIFT_VAULTS_URL, VAULT_PROVIDERS, VAULT_PROVIDER_PROFILE, VAULT_PROVIDER_TRAITS, VAULT_SHARE_PRICE_PROBE, VAULT_VENUE_PREFIX, VOLATILE_VAULT_OVERRIDES, YEARN_CHAIN_IDS, YEARN_YDAEMON_BASE, __resetResupplyUserCaches, accountDepositListKey, accountWithdrawalListKey, appendSnapshot, applyEarnSanity, applyPositionDelta, attachImplications, attachPricesToFlashLiquidity, blockNumberFromTag, borrowDescription, borrowFindings, borrowHeadline, buildExposures2 as buildExposures, buildFluidFTokensCall, buildLendingPositionUid, buildLiquityUserCall, buildLoopResult, buildMorphoTypeCall, buildMorphoTypeUserCallWithLens, buildPortfolioTotals, buildQueriesFromMeta, buildSumerAccumulators, buildSummaries, buildTellerUserCall, buildTermMaxUserCall, buildTermSheet, buildTermSheetsForGroup, buildVaultEarnUid, buildVaultLookup, buildVaultTermSheet, calculateLeverage, calculateNetApr, calculateOverallNetApr, calculateWeightedAverage, classifyFreshness, classifyReliability, classifyVault, clearPendleMarketsCache, clearSpectraMarketsCache, collateralSymbolsByVenue, collectFeedObservations, 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, consensusReference, convertCoolerMarketsToResponse, convertDssMarketsToResponse, convertExactlyMarketsToResponse, convertFlyingTulipMarketsToResponse, convertFrankencoinMarketsToResponse, convertFraxlendPairsToResponse, convertInverseMarketsToResponse, convertLenderUserDataResult, convertLiquityMarketsToResponse, convertLlamaLendMarketsToResponse, convertResupplyMarketsToResponse, convertRiverMarketsToResponse, convertTellerMarketsToResponse, convertTermMarketsToResponse, convertTermMaxMarketsToResponse, convertUsddMarketsToResponse, createMarketUid, createMidnightBookSource, createMulticallRpcCall, createRawRpcCalls, createTermBookSource, createTermMaxDataSource, decodeListaMarkets, decodeMarkets, decodePackedListaUserDataset, decodePackedMorphoUserDataset, deriveBorrowTags, deriveSupplyTags, detectInterfaceKinds, dexResolverFor, disambiguateEarnNames, dolomiteVaultAddress, dssIlkBytes32, dssKeyParts, dssLenderKey, duration, earnDescription, earnLabel, earnMarketFromPool, earnMarketFromVault, earnMarketLabel, earnPositionFromLenderEntry, earnPositionFromVaultBalance, earnPositionTotals, earnRateAtMaturity, earnRowSubtitle, earnUidFromMarketUid, earnVaultTerms, earnVenueKind, emitterCoverage, encodeBalanceFetcherCalldata, enrichTermSheet, enrichmentIndexFromRows, enumerateEmitters, exactlyPairLtv, exactlyPenaltyRateToAprPercent, exactlyWadRateToPercent, feePhrase, feedKeyOf, feedStatKey, fetchCoolerMarkets, fetchDolomiteAccountNumbers, fetchDolomiteSubAccounts, fetchDssMarkets, fetchEulerEarnVaults, fetchEulerEarnVaultsFromSubgraph, fetchEulerSubAccountIndexes, fetchExactlyMarkets, fetchFlashLiquidityForChain, fetchFluidDexState, fetchFluidFTokens, fetchFlyingTulipMarkets, fetchFrankencoinMarkets, fetchFraxlendPairs, fetchGeneralYields, fetchGeneralYieldsByMarketUid, fetchGmxExecutionFees, fetchGmxTickerPrices, fetchGmxVaults, fetchHypercoreVaults, fetchInverseMarkets, fetchLagoonApiVaults, fetchLagoonVaults, fetchLiquityMarkets, fetchListaVaultsFromChain, fetchLlamaLendMarkets, fetchMorphoUserBalances, fetchMorphoUserPositionMarkets, fetchMorphoVaults, fetchMorphoVaultsFromApi, fetchMorphoVaultsFromChain, fetchOraclePrices, fetchPendleApiAssets, fetchPendleApiMarkets, fetchPendlePrices, fetchPendlePtMarkets, fetchResupplyMarkets, fetchRiverMarkets, fetchSiloVaults, fetchSpectraApiMarkets, fetchSpectraPtMarkets, fetchTellerMarkets, fetchTermMarkets, fetchTermMaxMarkets, fetchTermStoreOrders, fetchTokenBalances, fetchTokenMetadata, fetchUpshiftApiVaults, fetchUpshiftVaults, fetchUsddMarkets, fetchYearnApiVaults, fetchYearnVaults, fillableRemaining, filterActiveLenders, filterLenderMeta, filterLendersByProtocol, finalizeInfo, findingsFor, formatRaw, frankencoinKeyParts, frankencoinLenderKey, fraxlendAssetPerCollateral, fraxlendKeyParts, fraxlendLenderKey, fuseLenderData, generateLendingPools, getAavesForChain, getAssetConfig, getBalanceForMarketUid, getBorrowCapacity, getCachedFluidDexState, getCachedLiquityTroves, getCachedTellerBids, getCachedTermMaxDiscovery, getCachedTermMaxMarket, getCachedTermMaxMarkets, getCoreValidators, getFluidFTokensConverter, getGmxApiHost, getGmxReadContracts, getGmxUserPositions, getHealthFactor, getHypercoreUserPositions, getHypercoreVaultRegistry, getLenderAssets, getLenderPublicData, getLenderPublicDataAll, getLenderPublicDataViaApi, getLenderUserDataMulti, getLenderUserDataResult, getLendersForChain, getLstDelegation, getLstValidators, getLstWithdrawalRegistry, getLstWithdrawalRequests, getMaxAmountClose, getMaxAmountCollateralSwap, getMaxAmountDebtSwap, getMaxAmountOpen, getMergedUserData, getMorphoTypeMarketConverter, getReadFailurePolicy, getResolvedDolomiteAccountNumbers, getResolvedDolomiteSubAccounts, getStCeloValidatorGroups, getSubAccountAddress, getSubAccountIndex, getTermProfile, getVaultPublicDataAll, getVaultWithdrawalRequests, hasCritical, hasEulerEarnVaultSubgraph, hasLagoonVaults, hasMorphoPositionIndex, hasMorphoUserApi, hasMorphoUserSubgraph, hasPendleMarkets, hasSpectraMarkets, hasUpshiftVaults, hasYearnVaults, ilkToKeySegment, implausibleRatePercent, injectLenderInfoIntoEntries, inverseKeyParts, inverseLenderKey, isBoundNeed, isFailedCall, isIlliquid, isLendingPosition, isLiveMarket as isLivePendleMarket, isLiveSpectraMarket, isMaturedTerm, isSecondaryMarketOnly, isStablecoinSymbol, isUnearnableEarnRate, isUnrealizableEarnRate, isVaultPosition, isVaultVenue, isYearnV3, keySegmentToIlk, keysFromMaps, lenderApiOnly, lenderFamily, liquityCandidateTroveIds, liquityKeyParts, liquityLenderKey, llamaLendKeyParts, llamaLendLenderKey, marketKeysOf, meetsLiquidityFloor, mergeDeep, multicall3Abi2 as multicall3Abi, nanTo, needsLenderApproval, needsTokenApproval, noOpResult, normalizeToBytes, organizeUserQueries, parseBalanceFetcherResult, parseDolomiteSubAccountId, parseEarnUid, parseLenderKey, parseMergedResult, parseMulticallRpcResponses, parseExpirySeconds as parsePendleExpirySeconds, parseRawRpcBatchResponses, parseRawRpcResponses, parseCurveFee as parseSpectraCurveFee, parsePtRate as parseSpectraPtRate, parseTermMaxLtv, parseTokenBalanceResult, pct, assetKey as pendleAssetKey, pickPool as pickSpectraPool, positivePart2 as positivePart, predictInverseEscrow, prepareLenderUserDataRpcCalls, prepareMergedMulticallParams, prepareMergedRpcCalls, prepareMulticallInputs, prepareTokenBalanceRpcCalls, priceGlvVaults, priceGmMarkets, probeAaveFeedTimestamps, pruneFeedStats, rankFindings, ratePercent, readUserPositions, readVaultSharePrices, rejectOutliers as rejectPriceOutliers, repairImpossibleTvl, resolveAdapter, resolveDerivation, resolveDolomiteRowIdentity, resolveEarnIdentity, resolveModeConfig, resolveStCeloDepositGroup, resolveVaultProfileId, resupplyKeyParts, resupplyLenderKey, resupplyMarketLabel, riverKeyParts, riverLenderKey, sanePercent as saneSpectraPercent, savingsAddresses, savingsBalanceKind, secondaryMarketVault, selectAssetGroupPrices, setMysticApiKey, shortDate, spectraAddress, spectraNetwork, spectraPoolsUrl, splitChainScopedAddress as splitPendleChainScopedAddress, stampCapabilities, stampEarnSubtitles, stampVaultClassification, stampVaultTermSheets, stripLeadingBrand, subAccountsOf, supplyDescription, supplyFindings, supplyHeadline, swapRoutedProvidersArePriceConsistent, tellerBpsToPercent, tellerImpliedLtv, tellerLenderKey, tellerPoolFromLenderKey, termApiBaseUrl, termLenderKey, termMaxApiBase, borrowNif as termMaxBorrowNif, curveApr as termMaxCurveApr, curveAprNumber as termMaxCurveAprNumber, daysToMaturity as termMaxDaysToMaturity, lendNif as termMaxLendNif, mintGtFeeRatio as termMaxMintGtFeeRatio, ratioToNumber as termMaxRatioToNumber, ratioToPercent as termMaxRatioToPercent, termOfferRateToAprPct, termOrderStoreBaseUrl, tickToAprNumber, tickToPrice, toDigest, toDolomiteSubAccountId, toTermFillNow, toTermSheetInput, toVaultTermInput, trancheFromCounterparty, tryParseEarnUid, unflattenLenderData, updateFeedStats, usdValue, usddIlkBytes32, usddKeyParts, usddLenderKey, validateTermSheet, validateTermSheets, validateUserData, vaultSharesToAssets, vaultTermInputFromEarnMarket, vaultTermInputFromSourceRow, vaultTraits, vaultVenue, venueBrand, venueBrandKey, withMaturityLabel, withTrancheLabel };
|
|
84081
|
+
export { ApiBookSource, DEFAULT_MIDNIGHT_API, DEFAULT_OUTLIER_GUARD, DEFAULT_PROFILE_ID, DEFAULT_STALE_REJECT_SECONDS, DEFAULT_TERMMAX_API, DEFAULT_TERM_ORDER_STORE, DOLOMITE_ISO_ID_PREFIX, EARN_DESCRIPTIONS, EARN_LABELS, EARN_RATE_SOURCE_BY_PROVIDER, EMPTY_BALANCE, EXACTLY_LENDER_KEY, FLYING_TULIP_LENDER_KEY, FRACTION_RATE_PROVIDERS, 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, MULTICALL_FAILURE, MaxParamThresholds, PASSTHROUGH_RATE_EPSILON, PENDLE_ASSETS_URL, PENDLE_CHAIN_IDS, PENDLE_MARKETS_URL, PREFIX_LENDERS, SDK_FRACTION_RATE_PROVIDERS, SPECTRA_NETWORKS, SPECTRA_RATE_MAX_PERCENT, SPECTRA_RATE_MIN_PERCENT, STABLECOIN_SYMBOLS, STCELO_MANAGER_ADDRESS, TELLER_CALLS_PER_BID, DECIMAL_BASE as TERMMAX_DECIMAL_BASE, TERMMAX_LIQUIDATION_PENALTY, TERMMAX_LIQUIDATION_WINDOW_SECS, TERMMAX_LIQUIDATOR_BONUS, TERMMAX_MARKETS_PER_CALL, TERMMAX_PARTIAL_CLOSE_FACTOR, TERMMAX_PARTIAL_LIQUIDATION_THRESHOLD_USD, TERM_ADAPTERS, TERM_PROFILES, TERM_SHEET_SCHEMA_VERSION, TermMaxApiSource, TermSubgraphSource, UPSHIFT_CHAIN_IDS, UPSHIFT_VAULTS_URL, VAULT_PROVIDERS, VAULT_PROVIDER_PROFILE, VAULT_PROVIDER_TRAITS, VAULT_SHARE_PRICE_PROBE, VAULT_VENUE_PREFIX, VOLATILE_VAULT_OVERRIDES, YEARN_CHAIN_IDS, YEARN_YDAEMON_BASE, __resetResupplyUserCaches, accountDepositListKey, accountWithdrawalListKey, appendSnapshot, applyEarnSanity, applyPositionDelta, attachImplications, attachPricesToFlashLiquidity, blockNumberFromTag, borrowDescription, borrowFindings, borrowHeadline, buildExposures2 as buildExposures, buildFluidFTokensCall, buildLendingPositionUid, buildLiquityUserCall, buildLoopResult, buildMorphoTypeCall, buildMorphoTypeUserCallWithLens, buildPortfolioTotals, buildQueriesFromMeta, buildSumerAccumulators, buildSummaries, buildTellerUserCall, buildTermMaxUserCall, buildTermSheet, buildTermSheetsForGroup, buildVaultEarnUid, buildVaultLookup, buildVaultTermSheet, calculateLeverage, calculateNetApr, calculateOverallNetApr, calculateWeightedAverage, classifyFreshness, classifyReliability, classifyVault, clearPendleMarketsCache, clearSpectraMarketsCache, collateralSymbolsByVenue, collectFeedObservations, 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, consensusReference, convertCoolerMarketsToResponse, convertDssMarketsToResponse, convertExactlyMarketsToResponse, convertFlyingTulipMarketsToResponse, convertFrankencoinMarketsToResponse, convertFraxlendPairsToResponse, convertInverseMarketsToResponse, convertLenderUserDataResult, convertLiquityMarketsToResponse, convertLlamaLendMarketsToResponse, convertResupplyMarketsToResponse, convertRiverMarketsToResponse, convertTellerMarketsToResponse, convertTermMarketsToResponse, convertTermMaxMarketsToResponse, convertUsddMarketsToResponse, createMarketUid, createMidnightBookSource, createMultiAccountTypeUserState, createMulticallRpcCall, createRawRpcCalls, createTermBookSource, createTermMaxDataSource, decodeListaMarkets, decodeMarkets, decodePackedListaUserDataset, decodePackedMorphoUserDataset, deriveBorrowTags, deriveSupplyTags, detectInterfaceKinds, dexResolverFor, disambiguateEarnNames, dolomiteVaultAddress, dssIlkBytes32, dssKeyParts, dssLenderKey, duration, earnDescription, earnLabel, earnMarketFromPool, earnMarketFromVault, earnMarketLabel, earnPositionFromLenderEntry, earnPositionFromVaultBalance, earnPositionTotals, earnRateAtMaturity, earnRowSubtitle, earnUidFromMarketUid, earnVaultTerms, earnVenueKind, emitterCoverage, encodeBalanceFetcherCalldata, enrichTermSheet, enrichmentIndexFromRows, enumerateEmitters, exactlyPairLtv, exactlyPenaltyRateToAprPercent, exactlyWadRateToPercent, feePhrase, feedKeyOf, feedStatKey, fetchCoolerMarkets, fetchDolomiteAccountNumbers, fetchDolomiteSubAccounts, fetchDssMarkets, fetchEulerEarnVaults, fetchEulerEarnVaultsFromSubgraph, fetchEulerSubAccountIndexes, fetchExactlyMarkets, fetchFlashLiquidityForChain, fetchFluidDexState, fetchFluidFTokens, fetchFlyingTulipMarkets, fetchFrankencoinMarkets, fetchFraxlendPairs, fetchGeneralYields, fetchGeneralYieldsByMarketUid, fetchGmxExecutionFees, fetchGmxTickerPrices, fetchGmxVaults, fetchHypercoreVaults, fetchInverseMarkets, fetchLagoonApiVaults, fetchLagoonVaults, fetchLiquityMarkets, fetchListaVaultsFromChain, fetchLlamaLendMarkets, fetchMorphoUserBalances, fetchMorphoUserPositionMarkets, fetchMorphoVaults, fetchMorphoVaultsFromApi, fetchMorphoVaultsFromChain, fetchOraclePrices, fetchPendleApiAssets, fetchPendleApiMarkets, fetchPendlePrices, fetchPendlePtMarkets, fetchResupplyMarkets, fetchRiverMarkets, fetchSiloVaults, fetchSpectraApiMarkets, fetchSpectraPtMarkets, fetchTellerMarkets, fetchTermMarkets, fetchTermMaxMarkets, fetchTermStoreOrders, fetchTokenBalances, fetchTokenMetadata, fetchUpshiftApiVaults, fetchUpshiftVaults, fetchUsddMarkets, fetchYearnApiVaults, fetchYearnVaults, fillableRemaining, filterActiveLenders, filterLenderMeta, filterLendersByProtocol, finalizeInfo, findingsFor, formatRaw, frankencoinKeyParts, frankencoinLenderKey, fraxlendAssetPerCollateral, fraxlendKeyParts, fraxlendLenderKey, fuseLenderData, generateLendingPools, getAavesForChain, getAssetConfig, getBalanceForMarketUid, getBorrowCapacity, getCachedFluidDexState, getCachedLiquityTroves, getCachedTellerBids, getCachedTermMaxDiscovery, getCachedTermMaxMarket, getCachedTermMaxMarkets, getCoreValidators, getFluidFTokensConverter, getGmxApiHost, getGmxReadContracts, getGmxUserPositions, getHealthFactor, getHypercoreUserPositions, getHypercoreVaultRegistry, getLenderAssets, getLenderPublicData, getLenderPublicDataAll, getLenderPublicDataViaApi, getLenderUserDataMulti, getLenderUserDataResult, getLendersForChain, getLstDelegation, getLstValidators, getLstWithdrawalRegistry, getLstWithdrawalRequests, getMaxAmountClose, getMaxAmountCollateralSwap, getMaxAmountDebtSwap, getMaxAmountOpen, getMergedUserData, getMorphoTypeMarketConverter, getReadFailurePolicy, getResolvedDolomiteAccountNumbers, getResolvedDolomiteSubAccounts, getStCeloValidatorGroups, getSubAccountAddress, getSubAccountIndex, getTermProfile, getVaultPublicDataAll, getVaultWithdrawalRequests, hasCritical, hasEulerEarnVaultSubgraph, hasLagoonVaults, hasMorphoPositionIndex, hasMorphoUserApi, hasMorphoUserSubgraph, hasPendleMarkets, hasSpectraMarkets, hasUpshiftVaults, hasYearnVaults, ilkToKeySegment, implausibleRatePercent, injectLenderInfoIntoEntries, inverseKeyParts, inverseLenderKey, isBoundNeed, isFailedCall, isIlliquid, isLendingPosition, isLiveMarket as isLivePendleMarket, isLiveSpectraMarket, isMaturedTerm, isSecondaryMarketOnly, isStablecoinSymbol, isUnearnableEarnRate, isUnrealizableEarnRate, isVaultPosition, isVaultVenue, isYearnV3, keySegmentToIlk, keysFromMaps, lenderApiOnly, lenderFamily, liquityCandidateTroveIds, liquityKeyParts, liquityLenderKey, llamaLendKeyParts, llamaLendLenderKey, marketKeysOf, meetsLiquidityFloor, mergeDeep, multicall3Abi2 as multicall3Abi, nanTo, needsLenderApproval, needsTokenApproval, noOpResult, normalizeToBytes, organizeUserQueries, parseBalanceFetcherResult, parseDolomiteSubAccountId, parseEarnUid, parseLenderKey, parseMergedResult, parseMulticallRpcResponses, parseExpirySeconds as parsePendleExpirySeconds, parseRawRpcBatchResponses, parseRawRpcResponses, parseCurveFee as parseSpectraCurveFee, parsePtRate as parseSpectraPtRate, parseTermMaxLtv, parseTokenBalanceResult, pct, assetKey as pendleAssetKey, pickPool as pickSpectraPool, positivePart2 as positivePart, predictInverseEscrow, prepareLenderUserDataRpcCalls, prepareMergedMulticallParams, prepareMergedRpcCalls, prepareMulticallInputs, prepareTokenBalanceRpcCalls, priceGlvVaults, priceGmMarkets, probeAaveFeedTimestamps, pruneFeedStats, rankFindings, ratePercent, readUserPositions, readVaultSharePrices, rejectOutliers as rejectPriceOutliers, repairImpossibleTvl, resolveAdapter, resolveDerivation, resolveDolomiteRowIdentity, resolveEarnIdentity, resolveModeConfig, resolveStCeloDepositGroup, resolveVaultProfileId, resupplyKeyParts, resupplyLenderKey, resupplyMarketLabel, riverKeyParts, riverLenderKey, sanePercent as saneSpectraPercent, savingsAddresses, savingsBalanceKind, secondaryMarketVault, selectAssetGroupPrices, setMysticApiKey, shortDate, spectraAddress, spectraNetwork, spectraPoolsUrl, splitChainScopedAddress as splitPendleChainScopedAddress, stampCapabilities, stampEarnSubtitles, stampVaultClassification, stampVaultTermSheets, stripLeadingBrand, subAccountsOf, supplyDescription, supplyFindings, supplyHeadline, swapRoutedProvidersArePriceConsistent, tellerBpsToPercent, tellerImpliedLtv, tellerLenderKey, tellerPoolFromLenderKey, termApiBaseUrl, termLenderKey, termMaxApiBase, borrowNif as termMaxBorrowNif, curveApr as termMaxCurveApr, curveAprNumber as termMaxCurveAprNumber, daysToMaturity as termMaxDaysToMaturity, lendNif as termMaxLendNif, mintGtFeeRatio as termMaxMintGtFeeRatio, ratioToNumber as termMaxRatioToNumber, ratioToPercent as termMaxRatioToPercent, termOfferRateToAprPct, termOrderStoreBaseUrl, tickToAprNumber, tickToPrice, toDigest, toDolomiteSubAccountId, toTermFillNow, toTermSheetInput, toVaultTermInput, trancheFromCounterparty, tryParseEarnUid, unflattenLenderData, updateFeedStats, usdValue, usddIlkBytes32, usddKeyParts, usddLenderKey, validateTermSheet, validateTermSheets, validateUserData, vaultSharesToAssets, vaultTermInputFromEarnMarket, vaultTermInputFromSourceRow, vaultTraits, vaultVenue, venueBrand, venueBrandKey, withMaturityLabel, withTrancheLabel };
|
|
83060
84082
|
//# sourceMappingURL=index.js.map
|
|
83061
84083
|
//# sourceMappingURL=index.js.map
|