@1delta/margin-fetcher 0.0.336 → 0.0.338

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 (30) hide show
  1. package/dist/index.js +380 -209
  2. package/dist/index.js.map +1 -1
  3. package/dist/lending/public-data/gearbox/publicCallParse.d.ts.map +1 -1
  4. package/dist/lending/public-data/gearbox/publicCallParse.test.d.ts +2 -0
  5. package/dist/lending/public-data/gearbox/publicCallParse.test.d.ts.map +1 -0
  6. package/dist/lending/user-data/aave-v2-type/userCallParse.d.ts.map +1 -1
  7. package/dist/lending/user-data/aave-v3-type/userCallParse.d.ts.map +1 -1
  8. package/dist/lending/user-data/aave-v3-type/userCallParseYldr.d.ts.map +1 -1
  9. package/dist/lending/user-data/compound-v2/userCallParse.d.ts.map +1 -1
  10. package/dist/lending/user-data/compound-v3/userCallParse.d.ts.map +1 -1
  11. package/dist/lending/user-data/dolomite/userCallParse.d.ts.map +1 -1
  12. package/dist/lending/user-data/euler/userCallParse.d.ts.map +1 -1
  13. package/dist/lending/user-data/fetch-balances/e2e.d.ts.map +1 -1
  14. package/dist/lending/user-data/fetch-balances/parse.d.ts +26 -1
  15. package/dist/lending/user-data/fetch-balances/parse.d.ts.map +1 -1
  16. package/dist/lending/user-data/init/userCallParse.d.ts.map +1 -1
  17. package/dist/lending/user-data/river/userCallParse.d.ts.map +1 -1
  18. package/dist/lending/user-data/teller/userCallParse.d.ts.map +1 -1
  19. package/dist/lending/user-data/utils/types.d.ts +14 -0
  20. package/dist/lending/user-data/utils/types.d.ts.map +1 -1
  21. package/dist/types/apiReturnType.d.ts +7 -0
  22. package/dist/types/apiReturnType.d.ts.map +1 -1
  23. package/dist/utils/multicall.d.ts +41 -12
  24. package/dist/utils/multicall.d.ts.map +1 -1
  25. package/dist/yields/rewards/fetchLenderRewards.d.ts.map +1 -1
  26. package/dist/yields/rewards/index.d.ts +1 -1
  27. package/dist/yields/rewards/index.d.ts.map +1 -1
  28. package/dist/yields/rewards/merkl.d.ts +24 -0
  29. package/dist/yields/rewards/merkl.d.ts.map +1 -1
  30. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -20464,6 +20464,16 @@ var getGearboxV3PublicDataConverter = (_lender, chainId, prices, additionalYield
20464
20464
  0
20465
20465
  );
20466
20466
  const poolUtilization = poolExpectedLiquidity > 0 ? poolIrmDebt / poolExpectedLiquidity : 0;
