@1delta/margin-fetcher 0.0.410 → 0.0.412
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 +593 -37
- package/dist/index.js +2371 -377
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { parseAbi, keccak256, encodeAbiParameters, formatEther, BaseError,
|
|
1
|
+
import { parseAbi, keccak256, encodeAbiParameters, formatEther, BaseError, erc20Abi, stringToHex, pad, encodeFunctionData, formatUnits, isAddress, getAddress, decodeFunctionResult, decodeAbiParameters, concat, AbiEncodingLengthMismatchError, concatHex, toBytes, slice, hexToString, InvalidAddressError, boolToHex, integerRegex, numberToHex, bytesRegex, BytesSizeMismatchError, arrayRegex, UnsupportedPackedAbiType } from './chunk-YILYOOYB.js';
|
|
2
2
|
import './chunk-BYTNVMX7.js';
|
|
3
3
|
import './chunk-PR4QN5HX.js';
|
|
4
|
-
import { Lender, LIQUITY_FAMILY_LENDERS, isAaveType, isCompoundV3, isMultiMarket, isSiloV2Type, isSiloV3Type, isDolomite, isMidnight, isTerm, isExactly, isLiquityFamily, isRiver, isTeller, isInverse, isTermMax, isUsdd, isEulerType, isAaveV4Type, isInit, isMorphoType, isCompoundV2Type, isVenusType, isSumerType, AAVE_V3_LENDERS, AAVE_V2_LENDERS, isAaveV2Type, isAaveV32Type, isAaveV3Type, isFluid, isGearboxV3, isYLDR, isCompoundV3Type, isLista, isTectonicType, isKineticType, isBenqiType } from '@1delta/lender-registry';
|
|
4
|
+
import { Lender, LIQUITY_FAMILY_LENDERS, isAaveType, isCompoundV3, isMultiMarket, isSiloV2Type, isSiloV3Type, isDolomite, isMidnight, isTerm, isExactly, isLiquityFamily, isRiver, isTeller, isInverse, isTermMax, isResupply, isUsdd, isFrankencoin, isLlamaLend, isEulerType, isAaveV4Type, isInit, isMorphoType, isCompoundV2Type, isVenusType, isSumerType, AAVE_V3_LENDERS, AAVE_V2_LENDERS, isAaveV2Type, isAaveV32Type, isAaveV3Type, isFluid, isGearboxV3, isYLDR, isCompoundV3Type, isLista, isTectonicType, isKineticType, isBenqiType } from '@1delta/lender-registry';
|
|
5
5
|
export { isAaveType, isAaveV2Type, isAaveV32Type, isAaveV3Type, isCompoundV3, isCompoundV3Type, isInit, isMorphoType, isMultiMarket, isYLDR } from '@1delta/lender-registry';
|
|
6
|
-
import { fetchTokenLists, fetchTokenList, aavePools, compoundV3Pools, initConfig, morphoPools, compoundV2Pools, eulerVaults, siloMarkets, siloV2LenderKey, siloMarketsV3, siloV3LenderKey, aaveV4Spokes, aaveV4SpokeLenderKey, fluidResolvers, gearboxResolvers, dolomiteConfigs, midnightConfig, termConfig, termMarketsByChain, exactlyConfig, liquityLendersByChain, riverLendersByChain, inverseLendersByChain, usddLendersByChain, tellerConfigByChain, tellerPoolsByChain, termMaxConfigByChain, aaveReserves, compoundV3Reserves, liquityConfigFor, liquityBranchesByChain, riverConfigFor, riverChainData, termMaxApiBaseUrl, termMaxLenderKey, inverseConfigFor, inverseChainData, usddConfigFor, usddChainData, aaveOracles, morphoTypeMarkets, resolveMidnightApiBase, resolveTermApiBase, getSiloV2MarketEntry, getSiloV3MarketEntry, dolomiteEmode, aaveTokens, morphoTypeVaults, eulerConfigs, gearboxMarketCompressor, gearboxMarketConfigurators, gearboxV3LenderKey, midnightMarketsByChain, parseAaveV4SpokeLenderKey, gearboxAccountCompressor, compoundV2Tokens, exactlyMarketsByChain, aaveOraclesConfig, compoundV2Oracles, compoundV2TokenArray, compoundV2OraclesConfig, compoundV3OraclesData, compoundV3BaseData, compoundV2Reserves, aaveV4Oracles } from '@1delta/data-sdk';
|
|
6
|
+
import { fetchTokenLists, fetchTokenList, aavePools, compoundV3Pools, initConfig, morphoPools, compoundV2Pools, eulerVaults, siloMarkets, siloV2LenderKey, siloMarketsV3, siloV3LenderKey, aaveV4Spokes, aaveV4SpokeLenderKey, fluidResolvers, gearboxResolvers, dolomiteConfigs, midnightConfig, termConfig, termMarketsByChain, exactlyConfig, liquityLendersByChain, riverLendersByChain, inverseLendersByChain, llamaLendLendersByChain, usddLendersByChain, frankencoinLendersByChain, resupplyLendersByChain, tellerConfigByChain, tellerPoolsByChain, termMaxConfigByChain, aaveReserves, compoundV3Reserves, liquityConfigFor, liquityBranchesByChain, riverConfigFor, riverChainData, termMaxApiBaseUrl, termMaxLenderKey, inverseConfigFor, inverseChainData, llamaLendConfigFor, llamaLendChainData, llamaLendApiBaseUrl, resupplyConfigFor, usddConfigFor, usddChainData, frankencoinConfigFor, frankencoinChainData, aaveOracles, morphoTypeMarkets, resolveMidnightApiBase, resolveTermApiBase, llamaLendMarketByVault, getSiloV2MarketEntry, getSiloV3MarketEntry, dolomiteEmode, aaveTokens, morphoTypeVaults, eulerConfigs, gearboxMarketCompressor, gearboxMarketConfigurators, gearboxV3LenderKey, midnightMarketsByChain, parseAaveV4SpokeLenderKey, gearboxAccountCompressor, compoundV2Tokens, exactlyMarketsByChain, aaveOraclesConfig, compoundV2Oracles, compoundV2TokenArray, compoundV2OraclesConfig, compoundV3OraclesData, compoundV3BaseData, compoundV2Reserves, aaveV4Oracles } from '@1delta/data-sdk';
|
|
7
7
|
import lodash from 'lodash';
|
|
8
8
|
import { multicallRetryUniversal, getEvmClient, getEvmChain, getEvmClientUniversal } from '@1delta/providers';
|
|
9
|
-
import { LiquityTroveManagerAbi, LiquityActivePoolAbi, LiquityStabilityPoolAbi, LiquityPriceFeedAbi, LiquitySortedTrovesAbi, RiverTroveManagerAbi, RiverStabilityPoolAbi, TellerMarketRegistryAbi, TellerV2Abi, InverseMarketAbi, InverseOracleAbi, InverseDbrAbi, Erc20Abi, MetaMorphoAbi, ExactlyPreviewerAbi, ExactlyAuditorAbi, LenderCommitmentGroupAbi, UsddVatAbi, UsddJugAbi, UsddSpotAbi, FluidLendingResolverAbi, FluidVaultResolverAbi, FluidLiquidityResolverAbi, MoolahVaultAbi, MorphoLensAbi, AaveV4SpokeAbi, AaveV4OracleAbi, AaveV4HubAbi, DolomiteMarginAbi, GearboxMarketCompressorV310Abi, MorphoBlueAbi, MidnightAbi, TermRepoTokenAbi, TermRepoServicerAbi, TermRepoCollateralManagerAbi, LiquityTroveNFTAbi, LiquityCollSurplusPoolAbi, TellerCollateralManagerAbi, InverseEscrowAbi, GearboxCreditAccountCompressorV310Abi, UsddCdpManagerAbi, UsddProxyRegistryAbi, TermPriceConsumerAbi, TermMaxOracleAggregatorV2Abi } from '@1delta/abis';
|
|
9
|
+
import { LiquityTroveManagerAbi, LiquityActivePoolAbi, LiquityStabilityPoolAbi, LiquityPriceFeedAbi, LiquitySortedTrovesAbi, RiverTroveManagerAbi, RiverStabilityPoolAbi, TellerMarketRegistryAbi, TellerV2Abi, InverseMarketAbi, InverseOracleAbi, InverseDbrAbi, Erc20Abi, LlamaLendControllerAbi, LlamaLendControllerV1Abi, LlamaLendControllerV2Abi, LlamaLendVaultAbi, LlamaLendAmmAbi, MetaMorphoAbi, ExactlyPreviewerAbi, ExactlyAuditorAbi, LenderCommitmentGroupAbi, ResupplyRegistryAbi, ResupplyPairAbi, UsddVatAbi, UsddJugAbi, UsddSpotAbi, FrankencoinPositionAbi, FluidLendingResolverAbi, FluidVaultResolverAbi, FluidLiquidityResolverAbi, MoolahVaultAbi, ResupplyUtilitiesAbi, MorphoLensAbi, AaveV4SpokeAbi, AaveV4OracleAbi, AaveV4HubAbi, DolomiteMarginAbi, GearboxMarketCompressorV310Abi, MorphoBlueAbi, MidnightAbi, TermRepoTokenAbi, TermRepoServicerAbi, TermRepoCollateralManagerAbi, LiquityTroveNFTAbi, LiquityCollSurplusPoolAbi, TellerCollateralManagerAbi, TermMaxViewerAbi, InverseEscrowAbi, GearboxCreditAccountCompressorV310Abi, UsddCdpManagerAbi, UsddProxyRegistryAbi, TermPriceConsumerAbi, TermMaxOracleAggregatorV2Abi } from '@1delta/abis';
|
|
10
10
|
export { MorphoLensAbi } from '@1delta/abis';
|
|
11
11
|
import { prepareDebitDataMulticall, prepareLenderDebitMulticall, parseDebitDataResult, parseLenderDebitResult, getPermit2ContractAddress, getCompoundV3CometAddress as getCompoundV3CometAddress$1, getMorphoAddress, getAaveCollateralTokenAddress, getSiloHalfForUnderlying, InitMarginAddresses, getLstAcceptedInputs } from '@1delta/calldata-sdk';
|
|
12
12
|
import { proxyNativeFetch } from '@1delta/proxy-fetch';
|
|
@@ -7519,9 +7519,18 @@ var getLendersForChain = (c) => {
|
|
|
7519
7519
|
for (const l of inverseLendersByChain(c)) {
|
|
7520
7520
|
lenders.push(l);
|
|
7521
7521
|
}
|
|
7522
|
+
for (const l of llamaLendLendersByChain(c)) {
|
|
7523
|
+
lenders.push(l);
|
|
7524
|
+
}
|
|
7522
7525
|
for (const l of usddLendersByChain(c)) {
|
|
7523
7526
|
lenders.push(l);
|
|
7524
7527
|
}
|
|
7528
|
+
for (const l of frankencoinLendersByChain(c)) {
|
|
7529
|
+
lenders.push(l);
|
|
7530
|
+
}
|
|
7531
|
+
for (const l of resupplyLendersByChain(c)) {
|
|
7532
|
+
lenders.push(l);
|
|
7533
|
+
}
|
|
7525
7534
|
if (tellerConfigByChain(c)?.tellerV2 && tellerPoolsByChain(c).length > 0) {
|
|
7526
7535
|
lenders.push(Lender.TELLER);
|
|
7527
7536
|
}
|
|
@@ -7543,7 +7552,7 @@ var filterLendersByProtocol = (allLenders, protocolList) => {
|
|
|
7543
7552
|
(b) => protocolList.includes(b)
|
|
7544
7553
|
);
|
|
7545
7554
|
return allLenders.filter(
|
|
7546
|
-
(lender) => protocolList.includes(lender) || hasMorpho && lender?.startsWith("MORPHO_BLUE") || hasMoolah && lender?.startsWith("LISTA_DAO") || hasFluid && lender?.startsWith("FLUID") || hasGearboxV3 && lender?.startsWith("GEARBOX_V3") || hasDolomite && lender?.startsWith("DOLOMITE") || liquityBases.some((b) => lender?.startsWith(b)) || protocolList.includes(Lender.RIVER) && lender?.startsWith("RIVER") || protocolList.includes(Lender.TELLER) && lender?.startsWith("TELLER") || protocolList.includes(Lender.USDD) && lender?.startsWith("USDD")
|
|
7555
|
+
(lender) => protocolList.includes(lender) || hasMorpho && lender?.startsWith("MORPHO_BLUE") || hasMoolah && lender?.startsWith("LISTA_DAO") || hasFluid && lender?.startsWith("FLUID") || hasGearboxV3 && lender?.startsWith("GEARBOX_V3") || hasDolomite && lender?.startsWith("DOLOMITE") || liquityBases.some((b) => lender?.startsWith(b)) || protocolList.includes(Lender.RIVER) && lender?.startsWith("RIVER") || protocolList.includes(Lender.TELLER) && lender?.startsWith("TELLER") || protocolList.includes(Lender.USDD) && lender?.startsWith("USDD") || protocolList.includes(Lender.FRANKENCOIN) && lender?.startsWith("FRANKENCOIN")
|
|
7547
7556
|
);
|
|
7548
7557
|
};
|
|
7549
7558
|
var getAavesForChain = () => {
|
|
@@ -11208,8 +11217,8 @@ async function fetchListaBrokerUserData(chainId, account, marketKeys, nowSecs =
|
|
|
11208
11217
|
const brokers = await resolveListaBrokers(chainId, marketKeys, getClient);
|
|
11209
11218
|
const ids = Object.keys(brokers);
|
|
11210
11219
|
const out = {};
|
|
11211
|
-
const
|
|
11212
|
-
BROKER_USER_CACHE[
|
|
11220
|
+
const cacheKey7 = `${chainId}:${account.toLowerCase()}`;
|
|
11221
|
+
BROKER_USER_CACHE[cacheKey7] = out;
|
|
11213
11222
|
if (ids.length === 0) return out;
|
|
11214
11223
|
try {
|
|
11215
11224
|
const client = getClient(chainId);
|
|
@@ -22127,15 +22136,7 @@ function exactlyPairLtv(collateralAdjustFactor, borrowAdjustFactor) {
|
|
|
22127
22136
|
|
|
22128
22137
|
// src/lending/public-data/exactly/convertPublic.ts
|
|
22129
22138
|
var nowSec3 = () => Math.floor(Date.now() / 1e3);
|
|
22130
|
-
|
|
22131
|
-
const body = market.startsWith("0x") ? market.slice(2) : market;
|
|
22132
|
-
return "EXACTLY_" + body.toUpperCase();
|
|
22133
|
-
}
|
|
22134
|
-
function exactlyMarketFromLenderKey(lender) {
|
|
22135
|
-
if (!lender.startsWith("EXACTLY_")) return void 0;
|
|
22136
|
-
const body = lender.slice("EXACTLY_".length);
|
|
22137
|
-
return body.length === 40 ? "0x" + body.toLowerCase() : void 0;
|
|
22138
|
-
}
|
|
22139
|
+
var EXACTLY_LENDER_KEY = "EXACTLY";
|
|
22139
22140
|
function toHuman(raw, decimals) {
|
|
22140
22141
|
return Number(raw) / 10 ** decimals;
|
|
22141
22142
|
}
|
|
@@ -22151,9 +22152,12 @@ function convertExactlyMarketsToResponse(raw, chainId, prices = {}, _additionalY
|
|
|
22151
22152
|
const out = {};
|
|
22152
22153
|
const now = nowSec3();
|
|
22153
22154
|
const markets = raw?.markets ?? [];
|
|
22155
|
+
if (markets.length === 0) return out;
|
|
22154
22156
|
const liqBonus = raw?.liquidationIncentive ? Number(raw.liquidationIncentive.liquidator) / 1e18 : 0;
|
|
22157
|
+
const lenderKey = EXACTLY_LENDER_KEY;
|
|
22158
|
+
const entry = { data: {} };
|
|
22159
|
+
const penaltyAprs = [];
|
|
22155
22160
|
for (const m of markets) {
|
|
22156
|
-
const lenderKey = exactlyLenderKey(m.market);
|
|
22157
22161
|
const assetAddr = m.asset.toLowerCase();
|
|
22158
22162
|
const decimals = m.decimals;
|
|
22159
22163
|
const asset = tokens[assetAddr];
|
|
@@ -22185,9 +22189,10 @@ function convertExactlyMarketsToResponse(raw, chainId, prices = {}, _additionalY
|
|
|
22185
22189
|
const totalDebt = toHuman(m.totalFloatingBorrowAssets, decimals) + fixedBorrowed;
|
|
22186
22190
|
const borrowLiquidity = toHuman(m.floatingAvailableAssets, decimals);
|
|
22187
22191
|
const utilization = totalDeposits > 0 ? totalDebt / totalDeposits : 0;
|
|
22188
|
-
const
|
|
22192
|
+
const adjustFactor = Number(m.adjustFactor) / 1e18;
|
|
22193
|
+
const borrowFactor = adjustFactor > 0 ? 1 / adjustFactor : 1;
|
|
22189
22194
|
const penaltyApr = exactlyPenaltyRateToAprPercent(m.penaltyRate);
|
|
22190
|
-
|
|
22195
|
+
penaltyAprs.push(penaltyApr);
|
|
22191
22196
|
const loanUid = createMarketUid(chainId, lenderKey, assetAddr);
|
|
22192
22197
|
entry.data[loanUid] = {
|
|
22193
22198
|
marketUid: loanUid,
|
|
@@ -22215,17 +22220,28 @@ function convertExactlyMarketsToResponse(raw, chainId, prices = {}, _additionalY
|
|
|
22215
22220
|
variableBorrowRate: exactlyWadRateToPercent(m.floatingBorrowRate),
|
|
22216
22221
|
rateModel: "fixedTerm",
|
|
22217
22222
|
// Fixed-rate lender convention (Term/Lista): best fixed borrow APR on the
|
|
22218
|
-
// stable slot; the full per-maturity menu is
|
|
22223
|
+
// stable slot; the full per-maturity menu is this entry's `terms`.
|
|
22219
22224
|
stableBorrowRate: bestFixedBorrowApr,
|
|
22225
|
+
// PER-ASSET fixed-term menu + descriptor. Cross-margin means one lender
|
|
22226
|
+
// key spans every asset, and each asset has its OWN fixed pools — so
|
|
22227
|
+
// these cannot live on `params.market` (which assumes one borrowable
|
|
22228
|
+
// asset per key, true for every isolated fixed-term lender but not here).
|
|
22229
|
+
terms: terms.length > 0 ? terms : void 0,
|
|
22230
|
+
fixedTerm: {
|
|
22231
|
+
model: "exactly",
|
|
22232
|
+
fees: { latePenaltyApr: penaltyApr },
|
|
22233
|
+
earlyRepay: { kind: "discount" },
|
|
22234
|
+
provider: { kind: "pool", address: m.market.toLowerCase() }
|
|
22235
|
+
},
|
|
22220
22236
|
intrinsicYield: 0,
|
|
22221
22237
|
rewards: void 0,
|
|
22222
22238
|
decimals,
|
|
22223
22239
|
config: {
|
|
22224
22240
|
0: {
|
|
22225
22241
|
category: 0,
|
|
22226
|
-
borrowCollateralFactor:
|
|
22227
|
-
collateralFactor:
|
|
22228
|
-
borrowFactor
|
|
22242
|
+
borrowCollateralFactor: adjustFactor,
|
|
22243
|
+
collateralFactor: adjustFactor,
|
|
22244
|
+
borrowFactor,
|
|
22229
22245
|
liquidationPenalty: liqBonus,
|
|
22230
22246
|
closeFactor: 1,
|
|
22231
22247
|
collateralDisabled: false,
|
|
@@ -22240,93 +22256,50 @@ function convertExactlyMarketsToResponse(raw, chainId, prices = {}, _additionalY
|
|
|
22240
22256
|
// Exactly DOES have a variable (floating) borrow side.
|
|
22241
22257
|
variableBorrowDisabled: false,
|
|
22242
22258
|
isActive: true,
|
|
22243
|
-
isFrozen: false
|
|
22244
|
-
|
|
22245
|
-
|
|
22246
|
-
|
|
22247
|
-
|
|
22248
|
-
|
|
22249
|
-
const collUid = createMarketUid(chainId, lenderKey, collAddr);
|
|
22250
|
-
entry.data[collUid] = {
|
|
22251
|
-
marketUid: collUid,
|
|
22252
|
-
name: "Collateral " + c.assetSymbol,
|
|
22253
|
-
poolId: c.market.toLowerCase(),
|
|
22254
|
-
underlying: collAddr,
|
|
22255
|
-
asset: currencyFor3(collAddr, c.decimals, c.assetSymbol, tokens),
|
|
22256
|
-
totalDeposits: 0,
|
|
22257
|
-
totalDebtStable: 0,
|
|
22258
|
-
totalDebt: 0,
|
|
22259
|
-
totalLiquidity: 0,
|
|
22260
|
-
borrowLiquidity: 0,
|
|
22261
|
-
totalLiquidityUSD: 0,
|
|
22262
|
-
borrowLiquidityUSD: 0,
|
|
22263
|
-
totalDepositsUSD: 0,
|
|
22264
|
-
totalDebtStableUSD: 0,
|
|
22265
|
-
totalDebtUSD: 0,
|
|
22266
|
-
utilization: 0,
|
|
22267
|
-
depositRate: 0,
|
|
22268
|
-
variableBorrowRate: 0,
|
|
22269
|
-
stableBorrowRate: 0,
|
|
22270
|
-
intrinsicYield: 0,
|
|
22271
|
-
rewards: void 0,
|
|
22272
|
-
decimals: c.decimals,
|
|
22273
|
-
config: {
|
|
22274
|
-
0: {
|
|
22275
|
-
category: 0,
|
|
22276
|
-
borrowCollateralFactor: ltv,
|
|
22277
|
-
collateralFactor: ltv,
|
|
22278
|
-
borrowFactor: 1,
|
|
22279
|
-
liquidationPenalty: liqBonus,
|
|
22280
|
-
closeFactor: 1,
|
|
22281
|
-
collateralDisabled: false,
|
|
22282
|
-
debtDisabled: true
|
|
22283
|
-
}
|
|
22284
|
-
},
|
|
22285
|
-
closeFactor: 1,
|
|
22286
|
-
collateralActive: true,
|
|
22287
|
-
borrowingEnabled: false,
|
|
22288
|
-
depositsEnabled: true,
|
|
22289
|
-
hasStable: false,
|
|
22290
|
-
isActive: true,
|
|
22291
|
-
isFrozen: false
|
|
22292
|
-
};
|
|
22293
|
-
}
|
|
22294
|
-
entry.params = {
|
|
22295
|
-
market: {
|
|
22296
|
-
lender: lenderKey,
|
|
22297
|
-
name: "Exactly " + m.assetSymbol,
|
|
22298
|
-
loanDecimals: decimals,
|
|
22299
|
-
collateralDecimals: decimals,
|
|
22300
|
-
// Market address doubles as the market id (it IS the lender-key body).
|
|
22301
|
-
id: m.market.toLowerCase(),
|
|
22302
|
-
// Self-pair adjust factor (WAD string); pairwise LTVs live on the
|
|
22303
|
-
// per-collateral entries above.
|
|
22304
|
-
lltv: m.adjustFactor.toString(),
|
|
22305
|
-
oracle: zeroAddress,
|
|
22306
|
-
irm: zeroAddress,
|
|
22307
|
-
collateralAddress: assetAddr,
|
|
22308
|
-
loanAddress: assetAddr,
|
|
22309
|
-
terms: terms.length > 0 ? terms : void 0,
|
|
22310
|
-
// Canonical cross-protocol fixed-term descriptor. Exactly: MENU of
|
|
22311
|
-
// calendar maturities (terms[], termId = maturity), pool-fronted
|
|
22312
|
-
// utilization-curve rates, early repay = DISCOUNT (unassigned-earnings
|
|
22313
|
-
// rebate via previewRepayAtMaturity), late repay = per-second penalty.
|
|
22314
|
-
fixedTerm: {
|
|
22315
|
-
model: "exactly",
|
|
22316
|
-
fees: { latePenaltyApr: penaltyApr },
|
|
22317
|
-
earlyRepay: { kind: "discount" },
|
|
22318
|
-
provider: { kind: "pool", address: m.market.toLowerCase() }
|
|
22319
|
-
},
|
|
22320
|
-
// Exactly-specific extras (consumed by calldata / worker-api resolvers)
|
|
22259
|
+
isFrozen: false,
|
|
22260
|
+
// Per-asset Exactly extras. `poolId` above already carries the Market
|
|
22261
|
+
// address (the write target — resolve it from the ASSET now, via
|
|
22262
|
+
// `exactlyMarketByAsset`, never from the lender key).
|
|
22263
|
+
exactly: {
|
|
22264
|
+
market: m.market.toLowerCase(),
|
|
22321
22265
|
penaltyRate: m.penaltyRate.toString(),
|
|
22322
22266
|
adjustFactor: m.adjustFactor.toString(),
|
|
22323
22267
|
maxFuturePools: m.maxFuturePools,
|
|
22324
22268
|
usdPrice: m.usdPrice.toString()
|
|
22325
22269
|
}
|
|
22326
22270
|
};
|
|
22327
|
-
entry.chainId = chainId;
|
|
22328
|
-
out[lenderKey] = entry;
|
|
22329
22271
|
}
|
|
22272
|
+
const uniformPenaltyApr = penaltyAprs.length > 0 && penaltyAprs.every((p) => p === penaltyAprs[0]) ? penaltyAprs[0] : void 0;
|
|
22273
|
+
entry.params = {
|
|
22274
|
+
market: {
|
|
22275
|
+
lender: lenderKey,
|
|
22276
|
+
name: "Exactly",
|
|
22277
|
+
// The per-chain Auditor — the shared cross-margin risk module every
|
|
22278
|
+
// Market reports to (Compound V2's Comptroller seam).
|
|
22279
|
+
id: (exactlyConfig()?.[chainId]?.auditor ?? zeroAddress).toLowerCase(),
|
|
22280
|
+
// No market-level LLTV: risk is per-asset (collateralFactor/borrowFactor
|
|
22281
|
+
// on each entry) and effective pair LTV is their product.
|
|
22282
|
+
lltv: "0",
|
|
22283
|
+
oracle: zeroAddress,
|
|
22284
|
+
irm: zeroAddress,
|
|
22285
|
+
collateralAddress: zeroAddress,
|
|
22286
|
+
loanAddress: zeroAddress,
|
|
22287
|
+
// `terms` is deliberately ABSENT at market level — each asset has its own
|
|
22288
|
+
// fixed pools, so the menu is on `data[*].terms`. A market-level
|
|
22289
|
+
// descriptor is still emitted so consumers that only probe
|
|
22290
|
+
// `params.market.fixedTerm` still recognise Exactly as fixed-term; its
|
|
22291
|
+
// `provider.address` is omitted (no single Market) and the late-penalty
|
|
22292
|
+
// rate is carried only when every asset agrees (it does today).
|
|
22293
|
+
fixedTerm: {
|
|
22294
|
+
model: "exactly",
|
|
22295
|
+
fees: uniformPenaltyApr !== void 0 ? { latePenaltyApr: uniformPenaltyApr } : {},
|
|
22296
|
+
earlyRepay: { kind: "discount" },
|
|
22297
|
+
provider: { kind: "pool" }
|
|
22298
|
+
}
|
|
22299
|
+
}
|
|
22300
|
+
};
|
|
22301
|
+
entry.chainId = chainId;
|
|
22302
|
+
out[lenderKey] = entry;
|
|
22330
22303
|
return out;
|
|
22331
22304
|
}
|
|
22332
22305
|
var READS_PER_BRANCH = 8;
|
|
@@ -22918,7 +22891,7 @@ async function fetchTellerMarkets(chainId) {
|
|
|
22918
22891
|
} catch {
|
|
22919
22892
|
return { chainId, pools: [] };
|
|
22920
22893
|
}
|
|
22921
|
-
const
|
|
22894
|
+
const big13 = (i) => {
|
|
22922
22895
|
const r = results[i];
|
|
22923
22896
|
if (typeof r === "bigint") return r;
|
|
22924
22897
|
if (typeof r === "number") return BigInt(r);
|
|
@@ -22931,21 +22904,21 @@ async function fetchTellerMarkets(chainId) {
|
|
|
22931
22904
|
}
|
|
22932
22905
|
return null;
|
|
22933
22906
|
};
|
|
22934
|
-
const
|
|
22935
|
-
const b =
|
|
22907
|
+
const num10 = (i) => {
|
|
22908
|
+
const b = big13(i);
|
|
22936
22909
|
return b === null ? null : Number(b);
|
|
22937
22910
|
};
|
|
22938
22911
|
const pool0 = pools.map((config, i) => {
|
|
22939
22912
|
const base = i * READS_PER_POOL;
|
|
22940
22913
|
return {
|
|
22941
22914
|
config,
|
|
22942
|
-
available:
|
|
22943
|
-
committed:
|
|
22944
|
-
minRateBps:
|
|
22945
|
-
collateralPerPrincipal:
|
|
22946
|
-
maxLoanDuration:
|
|
22947
|
-
marketId:
|
|
22948
|
-
totalAssets:
|
|
22915
|
+
available: big13(base),
|
|
22916
|
+
committed: big13(base + 1),
|
|
22917
|
+
minRateBps: num10(base + 2),
|
|
22918
|
+
collateralPerPrincipal: big13(base + 3),
|
|
22919
|
+
maxLoanDuration: num10(base + 4),
|
|
22920
|
+
marketId: big13(base + 5),
|
|
22921
|
+
totalAssets: big13(base + 6)
|
|
22949
22922
|
};
|
|
22950
22923
|
});
|
|
22951
22924
|
const attByMarket = /* @__PURE__ */ new Map();
|
|
@@ -23863,7 +23836,7 @@ var INVERSE_PUBLIC_READ_ABI = [
|
|
|
23863
23836
|
...InverseDbrAbi,
|
|
23864
23837
|
...Erc20Abi
|
|
23865
23838
|
];
|
|
23866
|
-
var READS_PER_MARKET2 =
|
|
23839
|
+
var READS_PER_MARKET2 = 5;
|
|
23867
23840
|
var fetchJson = async (url, timeoutMs = 6e3) => {
|
|
23868
23841
|
const res = await fetch(url, {
|
|
23869
23842
|
headers: { accept: "application/json" },
|
|
@@ -23906,15 +23879,24 @@ async function fetchInverseMarkets(lender, chainId) {
|
|
|
23906
23879
|
if (Object.keys(byAddr).length > 0) {
|
|
23907
23880
|
const rows = markets.map((market) => {
|
|
23908
23881
|
const m = byAddr[market.address.toLowerCase()];
|
|
23909
|
-
const
|
|
23882
|
+
const num10 = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
23910
23883
|
return {
|
|
23911
23884
|
market,
|
|
23912
|
-
totalDebt:
|
|
23913
|
-
dolaLiquidity:
|
|
23914
|
-
leftToBorrow:
|
|
23915
|
-
price:
|
|
23885
|
+
totalDebt: num10(m?.totalDebt),
|
|
23886
|
+
dolaLiquidity: num10(m?.dolaLiquidity),
|
|
23887
|
+
leftToBorrow: num10(m?.leftToBorrow),
|
|
23888
|
+
price: num10(m?.price),
|
|
23916
23889
|
borrowPaused: typeof m?.borrowPaused === "boolean" ? m.borrowPaused : null,
|
|
23917
|
-
dailyBorrows:
|
|
23890
|
+
dailyBorrows: num10(m?.dailyBorrows),
|
|
23891
|
+
// The API serves it as a DECIMAL (`replenishmentIncentive: 0.1`),
|
|
23892
|
+
// unlike the on-chain bps — normalize here, and fall back to the
|
|
23893
|
+
// curated metadata value when the field is missing.
|
|
23894
|
+
replenishmentIncentiveBps: (() => {
|
|
23895
|
+
const dec = num10(m?.replenishmentIncentive);
|
|
23896
|
+
if (dec !== null) return Math.round(dec * 1e4);
|
|
23897
|
+
const meta = Number(market.replenishmentIncentiveBps);
|
|
23898
|
+
return Number.isFinite(meta) ? meta : null;
|
|
23899
|
+
})()
|
|
23918
23900
|
};
|
|
23919
23901
|
});
|
|
23920
23902
|
return {
|
|
@@ -23939,7 +23921,8 @@ async function fetchInverseMarkets(lender, chainId) {
|
|
|
23939
23921
|
address: config.oracle,
|
|
23940
23922
|
name: "viewPrice",
|
|
23941
23923
|
params: [m.collToken, BigInt(m.collateralFactorBps)]
|
|
23942
|
-
}
|
|
23924
|
+
},
|
|
23925
|
+
{ address: m.address, name: "replenishmentIncentiveBps", params: [] }
|
|
23943
23926
|
])
|
|
23944
23927
|
];
|
|
23945
23928
|
try {
|
|
@@ -23962,6 +23945,7 @@ async function fetchInverseMarkets(lender, chainId) {
|
|
|
23962
23945
|
const paused = results[base + 1];
|
|
23963
23946
|
const liq = bigAt(base + 2);
|
|
23964
23947
|
const price2 = bigAt(base + 3);
|
|
23948
|
+
const replenishIncentive = bigAt(base + 4);
|
|
23965
23949
|
return {
|
|
23966
23950
|
market,
|
|
23967
23951
|
totalDebt: totalDebt !== null ? Number(totalDebt) / 10 ** debtDecimals : null,
|
|
@@ -23973,7 +23957,11 @@ async function fetchInverseMarkets(lender, chainId) {
|
|
|
23973
23957
|
// 10^(36 − collDecimals) per unit — normalize to USD per token.
|
|
23974
23958
|
price: price2 !== null ? Number(price2) / 10 ** (36 - market.collDecimals) : null,
|
|
23975
23959
|
borrowPaused: typeof paused === "boolean" ? paused : null,
|
|
23976
|
-
dailyBorrows: null
|
|
23960
|
+
dailyBorrows: null,
|
|
23961
|
+
replenishmentIncentiveBps: replenishIncentive !== null ? Number(replenishIncentive) : (() => {
|
|
23962
|
+
const meta = Number(market.replenishmentIncentiveBps);
|
|
23963
|
+
return Number.isFinite(meta) ? meta : null;
|
|
23964
|
+
})()
|
|
23977
23965
|
};
|
|
23978
23966
|
});
|
|
23979
23967
|
return {
|
|
@@ -23993,6 +23981,454 @@ function num(api, key) {
|
|
|
23993
23981
|
const v = api?.[key];
|
|
23994
23982
|
return typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
23995
23983
|
}
|
|
23984
|
+
var BANDS_ENDPOINTS = [4, 10, 20, 50];
|
|
23985
|
+
var DEFAULT_BANDS = 10;
|
|
23986
|
+
var LLAMALEND_READ_ABI = [
|
|
23987
|
+
...LlamaLendControllerAbi,
|
|
23988
|
+
...LlamaLendControllerV1Abi,
|
|
23989
|
+
...LlamaLendControllerV2Abi,
|
|
23990
|
+
...LlamaLendVaultAbi,
|
|
23991
|
+
...LlamaLendAmmAbi,
|
|
23992
|
+
...Erc20Abi
|
|
23993
|
+
];
|
|
23994
|
+
var ZERO = "0x0000000000000000000000000000000000000000";
|
|
23995
|
+
var fetchJson2 = async (url, timeoutMs = 8e3) => {
|
|
23996
|
+
const res = await fetch(url, {
|
|
23997
|
+
headers: { accept: "application/json" },
|
|
23998
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
23999
|
+
});
|
|
24000
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
24001
|
+
return res.json();
|
|
24002
|
+
};
|
|
24003
|
+
var num2 = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
24004
|
+
var toBig5 = (v) => {
|
|
24005
|
+
if (typeof v === "bigint") return v;
|
|
24006
|
+
if (typeof v === "number" && Number.isFinite(v)) return BigInt(Math.trunc(v));
|
|
24007
|
+
return null;
|
|
24008
|
+
};
|
|
24009
|
+
var human = (v, decimals) => v === null ? null : Number(v) / 10 ** decimals;
|
|
24010
|
+
var bandsFor = (m) => m.defaultBands && m.defaultBands >= 4 && m.defaultBands <= 50 ? m.defaultBands : DEFAULT_BANDS;
|
|
24011
|
+
var bandGrid = (m) => {
|
|
24012
|
+
const set = /* @__PURE__ */ new Set([...BANDS_ENDPOINTS, bandsFor(m)]);
|
|
24013
|
+
return [...set].sort((a, b) => a - b);
|
|
24014
|
+
};
|
|
24015
|
+
var maxBorrowableCall = (m, oneUnit, n) => m.version === 1 ? {
|
|
24016
|
+
address: m.controller,
|
|
24017
|
+
name: "max_borrowable",
|
|
24018
|
+
params: [oneUnit, BigInt(n), 0n, ZERO]
|
|
24019
|
+
} : {
|
|
24020
|
+
address: m.controller,
|
|
24021
|
+
name: "max_borrowable",
|
|
24022
|
+
params: [oneUnit, BigInt(n), ZERO]
|
|
24023
|
+
};
|
|
24024
|
+
var buildBandLtv = (perBand, borrowedDecimals, collateralPrice) => {
|
|
24025
|
+
if (!collateralPrice || collateralPrice <= 0) return null;
|
|
24026
|
+
const out = {};
|
|
24027
|
+
for (const { n, maxBorrowable } of perBand) {
|
|
24028
|
+
const borrowable = human(maxBorrowable, borrowedDecimals);
|
|
24029
|
+
if (borrowable === null || borrowable <= 0) continue;
|
|
24030
|
+
const ltv = borrowable / collateralPrice;
|
|
24031
|
+
if (ltv > 0 && ltv <= 1) out[String(n)] = ltv;
|
|
24032
|
+
}
|
|
24033
|
+
return Object.keys(out).length > 0 ? out : null;
|
|
24034
|
+
};
|
|
24035
|
+
async function fetchChainExtras(chainId, markets) {
|
|
24036
|
+
const perMarketCalls = markets.map((m) => {
|
|
24037
|
+
const grid = bandGrid(m);
|
|
24038
|
+
const oneUnit = 10n ** BigInt(m.collateralDecimals);
|
|
24039
|
+
const calls = [
|
|
24040
|
+
{ address: m.amm, name: "price_oracle", params: [] },
|
|
24041
|
+
{ address: m.amm, name: "active_band", params: [] },
|
|
24042
|
+
{ address: m.controller, name: "n_loans", params: [] },
|
|
24043
|
+
{ address: m.vault, name: "maxDeposit", params: [ZERO] },
|
|
24044
|
+
// v1 controllers have no `borrow_cap`; allowFailure turns that into a
|
|
24045
|
+
// null rather than sinking the whole batch.
|
|
24046
|
+
{ address: m.controller, name: "borrow_cap", params: [] },
|
|
24047
|
+
...grid.map((n) => maxBorrowableCall(m, oneUnit, n))
|
|
24048
|
+
];
|
|
24049
|
+
return { market: m, grid, calls };
|
|
24050
|
+
});
|
|
24051
|
+
const flat = perMarketCalls.flatMap((x) => x.calls);
|
|
24052
|
+
if (flat.length === 0) return {};
|
|
24053
|
+
let results;
|
|
24054
|
+
try {
|
|
24055
|
+
results = await multicallRetryUniversal({
|
|
24056
|
+
chain: chainId,
|
|
24057
|
+
calls: flat,
|
|
24058
|
+
abi: LLAMALEND_READ_ABI,
|
|
24059
|
+
allowFailure: true
|
|
24060
|
+
});
|
|
24061
|
+
} catch {
|
|
24062
|
+
return {};
|
|
24063
|
+
}
|
|
24064
|
+
const out = {};
|
|
24065
|
+
let cursor = 0;
|
|
24066
|
+
for (const { market, grid } of perMarketCalls) {
|
|
24067
|
+
const priceRaw = toBig5(results[cursor]);
|
|
24068
|
+
const activeBandRaw = toBig5(results[cursor + 1]);
|
|
24069
|
+
const nLoansRaw = toBig5(results[cursor + 2]);
|
|
24070
|
+
const maxDepositRaw = toBig5(results[cursor + 3]);
|
|
24071
|
+
const borrowCapRaw = toBig5(results[cursor + 4]);
|
|
24072
|
+
const perBand = grid.map((n, i) => ({
|
|
24073
|
+
n,
|
|
24074
|
+
maxBorrowable: toBig5(results[cursor + 5 + i])
|
|
24075
|
+
}));
|
|
24076
|
+
cursor += 5 + grid.length;
|
|
24077
|
+
const collateralPrice = priceRaw === null ? null : Number(priceRaw) / 1e18;
|
|
24078
|
+
const bandLtv = buildBandLtv(
|
|
24079
|
+
perBand,
|
|
24080
|
+
market.borrowedDecimals,
|
|
24081
|
+
collateralPrice
|
|
24082
|
+
);
|
|
24083
|
+
const defaultN = String(bandsFor(market));
|
|
24084
|
+
out[market.controller.toLowerCase()] = {
|
|
24085
|
+
collateralPrice,
|
|
24086
|
+
bandLtv,
|
|
24087
|
+
collateralFactor: bandLtv?.[defaultN] ?? null,
|
|
24088
|
+
borrowCap: human(borrowCapRaw, market.borrowedDecimals),
|
|
24089
|
+
maxDeposit: human(maxDepositRaw, market.borrowedDecimals),
|
|
24090
|
+
nLoans: nLoansRaw === null ? null : Number(nLoansRaw),
|
|
24091
|
+
activeBand: activeBandRaw === null ? null : Number(activeBandRaw)
|
|
24092
|
+
};
|
|
24093
|
+
}
|
|
24094
|
+
return out;
|
|
24095
|
+
}
|
|
24096
|
+
var isBorrowingEnabled = (version, availableToBorrow, borrowCap, totalDebt) => {
|
|
24097
|
+
const liquid = (availableToBorrow ?? 0) > 0;
|
|
24098
|
+
if (version === 1) return liquid;
|
|
24099
|
+
if (borrowCap === null) return liquid;
|
|
24100
|
+
if (borrowCap <= 0) return false;
|
|
24101
|
+
return liquid && (totalDebt ?? 0) < borrowCap;
|
|
24102
|
+
};
|
|
24103
|
+
async function fetchLlamaLendMarkets(lender, chainId) {
|
|
24104
|
+
const config = llamaLendConfigFor(lender, chainId);
|
|
24105
|
+
const chainData = llamaLendChainData(lender, chainId);
|
|
24106
|
+
const markets = chainData?.markets ?? [];
|
|
24107
|
+
const empty = {
|
|
24108
|
+
lender,
|
|
24109
|
+
config,
|
|
24110
|
+
chainData,
|
|
24111
|
+
markets: [],
|
|
24112
|
+
source: "none"
|
|
24113
|
+
};
|
|
24114
|
+
if (!config || markets.length === 0) return empty;
|
|
24115
|
+
const extrasPromise = fetchChainExtras(chainId, markets);
|
|
24116
|
+
try {
|
|
24117
|
+
const base = llamaLendApiBaseUrl(lender, chainId);
|
|
24118
|
+
const api = await fetchJson2(`${base}/v1/getLendingVaults/all`);
|
|
24119
|
+
const byController = {};
|
|
24120
|
+
for (const row of api?.data?.lendingVaultData ?? []) {
|
|
24121
|
+
const c = row?.controllerAddress;
|
|
24122
|
+
if (c) byController[String(c).toLowerCase()] = row;
|
|
24123
|
+
}
|
|
24124
|
+
if (Object.keys(byController).length > 0) {
|
|
24125
|
+
const extras = await extrasPromise;
|
|
24126
|
+
const rows = markets.map((market) => {
|
|
24127
|
+
const r = byController[market.controller.toLowerCase()];
|
|
24128
|
+
const ex = extras[market.controller.toLowerCase()];
|
|
24129
|
+
const totalDebt = num2(r?.borrowed?.total);
|
|
24130
|
+
const availableToBorrow = num2(r?.availableToBorrow?.total);
|
|
24131
|
+
return {
|
|
24132
|
+
market,
|
|
24133
|
+
totalDebt,
|
|
24134
|
+
totalSupplied: num2(r?.totalSupplied?.total),
|
|
24135
|
+
availableToBorrow,
|
|
24136
|
+
// `borrowApr`/`lendApr` are the NOMINAL rates and match
|
|
24137
|
+
// `Vault.borrow_apr()`/`lend_apr()`. The sibling `borrowApy` /
|
|
24138
|
+
// `lendApy` fields are compounded — mixing them in would make this
|
|
24139
|
+
// lender look systematically more expensive than its peers.
|
|
24140
|
+
borrowApr: num2(r?.rates?.borrowApr),
|
|
24141
|
+
lendApr: num2(r?.rates?.lendApr),
|
|
24142
|
+
collateralPrice: ex?.collateralPrice ?? null,
|
|
24143
|
+
collateralPriceUsd: num2(r?.assets?.collateral?.usdPrice),
|
|
24144
|
+
borrowedPriceUsd: num2(r?.assets?.borrowed?.usdPrice),
|
|
24145
|
+
collateralFactor: ex?.collateralFactor ?? null,
|
|
24146
|
+
bandLtv: ex?.bandLtv ?? null,
|
|
24147
|
+
borrowCap: ex?.borrowCap ?? null,
|
|
24148
|
+
borrowingEnabled: isBorrowingEnabled(
|
|
24149
|
+
market.version,
|
|
24150
|
+
availableToBorrow,
|
|
24151
|
+
ex?.borrowCap ?? null,
|
|
24152
|
+
totalDebt
|
|
24153
|
+
),
|
|
24154
|
+
maxDeposit: ex?.maxDeposit ?? null,
|
|
24155
|
+
nLoans: ex?.nLoans ?? null,
|
|
24156
|
+
activeBand: ex?.activeBand ?? null
|
|
24157
|
+
};
|
|
24158
|
+
});
|
|
24159
|
+
return { lender, config, chainData, markets: rows, source: "api" };
|
|
24160
|
+
}
|
|
24161
|
+
} catch {
|
|
24162
|
+
}
|
|
24163
|
+
const READS_PER_MARKET4 = 5;
|
|
24164
|
+
const calls = markets.flatMap((m) => [
|
|
24165
|
+
{ address: m.controller, name: "total_debt", params: [] },
|
|
24166
|
+
{ address: m.vault, name: "totalAssets", params: [] },
|
|
24167
|
+
{ address: m.vault, name: "borrow_apr", params: [] },
|
|
24168
|
+
{ address: m.vault, name: "lend_apr", params: [] },
|
|
24169
|
+
// v2 tracks its own lent-out accounting; v1 has no such getter, so the
|
|
24170
|
+
// controller's token balance IS the borrowable liquidity there.
|
|
24171
|
+
m.version === 2 ? { address: m.controller, name: "available_balance", params: [] } : { address: m.borrowedToken, name: "balanceOf", params: [m.controller] }
|
|
24172
|
+
]);
|
|
24173
|
+
try {
|
|
24174
|
+
const results = await multicallRetryUniversal({
|
|
24175
|
+
chain: chainId,
|
|
24176
|
+
calls,
|
|
24177
|
+
abi: LLAMALEND_READ_ABI,
|
|
24178
|
+
allowFailure: true
|
|
24179
|
+
});
|
|
24180
|
+
const extras = await extrasPromise;
|
|
24181
|
+
const rows = markets.map((market, i) => {
|
|
24182
|
+
const b = i * READS_PER_MARKET4;
|
|
24183
|
+
const ex = extras[market.controller.toLowerCase()];
|
|
24184
|
+
const totalDebt = human(toBig5(results[b]), market.borrowedDecimals);
|
|
24185
|
+
const availableToBorrow = human(
|
|
24186
|
+
toBig5(results[b + 4]),
|
|
24187
|
+
market.borrowedDecimals
|
|
24188
|
+
);
|
|
24189
|
+
const borrowAprRaw = toBig5(results[b + 2]);
|
|
24190
|
+
const lendAprRaw = toBig5(results[b + 3]);
|
|
24191
|
+
const collateralPrice = ex?.collateralPrice ?? null;
|
|
24192
|
+
return {
|
|
24193
|
+
market,
|
|
24194
|
+
totalDebt,
|
|
24195
|
+
totalSupplied: human(toBig5(results[b + 1]), market.borrowedDecimals),
|
|
24196
|
+
availableToBorrow,
|
|
24197
|
+
// Both getters are already annualised nominal rates, WAD-scaled.
|
|
24198
|
+
borrowApr: borrowAprRaw === null ? null : Number(borrowAprRaw) / 1e18,
|
|
24199
|
+
lendApr: lendAprRaw === null ? null : Number(lendAprRaw) / 1e18,
|
|
24200
|
+
collateralPrice,
|
|
24201
|
+
// No USD leg on-chain — the oracle prices collateral in the borrowed
|
|
24202
|
+
// token only. The converter falls back to the global price oracle.
|
|
24203
|
+
collateralPriceUsd: null,
|
|
24204
|
+
borrowedPriceUsd: null,
|
|
24205
|
+
collateralFactor: ex?.collateralFactor ?? null,
|
|
24206
|
+
bandLtv: ex?.bandLtv ?? null,
|
|
24207
|
+
borrowCap: ex?.borrowCap ?? null,
|
|
24208
|
+
borrowingEnabled: isBorrowingEnabled(
|
|
24209
|
+
market.version,
|
|
24210
|
+
availableToBorrow,
|
|
24211
|
+
ex?.borrowCap ?? null,
|
|
24212
|
+
totalDebt
|
|
24213
|
+
),
|
|
24214
|
+
maxDeposit: ex?.maxDeposit ?? null,
|
|
24215
|
+
nLoans: ex?.nLoans ?? null,
|
|
24216
|
+
activeBand: ex?.activeBand ?? null
|
|
24217
|
+
};
|
|
24218
|
+
});
|
|
24219
|
+
return { lender, config, chainData, markets: rows, source: "chain" };
|
|
24220
|
+
} catch {
|
|
24221
|
+
return empty;
|
|
24222
|
+
}
|
|
24223
|
+
}
|
|
24224
|
+
var VAULT_PRICE_ABI = [
|
|
24225
|
+
{
|
|
24226
|
+
name: "convertToAssets",
|
|
24227
|
+
type: "function",
|
|
24228
|
+
stateMutability: "view",
|
|
24229
|
+
inputs: [{ name: "shares", type: "uint256" }],
|
|
24230
|
+
outputs: [{ type: "uint256" }]
|
|
24231
|
+
}
|
|
24232
|
+
];
|
|
24233
|
+
var IDENTITY_READS = 3;
|
|
24234
|
+
var STATE_READS = 12;
|
|
24235
|
+
var ONE = 10n ** 18n;
|
|
24236
|
+
var identityCache = /* @__PURE__ */ new Map();
|
|
24237
|
+
var identityKey = (chainId, pair) => `${chainId}:${pair.toLowerCase()}`;
|
|
24238
|
+
var big = (v) => {
|
|
24239
|
+
if (typeof v === "bigint") return v;
|
|
24240
|
+
if (typeof v === "number") return BigInt(v);
|
|
24241
|
+
return null;
|
|
24242
|
+
};
|
|
24243
|
+
async function fetchResupplyMarkets(lender, chainId) {
|
|
24244
|
+
const config = resupplyConfigFor(lender, chainId);
|
|
24245
|
+
if (!config?.registry) return { lender, config, pairs: [] };
|
|
24246
|
+
let discovered = [];
|
|
24247
|
+
try {
|
|
24248
|
+
const [addresses] = await multicallRetryUniversal({
|
|
24249
|
+
chain: chainId,
|
|
24250
|
+
calls: [
|
|
24251
|
+
{ address: config.registry, name: "getAllPairAddresses", params: [] }
|
|
24252
|
+
],
|
|
24253
|
+
abi: ResupplyRegistryAbi,
|
|
24254
|
+
allowFailure: true
|
|
24255
|
+
});
|
|
24256
|
+
if (Array.isArray(addresses)) {
|
|
24257
|
+
discovered = addresses.filter(
|
|
24258
|
+
(a) => typeof a === "string" && a.startsWith("0x")
|
|
24259
|
+
);
|
|
24260
|
+
}
|
|
24261
|
+
} catch {
|
|
24262
|
+
return { lender, config, pairs: [] };
|
|
24263
|
+
}
|
|
24264
|
+
if (discovered.length === 0) return { lender, config, pairs: [] };
|
|
24265
|
+
if (config.pairAllowlist && config.pairAllowlist.length > 0) {
|
|
24266
|
+
const allow = new Set(config.pairAllowlist.map((p) => p.toLowerCase()));
|
|
24267
|
+
discovered = discovered.filter((p) => allow.has(p.toLowerCase()));
|
|
24268
|
+
if (discovered.length === 0) return { lender, config, pairs: [] };
|
|
24269
|
+
}
|
|
24270
|
+
const unknown = discovered.filter(
|
|
24271
|
+
(p) => !identityCache.has(identityKey(chainId, p))
|
|
24272
|
+
);
|
|
24273
|
+
if (unknown.length > 0) {
|
|
24274
|
+
const calls2 = unknown.flatMap((pair) => [
|
|
24275
|
+
{ address: pair, name: "name", params: [] },
|
|
24276
|
+
{ address: pair, name: "collateral", params: [] },
|
|
24277
|
+
{ address: pair, name: "underlying", params: [] }
|
|
24278
|
+
]);
|
|
24279
|
+
let res = [];
|
|
24280
|
+
try {
|
|
24281
|
+
res = await multicallRetryUniversal({
|
|
24282
|
+
chain: chainId,
|
|
24283
|
+
calls: calls2,
|
|
24284
|
+
abi: unknown.flatMap(() => [
|
|
24285
|
+
ResupplyPairAbi,
|
|
24286
|
+
ResupplyPairAbi,
|
|
24287
|
+
ResupplyPairAbi
|
|
24288
|
+
]),
|
|
24289
|
+
allowFailure: true
|
|
24290
|
+
});
|
|
24291
|
+
} catch {
|
|
24292
|
+
return { lender, config, pairs: [] };
|
|
24293
|
+
}
|
|
24294
|
+
const pending = [];
|
|
24295
|
+
unknown.forEach((pair, i) => {
|
|
24296
|
+
const base = i * IDENTITY_READS;
|
|
24297
|
+
const name = res[base];
|
|
24298
|
+
const collateral = res[base + 1];
|
|
24299
|
+
const underlying = res[base + 2];
|
|
24300
|
+
if (typeof collateral !== "string" || !collateral.startsWith("0x") || typeof underlying !== "string" || !underlying.startsWith("0x")) {
|
|
24301
|
+
return;
|
|
24302
|
+
}
|
|
24303
|
+
pending.push({
|
|
24304
|
+
pair,
|
|
24305
|
+
name: typeof name === "string" ? name : pair,
|
|
24306
|
+
collateral,
|
|
24307
|
+
underlying
|
|
24308
|
+
});
|
|
24309
|
+
});
|
|
24310
|
+
if (pending.length > 0) {
|
|
24311
|
+
let dec = [];
|
|
24312
|
+
try {
|
|
24313
|
+
dec = await multicallRetryUniversal({
|
|
24314
|
+
chain: chainId,
|
|
24315
|
+
calls: pending.flatMap((p) => [
|
|
24316
|
+
{ address: p.collateral, name: "decimals", params: [] },
|
|
24317
|
+
{ address: p.underlying, name: "decimals", params: [] }
|
|
24318
|
+
]),
|
|
24319
|
+
abi: pending.flatMap(() => [erc20Abi, erc20Abi]),
|
|
24320
|
+
allowFailure: true
|
|
24321
|
+
});
|
|
24322
|
+
} catch {
|
|
24323
|
+
dec = [];
|
|
24324
|
+
}
|
|
24325
|
+
pending.forEach((p, i) => {
|
|
24326
|
+
const cd = Number(dec[i * 2]);
|
|
24327
|
+
const ud = Number(dec[i * 2 + 1]);
|
|
24328
|
+
identityCache.set(identityKey(chainId, p.pair), {
|
|
24329
|
+
pair: p.pair,
|
|
24330
|
+
name: p.name,
|
|
24331
|
+
collateral: p.collateral,
|
|
24332
|
+
underlying: p.underlying,
|
|
24333
|
+
collateralDecimals: Number.isFinite(cd) && cd > 0 ? cd : 18,
|
|
24334
|
+
underlyingDecimals: Number.isFinite(ud) && ud > 0 ? ud : 18
|
|
24335
|
+
});
|
|
24336
|
+
});
|
|
24337
|
+
}
|
|
24338
|
+
}
|
|
24339
|
+
const identities = discovered.map((p) => identityCache.get(identityKey(chainId, p))).filter((x) => !!x);
|
|
24340
|
+
if (identities.length === 0) return { lender, config, pairs: [] };
|
|
24341
|
+
const utilities = config.utilities;
|
|
24342
|
+
const calls = [];
|
|
24343
|
+
const abis = [];
|
|
24344
|
+
for (const id of identities) {
|
|
24345
|
+
calls.push(
|
|
24346
|
+
{ address: id.pair, name: "maxLTV", params: [] },
|
|
24347
|
+
{ address: id.pair, name: "borrowLimit", params: [] },
|
|
24348
|
+
{ address: id.pair, name: "liquidationFee", params: [] },
|
|
24349
|
+
{ address: id.pair, name: "mintFee", params: [] },
|
|
24350
|
+
{ address: id.pair, name: "minimumBorrowAmount", params: [] },
|
|
24351
|
+
{ address: id.pair, name: "getPairAccounting", params: [] },
|
|
24352
|
+
{ address: id.pair, name: "currentRateInfo", params: [] },
|
|
24353
|
+
{ address: id.pair, name: "exchangeRateInfo", params: [] },
|
|
24354
|
+
// The collateral vault's own share price — the exact input Resupply's
|
|
24355
|
+
// `BasicVaultOracle` uses. Read LIVE rather than inverting the pair's
|
|
24356
|
+
// cached `exchangeRate`, which only moves when someone writes.
|
|
24357
|
+
{ address: id.collateral, name: "convertToAssets", params: [ONE] }
|
|
24358
|
+
);
|
|
24359
|
+
abis.push(
|
|
24360
|
+
ResupplyPairAbi,
|
|
24361
|
+
ResupplyPairAbi,
|
|
24362
|
+
ResupplyPairAbi,
|
|
24363
|
+
ResupplyPairAbi,
|
|
24364
|
+
ResupplyPairAbi,
|
|
24365
|
+
ResupplyPairAbi,
|
|
24366
|
+
ResupplyPairAbi,
|
|
24367
|
+
ResupplyPairAbi,
|
|
24368
|
+
VAULT_PRICE_ABI
|
|
24369
|
+
);
|
|
24370
|
+
if (utilities) {
|
|
24371
|
+
calls.push(
|
|
24372
|
+
{ address: utilities, name: "getPairInterestRate", params: [id.pair] },
|
|
24373
|
+
{
|
|
24374
|
+
address: utilities,
|
|
24375
|
+
name: "getUnderlyingSupplyRate",
|
|
24376
|
+
params: [id.pair]
|
|
24377
|
+
},
|
|
24378
|
+
{ address: id.pair, name: "totalDebtAvailable", params: [] }
|
|
24379
|
+
);
|
|
24380
|
+
abis.push(ResupplyUtilitiesAbi, ResupplyUtilitiesAbi, ResupplyPairAbi);
|
|
24381
|
+
} else {
|
|
24382
|
+
calls.push(
|
|
24383
|
+
{ address: id.pair, name: "totalDebtAvailable", params: [] },
|
|
24384
|
+
{ address: id.pair, name: "totalDebtAvailable", params: [] },
|
|
24385
|
+
{ address: id.pair, name: "totalDebtAvailable", params: [] }
|
|
24386
|
+
);
|
|
24387
|
+
abis.push(ResupplyPairAbi, ResupplyPairAbi, ResupplyPairAbi);
|
|
24388
|
+
}
|
|
24389
|
+
}
|
|
24390
|
+
const PAIRS_PER_BATCH = 6;
|
|
24391
|
+
const results = [];
|
|
24392
|
+
for (let i = 0; i < identities.length; i += PAIRS_PER_BATCH) {
|
|
24393
|
+
const from = i * STATE_READS;
|
|
24394
|
+
const to = Math.min(i + PAIRS_PER_BATCH, identities.length) * STATE_READS;
|
|
24395
|
+
try {
|
|
24396
|
+
const chunk7 = await multicallRetryUniversal({
|
|
24397
|
+
chain: chainId,
|
|
24398
|
+
calls: calls.slice(from, to),
|
|
24399
|
+
abi: abis.slice(from, to),
|
|
24400
|
+
allowFailure: true
|
|
24401
|
+
});
|
|
24402
|
+
results.push(...chunk7);
|
|
24403
|
+
} catch {
|
|
24404
|
+
results.push(...new Array(to - from).fill("0x"));
|
|
24405
|
+
}
|
|
24406
|
+
}
|
|
24407
|
+
const pairs = identities.map((identity, i) => {
|
|
24408
|
+
const base = i * STATE_READS;
|
|
24409
|
+
const accounting = results[base + 5];
|
|
24410
|
+
const rateInfo = results[base + 6];
|
|
24411
|
+
const exchangeInfo = results[base + 7];
|
|
24412
|
+
const tuple = (v, idx) => Array.isArray(v) ? big(v[idx]) : null;
|
|
24413
|
+
return {
|
|
24414
|
+
identity,
|
|
24415
|
+
maxLTV: big(results[base]),
|
|
24416
|
+
borrowLimit: big(results[base + 1]),
|
|
24417
|
+
liquidationFee: big(results[base + 2]),
|
|
24418
|
+
mintFee: big(results[base + 3]),
|
|
24419
|
+
minimumBorrowAmount: big(results[base + 4]),
|
|
24420
|
+
totalBorrowAmount: tuple(accounting, 1),
|
|
24421
|
+
totalBorrowShares: tuple(accounting, 2),
|
|
24422
|
+
totalCollateral: tuple(accounting, 3),
|
|
24423
|
+
ratePerSec: tuple(rateInfo, 1),
|
|
24424
|
+
exchangeRate: tuple(exchangeInfo, 2),
|
|
24425
|
+
collateralPrice: big(results[base + 8]),
|
|
24426
|
+
liveRatePerSec: utilities ? big(results[base + 9]) : null,
|
|
24427
|
+
underlyingSupplyRatePerSec: utilities ? big(results[base + 10]) : null
|
|
24428
|
+
};
|
|
24429
|
+
});
|
|
24430
|
+
return { lender, config, pairs };
|
|
24431
|
+
}
|
|
23996
24432
|
|
|
23997
24433
|
// src/lending/public-data/inverse/convertPublic.ts
|
|
23998
24434
|
function inverseLenderKey(lender, market) {
|
|
@@ -24160,8 +24596,13 @@ function convertInverseMarketsToResponse(raw, chainId, prices = {}, _additionalY
|
|
|
24160
24596
|
liquidationFactorBps: market.liquidationFactorBps,
|
|
24161
24597
|
/** Fixed borrow APR as a DECIMAL (DBR price in DOLA). */
|
|
24162
24598
|
dbrPriceDola: raw.dbrPriceDola !== null ? String(raw.dbrPriceDola) : void 0,
|
|
24163
|
-
/** Force-replenish penalty (5475 = 54.75% APR on missed DBR)
|
|
24599
|
+
/** Force-replenish penalty (5475 = 54.75% APR on missed DBR):
|
|
24600
|
+
* the DOLA debt added per 1 DBR minted back to the borrower. */
|
|
24164
24601
|
replenishmentPriceBps: raw.replenishmentPriceBps !== null ? String(raw.replenishmentPriceBps) : void 0,
|
|
24602
|
+
/** Replenisher bot's cut (1000 = 10%) — carved OUT of the cost
|
|
24603
|
+
* above and paid from market liquidity, NOT charged on top of
|
|
24604
|
+
* the borrower's debt. Bot-side economics (liquidation dashboard). */
|
|
24605
|
+
replenishmentIncentiveBps: m.replenishmentIncentiveBps !== null ? String(m.replenishmentIncentiveBps) : void 0,
|
|
24165
24606
|
borrowPaused: paused,
|
|
24166
24607
|
addresses: {
|
|
24167
24608
|
market: market.address,
|
|
@@ -24178,6 +24619,500 @@ function convertInverseMarketsToResponse(raw, chainId, prices = {}, _additionalY
|
|
|
24178
24619
|
}
|
|
24179
24620
|
return out;
|
|
24180
24621
|
}
|
|
24622
|
+
|
|
24623
|
+
// src/lending/public-data/llamalend/convertPublic.ts
|
|
24624
|
+
function llamaLendLenderKey(lender, controller) {
|
|
24625
|
+
return `${lender}_${controller.replace(/^0x/i, "").toUpperCase()}`;
|
|
24626
|
+
}
|
|
24627
|
+
function llamaLendKeyParts(key) {
|
|
24628
|
+
if (!key.startsWith("LLAMALEND_")) return void 0;
|
|
24629
|
+
const suffix = key.slice("LLAMALEND_".length);
|
|
24630
|
+
if (!/^[0-9A-F]{40}$/.test(suffix)) return void 0;
|
|
24631
|
+
return { lender: "LLAMALEND", controller: "0x" + suffix.toLowerCase() };
|
|
24632
|
+
}
|
|
24633
|
+
function currencyFor9(address, decimals, symbol, tokens) {
|
|
24634
|
+
const lower3 = address.toLowerCase();
|
|
24635
|
+
return tokens[lower3] ?? { address: lower3, symbol, name: symbol, decimals };
|
|
24636
|
+
}
|
|
24637
|
+
function convertLlamaLendMarketsToResponse(raw, chainId, prices = {}, additionalYields = {
|
|
24638
|
+
intrinsicYields: {},
|
|
24639
|
+
lenderRewards: {},
|
|
24640
|
+
loaded: true
|
|
24641
|
+
}, tokens = {}) {
|
|
24642
|
+
const out = {};
|
|
24643
|
+
const cfg = raw?.config;
|
|
24644
|
+
if (!cfg) return out;
|
|
24645
|
+
for (const m of raw.markets ?? []) {
|
|
24646
|
+
const market = m.market;
|
|
24647
|
+
const lenderKey = llamaLendLenderKey(raw.lender, market.controller);
|
|
24648
|
+
const collAddr = market.collateralToken.toLowerCase();
|
|
24649
|
+
const loanAddr = market.borrowedToken.toLowerCase();
|
|
24650
|
+
const collDecimals = market.collateralDecimals;
|
|
24651
|
+
const loanDecimals = market.borrowedDecimals;
|
|
24652
|
+
const collToken = tokens[collAddr];
|
|
24653
|
+
const loanToken = tokens[loanAddr];
|
|
24654
|
+
const collSymbol = collToken?.symbol ?? market.collateralSymbol ?? "COLL";
|
|
24655
|
+
const loanSymbol = loanToken?.symbol ?? market.borrowedSymbol ?? "LOAN";
|
|
24656
|
+
const marketName = market.name ?? `${loanSymbol} / ${collSymbol}`;
|
|
24657
|
+
const collPriceKey = toOracleKey(collToken?.assetGroup) || toGenericPriceKey(collAddr, chainId);
|
|
24658
|
+
const loanPriceKey = toOracleKey(loanToken?.assetGroup) || toGenericPriceKey(loanAddr, chainId);
|
|
24659
|
+
prices[collPriceKey] || m.collateralPriceUsd || 0;
|
|
24660
|
+
const loanPrice = prices[loanPriceKey] || m.borrowedPriceUsd || 0;
|
|
24661
|
+
const totalDebt = m.totalDebt ?? 0;
|
|
24662
|
+
const totalDeposits = m.totalSupplied ?? 0;
|
|
24663
|
+
const borrowLiquidity = m.borrowingEnabled ? m.availableToBorrow ?? 0 : 0;
|
|
24664
|
+
const withdrawLiquidity = m.availableToBorrow ?? 0;
|
|
24665
|
+
const reserves = totalDebt + (m.availableToBorrow ?? 0);
|
|
24666
|
+
const utilization = reserves > 0 ? totalDebt / reserves : 0;
|
|
24667
|
+
const borrowRatePct = (m.borrowApr ?? 0) * 100;
|
|
24668
|
+
const depositRatePct = (m.lendApr ?? 0) * 100;
|
|
24669
|
+
const ltv = m.collateralFactor ?? 0;
|
|
24670
|
+
const liqPenalty = Number(market.liquidationDiscount) / 1e18 || 0;
|
|
24671
|
+
const closeFactor = 1;
|
|
24672
|
+
const depositsEnabled = (m.maxDeposit ?? 0) > 0;
|
|
24673
|
+
const entry = { data: {} };
|
|
24674
|
+
const collUid = createMarketUid(chainId, lenderKey, collAddr);
|
|
24675
|
+
entry.data[collUid] = {
|
|
24676
|
+
marketUid: collUid,
|
|
24677
|
+
name: "Collateral " + collSymbol,
|
|
24678
|
+
poolId: market.controller.toLowerCase(),
|
|
24679
|
+
underlying: collAddr,
|
|
24680
|
+
asset: currencyFor9(collAddr, collDecimals, collSymbol, tokens),
|
|
24681
|
+
// Collateral lives inside the LLAMMA spread over bands; there is no
|
|
24682
|
+
// single market-level balance worth reporting, and the number the UI
|
|
24683
|
+
// needs is the borrowed side anyway.
|
|
24684
|
+
totalDeposits: 0,
|
|
24685
|
+
totalDebtStable: 0,
|
|
24686
|
+
totalDebt: 0,
|
|
24687
|
+
totalLiquidity: 0,
|
|
24688
|
+
borrowLiquidity: 0,
|
|
24689
|
+
totalLiquidityUSD: 0,
|
|
24690
|
+
borrowLiquidityUSD: 0,
|
|
24691
|
+
totalDepositsUSD: 0,
|
|
24692
|
+
totalDebtStableUSD: 0,
|
|
24693
|
+
totalDebtUSD: 0,
|
|
24694
|
+
utilization: 0,
|
|
24695
|
+
depositRate: 0,
|
|
24696
|
+
variableBorrowRate: 0,
|
|
24697
|
+
stableBorrowRate: 0,
|
|
24698
|
+
intrinsicYield: additionalYields?.intrinsicYields?.[collToken?.assetGroup] ?? 0,
|
|
24699
|
+
rewards: void 0,
|
|
24700
|
+
decimals: collDecimals,
|
|
24701
|
+
config: {
|
|
24702
|
+
0: {
|
|
24703
|
+
category: 0,
|
|
24704
|
+
borrowCollateralFactor: ltv,
|
|
24705
|
+
collateralFactor: ltv,
|
|
24706
|
+
borrowFactor: 1,
|
|
24707
|
+
liquidationPenalty: liqPenalty,
|
|
24708
|
+
closeFactor,
|
|
24709
|
+
collateralDisabled: false,
|
|
24710
|
+
debtDisabled: true
|
|
24711
|
+
}
|
|
24712
|
+
},
|
|
24713
|
+
closeFactor,
|
|
24714
|
+
collateralActive: true,
|
|
24715
|
+
borrowingEnabled: false,
|
|
24716
|
+
depositsEnabled: m.borrowingEnabled,
|
|
24717
|
+
hasStable: false,
|
|
24718
|
+
isActive: true,
|
|
24719
|
+
isFrozen: false
|
|
24720
|
+
};
|
|
24721
|
+
const loanUid = createMarketUid(chainId, lenderKey, loanAddr);
|
|
24722
|
+
entry.data[loanUid] = {
|
|
24723
|
+
marketUid: loanUid,
|
|
24724
|
+
name: loanSymbol,
|
|
24725
|
+
poolId: market.controller.toLowerCase(),
|
|
24726
|
+
underlying: loanAddr,
|
|
24727
|
+
asset: currencyFor9(loanAddr, loanDecimals, loanSymbol, tokens),
|
|
24728
|
+
totalDeposits,
|
|
24729
|
+
totalDebtStable: 0,
|
|
24730
|
+
totalDebt,
|
|
24731
|
+
totalLiquidity: withdrawLiquidity,
|
|
24732
|
+
borrowLiquidity,
|
|
24733
|
+
totalLiquidityUSD: withdrawLiquidity * loanPrice,
|
|
24734
|
+
borrowLiquidityUSD: borrowLiquidity * loanPrice,
|
|
24735
|
+
totalDepositsUSD: totalDeposits * loanPrice,
|
|
24736
|
+
totalDebtStableUSD: 0,
|
|
24737
|
+
totalDebtUSD: totalDebt * loanPrice,
|
|
24738
|
+
utilization,
|
|
24739
|
+
depositRate: depositRatePct,
|
|
24740
|
+
variableBorrowRate: borrowRatePct,
|
|
24741
|
+
stableBorrowRate: 0,
|
|
24742
|
+
// Which curve the depth layer should use. Both are closed-form and both
|
|
24743
|
+
// policies also expose an exact on-chain `future_rate`, so rate-at-depth
|
|
24744
|
+
// never has to be modelled here.
|
|
24745
|
+
rateModel: market.rateModel ?? (market.version === 1 ? "semilog" : "hyperbolic"),
|
|
24746
|
+
intrinsicYield: additionalYields?.intrinsicYields?.[loanToken?.assetGroup] ?? 0,
|
|
24747
|
+
rewards: additionalYields?.lenderRewards?.[lenderKey] ?? void 0,
|
|
24748
|
+
decimals: loanDecimals,
|
|
24749
|
+
config: {
|
|
24750
|
+
0: {
|
|
24751
|
+
category: 0,
|
|
24752
|
+
borrowCollateralFactor: 0,
|
|
24753
|
+
collateralFactor: 0,
|
|
24754
|
+
borrowFactor: 1,
|
|
24755
|
+
liquidationPenalty: liqPenalty,
|
|
24756
|
+
closeFactor,
|
|
24757
|
+
collateralDisabled: true,
|
|
24758
|
+
debtDisabled: !m.borrowingEnabled
|
|
24759
|
+
}
|
|
24760
|
+
},
|
|
24761
|
+
closeFactor,
|
|
24762
|
+
collateralActive: false,
|
|
24763
|
+
borrowingEnabled: m.borrowingEnabled,
|
|
24764
|
+
depositsEnabled,
|
|
24765
|
+
hasStable: false,
|
|
24766
|
+
variableBorrowDisabled: !m.borrowingEnabled,
|
|
24767
|
+
isActive: true,
|
|
24768
|
+
isFrozen: false
|
|
24769
|
+
};
|
|
24770
|
+
entry.params = {
|
|
24771
|
+
market: {
|
|
24772
|
+
lender: lenderKey,
|
|
24773
|
+
name: marketName,
|
|
24774
|
+
loanDecimals,
|
|
24775
|
+
collateralDecimals: collDecimals,
|
|
24776
|
+
// The Controller doubles as the market id.
|
|
24777
|
+
id: market.controller.toLowerCase(),
|
|
24778
|
+
lltv: String(ltv),
|
|
24779
|
+
oracle: market.priceOracle ?? market.amm,
|
|
24780
|
+
irm: market.monetaryPolicy ?? zeroAddress,
|
|
24781
|
+
collateralAddress: collAddr,
|
|
24782
|
+
loanAddress: loanAddr,
|
|
24783
|
+
// --- LlamaLend descriptor (consumed by the calldata builders,
|
|
24784
|
+
// the leverage sizer and worker-api resolvers) ---
|
|
24785
|
+
llamalend: {
|
|
24786
|
+
/** 1 = `oneway` (v1), 2 = `oneway-v2`. Branch every encoder on this. */
|
|
24787
|
+
version: market.version,
|
|
24788
|
+
/** FAIL CLOSED — an unknown market is not delegatable. */
|
|
24789
|
+
supportsDelegation: market.supportsDelegation === true,
|
|
24790
|
+
/**
|
|
24791
|
+
* The market's index in its factory — also the `controller_id` that
|
|
24792
|
+
* Curve's leverage zap requires in `callback_args`. Without it no
|
|
24793
|
+
* leveraged transaction can be encoded.
|
|
24794
|
+
*/
|
|
24795
|
+
factoryIndex: market.factoryIndex,
|
|
24796
|
+
/**
|
|
24797
|
+
* Whether Curve's deployed v1 zap accepts this market. A WIDER gate
|
|
24798
|
+
* than `supportsDelegation` — leverage is EOA-direct and needs no
|
|
24799
|
+
* grant — so never conflate the two.
|
|
24800
|
+
*/
|
|
24801
|
+
supportsLeverage: market.supportsLeverage === true,
|
|
24802
|
+
/**
|
|
24803
|
+
* Band count the reported `collateralFactor` was computed at. A
|
|
24804
|
+
* consumer quoting a different `N` MUST re-read `bandLtv`.
|
|
24805
|
+
*/
|
|
24806
|
+
defaultBands: market.defaultBands ?? 10,
|
|
24807
|
+
/** `{ [N]: ltv }` — the collateral-factor curve across band counts. */
|
|
24808
|
+
bandLtv: m.bandLtv ?? void 0,
|
|
24809
|
+
/** AMM band-geometry parameter. */
|
|
24810
|
+
ammA: market.ammA,
|
|
24811
|
+
loanDiscount: market.loanDiscount,
|
|
24812
|
+
/** HARD-liquidation bonus only; soft liquidation carries no penalty. */
|
|
24813
|
+
liquidationDiscount: market.liquidationDiscount,
|
|
24814
|
+
/**
|
|
24815
|
+
* Positions soft-liquidate over a band RANGE rather than at a single
|
|
24816
|
+
* price. `activeBand` says whether the market is currently
|
|
24817
|
+
* converting anyone; the per-user range comes from `user_prices`.
|
|
24818
|
+
*/
|
|
24819
|
+
activeBand: m.activeBand ?? void 0,
|
|
24820
|
+
nLoans: m.nLoans ?? void 0,
|
|
24821
|
+
/** Collateral price in BORROWED-token terms (the AMM's EMA oracle). */
|
|
24822
|
+
collateralPrice: m.collateralPrice !== null ? String(m.collateralPrice) : void 0,
|
|
24823
|
+
/** v2 only; `0` means borrowing is switched off. */
|
|
24824
|
+
borrowCap: m.borrowCap !== null ? String(m.borrowCap) : void 0,
|
|
24825
|
+
addresses: {
|
|
24826
|
+
controller: market.controller,
|
|
24827
|
+
vault: market.vault,
|
|
24828
|
+
/**
|
|
24829
|
+
* MUST be excluded from any leverage swap route — the Controller
|
|
24830
|
+
* asserts this AMM's band state is unchanged across a callback,
|
|
24831
|
+
* so a route through it reverts with no usable reason string.
|
|
24832
|
+
*/
|
|
24833
|
+
amm: market.amm,
|
|
24834
|
+
monetaryPolicy: market.monetaryPolicy,
|
|
24835
|
+
priceOracle: market.priceOracle,
|
|
24836
|
+
/**
|
|
24837
|
+
* Curve's deployed v1 leverage zaps and the aggregator routers
|
|
24838
|
+
* they are hard-wired to. We route leverage through these rather
|
|
24839
|
+
* than deploying a callbacker: their router is an immutable with
|
|
24840
|
+
* no allowlist, so arbitrary aggregator calldata is permitted.
|
|
24841
|
+
*
|
|
24842
|
+
* A quote MUST be checked against the matching `*Router` before
|
|
24843
|
+
* encoding — the zap forwards mismatched calldata to its own
|
|
24844
|
+
* router rather than rejecting it.
|
|
24845
|
+
*/
|
|
24846
|
+
leverageZapOdos: cfg.leverageZapOdos,
|
|
24847
|
+
leverageZapOdosRouter: cfg.leverageZapOdosRouter,
|
|
24848
|
+
leverageZap1inch: cfg.leverageZap1inch,
|
|
24849
|
+
leverageZap1inchRouter: cfg.leverageZap1inchRouter,
|
|
24850
|
+
oneWayFactory: cfg.oneWayFactory,
|
|
24851
|
+
lendFactory: cfg.lendFactory
|
|
24852
|
+
}
|
|
24853
|
+
}
|
|
24854
|
+
}
|
|
24855
|
+
};
|
|
24856
|
+
entry.chainId = chainId;
|
|
24857
|
+
out[lenderKey] = entry;
|
|
24858
|
+
}
|
|
24859
|
+
return out;
|
|
24860
|
+
}
|
|
24861
|
+
var llamaLendKey = (controller) => `LLAMALEND_${controller.replace(/^0x/i, "").toUpperCase()}`;
|
|
24862
|
+
function resolveWrappedMarket(chainId, collateralVault, pairName) {
|
|
24863
|
+
const market = llamaLendMarketByVault("LLAMALEND", chainId, collateralVault);
|
|
24864
|
+
if (market) {
|
|
24865
|
+
return {
|
|
24866
|
+
provider: "llamalend",
|
|
24867
|
+
vault: collateralVault,
|
|
24868
|
+
lender: llamaLendKey(market.controller),
|
|
24869
|
+
controller: market.controller,
|
|
24870
|
+
amm: market.amm,
|
|
24871
|
+
version: market.version,
|
|
24872
|
+
collateralSymbol: market.collateralSymbol
|
|
24873
|
+
};
|
|
24874
|
+
}
|
|
24875
|
+
const isFraxlend = /fraxlend/i.test(pairName);
|
|
24876
|
+
return {
|
|
24877
|
+
provider: isFraxlend ? "fraxlend" : "unknown",
|
|
24878
|
+
vault: collateralVault
|
|
24879
|
+
};
|
|
24880
|
+
}
|
|
24881
|
+
function resupplyLenderKey(lender, chainId, pair) {
|
|
24882
|
+
return `${lender}_${chainId}_${pair.replace(/^0x/i, "").toUpperCase()}`;
|
|
24883
|
+
}
|
|
24884
|
+
function resupplyKeyParts(key) {
|
|
24885
|
+
if (!key.startsWith("RESUPPLY_")) return void 0;
|
|
24886
|
+
const suffix = key.slice("RESUPPLY_".length);
|
|
24887
|
+
const m = suffix.match(/^(\d+)_([0-9A-Fa-f]{40})$/);
|
|
24888
|
+
if (!m) return void 0;
|
|
24889
|
+
return {
|
|
24890
|
+
lender: "RESUPPLY",
|
|
24891
|
+
chainId: m[1],
|
|
24892
|
+
pair: `0x${m[2].toLowerCase()}`
|
|
24893
|
+
};
|
|
24894
|
+
}
|
|
24895
|
+
var SECONDS_PER_YEAR9 = 31536e3;
|
|
24896
|
+
var LTV_PRECISION = 1e5;
|
|
24897
|
+
var ONE2 = 10n ** 18n;
|
|
24898
|
+
function currencyFor10(address, decimals, symbol, tokens) {
|
|
24899
|
+
const lower3 = address.toLowerCase();
|
|
24900
|
+
return tokens[lower3] ?? { address: lower3, symbol, name: symbol, decimals };
|
|
24901
|
+
}
|
|
24902
|
+
function ratePerSecToApr(rate) {
|
|
24903
|
+
if (rate === null) return 0;
|
|
24904
|
+
return Number(rate) / 1e18 * SECONDS_PER_YEAR9 * 100;
|
|
24905
|
+
}
|
|
24906
|
+
function convertResupplyMarketsToResponse(raw, chainId, prices = {}, _additionalYields = {
|
|
24907
|
+
intrinsicYields: {},
|
|
24908
|
+
lenderRewards: {},
|
|
24909
|
+
loaded: true
|
|
24910
|
+
}, tokens = {}) {
|
|
24911
|
+
const out = {};
|
|
24912
|
+
const cfg = raw?.config;
|
|
24913
|
+
if (!cfg) return out;
|
|
24914
|
+
const debtAddr = cfg.reusd.toLowerCase();
|
|
24915
|
+
const debtDecimals = cfg.debtDecimals ?? 18;
|
|
24916
|
+
const debtToken = tokens[debtAddr];
|
|
24917
|
+
const debtSymbol = debtToken?.symbol ?? "reUSD";
|
|
24918
|
+
const debtPriceKey = toOracleKey(debtToken?.assetGroup) || toGenericPriceKey(debtAddr, chainId);
|
|
24919
|
+
const debtPrice = prices[debtPriceKey] || 1;
|
|
24920
|
+
for (const p of raw.pairs ?? []) {
|
|
24921
|
+
const id = p.identity;
|
|
24922
|
+
if (p.maxLTV === null || p.borrowLimit === null) continue;
|
|
24923
|
+
if (p.totalBorrowAmount === null || p.totalCollateral === null) continue;
|
|
24924
|
+
if (p.collateralPrice === null || p.collateralPrice === 0n) continue;
|
|
24925
|
+
const lenderKey = resupplyLenderKey(raw.lender, chainId, id.pair);
|
|
24926
|
+
const collAddr = id.underlying.toLowerCase();
|
|
24927
|
+
const collDecimals = id.underlyingDecimals;
|
|
24928
|
+
const collToken = tokens[collAddr];
|
|
24929
|
+
const collSymbol = collToken?.symbol ?? "COLL";
|
|
24930
|
+
const collPriceKey = toOracleKey(collToken?.assetGroup) || toGenericPriceKey(collAddr, chainId);
|
|
24931
|
+
const collPrice = prices[collPriceKey] || 1;
|
|
24932
|
+
const shares = p.totalCollateral ?? 0n;
|
|
24933
|
+
const sharePrice = p.collateralPrice ?? 0n;
|
|
24934
|
+
const collUnderlyingRaw = sharePrice > 0n ? shares * sharePrice / ONE2 : 0n;
|
|
24935
|
+
const totalColl = Number(collUnderlyingRaw) / 10 ** collDecimals;
|
|
24936
|
+
const totalDebt = p.totalBorrowAmount !== null ? Number(p.totalBorrowAmount) / 10 ** debtDecimals : 0;
|
|
24937
|
+
const borrowLimit = p.borrowLimit !== null ? Number(p.borrowLimit) / 10 ** debtDecimals : 0;
|
|
24938
|
+
const borrowLiquidity = Math.max(borrowLimit - totalDebt, 0);
|
|
24939
|
+
const halted = (p.borrowLimit ?? 0n) === 0n;
|
|
24940
|
+
const wrappedMarket = resolveWrappedMarket(chainId, id.collateral, id.name);
|
|
24941
|
+
const maxLtv = p.maxLTV !== null ? Number(p.maxLTV) / LTV_PRECISION : 0;
|
|
24942
|
+
const liquidationPenalty = p.liquidationFee !== null ? Number(p.liquidationFee) / LTV_PRECISION : 0;
|
|
24943
|
+
const mintFeePct = p.mintFee !== null ? Number(p.mintFee) / LTV_PRECISION * 100 : 0;
|
|
24944
|
+
const borrowApr = ratePerSecToApr(p.liveRatePerSec ?? p.ratePerSec);
|
|
24945
|
+
const collateralIntrinsicApr = ratePerSecToApr(p.underlyingSupplyRatePerSec);
|
|
24946
|
+
const entry = { data: {} };
|
|
24947
|
+
const collUid = createMarketUid(chainId, lenderKey, collAddr);
|
|
24948
|
+
entry.data[collUid] = {
|
|
24949
|
+
marketUid: collUid,
|
|
24950
|
+
name: "Collateral " + collSymbol,
|
|
24951
|
+
poolId: id.pair.toLowerCase(),
|
|
24952
|
+
underlying: collAddr,
|
|
24953
|
+
asset: currencyFor10(collAddr, collDecimals, collSymbol, tokens),
|
|
24954
|
+
totalDeposits: totalColl,
|
|
24955
|
+
totalDebtStable: 0,
|
|
24956
|
+
totalDebt: 0,
|
|
24957
|
+
totalLiquidity: totalColl,
|
|
24958
|
+
borrowLiquidity: 0,
|
|
24959
|
+
totalLiquidityUSD: totalColl * collPrice,
|
|
24960
|
+
borrowLiquidityUSD: 0,
|
|
24961
|
+
totalDepositsUSD: totalColl * collPrice,
|
|
24962
|
+
totalDebtStableUSD: 0,
|
|
24963
|
+
totalDebtUSD: 0,
|
|
24964
|
+
utilization: 0,
|
|
24965
|
+
depositRate: 0,
|
|
24966
|
+
variableBorrowRate: 0,
|
|
24967
|
+
stableBorrowRate: 0,
|
|
24968
|
+
// The wrapped Curve Lend / Fraxlend supply rate — this collateral is a
|
|
24969
|
+
// lending position and earns while it sits here.
|
|
24970
|
+
intrinsicYield: collateralIntrinsicApr,
|
|
24971
|
+
rewards: void 0,
|
|
24972
|
+
decimals: collDecimals,
|
|
24973
|
+
config: {
|
|
24974
|
+
0: {
|
|
24975
|
+
category: 0,
|
|
24976
|
+
borrowCollateralFactor: maxLtv,
|
|
24977
|
+
collateralFactor: maxLtv,
|
|
24978
|
+
borrowFactor: 1,
|
|
24979
|
+
liquidationPenalty,
|
|
24980
|
+
// Liquidation takes the WHOLE position (`liquidate(borrower)` repays
|
|
24981
|
+
// all of it) — there is no partial close.
|
|
24982
|
+
closeFactor: 1,
|
|
24983
|
+
collateralDisabled: false,
|
|
24984
|
+
debtDisabled: true
|
|
24985
|
+
}
|
|
24986
|
+
},
|
|
24987
|
+
closeFactor: 1,
|
|
24988
|
+
collateralActive: true,
|
|
24989
|
+
borrowingEnabled: false,
|
|
24990
|
+
// Deposits stay open on a paused pair so positions can be topped up to
|
|
24991
|
+
// avoid liquidation; only borrowing is stopped.
|
|
24992
|
+
depositsEnabled: true,
|
|
24993
|
+
hasStable: false,
|
|
24994
|
+
isActive: !halted,
|
|
24995
|
+
isFrozen: halted
|
|
24996
|
+
};
|
|
24997
|
+
const loanUid = createMarketUid(chainId, lenderKey, debtAddr);
|
|
24998
|
+
entry.data[loanUid] = {
|
|
24999
|
+
marketUid: loanUid,
|
|
25000
|
+
name: debtSymbol,
|
|
25001
|
+
poolId: id.pair.toLowerCase(),
|
|
25002
|
+
underlying: debtAddr,
|
|
25003
|
+
asset: currencyFor10(debtAddr, debtDecimals, debtSymbol, tokens),
|
|
25004
|
+
totalDeposits: 0,
|
|
25005
|
+
totalDebtStable: 0,
|
|
25006
|
+
totalDebt,
|
|
25007
|
+
totalLiquidity: borrowLiquidity,
|
|
25008
|
+
borrowLiquidity,
|
|
25009
|
+
totalLiquidityUSD: borrowLiquidity * debtPrice,
|
|
25010
|
+
borrowLiquidityUSD: borrowLiquidity * debtPrice,
|
|
25011
|
+
totalDepositsUSD: 0,
|
|
25012
|
+
totalDebtStableUSD: 0,
|
|
25013
|
+
totalDebtUSD: totalDebt * debtPrice,
|
|
25014
|
+
// Against the governance-set debt ceiling, not a deposit base — there is
|
|
25015
|
+
// no supply side to be utilized.
|
|
25016
|
+
utilization: borrowLimit > 0 ? Math.min(totalDebt / borrowLimit, 1) : 0,
|
|
25017
|
+
depositRate: 0,
|
|
25018
|
+
variableBorrowRate: borrowApr,
|
|
25019
|
+
stableBorrowRate: 0,
|
|
25020
|
+
// Pinned to ~half the greater of {wrapped supply rate, sfrxUSD risk-free
|
|
25021
|
+
// rate, floor}, then scaled by the reUSD off-peg weight. No utilization
|
|
25022
|
+
// curve anywhere in the protocol.
|
|
25023
|
+
rateModel: "protocolSet",
|
|
25024
|
+
// `mintFee` is added to the debt at borrow time. Zero on every live pair,
|
|
25025
|
+
// but it is governance-settable.
|
|
25026
|
+
originationFee: mintFeePct,
|
|
25027
|
+
intrinsicYield: 0,
|
|
25028
|
+
rewards: void 0,
|
|
25029
|
+
decimals: debtDecimals,
|
|
25030
|
+
config: {
|
|
25031
|
+
0: {
|
|
25032
|
+
category: 0,
|
|
25033
|
+
borrowCollateralFactor: 0,
|
|
25034
|
+
collateralFactor: 0,
|
|
25035
|
+
borrowFactor: 1,
|
|
25036
|
+
liquidationPenalty,
|
|
25037
|
+
closeFactor: 1,
|
|
25038
|
+
collateralDisabled: true,
|
|
25039
|
+
debtDisabled: halted
|
|
25040
|
+
}
|
|
25041
|
+
},
|
|
25042
|
+
closeFactor: 1,
|
|
25043
|
+
collateralActive: false,
|
|
25044
|
+
borrowingEnabled: !halted,
|
|
25045
|
+
depositsEnabled: false,
|
|
25046
|
+
hasStable: false,
|
|
25047
|
+
variableBorrowDisabled: halted,
|
|
25048
|
+
isActive: !halted,
|
|
25049
|
+
isFrozen: halted
|
|
25050
|
+
};
|
|
25051
|
+
entry.params = {
|
|
25052
|
+
market: {
|
|
25053
|
+
lender: lenderKey,
|
|
25054
|
+
name: id.name,
|
|
25055
|
+
loanDecimals: debtDecimals,
|
|
25056
|
+
collateralDecimals: collDecimals,
|
|
25057
|
+
id: id.pair.toLowerCase(),
|
|
25058
|
+
lltv: p.maxLTV !== null ? p.maxLTV.toString() : "0",
|
|
25059
|
+
// The oracle is the collateral vault's own `convertToAssets`; there is
|
|
25060
|
+
// no external price feed contract to name.
|
|
25061
|
+
oracle: zeroAddress,
|
|
25062
|
+
irm: zeroAddress,
|
|
25063
|
+
collateralAddress: collAddr,
|
|
25064
|
+
loanAddress: debtAddr,
|
|
25065
|
+
// --- Resupply descriptor (consumed by the calldata builders, the
|
|
25066
|
+
// worker-api resolvers and the loop quoter) ---
|
|
25067
|
+
resupply: {
|
|
25068
|
+
pair: id.pair,
|
|
25069
|
+
/** The ERC-4626 share the pair actually books as collateral. */
|
|
25070
|
+
collateralVault: id.collateral,
|
|
25071
|
+
collateralVaultDecimals: id.collateralDecimals,
|
|
25072
|
+
/** What the user deposits/withdraws (crvUSD or frxUSD). */
|
|
25073
|
+
underlying: id.underlying,
|
|
25074
|
+
/**
|
|
25075
|
+
* The EXTERNAL lending market this pair wraps. A Resupply position
|
|
25076
|
+
* inherits that market's risk (bad debt there is bad debt here), so
|
|
25077
|
+
* the link is first-class rather than a footnote. Resolved against
|
|
25078
|
+
* our own LlamaLend roster by vault address where possible.
|
|
25079
|
+
*/
|
|
25080
|
+
wrappedMarket,
|
|
25081
|
+
/** `convertToAssets(1e18)` — UNDERLYING per 1e18 shares. ~1e15 for
|
|
25082
|
+
* Curve Lend vaults. Required to size any share-denominated arg. */
|
|
25083
|
+
collateralPrice: (p.collateralPrice ?? 0n).toString(),
|
|
25084
|
+
/** The pair's cached `1e36 / collateralPrice` (stale between writes). */
|
|
25085
|
+
exchangeRate: (p.exchangeRate ?? 0n).toString(),
|
|
25086
|
+
maxLTV: (p.maxLTV ?? 0n).toString(),
|
|
25087
|
+
borrowLimit: (p.borrowLimit ?? 0n).toString(),
|
|
25088
|
+
/** Hard floor per position — a smaller borrow, or a repay leaving
|
|
25089
|
+
* less than this, reverts. */
|
|
25090
|
+
minimumBorrowAmount: (p.minimumBorrowAmount ?? 0n).toString(),
|
|
25091
|
+
liquidationFee: (p.liquidationFee ?? 0n).toString(),
|
|
25092
|
+
mintFee: (p.mintFee ?? 0n).toString(),
|
|
25093
|
+
totalBorrowShares: (p.totalBorrowShares ?? 0n).toString(),
|
|
25094
|
+
totalBorrowAmount: (p.totalBorrowAmount ?? 0n).toString(),
|
|
25095
|
+
totalCollateralShares: (p.totalCollateral ?? 0n).toString(),
|
|
25096
|
+
borrowRatePerSecond: (p.liveRatePerSec ?? p.ratePerSec ?? 0n).toString(),
|
|
25097
|
+
underlyingSupplyRatePerSecond: (p.underlyingSupplyRatePerSec ?? 0n).toString(),
|
|
25098
|
+
/** Zero borrow limit = paused by governance (no `isPaused` exists). */
|
|
25099
|
+
paused: halted,
|
|
25100
|
+
addresses: {
|
|
25101
|
+
registry: cfg.registry,
|
|
25102
|
+
reusd: cfg.reusd,
|
|
25103
|
+
utilities: cfg.utilities ?? void 0,
|
|
25104
|
+
curveSwapper: cfg.curveSwapper ?? void 0,
|
|
25105
|
+
ensoSwapper: cfg.ensoSwapper ?? void 0,
|
|
25106
|
+
lifiSwapper: cfg.lifiSwapper ?? void 0
|
|
25107
|
+
}
|
|
25108
|
+
}
|
|
25109
|
+
}
|
|
25110
|
+
};
|
|
25111
|
+
entry.chainId = chainId;
|
|
25112
|
+
out[lenderKey] = entry;
|
|
25113
|
+
}
|
|
25114
|
+
return out;
|
|
25115
|
+
}
|
|
24181
25116
|
var READS_PER_ILK = 4;
|
|
24182
25117
|
var USDD_ABI_PER_READ = [UsddVatAbi, UsddJugAbi, UsddSpotAbi, erc20Abi];
|
|
24183
25118
|
var usddIlkBytes32 = (ilk) => stringToHex(ilk, { size: 32 });
|
|
@@ -24208,12 +25143,12 @@ async function fetchUsddMarkets(lender, chainId) {
|
|
|
24208
25143
|
} catch {
|
|
24209
25144
|
return { lender, config, chainData, markets: [] };
|
|
24210
25145
|
}
|
|
24211
|
-
const
|
|
25146
|
+
const big13 = (v) => {
|
|
24212
25147
|
if (typeof v === "bigint") return v;
|
|
24213
25148
|
if (typeof v === "number") return BigInt(v);
|
|
24214
25149
|
return null;
|
|
24215
25150
|
};
|
|
24216
|
-
const field12 = (res, name, idx) =>
|
|
25151
|
+
const field12 = (res, name, idx) => big13(res?.[name] ?? res?.[idx]);
|
|
24217
25152
|
const out = markets.map((market, i) => {
|
|
24218
25153
|
const base = i * READS_PER_ILK;
|
|
24219
25154
|
const vatIlk = results[base];
|
|
@@ -24228,7 +25163,7 @@ async function fetchUsddMarkets(lender, chainId) {
|
|
|
24228
25163
|
dust: field12(vatIlk, "dust", 4),
|
|
24229
25164
|
duty: field12(jugIlk, "duty", 0),
|
|
24230
25165
|
mat: field12(spotIlk, "mat", 1),
|
|
24231
|
-
joinBalance:
|
|
25166
|
+
joinBalance: big13(results[base + 3])
|
|
24232
25167
|
};
|
|
24233
25168
|
});
|
|
24234
25169
|
return { lender, config, chainData, markets: out };
|
|
@@ -24252,7 +25187,7 @@ var YEAR_SECONDS2 = 31536e3;
|
|
|
24252
25187
|
function toHuman4(raw, decimals) {
|
|
24253
25188
|
return Number(raw) / 10 ** decimals;
|
|
24254
25189
|
}
|
|
24255
|
-
function
|
|
25190
|
+
function currencyFor11(address, decimals, symbol, tokens) {
|
|
24256
25191
|
const lower3 = address.toLowerCase();
|
|
24257
25192
|
return tokens[lower3] ?? { address: lower3, symbol, name: symbol, decimals };
|
|
24258
25193
|
}
|
|
@@ -24300,7 +25235,7 @@ function convertUsddMarketsToResponse(raw, chainId, prices = {}, _additionalYiel
|
|
|
24300
25235
|
name: "Collateral " + collSymbol,
|
|
24301
25236
|
poolId: market.gemJoin.toLowerCase(),
|
|
24302
25237
|
underlying: collAddr,
|
|
24303
|
-
asset:
|
|
25238
|
+
asset: currencyFor11(collAddr, collDecimals, collSymbol, tokens),
|
|
24304
25239
|
totalDeposits: totalColl,
|
|
24305
25240
|
totalDebtStable: 0,
|
|
24306
25241
|
totalDebt: 0,
|
|
@@ -24344,7 +25279,7 @@ function convertUsddMarketsToResponse(raw, chainId, prices = {}, _additionalYiel
|
|
|
24344
25279
|
name: debtSymbol,
|
|
24345
25280
|
poolId: cfg.vat.toLowerCase(),
|
|
24346
25281
|
underlying: debtAddr,
|
|
24347
|
-
asset:
|
|
25282
|
+
asset: currencyFor11(debtAddr, debtDecimals, debtSymbol, tokens),
|
|
24348
25283
|
totalDeposits: 0,
|
|
24349
25284
|
totalDebtStable: 0,
|
|
24350
25285
|
totalDebt,
|
|
@@ -24436,6 +25371,304 @@ function convertUsddMarketsToResponse(raw, chainId, prices = {}, _additionalYiel
|
|
|
24436
25371
|
}
|
|
24437
25372
|
return out;
|
|
24438
25373
|
}
|
|
25374
|
+
var READS_PER_MARKET3 = 10;
|
|
25375
|
+
var FRANKENCOIN_ABI_PER_READ = [
|
|
25376
|
+
FrankencoinPositionAbi,
|
|
25377
|
+
FrankencoinPositionAbi,
|
|
25378
|
+
FrankencoinPositionAbi,
|
|
25379
|
+
FrankencoinPositionAbi,
|
|
25380
|
+
FrankencoinPositionAbi,
|
|
25381
|
+
FrankencoinPositionAbi,
|
|
25382
|
+
FrankencoinPositionAbi,
|
|
25383
|
+
FrankencoinPositionAbi,
|
|
25384
|
+
FrankencoinPositionAbi,
|
|
25385
|
+
erc20Abi
|
|
25386
|
+
];
|
|
25387
|
+
async function fetchFrankencoinMarkets(lender, chainId) {
|
|
25388
|
+
const config = frankencoinConfigFor(lender, chainId);
|
|
25389
|
+
const chainData = frankencoinChainData(lender, chainId);
|
|
25390
|
+
const markets = chainData?.markets ?? [];
|
|
25391
|
+
if (!config || markets.length === 0) {
|
|
25392
|
+
return { lender, config, chainData, markets: [] };
|
|
25393
|
+
}
|
|
25394
|
+
const calls = markets.flatMap((m) => [
|
|
25395
|
+
{ address: m.position, name: "price", params: [] },
|
|
25396
|
+
{ address: m.position, name: "minted", params: [] },
|
|
25397
|
+
{ address: m.position, name: "availableForClones", params: [] },
|
|
25398
|
+
{ address: m.position, name: "annualInterestPPM", params: [] },
|
|
25399
|
+
{ address: m.position, name: "calculateCurrentFee", params: [] },
|
|
25400
|
+
{ address: m.position, name: "reserveContribution", params: [] },
|
|
25401
|
+
{ address: m.position, name: "challengedAmount", params: [] },
|
|
25402
|
+
{ address: m.position, name: "expiration", params: [] },
|
|
25403
|
+
// Read LIVE rather than trusting the generator's snapshot: a position
|
|
25404
|
+
// can close between metadata runs (and dropping below
|
|
25405
|
+
// `minimumCollateral` closes one permanently), and publishing a dead
|
|
25406
|
+
// market as borrowable is the worst failure mode here.
|
|
25407
|
+
{ address: m.position, name: "isClosed", params: [] },
|
|
25408
|
+
{ address: m.collToken, name: "balanceOf", params: [m.position] }
|
|
25409
|
+
]);
|
|
25410
|
+
let results = [];
|
|
25411
|
+
try {
|
|
25412
|
+
results = await multicallRetryUniversal({
|
|
25413
|
+
chain: chainId,
|
|
25414
|
+
calls,
|
|
25415
|
+
abi: markets.flatMap(() => FRANKENCOIN_ABI_PER_READ),
|
|
25416
|
+
allowFailure: true
|
|
25417
|
+
});
|
|
25418
|
+
} catch {
|
|
25419
|
+
return { lender, config, chainData, markets: [] };
|
|
25420
|
+
}
|
|
25421
|
+
const big13 = (v) => {
|
|
25422
|
+
if (typeof v === "bigint") return v;
|
|
25423
|
+
if (typeof v === "number") return BigInt(v);
|
|
25424
|
+
return null;
|
|
25425
|
+
};
|
|
25426
|
+
const out = markets.map((market, i) => {
|
|
25427
|
+
const base = i * READS_PER_MARKET3;
|
|
25428
|
+
const expiration = big13(results[base + 7]);
|
|
25429
|
+
return {
|
|
25430
|
+
market,
|
|
25431
|
+
price: big13(results[base]),
|
|
25432
|
+
minted: big13(results[base + 1]),
|
|
25433
|
+
availableForClones: big13(results[base + 2]),
|
|
25434
|
+
annualInterestPPM: big13(results[base + 3]),
|
|
25435
|
+
currentFeePPM: big13(results[base + 4]),
|
|
25436
|
+
reserveContribution: big13(results[base + 5]),
|
|
25437
|
+
challengedAmount: big13(results[base + 6]),
|
|
25438
|
+
expiration,
|
|
25439
|
+
isClosed: typeof results[base + 8] === "boolean" ? results[base + 8] : null,
|
|
25440
|
+
collateralBalance: big13(results[base + 9])
|
|
25441
|
+
};
|
|
25442
|
+
});
|
|
25443
|
+
return { lender, config, chainData, markets: out };
|
|
25444
|
+
}
|
|
25445
|
+
|
|
25446
|
+
// src/lending/public-data/frankencoin/convertPublic.ts
|
|
25447
|
+
function frankencoinLenderKey(lender, chainId, position) {
|
|
25448
|
+
return `${lender}_${chainId}_${position.replace(/^0x/i, "").toUpperCase()}`;
|
|
25449
|
+
}
|
|
25450
|
+
function frankencoinKeyParts(key) {
|
|
25451
|
+
if (!key.startsWith("FRANKENCOIN_")) return void 0;
|
|
25452
|
+
const suffix = key.slice("FRANKENCOIN_".length);
|
|
25453
|
+
const m = suffix.match(/^(\d+)_([0-9A-Fa-f]{40})$/);
|
|
25454
|
+
if (!m) return void 0;
|
|
25455
|
+
return {
|
|
25456
|
+
lender: "FRANKENCOIN",
|
|
25457
|
+
chainId: m[1],
|
|
25458
|
+
position: `0x${m[2].toLowerCase()}`
|
|
25459
|
+
};
|
|
25460
|
+
}
|
|
25461
|
+
var PPM = 1e6;
|
|
25462
|
+
function currencyFor12(address, decimals, symbol, tokens) {
|
|
25463
|
+
const lower3 = address.toLowerCase();
|
|
25464
|
+
return tokens[lower3] ?? { address: lower3, symbol, name: symbol, decimals };
|
|
25465
|
+
}
|
|
25466
|
+
function convertFrankencoinMarketsToResponse(raw, chainId, prices = {}, _additionalYields = {
|
|
25467
|
+
intrinsicYields: {},
|
|
25468
|
+
lenderRewards: {},
|
|
25469
|
+
loaded: true
|
|
25470
|
+
}, tokens = {}) {
|
|
25471
|
+
const out = {};
|
|
25472
|
+
const cfg = raw?.config;
|
|
25473
|
+
const chainData = raw?.chainData;
|
|
25474
|
+
if (!cfg || !chainData) return out;
|
|
25475
|
+
const debtAddr = cfg.zchf.toLowerCase();
|
|
25476
|
+
const debtDecimals = cfg.debtDecimals ?? 18;
|
|
25477
|
+
const debtToken = tokens[debtAddr];
|
|
25478
|
+
const debtSymbol = debtToken?.symbol ?? "ZCHF";
|
|
25479
|
+
const debtPriceKey = toOracleKey(debtToken?.assetGroup) || toGenericPriceKey(debtAddr, chainId);
|
|
25480
|
+
const debtPrice = prices[debtPriceKey] ?? 0;
|
|
25481
|
+
const nowSec9 = Math.floor(Date.now() / 1e3);
|
|
25482
|
+
for (const m of raw.markets ?? []) {
|
|
25483
|
+
const market = m.market;
|
|
25484
|
+
const lenderKey = frankencoinLenderKey(raw.lender, chainId, market.position);
|
|
25485
|
+
const collAddr = market.collToken.toLowerCase();
|
|
25486
|
+
const collDecimals = market.collDecimals;
|
|
25487
|
+
const collToken = tokens[collAddr];
|
|
25488
|
+
const collSymbol = collToken?.symbol ?? market.collSymbol ?? "COLL";
|
|
25489
|
+
const marketName = market.name ?? `${debtSymbol} / ${collSymbol}`;
|
|
25490
|
+
const collPriceKey = toOracleKey(collToken?.assetGroup) || toGenericPriceKey(collAddr, chainId);
|
|
25491
|
+
const collPrice = prices[collPriceKey] ?? 0;
|
|
25492
|
+
const declaredPrice = m.price !== null ? Number(m.price) / 10 ** (36 - collDecimals) : Number(market.price) / 10 ** (36 - collDecimals);
|
|
25493
|
+
const totalColl = m.collateralBalance !== null ? Number(m.collateralBalance) / 10 ** collDecimals : 0;
|
|
25494
|
+
const totalDebt = m.minted !== null ? Number(m.minted) / 10 ** debtDecimals : 0;
|
|
25495
|
+
const borrowLiquidity = m.availableForClones !== null ? Number(m.availableForClones) / 10 ** debtDecimals : 0;
|
|
25496
|
+
const expiration = m.expiration !== null ? Number(m.expiration) : Number(market.expiration);
|
|
25497
|
+
const expired = expiration > 0 && expiration <= nowSec9;
|
|
25498
|
+
const challenged = (m.challengedAmount ?? 0n) > 0n;
|
|
25499
|
+
const closed = m.isClosed === true;
|
|
25500
|
+
const halted = expired || closed;
|
|
25501
|
+
const borrowApr = m.annualInterestPPM !== null ? Number(m.annualInterestPPM) / PPM * 100 : 0;
|
|
25502
|
+
const upfrontFeePct = m.currentFeePPM !== null ? Number(m.currentFeePPM) / PPM * 100 : 0;
|
|
25503
|
+
const reserveContributionPpm = m.reserveContribution !== null ? Number(m.reserveContribution) : Number(market.reserveContribution);
|
|
25504
|
+
const ltvVsMarket = collPrice > 0 ? Math.min(declaredPrice / collPrice, 1) : 0;
|
|
25505
|
+
const declaredVsMarket = collPrice > 0 ? declaredPrice / collPrice : void 0;
|
|
25506
|
+
const entry = { data: {} };
|
|
25507
|
+
const collUid = createMarketUid(chainId, lenderKey, collAddr);
|
|
25508
|
+
entry.data[collUid] = {
|
|
25509
|
+
marketUid: collUid,
|
|
25510
|
+
name: "Collateral " + collSymbol,
|
|
25511
|
+
poolId: market.position.toLowerCase(),
|
|
25512
|
+
underlying: collAddr,
|
|
25513
|
+
asset: currencyFor12(collAddr, collDecimals, collSymbol, tokens),
|
|
25514
|
+
totalDeposits: totalColl,
|
|
25515
|
+
totalDebtStable: 0,
|
|
25516
|
+
totalDebt: 0,
|
|
25517
|
+
totalLiquidity: totalColl,
|
|
25518
|
+
borrowLiquidity: 0,
|
|
25519
|
+
totalLiquidityUSD: totalColl * collPrice,
|
|
25520
|
+
borrowLiquidityUSD: 0,
|
|
25521
|
+
totalDepositsUSD: totalColl * collPrice,
|
|
25522
|
+
totalDebtStableUSD: 0,
|
|
25523
|
+
totalDebtUSD: 0,
|
|
25524
|
+
utilization: 0,
|
|
25525
|
+
depositRate: 0,
|
|
25526
|
+
variableBorrowRate: 0,
|
|
25527
|
+
stableBorrowRate: 0,
|
|
25528
|
+
intrinsicYield: 0,
|
|
25529
|
+
rewards: void 0,
|
|
25530
|
+
decimals: collDecimals,
|
|
25531
|
+
config: {
|
|
25532
|
+
0: {
|
|
25533
|
+
category: 0,
|
|
25534
|
+
borrowCollateralFactor: ltvVsMarket,
|
|
25535
|
+
collateralFactor: ltvVsMarket,
|
|
25536
|
+
borrowFactor: 1,
|
|
25537
|
+
// Liquidation is a Dutch auction against the declared price, not a
|
|
25538
|
+
// fixed penalty; the challenger reward (2 %) is the closest
|
|
25539
|
+
// bounded cost and is carried in the descriptor.
|
|
25540
|
+
liquidationPenalty: 0,
|
|
25541
|
+
closeFactor: 1,
|
|
25542
|
+
collateralDisabled: false,
|
|
25543
|
+
debtDisabled: true
|
|
25544
|
+
}
|
|
25545
|
+
},
|
|
25546
|
+
closeFactor: 1,
|
|
25547
|
+
collateralActive: true,
|
|
25548
|
+
borrowingEnabled: false,
|
|
25549
|
+
depositsEnabled: !halted,
|
|
25550
|
+
hasStable: false,
|
|
25551
|
+
isActive: !halted,
|
|
25552
|
+
isFrozen: halted
|
|
25553
|
+
};
|
|
25554
|
+
const loanUid = createMarketUid(chainId, lenderKey, debtAddr);
|
|
25555
|
+
entry.data[loanUid] = {
|
|
25556
|
+
marketUid: loanUid,
|
|
25557
|
+
name: debtSymbol,
|
|
25558
|
+
poolId: cfg.mintingHub.toLowerCase(),
|
|
25559
|
+
underlying: debtAddr,
|
|
25560
|
+
asset: currencyFor12(debtAddr, debtDecimals, debtSymbol, tokens),
|
|
25561
|
+
totalDeposits: 0,
|
|
25562
|
+
totalDebtStable: 0,
|
|
25563
|
+
totalDebt,
|
|
25564
|
+
totalLiquidity: borrowLiquidity,
|
|
25565
|
+
borrowLiquidity,
|
|
25566
|
+
totalLiquidityUSD: borrowLiquidity * debtPrice,
|
|
25567
|
+
borrowLiquidityUSD: borrowLiquidity * debtPrice,
|
|
25568
|
+
totalDepositsUSD: 0,
|
|
25569
|
+
totalDebtStableUSD: 0,
|
|
25570
|
+
totalDebtUSD: totalDebt * debtPrice,
|
|
25571
|
+
utilization: 0,
|
|
25572
|
+
// The earn side is the savings module (savings provider), not a
|
|
25573
|
+
// lending deposit.
|
|
25574
|
+
depositRate: 0,
|
|
25575
|
+
variableBorrowRate: borrowApr,
|
|
25576
|
+
stableBorrowRate: 0,
|
|
25577
|
+
// Per-position fixed rate (hub lead rate + risk premium) — no
|
|
25578
|
+
// utilization curve anywhere in the protocol.
|
|
25579
|
+
rateModel: "protocolSet",
|
|
25580
|
+
// One-off, pro-rata to expiry, charged at mint out of the proceeds.
|
|
25581
|
+
originationFee: upfrontFeePct,
|
|
25582
|
+
intrinsicYield: 0,
|
|
25583
|
+
rewards: void 0,
|
|
25584
|
+
decimals: debtDecimals,
|
|
25585
|
+
config: {
|
|
25586
|
+
0: {
|
|
25587
|
+
category: 0,
|
|
25588
|
+
borrowCollateralFactor: 0,
|
|
25589
|
+
collateralFactor: 0,
|
|
25590
|
+
borrowFactor: 1,
|
|
25591
|
+
liquidationPenalty: 0,
|
|
25592
|
+
closeFactor: 1,
|
|
25593
|
+
collateralDisabled: true,
|
|
25594
|
+
debtDisabled: halted
|
|
25595
|
+
}
|
|
25596
|
+
},
|
|
25597
|
+
closeFactor: 1,
|
|
25598
|
+
collateralActive: false,
|
|
25599
|
+
borrowingEnabled: !halted && !challenged,
|
|
25600
|
+
depositsEnabled: false,
|
|
25601
|
+
hasStable: false,
|
|
25602
|
+
variableBorrowDisabled: halted || challenged,
|
|
25603
|
+
isActive: !halted,
|
|
25604
|
+
isFrozen: halted
|
|
25605
|
+
};
|
|
25606
|
+
entry.params = {
|
|
25607
|
+
market: {
|
|
25608
|
+
lender: lenderKey,
|
|
25609
|
+
name: marketName,
|
|
25610
|
+
loanDecimals: debtDecimals,
|
|
25611
|
+
collateralDecimals: collDecimals,
|
|
25612
|
+
// The original position doubles as the market id.
|
|
25613
|
+
id: market.position.toLowerCase(),
|
|
25614
|
+
lltv: m.price !== null ? m.price.toString() : market.price,
|
|
25615
|
+
// There is no oracle contract — deliberately zero, with the
|
|
25616
|
+
// declared price carried below.
|
|
25617
|
+
oracle: zeroAddress,
|
|
25618
|
+
irm: zeroAddress,
|
|
25619
|
+
collateralAddress: collAddr,
|
|
25620
|
+
loanAddress: debtAddr,
|
|
25621
|
+
// --- Frankencoin descriptor (consumed by the calldata builders,
|
|
25622
|
+
// worker-api resolvers and any quote layer) ---
|
|
25623
|
+
frankencoin: {
|
|
25624
|
+
position: market.position,
|
|
25625
|
+
/** Owner-DECLARED liquidation price (raw, 36-dec scaled). */
|
|
25626
|
+
declaredPrice: m.price !== null ? m.price.toString() : market.price,
|
|
25627
|
+
/** Same, as ZCHF per whole collateral unit. */
|
|
25628
|
+
declaredPriceHuman: declaredPrice,
|
|
25629
|
+
/** `declaredPrice / marketPrice`, UNCLAMPED — the liquidation
|
|
25630
|
+
* signal. `>= 1` means the collateral can no longer be sold at
|
|
25631
|
+
* the declared price, so a challenge would succeed. `undefined`
|
|
25632
|
+
* when we have no market price for the collateral. This is NOT
|
|
25633
|
+
* the health factor: our HF is `mintingCapacity / minted` (the
|
|
25634
|
+
* protocol's own `minted <= coll * price` invariant), which
|
|
25635
|
+
* answers "can I borrow more", not "am I liquidatable". */
|
|
25636
|
+
declaredVsMarket,
|
|
25637
|
+
/** True when the declared price has been reached or passed and a
|
|
25638
|
+
* challenge would therefore clear. Undefined without a market
|
|
25639
|
+
* price. */
|
|
25640
|
+
challengeable: declaredVsMarket === void 0 ? void 0 : declaredVsMarket >= 1,
|
|
25641
|
+
/** ppm withheld into the FPS equity reserve at mint. */
|
|
25642
|
+
reserveContributionPPM: String(reserveContributionPpm),
|
|
25643
|
+
/** ppm one-off upfront interest for minting now. */
|
|
25644
|
+
upfrontFeePPM: m.currentFeePPM !== null ? m.currentFeePPM.toString() : void 0,
|
|
25645
|
+
annualInterestPPM: m.annualInterestPPM !== null ? m.annualInterestPPM.toString() : void 0,
|
|
25646
|
+
riskPremiumPPM: market.riskPremiumPPM,
|
|
25647
|
+
minimumCollateral: market.minimumCollateral,
|
|
25648
|
+
expiration: String(expiration),
|
|
25649
|
+
expired,
|
|
25650
|
+
closed,
|
|
25651
|
+
challengePeriod: market.challengePeriod,
|
|
25652
|
+
challengedAmount: m.challengedAmount !== null ? m.challengedAmount.toString() : void 0,
|
|
25653
|
+
isChallenged: challenged,
|
|
25654
|
+
/** ppm reward paid to a successful challenger (hub constant). */
|
|
25655
|
+
challengerRewardPPM: "20000",
|
|
25656
|
+
version: market.version ?? 2,
|
|
25657
|
+
addresses: {
|
|
25658
|
+
mintingHub: cfg.mintingHub,
|
|
25659
|
+
zchf: cfg.zchf,
|
|
25660
|
+
equity: cfg.equity,
|
|
25661
|
+
roller: cfg.roller,
|
|
25662
|
+
chfUsdFeed: cfg.chfUsdFeed
|
|
25663
|
+
}
|
|
25664
|
+
}
|
|
25665
|
+
}
|
|
25666
|
+
};
|
|
25667
|
+
entry.chainId = chainId;
|
|
25668
|
+
out[lenderKey] = entry;
|
|
25669
|
+
}
|
|
25670
|
+
return out;
|
|
25671
|
+
}
|
|
24439
25672
|
|
|
24440
25673
|
// src/lending/public-data/silo-v2/fetchPublic.ts
|
|
24441
25674
|
var BASE_URL2 = "https://api-v3.silo.finance";
|
|
@@ -25045,8 +26278,12 @@ async function getLenderDataFromApi(lender, chainId, prices, additionalYields, i
|
|
|
25045
26278
|
if (isRiver(lender)) return await fetchRiverMarkets(lender, chainId);
|
|
25046
26279
|
if (isTeller(lender)) return await fetchTellerMarkets(chainId);
|
|
25047
26280
|
if (isInverse(lender)) return await fetchInverseMarkets(lender, chainId);
|
|
26281
|
+
if (isLlamaLend(lender)) return await fetchLlamaLendMarkets(lender, chainId);
|
|
26282
|
+
if (isResupply(lender)) return await fetchResupplyMarkets(lender, chainId);
|
|
25048
26283
|
if (isTermMax(lender)) return await fetchTermMaxMarkets(chainId);
|
|
25049
26284
|
if (isUsdd(lender)) return await fetchUsddMarkets(lender, chainId);
|
|
26285
|
+
if (isFrankencoin(lender))
|
|
26286
|
+
return await fetchFrankencoinMarkets(lender, chainId);
|
|
25050
26287
|
return {};
|
|
25051
26288
|
}
|
|
25052
26289
|
function convertLenderDataFromApi(lender, chainId, data, prices, additionalYields, list = {}) {
|
|
@@ -25108,6 +26345,30 @@ function convertLenderDataFromApi(lender, chainId, data, prices, additionalYield
|
|
|
25108
26345
|
additionalYields,
|
|
25109
26346
|
list
|
|
25110
26347
|
);
|
|
26348
|
+
if (isLlamaLend(lender))
|
|
26349
|
+
return convertLlamaLendMarketsToResponse(
|
|
26350
|
+
data,
|
|
26351
|
+
chainId,
|
|
26352
|
+
prices,
|
|
26353
|
+
additionalYields,
|
|
26354
|
+
list
|
|
26355
|
+
);
|
|
26356
|
+
if (isResupply(lender))
|
|
26357
|
+
return convertResupplyMarketsToResponse(
|
|
26358
|
+
data,
|
|
26359
|
+
chainId,
|
|
26360
|
+
prices,
|
|
26361
|
+
additionalYields,
|
|
26362
|
+
list
|
|
26363
|
+
);
|
|
26364
|
+
if (isFrankencoin(lender))
|
|
26365
|
+
return convertFrankencoinMarketsToResponse(
|
|
26366
|
+
data,
|
|
26367
|
+
chainId,
|
|
26368
|
+
prices,
|
|
26369
|
+
additionalYields,
|
|
26370
|
+
list
|
|
26371
|
+
);
|
|
25111
26372
|
if (isUsdd(lender))
|
|
25112
26373
|
return convertUsddMarketsToResponse(
|
|
25113
26374
|
data,
|
|
@@ -25325,7 +26586,10 @@ function lenderApiOnly(lender, chainId) {
|
|
|
25325
26586
|
if (isTeller(lender)) return true;
|
|
25326
26587
|
if (isInverse(lender)) return true;
|
|
25327
26588
|
if (isTermMax(lender)) return true;
|
|
26589
|
+
if (isResupply(lender)) return true;
|
|
25328
26590
|
if (isUsdd(lender)) return true;
|
|
26591
|
+
if (isFrankencoin(lender)) return true;
|
|
26592
|
+
if (isLlamaLend(lender)) return true;
|
|
25329
26593
|
return false;
|
|
25330
26594
|
}
|
|
25331
26595
|
function lenderApiWithOnChainFallback(lender, chainId) {
|
|
@@ -26477,8 +27741,22 @@ var buildRiverUserCall = (chainId, lender, account) => {
|
|
|
26477
27741
|
});
|
|
26478
27742
|
return calls;
|
|
26479
27743
|
};
|
|
27744
|
+
var LLAMALEND_CALLS_PER_MARKET = 5;
|
|
27745
|
+
var buildLlamaLendUserCall = (chainId, lender, account, spender) => {
|
|
27746
|
+
const cfg = llamaLendConfigFor(lender, chainId);
|
|
27747
|
+
const markets = llamaLendChainData(lender, chainId)?.markets ?? [];
|
|
27748
|
+
if (!cfg || markets.length === 0) return [];
|
|
27749
|
+
const delegate = account;
|
|
27750
|
+
return markets.flatMap((m) => [
|
|
27751
|
+
{ address: m.controller, name: "user_state", params: [account] },
|
|
27752
|
+
{ address: m.controller, name: "health", params: [account, true] },
|
|
27753
|
+
{ address: m.controller, name: "user_prices", params: [account] },
|
|
27754
|
+
{ address: m.amm, name: "read_user_tick_numbers", params: [account] },
|
|
27755
|
+
{ address: m.controller, name: "approval", params: [account, delegate] }
|
|
27756
|
+
]);
|
|
27757
|
+
};
|
|
26480
27758
|
var INVERSE_CALLS_PER_MARKET = 4;
|
|
26481
|
-
var INVERSE_TAIL_CALLS =
|
|
27759
|
+
var INVERSE_TAIL_CALLS = 4;
|
|
26482
27760
|
var proxyInitCode = (impl) => concat([
|
|
26483
27761
|
"0x3d602d80600a3d3981f3363d3d373d3d3d363d73",
|
|
26484
27762
|
impl,
|
|
@@ -26513,21 +27791,136 @@ var buildInverseUserCall = (chainId, lender, account) => {
|
|
|
26513
27791
|
calls.push(
|
|
26514
27792
|
{ address: cfg.dbr, name: "balanceOf", params: [account] },
|
|
26515
27793
|
{ address: cfg.dbr, name: "deficitOf", params: [account] },
|
|
26516
|
-
{ address: cfg.dbr, name: "signedBalanceOf", params: [account] }
|
|
27794
|
+
{ address: cfg.dbr, name: "signedBalanceOf", params: [account] },
|
|
27795
|
+
{ address: cfg.dbr, name: "debts", params: [account] }
|
|
26517
27796
|
);
|
|
26518
27797
|
return calls;
|
|
26519
27798
|
};
|
|
27799
|
+
var RESUPPLY_CALLS_PER_PAIR = 2;
|
|
27800
|
+
var ONE3 = 10n ** 18n;
|
|
27801
|
+
var ROSTER_TTL_MS = 5 * 6e4;
|
|
27802
|
+
var DISCOVERY_TTL_MS = 6e4;
|
|
27803
|
+
var SNAPSHOT_CHUNK = 12;
|
|
27804
|
+
var rosterCache = /* @__PURE__ */ new Map();
|
|
27805
|
+
var discoveryCache2 = /* @__PURE__ */ new Map();
|
|
27806
|
+
var rosterKey = (chainId, lender) => `${chainId}:${lender}`;
|
|
27807
|
+
var discoveryKey = (chainId, lender, account) => `${chainId}:${lender}:${account.toLowerCase()}`;
|
|
27808
|
+
var getCachedResupplyDiscovery = (chainId, lender, account) => discoveryCache2.get(discoveryKey(chainId, lender, account));
|
|
27809
|
+
var fetchRoster = async (chainId, lender, registry, allowlist) => {
|
|
27810
|
+
const cached = rosterCache.get(rosterKey(chainId, lender));
|
|
27811
|
+
if (cached && Date.now() - cached.at < ROSTER_TTL_MS) return cached;
|
|
27812
|
+
let addresses = [];
|
|
27813
|
+
const [raw] = await multicallRetryUniversal({
|
|
27814
|
+
chain: chainId,
|
|
27815
|
+
calls: [{ address: registry, name: "getAllPairAddresses", params: [] }],
|
|
27816
|
+
abi: ResupplyRegistryAbi,
|
|
27817
|
+
allowFailure: true
|
|
27818
|
+
});
|
|
27819
|
+
if (Array.isArray(raw)) {
|
|
27820
|
+
addresses = raw.filter(
|
|
27821
|
+
(a) => typeof a === "string" && a.startsWith("0x")
|
|
27822
|
+
);
|
|
27823
|
+
}
|
|
27824
|
+
if (allowlist && allowlist.length > 0) {
|
|
27825
|
+
const allow = new Set(allowlist.map((p) => p.toLowerCase()));
|
|
27826
|
+
addresses = addresses.filter((p) => allow.has(p.toLowerCase()));
|
|
27827
|
+
}
|
|
27828
|
+
if (addresses.length === 0) {
|
|
27829
|
+
const empty = { pairs: [], at: Date.now() };
|
|
27830
|
+
rosterCache.set(rosterKey(chainId, lender), empty);
|
|
27831
|
+
return empty;
|
|
27832
|
+
}
|
|
27833
|
+
const cols = await multicallRetryUniversal({
|
|
27834
|
+
chain: chainId,
|
|
27835
|
+
calls: addresses.map((pair) => ({
|
|
27836
|
+
address: pair,
|
|
27837
|
+
name: "collateral",
|
|
27838
|
+
params: []
|
|
27839
|
+
})),
|
|
27840
|
+
abi: addresses.map(() => ResupplyPairAbi),
|
|
27841
|
+
allowFailure: true
|
|
27842
|
+
});
|
|
27843
|
+
const pairs = addresses.map((pair, i) => ({ pair, collateral: cols[i] })).filter(
|
|
27844
|
+
(p) => typeof p.collateral === "string" && p.collateral.startsWith("0x")
|
|
27845
|
+
);
|
|
27846
|
+
const roster = { pairs, at: Date.now() };
|
|
27847
|
+
rosterCache.set(rosterKey(chainId, lender), roster);
|
|
27848
|
+
return roster;
|
|
27849
|
+
};
|
|
27850
|
+
var discoverPositions = async (chainId, pairs, account) => {
|
|
27851
|
+
const active = [];
|
|
27852
|
+
for (let i = 0; i < pairs.length; i += SNAPSHOT_CHUNK) {
|
|
27853
|
+
const slice2 = pairs.slice(i, i + SNAPSHOT_CHUNK);
|
|
27854
|
+
let res = [];
|
|
27855
|
+
try {
|
|
27856
|
+
res = await multicallRetryUniversal({
|
|
27857
|
+
chain: chainId,
|
|
27858
|
+
calls: slice2.map((p) => ({
|
|
27859
|
+
address: p.pair,
|
|
27860
|
+
name: "getUserSnapshot",
|
|
27861
|
+
params: [account]
|
|
27862
|
+
})),
|
|
27863
|
+
abi: slice2.map(() => ResupplyPairAbi),
|
|
27864
|
+
allowFailure: true
|
|
27865
|
+
});
|
|
27866
|
+
} catch {
|
|
27867
|
+
continue;
|
|
27868
|
+
}
|
|
27869
|
+
slice2.forEach((p, j) => {
|
|
27870
|
+
const snap = res[j];
|
|
27871
|
+
if (!Array.isArray(snap)) return;
|
|
27872
|
+
const borrowShares = typeof snap[0] === "bigint" ? snap[0] : 0n;
|
|
27873
|
+
const collateralShares = typeof snap[1] === "bigint" ? snap[1] : 0n;
|
|
27874
|
+
if (borrowShares === 0n && collateralShares === 0n) return;
|
|
27875
|
+
active.push({ ...p, borrowShares, collateralShares });
|
|
27876
|
+
});
|
|
27877
|
+
}
|
|
27878
|
+
return active;
|
|
27879
|
+
};
|
|
27880
|
+
var buildResupplyUserCall = async (chainId, lender, account) => {
|
|
27881
|
+
const cfg = resupplyConfigFor(lender, chainId);
|
|
27882
|
+
const key = discoveryKey(chainId, lender, account);
|
|
27883
|
+
const stash = (positions2) => discoveryCache2.set(key, { positions: positions2, at: Date.now() });
|
|
27884
|
+
if (!cfg?.registry) {
|
|
27885
|
+
stash([]);
|
|
27886
|
+
return [];
|
|
27887
|
+
}
|
|
27888
|
+
let roster;
|
|
27889
|
+
try {
|
|
27890
|
+
roster = await fetchRoster(chainId, lender, cfg.registry, cfg.pairAllowlist);
|
|
27891
|
+
} catch {
|
|
27892
|
+
return [];
|
|
27893
|
+
}
|
|
27894
|
+
if (roster.pairs.length === 0) {
|
|
27895
|
+
stash([]);
|
|
27896
|
+
return [];
|
|
27897
|
+
}
|
|
27898
|
+
const cachedDiscovery = discoveryCache2.get(key);
|
|
27899
|
+
const positions = cachedDiscovery && Date.now() - cachedDiscovery.at < DISCOVERY_TTL_MS ? cachedDiscovery.positions : await discoverPositions(chainId, roster.pairs, account);
|
|
27900
|
+
stash(positions);
|
|
27901
|
+
if (positions.length === 0) return [];
|
|
27902
|
+
return positions.flatMap(({ pair, collateral }) => [
|
|
27903
|
+
// Totals with interest previewed — the denominator for the share→amount
|
|
27904
|
+
// conversion the parser does locally.
|
|
27905
|
+
{ address: pair, name: "getPairAccounting", params: [] },
|
|
27906
|
+
{ address: collateral, name: "convertToAssets", params: [ONE3] }
|
|
27907
|
+
]);
|
|
27908
|
+
};
|
|
27909
|
+
function __resetResupplyUserCaches() {
|
|
27910
|
+
rosterCache.clear();
|
|
27911
|
+
discoveryCache2.clear();
|
|
27912
|
+
}
|
|
26520
27913
|
var USDD_CALLS_PER_CDP = 1;
|
|
26521
27914
|
var MAX_CDP_WALK = 64;
|
|
26522
27915
|
var CACHE_TTL_MS2 = 5 * 6e4;
|
|
26523
|
-
var
|
|
27916
|
+
var discoveryCache3 = /* @__PURE__ */ new Map();
|
|
26524
27917
|
var cacheKey2 = (chainId, account) => `${chainId}:${account.toLowerCase()}`;
|
|
26525
27918
|
var getCachedUsddCdps = (chainId, account) => {
|
|
26526
|
-
const hit =
|
|
27919
|
+
const hit = discoveryCache3.get(cacheKey2(chainId, account));
|
|
26527
27920
|
if (!hit || Date.now() - hit.at > CACHE_TTL_MS2) return void 0;
|
|
26528
27921
|
return hit;
|
|
26529
27922
|
};
|
|
26530
|
-
var
|
|
27923
|
+
var big2 = (v) => {
|
|
26531
27924
|
try {
|
|
26532
27925
|
if (typeof v === "bigint") return v;
|
|
26533
27926
|
if (typeof v === "number" || typeof v === "string") return BigInt(v);
|
|
@@ -26539,7 +27932,7 @@ var field6 = (res, name, idx) => res?.[name] ?? res?.[idx];
|
|
|
26539
27932
|
var buildUsddUserCall = async (chainId, lender, account) => {
|
|
26540
27933
|
const cfg = usddConfigFor(lender, chainId);
|
|
26541
27934
|
const markets = usddChainData(lender, chainId)?.markets ?? [];
|
|
26542
|
-
const stash = (d) =>
|
|
27935
|
+
const stash = (d) => discoveryCache3.set(cacheKey2(chainId, account), d);
|
|
26543
27936
|
if (!cfg || markets.length === 0) {
|
|
26544
27937
|
stash({ cdps: [], ilks: [], at: Date.now() });
|
|
26545
27938
|
return [];
|
|
@@ -26558,7 +27951,7 @@ var buildUsddUserCall = async (chainId, lender, account) => {
|
|
|
26558
27951
|
],
|
|
26559
27952
|
allowFailure: false
|
|
26560
27953
|
});
|
|
26561
|
-
owners.push({ owner: account, count:
|
|
27954
|
+
owners.push({ owner: account, count: big2(rawCount), cursor: big2(rawFirst) });
|
|
26562
27955
|
const proxy = String(rawProxy ?? zero);
|
|
26563
27956
|
if (proxy.toLowerCase() !== zero) {
|
|
26564
27957
|
const [pCount, pFirst] = await multicallRetryUniversal({
|
|
@@ -26570,7 +27963,7 @@ var buildUsddUserCall = async (chainId, lender, account) => {
|
|
|
26570
27963
|
],
|
|
26571
27964
|
allowFailure: false
|
|
26572
27965
|
});
|
|
26573
|
-
owners.push({ owner: proxy, count:
|
|
27966
|
+
owners.push({ owner: proxy, count: big2(pCount), cursor: big2(pFirst) });
|
|
26574
27967
|
}
|
|
26575
27968
|
} catch {
|
|
26576
27969
|
return [];
|
|
@@ -26611,7 +28004,7 @@ var buildUsddUserCall = async (chainId, lender, account) => {
|
|
|
26611
28004
|
if (curated.has(ilk)) {
|
|
26612
28005
|
cdps.push({ cdpId: cursor.toString(), urn: String(urn), ilk });
|
|
26613
28006
|
}
|
|
26614
|
-
cursor =
|
|
28007
|
+
cursor = big2(field6(link, "next", 1));
|
|
26615
28008
|
}
|
|
26616
28009
|
}
|
|
26617
28010
|
} catch {
|
|
@@ -26634,12 +28027,83 @@ var buildUsddUserCall = async (chainId, lender, account) => {
|
|
|
26634
28027
|
}
|
|
26635
28028
|
return calls;
|
|
26636
28029
|
};
|
|
28030
|
+
var FRANKENCOIN_CALLS_PER_POSITION = 6;
|
|
28031
|
+
var BOOK_TTL_MS = 5 * 6e4;
|
|
28032
|
+
var DISCOVERY_TTL_MS2 = 5 * 6e4;
|
|
28033
|
+
var API_BASE = "https://api.frankencoin.com";
|
|
28034
|
+
var bookCache;
|
|
28035
|
+
var fetchBook = async () => {
|
|
28036
|
+
if (bookCache && Date.now() - bookCache.at < BOOK_TTL_MS) {
|
|
28037
|
+
return bookCache.entries;
|
|
28038
|
+
}
|
|
28039
|
+
const res = await fetch(`${API_BASE}/positions/open`, {
|
|
28040
|
+
headers: { Accept: "application/json" }
|
|
28041
|
+
});
|
|
28042
|
+
if (!res.ok) throw new Error(`frankencoin book: ${res.status}`);
|
|
28043
|
+
const data = await res.json();
|
|
28044
|
+
const entries = Object.values(data?.map ?? {}).map((p) => ({
|
|
28045
|
+
position: String(p.position).toLowerCase(),
|
|
28046
|
+
owner: String(p.owner).toLowerCase(),
|
|
28047
|
+
// An original is its own parent.
|
|
28048
|
+
original: String(p.original ?? p.position).toLowerCase(),
|
|
28049
|
+
version: Number(p.version),
|
|
28050
|
+
closed: !!p.closed,
|
|
28051
|
+
denied: !!p.denied
|
|
28052
|
+
}));
|
|
28053
|
+
bookCache = { at: Date.now(), entries };
|
|
28054
|
+
return entries;
|
|
28055
|
+
};
|
|
28056
|
+
var discoveryCache4 = /* @__PURE__ */ new Map();
|
|
28057
|
+
var cacheKey3 = (chainId, account) => `${chainId}:${account.toLowerCase()}`;
|
|
28058
|
+
var getCachedFrankencoinPositions = (chainId, account) => {
|
|
28059
|
+
const hit = discoveryCache4.get(cacheKey3(chainId, account));
|
|
28060
|
+
if (!hit || Date.now() - hit.at > DISCOVERY_TTL_MS2) return void 0;
|
|
28061
|
+
return hit;
|
|
28062
|
+
};
|
|
28063
|
+
var buildFrankencoinUserCall = async (chainId, lender, account) => {
|
|
28064
|
+
const cfg = frankencoinConfigFor(lender, chainId);
|
|
28065
|
+
const markets = frankencoinChainData(lender, chainId)?.markets ?? [];
|
|
28066
|
+
const stash = (d) => discoveryCache4.set(cacheKey3(chainId, account), d);
|
|
28067
|
+
if (!cfg || markets.length === 0) {
|
|
28068
|
+
stash({ positions: [], at: Date.now() });
|
|
28069
|
+
return [];
|
|
28070
|
+
}
|
|
28071
|
+
const curated = new Set(markets.map((m) => m.position.toLowerCase()));
|
|
28072
|
+
const lower3 = account.toLowerCase();
|
|
28073
|
+
let book = [];
|
|
28074
|
+
try {
|
|
28075
|
+
book = await fetchBook();
|
|
28076
|
+
} catch {
|
|
28077
|
+
return [];
|
|
28078
|
+
}
|
|
28079
|
+
const positions = book.filter(
|
|
28080
|
+
(e) => e.owner === lower3 && e.version === 2 && !e.closed && !e.denied && curated.has(e.original)
|
|
28081
|
+
).map((e) => ({ position: e.position, original: e.original }));
|
|
28082
|
+
stash({ positions, at: Date.now() });
|
|
28083
|
+
if (positions.length === 0) return [];
|
|
28084
|
+
const collByOriginal = new Map(
|
|
28085
|
+
markets.map((m) => [m.position.toLowerCase(), m.collToken])
|
|
28086
|
+
);
|
|
28087
|
+
const calls = [];
|
|
28088
|
+
for (const p of positions) {
|
|
28089
|
+
const coll = collByOriginal.get(p.original);
|
|
28090
|
+
calls.push(
|
|
28091
|
+
{ address: p.position, name: "owner", params: [] },
|
|
28092
|
+
{ address: p.position, name: "minted", params: [] },
|
|
28093
|
+
{ address: p.position, name: "price", params: [] },
|
|
28094
|
+
{ address: p.position, name: "expiration", params: [] },
|
|
28095
|
+
{ address: p.position, name: "challengedAmount", params: [] },
|
|
28096
|
+
{ address: coll, name: "balanceOf", params: [p.position] }
|
|
28097
|
+
);
|
|
28098
|
+
}
|
|
28099
|
+
return calls;
|
|
28100
|
+
};
|
|
26637
28101
|
var TELLER_CALLS_PER_BID = 4;
|
|
26638
28102
|
var CACHE_TTL_MS3 = 5 * 6e4;
|
|
26639
|
-
var
|
|
26640
|
-
var
|
|
28103
|
+
var discoveryCache5 = /* @__PURE__ */ new Map();
|
|
28104
|
+
var cacheKey4 = (chainId, account) => `${chainId}:${account.toLowerCase()}`;
|
|
26641
28105
|
var getCachedTellerBids = (chainId, account) => {
|
|
26642
|
-
const hit =
|
|
28106
|
+
const hit = discoveryCache5.get(cacheKey4(chainId, account));
|
|
26643
28107
|
if (!hit || Date.now() - hit.at > CACHE_TTL_MS3) return void 0;
|
|
26644
28108
|
return hit;
|
|
26645
28109
|
};
|
|
@@ -26680,7 +28144,7 @@ var buildTellerUserCall = async (chainId, _lender, account) => {
|
|
|
26680
28144
|
return [];
|
|
26681
28145
|
}
|
|
26682
28146
|
if (ids.length === 0) {
|
|
26683
|
-
|
|
28147
|
+
discoveryCache5.set(cacheKey4(chainId, account), { bids: [], at: Date.now() });
|
|
26684
28148
|
return [];
|
|
26685
28149
|
}
|
|
26686
28150
|
const poolByAddr = /* @__PURE__ */ new Map();
|
|
@@ -26707,7 +28171,7 @@ var buildTellerUserCall = async (chainId, _lender, account) => {
|
|
|
26707
28171
|
const pool = poolByAddr.get(lenderAddr);
|
|
26708
28172
|
if (pool) kept.push({ bidId: id, pool });
|
|
26709
28173
|
});
|
|
26710
|
-
|
|
28174
|
+
discoveryCache5.set(cacheKey4(chainId, account), { bids: kept, at: Date.now() });
|
|
26711
28175
|
if (kept.length === 0) return [];
|
|
26712
28176
|
const ts = nowSec5();
|
|
26713
28177
|
const calls = [];
|
|
@@ -26733,10 +28197,10 @@ var buildTellerUserCall = async (chainId, _lender, account) => {
|
|
|
26733
28197
|
};
|
|
26734
28198
|
var TERMMAX_CALLS_PER_ACCOUNT = 1;
|
|
26735
28199
|
var CACHE_TTL_MS4 = 5 * 6e4;
|
|
26736
|
-
var
|
|
26737
|
-
var
|
|
28200
|
+
var discoveryCache6 = /* @__PURE__ */ new Map();
|
|
28201
|
+
var cacheKey5 = (chainId, account) => `${chainId}:${account.toLowerCase()}`;
|
|
26738
28202
|
var getCachedTermMaxDiscovery = (chainId, account) => {
|
|
26739
|
-
const hit =
|
|
28203
|
+
const hit = discoveryCache6.get(cacheKey5(chainId, account));
|
|
26740
28204
|
if (!hit || Date.now() - hit.at > CACHE_TTL_MS4) return void 0;
|
|
26741
28205
|
return hit;
|
|
26742
28206
|
};
|
|
@@ -26752,11 +28216,11 @@ var buildTermMaxUserCall = async (chainId, _lender, account) => {
|
|
|
26752
28216
|
}
|
|
26753
28217
|
}
|
|
26754
28218
|
if (markets.length === 0) {
|
|
26755
|
-
|
|
28219
|
+
discoveryCache6.set(cacheKey5(chainId, account), { markets: [], at: Date.now() });
|
|
26756
28220
|
return [];
|
|
26757
28221
|
}
|
|
26758
28222
|
markets = [...markets].sort((a, b) => a.market.localeCompare(b.market));
|
|
26759
|
-
|
|
28223
|
+
discoveryCache6.set(cacheKey5(chainId, account), { markets, at: Date.now() });
|
|
26760
28224
|
return [
|
|
26761
28225
|
{
|
|
26762
28226
|
address: proto.viewer,
|
|
@@ -26789,7 +28253,12 @@ async function buildUserCall(chainId, lender, account, params, getClient) {
|
|
|
26789
28253
|
if (isTeller(lender)) return buildTellerUserCall(chainId, lender, account);
|
|
26790
28254
|
if (isTermMax(lender)) return buildTermMaxUserCall(chainId, lender, account);
|
|
26791
28255
|
if (isInverse(lender)) return buildInverseUserCall(chainId, lender, account);
|
|
28256
|
+
if (isLlamaLend(lender))
|
|
28257
|
+
return buildLlamaLendUserCall(chainId, lender, account);
|
|
28258
|
+
if (isResupply(lender)) return buildResupplyUserCall(chainId, lender, account);
|
|
26792
28259
|
if (isUsdd(lender)) return buildUsddUserCall(chainId, lender, account);
|
|
28260
|
+
if (isFrankencoin(lender))
|
|
28261
|
+
return buildFrankencoinUserCall(chainId, lender, account);
|
|
26793
28262
|
if (isCompoundV3Type(lender))
|
|
26794
28263
|
return buildCompoundV3UserCall(chainId, lender, account);
|
|
26795
28264
|
if (isEulerType(lender))
|
|
@@ -26826,10 +28295,12 @@ function organizeUserQueries(queries) {
|
|
|
26826
28295
|
const teller = queries.filter((q) => isTeller(q.lender));
|
|
26827
28296
|
const termMax = queries.filter((q) => isTermMax(q.lender));
|
|
26828
28297
|
const usdd = queries.filter((q) => isUsdd(q.lender));
|
|
26829
|
-
|
|
28298
|
+
const llamaLend = queries.filter((q) => isLlamaLend(q.lender));
|
|
28299
|
+
const frankencoin = queries.filter((q) => isFrankencoin(q.lender));
|
|
28300
|
+
if (morphos.length === 0 && gearbox.length === 0 && midnight.length === 0 && term.length === 0 && exactly.length === 0 && liquity.length === 0 && river.length === 0 && teller.length === 0 && termMax.length === 0 && usdd.length === 0 && frankencoin.length === 0 && llamaLend.length === 0)
|
|
26830
28301
|
return queries;
|
|
26831
28302
|
const others = queries.filter(
|
|
26832
|
-
(q) => !isMorphoType(q.lender) && !isGearboxV3(q.lender) && !isMidnight(q.lender) && !isTerm(q.lender) && !isExactly(q.lender) && !isLiquityFamily(q.lender) && !isRiver(q.lender) && !isTeller(q.lender) && !isTermMax(q.lender) && !isUsdd(q.lender)
|
|
28303
|
+
(q) => !isMorphoType(q.lender) && !isGearboxV3(q.lender) && !isMidnight(q.lender) && !isTerm(q.lender) && !isExactly(q.lender) && !isLiquityFamily(q.lender) && !isRiver(q.lender) && !isTeller(q.lender) && !isTermMax(q.lender) && !isUsdd(q.lender) && !isFrankencoin(q.lender) && !isLlamaLend(q.lender)
|
|
26833
28304
|
);
|
|
26834
28305
|
const morphoBlue = morphos.filter((q) => q.lender.startsWith("MORPHO_BLUE"));
|
|
26835
28306
|
const moolah = morphos.filter((q) => q.lender.startsWith("LISTA_DAO"));
|
|
@@ -26890,6 +28361,14 @@ function organizeUserQueries(queries) {
|
|
|
26890
28361
|
assets: void 0
|
|
26891
28362
|
});
|
|
26892
28363
|
}
|
|
28364
|
+
if (frankencoin.length > 0) {
|
|
28365
|
+
result.push({
|
|
28366
|
+
lender: Lender.FRANKENCOIN,
|
|
28367
|
+
account: frankencoin[0].account,
|
|
28368
|
+
params: frankencoin.map((p) => p.lender),
|
|
28369
|
+
assets: void 0
|
|
28370
|
+
});
|
|
28371
|
+
}
|
|
26893
28372
|
if (usdd.length > 0) {
|
|
26894
28373
|
result.push({
|
|
26895
28374
|
lender: Lender.USDD,
|
|
@@ -26898,6 +28377,14 @@ function organizeUserQueries(queries) {
|
|
|
26898
28377
|
assets: void 0
|
|
26899
28378
|
});
|
|
26900
28379
|
}
|
|
28380
|
+
if (llamaLend.length > 0) {
|
|
28381
|
+
result.push({
|
|
28382
|
+
lender: Lender.LLAMALEND,
|
|
28383
|
+
account: llamaLend[0].account,
|
|
28384
|
+
params: llamaLend.map((p) => p.lender),
|
|
28385
|
+
assets: void 0
|
|
28386
|
+
});
|
|
28387
|
+
}
|
|
26901
28388
|
if (teller.length > 0) {
|
|
26902
28389
|
result.push({
|
|
26903
28390
|
lender: Lender.TELLER,
|
|
@@ -29417,7 +30904,7 @@ function toDetail(positions, kind, now, penaltyRate, penaltyApr) {
|
|
|
29417
30904
|
};
|
|
29418
30905
|
});
|
|
29419
30906
|
}
|
|
29420
|
-
var getExactlyUserDataConverter = (_lender, chainId, account, meta
|
|
30907
|
+
var getExactlyUserDataConverter = (_lender, chainId, account, meta) => {
|
|
29421
30908
|
const expected = exactlyConfig()?.[chainId]?.previewer ? 1 : 0;
|
|
29422
30909
|
return [
|
|
29423
30910
|
(data) => {
|
|
@@ -29426,69 +30913,32 @@ var getExactlyUserDataConverter = (_lender, chainId, account, meta, requestedLen
|
|
|
29426
30913
|
if (!res || res === "0x" || !Array.isArray(res)) return void 0;
|
|
29427
30914
|
const markets = res;
|
|
29428
30915
|
const now = nowSec6();
|
|
29429
|
-
const
|
|
29430
|
-
|
|
29431
|
-
);
|
|
29432
|
-
const
|
|
29433
|
-
|
|
29434
|
-
|
|
29435
|
-
const collUid = createMarketUid(chainId, lenderKey, collAddr);
|
|
29436
|
-
const collMeta = metaMap[collUid];
|
|
29437
|
-
const collDec = collMeta?.asset?.decimals ?? c.decimals;
|
|
29438
|
-
const collDisplayPrice = collMeta ? getDisplayPrice(collMeta) : 0;
|
|
29439
|
-
const collOraclePrice = collMeta ? getOraclePrice(collMeta) : 0;
|
|
29440
|
-
const collPriceHist = collMeta?.price?.priceUsd24h ?? collDisplayPrice;
|
|
29441
|
-
const collStr = parseRawAmount(cDeposit.toString(), collDec);
|
|
29442
|
-
const collNum = Number(collStr);
|
|
29443
|
-
return {
|
|
29444
|
-
uid: collUid,
|
|
29445
|
-
usd24h: collNum * collPriceHist,
|
|
29446
|
-
row: {
|
|
29447
|
-
marketUid: collUid,
|
|
29448
|
-
underlying: collAddr,
|
|
29449
|
-
deposits: collStr,
|
|
29450
|
-
debt: "0",
|
|
29451
|
-
debtStable: "0",
|
|
29452
|
-
depositsUSD: collNum * collDisplayPrice,
|
|
29453
|
-
debtUSD: 0,
|
|
29454
|
-
debtStableUSD: 0,
|
|
29455
|
-
depositsUSDOracle: collNum * collOraclePrice,
|
|
29456
|
-
debtUSDOracle: 0,
|
|
29457
|
-
debtStableUSDOracle: 0,
|
|
29458
|
-
stableBorrowRate: "0",
|
|
29459
|
-
collateralEnabled: true,
|
|
29460
|
-
claimableRewards: 0,
|
|
29461
|
-
// The SAME deposit reports as the own-asset row under its own
|
|
29462
|
-
// market key — cross-key aggregation must skip flagged rows.
|
|
29463
|
-
crossCollateral: true
|
|
29464
|
-
}
|
|
29465
|
-
};
|
|
29466
|
-
};
|
|
29467
|
-
const out = {};
|
|
30916
|
+
const lenderKey = EXACTLY_LENDER_KEY;
|
|
30917
|
+
const metaMap = meta?.[lenderKey];
|
|
30918
|
+
if (!metaMap) return void 0;
|
|
30919
|
+
const posData = {};
|
|
30920
|
+
let depositsUSD24h = 0;
|
|
30921
|
+
let debtUSD24h = 0;
|
|
29468
30922
|
for (const m of markets) {
|
|
29469
|
-
const lenderKey = exactlyLenderKey(m.market);
|
|
29470
|
-
const metaMap = meta?.[lenderKey];
|
|
29471
|
-
if (!metaMap) continue;
|
|
29472
30923
|
const assetAddr = m.asset.toLowerCase();
|
|
29473
30924
|
const loanUid = createMarketUid(chainId, lenderKey, assetAddr);
|
|
29474
30925
|
const loanMeta = metaMap[loanUid];
|
|
29475
30926
|
const decimals = loanMeta?.asset?.decimals ?? m.decimals;
|
|
29476
|
-
const
|
|
29477
|
-
const
|
|
29478
|
-
const
|
|
30927
|
+
const displayPrice = loanMeta ? getDisplayPrice(loanMeta) : 0;
|
|
30928
|
+
const oraclePrice = loanMeta ? getOraclePrice(loanMeta) : 0;
|
|
30929
|
+
const priceHist = loanMeta?.price?.priceUsd24h ?? displayPrice;
|
|
29479
30930
|
const fixedDebtUnits = sumPreview(m.fixedBorrowPositions);
|
|
29480
30931
|
const depositUnits = m.floatingDepositAssets + sumPreview(m.fixedDepositPositions);
|
|
29481
30932
|
const debtUnits = m.floatingBorrowAssets + fixedDebtUnits;
|
|
29482
30933
|
if (depositUnits === 0n && debtUnits === 0n) continue;
|
|
29483
30934
|
const depositsStr = parseRawAmount(depositUnits.toString(), decimals);
|
|
29484
30935
|
const depositsNum = Number(depositsStr);
|
|
29485
|
-
const debtStr = parseRawAmount(debtUnits.toString(), decimals);
|
|
29486
|
-
const debtNum = Number(debtStr);
|
|
29487
30936
|
const floatingDebtStr = parseRawAmount(
|
|
29488
30937
|
m.floatingBorrowAssets.toString(),
|
|
29489
30938
|
decimals
|
|
29490
30939
|
);
|
|
29491
30940
|
const fixedDebtStr = parseRawAmount(fixedDebtUnits.toString(), decimals);
|
|
30941
|
+
const debtNum = Number(floatingDebtStr) + Number(fixedDebtStr);
|
|
29492
30942
|
const penaltyApr = exactlyPenaltyRateToAprPercent(m.penaltyRate);
|
|
29493
30943
|
const fixedPositions = [
|
|
29494
30944
|
...toDetail(
|
|
@@ -29506,21 +30956,23 @@ var getExactlyUserDataConverter = (_lender, chainId, account, meta, requestedLen
|
|
|
29506
30956
|
penaltyApr
|
|
29507
30957
|
)
|
|
29508
30958
|
];
|
|
29509
|
-
|
|
29510
|
-
|
|
30959
|
+
depositsUSD24h += depositsNum * priceHist;
|
|
30960
|
+
debtUSD24h += debtNum * priceHist;
|
|
29511
30961
|
posData[loanUid] = {
|
|
29512
30962
|
marketUid: loanUid,
|
|
29513
30963
|
underlying: assetAddr,
|
|
29514
30964
|
deposits: depositsStr,
|
|
29515
30965
|
debt: floatingDebtStr,
|
|
29516
30966
|
debtStable: fixedDebtStr,
|
|
29517
|
-
depositsUSD: depositsNum *
|
|
29518
|
-
debtUSD: Number(floatingDebtStr) *
|
|
29519
|
-
debtStableUSD: Number(fixedDebtStr) *
|
|
29520
|
-
depositsUSDOracle: depositsNum *
|
|
29521
|
-
debtUSDOracle: Number(floatingDebtStr) *
|
|
29522
|
-
debtStableUSDOracle: Number(fixedDebtStr) *
|
|
30967
|
+
depositsUSD: depositsNum * displayPrice,
|
|
30968
|
+
debtUSD: Number(floatingDebtStr) * displayPrice,
|
|
30969
|
+
debtStableUSD: Number(fixedDebtStr) * displayPrice,
|
|
30970
|
+
depositsUSDOracle: depositsNum * oraclePrice,
|
|
30971
|
+
debtUSDOracle: Number(floatingDebtStr) * oraclePrice,
|
|
30972
|
+
debtStableUSDOracle: Number(fixedDebtStr) * oraclePrice,
|
|
29523
30973
|
stableBorrowRate: "0",
|
|
30974
|
+
// The Auditor's per-asset `enterMarket` flag: only entered deposits
|
|
30975
|
+
// back debt. A deposit with this false is inert collateral-wise.
|
|
29524
30976
|
collateralEnabled: m.isCollateral,
|
|
29525
30977
|
claimableRewards: 0,
|
|
29526
30978
|
// Per-maturity fixed-position detail (survives to the output — the
|
|
@@ -29544,10 +30996,10 @@ var getExactlyUserDataConverter = (_lender, chainId, account, meta, requestedLen
|
|
|
29544
30996
|
debtStable: trancheStr,
|
|
29545
30997
|
depositsUSD: 0,
|
|
29546
30998
|
debtUSD: 0,
|
|
29547
|
-
debtStableUSD: Number(trancheStr) *
|
|
30999
|
+
debtStableUSD: Number(trancheStr) * displayPrice,
|
|
29548
31000
|
depositsUSDOracle: 0,
|
|
29549
31001
|
debtUSDOracle: 0,
|
|
29550
|
-
debtStableUSDOracle: Number(trancheStr) *
|
|
31002
|
+
debtStableUSDOracle: Number(trancheStr) * oraclePrice,
|
|
29551
31003
|
collateralEnabled: false,
|
|
29552
31004
|
claimableRewards: 0,
|
|
29553
31005
|
term: {
|
|
@@ -29578,64 +31030,30 @@ var getExactlyUserDataConverter = (_lender, chainId, account, meta, requestedLen
|
|
|
29578
31030
|
}
|
|
29579
31031
|
};
|
|
29580
31032
|
}
|
|
29581
|
-
for (const c of enteredCollateral) {
|
|
29582
|
-
if (c.market.toLowerCase() === m.market.toLowerCase()) continue;
|
|
29583
|
-
const { uid, usd24h, row } = collateralRow(c, lenderKey, metaMap);
|
|
29584
|
-
posData[uid] = row;
|
|
29585
|
-
depositsUSD24h += usd24h;
|
|
29586
|
-
}
|
|
29587
|
-
const userData = createMultiAccountTypeUserState(
|
|
29588
|
-
{
|
|
29589
|
-
chainId,
|
|
29590
|
-
account,
|
|
29591
|
-
lendingPositions: { "0": posData },
|
|
29592
|
-
modes: { "0": 0 }
|
|
29593
|
-
},
|
|
29594
|
-
metaMap,
|
|
29595
|
-
{
|
|
29596
|
-
"0": {
|
|
29597
|
-
totalDeposits24h: depositsUSD24h,
|
|
29598
|
-
totalDebt24h: debtNum * loanPriceHist
|
|
29599
|
-
}
|
|
29600
|
-
}
|
|
29601
|
-
);
|
|
29602
|
-
if (userData && userData.data.length > 0) out[lenderKey] = userData;
|
|
29603
31033
|
}
|
|
29604
|
-
if (
|
|
29605
|
-
|
|
29606
|
-
|
|
29607
|
-
|
|
29608
|
-
|
|
29609
|
-
|
|
29610
|
-
|
|
29611
|
-
|
|
29612
|
-
|
|
29613
|
-
|
|
29614
|
-
|
|
29615
|
-
|
|
29616
|
-
|
|
29617
|
-
depositsUSD24h += usd24h;
|
|
31034
|
+
if (Object.keys(posData).length === 0) return void 0;
|
|
31035
|
+
const userData = createMultiAccountTypeUserState(
|
|
31036
|
+
{
|
|
31037
|
+
chainId,
|
|
31038
|
+
account,
|
|
31039
|
+
lendingPositions: { "0": posData },
|
|
31040
|
+
modes: { "0": 0 }
|
|
31041
|
+
},
|
|
31042
|
+
metaMap,
|
|
31043
|
+
{
|
|
31044
|
+
"0": {
|
|
31045
|
+
totalDeposits24h: depositsUSD24h,
|
|
31046
|
+
totalDebt24h: debtUSD24h
|
|
29618
31047
|
}
|
|
29619
|
-
if (Object.keys(posData).length === 0) continue;
|
|
29620
|
-
const userData = createMultiAccountTypeUserState(
|
|
29621
|
-
{
|
|
29622
|
-
chainId,
|
|
29623
|
-
account,
|
|
29624
|
-
lendingPositions: { "0": posData },
|
|
29625
|
-
modes: { "0": 0 }
|
|
29626
|
-
},
|
|
29627
|
-
metaMap,
|
|
29628
|
-
{ "0": { totalDeposits24h: depositsUSD24h, totalDebt24h: 0 } }
|
|
29629
|
-
);
|
|
29630
|
-
if (userData && userData.data.length > 0) out[req] = userData;
|
|
29631
31048
|
}
|
|
29632
|
-
|
|
29633
|
-
|
|
31049
|
+
);
|
|
31050
|
+
if (!userData || userData.data.length === 0) return void 0;
|
|
31051
|
+
return { [lenderKey]: userData };
|
|
29634
31052
|
},
|
|
29635
31053
|
expected
|
|
29636
31054
|
];
|
|
29637
31055
|
};
|
|
29638
|
-
var
|
|
31056
|
+
var big3 = (v) => {
|
|
29639
31057
|
try {
|
|
29640
31058
|
if (typeof v === "bigint") return v;
|
|
29641
31059
|
if (typeof v === "number" || typeof v === "string") return BigInt(v);
|
|
@@ -29643,7 +31061,7 @@ var big2 = (v) => {
|
|
|
29643
31061
|
}
|
|
29644
31062
|
return 0n;
|
|
29645
31063
|
};
|
|
29646
|
-
var field7 = (res, name, idx) =>
|
|
31064
|
+
var field7 = (res, name, idx) => big3(res?.[name] ?? res?.[idx]);
|
|
29647
31065
|
var getLiquityUserDataConverter = (lender, chainId, account, meta) => {
|
|
29648
31066
|
const cfg = liquityConfigFor(lender, chainId);
|
|
29649
31067
|
const branches = liquityBranchesByChain(lender, chainId);
|
|
@@ -29764,11 +31182,11 @@ var getLiquityUserDataConverter = (lender, chainId, account, meta) => {
|
|
|
29764
31182
|
};
|
|
29765
31183
|
});
|
|
29766
31184
|
const spBase = troves.length * 2;
|
|
29767
|
-
const spDeposit =
|
|
29768
|
-
const spYield =
|
|
29769
|
-
const spCollGain =
|
|
29770
|
-
const spStashed =
|
|
29771
|
-
const collSurplus = branch.collSurplusPool ?
|
|
31185
|
+
const spDeposit = big3(slice2[spBase]);
|
|
31186
|
+
const spYield = big3(slice2[spBase + 1]);
|
|
31187
|
+
const spCollGain = big3(slice2[spBase + 2]);
|
|
31188
|
+
const spStashed = big3(slice2[spBase + 3]);
|
|
31189
|
+
const collSurplus = branch.collSurplusPool ? big3(slice2[spBase + 4]) : 0n;
|
|
29772
31190
|
const spStable = spDeposit + spYield;
|
|
29773
31191
|
const spColl = spCollGain + spStashed + collSurplus;
|
|
29774
31192
|
if (spStable > 0n || spColl > 0n) {
|
|
@@ -29847,7 +31265,7 @@ var getLiquityUserDataConverter = (lender, chainId, account, meta) => {
|
|
|
29847
31265
|
expected
|
|
29848
31266
|
];
|
|
29849
31267
|
};
|
|
29850
|
-
var
|
|
31268
|
+
var big4 = (v) => {
|
|
29851
31269
|
try {
|
|
29852
31270
|
if (typeof v === "bigint") return v;
|
|
29853
31271
|
if (typeof v === "number" || typeof v === "string") return BigInt(v);
|
|
@@ -29855,7 +31273,7 @@ var big3 = (v) => {
|
|
|
29855
31273
|
}
|
|
29856
31274
|
return 0n;
|
|
29857
31275
|
};
|
|
29858
|
-
var field8 = (res, name, idx) =>
|
|
31276
|
+
var field8 = (res, name, idx) => big4(res?.[name] ?? res?.[idx]);
|
|
29859
31277
|
var getRiverUserDataConverter = (lender, chainId, account, meta) => {
|
|
29860
31278
|
const cfg = riverConfigFor(lender, chainId);
|
|
29861
31279
|
const markets = riverChainData(lender, chainId)?.markets ?? [];
|
|
@@ -29867,13 +31285,13 @@ var getRiverUserDataConverter = (lender, chainId, account, meta) => {
|
|
|
29867
31285
|
const debtAddr = cfg.debtToken.toLowerCase();
|
|
29868
31286
|
const debtDecimals = cfg.debtDecimals ?? 18;
|
|
29869
31287
|
const out = {};
|
|
29870
|
-
const spDeposit =
|
|
31288
|
+
const spDeposit = big4(data[markets.length * RIVER_CALLS_PER_MARKET]);
|
|
29871
31289
|
markets.forEach((market, i) => {
|
|
29872
31290
|
const base = i * RIVER_CALLS_PER_MARKET;
|
|
29873
31291
|
const entire = data[base];
|
|
29874
31292
|
if (isFailedCall(entire) || isFailedCall(data[base + 1])) return;
|
|
29875
|
-
const status = Number(
|
|
29876
|
-
const surplus =
|
|
31293
|
+
const status = Number(big4(data[base + 1]));
|
|
31294
|
+
const surplus = big4(data[base + 2]);
|
|
29877
31295
|
const lenderKey = riverLenderKey(lender, chainId, market.index);
|
|
29878
31296
|
const metaMap = meta?.[lenderKey];
|
|
29879
31297
|
if (!metaMap) return;
|
|
@@ -29981,7 +31399,7 @@ var getRiverUserDataConverter = (lender, chainId, account, meta) => {
|
|
|
29981
31399
|
expected
|
|
29982
31400
|
];
|
|
29983
31401
|
};
|
|
29984
|
-
var
|
|
31402
|
+
var big5 = (v) => {
|
|
29985
31403
|
try {
|
|
29986
31404
|
if (typeof v === "bigint") return v;
|
|
29987
31405
|
if (typeof v === "number" || typeof v === "string") return BigInt(v);
|
|
@@ -30000,20 +31418,24 @@ var getInverseUserDataConverter = (lender, chainId, account, meta) => {
|
|
|
30000
31418
|
const dolaAddr = cfg.dola.toLowerCase();
|
|
30001
31419
|
const debtDecimals = cfg.debtDecimals ?? 18;
|
|
30002
31420
|
const tailBase = markets.length * INVERSE_CALLS_PER_MARKET;
|
|
30003
|
-
const dbrBalance =
|
|
30004
|
-
const dbrDeficit =
|
|
31421
|
+
const dbrBalance = big5(data[tailBase]);
|
|
31422
|
+
const dbrDeficit = big5(data[tailBase + 1]);
|
|
30005
31423
|
const dbrSignedRaw = data[tailBase + 2];
|
|
30006
|
-
const dbrSigned = isFailedCall(dbrSignedRaw) ? 0n :
|
|
31424
|
+
const dbrSigned = isFailedCall(dbrSignedRaw) ? 0n : big5(dbrSignedRaw);
|
|
31425
|
+
const dbrTotalDebtRaw = data[tailBase + 3];
|
|
31426
|
+
const dbrTotalDebt = isFailedCall(dbrTotalDebtRaw) ? 0n : big5(dbrTotalDebtRaw);
|
|
31427
|
+
const dbrRunway = dbrTotalDebt > 0n ? dbrBalance * 31536000n / dbrTotalDebt : 0n;
|
|
31428
|
+
const nowSec9 = BigInt(Math.floor(Date.now() / 1e3));
|
|
30007
31429
|
const out = {};
|
|
30008
31430
|
markets.forEach((market, i) => {
|
|
30009
31431
|
const base = i * INVERSE_CALLS_PER_MARKET;
|
|
30010
|
-
const escrowBal = isFailedCall(data[base]) ? 0n :
|
|
31432
|
+
const escrowBal = isFailedCall(data[base]) ? 0n : big5(data[base]);
|
|
30011
31433
|
const debtRaw = data[base + 1];
|
|
30012
31434
|
if (isFailedCall(debtRaw)) return;
|
|
30013
|
-
const debt =
|
|
31435
|
+
const debt = big5(debtRaw);
|
|
30014
31436
|
if (escrowBal === 0n && debt === 0n) return;
|
|
30015
|
-
const creditLimit = isFailedCall(data[base + 2]) ? 0n :
|
|
30016
|
-
const withdrawalLimit = isFailedCall(data[base + 3]) ? 0n :
|
|
31437
|
+
const creditLimit = isFailedCall(data[base + 2]) ? 0n : big5(data[base + 2]);
|
|
31438
|
+
const withdrawalLimit = isFailedCall(data[base + 3]) ? 0n : big5(data[base + 3]);
|
|
30017
31439
|
const lenderKey = inverseLenderKey(lender, market.address);
|
|
30018
31440
|
const metaMap = meta?.[lenderKey];
|
|
30019
31441
|
if (!metaMap) return;
|
|
@@ -30034,7 +31456,10 @@ var getInverseUserDataConverter = (lender, chainId, account, meta) => {
|
|
|
30034
31456
|
withdrawalLimit: withdrawalLimit.toString(),
|
|
30035
31457
|
dbrBalance: dbrBalance.toString(),
|
|
30036
31458
|
dbrDeficit: dbrDeficit.toString(),
|
|
30037
|
-
dbrSignedBalance: dbrSigned.toString()
|
|
31459
|
+
dbrSignedBalance: dbrSigned.toString(),
|
|
31460
|
+
dbrTotalDebt: dbrTotalDebt.toString(),
|
|
31461
|
+
dbrRunwaySeconds: dbrRunway.toString(),
|
|
31462
|
+
dbrDepletionTimestamp: dbrTotalDebt > 0n ? String(nowSec9 + dbrRunway) : void 0
|
|
30038
31463
|
};
|
|
30039
31464
|
const collStr = parseRawAmount(escrowBal.toString(), collDecimals);
|
|
30040
31465
|
const collNum = Number(collStr);
|
|
@@ -30096,8 +31521,273 @@ var getInverseUserDataConverter = (lender, chainId, account, meta) => {
|
|
|
30096
31521
|
expected
|
|
30097
31522
|
];
|
|
30098
31523
|
};
|
|
31524
|
+
var big6 = (v) => {
|
|
31525
|
+
try {
|
|
31526
|
+
if (typeof v === "bigint") return v;
|
|
31527
|
+
if (typeof v === "number" || typeof v === "string") return BigInt(v);
|
|
31528
|
+
} catch {
|
|
31529
|
+
}
|
|
31530
|
+
return 0n;
|
|
31531
|
+
};
|
|
31532
|
+
var arrAt = (v, i) => {
|
|
31533
|
+
if (isFailedCall(v) || !Array.isArray(v)) return 0n;
|
|
31534
|
+
return big6(v[i]);
|
|
31535
|
+
};
|
|
31536
|
+
var getLlamaLendUserDataConverter = (lender, chainId, account, meta) => {
|
|
31537
|
+
const cfg = llamaLendConfigFor(lender, chainId);
|
|
31538
|
+
const markets = llamaLendChainData(lender, chainId)?.markets ?? [];
|
|
31539
|
+
const expected = cfg && markets.length > 0 ? markets.length * LLAMALEND_CALLS_PER_MARKET : 0;
|
|
31540
|
+
return [
|
|
31541
|
+
(data) => {
|
|
31542
|
+
if (!cfg || expected === 0) return void 0;
|
|
31543
|
+
if (!data || data.length < expected) return void 0;
|
|
31544
|
+
const out = {};
|
|
31545
|
+
markets.forEach((market, i) => {
|
|
31546
|
+
const base = i * LLAMALEND_CALLS_PER_MARKET;
|
|
31547
|
+
const stateRaw = data[base];
|
|
31548
|
+
if (isFailedCall(stateRaw) || !Array.isArray(stateRaw)) return;
|
|
31549
|
+
const collateral = big6(stateRaw[0]);
|
|
31550
|
+
const bandBorrowed = big6(stateRaw[1]);
|
|
31551
|
+
const debt = big6(stateRaw[2]);
|
|
31552
|
+
const bandCount = Number(big6(stateRaw[3]));
|
|
31553
|
+
if (collateral === 0n && debt === 0n && bandBorrowed === 0n) return;
|
|
31554
|
+
const healthRaw = data[base + 1];
|
|
31555
|
+
const health = isFailedCall(healthRaw) ? 0n : big6(healthRaw);
|
|
31556
|
+
const pricesRaw = data[base + 2];
|
|
31557
|
+
const priceUpper = arrAt(pricesRaw, 0);
|
|
31558
|
+
const priceLower = arrAt(pricesRaw, 1);
|
|
31559
|
+
const ticksRaw = data[base + 3];
|
|
31560
|
+
const bands = isFailedCall(ticksRaw) || !Array.isArray(ticksRaw) ? void 0 : [Number(big6(ticksRaw[0])), Number(big6(ticksRaw[1]))];
|
|
31561
|
+
const approvalRaw = data[base + 4];
|
|
31562
|
+
const delegated = isFailedCall(approvalRaw) ? false : approvalRaw === true;
|
|
31563
|
+
const lenderKey = llamaLendLenderKey(lender, market.controller);
|
|
31564
|
+
const metaMap = meta?.[lenderKey];
|
|
31565
|
+
if (!metaMap) return;
|
|
31566
|
+
const collAddr = market.collateralToken.toLowerCase();
|
|
31567
|
+
const loanAddr = market.borrowedToken.toLowerCase();
|
|
31568
|
+
const collUid = createMarketUid(chainId, lenderKey, collAddr);
|
|
31569
|
+
const loanUid = createMarketUid(chainId, lenderKey, loanAddr);
|
|
31570
|
+
const collMeta = metaMap[collUid];
|
|
31571
|
+
const loanMeta = metaMap[loanUid];
|
|
31572
|
+
const collDecimals = collMeta?.asset?.decimals ?? market.collateralDecimals;
|
|
31573
|
+
const loanDecimals = loanMeta?.asset?.decimals ?? market.borrowedDecimals;
|
|
31574
|
+
const collDisplay = collMeta ? getDisplayPrice(collMeta) : 0;
|
|
31575
|
+
const collOracle = collMeta ? getOraclePrice(collMeta) : 0;
|
|
31576
|
+
const collHist = collMeta?.price?.priceUsd24h ?? collDisplay;
|
|
31577
|
+
const loanDisplay = loanMeta ? getDisplayPrice(loanMeta) : 0;
|
|
31578
|
+
const loanOracle = loanMeta ? getOraclePrice(loanMeta) : 0;
|
|
31579
|
+
const loanHist = loanMeta?.price?.priceUsd24h ?? loanDisplay;
|
|
31580
|
+
const llamalendInfo = {
|
|
31581
|
+
health: health.toString(),
|
|
31582
|
+
priceUpper: priceUpper.toString(),
|
|
31583
|
+
priceLower: priceLower.toString(),
|
|
31584
|
+
bands,
|
|
31585
|
+
bandCount,
|
|
31586
|
+
bandCollateralInBorrowed: bandBorrowed.toString(),
|
|
31587
|
+
softLiquidating: bandBorrowed > 0n,
|
|
31588
|
+
delegated,
|
|
31589
|
+
supportsDelegation: market.supportsDelegation === true,
|
|
31590
|
+
version: market.version
|
|
31591
|
+
};
|
|
31592
|
+
const collStr = parseRawAmount(collateral.toString(), collDecimals);
|
|
31593
|
+
const collNum = Number(collStr);
|
|
31594
|
+
const debtStr = parseRawAmount(debt.toString(), loanDecimals);
|
|
31595
|
+
const debtNum = Number(debtStr);
|
|
31596
|
+
const bandBorrowedStr = parseRawAmount(
|
|
31597
|
+
bandBorrowed.toString(),
|
|
31598
|
+
loanDecimals
|
|
31599
|
+
);
|
|
31600
|
+
const bandBorrowedNum = Number(bandBorrowedStr);
|
|
31601
|
+
const lendingPositions = {
|
|
31602
|
+
"0": {
|
|
31603
|
+
[collUid]: {
|
|
31604
|
+
marketUid: collUid,
|
|
31605
|
+
underlying: collAddr,
|
|
31606
|
+
deposits: collStr,
|
|
31607
|
+
debt: "0",
|
|
31608
|
+
debtStable: "0",
|
|
31609
|
+
depositsUSD: collNum * collDisplay,
|
|
31610
|
+
debtUSD: 0,
|
|
31611
|
+
debtStableUSD: 0,
|
|
31612
|
+
depositsUSDOracle: collNum * collOracle,
|
|
31613
|
+
debtUSDOracle: 0,
|
|
31614
|
+
debtStableUSDOracle: 0,
|
|
31615
|
+
stableBorrowRate: "0",
|
|
31616
|
+
collateralEnabled: true,
|
|
31617
|
+
claimableRewards: 0
|
|
31618
|
+
},
|
|
31619
|
+
[loanUid]: {
|
|
31620
|
+
marketUid: loanUid,
|
|
31621
|
+
underlying: loanAddr,
|
|
31622
|
+
deposits: bandBorrowedStr,
|
|
31623
|
+
debt: debtStr,
|
|
31624
|
+
debtStable: "0",
|
|
31625
|
+
depositsUSD: bandBorrowedNum * loanDisplay,
|
|
31626
|
+
debtUSD: debtNum * loanDisplay,
|
|
31627
|
+
debtStableUSD: 0,
|
|
31628
|
+
depositsUSDOracle: bandBorrowedNum * loanOracle,
|
|
31629
|
+
debtUSDOracle: debtNum * loanOracle,
|
|
31630
|
+
debtStableUSDOracle: 0,
|
|
31631
|
+
stableBorrowRate: "0",
|
|
31632
|
+
collateralEnabled: false,
|
|
31633
|
+
claimableRewards: 0,
|
|
31634
|
+
llamalendInfo
|
|
31635
|
+
}
|
|
31636
|
+
}
|
|
31637
|
+
};
|
|
31638
|
+
const modes = { "0": 0 };
|
|
31639
|
+
const hist = {
|
|
31640
|
+
"0": {
|
|
31641
|
+
totalDeposits24h: collNum * collHist + bandBorrowedNum * loanHist,
|
|
31642
|
+
totalDebt24h: debtNum * loanHist
|
|
31643
|
+
}
|
|
31644
|
+
};
|
|
31645
|
+
const userData = createMultiAccountTypeUserState(
|
|
31646
|
+
{ chainId, account, lendingPositions, modes },
|
|
31647
|
+
metaMap,
|
|
31648
|
+
hist
|
|
31649
|
+
);
|
|
31650
|
+
if (userData && userData.data.length > 0) out[lenderKey] = userData;
|
|
31651
|
+
});
|
|
31652
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
31653
|
+
},
|
|
31654
|
+
expected
|
|
31655
|
+
];
|
|
31656
|
+
};
|
|
31657
|
+
var big7 = (v) => {
|
|
31658
|
+
try {
|
|
31659
|
+
if (typeof v === "bigint") return v;
|
|
31660
|
+
if (typeof v === "number" || typeof v === "string") return BigInt(v);
|
|
31661
|
+
} catch {
|
|
31662
|
+
}
|
|
31663
|
+
return 0n;
|
|
31664
|
+
};
|
|
31665
|
+
var tupleAt = (v, i) => Array.isArray(v) ? big7(v[i]) : 0n;
|
|
31666
|
+
var ONE4 = 10n ** 18n;
|
|
31667
|
+
function sharesToAmount(shares, totalAmount, totalShares) {
|
|
31668
|
+
if (totalShares === 0n || shares === 0n) return 0n;
|
|
31669
|
+
const q = shares * totalAmount / totalShares;
|
|
31670
|
+
return q * totalShares < shares * totalAmount ? q + 1n : q;
|
|
31671
|
+
}
|
|
31672
|
+
var getResupplyUserDataConverter = (lender, chainId, account, meta) => {
|
|
31673
|
+
const cfg = resupplyConfigFor(lender, chainId);
|
|
31674
|
+
const discovery = getCachedResupplyDiscovery(chainId, lender, account);
|
|
31675
|
+
const positions = discovery?.positions ?? [];
|
|
31676
|
+
const expected = cfg && positions.length > 0 ? positions.length * RESUPPLY_CALLS_PER_PAIR : 0;
|
|
31677
|
+
return [
|
|
31678
|
+
(data) => {
|
|
31679
|
+
if (!cfg || expected === 0) return void 0;
|
|
31680
|
+
if (!data || data.length < expected) return void 0;
|
|
31681
|
+
const debtAddr = cfg.reusd.toLowerCase();
|
|
31682
|
+
const debtDecimals = cfg.debtDecimals ?? 18;
|
|
31683
|
+
const out = {};
|
|
31684
|
+
positions.forEach(
|
|
31685
|
+
({ pair, collateral, borrowShares, collateralShares }, i) => {
|
|
31686
|
+
const base = i * RESUPPLY_CALLS_PER_PAIR;
|
|
31687
|
+
const accounting = data[base];
|
|
31688
|
+
if (isFailedCall(accounting) || !Array.isArray(accounting)) return;
|
|
31689
|
+
const totalBorrowAmount = tupleAt(accounting, 1);
|
|
31690
|
+
const totalBorrowShares = tupleAt(accounting, 2);
|
|
31691
|
+
const sharePrice = isFailedCall(data[base + 1]) ? 0n : big7(data[base + 1]);
|
|
31692
|
+
const lenderKey = resupplyLenderKey(lender, chainId, pair);
|
|
31693
|
+
const metaMap = meta?.[lenderKey];
|
|
31694
|
+
if (!metaMap) return;
|
|
31695
|
+
const debt = sharesToAmount(
|
|
31696
|
+
borrowShares,
|
|
31697
|
+
totalBorrowAmount,
|
|
31698
|
+
totalBorrowShares
|
|
31699
|
+
);
|
|
31700
|
+
const collUnderlying = sharePrice > 0n ? collateralShares * sharePrice / ONE4 : 0n;
|
|
31701
|
+
const collAddrEntry = Object.values(metaMap).find(
|
|
31702
|
+
(m) => m?.underlying && m.underlying.toLowerCase() !== debtAddr
|
|
31703
|
+
);
|
|
31704
|
+
const collAddr = collAddrEntry?.underlying?.toLowerCase();
|
|
31705
|
+
if (!collAddr) return;
|
|
31706
|
+
const collUid = createMarketUid(chainId, lenderKey, collAddr);
|
|
31707
|
+
const loanUid = createMarketUid(chainId, lenderKey, debtAddr);
|
|
31708
|
+
const collMeta = metaMap[collUid];
|
|
31709
|
+
const loanMeta = metaMap[loanUid];
|
|
31710
|
+
const collDecimals = collMeta?.asset?.decimals ?? 18;
|
|
31711
|
+
const collDisplay = collMeta ? getDisplayPrice(collMeta) : 0;
|
|
31712
|
+
const collOracle = collMeta ? getOraclePrice(collMeta) : 0;
|
|
31713
|
+
const collHist = collMeta?.price?.priceUsd24h ?? collDisplay;
|
|
31714
|
+
const loanDisplay = loanMeta ? getDisplayPrice(loanMeta) : 0;
|
|
31715
|
+
const loanOracle = loanMeta ? getOraclePrice(loanMeta) : 0;
|
|
31716
|
+
const loanHist = loanMeta?.price?.priceUsd24h ?? loanDisplay;
|
|
31717
|
+
const resupplyInfo = {
|
|
31718
|
+
borrowShares: borrowShares.toString(),
|
|
31719
|
+
collateralShares: collateralShares.toString(),
|
|
31720
|
+
collateralSharePrice: sharePrice.toString(),
|
|
31721
|
+
pair,
|
|
31722
|
+
collateralVault: collateral
|
|
31723
|
+
};
|
|
31724
|
+
const collStr = parseRawAmount(
|
|
31725
|
+
collUnderlying.toString(),
|
|
31726
|
+
collDecimals
|
|
31727
|
+
);
|
|
31728
|
+
const collNum = Number(collStr);
|
|
31729
|
+
const debtStr = parseRawAmount(debt.toString(), debtDecimals);
|
|
31730
|
+
const debtNum = Number(debtStr);
|
|
31731
|
+
const lendingPositions = {
|
|
31732
|
+
"0": {
|
|
31733
|
+
[collUid]: {
|
|
31734
|
+
marketUid: collUid,
|
|
31735
|
+
underlying: collAddr,
|
|
31736
|
+
deposits: collStr,
|
|
31737
|
+
debt: "0",
|
|
31738
|
+
debtStable: "0",
|
|
31739
|
+
depositsUSD: collNum * collDisplay,
|
|
31740
|
+
debtUSD: 0,
|
|
31741
|
+
debtStableUSD: 0,
|
|
31742
|
+
depositsUSDOracle: collNum * collOracle,
|
|
31743
|
+
debtUSDOracle: 0,
|
|
31744
|
+
debtStableUSDOracle: 0,
|
|
31745
|
+
stableBorrowRate: "0",
|
|
31746
|
+
collateralEnabled: true,
|
|
31747
|
+
claimableRewards: 0,
|
|
31748
|
+
resupplyInfo
|
|
31749
|
+
},
|
|
31750
|
+
[loanUid]: {
|
|
31751
|
+
marketUid: loanUid,
|
|
31752
|
+
underlying: debtAddr,
|
|
31753
|
+
deposits: "0",
|
|
31754
|
+
debt: debtStr,
|
|
31755
|
+
debtStable: "0",
|
|
31756
|
+
depositsUSD: 0,
|
|
31757
|
+
debtUSD: debtNum * loanDisplay,
|
|
31758
|
+
debtStableUSD: 0,
|
|
31759
|
+
depositsUSDOracle: 0,
|
|
31760
|
+
debtUSDOracle: debtNum * loanOracle,
|
|
31761
|
+
debtStableUSDOracle: 0,
|
|
31762
|
+
stableBorrowRate: "0",
|
|
31763
|
+
collateralEnabled: false,
|
|
31764
|
+
claimableRewards: 0,
|
|
31765
|
+
resupplyInfo
|
|
31766
|
+
}
|
|
31767
|
+
}
|
|
31768
|
+
};
|
|
31769
|
+
const modes = { "0": 0 };
|
|
31770
|
+
const hist = {
|
|
31771
|
+
"0": {
|
|
31772
|
+
totalDeposits24h: collNum * collHist,
|
|
31773
|
+
totalDebt24h: debtNum * loanHist
|
|
31774
|
+
}
|
|
31775
|
+
};
|
|
31776
|
+
const userData = createMultiAccountTypeUserState(
|
|
31777
|
+
{ chainId, account, lendingPositions, modes },
|
|
31778
|
+
metaMap,
|
|
31779
|
+
hist
|
|
31780
|
+
);
|
|
31781
|
+
if (userData && userData.data.length > 0) out[lenderKey] = userData;
|
|
31782
|
+
}
|
|
31783
|
+
);
|
|
31784
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
31785
|
+
},
|
|
31786
|
+
expected
|
|
31787
|
+
];
|
|
31788
|
+
};
|
|
30099
31789
|
var RAY4 = 10n ** 27n;
|
|
30100
|
-
var
|
|
31790
|
+
var big8 = (v) => {
|
|
30101
31791
|
try {
|
|
30102
31792
|
if (typeof v === "bigint") return v;
|
|
30103
31793
|
if (typeof v === "number" || typeof v === "string") return BigInt(v);
|
|
@@ -30105,7 +31795,7 @@ var big5 = (v) => {
|
|
|
30105
31795
|
}
|
|
30106
31796
|
return 0n;
|
|
30107
31797
|
};
|
|
30108
|
-
var field9 = (res, name, idx) =>
|
|
31798
|
+
var field9 = (res, name, idx) => big8(res?.[name] ?? res?.[idx]);
|
|
30109
31799
|
var getUsddUserDataConverter = (lender, chainId, account, meta) => {
|
|
30110
31800
|
const cfg = usddConfigFor(lender, chainId);
|
|
30111
31801
|
const markets = usddChainData(lender, chainId)?.markets ?? [];
|
|
@@ -30218,10 +31908,142 @@ var getUsddUserDataConverter = (lender, chainId, account, meta) => {
|
|
|
30218
31908
|
expected
|
|
30219
31909
|
];
|
|
30220
31910
|
};
|
|
31911
|
+
var big9 = (v) => {
|
|
31912
|
+
try {
|
|
31913
|
+
if (typeof v === "bigint") return v;
|
|
31914
|
+
if (typeof v === "number" || typeof v === "string") return BigInt(v);
|
|
31915
|
+
} catch {
|
|
31916
|
+
}
|
|
31917
|
+
return 0n;
|
|
31918
|
+
};
|
|
31919
|
+
var getFrankencoinUserDataConverter = (lender, chainId, account, meta) => {
|
|
31920
|
+
const cfg = frankencoinConfigFor(lender, chainId);
|
|
31921
|
+
const markets = frankencoinChainData(lender, chainId)?.markets ?? [];
|
|
31922
|
+
const discovery = getCachedFrankencoinPositions(chainId, account);
|
|
31923
|
+
const positions = discovery?.positions ?? [];
|
|
31924
|
+
const expected = cfg && markets.length > 0 && positions.length > 0 ? positions.length * FRANKENCOIN_CALLS_PER_POSITION : 0;
|
|
31925
|
+
return [
|
|
31926
|
+
(data) => {
|
|
31927
|
+
if (!cfg || expected === 0) return void 0;
|
|
31928
|
+
if (!data || data.length < expected) return void 0;
|
|
31929
|
+
const debtAddr = cfg.zchf.toLowerCase();
|
|
31930
|
+
const debtDecimals = cfg.debtDecimals ?? 18;
|
|
31931
|
+
const marketByOriginal = new Map(
|
|
31932
|
+
markets.map((m) => [m.position.toLowerCase(), m])
|
|
31933
|
+
);
|
|
31934
|
+
const lowerAccount = account.toLowerCase();
|
|
31935
|
+
const perMarket = /* @__PURE__ */ new Map();
|
|
31936
|
+
positions.forEach((p, i) => {
|
|
31937
|
+
const base = i * FRANKENCOIN_CALLS_PER_POSITION;
|
|
31938
|
+
const ownerRes = data[base];
|
|
31939
|
+
if (isFailedCall(ownerRes)) return;
|
|
31940
|
+
if (String(ownerRes).toLowerCase() !== lowerAccount) return;
|
|
31941
|
+
const minted = big9(data[base + 1]);
|
|
31942
|
+
const price2 = big9(data[base + 2]);
|
|
31943
|
+
const expiration = big9(data[base + 3]);
|
|
31944
|
+
const challenged = big9(data[base + 4]);
|
|
31945
|
+
const coll = big9(data[base + 5]);
|
|
31946
|
+
if (minted === 0n && coll === 0n) return;
|
|
31947
|
+
const market = marketByOriginal.get(p.original);
|
|
31948
|
+
if (!market) return;
|
|
31949
|
+
const key = frankencoinLenderKey(lender, chainId, market.position);
|
|
31950
|
+
if (!perMarket.has(key)) perMarket.set(key, { market, rows: [] });
|
|
31951
|
+
perMarket.get(key).rows.push({
|
|
31952
|
+
info: {
|
|
31953
|
+
position: p.position,
|
|
31954
|
+
original: p.original,
|
|
31955
|
+
declaredPrice: price2.toString(),
|
|
31956
|
+
expiration: expiration.toString(),
|
|
31957
|
+
challengedAmount: challenged.toString(),
|
|
31958
|
+
reserveContributionPPM: String(market.reserveContribution)
|
|
31959
|
+
},
|
|
31960
|
+
coll,
|
|
31961
|
+
debt: minted
|
|
31962
|
+
});
|
|
31963
|
+
});
|
|
31964
|
+
const out = {};
|
|
31965
|
+
for (const [lenderKey, { market, rows }] of perMarket) {
|
|
31966
|
+
const metaMap = meta?.[lenderKey];
|
|
31967
|
+
if (!metaMap) continue;
|
|
31968
|
+
const collAddr = market.collToken.toLowerCase();
|
|
31969
|
+
const collUid = createMarketUid(chainId, lenderKey, collAddr);
|
|
31970
|
+
const loanUid = createMarketUid(chainId, lenderKey, debtAddr);
|
|
31971
|
+
const collMeta = metaMap[collUid];
|
|
31972
|
+
const loanMeta = metaMap[loanUid];
|
|
31973
|
+
const collDecimals = collMeta?.asset?.decimals ?? market.collDecimals;
|
|
31974
|
+
const collDisplay = collMeta ? getDisplayPrice(collMeta) : 0;
|
|
31975
|
+
const collOracle = collMeta ? getOraclePrice(collMeta) : 0;
|
|
31976
|
+
const collHist = collMeta?.price?.priceUsd24h ?? collDisplay;
|
|
31977
|
+
const loanDisplay = loanMeta ? getDisplayPrice(loanMeta) : 0;
|
|
31978
|
+
const loanOracle = loanMeta ? getOraclePrice(loanMeta) : 0;
|
|
31979
|
+
const loanHist = loanMeta?.price?.priceUsd24h ?? loanDisplay;
|
|
31980
|
+
const lendingPositions = {};
|
|
31981
|
+
const modes = {};
|
|
31982
|
+
const hist = {};
|
|
31983
|
+
for (const row of rows) {
|
|
31984
|
+
const id = row.info.position;
|
|
31985
|
+
const collStr = parseRawAmount(row.coll.toString(), collDecimals);
|
|
31986
|
+
const collNum = Number(collStr);
|
|
31987
|
+
const debtStr = parseRawAmount(row.debt.toString(), debtDecimals);
|
|
31988
|
+
const debtNum = Number(debtStr);
|
|
31989
|
+
lendingPositions[id] = {
|
|
31990
|
+
[collUid]: {
|
|
31991
|
+
marketUid: collUid,
|
|
31992
|
+
underlying: collAddr,
|
|
31993
|
+
deposits: collStr,
|
|
31994
|
+
debt: "0",
|
|
31995
|
+
debtStable: "0",
|
|
31996
|
+
depositsUSD: collNum * collDisplay,
|
|
31997
|
+
debtUSD: 0,
|
|
31998
|
+
debtStableUSD: 0,
|
|
31999
|
+
depositsUSDOracle: collNum * collOracle,
|
|
32000
|
+
debtUSDOracle: 0,
|
|
32001
|
+
debtStableUSDOracle: 0,
|
|
32002
|
+
stableBorrowRate: "0",
|
|
32003
|
+
collateralEnabled: true,
|
|
32004
|
+
claimableRewards: 0
|
|
32005
|
+
},
|
|
32006
|
+
[loanUid]: {
|
|
32007
|
+
marketUid: loanUid,
|
|
32008
|
+
underlying: debtAddr,
|
|
32009
|
+
deposits: "0",
|
|
32010
|
+
debt: debtStr,
|
|
32011
|
+
debtStable: "0",
|
|
32012
|
+
depositsUSD: 0,
|
|
32013
|
+
debtUSD: debtNum * loanDisplay,
|
|
32014
|
+
debtStableUSD: 0,
|
|
32015
|
+
depositsUSDOracle: 0,
|
|
32016
|
+
debtUSDOracle: debtNum * loanOracle,
|
|
32017
|
+
debtStableUSDOracle: 0,
|
|
32018
|
+
stableBorrowRate: "0",
|
|
32019
|
+
collateralEnabled: false,
|
|
32020
|
+
claimableRewards: 0,
|
|
32021
|
+
frankencoinInfo: row.info
|
|
32022
|
+
}
|
|
32023
|
+
};
|
|
32024
|
+
modes[id] = 0;
|
|
32025
|
+
hist[id] = {
|
|
32026
|
+
totalDeposits24h: collNum * collHist,
|
|
32027
|
+
totalDebt24h: debtNum * loanHist
|
|
32028
|
+
};
|
|
32029
|
+
}
|
|
32030
|
+
if (Object.keys(lendingPositions).length === 0) continue;
|
|
32031
|
+
const userData = createMultiAccountTypeUserState(
|
|
32032
|
+
{ chainId, account, lendingPositions, modes },
|
|
32033
|
+
metaMap,
|
|
32034
|
+
hist
|
|
32035
|
+
);
|
|
32036
|
+
if (userData && userData.data.length > 0) out[lenderKey] = userData;
|
|
32037
|
+
}
|
|
32038
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
32039
|
+
},
|
|
32040
|
+
expected
|
|
32041
|
+
];
|
|
32042
|
+
};
|
|
30221
32043
|
|
|
30222
32044
|
// src/lending/user-data/teller/userCallParse.ts
|
|
30223
32045
|
var nowSec7 = () => Math.floor(Date.now() / 1e3);
|
|
30224
|
-
var
|
|
32046
|
+
var big10 = (v) => {
|
|
30225
32047
|
try {
|
|
30226
32048
|
if (typeof v === "bigint") return v;
|
|
30227
32049
|
if (typeof v === "number" || typeof v === "string") return BigInt(v);
|
|
@@ -30243,7 +32065,7 @@ var getTellerUserDataConverter = (_lender, chainId, account, meta) => {
|
|
|
30243
32065
|
const base = i * TELLER_CALLS_PER_BID;
|
|
30244
32066
|
const bidRes = data[base];
|
|
30245
32067
|
const owed = data[base + 1];
|
|
30246
|
-
const collAmount =
|
|
32068
|
+
const collAmount = big10(data[base + 2]);
|
|
30247
32069
|
const defaulted = !!data[base + 3];
|
|
30248
32070
|
if (isFailedCall(bidRes) || isFailedCall(owed) || !bidRes) return;
|
|
30249
32071
|
const pool = b.pool;
|
|
@@ -30264,17 +32086,17 @@ var getTellerUserDataConverter = (_lender, chainId, account, meta) => {
|
|
|
30264
32086
|
const collDisplay = collMeta ? getDisplayPrice(collMeta) : 0;
|
|
30265
32087
|
const collOracle = collMeta ? getOraclePrice(collMeta) : 0;
|
|
30266
32088
|
const collHist = collMeta?.price?.priceUsd24h ?? collDisplay;
|
|
30267
|
-
const owedPrincipal =
|
|
30268
|
-
const owedInterest =
|
|
32089
|
+
const owedPrincipal = big10(field10(owed, "principal", 0));
|
|
32090
|
+
const owedInterest = big10(field10(owed, "interest", 1));
|
|
30269
32091
|
const owedTotal = owedPrincipal + owedInterest;
|
|
30270
32092
|
if (owedTotal === 0n && collAmount === 0n) return;
|
|
30271
32093
|
const loanDetails = field10(bidRes, "loanDetails", 5);
|
|
30272
32094
|
const terms = field10(bidRes, "terms", 6);
|
|
30273
32095
|
const acceptedTs = Number(
|
|
30274
|
-
|
|
32096
|
+
big10(field10(loanDetails, "acceptedTimestamp", 4))
|
|
30275
32097
|
);
|
|
30276
|
-
const loanDuration = Number(
|
|
30277
|
-
const aprBps = Number(
|
|
32098
|
+
const loanDuration = Number(big10(field10(loanDetails, "loanDuration", 6)));
|
|
32099
|
+
const aprBps = Number(big10(field10(terms, "APR", 2)));
|
|
30278
32100
|
const maturity = acceptedTs > 0 ? acceptedTs + loanDuration : void 0;
|
|
30279
32101
|
const isMatured = defaulted || maturity !== void 0 && maturity < now;
|
|
30280
32102
|
const collStr = parseRawAmount(collAmount.toString(), collDecimals);
|
|
@@ -30561,7 +32383,7 @@ function getUserDataConverter(lender, chainId, account, params, meta) {
|
|
|
30561
32383
|
if (isTerm(lender))
|
|
30562
32384
|
return getTermUserDataConverter(lender, chainId, account, meta);
|
|
30563
32385
|
if (isExactly(lender))
|
|
30564
|
-
return getExactlyUserDataConverter(lender, chainId, account, meta
|
|
32386
|
+
return getExactlyUserDataConverter(lender, chainId, account, meta);
|
|
30565
32387
|
if (isLiquityFamily(lender))
|
|
30566
32388
|
return getLiquityUserDataConverter(lender, chainId, account, meta);
|
|
30567
32389
|
if (isRiver(lender))
|
|
@@ -30572,8 +32394,14 @@ function getUserDataConverter(lender, chainId, account, params, meta) {
|
|
|
30572
32394
|
return getTermMaxUserDataConverter(lender, chainId, account, meta);
|
|
30573
32395
|
if (isInverse(lender))
|
|
30574
32396
|
return getInverseUserDataConverter(lender, chainId, account, meta);
|
|
32397
|
+
if (isLlamaLend(lender))
|
|
32398
|
+
return getLlamaLendUserDataConverter(lender, chainId, account, meta);
|
|
32399
|
+
if (isResupply(lender))
|
|
32400
|
+
return getResupplyUserDataConverter(lender, chainId, account, meta);
|
|
30575
32401
|
if (isUsdd(lender))
|
|
30576
32402
|
return getUsddUserDataConverter(lender, chainId, account, meta);
|
|
32403
|
+
if (isFrankencoin(lender))
|
|
32404
|
+
return getFrankencoinUserDataConverter(lender, chainId, account, meta);
|
|
30577
32405
|
if (isCompoundV3Type(lender))
|
|
30578
32406
|
return getCompoundV3UserDataConverter(
|
|
30579
32407
|
lender,
|
|
@@ -35129,6 +36957,15 @@ var accountLensAbi = [
|
|
|
35129
36957
|
stateMutability: "view"
|
|
35130
36958
|
}
|
|
35131
36959
|
];
|
|
36960
|
+
var VAULT_CONVERT_ABI = [
|
|
36961
|
+
{
|
|
36962
|
+
name: "convertToAssets",
|
|
36963
|
+
type: "function",
|
|
36964
|
+
stateMutability: "view",
|
|
36965
|
+
inputs: [{ name: "shares", type: "uint256" }],
|
|
36966
|
+
outputs: [{ type: "uint256" }]
|
|
36967
|
+
}
|
|
36968
|
+
];
|
|
35132
36969
|
var getAbi2 = (lender) => {
|
|
35133
36970
|
if (isAaveV4Type(lender)) return [...AaveV4SpokeAbi];
|
|
35134
36971
|
if (isAaveV2Type(lender))
|
|
@@ -35171,9 +37008,16 @@ var getAbi2 = (lender) => {
|
|
|
35171
37008
|
return [...RiverTroveManagerAbi, ...RiverStabilityPoolAbi];
|
|
35172
37009
|
if (isTeller(lender))
|
|
35173
37010
|
return [...TellerV2Abi, ...TellerCollateralManagerAbi];
|
|
37011
|
+
if (isTermMax(lender)) return [...TermMaxViewerAbi];
|
|
35174
37012
|
if (isInverse(lender))
|
|
35175
37013
|
return [...InverseMarketAbi, ...InverseEscrowAbi, ...InverseDbrAbi];
|
|
37014
|
+
if (isLlamaLend(lender))
|
|
37015
|
+
return [...LlamaLendControllerAbi, ...LlamaLendAmmAbi];
|
|
35176
37016
|
if (isUsdd(lender)) return [...UsddVatAbi];
|
|
37017
|
+
if (isFrankencoin(lender))
|
|
37018
|
+
return [...FrankencoinPositionAbi, ...erc20Abi];
|
|
37019
|
+
if (isResupply(lender))
|
|
37020
|
+
return [...ResupplyPairAbi, ...VAULT_CONVERT_ABI];
|
|
35177
37021
|
if (isInit(lender)) return InitLensAbi;
|
|
35178
37022
|
if (isEulerType(lender)) return accountLensAbi;
|
|
35179
37023
|
if (isCompoundV2Type(lender))
|
|
@@ -35785,11 +37629,11 @@ async function fetchJsonWithProxyFallback(url, body, proxyConfig) {
|
|
|
35785
37629
|
}
|
|
35786
37630
|
var inflight = /* @__PURE__ */ new Map();
|
|
35787
37631
|
var resolved = /* @__PURE__ */ new Map();
|
|
35788
|
-
function
|
|
37632
|
+
function cacheKey6(chainId, account) {
|
|
35789
37633
|
return `${chainId}:${account.toLowerCase()}`;
|
|
35790
37634
|
}
|
|
35791
37635
|
async function dedupedFetch(chainId, account, loader) {
|
|
35792
|
-
const key =
|
|
37636
|
+
const key = cacheKey6(chainId, account);
|
|
35793
37637
|
const now = Date.now();
|
|
35794
37638
|
const cached = resolved.get(key);
|
|
35795
37639
|
if (cached && cached.expiresAt > now) {
|
|
@@ -40275,7 +42119,7 @@ var DOLA_STAKING_URL = "https://www.inverse.finance/api/dola-staking";
|
|
|
40275
42119
|
var JDOLA_STAKING_URL = "https://www.inverse.finance/api/junior/jdola-staking";
|
|
40276
42120
|
var SDOLA_KEY = "SDOLA";
|
|
40277
42121
|
var SDOLA_GROUP_KEY = "sDOLA::SDOLA";
|
|
40278
|
-
var
|
|
42122
|
+
var fetchJson3 = async (url) => {
|
|
40279
42123
|
const res = await fetch(url, {
|
|
40280
42124
|
headers: { accept: "application/json" },
|
|
40281
42125
|
signal: AbortSignal.timeout(8e3)
|
|
@@ -40285,12 +42129,12 @@ var fetchJson2 = async (url) => {
|
|
|
40285
42129
|
};
|
|
40286
42130
|
var fetchSdolaApyPercent = async () => {
|
|
40287
42131
|
try {
|
|
40288
|
-
const d = await
|
|
42132
|
+
const d = await fetchJson3(DOLA_STAKING_URL);
|
|
40289
42133
|
const apy = Number(d?.calculatedApy);
|
|
40290
42134
|
if (Number.isFinite(apy) && apy > 0) return apy;
|
|
40291
42135
|
throw new Error("calculatedApy missing");
|
|
40292
42136
|
} catch {
|
|
40293
|
-
const d = await
|
|
42137
|
+
const d = await fetchJson3(JDOLA_STAKING_URL);
|
|
40294
42138
|
const apy = Number(d?.sDolaApy);
|
|
40295
42139
|
if (Number.isFinite(apy) && apy > 0) return apy;
|
|
40296
42140
|
throw new Error("sDolaApy missing");
|
|
@@ -40722,6 +42566,72 @@ var usddFetcher = {
|
|
|
40722
42566
|
return out;
|
|
40723
42567
|
}
|
|
40724
42568
|
};
|
|
42569
|
+
var FRANKENCOIN_SAVINGS_MODULE = "0x27d9ad987bde08a0d083ef7e0e4043c857a17b38";
|
|
42570
|
+
var SAVINGS_INFO_URL = "https://api.frankencoin.com/savings/core/info";
|
|
42571
|
+
var RATE_ABI2 = [
|
|
42572
|
+
{
|
|
42573
|
+
name: "currentRatePPM",
|
|
42574
|
+
type: "function",
|
|
42575
|
+
stateMutability: "view",
|
|
42576
|
+
inputs: [],
|
|
42577
|
+
outputs: [{ type: "uint24" }]
|
|
42578
|
+
}
|
|
42579
|
+
];
|
|
42580
|
+
var ZCHF_SAVINGS_KEY = "ZCHF_SAVINGS";
|
|
42581
|
+
var aprFromRatePPM = (ppm) => Number(ppm) / 1e4;
|
|
42582
|
+
var fetchRateOnChain = async () => {
|
|
42583
|
+
const [ppm] = await multicallRetryUniversal({
|
|
42584
|
+
chain: Chain.ETHEREUM_MAINNET,
|
|
42585
|
+
abi: RATE_ABI2,
|
|
42586
|
+
calls: [
|
|
42587
|
+
{
|
|
42588
|
+
address: FRANKENCOIN_SAVINGS_MODULE,
|
|
42589
|
+
name: "currentRatePPM",
|
|
42590
|
+
params: []
|
|
42591
|
+
}
|
|
42592
|
+
],
|
|
42593
|
+
allowFailure: false
|
|
42594
|
+
});
|
|
42595
|
+
if (ppm === void 0 || ppm === null) {
|
|
42596
|
+
throw new Error("Frankencoin: unreadable currentRatePPM()");
|
|
42597
|
+
}
|
|
42598
|
+
return aprFromRatePPM(ppm);
|
|
42599
|
+
};
|
|
42600
|
+
var fetchRateFromApi = async () => {
|
|
42601
|
+
const res = await fetch(SAVINGS_INFO_URL, {
|
|
42602
|
+
headers: { accept: "application/json" },
|
|
42603
|
+
signal: AbortSignal.timeout(8e3)
|
|
42604
|
+
});
|
|
42605
|
+
if (!res.ok) throw new Error(`Frankencoin: savings info HTTP ${res.status}`);
|
|
42606
|
+
const body = await res.json();
|
|
42607
|
+
const rate = body?.status?.[String(Chain.ETHEREUM_MAINNET)]?.[FRANKENCOIN_SAVINGS_MODULE]?.rate;
|
|
42608
|
+
if (typeof rate !== "number" || !Number.isFinite(rate)) {
|
|
42609
|
+
throw new Error("Frankencoin: savings info carried no rate for the module");
|
|
42610
|
+
}
|
|
42611
|
+
return aprFromRatePPM(rate);
|
|
42612
|
+
};
|
|
42613
|
+
var frankencoinSavingsFetcher = {
|
|
42614
|
+
label: "FRANKENCOIN_SAVINGS",
|
|
42615
|
+
fetch: async () => {
|
|
42616
|
+
const legs = await Promise.allSettled([
|
|
42617
|
+
fetchRateOnChain(),
|
|
42618
|
+
fetchRateFromApi()
|
|
42619
|
+
]);
|
|
42620
|
+
const onChain = legs[0];
|
|
42621
|
+
if (onChain.status === "fulfilled") {
|
|
42622
|
+
return { [ZCHF_SAVINGS_KEY]: onChain.value };
|
|
42623
|
+
}
|
|
42624
|
+
const api = legs[1];
|
|
42625
|
+
if (api.status === "fulfilled") {
|
|
42626
|
+
return { [ZCHF_SAVINGS_KEY]: api.value };
|
|
42627
|
+
}
|
|
42628
|
+
throw new Error(
|
|
42629
|
+
`Frankencoin: both rate legs failed (chain: ${String(
|
|
42630
|
+
onChain.reason
|
|
42631
|
+
)}; api: ${String(api.reason)})`
|
|
42632
|
+
);
|
|
42633
|
+
}
|
|
42634
|
+
};
|
|
40725
42635
|
|
|
40726
42636
|
// src/yields/intrinsic/fetchers/nativeCreditPool.ts
|
|
40727
42637
|
var nativeCreditPoolYieldKey = (chainId, underlying) => `${chainId}:${underlying.toLowerCase()}`;
|
|
@@ -42830,6 +44740,50 @@ var SINGLE_CHAIN_ENTRIES = {
|
|
|
42830
44740
|
withdrawalCooldownSeconds: 90 * 86400,
|
|
42831
44741
|
yieldFetcher: reProtocolFetcher,
|
|
42832
44742
|
yieldKey: REUSDE_KEY
|
|
44743
|
+
},
|
|
44744
|
+
{
|
|
44745
|
+
// Frankencoin savings module — a Swiss-franc savings account, not
|
|
44746
|
+
// a vault. There is NO share token: `save(amount)` books ZCHF into
|
|
44747
|
+
// an internal `savings(address)` account and `withdraw(target,
|
|
44748
|
+
// amount)` pays it back out, so the position is a balance that
|
|
44749
|
+
// grows in place (`isRebasing: true`, `exchangeRate` pinned at
|
|
44750
|
+
// par) and the module's own ZCHF balance is the whole book. Hence
|
|
44751
|
+
// the bespoke `frankencoin-savings` reader.
|
|
44752
|
+
//
|
|
44753
|
+
// TRAP — the published address config is stale. `@frankencoin/zchf`
|
|
44754
|
+
// exports `savingsV2 = 0x3BF301B0…`, which now runs at 1 % and
|
|
44755
|
+
// holds 17k ZCHF; the live module is the `savingsReferral`
|
|
44756
|
+
// deployment below, at 3.5 % holding 12.17M (verified on-chain
|
|
44757
|
+
// 2026-08-04, `currentRatePPM() = 35000`). Both answer
|
|
44758
|
+
// `currentRatePPM()`, so only the balance distinguishes them.
|
|
44759
|
+
//
|
|
44760
|
+
// `symbol: 'ZCHF'` is deliberate. `fetchPublic` composes
|
|
44761
|
+
// `displayName` from the *underlying's* token-list symbol
|
|
44762
|
+
// (→ "Frankencoin ZCHF"), so `symbol` only drives `name` and the
|
|
44763
|
+
// ticker a vault list renders — and the honest ticker for a
|
|
44764
|
+
// position denominated 1:1 in ZCHF is ZCHF. Inventing `sZCHF`
|
|
44765
|
+
// would name a token that does not exist, and `svZCHF` is already
|
|
44766
|
+
// taken by an unrelated third-party ERC-4626 wrapper
|
|
44767
|
+
// (0x637f00cA…, ~1 ZCHF of TVL) that would then be conflated with
|
|
44768
|
+
// this row.
|
|
44769
|
+
//
|
|
44770
|
+
// Exit is instant and never short (withdrawals are paid from the
|
|
44771
|
+
// module's own balance), but the YIELD is not instant:
|
|
44772
|
+
// `INTEREST_DELAY` is 3 days and a top-up re-weights the account's
|
|
44773
|
+
// tick counter, so exiting early can realise ~0 %.
|
|
44774
|
+
reader: "frankencoin-savings",
|
|
44775
|
+
address: "0x27d9ad987bde08a0d083ef7e0e4043c857a17b38",
|
|
44776
|
+
underlying: "0xb58e61c3098d85632df34eecfb899a1ed80921cb",
|
|
44777
|
+
// ZCHF
|
|
44778
|
+
symbol: "ZCHF",
|
|
44779
|
+
brand: "Frankencoin",
|
|
44780
|
+
description: "ZCHF is Frankencoin's decentralised Swiss-franc stablecoin, minted against collateral in permissionless, auction-policed positions. The savings module pays a governance-set rate funded by borrower interest: deposits are never lent on (they sit segregated inside the module) and interest is minted by the protocol into your balance, so there are no shares and no share price. Withdrawals are instant and uncapped, but interest only starts accruing after 3 days and a top-up restarts that clock pro-rata, so a short stay can earn nothing.",
|
|
44781
|
+
decimals: 18,
|
|
44782
|
+
isRebasing: true,
|
|
44783
|
+
isMintable: true,
|
|
44784
|
+
withdrawalMode: "instant",
|
|
44785
|
+
yieldFetcher: frankencoinSavingsFetcher,
|
|
44786
|
+
yieldKey: ZCHF_SAVINGS_KEY
|
|
42833
44787
|
}
|
|
42834
44788
|
],
|
|
42835
44789
|
"42161": [
|
|
@@ -44608,14 +46562,15 @@ function parseExactlyResults(data, _meta, context) {
|
|
|
44608
46562
|
if (tracked.size > 0 && !tracked.has(market.toLowerCase())) continue;
|
|
44609
46563
|
const priceUSD = Number(usdPrice) / 1e18;
|
|
44610
46564
|
if (!(priceUSD > 0)) continue;
|
|
44611
|
-
const lenderKey = exactlyLenderKey(market);
|
|
44612
46565
|
entries.push({
|
|
44613
46566
|
asset,
|
|
44614
46567
|
// Direct USD price — no oracle-unit denomination, so raw == USD.
|
|
44615
46568
|
price: priceUSD,
|
|
44616
46569
|
priceUSD,
|
|
44617
|
-
|
|
44618
|
-
|
|
46570
|
+
// ONE Exactly key per chain (cross-margin); the asset segment of the
|
|
46571
|
+
// marketUid is what distinguishes the per-asset rows.
|
|
46572
|
+
marketUid: createMarketUid(chainId, EXACTLY_LENDER_KEY, asset),
|
|
46573
|
+
targetLender: EXACTLY_LENDER_KEY,
|
|
44619
46574
|
description: "Exactly market oracle (USD)"
|
|
44620
46575
|
});
|
|
44621
46576
|
}
|
|
@@ -50139,7 +52094,7 @@ query EvkByAssets($assets: [Bytes!]!) {
|
|
|
50139
52094
|
}
|
|
50140
52095
|
}
|
|
50141
52096
|
`;
|
|
50142
|
-
var
|
|
52097
|
+
var ZERO2 = 0n;
|
|
50143
52098
|
var RAY_TO_PERCENT3 = 1e25;
|
|
50144
52099
|
function readAddress2(field12) {
|
|
50145
52100
|
if (!field12) return void 0;
|
|
@@ -50154,28 +52109,28 @@ function parseVaultFee(v) {
|
|
|
50154
52109
|
return n;
|
|
50155
52110
|
}
|
|
50156
52111
|
function safeBigInt(v) {
|
|
50157
|
-
if (v == null || v === "") return
|
|
52112
|
+
if (v == null || v === "") return ZERO2;
|
|
50158
52113
|
try {
|
|
50159
52114
|
return BigInt(v);
|
|
50160
52115
|
} catch {
|
|
50161
|
-
return
|
|
52116
|
+
return ZERO2;
|
|
50162
52117
|
}
|
|
50163
52118
|
}
|
|
50164
52119
|
function computeWeightedSupplyApy(strategies, totalAssetsRaw, feePercent, evkIndex) {
|
|
50165
52120
|
if (!strategies?.length) return 0;
|
|
50166
52121
|
const totalAssets = safeBigInt(totalAssetsRaw);
|
|
50167
|
-
if (totalAssets ===
|
|
50168
|
-
let weightedRay =
|
|
52122
|
+
if (totalAssets === ZERO2) return 0;
|
|
52123
|
+
let weightedRay = ZERO2;
|
|
50169
52124
|
for (const s of strategies) {
|
|
50170
52125
|
const evk = s.strategy?.toLowerCase();
|
|
50171
52126
|
if (!evk) continue;
|
|
50172
52127
|
const apyRay = evkIndex.bySupplyApyRay.get(evk);
|
|
50173
52128
|
if (apyRay == null) continue;
|
|
50174
52129
|
const allocated = safeBigInt(s.allocatedAssets);
|
|
50175
|
-
if (allocated ===
|
|
52130
|
+
if (allocated === ZERO2) continue;
|
|
50176
52131
|
weightedRay += allocated * apyRay;
|
|
50177
52132
|
}
|
|
50178
|
-
if (weightedRay ===
|
|
52133
|
+
if (weightedRay === ZERO2) return 0;
|
|
50179
52134
|
const apyRayPerAsset = weightedRay / totalAssets;
|
|
50180
52135
|
const grossPercent = apyToAprPercent(Number(apyRayPerAsset) / RAY_TO_PERCENT3);
|
|
50181
52136
|
const netPercent = grossPercent * (1 - feePercent / 100);
|
|
@@ -50183,24 +52138,24 @@ function computeWeightedSupplyApy(strategies, totalAssetsRaw, feePercent, evkInd
|
|
|
50183
52138
|
}
|
|
50184
52139
|
function computeRealLiquidity(strategies, totalAssetsRaw, evkIndex) {
|
|
50185
52140
|
const totalAssets = safeBigInt(totalAssetsRaw);
|
|
50186
|
-
if (totalAssets ===
|
|
52141
|
+
if (totalAssets === ZERO2) return ZERO2;
|
|
50187
52142
|
if (evkIndex.byCash.size === 0 && evkIndex.bySupplyApyRay.size === 0) {
|
|
50188
52143
|
return totalAssets;
|
|
50189
52144
|
}
|
|
50190
52145
|
if (!strategies?.length) {
|
|
50191
52146
|
return totalAssets;
|
|
50192
52147
|
}
|
|
50193
|
-
let allocSum =
|
|
50194
|
-
let withdrawable =
|
|
52148
|
+
let allocSum = ZERO2;
|
|
52149
|
+
let withdrawable = ZERO2;
|
|
50195
52150
|
for (const s of strategies) {
|
|
50196
52151
|
const alloc = safeBigInt(s.allocatedAssets);
|
|
50197
|
-
if (alloc ===
|
|
52152
|
+
if (alloc === ZERO2) continue;
|
|
50198
52153
|
allocSum += alloc;
|
|
50199
52154
|
const evk = s.strategy?.toLowerCase();
|
|
50200
52155
|
const cash = evk ? evkIndex.byCash.get(evk) : void 0;
|
|
50201
52156
|
withdrawable += cash == null ? alloc : alloc < cash ? alloc : cash;
|
|
50202
52157
|
}
|
|
50203
|
-
const idle = totalAssets > allocSum ? totalAssets - allocSum :
|
|
52158
|
+
const idle = totalAssets > allocSum ? totalAssets - allocSum : ZERO2;
|
|
50204
52159
|
const result = idle + withdrawable;
|
|
50205
52160
|
return result > totalAssets ? totalAssets : result;
|
|
50206
52161
|
}
|
|
@@ -50504,11 +52459,11 @@ var fetchEulerEarnVaults = async (chainId, prices = {}, tokenList = {}, multical
|
|
|
50504
52459
|
};
|
|
50505
52460
|
var warn6 = (...args) => {
|
|
50506
52461
|
};
|
|
50507
|
-
var
|
|
52462
|
+
var num3 = (v) => {
|
|
50508
52463
|
const n = Number(v);
|
|
50509
52464
|
return Number.isFinite(n) ? n : 0;
|
|
50510
52465
|
};
|
|
50511
|
-
var
|
|
52466
|
+
var big11 = (v) => {
|
|
50512
52467
|
try {
|
|
50513
52468
|
if (v === void 0 || v === null || v === "") return "0";
|
|
50514
52469
|
const s = String(v);
|
|
@@ -50539,21 +52494,21 @@ async function fetchTermMaxVaultsFromApi(chainId, prices = {}, tokenList = {}, f
|
|
|
50539
52494
|
const underlying = lower2(r?.asset?.contractAddress);
|
|
50540
52495
|
if (!address || !underlying) continue;
|
|
50541
52496
|
if (r.isEnabled === false) continue;
|
|
50542
|
-
const assetDecimals =
|
|
52497
|
+
const assetDecimals = num3(r?.asset?.decimals) || 18;
|
|
50543
52498
|
const scale = 10 ** assetDecimals;
|
|
50544
52499
|
const assetEntry = tokenList[underlying];
|
|
50545
52500
|
const priceKey = toOracleKey(assetEntry?.assetGroup) || toGenericPriceKey(underlying, chainId);
|
|
50546
52501
|
const priceUsd = prices[priceKey];
|
|
50547
|
-
const totalAssets =
|
|
50548
|
-
const totalSupply =
|
|
52502
|
+
const totalAssets = big11(r.totalAssets);
|
|
52503
|
+
const totalSupply = big11(r.totalSupplyAmt);
|
|
50549
52504
|
const totalAssetsFormatted = Number(totalAssets) / scale;
|
|
50550
|
-
const supplyRate =
|
|
50551
|
-
const rewardsRate =
|
|
50552
|
-
const rawLiquidity = BigInt(
|
|
52505
|
+
const supplyRate = num3(r.apr) * 100;
|
|
52506
|
+
const rewardsRate = num3(r?.incentiveData?.TMX_APR) * 100;
|
|
52507
|
+
const rawLiquidity = BigInt(big11(r.redeemableAmt ?? r.idleFunds ?? "0"));
|
|
50553
52508
|
const totalAssetsBig = BigInt(totalAssets);
|
|
50554
52509
|
const liquidity = (rawLiquidity > totalAssetsBig ? totalAssetsBig : rawLiquidity).toString();
|
|
50555
52510
|
const liquidityFormatted = Number(liquidity) / scale;
|
|
50556
|
-
const totalSupplyValue =
|
|
52511
|
+
const totalSupplyValue = num3(r.totalSupplyValue);
|
|
50557
52512
|
out[address] = {
|
|
50558
52513
|
address,
|
|
50559
52514
|
underlying,
|
|
@@ -50570,8 +52525,8 @@ async function fetchTermMaxVaultsFromApi(chainId, prices = {}, tokenList = {}, f
|
|
|
50570
52525
|
rewardsRate,
|
|
50571
52526
|
depositRate: supplyRate + rewardsRate,
|
|
50572
52527
|
// 1e8-scaled upstream (10000000 = 10%).
|
|
50573
|
-
fee:
|
|
50574
|
-
timelock:
|
|
52528
|
+
fee: num3(r.performanceFeeRate) / 1e6,
|
|
52529
|
+
timelock: num3(r.timeLockSeconds) || void 0,
|
|
50575
52530
|
curator: r?.curator?.curatorAddress ? lower2(r.curator.curatorAddress) : void 0,
|
|
50576
52531
|
// The API is the ONLY source for this — do not derive it from `name`.
|
|
50577
52532
|
curatorName: r?.curator?.name || void 0,
|
|
@@ -50585,7 +52540,7 @@ async function fetchTermMaxVaultsFromApi(chainId, prices = {}, tokenList = {}, f
|
|
|
50585
52540
|
liquidityUsd: priceUsd ? liquidityFormatted * priceUsd : 0,
|
|
50586
52541
|
version: r.version,
|
|
50587
52542
|
isPaused: r.isPaused === true || void 0,
|
|
50588
|
-
supplyCap: r.capacity ?
|
|
52543
|
+
supplyCap: r.capacity ? big11(r.capacity) : void 0,
|
|
50589
52544
|
basePool: r.poolAddress ? lower2(r.poolAddress) : void 0
|
|
50590
52545
|
};
|
|
50591
52546
|
}
|
|
@@ -50641,7 +52596,7 @@ var Erc20DecimalsBalanceAbi = [
|
|
|
50641
52596
|
|
|
50642
52597
|
// src/vaults/termmax/fetchFromChain.ts
|
|
50643
52598
|
var DECIMAL_BASE2 = 100000000n;
|
|
50644
|
-
var
|
|
52599
|
+
var big12 = (v) => {
|
|
50645
52600
|
if (v === void 0 || v === null || v === "0x") return 0n;
|
|
50646
52601
|
try {
|
|
50647
52602
|
return typeof v === "bigint" ? v : BigInt(v);
|
|
@@ -50649,7 +52604,7 @@ var big8 = (v) => {
|
|
|
50649
52604
|
return 0n;
|
|
50650
52605
|
}
|
|
50651
52606
|
};
|
|
50652
|
-
var
|
|
52607
|
+
var num4 = (v) => {
|
|
50653
52608
|
const n = Number(v);
|
|
50654
52609
|
return Number.isFinite(n) ? n : void 0;
|
|
50655
52610
|
};
|
|
@@ -50705,23 +52660,23 @@ var fetchTermMaxVaultsFromChain = async (chainId, multicallRetry, prices = {}, t
|
|
|
50705
52660
|
vaults.forEach((address, i) => {
|
|
50706
52661
|
const at = (k) => res[i * READS_PER_VAULT + VAULT_READS.indexOf(k)];
|
|
50707
52662
|
const asset = addr(at("asset"));
|
|
50708
|
-
const totalAssets =
|
|
52663
|
+
const totalAssets = big12(at("totalAssets"));
|
|
50709
52664
|
if (!asset || totalAssets === 0n) return;
|
|
50710
52665
|
rows.push({
|
|
50711
52666
|
address,
|
|
50712
52667
|
name: str(at("name")),
|
|
50713
52668
|
symbol: str(at("symbol")),
|
|
50714
|
-
decimals:
|
|
52669
|
+
decimals: num4(at("decimals")) ?? 18,
|
|
50715
52670
|
asset,
|
|
50716
52671
|
totalAssets,
|
|
50717
|
-
totalSupply:
|
|
50718
|
-
annualizedInterest:
|
|
50719
|
-
accretingPrincipal:
|
|
50720
|
-
performanceFeeRate:
|
|
50721
|
-
aprRaw: at("apr") != null ?
|
|
52672
|
+
totalSupply: big12(at("totalSupply")),
|
|
52673
|
+
annualizedInterest: big12(at("annualizedInterest")),
|
|
52674
|
+
accretingPrincipal: big12(at("accretingPrincipal")),
|
|
52675
|
+
performanceFeeRate: big12(at("performanceFeeRate")),
|
|
52676
|
+
aprRaw: at("apr") != null ? big12(at("apr")) : void 0,
|
|
50722
52677
|
curator: addr(at("curator")),
|
|
50723
52678
|
guardian: addr(at("guardian")),
|
|
50724
|
-
timelock:
|
|
52679
|
+
timelock: num4(at("timelock")),
|
|
50725
52680
|
version: str(at("getVersion"))
|
|
50726
52681
|
});
|
|
50727
52682
|
});
|
|
@@ -50738,8 +52693,8 @@ var fetchTermMaxVaultsFromChain = async (chainId, multicallRetry, prices = {}, t
|
|
|
50738
52693
|
});
|
|
50739
52694
|
const out = {};
|
|
50740
52695
|
rows.forEach((r, i) => {
|
|
50741
|
-
const assetDecimals =
|
|
50742
|
-
const idle =
|
|
52696
|
+
const assetDecimals = num4(res2[i * 2]) ?? r.decimals;
|
|
52697
|
+
const idle = big12(res2[i * 2 + 1]);
|
|
50743
52698
|
const assetEntry = tokenList[r.asset];
|
|
50744
52699
|
const priceKey = toOracleKey(assetEntry?.assetGroup) || toGenericPriceKey(r.asset, chainId);
|
|
50745
52700
|
const priceUsd = prices[priceKey];
|
|
@@ -56142,6 +58097,20 @@ var NativeWithdrawQueueReadAbi = [
|
|
|
56142
58097
|
}
|
|
56143
58098
|
];
|
|
56144
58099
|
|
|
58100
|
+
// src/vaults/savings/abis/frankencoin.ts
|
|
58101
|
+
var FrankencoinSavingsReadAbi = [
|
|
58102
|
+
{
|
|
58103
|
+
/** Savings rate in parts per million — `35000` = 3.5 % nominal APR.
|
|
58104
|
+
* `0` means the module is disabled (`save` reverts with
|
|
58105
|
+
* `ModuleDisabled`); existing balances stay withdrawable. */
|
|
58106
|
+
name: "currentRatePPM",
|
|
58107
|
+
type: "function",
|
|
58108
|
+
stateMutability: "view",
|
|
58109
|
+
inputs: [],
|
|
58110
|
+
outputs: [{ type: "uint24" }]
|
|
58111
|
+
}
|
|
58112
|
+
];
|
|
58113
|
+
|
|
56145
58114
|
// src/vaults/savings/abis/yearnStrategy.ts
|
|
56146
58115
|
var AvailableWithdrawLimitAbi = [
|
|
56147
58116
|
{
|
|
@@ -56241,6 +58210,29 @@ var readerErc4626WithdrawLimit = (entry) => {
|
|
|
56241
58210
|
};
|
|
56242
58211
|
};
|
|
56243
58212
|
|
|
58213
|
+
// src/vaults/savings/readers/frankencoinSavings.ts
|
|
58214
|
+
var readerFrankencoinSavings = (entry) => ({
|
|
58215
|
+
calls: [
|
|
58216
|
+
{ address: entry.underlying, name: "balanceOf", params: [entry.address] },
|
|
58217
|
+
{ address: entry.address, name: "currentRatePPM", params: [] }
|
|
58218
|
+
],
|
|
58219
|
+
abis: [BalanceOfAbi, FrankencoinSavingsReadAbi],
|
|
58220
|
+
parse: ([balance, ratePPM]) => {
|
|
58221
|
+
const deposits = toBigInt15(balance);
|
|
58222
|
+
if (deposits === void 0) return void 0;
|
|
58223
|
+
if (toBigInt15(ratePPM) === void 0) return void 0;
|
|
58224
|
+
return {
|
|
58225
|
+
totalAssets: deposits,
|
|
58226
|
+
// No shares exist; the "supply" IS the deposited principal, and
|
|
58227
|
+
// the rate is fixed at par. Both are load-bearing downstream:
|
|
58228
|
+
// `fetchPublic` derives `convertToAssets` / `convertToShares` from
|
|
58229
|
+
// `exchangeRate`, and 1e18 makes them the identity.
|
|
58230
|
+
totalSupply: deposits,
|
|
58231
|
+
exchangeRate: ONE_E1811
|
|
58232
|
+
};
|
|
58233
|
+
}
|
|
58234
|
+
});
|
|
58235
|
+
|
|
56244
58236
|
// src/vaults/savings/readers/navOracle.ts
|
|
56245
58237
|
var readerNavOracle = (entry) => {
|
|
56246
58238
|
const shareUnit = 10n ** BigInt(entry.decimals);
|
|
@@ -56334,6 +58326,8 @@ var buildReader2 = (entry) => {
|
|
|
56334
58326
|
return readerNativeWnlp(entry);
|
|
56335
58327
|
case "nav-oracle":
|
|
56336
58328
|
return readerNavOracle(entry);
|
|
58329
|
+
case "frankencoin-savings":
|
|
58330
|
+
return readerFrankencoinSavings(entry);
|
|
56337
58331
|
case "erc4626-idle":
|
|
56338
58332
|
return readerErc4626Idle(entry);
|
|
56339
58333
|
case "erc4626-withdraw-limit":
|
|
@@ -56576,7 +58570,7 @@ var pickApr = (apr) => {
|
|
|
56576
58570
|
if (apr.inception != null) return { rate: apr.inception, window: "inception" };
|
|
56577
58571
|
return { rate: 0, window: "none" };
|
|
56578
58572
|
};
|
|
56579
|
-
var
|
|
58573
|
+
var num5 = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
56580
58574
|
function parseVault7(v, chainId, prices, tokenList) {
|
|
56581
58575
|
const address = (v?.address ?? "").toLowerCase();
|
|
56582
58576
|
const assetAddr = (v?.asset?.address ?? "").toLowerCase();
|
|
@@ -56592,14 +58586,14 @@ function parseVault7(v, chainId, prices, tokenList) {
|
|
|
56592
58586
|
parseRawAmount(totalAssetsRaw, assetDecimals)
|
|
56593
58587
|
);
|
|
56594
58588
|
const apr = {
|
|
56595
|
-
weekly:
|
|
56596
|
-
monthly:
|
|
56597
|
-
yearly:
|
|
56598
|
-
inception:
|
|
58589
|
+
weekly: num5(state.weeklyApr?.twrrNetApr),
|
|
58590
|
+
monthly: num5(state.monthlyApr?.twrrNetApr),
|
|
58591
|
+
yearly: num5(state.yearlyApr?.twrrNetApr),
|
|
58592
|
+
inception: num5(state.inceptionApr?.twrrNetApr)
|
|
56599
58593
|
};
|
|
56600
58594
|
const { rate: supplyRate, window: aprWindow } = pickApr(apr);
|
|
56601
58595
|
const oracleKey = toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(assetAddr, chainId);
|
|
56602
|
-
const apiTotalAssetsUsd =
|
|
58596
|
+
const apiTotalAssetsUsd = num5(state.totalAssetsUsd) ?? 0;
|
|
56603
58597
|
const impliedPriceUsd = totalAssetsFormatted > 0 ? apiTotalAssetsUsd / totalAssetsFormatted : 0;
|
|
56604
58598
|
const priceUsd = prices[oracleKey] ?? prices[assetAddr] ?? impliedPriceUsd;
|
|
56605
58599
|
const totalAssetsUsd = apiTotalAssetsUsd || totalAssetsFormatted * priceUsd;
|
|
@@ -56619,7 +58613,7 @@ function parseVault7(v, chainId, prices, tokenList) {
|
|
|
56619
58613
|
totalAssets: totalAssetsRaw,
|
|
56620
58614
|
totalSupply: totalSupplyRaw,
|
|
56621
58615
|
pricePerShare: state.pricePerShare?.toString() ?? "0",
|
|
56622
|
-
pricePerShareUsd:
|
|
58616
|
+
pricePerShareUsd: num5(state.pricePerShareUsd) ?? void 0,
|
|
56623
58617
|
supplyRate,
|
|
56624
58618
|
rewardsRate: 0,
|
|
56625
58619
|
depositRate: supplyRate,
|
|
@@ -56816,7 +58810,7 @@ var toBigInt16 = (v) => {
|
|
|
56816
58810
|
}
|
|
56817
58811
|
return void 0;
|
|
56818
58812
|
};
|
|
56819
|
-
var
|
|
58813
|
+
var num6 = (v) => {
|
|
56820
58814
|
const n = Number(v);
|
|
56821
58815
|
return Number.isFinite(n) ? n : 0;
|
|
56822
58816
|
};
|
|
@@ -56873,12 +58867,12 @@ var fetchAaveEarnVaults = async (chainId, multicallRetry, prices = {}, tokenList
|
|
|
56873
58867
|
const totalAssets = toBigInt16(slice2[0]) ?? totalSupply * convertToAssets / shareUnit;
|
|
56874
58868
|
const totalAssetsFormatted = Number(totalAssets) / 10 ** assetDecimals;
|
|
56875
58869
|
const asset = tokenList[underlyingLc];
|
|
56876
|
-
const priceUsd = prices[underlyingLc] ?? (v.balance?.usdPerToken != null ?
|
|
58870
|
+
const priceUsd = prices[underlyingLc] ?? (v.balance?.usdPerToken != null ? num6(v.balance.usdPerToken) : void 0);
|
|
56877
58871
|
const totalAssetsUsd = priceUsd !== void 0 ? totalAssetsFormatted * priceUsd : 0;
|
|
56878
|
-
const supplyRate =
|
|
58872
|
+
const supplyRate = num6(v.vaultApr?.formatted);
|
|
56879
58873
|
const rewardsRate = 0;
|
|
56880
58874
|
const depositRate = supplyRate + rewardsRate;
|
|
56881
|
-
const fee =
|
|
58875
|
+
const fee = num6(v.fee?.value);
|
|
56882
58876
|
const symbol = (v.shareSymbol ?? "").trim();
|
|
56883
58877
|
const shareName = (v.shareName ?? "").trim();
|
|
56884
58878
|
const name = shareName || symbol;
|
|
@@ -56915,7 +58909,7 @@ var fetchAaveEarnVaults = async (chainId, multicallRetry, prices = {}, tokenList
|
|
|
56915
58909
|
};
|
|
56916
58910
|
|
|
56917
58911
|
// src/vaults/upshift/fetchPublic.ts
|
|
56918
|
-
var
|
|
58912
|
+
var num7 = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
56919
58913
|
var isEvmAddress = (a) => /^0x[0-9a-fA-F]{40}$/.test(a);
|
|
56920
58914
|
var derivePricePerShare = (totalAssetsRaw, totalSupplyRaw, shareDecimals) => {
|
|
56921
58915
|
try {
|
|
@@ -56942,12 +58936,12 @@ function parseVault8(v, chainId, prices, tokenList) {
|
|
|
56942
58936
|
const totalAssetsFormatted = Number(
|
|
56943
58937
|
parseRawAmount(totalAssetsRaw, assetDecimals)
|
|
56944
58938
|
);
|
|
56945
|
-
const base =
|
|
56946
|
-
const campaign =
|
|
58939
|
+
const base = num7(v.apy?.apy) ?? 0;
|
|
58940
|
+
const campaign = num7(v.apy?.campaignApy);
|
|
56947
58941
|
const supplyRate = apyToAprPercent(base);
|
|
56948
58942
|
const rewardsRate = campaign != null ? apyToAprPercent(campaign) : 0;
|
|
56949
58943
|
const oracleKey = toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(assetAddr, chainId);
|
|
56950
|
-
const apiTvlUsd =
|
|
58944
|
+
const apiTvlUsd = num7(v.latest_reported_tvl) ?? 0;
|
|
56951
58945
|
const impliedPriceUsd = totalAssetsFormatted > 0 ? apiTvlUsd / totalAssetsFormatted : 0;
|
|
56952
58946
|
const priceUsd = prices[oracleKey] ?? prices[assetAddr] ?? impliedPriceUsd;
|
|
56953
58947
|
const totalAssetsUsd = apiTvlUsd || totalAssetsFormatted * priceUsd;
|
|
@@ -56972,10 +58966,10 @@ function parseVault8(v, chainId, prices, tokenList) {
|
|
|
56972
58966
|
rewardsRate,
|
|
56973
58967
|
depositRate: supplyRate + rewardsRate,
|
|
56974
58968
|
apy: {
|
|
56975
|
-
base:
|
|
58969
|
+
base: num7(v.apy?.apy),
|
|
56976
58970
|
campaign,
|
|
56977
|
-
points:
|
|
56978
|
-
underlying:
|
|
58971
|
+
points: num7(v.apy?.pointsApy),
|
|
58972
|
+
underlying: num7(v.apy?.underlyingApy)
|
|
56979
58973
|
},
|
|
56980
58974
|
isDepositPaused: v.isDepositPaused ?? false,
|
|
56981
58975
|
isWithdrawalPaused: v.isWithdrawalPaused ?? false,
|
|
@@ -57084,9 +59078,9 @@ var asBig = (v) => {
|
|
|
57084
59078
|
return null;
|
|
57085
59079
|
}
|
|
57086
59080
|
};
|
|
57087
|
-
var
|
|
59081
|
+
var num8 = (v) => typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
57088
59082
|
var toPct = (v) => {
|
|
57089
|
-
const n =
|
|
59083
|
+
const n = num8(v);
|
|
57090
59084
|
return n == null ? 0 : n * 100;
|
|
57091
59085
|
};
|
|
57092
59086
|
var deriveTotalSupply = (totalAssetsRaw, pricePerShareRaw, decimals) => {
|
|
@@ -57118,16 +59112,16 @@ function parseVault9(v, chainId, prices, tokenList) {
|
|
|
57118
59112
|
const totalAssetsFormatted = Number(
|
|
57119
59113
|
parseRawAmount(totalAssetsRaw, assetDecimals)
|
|
57120
59114
|
);
|
|
57121
|
-
const realized =
|
|
57122
|
-
const forward =
|
|
59115
|
+
const realized = num8(v.apr?.netAPR);
|
|
59116
|
+
const forward = num8(v.apr?.forwardAPR?.netAPR);
|
|
57123
59117
|
const isForwardApr = realized == null && forward != null;
|
|
57124
59118
|
const supplyRate = toPct(realized ?? forward);
|
|
57125
59119
|
const rewardsRate = toPct(v.apr?.extra?.stakingRewardsAPR);
|
|
57126
59120
|
const fee = toPct(v.apr?.fees?.performance);
|
|
57127
59121
|
const oracleKey = toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(assetAddr, chainId);
|
|
57128
|
-
const apiPrice =
|
|
59122
|
+
const apiPrice = num8(v.tvl?.price) ?? 0;
|
|
57129
59123
|
const priceUsd = prices[oracleKey] ?? prices[assetAddr] ?? apiPrice;
|
|
57130
|
-
const apiTvlUsd =
|
|
59124
|
+
const apiTvlUsd = num8(v.tvl?.tvl) ?? 0;
|
|
57131
59125
|
const totalAssetsUsd = apiTvlUsd || totalAssetsFormatted * priceUsd;
|
|
57132
59126
|
const name = (v.name ?? "").trim();
|
|
57133
59127
|
const symbol = (v.symbol ?? "").trim();
|
|
@@ -58115,23 +60109,23 @@ var priceGmMarkets = async (chainId, multicallRetry, markets, prices) => {
|
|
|
58115
60109
|
const indexMax = price(prices, m.indexToken)?.max;
|
|
58116
60110
|
if (Array.isArray(dsRes) && longMax != null && shortMax != null) {
|
|
58117
60111
|
const base = i * SLOTS;
|
|
58118
|
-
const
|
|
60112
|
+
const big13 = (j) => typeof dsRes[base + j] === "bigint" ? dsRes[base + j] : 0n;
|
|
58119
60113
|
const cap = computeDepositCapacityUsd(
|
|
58120
|
-
[info?.longTokenAmount, longMax,
|
|
58121
|
-
[info?.shortTokenAmount, shortMax,
|
|
60114
|
+
[info?.longTokenAmount, longMax, big13(0), big13(2)],
|
|
60115
|
+
[info?.shortTokenAmount, shortMax, big13(1), big13(3)]
|
|
58122
60116
|
);
|
|
58123
60117
|
if (cap != null) value.depositCapacityUsd = cap;
|
|
58124
60118
|
if (indexMax != null) {
|
|
58125
60119
|
const divisor = m.longToken.toLowerCase() === m.shortToken.toLowerCase() ? 2n : 1n;
|
|
58126
|
-
const reservedUsdLong = (
|
|
58127
|
-
const reservedUsdShort = (
|
|
60120
|
+
const reservedUsdLong = (big13(4) + big13(5)) / divisor * indexMax;
|
|
60121
|
+
const reservedUsdShort = (big13(6) + big13(7)) / divisor;
|
|
58128
60122
|
const liq = computeLiquidityUsd(
|
|
58129
60123
|
info?.longTokenUsd,
|
|
58130
60124
|
info?.shortTokenUsd,
|
|
58131
60125
|
reservedUsdLong,
|
|
58132
60126
|
reservedUsdShort,
|
|
58133
|
-
|
|
58134
|
-
|
|
60127
|
+
big13(8),
|
|
60128
|
+
big13(9)
|
|
58135
60129
|
);
|
|
58136
60130
|
if (liq != null)
|
|
58137
60131
|
value.liquidityUsd = Math.max(0, Math.min(liq, value.tvlUsd));
|
|
@@ -58330,27 +60324,27 @@ var fetchGmxExecutionFees = async (chainId, multicallRetry, gasPriceWei) => {
|
|
|
58330
60324
|
} catch {
|
|
58331
60325
|
return void 0;
|
|
58332
60326
|
}
|
|
58333
|
-
const
|
|
58334
|
-
const base =
|
|
58335
|
-
const mult =
|
|
60327
|
+
const big13 = (i) => typeof res[i] === "bigint" ? res[i] : 0n;
|
|
60328
|
+
const base = big13(0);
|
|
60329
|
+
const mult = big13(1);
|
|
58336
60330
|
if (base === 0n && mult === 0n) return void 0;
|
|
58337
60331
|
const PRECISION = 10n ** 30n;
|
|
58338
60332
|
const adjusted = (opGas) => base + opGas * mult / PRECISION;
|
|
58339
60333
|
const fee = (opGas) => (adjusted(opGas) * gasPriceWei).toString();
|
|
58340
|
-
const glvExtra =
|
|
60334
|
+
const glvExtra = big13(6) * GLV_NOMINAL_MARKET_COUNT;
|
|
58341
60335
|
return {
|
|
58342
60336
|
chainId,
|
|
58343
60337
|
gasPriceWei: gasPriceWei.toString(),
|
|
58344
|
-
deposit: fee(
|
|
58345
|
-
withdrawal: fee(
|
|
58346
|
-
glvDeposit: fee(
|
|
58347
|
-
glvWithdrawal: fee(
|
|
60338
|
+
deposit: fee(big13(2)),
|
|
60339
|
+
withdrawal: fee(big13(3)),
|
|
60340
|
+
glvDeposit: fee(big13(4) + glvExtra),
|
|
60341
|
+
glvWithdrawal: fee(big13(5) + glvExtra)
|
|
58348
60342
|
};
|
|
58349
60343
|
};
|
|
58350
60344
|
|
|
58351
60345
|
// src/vaults/gmx/fetchPublic.ts
|
|
58352
60346
|
var GMX_TOKEN_DECIMALS = 18;
|
|
58353
|
-
var
|
|
60347
|
+
var num9 = (n) => typeof n === "number" && Number.isFinite(n) ? n : 0;
|
|
58354
60348
|
var minDefined = (a, b) => a == null ? b : b == null ? a : Math.min(a, b);
|
|
58355
60349
|
var glvMarketRoomUsd = (cap, priceUsd) => {
|
|
58356
60350
|
const currentUsd = Number(cap.balanceAmount) / 1e18 * priceUsd;
|
|
@@ -58384,9 +60378,9 @@ var fetchGmxVaults = async (chainId, multicallRetry, options) => {
|
|
|
58384
60378
|
indexToken: indexToken ? indexToken.toLowerCase() : void 0,
|
|
58385
60379
|
longSymbol,
|
|
58386
60380
|
shortSymbol,
|
|
58387
|
-
apy:
|
|
58388
|
-
baseApy:
|
|
58389
|
-
bonusApr:
|
|
60381
|
+
apy: num9(entry?.apy),
|
|
60382
|
+
baseApy: num9(entry?.baseApy),
|
|
60383
|
+
bonusApr: num9(entry?.bonusApr),
|
|
58390
60384
|
yieldProfile: "volatile",
|
|
58391
60385
|
denomination: denominationFor(longSymbol, shortSymbol)
|
|
58392
60386
|
};
|
|
@@ -59563,6 +61557,6 @@ async function fetchTokenBalances(chainId, account, tokens, options = {}) {
|
|
|
59563
61557
|
return parseTokenBalanceResult(rawResult, prepared.query);
|
|
59564
61558
|
}
|
|
59565
61559
|
|
|
59566
|
-
export { ApiBookSource, DEFAULT_MIDNIGHT_API, DEFAULT_OUTLIER_GUARD, DEFAULT_STALE_REJECT_SECONDS, DEFAULT_TERMMAX_API, EMPTY_BALANCE, GMX_API_HOSTS, GMX_READ_CONTRACTS, GMX_SUPPORTED_CHAINS, HYPERCORE_VAULT_REGISTRY, IDLE_MARKET_ID, INTERFACE_IDS, LAGOON_API_URL, LAGOON_CHAIN_IDS, MORPHO_LENS, MaxParamThresholds, STABLECOIN_SYMBOLS, STCELO_MANAGER_ADDRESS, TELLER_CALLS_PER_BID, TERMMAX_CALLS_PER_ACCOUNT, DECIMAL_BASE as TERMMAX_DECIMAL_BASE, TERMMAX_LIQUIDATION_PENALTY, TERMMAX_LIQUIDATION_WINDOW_SECS, TERMMAX_LIQUIDATOR_BONUS, TERMMAX_PARTIAL_CLOSE_FACTOR, TERMMAX_PARTIAL_LIQUIDATION_THRESHOLD_USD, TermMaxApiSource, TermSubgraphSource, UPSHIFT_CHAIN_IDS, UPSHIFT_VAULTS_URL, VAULT_SHARE_PRICE_PROBE, VOLATILE_VAULT_OVERRIDES, YEARN_CHAIN_IDS, YEARN_YDAEMON_BASE, accountDepositListKey, accountWithdrawalListKey, appendSnapshot, applyPositionDelta, attachPricesToFlashLiquidity, buildFluidFTokensCall, buildLiquityUserCall, buildLoopResult, buildMorphoTypeCall, buildMorphoTypeUserCallWithLens, buildPortfolioTotals, buildSumerAccumulators, buildSummaries, buildTellerUserCall, buildTermMaxUserCall, buildVaultLookup, calculateLeverage, calculateNetApr, calculateOverallNetApr, calculateWeightedAverage, classifyFreshness, classifyReliability, classifyVault, 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, convertExactlyMarketsToResponse, convertInverseMarketsToResponse, convertLenderUserDataResult, convertLiquityMarketsToResponse, convertRiverMarketsToResponse, convertTellerMarketsToResponse, convertTermMarketsToResponse, convertTermMaxMarketsToResponse, convertUsddMarketsToResponse, createMarketUid, createMidnightBookSource, createMulticallRpcCall, createRawRpcCalls, createTermBookSource, createTermMaxDataSource, decodeListaMarkets, decodeMarkets, decodePackedListaUserDataset, decodePackedMorphoUserDataset, detectInterfaceKinds, encodeBalanceFetcherCalldata,
|
|
61560
|
+
export { ApiBookSource, DEFAULT_MIDNIGHT_API, DEFAULT_OUTLIER_GUARD, DEFAULT_STALE_REJECT_SECONDS, DEFAULT_TERMMAX_API, EMPTY_BALANCE, EXACTLY_LENDER_KEY, GMX_API_HOSTS, GMX_READ_CONTRACTS, GMX_SUPPORTED_CHAINS, HYPERCORE_VAULT_REGISTRY, IDLE_MARKET_ID, INTERFACE_IDS, LAGOON_API_URL, LAGOON_CHAIN_IDS, MORPHO_LENS, MaxParamThresholds, STABLECOIN_SYMBOLS, STCELO_MANAGER_ADDRESS, TELLER_CALLS_PER_BID, TERMMAX_CALLS_PER_ACCOUNT, DECIMAL_BASE as TERMMAX_DECIMAL_BASE, TERMMAX_LIQUIDATION_PENALTY, TERMMAX_LIQUIDATION_WINDOW_SECS, TERMMAX_LIQUIDATOR_BONUS, TERMMAX_PARTIAL_CLOSE_FACTOR, TERMMAX_PARTIAL_LIQUIDATION_THRESHOLD_USD, TermMaxApiSource, TermSubgraphSource, UPSHIFT_CHAIN_IDS, UPSHIFT_VAULTS_URL, VAULT_SHARE_PRICE_PROBE, VOLATILE_VAULT_OVERRIDES, YEARN_CHAIN_IDS, YEARN_YDAEMON_BASE, __resetResupplyUserCaches, accountDepositListKey, accountWithdrawalListKey, appendSnapshot, applyPositionDelta, attachPricesToFlashLiquidity, buildFluidFTokensCall, buildLiquityUserCall, buildLoopResult, buildMorphoTypeCall, buildMorphoTypeUserCallWithLens, buildPortfolioTotals, buildSumerAccumulators, buildSummaries, buildTellerUserCall, buildTermMaxUserCall, buildVaultLookup, calculateLeverage, calculateNetApr, calculateOverallNetApr, calculateWeightedAverage, classifyFreshness, classifyReliability, classifyVault, 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, convertExactlyMarketsToResponse, convertFrankencoinMarketsToResponse, convertInverseMarketsToResponse, convertLenderUserDataResult, convertLiquityMarketsToResponse, convertLlamaLendMarketsToResponse, convertResupplyMarketsToResponse, convertRiverMarketsToResponse, convertTellerMarketsToResponse, convertTermMarketsToResponse, convertTermMaxMarketsToResponse, convertUsddMarketsToResponse, createMarketUid, createMidnightBookSource, createMulticallRpcCall, createRawRpcCalls, createTermBookSource, createTermMaxDataSource, decodeListaMarkets, decodeMarkets, decodePackedListaUserDataset, decodePackedMorphoUserDataset, detectInterfaceKinds, encodeBalanceFetcherCalldata, exactlyPairLtv, exactlyPenaltyRateToAprPercent, exactlyWadRateToPercent, feedKeyOf, feedStatKey, fetchDolomiteAccountNumbers, fetchEulerEarnVaults, fetchEulerEarnVaultsFromSubgraph, fetchEulerSubAccountIndexes, fetchExactlyMarkets, fetchFlashLiquidityForChain, fetchFluidFTokens, fetchFrankencoinMarkets, fetchGeneralYields, fetchGeneralYieldsByMarketUid, fetchGmxExecutionFees, fetchGmxTickerPrices, fetchGmxVaults, fetchHypercoreVaults, fetchInverseMarkets, fetchLagoonApiVaults, fetchLagoonVaults, fetchLiquityMarkets, fetchListaVaultsFromChain, fetchLlamaLendMarkets, fetchMorphoUserBalances, fetchMorphoUserPositionMarkets, fetchMorphoVaults, fetchMorphoVaultsFromApi, fetchMorphoVaultsFromChain, fetchOraclePrices, fetchPendlePrices, fetchResupplyMarkets, fetchRiverMarkets, fetchSiloVaults, fetchTellerMarkets, fetchTermMarkets, fetchTermMaxMarkets, fetchTokenBalances, fetchTokenMetadata, fetchUpshiftApiVaults, fetchUpshiftVaults, fetchUsddMarkets, fetchYearnApiVaults, fetchYearnVaults, filterActiveLenders, filterLendersByProtocol, frankencoinKeyParts, frankencoinLenderKey, fuseLenderData, generateLendingPools, getAavesForChain, getAssetConfig, getBalanceForMarketUid, getBorrowCapacity, 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, getResolvedDolomiteAccountNumbers, getStCeloValidatorGroups, getSubAccountAddress, getSubAccountIndex, getVaultPublicDataAll, getVaultWithdrawalRequests, hasEulerEarnVaultSubgraph, hasLagoonVaults, hasMorphoPositionIndex, hasMorphoUserApi, hasMorphoUserSubgraph, hasUpshiftVaults, hasYearnVaults, inverseKeyParts, inverseLenderKey, isStablecoinSymbol, isYearnV3, keysFromMaps, lenderApiOnly, lenderFamily, liquityCandidateTroveIds, liquityKeyParts, liquityLenderKey, llamaLendKeyParts, llamaLendLenderKey, multicall3Abi2 as multicall3Abi, nanTo, needsLenderApproval, needsTokenApproval, noOpResult, normalizeToBytes, parseBalanceFetcherResult, parseMergedResult, parseMulticallRpcResponses, parseRawRpcBatchResponses, parseRawRpcResponses, parseTermMaxLtv, parseTokenBalanceResult, positivePart2 as positivePart, predictInverseEscrow, prepareLenderUserDataRpcCalls, prepareMergedMulticallParams, prepareMergedRpcCalls, prepareMulticallInputs, prepareTokenBalanceRpcCalls, priceGlvVaults, priceGmMarkets, probeAaveFeedTimestamps, pruneFeedStats, readVaultSharePrices, rejectOutliers as rejectPriceOutliers, resolveDerivation, resolveStCeloDepositGroup, resupplyKeyParts, resupplyLenderKey, riverKeyParts, riverLenderKey, selectAssetGroupPrices, stampVaultClassification, tellerBpsToPercent, tellerImpliedLtv, tellerLenderKey, tellerPoolFromLenderKey, 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, tickToAprNumber, tickToPrice, unflattenLenderData, updateFeedStats, usddIlkBytes32, usddKeyParts, usddLenderKey };
|
|
59567
61561
|
//# sourceMappingURL=index.js.map
|
|
59568
61562
|
//# sourceMappingURL=index.js.map
|