@1delta/margin-fetcher 0.0.337 → 0.0.339

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.
Files changed (31) hide show
  1. package/dist/index.js +384 -212
  2. package/dist/index.js.map +1 -1
  3. package/dist/lending/public-data/liquity/convertPublic.d.ts +20 -0
  4. package/dist/lending/public-data/liquity/convertPublic.d.ts.map +1 -1
  5. package/dist/lending/public-data/liquity/types.d.ts +5 -1
  6. package/dist/lending/public-data/liquity/types.d.ts.map +1 -1
  7. package/dist/lending/user-data/aave-v2-type/userCallParse.d.ts.map +1 -1
  8. package/dist/lending/user-data/aave-v3-type/userCallParse.d.ts.map +1 -1
  9. package/dist/lending/user-data/aave-v3-type/userCallParseYldr.d.ts.map +1 -1
  10. package/dist/lending/user-data/compound-v2/userCallParse.d.ts.map +1 -1
  11. package/dist/lending/user-data/compound-v3/userCallParse.d.ts.map +1 -1
  12. package/dist/lending/user-data/dolomite/userCallParse.d.ts.map +1 -1
  13. package/dist/lending/user-data/euler/userCallParse.d.ts.map +1 -1
  14. package/dist/lending/user-data/fetch-balances/e2e.d.ts.map +1 -1
  15. package/dist/lending/user-data/fetch-balances/parse.d.ts +26 -1
  16. package/dist/lending/user-data/fetch-balances/parse.d.ts.map +1 -1
  17. package/dist/lending/user-data/init/userCallParse.d.ts.map +1 -1
  18. package/dist/lending/user-data/river/userCallParse.d.ts.map +1 -1
  19. package/dist/lending/user-data/teller/userCallParse.d.ts.map +1 -1
  20. package/dist/lending/user-data/utils/types.d.ts +7 -0
  21. package/dist/lending/user-data/utils/types.d.ts.map +1 -1
  22. package/dist/prices/oracle-prices/fetchers/liquity.d.ts +24 -0
  23. package/dist/prices/oracle-prices/fetchers/liquity.d.ts.map +1 -1
  24. package/dist/utils/multicall.d.ts +41 -12
  25. package/dist/utils/multicall.d.ts.map +1 -1
  26. package/dist/yields/rewards/fetchLenderRewards.d.ts.map +1 -1
  27. package/dist/yields/rewards/index.d.ts +1 -1
  28. package/dist/yields/rewards/index.d.ts.map +1 -1
  29. package/dist/yields/rewards/merkl.d.ts +24 -0
  30. package/dist/yields/rewards/merkl.d.ts.map +1 -1
  31. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -22206,6 +22206,15 @@ function liquityKeyParts(key) {
22206
22206
  return { lender: base, chainId: m[1], collIndex: Number(m[2]) };
22207
22207
  }
22208
22208
  var WAD6 = 1e18;
22209
+ var MAX_PLAUSIBLE_UNIT_USD = 1e7;
22210
+ function liquityCollateralPrice(raw, collDecimals, priceDecimals) {
22211
+ if (raw == null || raw <= 0n) return 0;
22212
+ if (priceDecimals != null) return Number(raw) / 10 ** priceDecimals;
22213
+ const plain = Number(raw) / WAD6;
22214
+ if (collDecimals >= 18 || plain <= MAX_PLAUSIBLE_UNIT_USD) return plain;
22215
+ const adjusted = Number(raw) / 10 ** (36 - collDecimals);
22216
+ return adjusted <= MAX_PLAUSIBLE_UNIT_USD ? adjusted : 0;
22217
+ }
22209
22218
  function toHuman2(raw, decimals) {
22210
22219
  return Number(raw) / 10 ** decimals;
22211
22220
  }
@@ -22237,7 +22246,7 @@ function convertLiquityMarketsToResponse(raw, chainId, prices = {}, _additionalY
22237
22246
  const collSymbol = collToken?.symbol ?? branch.name?.split(" / ").pop() ?? "COLL";
22238
22247
  const marketName = branch.name ?? `${stableSymbol} / ${collSymbol}`;
22239
22248
  const collPriceKey = toOracleKey(collToken?.assetGroup) || toGenericPriceKey(collAddr, chainId);
22240
- const collPrice = (b.collPrice !== null ? Number(b.collPrice) / WAD6 : 0) || (prices[collPriceKey] ?? 0);
22249
+ const collPrice = liquityCollateralPrice(b.collPrice, collDecimals, branch.priceDecimals) || (prices[collPriceKey] ?? 0);
22241
22250
  const entireDebt = b.entireDebt !== null ? toHuman2(b.entireDebt, stableDecimals) : 0;
22242
22251
  const entireColl = b.entireColl !== null ? toHuman2(b.entireColl, collDecimals) : 0;
22243
22252
  const spDeposits = b.spDeposits !== null ? toHuman2(b.spDeposits, stableDecimals) : 0;
@@ -24149,6 +24158,244 @@ var buildCompoundV2UserCall = (chainId, lender, account) => {
24149
24158
  ];
24150
24159
  return calls;
24151
24160
  };