20467
+ const quotaRatePctByToken = {};
20468
+ const quotaSrc = Array.isArray(m?.quotaKeeper?.quotas) && m.quotaKeeper.quotas || Array.isArray(m?.rateKeeper?.rates) && m.rateKeeper.rates || [];
20469
+ for (const q of quotaSrc) {
20470
+ const t = (q?.token ?? "").toString().toLowerCase();
20471
+ if (!t) continue;
20472
+ if (q?.isActive === false) continue;
20473
+ const rate = Number(q?.rate ?? 0);
20474
+ if (!(rate > 0)) continue;
20475
+ quotaRatePctByToken[t] = rate / 100;
20476
+ }
20467
20477
  for (const cm of m.creditManagers ?? []) {
20468
20478
  const facade = cm?.creditFacade;
20469
20479
  const manager = cm?.creditManager;
@@ -20561,6 +20571,8 @@ var getGearboxV3PublicDataConverter = (_lender, chainId, prices, additionalYield
20561
20571
  const ctPriceKey = toOracleKey(ctMeta?.assetGroup) ?? toGenericPriceKey(token, chainId);
20562
20572
  const colMarketUid = createMarketUid(chainId, lender, token);
20563
20573
  if (colMarketUid === loanMarketUid) continue;
20574
+ const quotaRate = quotaRatePctByToken[token] ?? 0;
20575
+ const grossIntrinsic = additionalYields?.intrinsicYields?.[ctPriceKey] ?? 0;
20564
20576
  data2[colMarketUid] = {
20565
20577
  marketUid: colMarketUid,
20566
20578
  name: "Collateral " + (ctMeta?.symbol ?? ""),
@@ -20581,7 +20593,8 @@ var getGearboxV3PublicDataConverter = (_lender, chainId, prices, additionalYield
20581
20593
  depositRate: 0,
20582
20594
  variableBorrowRate: 0,
20583
20595
  stableBorrowRate: 0,
20584
- intrinsicYield: additionalYields?.intrinsicYields?.[ctPriceKey] ?? 0,
20596
+ intrinsicYield: grossIntrinsic - quotaRate,
20597
+ quotaRate,
20585
20598
  rewards: [],
20586
20599
  decimals: ctDecimals,
20587
20600
  config: {
@@ -24136,6 +24149,244 @@ var buildCompoundV2UserCall = (chainId, lender, account) => {
24136
24149
  ];
24137
24150
  return calls;
24138
24151
  };
24152
+
24153
+ // src/utils/constants.ts
24154
+ var MULTICALL_DEFAULT_BATCH_SIZE = 4096;
24155
+ var CELO_MULTICALL_ADDRESS = "0x633987602DE5C4F337e3DbF265303A1080324204";
24156
+ var BNB_MULTICALL_ADDRESS = "0x963Df249eD09c358A4819E39d9Cd5736c3087184";
24157
+ var MANTLE_MULTICALL_ADDRESS = "0x2A51f2F647E1883F88C992244dEd171238693107";
24158
+ var ARBITRUM_ONE_MULTICALL_ADDRESS = "0xadF885960B47eA2CD9B55E6DAc6B42b7Cb2806dB";
24159
+ var LINEA_MULTICALL_ADDRESS = "0xac1cE734566f390A94b00eb9bf561c2625BF44ea";
24160
+ var AVALANCHE_MULTICALL_ADDRESS = "0x0139141Cd4Ee88dF3Cdb65881D411bAE271Ef0C2";
24161
+ var BASE_MULTICALL_ADDRESS = "0x091e99cb1C49331a94dD62755D168E941AbD0693";
24162
+ var BLAST_MULTICALL_ADDRESS = "0xdC7f370de7631cE9e2c2e1DCDA6B3B5744Cf4705";
24163
+ var TAIKO_MULTICALL_ADDRESS = "0x8E24CfC19c6C00c524353CB8816f5f1c2F33c201";
24164
+ var HEMI_MULTICALL_ADDRESS = "0x352A86168e6988A1aDF9A15Cb00017AAd3B67155";
24165
+ var GNOSIS_MULTICALL_ADDRESS = "0x4dfa9a980efE4802E969AC33968E3d6E59B8a19e";
24166
+ var MODE_MULTICALL_ADDRESS = "0xAB39cE30D98a59DFDa40A630b074170800bfF179";
24167
+ var FANTOM_MULTICALL_ADDRESS = "0xDb51CffFf3B989d0cB6b58AbF173371b6F2d0D24";
24168
+ var SCROLL_MULTICALL_ADDRESS = "0x3b615B1AC55bc34e51a81D3dea67467F32bcb8C2";
24169
+ var SHAPE_MULTICALL_ADDRESS = "0x356A450B32f5030ae7083702b86FaFbBe7490411";
24170
+ var SONIC_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
24171
+ var INK_MULTICALL_ADDRESS = "0xA0fCec583AeE6176527C07B198e5561722332014";
24172
+ var METIS_MULTICALL_ADDRESS = "0x7a59ddbB76521E8982Fa3A08598C9a83b14A6C07";
24173
+ var IOTA_MULTICALL_ADDRESS = "0x9683D433621A83aA7dd290106e1da85251317F55";
24174
+ var KAVA_MULTICALL_ADDRESS = "0x8B741B0D79BE80E135C880F7583d427B4D41F015";
24175
+ var CORN_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
24176
+ var SAGA_MULTICALL_ADDRESS = "0x743E03cceB4af2efA3CC76838f6E8B50B63F184c";
24177
+ var CYBER_MULTICALL_ADDRESS = "0x906d6eB9CF8f64e100e44f8f491b833a8d40B530";
24178
+ var METAL_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
24179
+ var ZERO_MULTICALL_ADDRESS = "0x9CA4dcb2505fbf536F6c54AA0a77C79f4fBC35C0";
24180
+ var BOB_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
24181
+ var WORLDCHAIN_MULTICALL_ADDRESS = "0x0a22c04215c97E3F532F4eF30e0aD9458792dAB9";
24182
+ var LISK_MULTICALL_ADDRESS = "0xE3dbcD53f4Ce1b06Ab200f4912BD35672e68f1FA";
24183
+ var REDSTONE_MULTICALL_ADDRESS = "0xd57B52452a0FDfE3ff8e0A40Bd10D00D0bfe0723";
24184
+ var MANTA_MULTICALL_ADDRESS = "0x52dFC0D9960F11A9Ca9FF616e791B91188446a60";
24185
+ var ZORA_MULTICALL_ADDRESS = "0xA51c76bEE6746cB487a7e9312E43e2b8f4A37C15";
24186
+ var CORE_MULTICALL_ADDRESS = "0xFe9F82D820757787895Da00B1dBD35c3B8b04894";
24187
+ var MORPH_MULTICALL_ADDRESS = "0xAcD82113982479B25E7c1D09858F0130921Dbbca";
24188
+ var TELOS_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
24189
+ var MULTICALL_ADDRESS = {
24190
+ [Chain.OP_MAINNET]: "0x1F98415757620B543A52E61c46B32eB19261F984",
24191
+ [Chain.POLYGON_MAINNET]: "0x1F98415757620B543A52E61c46B32eB19261F984",
24192
+ [Chain.ETHEREUM_MAINNET]: "0x1F98415757620B543A52E61c46B32eB19261F984",
24193
+ [Chain.ARBITRUM_ONE]: ARBITRUM_ONE_MULTICALL_ADDRESS,
24194
+ [Chain.BASE]: BASE_MULTICALL_ADDRESS,
24195
+ [Chain.CELO_MAINNET]: CELO_MULTICALL_ADDRESS,
24196
+ [Chain.BNB_SMART_CHAIN_MAINNET]: BNB_MULTICALL_ADDRESS,
24197
+ [Chain.MANTLE]: MANTLE_MULTICALL_ADDRESS,
24198
+ [Chain.BLAST]: BLAST_MULTICALL_ADDRESS,
24199
+ [Chain.LINEA]: LINEA_MULTICALL_ADDRESS,
24200
+ [Chain.AVALANCHE_C_CHAIN]: AVALANCHE_MULTICALL_ADDRESS,
24201
+ [Chain.TAIKO_ALETHIA]: TAIKO_MULTICALL_ADDRESS,
24202
+ [Chain.HEMI_NETWORK]: HEMI_MULTICALL_ADDRESS,
24203
+ [Chain.GNOSIS]: GNOSIS_MULTICALL_ADDRESS,
24204
+ [Chain.CORE_BLOCKCHAIN_MAINNET]: CORE_MULTICALL_ADDRESS,
24205
+ [Chain.METIS_ANDROMEDA_MAINNET]: METIS_MULTICALL_ADDRESS,
24206
+ [Chain.MODE]: MODE_MULTICALL_ADDRESS,
24207
+ [Chain.INK]: INK_MULTICALL_ADDRESS,
24208
+ [Chain.IOTA_EVM]: IOTA_MULTICALL_ADDRESS,
24209
+ [Chain.CORN]: CORN_MULTICALL_ADDRESS,
24210
+ [Chain.SONIC_MAINNET]: SONIC_MULTICALL_ADDRESS,
24211
+ [Chain.FANTOM_OPERA]: FANTOM_MULTICALL_ADDRESS,
24212
+ [Chain.SCROLL]: SCROLL_MULTICALL_ADDRESS,
24213
+ [Chain.SHAPE]: SHAPE_MULTICALL_ADDRESS,
24214
+ [Chain.CYBER_MAINNET]: CYBER_MULTICALL_ADDRESS,
24215
+ [Chain.ZORA]: ZORA_MULTICALL_ADDRESS,
24216
+ [Chain.MANTA_PACIFIC_MAINNET]: MANTA_MULTICALL_ADDRESS,
24217
+ [Chain.REDSTONE]: REDSTONE_MULTICALL_ADDRESS,
24218
+ [Chain.KAVA]: KAVA_MULTICALL_ADDRESS,
24219
+ [Chain.METAL_L2]: METAL_MULTICALL_ADDRESS,
24220
+ [Chain.LISK]: LISK_MULTICALL_ADDRESS,
24221
+ [Chain.BOB]: BOB_MULTICALL_ADDRESS,
24222
+ [Chain.ZERO_NETWORK]: ZERO_MULTICALL_ADDRESS,
24223
+ [Chain.SAGA]: SAGA_MULTICALL_ADDRESS,
24224
+ [Chain.MORPH]: MORPH_MULTICALL_ADDRESS,
24225
+ [Chain.TELOS_EVM_MAINNET]: TELOS_MULTICALL_ADDRESS,
24226
+ [Chain.WORLD_CHAIN]: WORLDCHAIN_MULTICALL_ADDRESS
24227
+ };
24228
+
24229
+ // src/utils/multicall.ts
24230
+ var { isArray } = lodash;
24231
+ var maxRetries = 3;
24232
+ var MULTICALL_FAILURE = "0x";
24233
+ var isFailedCall = (value) => value === void 0 || value === null || value === MULTICALL_FAILURE;
24234
+ var retryFailedSlots = async (chainId, contracts, mapped, getEvmClient18, nextRpcId, batchSize, logs) => {
24235
+ const failedIdx = [];
24236
+ for (let i = 0; i < mapped.length; i++) {
24237
+ if (isFailedCall(mapped[i])) failedIdx.push(i);
24238
+ }
24239
+ if (failedIdx.length === 0) return mapped;
24240
+ try {
24241
+ const provider = getEvmClient18(chainId, nextRpcId);
24242
+ const returnData = await provider.multicall({
24243
+ allowFailure: true,
24244
+ batchSize,
24245
+ contracts: failedIdx.map((i) => contracts[i])
24246
+ });
24247
+ returnData.forEach((entry, k) => {
24248
+ if (entry?.status === "success") mapped[failedIdx[k]] = entry.result;
24249
+ });
24250
+ } catch (error) {
24251
+ if (logs) console.log("error in multicall failure-retry", error);
24252
+ }
24253
+ return mapped;
24254
+ };
24255
+ var multicallViemAbiArray = async (chainId, abi, calls, getEvmClient18, retry = true, providerId = 0, retries = maxRetries, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, logs = false, retryFailed = false) => {
24256
+ try {
24257
+ const provider = getEvmClient18(chainId, providerId);
24258
+ const abiIsArray = isArray(abi[0]);
24259
+ const contracts = calls.map(({ address, name, params }, i) => ({
24260
+ abi: abiIsArray ? abi?.[i] : abi,
24261
+ address,
24262
+ functionName: name,
24263
+ args: params
24264
+ }));
24265
+ const returnData = await provider.multicall({
24266
+ allowFailure,
24267
+ batchSize,
24268
+ contracts
24269
+ });
24270
+ if (!allowFailure) return returnData;
24271
+ const res = returnData.map(
24272
+ ({ result, status }) => status !== "success" ? MULTICALL_FAILURE : result
24273
+ );
24274
+ if (!retryFailed) return res;
24275
+ return retryFailedSlots(
24276
+ chainId,
24277
+ contracts,
24278
+ res,
24279
+ getEvmClient18,
24280
+ providerId + 1,
24281
+ batchSize,
24282
+ logs
24283
+ );
24284
+ } catch (error) {
24285
+ if (logs) console.log("error in multicall", error);
24286
+ retries--;
24287
+ if (retries < 0) throw new Error("Failed too often");
24288
+ providerId++;
24289
+ return multicallViemAbiArray(
24290
+ chainId,
24291
+ abi,
24292
+ calls,
24293
+ getEvmClient18,
24294
+ retry,
24295
+ providerId,
24296
+ retries,
24297
+ allowFailure,
24298
+ batchSize,
24299
+ logs,
24300
+ retryFailed
24301
+ );
24302
+ }
24303
+ };
24304
+ var multicallShardedAbiArray = async (chainId, abi, calls, getEvmClient18, poolSize, retries = maxRetries, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, logs = false, retryFailed = false) => {
24305
+ if (poolSize <= 1) {
24306
+ return multicallViemAbiArray(
24307
+ chainId,
24308
+ abi,
24309
+ calls,
24310
+ getEvmClient18,
24311
+ true,
24312
+ 0,
24313
+ retries,
24314
+ allowFailure,
24315
+ batchSize,
24316
+ logs,
24317
+ retryFailed
24318
+ );
24319
+ }
24320
+ const abiIsArray = isArray(abi[0]);
24321
+ const contracts = calls.map(({ address, name, params }, i) => ({
24322
+ abi: abiIsArray ? abi?.[i] : abi,
24323
+ address,
24324
+ functionName: name,
24325
+ args: params
24326
+ }));
24327
+ const shardSize = Math.max(1, Math.ceil(contracts.length / poolSize));
24328
+ const batches = [];
24329
+ for (let i = 0; i < contracts.length; i += shardSize) {
24330
+ batches.push({ start: i, items: contracts.slice(i, i + shardSize) });
24331
+ }
24332
+ const results = new Array(contracts.length);
24333
+ const runBatch = async (batch, rpcId, attemptsLeft, size) => {
24334
+ try {
24335
+ const provider = getEvmClient18(chainId, rpcId);
24336
+ const returnData = await provider.multicall({
24337
+ allowFailure,
24338
+ batchSize: size,
24339
+ contracts: batch.items
24340
+ });
24341
+ let mapped = allowFailure ? returnData.map(
24342
+ ({ result, status }) => status !== "success" ? MULTICALL_FAILURE : result
24343
+ ) : returnData;
24344
+ if (allowFailure && retryFailed) {
24345
+ mapped = await retryFailedSlots(
24346
+ chainId,
24347
+ batch.items,
24348
+ mapped,
24349
+ getEvmClient18,
24350
+ rpcId + 1,
24351
+ size,
24352
+ logs
24353
+ );
24354
+ }
24355
+ for (let j = 0; j < mapped.length; j++) {
24356
+ results[batch.start + j] = mapped[j];
24357
+ }
24358
+ } catch (error) {
24359
+ if (logs) console.log("error in sharded multicall batch", error);
24360
+ if (attemptsLeft <= 0) throw error;
24361
+ return runBatch(
24362
+ batch,
24363
+ rpcId + 1,
24364
+ attemptsLeft - 1,
24365
+ Math.max(1, Math.floor(size / 2))
24366
+ );
24367
+ }
24368
+ };
24369
+ const workers = Math.max(1, Math.min(poolSize, batches.length));
24370
+ let cursor = 0;
24371
+ const worker = async (workerId) => {
24372
+ while (true) {
24373
+ const idx = cursor++;
24374
+ if (idx >= batches.length) break;
24375
+ await runBatch(batches[idx], workerId, retries, batchSize);
24376
+ }
24377
+ };
24378
+ await Promise.all(Array.from({ length: workers }, (_3, w) => worker(w)));
24379
+ return results;
24380
+ };
24381
+ function prepareMulticallInputs(abi, calls) {
24382
+ const abiIsArray = isArray(abi[0]);
24383
+ return calls.map(({ address, name, params }, i) => ({
24384
+ address,
24385
+ functionName: name,
24386
+ params: params || [],
24387
+ abi: abiIsArray ? abi[i] : abi
24388
+ }));
24389
+ }
24139
24390
  var getCompoundV2UserDataConverter = (lender, chainId, account, metaMap) => {
24140
24391
  switch (lender) {
24141
24392
  default: {
@@ -24190,10 +24441,15 @@ var getCompoundV2UserDataConverter = (lender, chainId, account, metaMap) => {
24190
24441
  }
24191
24442
  };
24192
24443
  function createCompoundV2Entry(i, data, key, assetsIn, vToken, meta, claimableRewards) {
24193
- const _depositsRaw = data[3 * i].toString();
24194
- const _borrowsRaw = data[3 * i + 1].toString();
24195
- const depositsRaw = _depositsRaw === "0x" ? "0" : _depositsRaw;
24196
- const borrowsRaw = _borrowsRaw === "0x" ? "0" : _borrowsRaw;
24444
+ if (isFailedCall(data[3 * i]) || isFailedCall(data[3 * i + 1])) {
24445
+ return {
24446
+ dataForAsset: void 0,
24447
+ addedDeposits: 0,
24448
+ addedDebt: 0
24449
+ };
24450
+ }
24451
+ const depositsRaw = data[3 * i].toString();
24452
+ const borrowsRaw = data[3 * i + 1].toString();
24197
24453
  const depositShares = data[3 * i + 2].toString();
24198
24454
  const collateralEnabled = Boolean(assetsIn?.includes(vToken));
24199
24455
  if (!collateralEnabled && depositsRaw === "0" && borrowsRaw === "0") {
@@ -25130,6 +25386,9 @@ var getAaveV2UserDataConverter = (lender, chainId, account, metaMap) => {
25130
25386
  };
25131
25387
  function createAaveV2Entry(i, data, key, meta, claimableRewards) {
25132
25388
  const reserveData = data[i];
25389
+ if (isFailedCall(reserveData)) {
25390
+ return { dataForAsset: void 0, addedDeposits: 0, addedDebt: 0 };
25391
+ }
25133
25392
  const currentATokenBalanceRaw = reserveData[0 /* currentATokenBalance */]?.toString();
25134
25393
  const currentStableDebtRaw = reserveData[1 /* currentStableDebt */]?.toString();
25135
25394
  const currentVariableDebtRaw = reserveData[2 /* currentVariableDebt */]?.toString();
@@ -25223,6 +25482,9 @@ var getAaveV3UserDataConverter = (lender, chainId, account, metaMap) => {
25223
25482
  };
25224
25483
  function createAaveV3Entry(i, data, key, meta) {
25225
25484
  const reserveData = data[i];
25485
+ if (isFailedCall(reserveData)) {
25486
+ return { dataForAsset: void 0, addedDeposits: 0, addedDebt: 0 };
25487
+ }
25226
25488
  const currentATokenBalanceRaw = reserveData[0 /* currentATokenBalance */]?.toString();
25227
25489
  const currentStableDebtRaw = reserveData[1 /* currentStableDebt */]?.toString();
25228
25490
  const currentVariableDebtRaw = reserveData[2 /* currentVariableDebt */]?.toString();
@@ -25266,6 +25528,9 @@ function createAaveV3Entry(i, data, key, meta) {
25266
25528
  };
25267
25529
  }
25268
25530
  function parseSingleBrokerData(data, validOwner, brokerAddress, lender, chainId, metaMap) {
25531
+ if (isFailedCall(data)) {
25532
+ return { result: {}, modes: {}, histData: {} };
25533
+ }
25269
25534
  const indexes = data[0 /* posMeta */].map((e, i) => ({ e, i })).filter((a) => a.e.owner.toLowerCase() === validOwner).map((a) => a.i);
25270
25535
  const histData = {};
25271
25536
  const modes = {};
@@ -25422,6 +25687,7 @@ var getCompoundV3UserDataConverter = (lender, chainId, account, metaMap) => {
25422
25687
  const metaEntity2 = metaMap?.[key2];
25423
25688
  const assetMeta = metaEntity2.asset;
25424
25689
  const decimals = assetMeta?.decimals ?? 18;
25690
+ if (isFailedCall(data[i])) continue;
25425
25691
  const depositsRaw2 = data[i][0]?.toString();
25426
25692
  if (depositsRaw2 === "0") continue;
25427
25693
  const deposits2 = parseRawAmount(depositsRaw2, decimals);
@@ -25444,20 +25710,21 @@ var getCompoundV3UserDataConverter = (lender, chainId, account, metaMap) => {
25444
25710
  collateralEnabled: true
25445
25711
  };
25446
25712
  }
25713
+ const baseFailed = isFailedCall(data[assetsNoBase.length]) || isFailedCall(data[assetsNoBase.length + 1]);
25447
25714
  const depositsRaw = data[assetsNoBase.length]?.toString();
25448
25715
  const debtRaw = data[assetsNoBase.length + 1]?.toString();
25449
25716
  const key = createMarketUid(chainId, lender, baseAsset);
25450
25717
  const metaEntity = metaMap?.[key];
25451
25718
  const baseMeta = metaEntity.asset;
25452
25719
  const baseDecimals = baseMeta.decimals ?? 18;
25453
- const deposits = parseRawAmount(depositsRaw, baseDecimals);
25454
- const debt = parseRawAmount(debtRaw, baseDecimals);
25720
+ const deposits = baseFailed ? "0" : parseRawAmount(depositsRaw, baseDecimals);
25721
+ const debt = baseFailed ? "0" : parseRawAmount(debtRaw, baseDecimals);
25455
25722
  const price2 = getDisplayPrice(metaEntity);
25456
25723
  const oPrice = getOraclePrice(metaEntity);
25457
25724
  const priceHist = metaEntity?.price?.priceUsd24h ?? price2;
25458
25725
  totalDebt24h += Number(debt) * priceHist;
25459
25726
  totalDeposits24h += Number(deposits) * priceHist;
25460
- const resultBase = depositsRaw === "0" && debtRaw === "0" ? {} : {
25727
+ const resultBase = baseFailed || depositsRaw === "0" && debtRaw === "0" ? {} : {
25461
25728
  [key]: {
25462
25729
  marketUid: key,
25463
25730
  underlying: baseAsset,
@@ -25551,6 +25818,9 @@ var getYldrUserDataConverter = (lender, chainId, account, metaMap) => {
25551
25818
  };
25552
25819
  function createAaveV3Entry2(i, data, key, meta) {
25553
25820
  const reserveData = data[i];
25821
+ if (isFailedCall(reserveData)) {
25822
+ return { dataForAsset: void 0, addedDeposits: 0, addedDebt: 0 };
25823
+ }
25554
25824
  const currentATokenBalanceRaw = reserveData[0 /* currentYTokenBalance */]?.toString();
25555
25825
  const currentVariableDebtRaw = reserveData[1 /* currentVariableDebt */]?.toString();
25556
25826
  if (currentATokenBalanceRaw === "0" && currentVariableDebtRaw === "0") {
@@ -26210,7 +26480,7 @@ var getEulerUserDataConverter = (lender, chainId, account, metaMap, subAccountIn
26210
26480
  const histData = {};
26211
26481
  for (let idx = 0; idx < sortedIndices.length; idx++) {
26212
26482
  const result = _data[idx];
26213
- if (!result) continue;
26483
+ if (isFailedCall(result) || !result) continue;
26214
26484
  const evcInfo = result.evcAccountInfo ?? result[0];
26215
26485
  const vaultAccounts = result.vaultAccountInfo ?? result[1] ?? [];
26216
26486
  const subAccountId = String(sortedIndices[idx]);
@@ -27192,6 +27462,7 @@ var getDolomiteUserDataConverter = (lender, chainId, account, metaMap) => {
27192
27462
  const lendingPositions = {};
27193
27463
  const modes = {};
27194
27464
  _data.forEach((res, i) => {
27465
+ if (isFailedCall(res)) return;
27195
27466
  const id = numbers[i];
27196
27467
  histData[id] = { totalDebt24h: 0, totalDeposits24h: 0 };
27197
27468
  lendingPositions[id] = {};
@@ -27916,6 +28187,7 @@ var getRiverUserDataConverter = (lender, chainId, account, meta) => {
27916
28187
  markets.forEach((market, i) => {
27917
28188
  const base = i * RIVER_CALLS_PER_MARKET;
27918
28189
  const entire = data[base];
28190
+ if (isFailedCall(entire) || isFailedCall(data[base + 1])) return;
27919
28191
  const status = Number(big2(data[base + 1]));
27920
28192
  const surplus = big2(data[base + 2]);
27921
28193
  const lenderKey = riverLenderKey(lender, chainId, market.index);
@@ -28052,7 +28324,7 @@ var getTellerUserDataConverter = (_lender, chainId, account, meta) => {
28052
28324
  const owed = data[base + 1];
28053
28325
  const collAmount = big3(data[base + 2]);
28054
28326
  const defaulted = !!data[base + 3];
28055
- if (!bidRes) return;
28327
+ if (isFailedCall(bidRes) || isFailedCall(owed) || !bidRes) return;
28056
28328
  const pool = b.pool;
28057
28329
  const lenderKey = tellerLenderKey(pool.pool);
28058
28330
  const metaMap = meta?.[lenderKey];
@@ -28077,7 +28349,9 @@ var getTellerUserDataConverter = (_lender, chainId, account, meta) => {
28077
28349
  if (owedTotal === 0n && collAmount === 0n) return;
28078
28350
  const loanDetails = field8(bidRes, "loanDetails", 5);
28079
28351
  const terms = field8(bidRes, "terms", 6);
28080
- const acceptedTs = Number(big3(field8(loanDetails, "acceptedTimestamp", 4)));
28352
+ const acceptedTs = Number(
28353
+ big3(field8(loanDetails, "acceptedTimestamp", 4))
28354
+ );
28081
28355
  const loanDuration = Number(big3(field8(loanDetails, "loanDuration", 6)));
28082
28356
  const aprBps = Number(big3(field8(terms, "APR", 2)));
28083
28357
  const maturity = acceptedTs > 0 ? acceptedTs + loanDuration : void 0;
@@ -28250,7 +28524,7 @@ var filterEmptyUserData = (userData, keepActiveControllerMode = false) => {
28250
28524
  if (filteredData.length === 0) return null;
28251
28525
  return { ...userData, data: filteredData };
28252
28526
  };
28253
- var convertLenderUserDataResult = (chainId, queriesRaw, rawResults, lenderState) => {
28527
+ var convertLenderUserDataResult = (chainId, queriesRaw, rawResults, lenderState, options) => {
28254
28528
  const queries = organizeUserQueries(queriesRaw);
28255
28529
  const lenderData = {};
28256
28530
  let currentSlice = 0;
@@ -28264,6 +28538,21 @@ var convertLenderUserDataResult = (chainId, queriesRaw, rawResults, lenderState)
28264
28538
  );
28265
28539
  try {
28266
28540
  const data = rawResults.slice(currentSlice, currentSlice + sliceLength);
28541
+ let failedCalls = 0;
28542
+ for (const entry of data) if (isFailedCall(entry)) failedCalls++;
28543
+ const allFailed = data.length > 0 && failedCalls === data.length;
28544
+ if (failedCalls > 0) {
28545
+ options?.onIncomplete?.({
28546
+ lender: query3.lender,
28547
+ failedCalls,
28548
+ totalCalls: data.length,
28549
+ dropped: allFailed
28550
+ });
28551
+ }
28552
+ if (allFailed) {
28553
+ currentSlice += sliceLength;
28554
+ continue;
28555
+ }
28267
28556
  const convertedData = converter(data);
28268
28557
  if (convertedData) {
28269
28558
  if (isMultiMarket(query3.lender)) {
@@ -28271,6 +28560,7 @@ var convertLenderUserDataResult = (chainId, queriesRaw, rawResults, lenderState)
28271
28560
  const filtered = filterEmptyUserData(convertedData[market]);
28272
28561
  if (filtered) {
28273
28562
  filtered.lender = market;
28563
+ if (failedCalls > 0) filtered.incomplete = true;
28274
28564
  lenderData[market] = filtered;
28275
28565
  }
28276
28566
  });
@@ -28283,6 +28573,7 @@ var convertLenderUserDataResult = (chainId, queriesRaw, rawResults, lenderState)
28283
28573
  );
28284
28574
  if (filtered) {
28285
28575
  filtered.lender = query3.lender;
28576
+ if (failedCalls > 0) filtered.incomplete = true;
28286
28577
  lenderData[query3.lender] = filtered;
28287
28578
  }
28288
28579
  }
@@ -28294,199 +28585,6 @@ var convertLenderUserDataResult = (chainId, queriesRaw, rawResults, lenderState)
28294
28585
  return lenderData;
28295
28586
  };
28296
28587
 
28297
- // src/utils/constants.ts
28298
- var MULTICALL_DEFAULT_BATCH_SIZE = 4096;
28299
- var CELO_MULTICALL_ADDRESS = "0x633987602DE5C4F337e3DbF265303A1080324204";
28300
- var BNB_MULTICALL_ADDRESS = "0x963Df249eD09c358A4819E39d9Cd5736c3087184";
28301
- var MANTLE_MULTICALL_ADDRESS = "0x2A51f2F647E1883F88C992244dEd171238693107";
28302
- var ARBITRUM_ONE_MULTICALL_ADDRESS = "0xadF885960B47eA2CD9B55E6DAc6B42b7Cb2806dB";
28303
- var LINEA_MULTICALL_ADDRESS = "0xac1cE734566f390A94b00eb9bf561c2625BF44ea";
28304
- var AVALANCHE_MULTICALL_ADDRESS = "0x0139141Cd4Ee88dF3Cdb65881D411bAE271Ef0C2";
28305
- var BASE_MULTICALL_ADDRESS = "0x091e99cb1C49331a94dD62755D168E941AbD0693";
28306
- var BLAST_MULTICALL_ADDRESS = "0xdC7f370de7631cE9e2c2e1DCDA6B3B5744Cf4705";
28307
- var TAIKO_MULTICALL_ADDRESS = "0x8E24CfC19c6C00c524353CB8816f5f1c2F33c201";
28308
- var HEMI_MULTICALL_ADDRESS = "0x352A86168e6988A1aDF9A15Cb00017AAd3B67155";
28309
- var GNOSIS_MULTICALL_ADDRESS = "0x4dfa9a980efE4802E969AC33968E3d6E59B8a19e";
28310
- var MODE_MULTICALL_ADDRESS = "0xAB39cE30D98a59DFDa40A630b074170800bfF179";
28311
- var FANTOM_MULTICALL_ADDRESS = "0xDb51CffFf3B989d0cB6b58AbF173371b6F2d0D24";
28312
- var SCROLL_MULTICALL_ADDRESS = "0x3b615B1AC55bc34e51a81D3dea67467F32bcb8C2";
28313
- var SHAPE_MULTICALL_ADDRESS = "0x356A450B32f5030ae7083702b86FaFbBe7490411";
28314
- var SONIC_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
28315
- var INK_MULTICALL_ADDRESS = "0xA0fCec583AeE6176527C07B198e5561722332014";
28316
- var METIS_MULTICALL_ADDRESS = "0x7a59ddbB76521E8982Fa3A08598C9a83b14A6C07";
28317
- var IOTA_MULTICALL_ADDRESS = "0x9683D433621A83aA7dd290106e1da85251317F55";
28318
- var KAVA_MULTICALL_ADDRESS = "0x8B741B0D79BE80E135C880F7583d427B4D41F015";
28319
- var CORN_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
28320
- var SAGA_MULTICALL_ADDRESS = "0x743E03cceB4af2efA3CC76838f6E8B50B63F184c";
28321
- var CYBER_MULTICALL_ADDRESS = "0x906d6eB9CF8f64e100e44f8f491b833a8d40B530";
28322
- var METAL_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
28323
- var ZERO_MULTICALL_ADDRESS = "0x9CA4dcb2505fbf536F6c54AA0a77C79f4fBC35C0";
28324
- var BOB_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
28325
- var WORLDCHAIN_MULTICALL_ADDRESS = "0x0a22c04215c97E3F532F4eF30e0aD9458792dAB9";
28326
- var LISK_MULTICALL_ADDRESS = "0xE3dbcD53f4Ce1b06Ab200f4912BD35672e68f1FA";
28327
- var REDSTONE_MULTICALL_ADDRESS = "0xd57B52452a0FDfE3ff8e0A40Bd10D00D0bfe0723";
28328
- var MANTA_MULTICALL_ADDRESS = "0x52dFC0D9960F11A9Ca9FF616e791B91188446a60";
28329
- var ZORA_MULTICALL_ADDRESS = "0xA51c76bEE6746cB487a7e9312E43e2b8f4A37C15";
28330
- var CORE_MULTICALL_ADDRESS = "0xFe9F82D820757787895Da00B1dBD35c3B8b04894";
28331
- var MORPH_MULTICALL_ADDRESS = "0xAcD82113982479B25E7c1D09858F0130921Dbbca";
28332
- var TELOS_MULTICALL_ADDRESS = "0x5d6b0f5335ec95cD2aB7E52f2A0750dd86502435";
28333
- var MULTICALL_ADDRESS = {
28334
- [Chain.OP_MAINNET]: "0x1F98415757620B543A52E61c46B32eB19261F984",
28335
- [Chain.POLYGON_MAINNET]: "0x1F98415757620B543A52E61c46B32eB19261F984",
28336
- [Chain.ETHEREUM_MAINNET]: "0x1F98415757620B543A52E61c46B32eB19261F984",
28337
- [Chain.ARBITRUM_ONE]: ARBITRUM_ONE_MULTICALL_ADDRESS,
28338
- [Chain.BASE]: BASE_MULTICALL_ADDRESS,
28339
- [Chain.CELO_MAINNET]: CELO_MULTICALL_ADDRESS,
28340
- [Chain.BNB_SMART_CHAIN_MAINNET]: BNB_MULTICALL_ADDRESS,
28341
- [Chain.MANTLE]: MANTLE_MULTICALL_ADDRESS,
28342
- [Chain.BLAST]: BLAST_MULTICALL_ADDRESS,
28343
- [Chain.LINEA]: LINEA_MULTICALL_ADDRESS,
28344
- [Chain.AVALANCHE_C_CHAIN]: AVALANCHE_MULTICALL_ADDRESS,
28345
- [Chain.TAIKO_ALETHIA]: TAIKO_MULTICALL_ADDRESS,
28346
- [Chain.HEMI_NETWORK]: HEMI_MULTICALL_ADDRESS,
28347
- [Chain.GNOSIS]: GNOSIS_MULTICALL_ADDRESS,
28348
- [Chain.CORE_BLOCKCHAIN_MAINNET]: CORE_MULTICALL_ADDRESS,
28349
- [Chain.METIS_ANDROMEDA_MAINNET]: METIS_MULTICALL_ADDRESS,
28350
- [Chain.MODE]: MODE_MULTICALL_ADDRESS,
28351
- [Chain.INK]: INK_MULTICALL_ADDRESS,
28352
- [Chain.IOTA_EVM]: IOTA_MULTICALL_ADDRESS,
28353
- [Chain.CORN]: CORN_MULTICALL_ADDRESS,
28354
- [Chain.SONIC_MAINNET]: SONIC_MULTICALL_ADDRESS,
28355
- [Chain.FANTOM_OPERA]: FANTOM_MULTICALL_ADDRESS,
28356
- [Chain.SCROLL]: SCROLL_MULTICALL_ADDRESS,
28357
- [Chain.SHAPE]: SHAPE_MULTICALL_ADDRESS,
28358
- [Chain.CYBER_MAINNET]: CYBER_MULTICALL_ADDRESS,
28359
- [Chain.ZORA]: ZORA_MULTICALL_ADDRESS,
28360
- [Chain.MANTA_PACIFIC_MAINNET]: MANTA_MULTICALL_ADDRESS,
28361
- [Chain.REDSTONE]: REDSTONE_MULTICALL_ADDRESS,
28362
- [Chain.KAVA]: KAVA_MULTICALL_ADDRESS,
28363
- [Chain.METAL_L2]: METAL_MULTICALL_ADDRESS,
28364
- [Chain.LISK]: LISK_MULTICALL_ADDRESS,
28365
- [Chain.BOB]: BOB_MULTICALL_ADDRESS,
28366
- [Chain.ZERO_NETWORK]: ZERO_MULTICALL_ADDRESS,
28367
- [Chain.SAGA]: SAGA_MULTICALL_ADDRESS,
28368
- [Chain.MORPH]: MORPH_MULTICALL_ADDRESS,
28369
- [Chain.TELOS_EVM_MAINNET]: TELOS_MULTICALL_ADDRESS,
28370
- [Chain.WORLD_CHAIN]: WORLDCHAIN_MULTICALL_ADDRESS
28371
- };
28372
-
28373
- // src/utils/multicall.ts
28374
- var { isArray } = lodash;
28375
- var maxRetries = 3;
28376
- var multicallViemAbiArray = async (chainId, abi, calls, getEvmClient18, retry = true, providerId = 0, retries = maxRetries, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, logs = false) => {
28377
- try {
28378
- const provider = getEvmClient18(chainId, providerId);
28379
- const abiIsArray = isArray(abi[0]);
28380
- const returnData = await provider.multicall({
28381
- allowFailure,
28382
- batchSize,
28383
- contracts: calls.map(({ address, name, params }, i) => ({
28384
- abi: abiIsArray ? abi?.[i] : abi,
28385
- address,
28386
- functionName: name,
28387
- args: params
28388
- }))
28389
- });
28390
- if (!allowFailure) return returnData;
28391
- const res = returnData.map(
28392
- ({ result, status }) => status !== "success" ? "0x" : result
28393
- );
28394
- return res;
28395
- } catch (error) {
28396
- if (logs) console.log("error in multicall", error);
28397
- retries--;
28398
- if (retries < 0) throw new Error("Failed too often");
28399
- providerId++;
28400
- return multicallViemAbiArray(
28401
- chainId,
28402
- abi,
28403
- calls,
28404
- getEvmClient18,
28405
- retry,
28406
- providerId,
28407
- retries,
28408
- allowFailure,
28409
- batchSize,
28410
- logs
28411
- );
28412
- }
28413
- };
28414
- var multicallShardedAbiArray = async (chainId, abi, calls, getEvmClient18, poolSize, retries = maxRetries, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, logs = false) => {
28415
- if (poolSize <= 1) {
28416
- return multicallViemAbiArray(
28417
- chainId,
28418
- abi,
28419
- calls,
28420
- getEvmClient18,
28421
- true,
28422
- 0,
28423
- retries,
28424
- allowFailure,
28425
- batchSize,
28426
- logs
28427
- );
28428
- }
28429
- const abiIsArray = isArray(abi[0]);
28430
- const contracts = calls.map(({ address, name, params }, i) => ({
28431
- abi: abiIsArray ? abi?.[i] : abi,
28432
- address,
28433
- functionName: name,
28434
- args: params
28435
- }));
28436
- const batches = [];
28437
- for (let i = 0; i < contracts.length; i += batchSize) {
28438
- batches.push({ start: i, items: contracts.slice(i, i + batchSize) });
28439
- }
28440
- const results = new Array(contracts.length);
28441
- const runBatch = async (batch, rpcId, attemptsLeft, size) => {
28442
- try {
28443
- const provider = getEvmClient18(chainId, rpcId);
28444
- const returnData = await provider.multicall({
28445
- allowFailure,
28446
- batchSize: size,
28447
- contracts: batch.items
28448
- });
28449
- const mapped = allowFailure ? returnData.map(
28450
- ({ result, status }) => status !== "success" ? "0x" : result
28451
- ) : returnData;
28452
- for (let j = 0; j < mapped.length; j++) {
28453
- results[batch.start + j] = mapped[j];
28454
- }
28455
- } catch (error) {
28456
- if (logs) console.log("error in sharded multicall batch", error);
28457
- if (attemptsLeft <= 0) throw error;
28458
- return runBatch(
28459
- batch,
28460
- rpcId + 1,
28461
- attemptsLeft - 1,
28462
- Math.max(1, Math.floor(size / 2))
28463
- );
28464
- }
28465
- };
28466
- const workers = Math.max(1, Math.min(poolSize, batches.length));
28467
- let cursor = 0;
28468
- const worker = async (workerId) => {
28469
- while (true) {
28470
- const idx = cursor++;
28471
- if (idx >= batches.length) break;
28472
- await runBatch(batches[idx], workerId, retries, batchSize);
28473
- }
28474
- };
28475
- await Promise.all(
28476
- Array.from({ length: workers }, (_3, w) => worker(w))
28477
- );
28478
- return results;
28479
- };
28480
- function prepareMulticallInputs(abi, calls) {
28481
- const abiIsArray = isArray(abi[0]);
28482
- return calls.map(({ address, name, params }, i) => ({
28483
- address,
28484
- functionName: name,
28485
- params: params || [],
28486
- abi: abiIsArray ? abi[i] : abi
28487
- }));
28488
- }
28489
-
28490
28588
  // src/utils/rpcCall.ts
28491
28589
  var multicall3Abi = [
28492
28590
  {
@@ -33111,7 +33209,10 @@ var getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient18, allowF
33111
33209
  retries,
33112
33210
  allowFailure,
33113
33211
  batchSize,
33114
- logs
33212
+ logs,
33213
+ // Retry individual failed slots: a dropped call here is indistinguishable
33214
+ // from "user has no position" downstream, so it is worth one extra pass.
33215
+ true
33115
33216
  );
33116
33217
  };
33117
33218
  var prepareLenderUserDataRpcCalls = async (chainId, queriesRaw, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, blockTag = "latest", allowFailure = true) => {
@@ -38864,15 +38965,16 @@ function createMerklRewardFetcher(config) {
38864
38965
  );
38865
38966
  for (const { chainId, opps } of chainResults) {
38866
38967
  for (const opp of opps) {
38867
- if (opp.action !== "LEND" && opp.action !== "BORROW") continue;
38868
38968
  if (!opp.apr || opp.apr <= 0) continue;
38869
38969
  const resolved2 = resolve(opp);
38870
38970
  if (!resolved2) continue;
38971
+ const bucket = resolved2.bucket ?? (opp.action === "LEND" ? "deposit" : opp.action === "BORROW" ? "borrow" : void 0);
38972
+ if (!bucket) continue;
38871
38973
  const lender = resolved2.lender ?? config.lenderKey;
38872
38974
  const reward = ensureReward(result, chainId, lender, resolved2.asset);
38873
38975
  const breakdowns = extractRewardBreakdowns(opp);
38874
38976
  reward.link = getMerkleUrl(opp);
38875
- if (opp.action === "LEND") {
38977
+ if (bucket === "deposit") {
38876
38978
  reward.deposit += opp.apr;
38877
38979
  reward.additionalDepositData.push(...breakdowns);
38878
38980
  } else {
@@ -38916,6 +39018,71 @@ var aaveMerklRewardFetcher = createMerklRewardFetcher({
38916
39018
  lenderKey: "AAVE_V3",
38917
39019
  chainIds: AAVE_V3_MERKL_CHAINS
38918
39020
  });
39021
+ var EULER_MERKL_CHAINS = [
39022
+ "1",
39023
+ // Ethereum
39024
+ "10",
39025
+ // Optimism
39026
+ "56",
39027
+ // BSC
39028
+ "130",
39029
+ // Unichain
39030
+ "137",
39031
+ // Polygon
39032
+ "8453",
39033
+ // Base
39034
+ "42161",
39035
+ // Arbitrum
39036
+ "43114",
39037
+ // Avalanche
39038
+ "80094"
39039
+ // Berachain
39040
+ ];
39041
+ var eulerMerklRewardFetcher = createMerklRewardFetcher({
39042
+ merklProtocolId: "euler",
39043
+ lenderKey: "EULER_V2",
39044
+ chainIds: EULER_MERKL_CHAINS,
39045
+ resolveAsset: (opp) => {
39046
+ const vault = opp.explorerAddress?.toLowerCase();
39047
+ if (!vault) return void 0;
39048
+ return { asset: vault };
39049
+ }
39050
+ });
39051
+ var MORPHO_MERKL_CHAINS = [
39052
+ "1",
39053
+ // Ethereum
39054
+ "130",
39055
+ // Unichain
39056
+ "137",
39057
+ // Polygon
39058
+ "8453",
39059
+ // Base
39060
+ "42161",
39061
+ // Arbitrum
39062
+ "4663"
39063
+ // Robinhood chain
39064
+ ];
39065
+ function parseMorphoUniqueKey(depositUrl) {
39066
+ if (!depositUrl) return void 0;
39067
+ const m = depositUrl.match(/\/market\/(0x[0-9a-fA-F]{64})/);
39068
+ return m?.[1]?.toLowerCase();
39069
+ }
39070
+ var morphoCollateralMerklRewardFetcher = createMerklRewardFetcher({
39071
+ merklProtocolId: "morpho",
39072
+ lenderKey: "MORPHO_BLUE",
39073
+ chainIds: MORPHO_MERKL_CHAINS,
39074
+ resolveAsset: (opp) => {
39075
+ if (opp.type !== "MORPHOCOLLATERAL") return void 0;
39076
+ const uniqueKey = parseMorphoUniqueKey(opp.depositUrl);
39077
+ const collateral = opp.explorerAddress?.toLowerCase();
39078
+ if (!uniqueKey || !collateral) return void 0;
39079
+ return {
39080
+ asset: collateral,
39081
+ lender: `MORPHO_BLUE_${uniqueKey.slice(2).toUpperCase()}`,
39082
+ bucket: "deposit"
39083
+ };
39084
+ }
39085
+ });
38919
39086
 
38920
39087
  // src/yields/rewards/fetchLenderRewards.ts
38921
39088
  function mergeRewardResults(target, source) {
@@ -38927,7 +39094,11 @@ function mergeRewardResults(target, source) {
38927
39094
  }
38928
39095
  }
38929
39096
  }
38930
- var rewardFetchers = [aaveMerklRewardFetcher];
39097
+ var rewardFetchers = [
39098
+ aaveMerklRewardFetcher,
39099
+ eulerMerklRewardFetcher,
39100
+ morphoCollateralMerklRewardFetcher
39101
+ ];
38931
39102
  async function fetchLenderRewards() {
38932
39103
  const results = await Promise.all(
38933
39104
  rewardFetchers.map((f) => safeFetch(f.label, f.fetch))