24161
+
24162
+ // src/utils/constants.ts
24163
+ var MULTICALL_DEFAULT_BATCH_SIZE = 4096;
24164
+ var CELO_MULTICALL_ADDRESS = "0x633987602DE5C4F337e3DbF265303A1080324204";
24165
+ var BNB_MULTICALL_ADDRESS = "0x963Df249eD09c358A4819E39d9Cd5736c3087184";
24166
+ var MANTLE_MULTICALL_ADDRESS = "0x2A51f2F647E1883F88C992244dEd171238693107";
24167
+ var ARBITRUM_ONE_MULTICALL_ADDRESS = "0xadF885960B47eA2CD9B55E6DAc6B42b7Cb2806dB";
24168
+ var LINEA_MULTICALL_ADDRESS = "0xac1cE734566f390A94b00eb9bf561c2625BF44ea";
24169
+ var AVALANCHE_MULTICALL_ADDRESS = "0x0139141Cd4Ee88dF3Cdb65881D411bAE271Ef0C2";
24170
+ var BASE_MULTICALL_ADDRESS = "0x091e99cb1C49331a94dD62755D168E941AbD0693";
24171
+ var BLAST_MULTICALL_ADDRESS = "0xdC7f370de7631cE9e2c2e1DCDA6B3B5744Cf4705";
24172
+ var TAIKO_MULTICALL_ADDRESS = "0x8E24CfC19c6C00c524353CB8816f5f1c2F33c201";
24173
+ var HEMI_MULTICALL_ADDRESS = "0x352A86168e6988A1aDF9A15Cb00017AAd3B67155";
24174
+ var GNOSIS_MULTICALL_ADDRESS = "0x4dfa9a980efE4802E969AC33968E3d6E59B8a19e";
24175
+ var MODE_MULTICALL_ADDRESS = "0xAB39cE30D98a59DFDa40A630b074170800bfF179";
24176
+ var FANTOM_MULTICALL_ADDRESS = "0xDb51CffFf3B989d0cB6b58AbF173371b6F2d0D24";
24177
+ var SCROLL_MULTICALL_ADDRESS = "0x3b615B1AC55bc34e51a81D3dea67467F32bcb8C2";
24178
+ var SHAPE_MULTICALL_ADDRESS = "0x356A450B32f5030ae7083702b86FaFbBe7490411";
24179
+ var SONIC_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
24180
+ var INK_MULTICALL_ADDRESS = "0xA0fCec583AeE6176527C07B198e5561722332014";
24181
+ var METIS_MULTICALL_ADDRESS = "0x7a59ddbB76521E8982Fa3A08598C9a83b14A6C07";
24182
+ var IOTA_MULTICALL_ADDRESS = "0x9683D433621A83aA7dd290106e1da85251317F55";
24183
+ var KAVA_MULTICALL_ADDRESS = "0x8B741B0D79BE80E135C880F7583d427B4D41F015";
24184
+ var CORN_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
24185
+ var SAGA_MULTICALL_ADDRESS = "0x743E03cceB4af2efA3CC76838f6E8B50B63F184c";
24186
+ var CYBER_MULTICALL_ADDRESS = "0x906d6eB9CF8f64e100e44f8f491b833a8d40B530";
24187
+ var METAL_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
24188
+ var ZERO_MULTICALL_ADDRESS = "0x9CA4dcb2505fbf536F6c54AA0a77C79f4fBC35C0";
24189
+ var BOB_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
24190
+ var WORLDCHAIN_MULTICALL_ADDRESS = "0x0a22c04215c97E3F532F4eF30e0aD9458792dAB9";
24191
+ var LISK_MULTICALL_ADDRESS = "0xE3dbcD53f4Ce1b06Ab200f4912BD35672e68f1FA";
24192
+ var REDSTONE_MULTICALL_ADDRESS = "0xd57B52452a0FDfE3ff8e0A40Bd10D00D0bfe0723";
24193
+ var MANTA_MULTICALL_ADDRESS = "0x52dFC0D9960F11A9Ca9FF616e791B91188446a60";
24194
+ var ZORA_MULTICALL_ADDRESS = "0xA51c76bEE6746cB487a7e9312E43e2b8f4A37C15";
24195
+ var CORE_MULTICALL_ADDRESS = "0xFe9F82D820757787895Da00B1dBD35c3B8b04894";
24196
+ var MORPH_MULTICALL_ADDRESS = "0xAcD82113982479B25E7c1D09858F0130921Dbbca";
24197
+ var TELOS_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
24198
+ var MULTICALL_ADDRESS = {
24199
+ [Chain.OP_MAINNET]: "0x1F98415757620B543A52E61c46B32eB19261F984",
24200
+ [Chain.POLYGON_MAINNET]: "0x1F98415757620B543A52E61c46B32eB19261F984",
24201
+ [Chain.ETHEREUM_MAINNET]: "0x1F98415757620B543A52E61c46B32eB19261F984",
24202
+ [Chain.ARBITRUM_ONE]: ARBITRUM_ONE_MULTICALL_ADDRESS,
24203
+ [Chain.BASE]: BASE_MULTICALL_ADDRESS,
24204
+ [Chain.CELO_MAINNET]: CELO_MULTICALL_ADDRESS,
24205
+ [Chain.BNB_SMART_CHAIN_MAINNET]: BNB_MULTICALL_ADDRESS,
24206
+ [Chain.MANTLE]: MANTLE_MULTICALL_ADDRESS,
24207
+ [Chain.BLAST]: BLAST_MULTICALL_ADDRESS,
24208
+ [Chain.LINEA]: LINEA_MULTICALL_ADDRESS,
24209
+ [Chain.AVALANCHE_C_CHAIN]: AVALANCHE_MULTICALL_ADDRESS,
24210
+ [Chain.TAIKO_ALETHIA]: TAIKO_MULTICALL_ADDRESS,
24211
+ [Chain.HEMI_NETWORK]: HEMI_MULTICALL_ADDRESS,
24212
+ [Chain.GNOSIS]: GNOSIS_MULTICALL_ADDRESS,
24213
+ [Chain.CORE_BLOCKCHAIN_MAINNET]: CORE_MULTICALL_ADDRESS,
24214
+ [Chain.METIS_ANDROMEDA_MAINNET]: METIS_MULTICALL_ADDRESS,
24215
+ [Chain.MODE]: MODE_MULTICALL_ADDRESS,
24216
+ [Chain.INK]: INK_MULTICALL_ADDRESS,
24217
+ [Chain.IOTA_EVM]: IOTA_MULTICALL_ADDRESS,
24218
+ [Chain.CORN]: CORN_MULTICALL_ADDRESS,
24219
+ [Chain.SONIC_MAINNET]: SONIC_MULTICALL_ADDRESS,
24220
+ [Chain.FANTOM_OPERA]: FANTOM_MULTICALL_ADDRESS,
24221
+ [Chain.SCROLL]: SCROLL_MULTICALL_ADDRESS,
24222
+ [Chain.SHAPE]: SHAPE_MULTICALL_ADDRESS,
24223
+ [Chain.CYBER_MAINNET]: CYBER_MULTICALL_ADDRESS,
24224
+ [Chain.ZORA]: ZORA_MULTICALL_ADDRESS,
24225
+ [Chain.MANTA_PACIFIC_MAINNET]: MANTA_MULTICALL_ADDRESS,
24226
+ [Chain.REDSTONE]: REDSTONE_MULTICALL_ADDRESS,
24227
+ [Chain.KAVA]: KAVA_MULTICALL_ADDRESS,
24228
+ [Chain.METAL_L2]: METAL_MULTICALL_ADDRESS,
24229
+ [Chain.LISK]: LISK_MULTICALL_ADDRESS,
24230
+ [Chain.BOB]: BOB_MULTICALL_ADDRESS,
24231
+ [Chain.ZERO_NETWORK]: ZERO_MULTICALL_ADDRESS,
24232
+ [Chain.SAGA]: SAGA_MULTICALL_ADDRESS,
24233
+ [Chain.MORPH]: MORPH_MULTICALL_ADDRESS,
24234
+ [Chain.TELOS_EVM_MAINNET]: TELOS_MULTICALL_ADDRESS,
24235
+ [Chain.WORLD_CHAIN]: WORLDCHAIN_MULTICALL_ADDRESS
24236
+ };
24237
+
24238
+ // src/utils/multicall.ts
24239
+ var { isArray } = lodash;
24240
+ var maxRetries = 3;
24241
+ var MULTICALL_FAILURE = "0x";
24242
+ var isFailedCall = (value) => value === void 0 || value === null || value === MULTICALL_FAILURE;
24243
+ var retryFailedSlots = async (chainId, contracts, mapped, getEvmClient18, nextRpcId, batchSize, logs) => {
24244
+ const failedIdx = [];
24245
+ for (let i = 0; i < mapped.length; i++) {
24246
+ if (isFailedCall(mapped[i])) failedIdx.push(i);
24247
+ }
24248
+ if (failedIdx.length === 0) return mapped;
24249
+ try {
24250
+ const provider = getEvmClient18(chainId, nextRpcId);
24251
+ const returnData = await provider.multicall({
24252
+ allowFailure: true,
24253
+ batchSize,
24254
+ contracts: failedIdx.map((i) => contracts[i])
24255
+ });
24256
+ returnData.forEach((entry, k) => {
24257
+ if (entry?.status === "success") mapped[failedIdx[k]] = entry.result;
24258
+ });
24259
+ } catch (error) {
24260
+ if (logs) console.log("error in multicall failure-retry", error);
24261
+ }
24262
+ return mapped;
24263
+ };
24264
+ var multicallViemAbiArray = async (chainId, abi, calls, getEvmClient18, retry = true, providerId = 0, retries = maxRetries, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, logs = false, retryFailed = false) => {
24265
+ try {
24266
+ const provider = getEvmClient18(chainId, providerId);
24267
+ const abiIsArray = isArray(abi[0]);
24268
+ const contracts = calls.map(({ address, name, params }, i) => ({
24269
+ abi: abiIsArray ? abi?.[i] : abi,
24270
+ address,
24271
+ functionName: name,
24272
+ args: params
24273
+ }));
24274
+ const returnData = await provider.multicall({
24275
+ allowFailure,
24276
+ batchSize,
24277
+ contracts
24278
+ });
24279
+ if (!allowFailure) return returnData;
24280
+ const res = returnData.map(
24281
+ ({ result, status }) => status !== "success" ? MULTICALL_FAILURE : result
24282
+ );
24283
+ if (!retryFailed) return res;
24284
+ return retryFailedSlots(
24285
+ chainId,
24286
+ contracts,
24287
+ res,
24288
+ getEvmClient18,
24289
+ providerId + 1,
24290
+ batchSize,
24291
+ logs
24292
+ );
24293
+ } catch (error) {
24294
+ if (logs) console.log("error in multicall", error);
24295
+ retries--;
24296
+ if (retries < 0) throw new Error("Failed too often");
24297
+ providerId++;
24298
+ return multicallViemAbiArray(
24299
+ chainId,
24300
+ abi,
24301
+ calls,
24302
+ getEvmClient18,
24303
+ retry,
24304
+ providerId,
24305
+ retries,
24306
+ allowFailure,
24307
+ batchSize,
24308
+ logs,
24309
+ retryFailed
24310
+ );
24311
+ }
24312
+ };
24313
+ var multicallShardedAbiArray = async (chainId, abi, calls, getEvmClient18, poolSize, retries = maxRetries, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, logs = false, retryFailed = false) => {
24314
+ if (poolSize <= 1) {
24315
+ return multicallViemAbiArray(
24316
+ chainId,
24317
+ abi,
24318
+ calls,
24319
+ getEvmClient18,
24320
+ true,
24321
+ 0,
24322
+ retries,
24323
+ allowFailure,
24324
+ batchSize,
24325
+ logs,
24326
+ retryFailed
24327
+ );
24328
+ }
24329
+ const abiIsArray = isArray(abi[0]);
24330
+ const contracts = calls.map(({ address, name, params }, i) => ({
24331
+ abi: abiIsArray ? abi?.[i] : abi,
24332
+ address,
24333
+ functionName: name,
24334
+ args: params
24335
+ }));
24336
+ const shardSize = Math.max(1, Math.ceil(contracts.length / poolSize));
24337
+ const batches = [];
24338
+ for (let i = 0; i < contracts.length; i += shardSize) {
24339
+ batches.push({ start: i, items: contracts.slice(i, i + shardSize) });
24340
+ }
24341
+ const results = new Array(contracts.length);
24342
+ const runBatch = async (batch, rpcId, attemptsLeft, size) => {
24343
+ try {
24344
+ const provider = getEvmClient18(chainId, rpcId);
24345
+ const returnData = await provider.multicall({
24346
+ allowFailure,
24347
+ batchSize: size,
24348
+ contracts: batch.items
24349
+ });
24350
+ let mapped = allowFailure ? returnData.map(
24351
+ ({ result, status }) => status !== "success" ? MULTICALL_FAILURE : result
24352
+ ) : returnData;
24353
+ if (allowFailure && retryFailed) {
24354
+ mapped = await retryFailedSlots(
24355
+ chainId,
24356
+ batch.items,
24357
+ mapped,
24358
+ getEvmClient18,
24359
+ rpcId + 1,
24360
+ size,
24361
+ logs
24362
+ );
24363
+ }
24364
+ for (let j = 0; j < mapped.length; j++) {
24365
+ results[batch.start + j] = mapped[j];
24366
+ }
24367
+ } catch (error) {
24368
+ if (logs) console.log("error in sharded multicall batch", error);
24369
+ if (attemptsLeft <= 0) throw error;
24370
+ return runBatch(
24371
+ batch,
24372
+ rpcId + 1,
24373
+ attemptsLeft - 1,
24374
+ Math.max(1, Math.floor(size / 2))
24375
+ );
24376
+ }
24377
+ };
24378
+ const workers = Math.max(1, Math.min(poolSize, batches.length));
24379
+ let cursor = 0;
24380
+ const worker = async (workerId) => {
24381
+ while (true) {
24382
+ const idx = cursor++;
24383
+ if (idx >= batches.length) break;
24384
+ await runBatch(batches[idx], workerId, retries, batchSize);
24385
+ }
24386
+ };
24387
+ await Promise.all(Array.from({ length: workers }, (_3, w) => worker(w)));
24388
+ return results;
24389
+ };
24390
+ function prepareMulticallInputs(abi, calls) {
24391
+ const abiIsArray = isArray(abi[0]);
24392
+ return calls.map(({ address, name, params }, i) => ({
24393
+ address,
24394
+ functionName: name,
24395
+ params: params || [],
24396
+ abi: abiIsArray ? abi[i] : abi
24397
+ }));
24398
+ }
24152
24399
  var getCompoundV2UserDataConverter = (lender, chainId, account, metaMap) => {
24153
24400
  switch (lender) {
24154
24401
  default: {
@@ -24203,10 +24450,15 @@ var getCompoundV2UserDataConverter = (lender, chainId, account, metaMap) => {
24203
24450
  }
24204
24451
  };
24205
24452
  function createCompoundV2Entry(i, data, key, assetsIn, vToken, meta, claimableRewards) {
24206
- const _depositsRaw = data[3 * i].toString();
24207
- const _borrowsRaw = data[3 * i + 1].toString();
24208
- const depositsRaw = _depositsRaw === "0x" ? "0" : _depositsRaw;
24209
- const borrowsRaw = _borrowsRaw === "0x" ? "0" : _borrowsRaw;
24453
+ if (isFailedCall(data[3 * i]) || isFailedCall(data[3 * i + 1])) {
24454
+ return {
24455
+ dataForAsset: void 0,
24456
+ addedDeposits: 0,
24457
+ addedDebt: 0
24458
+ };
24459
+ }
24460
+ const depositsRaw = data[3 * i].toString();
24461
+ const borrowsRaw = data[3 * i + 1].toString();
24210
24462
  const depositShares = data[3 * i + 2].toString();
24211
24463
  const collateralEnabled = Boolean(assetsIn?.includes(vToken));
24212
24464
  if (!collateralEnabled && depositsRaw === "0" && borrowsRaw === "0") {
@@ -25143,6 +25395,9 @@ var getAaveV2UserDataConverter = (lender, chainId, account, metaMap) => {
25143
25395
  };
25144
25396
  function createAaveV2Entry(i, data, key, meta, claimableRewards) {
25145
25397
  const reserveData = data[i];
25398
+ if (isFailedCall(reserveData)) {
25399
+ return { dataForAsset: void 0, addedDeposits: 0, addedDebt: 0 };
25400
+ }
25146
25401
  const currentATokenBalanceRaw = reserveData[0 /* currentATokenBalance */]?.toString();
25147
25402
  const currentStableDebtRaw = reserveData[1 /* currentStableDebt */]?.toString();
25148
25403
  const currentVariableDebtRaw = reserveData[2 /* currentVariableDebt */]?.toString();
@@ -25236,6 +25491,9 @@ var getAaveV3UserDataConverter = (lender, chainId, account, metaMap) => {
25236
25491
  };
25237
25492
  function createAaveV3Entry(i, data, key, meta) {
25238
25493
  const reserveData = data[i];
25494
+ if (isFailedCall(reserveData)) {
25495
+ return { dataForAsset: void 0, addedDeposits: 0, addedDebt: 0 };
25496
+ }
25239
25497
  const currentATokenBalanceRaw = reserveData[0 /* currentATokenBalance */]?.toString();
25240
25498
  const currentStableDebtRaw = reserveData[1 /* currentStableDebt */]?.toString();
25241
25499
  const currentVariableDebtRaw = reserveData[2 /* currentVariableDebt */]?.toString();
@@ -25279,6 +25537,9 @@ function createAaveV3Entry(i, data, key, meta) {
25279
25537
  };
25280
25538
  }
25281
25539
  function parseSingleBrokerData(data, validOwner, brokerAddress, lender, chainId, metaMap) {
25540
+ if (isFailedCall(data)) {
25541
+ return { result: {}, modes: {}, histData: {} };
25542
+ }
25282
25543
  const indexes = data[0 /* posMeta */].map((e, i) => ({ e, i })).filter((a) => a.e.owner.toLowerCase() === validOwner).map((a) => a.i);
25283
25544
  const histData = {};
25284
25545
  const modes = {};
@@ -25435,6 +25696,7 @@ var getCompoundV3UserDataConverter = (lender, chainId, account, metaMap) => {
25435
25696
  const metaEntity2 = metaMap?.[key2];
25436
25697
  const assetMeta = metaEntity2.asset;
25437
25698
  const decimals = assetMeta?.decimals ?? 18;
25699
+ if (isFailedCall(data[i])) continue;
25438
25700
  const depositsRaw2 = data[i][0]?.toString();
25439
25701
  if (depositsRaw2 === "0") continue;
25440
25702
  const deposits2 = parseRawAmount(depositsRaw2, decimals);
@@ -25457,20 +25719,21 @@ var getCompoundV3UserDataConverter = (lender, chainId, account, metaMap) => {
25457
25719
  collateralEnabled: true
25458
25720
  };
25459
25721
  }
25722
+ const baseFailed = isFailedCall(data[assetsNoBase.length]) || isFailedCall(data[assetsNoBase.length + 1]);
25460
25723
  const depositsRaw = data[assetsNoBase.length]?.toString();
25461
25724
  const debtRaw = data[assetsNoBase.length + 1]?.toString();
25462
25725
  const key = createMarketUid(chainId, lender, baseAsset);
25463
25726
  const metaEntity = metaMap?.[key];
25464
25727
  const baseMeta = metaEntity.asset;
25465
25728
  const baseDecimals = baseMeta.decimals ?? 18;
25466
- const deposits = parseRawAmount(depositsRaw, baseDecimals);
25467
- const debt = parseRawAmount(debtRaw, baseDecimals);
25729
+ const deposits = baseFailed ? "0" : parseRawAmount(depositsRaw, baseDecimals);
25730
+ const debt = baseFailed ? "0" : parseRawAmount(debtRaw, baseDecimals);
25468
25731
  const price2 = getDisplayPrice(metaEntity);
25469
25732
  const oPrice = getOraclePrice(metaEntity);
25470
25733
  const priceHist = metaEntity?.price?.priceUsd24h ?? price2;
25471
25734
  totalDebt24h += Number(debt) * priceHist;
25472
25735
  totalDeposits24h += Number(deposits) * priceHist;
25473
- const resultBase = depositsRaw === "0" && debtRaw === "0" ? {} : {
25736
+ const resultBase = baseFailed || depositsRaw === "0" && debtRaw === "0" ? {} : {
25474
25737
  [key]: {
25475
25738
  marketUid: key,
25476
25739
  underlying: baseAsset,
@@ -25564,6 +25827,9 @@ var getYldrUserDataConverter = (lender, chainId, account, metaMap) => {
25564
25827
  };
25565
25828
  function createAaveV3Entry2(i, data, key, meta) {
25566
25829
  const reserveData = data[i];
25830
+ if (isFailedCall(reserveData)) {
25831
+ return { dataForAsset: void 0, addedDeposits: 0, addedDebt: 0 };
25832
+ }
25567
25833
  const currentATokenBalanceRaw = reserveData[0 /* currentYTokenBalance */]?.toString();
25568
25834
  const currentVariableDebtRaw = reserveData[1 /* currentVariableDebt */]?.toString();
25569
25835
  if (currentATokenBalanceRaw === "0" && currentVariableDebtRaw === "0") {
@@ -26223,7 +26489,7 @@ var getEulerUserDataConverter = (lender, chainId, account, metaMap, subAccountIn
26223
26489
  const histData = {};
26224
26490
  for (let idx = 0; idx < sortedIndices.length; idx++) {
26225
26491
  const result = _data[idx];
26226
- if (!result) continue;
26492
+ if (isFailedCall(result) || !result) continue;
26227
26493
  const evcInfo = result.evcAccountInfo ?? result[0];
26228
26494
  const vaultAccounts = result.vaultAccountInfo ?? result[1] ?? [];
26229
26495
  const subAccountId = String(sortedIndices[idx]);
@@ -27205,6 +27471,7 @@ var getDolomiteUserDataConverter = (lender, chainId, account, metaMap) => {
27205
27471
  const lendingPositions = {};
27206
27472
  const modes = {};
27207
27473
  _data.forEach((res, i) => {
27474
+ if (isFailedCall(res)) return;
27208
27475
  const id = numbers[i];
27209
27476
  histData[id] = { totalDebt24h: 0, totalDeposits24h: 0 };
27210
27477
  lendingPositions[id] = {};
@@ -27929,6 +28196,7 @@ var getRiverUserDataConverter = (lender, chainId, account, meta) => {
27929
28196
  markets.forEach((market, i) => {
27930
28197
  const base = i * RIVER_CALLS_PER_MARKET;
27931
28198
  const entire = data[base];
28199
+ if (isFailedCall(entire) || isFailedCall(data[base + 1])) return;
27932
28200
  const status = Number(big2(data[base + 1]));
27933
28201
  const surplus = big2(data[base + 2]);
27934
28202
  const lenderKey = riverLenderKey(lender, chainId, market.index);
@@ -28065,7 +28333,7 @@ var getTellerUserDataConverter = (_lender, chainId, account, meta) => {
28065
28333
  const owed = data[base + 1];
28066
28334
  const collAmount = big3(data[base + 2]);
28067
28335
  const defaulted = !!data[base + 3];
28068
- if (!bidRes) return;
28336
+ if (isFailedCall(bidRes) || isFailedCall(owed) || !bidRes) return;
28069
28337
  const pool = b.pool;
28070
28338
  const lenderKey = tellerLenderKey(pool.pool);
28071
28339
  const metaMap = meta?.[lenderKey];
@@ -28090,7 +28358,9 @@ var getTellerUserDataConverter = (_lender, chainId, account, meta) => {
28090
28358
  if (owedTotal === 0n && collAmount === 0n) return;
28091
28359
  const loanDetails = field8(bidRes, "loanDetails", 5);
28092
28360
  const terms = field8(bidRes, "terms", 6);
28093
- const acceptedTs = Number(big3(field8(loanDetails, "acceptedTimestamp", 4)));
28361
+ const acceptedTs = Number(
28362
+ big3(field8(loanDetails, "acceptedTimestamp", 4))
28363
+ );
28094
28364
  const loanDuration = Number(big3(field8(loanDetails, "loanDuration", 6)));
28095
28365
  const aprBps = Number(big3(field8(terms, "APR", 2)));
28096
28366
  const maturity = acceptedTs > 0 ? acceptedTs + loanDuration : void 0;
@@ -28263,7 +28533,7 @@ var filterEmptyUserData = (userData, keepActiveControllerMode = false) => {
28263
28533
  if (filteredData.length === 0) return null;
28264
28534
  return { ...userData, data: filteredData };
28265
28535
  };
28266
- var convertLenderUserDataResult = (chainId, queriesRaw, rawResults, lenderState) => {
28536
+ var convertLenderUserDataResult = (chainId, queriesRaw, rawResults, lenderState, options) => {
28267
28537
  const queries = organizeUserQueries(queriesRaw);
28268
28538
  const lenderData = {};
28269
28539
  let currentSlice = 0;
@@ -28277,6 +28547,21 @@ var convertLenderUserDataResult = (chainId, queriesRaw, rawResults, lenderState)
28277
28547
  );
28278
28548
  try {
28279
28549
  const data = rawResults.slice(currentSlice, currentSlice + sliceLength);
28550
+ let failedCalls = 0;
28551
+ for (const entry of data) if (isFailedCall(entry)) failedCalls++;
28552
+ const allFailed = data.length > 0 && failedCalls === data.length;
28553
+ if (failedCalls > 0) {
28554
+ options?.onIncomplete?.({
28555
+ lender: query3.lender,
28556
+ failedCalls,
28557
+ totalCalls: data.length,
28558
+ dropped: allFailed
28559
+ });
28560
+ }
28561
+ if (allFailed) {
28562
+ currentSlice += sliceLength;
28563
+ continue;
28564
+ }
28280
28565
  const convertedData = converter(data);
28281
28566
  if (convertedData) {
28282
28567
  if (isMultiMarket(query3.lender)) {
@@ -28284,6 +28569,7 @@ var convertLenderUserDataResult = (chainId, queriesRaw, rawResults, lenderState)
28284
28569
  const filtered = filterEmptyUserData(convertedData[market]);
28285
28570
  if (filtered) {
28286
28571
  filtered.lender = market;
28572
+ if (failedCalls > 0) filtered.incomplete = true;
28287
28573
  lenderData[market] = filtered;
28288
28574
  }
28289
28575
  });
@@ -28296,6 +28582,7 @@ var convertLenderUserDataResult = (chainId, queriesRaw, rawResults, lenderState)
28296
28582
  );
28297
28583
  if (filtered) {
28298
28584
  filtered.lender = query3.lender;
28585
+ if (failedCalls > 0) filtered.incomplete = true;
28299
28586
  lenderData[query3.lender] = filtered;
28300
28587
  }
28301
28588
  }
@@ -28307,199 +28594,6 @@ var convertLenderUserDataResult = (chainId, queriesRaw, rawResults, lenderState)
28307
28594
  return lenderData;
28308
28595
  };
28309
28596
 
28310
- // src/utils/constants.ts
28311
- var MULTICALL_DEFAULT_BATCH_SIZE = 4096;
28312
- var CELO_MULTICALL_ADDRESS = "0x633987602DE5C4F337e3DbF265303A1080324204";
28313
- var BNB_MULTICALL_ADDRESS = "0x963Df249eD09c358A4819E39d9Cd5736c3087184";
28314
- var MANTLE_MULTICALL_ADDRESS = "0x2A51f2F647E1883F88C992244dEd171238693107";
28315
- var ARBITRUM_ONE_MULTICALL_ADDRESS = "0xadF885960B47eA2CD9B55E6DAc6B42b7Cb2806dB";
28316
- var LINEA_MULTICALL_ADDRESS = "0xac1cE734566f390A94b00eb9bf561c2625BF44ea";
28317
- var AVALANCHE_MULTICALL_ADDRESS = "0x0139141Cd4Ee88dF3Cdb65881D411bAE271Ef0C2";
28318
- var BASE_MULTICALL_ADDRESS = "0x091e99cb1C49331a94dD62755D168E941AbD0693";
28319
- var BLAST_MULTICALL_ADDRESS = "0xdC7f370de7631cE9e2c2e1DCDA6B3B5744Cf4705";
28320
- var TAIKO_MULTICALL_ADDRESS = "0x8E24CfC19c6C00c524353CB8816f5f1c2F33c201";
28321
- var HEMI_MULTICALL_ADDRESS = "0x352A86168e6988A1aDF9A15Cb00017AAd3B67155";
28322
- var GNOSIS_MULTICALL_ADDRESS = "0x4dfa9a980efE4802E969AC33968E3d6E59B8a19e";
28323
- var MODE_MULTICALL_ADDRESS = "0xAB39cE30D98a59DFDa40A630b074170800bfF179";
28324
- var FANTOM_MULTICALL_ADDRESS = "0xDb51CffFf3B989d0cB6b58AbF173371b6F2d0D24";
28325
- var SCROLL_MULTICALL_ADDRESS = "0x3b615B1AC55bc34e51a81D3dea67467F32bcb8C2";
28326
- var SHAPE_MULTICALL_ADDRESS = "0x356A450B32f5030ae7083702b86FaFbBe7490411";
28327
- var SONIC_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
28328
- var INK_MULTICALL_ADDRESS = "0xA0fCec583AeE6176527C07B198e5561722332014";
28329
- var METIS_MULTICALL_ADDRESS = "0x7a59ddbB76521E8982Fa3A08598C9a83b14A6C07";
28330
- var IOTA_MULTICALL_ADDRESS = "0x9683D433621A83aA7dd290106e1da85251317F55";
28331
- var KAVA_MULTICALL_ADDRESS = "0x8B741B0D79BE80E135C880F7583d427B4D41F015";
28332
- var CORN_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
28333
- var SAGA_MULTICALL_ADDRESS = "0x743E03cceB4af2efA3CC76838f6E8B50B63F184c";
28334
- var CYBER_MULTICALL_ADDRESS = "0x906d6eB9CF8f64e100e44f8f491b833a8d40B530";
28335
- var METAL_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
28336
- var ZERO_MULTICALL_ADDRESS = "0x9CA4dcb2505fbf536F6c54AA0a77C79f4fBC35C0";
28337
- var BOB_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
28338
- var WORLDCHAIN_MULTICALL_ADDRESS = "0x0a22c04215c97E3F532F4eF30e0aD9458792dAB9";
28339
- var LISK_MULTICALL_ADDRESS = "0xE3dbcD53f4Ce1b06Ab200f4912BD35672e68f1FA";
28340
- var REDSTONE_MULTICALL_ADDRESS = "0xd57B52452a0FDfE3ff8e0A40Bd10D00D0bfe0723";
28341
- var MANTA_MULTICALL_ADDRESS = "0x52dFC0D9960F11A9Ca9FF616e791B91188446a60";
28342
- var ZORA_MULTICALL_ADDRESS = "0xA51c76bEE6746cB487a7e9312E43e2b8f4A37C15";
28343
- var CORE_MULTICALL_ADDRESS = "0xFe9F82D820757787895Da00B1dBD35c3B8b04894";
28344
- var MORPH_MULTICALL_ADDRESS = "0xAcD82113982479B25E7c1D09858F0130921Dbbca";
28345
- var TELOS_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
28346
- var MULTICALL_ADDRESS = {
28347
- [Chain.OP_MAINNET]: "0x1F98415757620B543A52E61c46B32eB19261F984",
28348
- [Chain.POLYGON_MAINNET]: "0x1F98415757620B543A52E61c46B32eB19261F984",
28349
- [Chain.ETHEREUM_MAINNET]: "0x1F98415757620B543A52E61c46B32eB19261F984",
28350
- [Chain.ARBITRUM_ONE]: ARBITRUM_ONE_MULTICALL_ADDRESS,
28351
- [Chain.BASE]: BASE_MULTICALL_ADDRESS,
28352
- [Chain.CELO_MAINNET]: CELO_MULTICALL_ADDRESS,
28353
- [Chain.BNB_SMART_CHAIN_MAINNET]: BNB_MULTICALL_ADDRESS,
28354
- [Chain.MANTLE]: MANTLE_MULTICALL_ADDRESS,
28355
- [Chain.BLAST]: BLAST_MULTICALL_ADDRESS,
28356
- [Chain.LINEA]: LINEA_MULTICALL_ADDRESS,
28357
- [Chain.AVALANCHE_C_CHAIN]: AVALANCHE_MULTICALL_ADDRESS,
28358
- [Chain.TAIKO_ALETHIA]: TAIKO_MULTICALL_ADDRESS,
28359
- [Chain.HEMI_NETWORK]: HEMI_MULTICALL_ADDRESS,
28360
- [Chain.GNOSIS]: GNOSIS_MULTICALL_ADDRESS,
28361
- [Chain.CORE_BLOCKCHAIN_MAINNET]: CORE_MULTICALL_ADDRESS,
28362
- [Chain.METIS_ANDROMEDA_MAINNET]: METIS_MULTICALL_ADDRESS,
28363
- [Chain.MODE]: MODE_MULTICALL_ADDRESS,
28364
- [Chain.INK]: INK_MULTICALL_ADDRESS,
28365
- [Chain.IOTA_EVM]: IOTA_MULTICALL_ADDRESS,
28366
- [Chain.CORN]: CORN_MULTICALL_ADDRESS,
28367
- [Chain.SONIC_MAINNET]: SONIC_MULTICALL_ADDRESS,
28368
- [Chain.FANTOM_OPERA]: FANTOM_MULTICALL_ADDRESS,
28369
- [Chain.SCROLL]: SCROLL_MULTICALL_ADDRESS,
28370
- [Chain.SHAPE]: SHAPE_MULTICALL_ADDRESS,
28371
- [Chain.CYBER_MAINNET]: CYBER_MULTICALL_ADDRESS,
28372
- [Chain.ZORA]: ZORA_MULTICALL_ADDRESS,
28373
- [Chain.MANTA_PACIFIC_MAINNET]: MANTA_MULTICALL_ADDRESS,
28374
- [Chain.REDSTONE]: REDSTONE_MULTICALL_ADDRESS,
28375
- [Chain.KAVA]: KAVA_MULTICALL_ADDRESS,
28376
- [Chain.METAL_L2]: METAL_MULTICALL_ADDRESS,
28377
- [Chain.LISK]: LISK_MULTICALL_ADDRESS,
28378
- [Chain.BOB]: BOB_MULTICALL_ADDRESS,
28379
- [Chain.ZERO_NETWORK]: ZERO_MULTICALL_ADDRESS,
28380
- [Chain.SAGA]: SAGA_MULTICALL_ADDRESS,
28381
- [Chain.MORPH]: MORPH_MULTICALL_ADDRESS,
28382
- [Chain.TELOS_EVM_MAINNET]: TELOS_MULTICALL_ADDRESS,
28383
- [Chain.WORLD_CHAIN]: WORLDCHAIN_MULTICALL_ADDRESS
28384
- };
28385
-
28386
- // src/utils/multicall.ts
28387
- var { isArray } = lodash;
28388
- var maxRetries = 3;
28389
- var multicallViemAbiArray = async (chainId, abi, calls, getEvmClient18, retry = true, providerId = 0, retries = maxRetries, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, logs = false) => {
28390
- try {
28391
- const provider = getEvmClient18(chainId, providerId);
28392
- const abiIsArray = isArray(abi[0]);
28393
- const returnData = await provider.multicall({
28394
- allowFailure,
28395
- batchSize,
28396
- contracts: calls.map(({ address, name, params }, i) => ({
28397
- abi: abiIsArray ? abi?.[i] : abi,
28398
- address,
28399
- functionName: name,
28400
- args: params
28401
- }))
28402
- });
28403
- if (!allowFailure) return returnData;
28404
- const res = returnData.map(
28405
- ({ result, status }) => status !== "success" ? "0x" : result
28406
- );
28407
- return res;
28408
- } catch (error) {
28409
- if (logs) console.log("error in multicall", error);
28410
- retries--;
28411
- if (retries < 0) throw new Error("Failed too often");
28412
- providerId++;
28413
- return multicallViemAbiArray(
28414
- chainId,
28415
- abi,
28416
- calls,
28417
- getEvmClient18,
28418
- retry,
28419
- providerId,
28420
- retries,
28421
- allowFailure,
28422
- batchSize,
28423
- logs
28424
- );
28425
- }
28426
- };
28427
- var multicallShardedAbiArray = async (chainId, abi, calls, getEvmClient18, poolSize, retries = maxRetries, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, logs = false) => {
28428
- if (poolSize <= 1) {
28429
- return multicallViemAbiArray(
28430
- chainId,
28431
- abi,
28432
- calls,
28433
- getEvmClient18,
28434
- true,
28435
- 0,
28436
- retries,
28437
- allowFailure,
28438
- batchSize,
28439
- logs
28440
- );
28441
- }
28442
- const abiIsArray = isArray(abi[0]);
28443
- const contracts = calls.map(({ address, name, params }, i) => ({
28444
- abi: abiIsArray ? abi?.[i] : abi,
28445
- address,
28446
- functionName: name,
28447
- args: params
28448
- }));
28449
- const batches = [];
28450
- for (let i = 0; i < contracts.length; i += batchSize) {
28451
- batches.push({ start: i, items: contracts.slice(i, i + batchSize) });
28452
- }
28453
- const results = new Array(contracts.length);
28454
- const runBatch = async (batch, rpcId, attemptsLeft, size) => {
28455
- try {
28456
- const provider = getEvmClient18(chainId, rpcId);
28457
- const returnData = await provider.multicall({
28458
- allowFailure,
28459
- batchSize: size,
28460
- contracts: batch.items
28461
- });
28462
- const mapped = allowFailure ? returnData.map(
28463
- ({ result, status }) => status !== "success" ? "0x" : result
28464
- ) : returnData;
28465
- for (let j = 0; j < mapped.length; j++) {
28466
- results[batch.start + j] = mapped[j];
28467
- }
28468
- } catch (error) {
28469
- if (logs) console.log("error in sharded multicall batch", error);
28470
- if (attemptsLeft <= 0) throw error;
28471
- return runBatch(
28472
- batch,
28473
- rpcId + 1,
28474
- attemptsLeft - 1,
28475
- Math.max(1, Math.floor(size / 2))
28476
- );
28477
- }
28478
- };
28479
- const workers = Math.max(1, Math.min(poolSize, batches.length));
28480
- let cursor = 0;
28481
- const worker = async (workerId) => {
28482
- while (true) {
28483
- const idx = cursor++;
28484
- if (idx >= batches.length) break;
28485
- await runBatch(batches[idx], workerId, retries, batchSize);
28486
- }
28487
- };
28488
- await Promise.all(
28489
- Array.from({ length: workers }, (_3, w) => worker(w))
28490
- );
28491
- return results;
28492
- };
28493
- function prepareMulticallInputs(abi, calls) {
28494
- const abiIsArray = isArray(abi[0]);
28495
- return calls.map(({ address, name, params }, i) => ({
28496
- address,
28497
- functionName: name,
28498
- params: params || [],
28499
- abi: abiIsArray ? abi[i] : abi
28500
- }));
28501
- }
28502
-
28503
28597
  // src/utils/rpcCall.ts
28504
28598
  var multicall3Abi = [
28505
28599
  {
@@ -33124,7 +33218,10 @@ var getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient18, allowF
33124
33218
  retries,
33125
33219
  allowFailure,
33126
33220
  batchSize,
33127
- logs
33221
+ logs,
33222
+ // Retry individual failed slots: a dropped call here is indistinguishable
33223
+ // from "user has no position" downstream, so it is worth one extra pass.
33224
+ true
33128
33225
  );
33129
33226
  };
33130
33227
  var prepareLenderUserDataRpcCalls = async (chainId, queriesRaw, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, blockTag = "latest", allowFailure = true) => {
@@ -38877,15 +38974,16 @@ function createMerklRewardFetcher(config) {
38877
38974
  );
38878
38975
  for (const { chainId, opps } of chainResults) {
38879
38976
  for (const opp of opps) {
38880
- if (opp.action !== "LEND" && opp.action !== "BORROW") continue;
38881
38977
  if (!opp.apr || opp.apr <= 0) continue;
38882
38978
  const resolved2 = resolve(opp);
38883
38979
  if (!resolved2) continue;
38980
+ const bucket = resolved2.bucket ?? (opp.action === "LEND" ? "deposit" : opp.action === "BORROW" ? "borrow" : void 0);
38981
+ if (!bucket) continue;
38884
38982
  const lender = resolved2.lender ?? config.lenderKey;
38885
38983
  const reward = ensureReward(result, chainId, lender, resolved2.asset);
38886
38984
  const breakdowns = extractRewardBreakdowns(opp);
38887
38985
  reward.link = getMerkleUrl(opp);
38888
- if (opp.action === "LEND") {
38986
+ if (bucket === "deposit") {
38889
38987
  reward.deposit += opp.apr;
38890
38988
  reward.additionalDepositData.push(...breakdowns);
38891
38989
  } else {
@@ -38929,6 +39027,71 @@ var aaveMerklRewardFetcher = createMerklRewardFetcher({
38929
39027
  lenderKey: "AAVE_V3",
38930
39028
  chainIds: AAVE_V3_MERKL_CHAINS
38931
39029
  });
39030
+ var EULER_MERKL_CHAINS = [
39031
+ "1",
39032
+ // Ethereum
39033
+ "10",
39034
+ // Optimism
39035
+ "56",
39036
+ // BSC
39037
+ "130",
39038
+ // Unichain
39039
+ "137",
39040
+ // Polygon
39041
+ "8453",
39042
+ // Base
39043
+ "42161",
39044
+ // Arbitrum
39045
+ "43114",
39046
+ // Avalanche
39047
+ "80094"
39048
+ // Berachain
39049
+ ];
39050
+ var eulerMerklRewardFetcher = createMerklRewardFetcher({
39051
+ merklProtocolId: "euler",
39052
+ lenderKey: "EULER_V2",
39053
+ chainIds: EULER_MERKL_CHAINS,
39054
+ resolveAsset: (opp) => {
39055
+ const vault = opp.explorerAddress?.toLowerCase();
39056
+ if (!vault) return void 0;
39057
+ return { asset: vault };
39058
+ }
39059
+ });
39060
+ var MORPHO_MERKL_CHAINS = [
39061
+ "1",
39062
+ // Ethereum
39063
+ "130",
39064
+ // Unichain
39065
+ "137",
39066
+ // Polygon
39067
+ "8453",
39068
+ // Base
39069
+ "42161",
39070
+ // Arbitrum
39071
+ "4663"
39072
+ // Robinhood chain
39073
+ ];
39074
+ function parseMorphoUniqueKey(depositUrl) {
39075
+ if (!depositUrl) return void 0;
39076
+ const m = depositUrl.match(/\/market\/(0x[0-9a-fA-F]{64})/);
39077
+ return m?.[1]?.toLowerCase();
39078
+ }
39079
+ var morphoCollateralMerklRewardFetcher = createMerklRewardFetcher({
39080
+ merklProtocolId: "morpho",
39081
+ lenderKey: "MORPHO_BLUE",
39082
+ chainIds: MORPHO_MERKL_CHAINS,
39083
+ resolveAsset: (opp) => {
39084
+ if (opp.type !== "MORPHOCOLLATERAL") return void 0;
39085
+ const uniqueKey = parseMorphoUniqueKey(opp.depositUrl);
39086
+ const collateral = opp.explorerAddress?.toLowerCase();
39087
+ if (!uniqueKey || !collateral) return void 0;
39088
+ return {
39089
+ asset: collateral,
39090
+ lender: `MORPHO_BLUE_${uniqueKey.slice(2).toUpperCase()}`,
39091
+ bucket: "deposit"
39092
+ };
39093
+ }
39094
+ });
38932
39095
 
38933
39096
  // src/yields/rewards/fetchLenderRewards.ts
38934
39097
  function mergeRewardResults(target, source) {
@@ -38940,7 +39103,11 @@ function mergeRewardResults(target, source) {
38940
39103
  }
38941
39104
  }
38942
39105
  }
38943
- var rewardFetchers = [aaveMerklRewardFetcher];
39106
+ var rewardFetchers = [
39107
+ aaveMerklRewardFetcher,
39108
+ eulerMerklRewardFetcher,
39109
+ morphoCollateralMerklRewardFetcher
39110
+ ];
38944
39111
  async function fetchLenderRewards() {
38945
39112
  const results = await Promise.all(
38946
39113
  rewardFetchers.map((f) => safeFetch(f.label, f.fetch))
@@ -39629,7 +39796,6 @@ var termFetcher = {
39629
39796
  parse: parseTermResults,
39630
39797
  getAbi: getTermAbi
39631
39798
  };
39632
- var SANITY_MAX_USD = 1e9;
39633
39799
  function getLiquityCalls(chainId) {
39634
39800
  const results = [];
39635
39801
  for (const lender of LIQUITY_FAMILY_LENDERS) {
@@ -39648,6 +39814,8 @@ function getLiquityCalls(chainId) {
39648
39814
  chainId,
39649
39815
  collIndex: b.collIndex,
39650
39816
  collToken: b.collToken.toLowerCase(),
39817
+ collDecimals: b.collDecimals,
39818
+ priceDecimals: b.priceDecimals,
39651
39819
  debtToken: debtToken?.toLowerCase()
39652
39820
  },
39653
39821
  lender: liquityLenderKey(lender, chainId, b.collIndex)
@@ -39662,8 +39830,12 @@ function parseLiquityResults(data, meta, context) {
39662
39830
  const entries = [];
39663
39831
  const raw = data?.[0];
39664
39832
  const price2 = typeof raw === "bigint" ? raw : raw != null && raw !== "0x" ? BigInt(raw) : 0n;
39665
- const collUSD = Number(price2) / 1e18;
39666
- if (collUSD > 0 && collUSD < SANITY_MAX_USD) {
39833
+ const collUSD = liquityCollateralPrice(
39834
+ price2,
39835
+ meta.collDecimals,
39836
+ meta.priceDecimals
39837
+ );
39838
+ if (collUSD > 0) {
39667
39839
  entries.push({
39668
39840
  asset: meta.collToken,
39669
39841
  price: collUSD,