@1delta/margin-fetcher 5.0.45 → 5.0.47

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.js CHANGED
@@ -14976,8 +14976,46 @@ var ComptrollerAbi = [
14976
14976
  outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
14977
14977
  stateMutability: "view",
14978
14978
  type: "function"
14979
+ },
14980
+ // Per-market pause guardians. Classic Compound V2 keeps them as public
14981
+ // mappings on the Comptroller — the cToken lenses do NOT expose them, so a
14982
+ // fork on the standard lens path can only learn its pause state from here.
14983
+ // `mintAllowed` / `borrowAllowed` hard-revert ("mint is paused" /
14984
+ // "borrow is paused") when set, which is why they gate `depositsEnabled` /
14985
+ // `borrowingEnabled` rather than merely capping an amount.
14986
+ {
14987
+ inputs: [{ internalType: "address", name: "", type: "address" }],
14988
+ name: "mintGuardianPaused",
14989
+ outputs: [{ internalType: "bool", name: "", type: "bool" }],
14990
+ stateMutability: "view",
14991
+ type: "function"
14992
+ },
14993
+ {
14994
+ inputs: [{ internalType: "address", name: "", type: "address" }],
14995
+ name: "borrowGuardianPaused",
14996
+ outputs: [{ internalType: "bool", name: "", type: "bool" }],
14997
+ stateMutability: "view",
14998
+ type: "function"
14979
14999
  }
14980
15000
  ];
15001
+ var COMPTROLLER_PAUSE_READ_LENDERS = [
15002
+ Lender.COMPOUND_V2,
15003
+ Lender.CREAM_FINANCE,
15004
+ Lender.FLUX_FINANCE,
15005
+ Lender.WE_PIGGY,
15006
+ Lender.GAMMA,
15007
+ Lender.CAPY_FI,
15008
+ Lender.LODESTAR,
15009
+ Lender.TENDER
15010
+ ];
15011
+ var usesComptrollerPauseReads = (lender) => COMPTROLLER_PAUSE_READ_LENDERS.includes(lender);
15012
+ var parsePausedFlag = (raw) => typeof raw === "boolean" ? raw : void 0;
15013
+ var resolveMarketPause = (token, live) => {
15014
+ const mintPaused = live?.mintPaused ?? token?.mintPaused;
15015
+ const borrowPaused = live?.borrowPaused ?? token?.borrowPaused;
15016
+ if (mintPaused === void 0 && borrowPaused === void 0) return void 0;
15017
+ return { mintPaused, borrowPaused };
15018
+ };
14981
15019
 
14982
15020
  // src/lending/public-data/compound-v2/publicCallBuild.ts
14983
15021
  var buildCompoundV2StyleLenderReserveCall = (chainId, lender) => {
@@ -15058,6 +15096,18 @@ var buildCompoundV2StyleLenderReserveCall = (chainId, lender) => {
15058
15096
  name: "liquidationIncentiveMantissa",
15059
15097
  params: []
15060
15098
  });
15099
+ if (usesComptrollerPauseReads(lender)) {
15100
+ for (const name of ["mintGuardianPaused", "borrowGuardianPaused"]) {
15101
+ for (const tk of tokens) {
15102
+ calls.push({
15103
+ abi: ComptrollerAbi,
15104
+ address: stdComptroller,
15105
+ name,
15106
+ params: [tk.cToken]
15107
+ });
15108
+ }
15109
+ }
15110
+ }
15061
15111
  }
15062
15112
  return calls;
15063
15113
  };
@@ -15513,7 +15563,10 @@ function convertSingleEntry(opts) {
15513
15563
  if (perMarketIncentive !== void 0 && Number(perMarketIncentive) > 0) {
15514
15564
  liquidationPenalty = Math.max(
15515
15565
  Number(
15516
- parseRawAmount(perMarketIncentive.toString(), RESERVE_MANTISSA_DECIMALS)
15566
+ parseRawAmount(
15567
+ perMarketIncentive.toString(),
15568
+ RESERVE_MANTISSA_DECIMALS
15569
+ )
15517
15570
  ) - 1,
15518
15571
  0
15519
15572
  );
@@ -15534,7 +15587,11 @@ function convertSingleEntry(opts) {
15534
15587
  );
15535
15588
  const liquidity = totalSupplyUnderlying - totalDebt;
15536
15589
  const price2 = prices[asset.assetGroup] ?? 0;
15537
- const pausedActions = currentEntry.pausedActions;
15590
+ const pausedActions = { ...currentEntry.pausedActions };
15591
+ if (opts.pause?.mintPaused !== void 0)
15592
+ pausedActions[0 /* MINT */] = opts.pause.mintPaused;
15593
+ if (opts.pause?.borrowPaused !== void 0)
15594
+ pausedActions[2 /* BORROW */] = opts.pause.borrowPaused;
15538
15595
  const allPaused = pausedActions[0 /* MINT */] && pausedActions[2 /* BORROW */] && pausedActions[1 /* REDEEM */] && pausedActions[3 /* REPAY */];
15539
15596
  const poolId = asset.address;
15540
15597
  const collateralActive = Boolean(currentEntry?.isListed);
@@ -16366,7 +16423,9 @@ var getCompoundV2DataConverter = (lender, chainId, prices, additionalYields, tok
16366
16423
  const isSumer = isSumerType(lender);
16367
16424
  const stdComptroller = isSumer ? void 0 : getCompoundV2Comptroller(chainId, lender);
16368
16425
  const stdComptrollerCalls = stdComptroller ? 2 : 0;
16369
- const expectedNumberOfCalls = isSumer ? tokenCount + SUMER_GROUP_COUNT : tokenCount + stdComptrollerCalls;
16426
+ const pauseReads = Boolean(stdComptroller) && usesComptrollerPauseReads(lender);
16427
+ const pauseCalls = pauseReads ? tokenCount * 2 : 0;
16428
+ const expectedNumberOfCalls = isSumer ? tokenCount + SUMER_GROUP_COUNT : tokenCount + stdComptrollerCalls + pauseCalls;
16370
16429
  const reader = getReader(lender, chainId);
16371
16430
  return [
16372
16431
  (data) => {
@@ -16403,6 +16462,8 @@ var getCompoundV2DataConverter = (lender, chainId, prices, additionalYields, tok
16403
16462
  globalCloseFactor = closeFactorMantissa;
16404
16463
  globalLiquidationPenalty = incentiveMantissa !== void 0 ? Math.max(incentiveMantissa - 1, 0) : void 0;
16405
16464
  }
16465
+ const mintPausedBase = tokenCount + stdComptrollerCalls;
16466
+ const borrowPausedBase = mintPausedBase + tokenCount;
16406
16467
  for (let i = 0; i < tokenCount; i++) {
16407
16468
  const { underlying, cToken } = compoundV2Tokens2[i];
16408
16469
  if (!cToken || !underlying) continue;
@@ -16419,7 +16480,13 @@ var getCompoundV2DataConverter = (lender, chainId, prices, additionalYields, tok
16419
16480
  additionalYields,
16420
16481
  cToken,
16421
16482
  closeFactor: globalCloseFactor,
16422
- liquidationPenalty: globalLiquidationPenalty
16483
+ liquidationPenalty: globalLiquidationPenalty,
16484
+ // live guardian read first, then the static fallback published on
16485
+ // the token entry for forks that expose no getter at all
16486
+ pause: pauseReads ? resolveMarketPause(compoundV2Tokens2[i], {
16487
+ mintPaused: parsePausedFlag(data[mintPausedBase + i]),
16488
+ borrowPaused: parsePausedFlag(data[borrowPausedBase + i])
16489
+ }) : void 0
16423
16490
  });
16424
16491
  out.data[entry.marketUid] = entry;
16425
16492
  }
@@ -27655,7 +27722,31 @@ var maxRetries = 3;
27655
27722
  var MULTICALL_FAILURE = "0x";
27656
27723
  var isFailedCall = (value) => value === void 0 || value === null || value === MULTICALL_FAILURE;
27657
27724
  var MULTICALL_REPAIR_ROUNDS = 3;
27658
- var MAX_CALLS_PER_SHARD = 400;
27725
+ var MAX_CALLS_PER_SHARD = 300;
27726
+ var ONE_REQUEST_BATCH_BYTES = 1e6;
27727
+ var MAX_INFLIGHT_REQUESTS = 6;
27728
+ var HEDGE_DELAY_MS = 1200;
27729
+ var SHARD_TIMEOUT_MS = 4e3;
27730
+ var MIN_ADAPTIVE_SHARD = 25;
27731
+ var ADAPTIVE_CAP_TTL_MS = 6e4;
27732
+ var endpointCallCap = /* @__PURE__ */ new Map();
27733
+ var capFor = (url, requested) => {
27734
+ const hit = endpointCallCap.get(url);
27735
+ if (!hit) return requested;
27736
+ if (Date.now() - hit.at > ADAPTIVE_CAP_TTL_MS) {
27737
+ endpointCallCap.delete(url);
27738
+ return requested;
27739
+ }
27740
+ return Math.min(requested, hit.calls);
27741
+ };
27742
+ var noteEndpointRefusal = (url, calls) => {
27743
+ if (calls <= MIN_ADAPTIVE_SHARD) return;
27744
+ const next = Math.max(MIN_ADAPTIVE_SHARD, Math.floor(calls / 2));
27745
+ const current = endpointCallCap.get(url);
27746
+ if (current && Date.now() - current.at <= ADAPTIVE_CAP_TTL_MS && current.calls <= next)
27747
+ return;
27748
+ endpointCallCap.set(url, { calls: next, at: Date.now() });
27749
+ };
27659
27750
  var DETERMINISTIC_ERROR_NAMES = /* @__PURE__ */ new Set([
27660
27751
  "ContractFunctionRevertedError",
27661
27752
  "RawContractError",
@@ -27679,13 +27770,13 @@ var REPAIR_BACKOFF_JITTER_MS = 60;
27679
27770
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
27680
27771
  var backoffForRound = (round) => REPAIR_BACKOFF_BASE_MS * 2 ** round + Math.random() * REPAIR_BACKOFF_JITTER_MS;
27681
27772
  var endpointUrl = (client, rpcId) => client?.transport?.url ?? `rpc#${rpcId}`;
27682
- var resolveEndpoint = (chainId, getEvmClient16, startRpcId, tried, maxProbe = 12) => {
27773
+ var resolveEndpoint = (chainId, getEvmClient17, startRpcId, tried, maxProbe = 12, timeoutMs) => {
27683
27774
  let fallback = null;
27684
27775
  for (let probe = 0; probe < maxProbe; probe++) {
27685
27776
  const rpcId = startRpcId + probe;
27686
27777
  let client;
27687
27778
  try {
27688
- client = getEvmClient16(chainId, rpcId);
27779
+ client = getEvmClient17(chainId, rpcId, { timeoutMs });
27689
27780
  } catch {
27690
27781
  break;
27691
27782
  }
@@ -27715,7 +27806,7 @@ var recordPermanentFailures = (slots, offset, collector) => {
27715
27806
  if (slots[i].permanent) collector.add(offset + i);
27716
27807
  }
27717
27808
  };
27718
- var repairFailedSlots = async (chainId, contracts, slots, getEvmClient16, nextRpcId, batchSize, logs, rounds = MULTICALL_REPAIR_ROUNDS, options) => {
27809
+ var repairFailedSlots = async (chainId, contracts, slots, getEvmClient17, nextRpcId, batchSize, logs, rounds = MULTICALL_REPAIR_ROUNDS, options) => {
27719
27810
  let searchFrom = nextRpcId;
27720
27811
  for (let round = 0; round < rounds; round++) {
27721
27812
  const failedIdx = [];
@@ -27725,7 +27816,7 @@ var repairFailedSlots = async (chainId, contracts, slots, getEvmClient16, nextRp
27725
27816
  if (failedIdx.length === 0) return slots;
27726
27817
  const endpoint = resolveEndpoint(
27727
27818
  chainId,
27728
- getEvmClient16,
27819
+ getEvmClient17,
27729
27820
  searchFrom,
27730
27821
  options?.tried
27731
27822
  );
@@ -27777,9 +27868,9 @@ var repairFailedSlots = async (chainId, contracts, slots, getEvmClient16, nextRp
27777
27868
  }
27778
27869
  return slots;
27779
27870
  };
27780
- var multicallViemAbiArray = async (chainId, abi, calls, getEvmClient16, retry = true, providerId = 0, retries = maxRetries, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, logs = false, retryFailed = false, permanentFailures, options) => {
27871
+ var multicallViemAbiArray = async (chainId, abi, calls, getEvmClient17, retry = true, providerId = 0, retries = maxRetries, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, logs = false, retryFailed = false, permanentFailures, options) => {
27781
27872
  const tried = options?.tried ?? /* @__PURE__ */ new Set();
27782
- const endpoint = resolveEndpoint(chainId, getEvmClient16, providerId, tried);
27873
+ const endpoint = resolveEndpoint(chainId, getEvmClient17, providerId, tried);
27783
27874
  if (!endpoint) throw new Error("No usable RPC endpoint for " + chainId);
27784
27875
  const endpointOptions = {
27785
27876
  tried,
@@ -27816,7 +27907,7 @@ var multicallViemAbiArray = async (chainId, abi, calls, getEvmClient16, retry =
27816
27907
  chainId,
27817
27908
  abi,
27818
27909
  calls,
27819
- getEvmClient16,
27910
+ getEvmClient17,
27820
27911
  retry,
27821
27912
  endpoint.rpcId + 1,
27822
27913
  retries - 1,
@@ -27832,7 +27923,7 @@ var multicallViemAbiArray = async (chainId, abi, calls, getEvmClient16, retry =
27832
27923
  chainId,
27833
27924
  contracts,
27834
27925
  slots,
27835
- getEvmClient16,
27926
+ getEvmClient17,
27836
27927
  endpoint.rpcId + 1,
27837
27928
  batchSize,
27838
27929
  logs,
@@ -27856,7 +27947,7 @@ var multicallViemAbiArray = async (chainId, abi, calls, getEvmClient16, retry =
27856
27947
  chainId,
27857
27948
  abi,
27858
27949
  calls,
27859
- getEvmClient16,
27950
+ getEvmClient17,
27860
27951
  retry,
27861
27952
  endpoint.rpcId + 1,
27862
27953
  retries,
@@ -27869,13 +27960,13 @@ var multicallViemAbiArray = async (chainId, abi, calls, getEvmClient16, retry =
27869
27960
  );
27870
27961
  }
27871
27962
  };
27872
- var multicallShardedAbiArray = async (chainId, abi, calls, getEvmClient16, poolSize, retries = maxRetries, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, logs = false, retryFailed = false, permanentFailures, options) => {
27963
+ var multicallShardedAbiArray = async (chainId, abi, calls, getEvmClient17, poolSize, retries = maxRetries, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, logs = false, retryFailed = false, permanentFailures, options) => {
27873
27964
  if (poolSize <= 1) {
27874
27965
  return multicallViemAbiArray(
27875
27966
  chainId,
27876
27967
  abi,
27877
27968
  calls,
27878
- getEvmClient16,
27969
+ getEvmClient17,
27879
27970
  true,
27880
27971
  0,
27881
27972
  retries,
@@ -27894,39 +27985,30 @@ var multicallShardedAbiArray = async (chainId, abi, calls, getEvmClient16, poolS
27894
27985
  functionName: name,
27895
27986
  args: params
27896
27987
  }));
27988
+ const requestBytes = batchSize < MULTICALL_DEFAULT_BATCH_SIZE ? batchSize : ONE_REQUEST_BATCH_BYTES;
27989
+ const workerBudget = Math.max(1, Math.floor(MAX_INFLIGHT_REQUESTS / 2));
27990
+ const workers = Math.max(1, Math.min(poolSize, workerBudget));
27897
27991
  const shardSize = Math.max(
27898
27992
  1,
27899
- Math.min(MAX_CALLS_PER_SHARD, Math.ceil(contracts.length / poolSize))
27993
+ Math.min(MAX_CALLS_PER_SHARD, Math.ceil(contracts.length / workers))
27900
27994
  );
27901
27995
  const batches = [];
27902
27996
  for (let i = 0; i < contracts.length; i += shardSize) {
27903
27997
  batches.push({ start: i, items: contracts.slice(i, i + shardSize) });
27904
27998
  }
27905
27999
  const results = new Array(contracts.length);
27906
- const runBatch = async (batch, rpcId, attemptsLeft, size, tried) => {
27907
- const endpoint = resolveEndpoint(chainId, getEvmClient16, rpcId, tried);
27908
- if (!endpoint) {
27909
- if (logs)
27910
- console.log(
27911
- `sharded multicall: no untried endpoint left for chain ${chainId}`
27912
- );
27913
- return;
27914
- }
27915
- const shardOptions = {
27916
- tried,
27917
- onEndpointFailure: options?.onEndpointFailure
27918
- };
28000
+ const request = async (endpoint, items) => {
27919
28001
  try {
27920
28002
  const returnData = await endpoint.client.multicall({
27921
28003
  allowFailure,
27922
- batchSize: size,
27923
- contracts: batch.items
28004
+ batchSize: requestBytes,
28005
+ contracts: items
27924
28006
  });
27925
- let slots = toSlots(returnData, allowFailure);
27926
- if (allowFailure && attemptsLeft > 0 && slots.length > 0 && slots.every((s) => isFailedCall(s.value) && !s.permanent)) {
28007
+ const slots = toSlots(returnData, allowFailure);
28008
+ if (allowFailure && slots.length > 0 && slots.every((s) => isFailedCall(s.value) && !s.permanent)) {
27927
28009
  if (logs)
27928
28010
  console.log(
27929
- `sharded multicall shard fully failed on rpc ${endpoint.rpcId}, failing over`
28011
+ `sharded multicall: rpc ${endpoint.rpcId} answered ${items.length} calls with nothing`
27930
28012
  );
27931
28013
  options?.onEndpointFailure?.({
27932
28014
  chainId,
@@ -27934,61 +28016,165 @@ var multicallShardedAbiArray = async (chainId, abi, calls, getEvmClient16, poolS
27934
28016
  rpcId: endpoint.rpcId,
27935
28017
  kind: "slots"
27936
28018
  });
27937
- await sleep(backoffForRound(0));
27938
- return runBatch(
27939
- batch,
27940
- endpoint.rpcId + 1,
27941
- attemptsLeft - 1,
27942
- size,
27943
- tried
27944
- );
27945
- }
27946
- if (allowFailure && retryFailed) {
27947
- slots = await repairFailedSlots(
27948
- chainId,
27949
- batch.items,
27950
- slots,
27951
- getEvmClient16,
27952
- endpoint.rpcId + 1,
27953
- size,
27954
- logs,
27955
- MULTICALL_REPAIR_ROUNDS,
27956
- shardOptions
27957
- );
27958
- }
27959
- recordPermanentFailures(slots, batch.start, permanentFailures);
27960
- for (let j = 0; j < slots.length; j++) {
27961
- results[batch.start + j] = slots[j].value;
28019
+ noteEndpointRefusal(endpoint.url, items.length);
28020
+ return null;
27962
28021
  }
28022
+ return slots;
27963
28023
  } catch (error) {
27964
- if (logs) console.log("error in sharded multicall batch", error);
28024
+ if (logs) console.log("error in sharded multicall request", error);
27965
28025
  options?.onEndpointFailure?.({
27966
28026
  chainId,
27967
28027
  url: endpoint.url,
27968
28028
  rpcId: endpoint.rpcId,
27969
28029
  kind: "transport"
27970
28030
  });
27971
- if (attemptsLeft <= 0) throw error;
27972
- await sleep(backoffForRound(0));
27973
- return runBatch(
27974
- batch,
27975
- endpoint.rpcId + 1,
27976
- attemptsLeft - 1,
27977
- Math.max(1, Math.floor(size / 2)),
27978
- tried
28031
+ noteEndpointRefusal(endpoint.url, items.length);
28032
+ return null;
28033
+ }
28034
+ };
28035
+ const firstUsable = (attempts) => new Promise((resolve) => {
28036
+ let pending = attempts.length;
28037
+ let settled = false;
28038
+ const lose = () => {
28039
+ if (!settled && --pending === 0) resolve(null);
28040
+ };
28041
+ for (const attempt of attempts) {
28042
+ attempt.then((won) => {
28043
+ if (settled) return;
28044
+ if (won) {
28045
+ settled = true;
28046
+ resolve(won);
28047
+ } else lose();
28048
+ }, lose);
28049
+ }
28050
+ });
28051
+ const attemptHedged = async (items, startRpcId, tried) => {
28052
+ const primary = resolveEndpoint(
28053
+ chainId,
28054
+ getEvmClient17,
28055
+ startRpcId,
28056
+ tried,
28057
+ 12,
28058
+ SHARD_TIMEOUT_MS
28059
+ );
28060
+ if (!primary) {
28061
+ if (logs)
28062
+ console.log(
28063
+ `sharded multicall: no untried endpoint left for chain ${chainId}`
28064
+ );
28065
+ return null;
28066
+ }
28067
+ let timer;
28068
+ let hedgeStarted = false;
28069
+ let beginHedge = () => {
28070
+ };
28071
+ const hedged = new Promise((resolve) => {
28072
+ beginHedge = () => {
28073
+ if (hedgeStarted) return;
28074
+ hedgeStarted = true;
28075
+ clearTimeout(timer);
28076
+ const alt = resolveEndpoint(
28077
+ chainId,
28078
+ getEvmClient17,
28079
+ primary.rpcId + 1,
28080
+ tried,
28081
+ 12,
28082
+ SHARD_TIMEOUT_MS
28083
+ );
28084
+ if (!alt) return resolve(null);
28085
+ const altItems = items.slice(0, capFor(alt.url, items.length));
28086
+ if (altItems.length < items.length) return resolve(null);
28087
+ request(alt, items).then(
28088
+ (slots) => resolve(slots ? { slots, rpcId: alt.rpcId } : null)
28089
+ );
28090
+ };
28091
+ });
28092
+ timer = setTimeout(() => beginHedge(), HEDGE_DELAY_MS);
28093
+ const direct = request(primary, items).then((slots) => {
28094
+ if (slots) return { slots, rpcId: primary.rpcId };
28095
+ beginHedge();
28096
+ return null;
28097
+ });
28098
+ const won = await firstUsable([direct, hedged]);
28099
+ clearTimeout(timer);
28100
+ return won;
28101
+ };
28102
+ const runBatch = async (batch, rpcId, attemptsLeft, tried) => {
28103
+ if (!batch.items.length) return;
28104
+ const won = await attemptHedged(batch.items, rpcId, tried);
28105
+ if (!won) {
28106
+ if (attemptsLeft > 0 && batch.items.length > 1) {
28107
+ const half = Math.ceil(batch.items.length / 2);
28108
+ await sleep(backoffForRound(0));
28109
+ await runBatch(
28110
+ { start: batch.start, items: batch.items.slice(0, half) },
28111
+ rpcId,
28112
+ attemptsLeft - 1,
28113
+ tried
28114
+ );
28115
+ await runBatch(
28116
+ { start: batch.start + half, items: batch.items.slice(half) },
28117
+ rpcId + 1,
28118
+ attemptsLeft - 1,
28119
+ tried
28120
+ );
28121
+ }
28122
+ return;
28123
+ }
28124
+ let slots = won.slots;
28125
+ if (allowFailure && retryFailed) {
28126
+ slots = await repairFailedSlots(
28127
+ chainId,
28128
+ batch.items,
28129
+ slots,
28130
+ getEvmClient17,
28131
+ won.rpcId + 1,
28132
+ requestBytes,
28133
+ logs,
28134
+ MULTICALL_REPAIR_ROUNDS,
28135
+ { tried, onEndpointFailure: options?.onEndpointFailure }
27979
28136
  );
27980
28137
  }
28138
+ recordPermanentFailures(slots, batch.start, permanentFailures);
28139
+ for (let j = 0; j < slots.length; j++) {
28140
+ results[batch.start + j] = slots[j].value;
28141
+ }
27981
28142
  };
27982
- const workers = Math.max(1, Math.min(poolSize, batches.length));
27983
28143
  let cursor = 0;
27984
28144
  const worker = async (workerId) => {
27985
28145
  while (true) {
27986
28146
  const idx = cursor++;
27987
28147
  if (idx >= batches.length) break;
27988
- await runBatch(batches[idx], workerId, retries, batchSize, /* @__PURE__ */ new Set());
28148
+ const batch = batches[idx];
28149
+ const tried = /* @__PURE__ */ new Set();
28150
+ const start = resolveEndpoint(
28151
+ chainId,
28152
+ getEvmClient17,
28153
+ workerId,
28154
+ void 0,
28155
+ 12,
28156
+ SHARD_TIMEOUT_MS
28157
+ );
28158
+ const cap = start ? capFor(start.url, batch.items.length) : batch.items.length;
28159
+ for (let off = 0; off < batch.items.length; off += cap) {
28160
+ await runBatch(
28161
+ {
28162
+ start: batch.start + off,
28163
+ items: batch.items.slice(off, off + cap)
28164
+ },
28165
+ workerId,
28166
+ retries,
28167
+ tried
28168
+ );
28169
+ }
27989
28170
  }
27990
28171
  };
27991
- await Promise.all(Array.from({ length: workers }, (_3, w) => worker(w)));
28172
+ await Promise.all(
28173
+ Array.from(
28174
+ { length: Math.min(workers, batches.length) },
28175
+ (_3, w) => worker(w)
28176
+ )
28177
+ );
27992
28178
  return results;
27993
28179
  };
27994
28180
  function prepareMulticallInputs(abi, calls) {
@@ -38778,7 +38964,7 @@ function unflattenLenderData(pools) {
38778
38964
  }
38779
38965
  return result;
38780
38966
  }
38781
- var getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient16, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, retries = 3, logs = false, concurrency = 1, permanentFailures, onEndpointFailure) => {
38967
+ var getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient17, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, retries = 3, logs = false, concurrency = 1, permanentFailures, onEndpointFailure) => {
38782
38968
  const queries = organizeUserQueries(queriesRaw);
38783
38969
  const builtCalls = await Promise.all(
38784
38970
  queries.map(async (query3) => {
@@ -38788,7 +38974,7 @@ var getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient16, allowF
38788
38974
  query3.lender,
38789
38975
  query3.account,
38790
38976
  query3.params,
38791
- getEvmClient16
38977
+ getEvmClient17
38792
38978
  );
38793
38979
  return callData.map((call) => ({ call, abi: call.abi ?? abi }));
38794
38980
  })
@@ -38798,7 +38984,7 @@ var getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient16, allowF
38798
38984
  chainId,
38799
38985
  calls.map((call) => call.abi),
38800
38986
  calls.map((call) => call.call),
38801
- getEvmClient16,
38987
+ getEvmClient17,
38802
38988
  concurrency,
38803
38989
  retries,
38804
38990
  allowFailure,
@@ -44118,13 +44304,87 @@ var capFetcher = {
44118
44304
  return { [STCUSD_KEY]: apr, [STCUSD_BRIDGED_GROUP_KEY]: apr };
44119
44305
  }
44120
44306
  };
44121
- var CHAIN_ID10 = Chain.ETHEREUM_MAINNET;
44307
+ var CHAIN_ID10 = "1";
44308
+ var WSTGBP = "0x57c3571f10767e49c9d7b60feb6c67804783b7ae";
44309
+ var WREN_NAV_GROWTH_URL = "https://wstgbp.com/api/nav-growth";
44310
+ var ONE_E189 = 10n ** 18n;
44311
+ var WINDOW_SECONDS6 = 90 * 24 * 60 * 60;
44312
+ var BLOCK_TIME_SECONDS5 = 12;
44313
+ var WINDOW_BLOCKS5 = BigInt(Math.floor(WINDOW_SECONDS6 / BLOCK_TIME_SECONDS5));
44314
+ var MAX_RPC_TRIES5 = 2;
44315
+ var ONCHAIN_DEADLINE_MS = 12e3;
44316
+ var WSTGBP_KEY = "WSTGBP";
44317
+ var WSTGBP_GROUP_KEY = "Wren Staked tGBP::wstGBP";
44318
+ var NAVPRICE_ABI = [
44319
+ {
44320
+ name: "navprice",
44321
+ type: "function",
44322
+ stateMutability: "view",
44323
+ inputs: [],
44324
+ outputs: [{ type: "uint256" }]
44325
+ }
44326
+ ];
44327
+ var fetchWrenAprPercent = async () => {
44328
+ const res = await fetch(WREN_NAV_GROWTH_URL, {
44329
+ headers: { accept: "application/json" },
44330
+ signal: AbortSignal.timeout(8e3)
44331
+ });
44332
+ if (!res.ok) throw new Error(`Wren HTTP ${res.status}`);
44333
+ const json = await res.json();
44334
+ const apr = Number(json?.aprWad) / 1e16;
44335
+ if (!Number.isFinite(apr) || apr <= 0) throw new Error("aprWad missing");
44336
+ return apr;
44337
+ };
44338
+ var readNavAt = (client, blockNumber) => client.readContract({
44339
+ address: WSTGBP,
44340
+ abi: NAVPRICE_ABI,
44341
+ functionName: "navprice",
44342
+ ...blockNumber !== void 0 ? { blockNumber } : {}
44343
+ });
44344
+ var computeAprOnChain = async () => {
44345
+ let lastErr;
44346
+ const deadline = Date.now() + ONCHAIN_DEADLINE_MS;
44347
+ for (let rpcId = 0; rpcId < MAX_RPC_TRIES5; rpcId++) {
44348
+ if (Date.now() > deadline) break;
44349
+ try {
44350
+ const client = getEvmClient(CHAIN_ID10, rpcId);
44351
+ const head = await client.getBlockNumber();
44352
+ const pastBlock = head > WINDOW_BLOCKS5 ? head - WINDOW_BLOCKS5 : 0n;
44353
+ const [navNow, navThen, headBlock, thenBlock] = await Promise.all([
44354
+ readNavAt(client),
44355
+ readNavAt(client, pastBlock),
44356
+ client.getBlock({ blockNumber: head }),
44357
+ client.getBlock({ blockNumber: pastBlock })
44358
+ ]);
44359
+ if (navNow < ONE_E189 || navThen < ONE_E189) {
44360
+ throw new Error("wstGBP: navprice below par \u2014 pruned or bad read");
44361
+ }
44362
+ if (navNow < navThen) {
44363
+ throw new Error("wstGBP: navprice decreased \u2014 non-archival RPC");
44364
+ }
44365
+ const elapsed = Number(headBlock.timestamp - thenBlock.timestamp);
44366
+ if (elapsed <= 0) throw new Error("wstGBP: non-positive window");
44367
+ return annualizeRateDeltaPercent(navNow, navThen, elapsed);
44368
+ } catch (e) {
44369
+ lastErr = e;
44370
+ }
44371
+ }
44372
+ throw lastErr ?? new Error("wstGBP: no RPC served archive state");
44373
+ };
44374
+ var wrenFetcher = {
44375
+ label: "WREN",
44376
+ fetch: async () => {
44377
+ const apr = await fetchWrenAprPercent().catch(() => computeAprOnChain()).catch(() => 0);
44378
+ return { [WSTGBP_KEY]: apr, [WSTGBP_GROUP_KEY]: apr };
44379
+ }
44380
+ };
44381
+ var CHAIN_ID11 = Chain.ETHEREUM_MAINNET;
44122
44382
  var APYUSD = "0x38eeb52f0771140d10c4e9a9a72349a329fe8a6a";
44123
44383
  var APYX_LINEAR_VEST = "0x0d62b4cc02b4b51ed19ddf41d7a7979cf394c99f";
44124
44384
  var APYX_DISCOVER_URL = "https://api.apyx.fi/v1/rewards/seasons/2/discover";
44125
44385
  var APYX_DEFILLAMA_POOL = "cb6139f9-4a68-4efd-8245-0312a92aee55";
44126
44386
  var YEAR_SECONDS10 = 31536000n;
44127
- var ONE_E189 = 10n ** 18n;
44387
+ var ONE_E1810 = 10n ** 18n;
44128
44388
  var APYUSD_KEY = "APYUSD";
44129
44389
  var APYUSD_GROUP_KEY = "apyUSD::APYUSD";
44130
44390
  var APYUSD_LEGACY_GROUP_KEY = "apyUSD::apyUSD";
@@ -44153,7 +44413,7 @@ var APYX_READ_ABI = [
44153
44413
  ];
44154
44414
  var fetchApyusdAprOnChain = async () => {
44155
44415
  const [totalAssets, unvested, periodRemaining] = await multicallRetryUniversal({
44156
- chain: CHAIN_ID10,
44416
+ chain: CHAIN_ID11,
44157
44417
  abi: APYX_READ_ABI,
44158
44418
  calls: [
44159
44419
  { address: APYUSD, name: "totalAssets", params: [] },
@@ -44170,7 +44430,7 @@ var fetchApyusdAprOnChain = async () => {
44170
44430
  throw new Error("apyx vesting state empty");
44171
44431
  }
44172
44432
  const perSecond = unvested / periodRemaining;
44173
- return Number(perSecond * YEAR_SECONDS10 * ONE_E189 / totalAssets) / 1e16;
44433
+ return Number(perSecond * YEAR_SECONDS10 * ONE_E1810 / totalAssets) / 1e16;
44174
44434
  };
44175
44435
  var fetchApyusdApyFromApi = async () => {
44176
44436
  const res = await fetch(APYX_DISCOVER_URL, {
@@ -46266,6 +46526,55 @@ var SINGLE_CHAIN_ENTRIES = {
46266
46526
  yieldFetcher: capFetcher,
46267
46527
  yieldKey: STCUSD_KEY
46268
46528
  },
46529
+ {
46530
+ // Wren wstGBP — a value-accruing wrapper over tGBP, the FCA-registered
46531
+ // GBP stablecoin issued by BCP Technologies (cash + short-dated gilts,
46532
+ // 1:1 redeemable, listed on Coinbase and Kraken). **The second non-USD
46533
+ // row on this surface after Brix's wiTRY** — see the lira note there:
46534
+ // `supplyRate` is asset-denominated, so a GBP rate belongs beside a
46535
+ // dollar one only with the currency stated, which is why it is in the
46536
+ // description and in `props.savings.base: 'GBP'`. The FX exposure is far
46537
+ // milder than the lira's, but it is the same axis.
46538
+ //
46539
+ // NOT ERC-4626 in any part — `asset()`, `totalAssets()`,
46540
+ // `convertToAssets()` and every `max*` view revert. The token prices
46541
+ // ITSELF through `navprice()`, a figure the issuer restates roughly
46542
+ // weekly in ~6.7 bps steps, hence the `wren-nav` reader.
46543
+ //
46544
+ // Fork-verified 2026-08-14 on the live contract:
46545
+ // - `mint(uint256)` is PERMISSIONLESS and settles at NAV with no entry
46546
+ // fee (`mintcost() == navprice()`): 100 tGBP → 99.1355 wstGBP from a
46547
+ // fresh address. tGBP itself transfers freely (the iTRY check).
46548
+ // - `redeem(uint256)` is the instant exit and pays `burncost()`, which
46549
+ // is ~25 bps BELOW the NAV — 10 wstGBP returned exactly
46550
+ // 10.061984858035600520 tGBP. That gap is reported as the signed
46551
+ // `redemptionDiscountBps`, not smoothed into the share price.
46552
+ // - **`smelt(uint256)` burns shares and pays NOTHING immediately**,
46553
+ // booking a record under `redemptions(i)` for later settlement. It is
46554
+ // a distinct, uncharacterised path — never route an exit to it.
46555
+ // `exit(uint256)` reverts `0x9b604d0b` for an ordinary caller.
46556
+ //
46557
+ // Small: ~83.3k wstGBP over ~84.0k tGBP (≈ $114k at 1.352 GBP/USD).
46558
+ // Ethereum only — no other chain carries the contract, though tGBP
46559
+ // itself is a LayerZero OFT on six.
46560
+ reader: "wren-nav",
46561
+ address: "0x57c3571f10767e49c9d7b60feb6c67804783b7ae",
46562
+ underlying: "0x27f6c8289550fce67f6b50bed1f519966afe5287",
46563
+ // tGBP
46564
+ symbol: "wstGBP",
46565
+ brand: "Wren",
46566
+ // The backing is an FCA-registered issuer's segregated cash and gilt
46567
+ // reserves, and the share price is a NAV the issuer restates — attested,
46568
+ // not verifiable on-chain. Same class as Apyx and Brix.
46569
+ solvency: "nav-attested",
46570
+ description: "tGBP is a pound-sterling stablecoin from BCP Technologies, an FCA-registered issuer, backed 1:1 by cash and short-dated UK gilts held in segregated accounts. wstGBP wraps it and accrues the gilt yield through a NAV the issuer restates weekly \u2014 so the rate is earned in POUNDS, and a dollar-based holder keeps only what is left after the GBP/USD move. Minting is permissionless and free; redeeming is instant but settles ~25 bps below NAV.",
46571
+ decimals: 18,
46572
+ isRebasing: false,
46573
+ isMintable: true,
46574
+ withdrawalMode: "instant",
46575
+ yieldFetcher: wrenFetcher,
46576
+ yieldKey: WSTGBP_KEY
46577
+ },
46269
46578
  {
46270
46579
  // Apyx apyUSD — ERC-4626 over apxUSD, the "Dividend-Backed
46271
46580
  // Dollar" (variable-rate perpetual preferred stock of DAT
@@ -53696,6 +54005,19 @@ var FlashAbi = [
53696
54005
  name: "FLASHLOAN_PREMIUM_TOTAL",
53697
54006
  inputs: []
53698
54007
  },
54008
+ {
54009
+ inputs: [],
54010
+ name: "decimals",
54011
+ outputs: [
54012
+ {
54013
+ internalType: "uint8",
54014
+ name: "",
54015
+ type: "uint8"
54016
+ }
54017
+ ],
54018
+ stateMutability: "view",
54019
+ type: "function"
54020
+ },
53699
54021
  {
53700
54022
  inputs: [
53701
54023
  {
@@ -53718,6 +54040,14 @@ var FlashAbi = [
53718
54040
  ];
53719
54041
  var DEFAULT_BATCH_SIZE = 4096;
53720
54042
  var isValidResult = (v) => typeof v === "bigint";
54043
+ var NATIVE_DECIMALS = 18;
54044
+ function parseDecimalsResult(v) {
54045
+ const n = typeof v === "bigint" ? Number(v) : v;
54046
+ if (typeof n !== "number" || !Number.isInteger(n) || n < 0 || n > 36) {
54047
+ return void 0;
54048
+ }
54049
+ return n;
54050
+ }
53721
54051
  var FLASHLOAN_ENABLED_MASK = BigInt(
53722
54052
  "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF"
53723
54053
  );
@@ -53783,6 +54113,20 @@ async function fetchFlashLiquidityForChain(chain, multicallRetry, list = {}) {
53783
54113
  const balancerV3Calls = buildBalanceCalls(balancerV3s);
53784
54114
  const uniswapV4s = RELEVANT_UNISWAP_V4_FORKS[chain] ?? [];
53785
54115
  const uniswapV4Calls = buildBalanceCalls(uniswapV4s);
54116
+ const decimalsByAsset = {
54117
+ [zeroAddress]: NATIVE_DECIMALS
54118
+ };
54119
+ for (const asset of unifiedAssets) {
54120
+ const fromList = list[asset]?.decimals;
54121
+ if (typeof fromList === "number") decimalsByAsset[asset] = fromList;
54122
+ }
54123
+ const assetsMissingDecimals = unifiedAssets.filter(
54124
+ (asset) => decimalsByAsset[asset] === void 0
54125
+ );
54126
+ const decimalsCalls = assetsMissingDecimals.map((address) => ({
54127
+ name: "decimals",
54128
+ address
54129
+ }));
53786
54130
  const calls = [
53787
54131
  ...aaveCalls,
53788
54132
  ...balancerV2Calls,
@@ -53790,6 +54134,8 @@ async function fetchFlashLiquidityForChain(chain, multicallRetry, list = {}) {
53790
54134
  ...balancerV3Calls,
53791
54135
  ...uniswapV4Calls
53792
54136
  ];
54137
+ const decimalsOffset = calls.length;
54138
+ calls.push(...decimalsCalls);
53793
54139
  const rawResults = await multicallRetry({
53794
54140
  chain,
53795
54141
  calls,
@@ -53799,6 +54145,10 @@ async function fetchFlashLiquidityForChain(chain, multicallRetry, list = {}) {
53799
54145
  providerId: 0,
53800
54146
  allowFailure: true
53801
54147
  });
54148
+ assetsMissingDecimals.forEach((asset, i) => {
54149
+ const parsed = parseDecimalsResult(rawResults[decimalsOffset + i]);
54150
+ if (parsed !== void 0) decimalsByAsset[asset] = parsed;
54151
+ });
53802
54152
  let liquidity = {};
53803
54153
  let currentOffset = 0;
53804
54154
  aaveProtocols.forEach((aave) => {
@@ -53811,7 +54161,7 @@ async function fetchFlashLiquidityForChain(chain, multicallRetry, list = {}) {
53811
54161
  const rawAmount = data[2 * i];
53812
54162
  const config = data[2 * i + 1];
53813
54163
  if (typeof rawAmount !== "bigint" || typeof config !== "bigint") return;
53814
- const decimals = list[asset]?.decimals;
54164
+ const decimals = decimalsByAsset[asset];
53815
54165
  const enabled = !AAVE_V3_LENDERS.includes(aave) || getFlashLoanEnabled(config);
53816
54166
  if (enabled && rawAmount > 0n && FLASH_LOAN_IDS[aave] !== void 0) {
53817
54167
  if (!liquidity[asset]) liquidity[asset] = [];
@@ -53822,7 +54172,7 @@ async function fetchFlashLiquidityForChain(chain, multicallRetry, list = {}) {
53822
54172
  source: getAaveTypePoolAddress(chain, aave),
53823
54173
  fee: fee.toString(),
53824
54174
  availableRaw: rawAmount.toString(),
53825
- available: Number(formatUnits(rawAmount, decimals ?? 18)),
54175
+ available: decimals === void 0 ? void 0 : Number(formatUnits(rawAmount, decimals)),
53826
54176
  decimals
53827
54177
  });
53828
54178
  }
@@ -53833,7 +54183,7 @@ async function fetchFlashLiquidityForChain(chain, multicallRetry, list = {}) {
53833
54183
  const data = rawResults.slice(currentOffset, callLen + currentOffset);
53834
54184
  currentOffset += callLen;
53835
54185
  unifiedAssets.forEach((asset, i) => {
53836
- const decimals = list[asset]?.decimals;
54186
+ const decimals = decimalsByAsset[asset];
53837
54187
  const rawAmount = data[i];
53838
54188
  if (isValidResult(rawAmount) && rawAmount > 0n) {
53839
54189
  if (!liquidity[asset]) liquidity[asset] = [];
@@ -53844,7 +54194,7 @@ async function fetchFlashLiquidityForChain(chain, multicallRetry, list = {}) {
53844
54194
  source: balancer.address,
53845
54195
  fee: "0",
53846
54196
  availableRaw: rawAmount.toString(),
53847
- available: Number(formatUnits(rawAmount, decimals ?? 18)),
54197
+ available: decimals === void 0 ? void 0 : Number(formatUnits(rawAmount, decimals)),
53848
54198
  decimals
53849
54199
  });
53850
54200
  }
@@ -53858,7 +54208,7 @@ async function fetchFlashLiquidityForChain(chain, multicallRetry, list = {}) {
53858
54208
  const rawAmount = data[i];
53859
54209
  if (isValidResult(rawAmount) && rawAmount > 0n) {
53860
54210
  if (!liquidity[asset]) liquidity[asset] = [];
53861
- const decimals = list[asset]?.decimals;
54211
+ const decimals = decimalsByAsset[asset];
53862
54212
  liquidity[asset].push({
53863
54213
  id: FLASH_LOAN_IDS[morpho.pool],
53864
54214
  name: morpho.pool,
@@ -53866,7 +54216,7 @@ async function fetchFlashLiquidityForChain(chain, multicallRetry, list = {}) {
53866
54216
  source: morpho.address,
53867
54217
  fee: "0",
53868
54218
  availableRaw: rawAmount.toString(),
53869
- available: Number(formatUnits(rawAmount, decimals ?? 18)),
54219
+ available: decimals === void 0 ? void 0 : Number(formatUnits(rawAmount, decimals)),
53870
54220
  decimals
53871
54221
  });
53872
54222
  }
@@ -53877,7 +54227,7 @@ async function fetchFlashLiquidityForChain(chain, multicallRetry, list = {}) {
53877
54227
  const data = rawResults.slice(currentOffset, callLen + currentOffset);
53878
54228
  currentOffset += callLen;
53879
54229
  unifiedAssets.forEach((asset, i) => {
53880
- const decimals = list[asset]?.decimals;
54230
+ const decimals = decimalsByAsset[asset];
53881
54231
  const rawAmount = data[i];
53882
54232
  if (isValidResult(rawAmount) && rawAmount > 0n) {
53883
54233
  if (!liquidity[asset]) liquidity[asset] = [];
@@ -53888,7 +54238,7 @@ async function fetchFlashLiquidityForChain(chain, multicallRetry, list = {}) {
53888
54238
  source: balancerV3.address,
53889
54239
  fee: "0",
53890
54240
  availableRaw: rawAmount.toString(),
53891
- available: Number(formatUnits(rawAmount, decimals ?? 18)),
54241
+ available: decimals === void 0 ? void 0 : Number(formatUnits(rawAmount, decimals)),
53892
54242
  decimals
53893
54243
  });
53894
54244
  }
@@ -53899,7 +54249,7 @@ async function fetchFlashLiquidityForChain(chain, multicallRetry, list = {}) {
53899
54249
  const data = rawResults.slice(currentOffset, callLen + currentOffset);
53900
54250
  currentOffset += callLen;
53901
54251
  unifiedAssets.forEach((asset, i) => {
53902
- const decimals = list[asset]?.decimals;
54252
+ const decimals = decimalsByAsset[asset];
53903
54253
  const rawAmount = data[i];
53904
54254
  if (isValidResult(rawAmount) && rawAmount > 0n) {
53905
54255
  if (!liquidity[asset]) liquidity[asset] = [];
@@ -53910,7 +54260,7 @@ async function fetchFlashLiquidityForChain(chain, multicallRetry, list = {}) {
53910
54260
  source: uniV4.address,
53911
54261
  fee: "0",
53912
54262
  availableRaw: rawAmount.toString(),
53913
- available: Number(formatUnits(rawAmount, decimals ?? 18)),
54263
+ available: decimals === void 0 ? void 0 : Number(formatUnits(rawAmount, decimals)),
53914
54264
  decimals
53915
54265
  });
53916
54266
  }
@@ -53927,7 +54277,9 @@ function attachPricesToFlashLiquidity(chainId, liq, prices, list = {}) {
53927
54277
  const price2 = prices[priceKey] ?? 0;
53928
54278
  liqCopy[asset] = entry.map((e) => ({
53929
54279
  ...e,
53930
- availableUSD: e.available * price2
54280
+ // absent when the token amount itself is unknown — never 0, which reads
54281
+ // as "no liquidity" rather than "not priced"
54282
+ availableUSD: e.available === void 0 ? void 0 : e.available * price2
53931
54283
  }));
53932
54284
  });
53933
54285
  return liqCopy;
@@ -56548,7 +56900,7 @@ var Erc4626PreviewRedeemAbi = [
56548
56900
  ];
56549
56901
 
56550
56902
  // src/vaults/lst/readers/shared.ts
56551
- var ONE_E1810 = 10n ** 18n;
56903
+ var ONE_E1811 = 10n ** 18n;
56552
56904
  var rescaleDecimals = (v, fromDec, toDec) => toDec >= fromDec ? v * 10n ** BigInt(toDec - fromDec) : v / 10n ** BigInt(fromDec - toDec);
56553
56905
  var MULTICALL3_ADDRESS = "0xcA11bde05977b3631167028862bE2a173976CA11";
56554
56906
  var Multicall3BalanceAbi = [
@@ -56591,7 +56943,7 @@ var readerBeetsStS = (entry) => ({
56591
56943
  }
56592
56944
  const liquidity = toBigInt14(pool);
56593
56945
  return {
56594
- totalAssets: totalSupply * exchangeRate / ONE_E1810,
56946
+ totalAssets: totalSupply * exchangeRate / ONE_E1811,
56595
56947
  totalSupply,
56596
56948
  exchangeRate,
56597
56949
  liquidity
@@ -56624,7 +56976,7 @@ var readerBenqiSavax = (entry) => ({
56624
56976
  {
56625
56977
  address: entry.address,
56626
56978
  name: "getPooledAvaxByShares",
56627
- params: [ONE_E1810]
56979
+ params: [ONE_E1811]
56628
56980
  },
56629
56981
  { address: entry.address, name: "totalPooledAvax", params: [] }
56630
56982
  ],
@@ -56635,7 +56987,7 @@ var readerBenqiSavax = (entry) => ({
56635
56987
  if (totalSupply === void 0 || exchangeRate === void 0) {
56636
56988
  return void 0;
56637
56989
  }
56638
- const totalAssets = toBigInt14(totalPooled) ?? totalSupply * exchangeRate / ONE_E1810;
56990
+ const totalAssets = toBigInt14(totalPooled) ?? totalSupply * exchangeRate / ONE_E1811;
56639
56991
  return {
56640
56992
  totalAssets,
56641
56993
  totalSupply,
@@ -56654,7 +57006,7 @@ var readerBgtWrapper1to1 = (entry) => ({
56654
57006
  return {
56655
57007
  totalAssets: totalSupply,
56656
57008
  totalSupply,
56657
- exchangeRate: ONE_E1810
57009
+ exchangeRate: ONE_E1811
56658
57010
  };
56659
57011
  }
56660
57012
  });
@@ -56684,7 +57036,7 @@ var readerDineroBeraEth = (entry) => ({
56684
57036
  return void 0;
56685
57037
  }
56686
57038
  return {
56687
- totalAssets: totalSupply * exchangeRate / ONE_E1810,
57039
+ totalAssets: totalSupply * exchangeRate / ONE_E1811,
56688
57040
  totalSupply,
56689
57041
  exchangeRate
56690
57042
  };
@@ -56696,7 +57048,7 @@ var readerErc4626 = (entry) => ({
56696
57048
  calls: [
56697
57049
  { address: entry.address, name: "totalAssets", params: [] },
56698
57050
  { address: entry.address, name: "totalSupply", params: [] },
56699
- { address: entry.address, name: "convertToAssets", params: [ONE_E1810] }
57051
+ { address: entry.address, name: "convertToAssets", params: [ONE_E1811] }
56700
57052
  ],
56701
57053
  abis: [Erc4626ReadAbi, TotalSupplyAbi, Erc4626ReadAbi],
56702
57054
  parse: ([assets, supply, rate]) => {
@@ -56713,7 +57065,7 @@ var readerErc4626PreviewRedeem = (entry) => ({
56713
57065
  calls: [
56714
57066
  { address: entry.address, name: "totalAssets", params: [] },
56715
57067
  { address: entry.address, name: "totalSupply", params: [] },
56716
- { address: entry.address, name: "previewRedeem", params: [ONE_E1810] }
57068
+ { address: entry.address, name: "previewRedeem", params: [ONE_E1811] }
56717
57069
  ],
56718
57070
  abis: [Erc4626PreviewRedeemAbi, TotalSupplyAbi, Erc4626PreviewRedeemAbi],
56719
57071
  parse: ([assets, supply, rate]) => {
@@ -56793,7 +57145,7 @@ var readerEtherFiWeEth = (entry) => {
56793
57145
  }
56794
57146
  }
56795
57147
  return {
56796
- totalAssets: totalSupply * exchangeRate / ONE_E1810,
57148
+ totalAssets: totalSupply * exchangeRate / ONE_E1811,
56797
57149
  totalSupply,
56798
57150
  exchangeRate,
56799
57151
  liquidity
@@ -56826,7 +57178,7 @@ var readerHyperbeatBeHype = (entry) => {
56826
57178
  return {
56827
57179
  totalAssets: totalSupply,
56828
57180
  totalSupply,
56829
- exchangeRate: ONE_E1810
57181
+ exchangeRate: ONE_E1811
56830
57182
  };
56831
57183
  }
56832
57184
  };
@@ -56834,7 +57186,7 @@ var readerHyperbeatBeHype = (entry) => {
56834
57186
  return {
56835
57187
  calls: [
56836
57188
  { address: entry.address, name: "totalSupply", params: [] },
56837
- { address: stakingCore, name: "BeHYPEToHYPE", params: [ONE_E1810] }
57189
+ { address: stakingCore, name: "BeHYPEToHYPE", params: [ONE_E1811] }
56838
57190
  ],
56839
57191
  abis: [TotalSupplyAbi, HyperbeatStakingCoreAbi],
56840
57192
  parse: ([supply, rate]) => {
@@ -56844,7 +57196,7 @@ var readerHyperbeatBeHype = (entry) => {
56844
57196
  return void 0;
56845
57197
  }
56846
57198
  return {
56847
- totalAssets: totalSupply * exchangeRate / ONE_E1810,
57199
+ totalAssets: totalSupply * exchangeRate / ONE_E1811,
56848
57200
  totalSupply,
56849
57201
  exchangeRate
56850
57202
  };
@@ -56876,7 +57228,7 @@ var readerKelpRsEth = (entry) => {
56876
57228
  return {
56877
57229
  totalAssets: totalSupply,
56878
57230
  totalSupply,
56879
- exchangeRate: ONE_E1810
57231
+ exchangeRate: ONE_E1811
56880
57232
  };
56881
57233
  }
56882
57234
  };
@@ -56894,7 +57246,7 @@ var readerKelpRsEth = (entry) => {
56894
57246
  return void 0;
56895
57247
  }
56896
57248
  return {
56897
- totalAssets: totalSupply * exchangeRate / ONE_E1810,
57249
+ totalAssets: totalSupply * exchangeRate / ONE_E1811,
56898
57250
  totalSupply,
56899
57251
  exchangeRate
56900
57252
  };
@@ -56926,7 +57278,7 @@ var readerKinetiqKHype = (entry) => {
56926
57278
  return {
56927
57279
  totalAssets: totalSupply,
56928
57280
  totalSupply,
56929
- exchangeRate: ONE_E1810
57281
+ exchangeRate: ONE_E1811
56930
57282
  };
56931
57283
  }
56932
57284
  };
@@ -56934,7 +57286,7 @@ var readerKinetiqKHype = (entry) => {
56934
57286
  return {
56935
57287
  calls: [
56936
57288
  { address: entry.address, name: "totalSupply", params: [] },
56937
- { address: accountant, name: "kHYPEToHYPE", params: [ONE_E1810] }
57289
+ { address: accountant, name: "kHYPEToHYPE", params: [ONE_E1811] }
56938
57290
  ],
56939
57291
  abis: [TotalSupplyAbi, KinetiqStakingAccountantAbi],
56940
57292
  parse: ([supply, rate]) => {
@@ -56944,7 +57296,7 @@ var readerKinetiqKHype = (entry) => {
56944
57296
  return void 0;
56945
57297
  }
56946
57298
  return {
56947
- totalAssets: totalSupply * exchangeRate / ONE_E1810,
57299
+ totalAssets: totalSupply * exchangeRate / ONE_E1811,
56948
57300
  totalSupply,
56949
57301
  exchangeRate
56950
57302
  };
@@ -56984,7 +57336,7 @@ var readerLairStKaia = (entry) => ({
56984
57336
  if (totalSupply === void 0 || exchangeRate === void 0) {
56985
57337
  return void 0;
56986
57338
  }
56987
- const totalAssets = toBigInt14(totalStaking) ?? totalSupply * exchangeRate / ONE_E1810;
57339
+ const totalAssets = toBigInt14(totalStaking) ?? totalSupply * exchangeRate / ONE_E1811;
56988
57340
  return {
56989
57341
  totalAssets,
56990
57342
  totalSupply,
@@ -57018,7 +57370,7 @@ var readerLidoWstEth = (entry) => ({
57018
57370
  return void 0;
57019
57371
  }
57020
57372
  return {
57021
- totalAssets: totalSupply * exchangeRate / ONE_E1810,
57373
+ totalAssets: totalSupply * exchangeRate / ONE_E1811,
57022
57374
  totalSupply,
57023
57375
  exchangeRate
57024
57376
  };
@@ -57056,7 +57408,7 @@ var readerListaSlisBnb = (entry) => {
57056
57408
  return {
57057
57409
  totalAssets: totalSupply,
57058
57410
  totalSupply,
57059
- exchangeRate: ONE_E1810
57411
+ exchangeRate: ONE_E1811
57060
57412
  };
57061
57413
  }
57062
57414
  };
@@ -57064,7 +57416,7 @@ var readerListaSlisBnb = (entry) => {
57064
57416
  return {
57065
57417
  calls: [
57066
57418
  { address: entry.address, name: "totalSupply", params: [] },
57067
- { address: manager, name: "convertSnBnbToBnb", params: [ONE_E1810] },
57419
+ { address: manager, name: "convertSnBnbToBnb", params: [ONE_E1811] },
57068
57420
  { address: manager, name: "getTotalPooledBnb", params: [] }
57069
57421
  ],
57070
57422
  abis: [TotalSupplyAbi, ListaStakeManagerReadAbi, ListaStakeManagerReadAbi],
@@ -57075,7 +57427,7 @@ var readerListaSlisBnb = (entry) => {
57075
57427
  return void 0;
57076
57428
  }
57077
57429
  const pooledBnb = toBigInt14(pooled);
57078
- const totalAssets = pooledBnb ?? totalSupply * exchangeRate / ONE_E1810;
57430
+ const totalAssets = pooledBnb ?? totalSupply * exchangeRate / ONE_E1811;
57079
57431
  return { totalAssets, totalSupply, exchangeRate };
57080
57432
  }
57081
57433
  };
@@ -57105,7 +57457,7 @@ var readerMantleMEth = (entry) => {
57105
57457
  return {
57106
57458
  totalAssets: totalSupply,
57107
57459
  totalSupply,
57108
- exchangeRate: ONE_E1810
57460
+ exchangeRate: ONE_E1811
57109
57461
  };
57110
57462
  }
57111
57463
  };
@@ -57113,7 +57465,7 @@ var readerMantleMEth = (entry) => {
57113
57465
  return {
57114
57466
  calls: [
57115
57467
  { address: entry.address, name: "totalSupply", params: [] },
57116
- { address: staking, name: "mETHToETH", params: [ONE_E1810] }
57468
+ { address: staking, name: "mETHToETH", params: [ONE_E1811] }
57117
57469
  ],
57118
57470
  abis: [TotalSupplyAbi, MantleStakingAbi],
57119
57471
  parse: ([supply, rate]) => {
@@ -57123,7 +57475,7 @@ var readerMantleMEth = (entry) => {
57123
57475
  return void 0;
57124
57476
  }
57125
57477
  return {
57126
- totalAssets: totalSupply * exchangeRate / ONE_E1810,
57478
+ totalAssets: totalSupply * exchangeRate / ONE_E1811,
57127
57479
  totalSupply,
57128
57480
  exchangeRate
57129
57481
  };
@@ -57144,7 +57496,7 @@ var readerOffChain = (entry) => {
57144
57496
  return {
57145
57497
  totalAssets: rescaleDecimals(totalSupply, shareDec, underlyingDec),
57146
57498
  totalSupply,
57147
- exchangeRate: ONE_E1810
57499
+ exchangeRate: ONE_E1811
57148
57500
  };
57149
57501
  }
57150
57502
  };
@@ -57178,7 +57530,7 @@ var readerRenzoEzEth = (entry) => {
57178
57530
  return {
57179
57531
  totalAssets: totalSupply,
57180
57532
  totalSupply,
57181
- exchangeRate: ONE_E1810
57533
+ exchangeRate: ONE_E1811
57182
57534
  };
57183
57535
  }
57184
57536
  };
@@ -57197,7 +57549,7 @@ var readerRenzoEzEth = (entry) => {
57197
57549
  return {
57198
57550
  totalAssets: totalTvl,
57199
57551
  totalSupply,
57200
- exchangeRate: totalTvl * ONE_E1810 / totalSupply
57552
+ exchangeRate: totalTvl * ONE_E1811 / totalSupply
57201
57553
  };
57202
57554
  }
57203
57555
  };
@@ -57253,7 +57605,7 @@ var readerRocketReth = (entry) => {
57253
57605
  }
57254
57606
  const liquidity = depositPool ? toBigInt14(slice2[2]) : void 0;
57255
57607
  return {
57256
- totalAssets: totalSupply * exchangeRate / ONE_E1810,
57608
+ totalAssets: totalSupply * exchangeRate / ONE_E1811,
57257
57609
  totalSupply,
57258
57610
  exchangeRate,
57259
57611
  liquidity
@@ -57295,7 +57647,7 @@ var readerStaderEthx = (entry) => {
57295
57647
  return {
57296
57648
  totalAssets: totalSupply,
57297
57649
  totalSupply,
57298
- exchangeRate: ONE_E1810
57650
+ exchangeRate: ONE_E1811
57299
57651
  };
57300
57652
  }
57301
57653
  };
@@ -57313,7 +57665,7 @@ var readerStaderEthx = (entry) => {
57313
57665
  return void 0;
57314
57666
  }
57315
57667
  return {
57316
- totalAssets: totalSupply * exchangeRate / ONE_E1810,
57668
+ totalAssets: totalSupply * exchangeRate / ONE_E1811,
57317
57669
  totalSupply,
57318
57670
  exchangeRate
57319
57671
  };
@@ -57330,7 +57682,7 @@ var readerStaderMaticX = (entry) => {
57330
57682
  {
57331
57683
  address: rateAddress,
57332
57684
  name: "convertMaticXToMatic",
57333
- params: [ONE_E1810],
57685
+ params: [ONE_E1811],
57334
57686
  chainId: homeChainId
57335
57687
  }
57336
57688
  ],
@@ -57345,7 +57697,7 @@ var readerStaderMaticX = (entry) => {
57345
57697
  }
57346
57698
  const isCrossChain = homeContract !== void 0;
57347
57699
  return {
57348
- totalAssets: isCrossChain ? totalSupply * amountInMatic / ONE_E1810 : totalPooledMatic ?? totalSupply * amountInMatic / ONE_E1810,
57700
+ totalAssets: isCrossChain ? totalSupply * amountInMatic / ONE_E1811 : totalPooledMatic ?? totalSupply * amountInMatic / ONE_E1811,
57349
57701
  totalSupply,
57350
57702
  exchangeRate: amountInMatic
57351
57703
  };
@@ -57377,7 +57729,7 @@ var readerStakeWiseOsEth = (entry) => {
57377
57729
  return {
57378
57730
  totalAssets: totalSupply,
57379
57731
  totalSupply,
57380
- exchangeRate: ONE_E1810
57732
+ exchangeRate: ONE_E1811
57381
57733
  };
57382
57734
  }
57383
57735
  };
@@ -57385,7 +57737,7 @@ var readerStakeWiseOsEth = (entry) => {
57385
57737
  return {
57386
57738
  calls: [
57387
57739
  { address: entry.address, name: "totalSupply", params: [] },
57388
- { address: controller, name: "convertToAssets", params: [ONE_E1810] }
57740
+ { address: controller, name: "convertToAssets", params: [ONE_E1811] }
57389
57741
  ],
57390
57742
  abis: [TotalSupplyAbi, StakeWiseOsTokenAbi],
57391
57743
  parse: ([supply, rate]) => {
@@ -57395,7 +57747,7 @@ var readerStakeWiseOsEth = (entry) => {
57395
57747
  return void 0;
57396
57748
  }
57397
57749
  return {
57398
- totalAssets: totalSupply * exchangeRate / ONE_E1810,
57750
+ totalAssets: totalSupply * exchangeRate / ONE_E1811,
57399
57751
  totalSupply,
57400
57752
  exchangeRate
57401
57753
  };
@@ -57427,7 +57779,7 @@ var readerStCelo = (entry) => {
57427
57779
  return {
57428
57780
  totalAssets: totalSupply,
57429
57781
  totalSupply,
57430
- exchangeRate: ONE_E1810
57782
+ exchangeRate: ONE_E1811
57431
57783
  };
57432
57784
  }
57433
57785
  };
@@ -57435,7 +57787,7 @@ var readerStCelo = (entry) => {
57435
57787
  return {
57436
57788
  calls: [
57437
57789
  { address: entry.address, name: "totalSupply", params: [] },
57438
- { address: manager, name: "toCelo", params: [ONE_E1810] }
57790
+ { address: manager, name: "toCelo", params: [ONE_E1811] }
57439
57791
  ],
57440
57792
  abis: [TotalSupplyAbi, StCeloManagerAbi],
57441
57793
  parse: ([supply, rate]) => {
@@ -57445,7 +57797,7 @@ var readerStCelo = (entry) => {
57445
57797
  return void 0;
57446
57798
  }
57447
57799
  return {
57448
- totalAssets: totalSupply * exchangeRate / ONE_E1810,
57800
+ totalAssets: totalSupply * exchangeRate / ONE_E1811,
57449
57801
  totalSupply,
57450
57802
  exchangeRate
57451
57803
  };
@@ -57478,7 +57830,7 @@ var readerSwellGetRate = (entry) => ({
57478
57830
  return void 0;
57479
57831
  }
57480
57832
  return {
57481
- totalAssets: totalSupply * exchangeRate / ONE_E1810,
57833
+ totalAssets: totalSupply * exchangeRate / ONE_E1811,
57482
57834
  totalSupply,
57483
57835
  exchangeRate
57484
57836
  };
@@ -57509,7 +57861,7 @@ var readerValantisWstHype = (entry) => {
57509
57861
  return {
57510
57862
  totalAssets: totalSupply,
57511
57863
  totalSupply,
57512
- exchangeRate: ONE_E1810
57864
+ exchangeRate: ONE_E1811
57513
57865
  };
57514
57866
  }
57515
57867
  };
@@ -57527,7 +57879,7 @@ var readerValantisWstHype = (entry) => {
57527
57879
  return void 0;
57528
57880
  }
57529
57881
  return {
57530
- totalAssets: totalSupply * exchangeRate / ONE_E1810,
57882
+ totalAssets: totalSupply * exchangeRate / ONE_E1811,
57531
57883
  totalSupply,
57532
57884
  exchangeRate
57533
57885
  };
@@ -57561,7 +57913,7 @@ var readerVedaAccountant = (entry) => {
57561
57913
  return {
57562
57914
  totalAssets: rescaleDecimals(totalSupply, shareDec, underlyingDec),
57563
57915
  totalSupply,
57564
- exchangeRate: ONE_E1810
57916
+ exchangeRate: ONE_E1811
57565
57917
  };
57566
57918
  }
57567
57919
  };
@@ -57580,7 +57932,7 @@ var readerVedaAccountant = (entry) => {
57580
57932
  const exchangeRate = rawRate * scale3;
57581
57933
  return {
57582
57934
  totalAssets: rescaleDecimals(
57583
- totalSupply * exchangeRate / ONE_E1810,
57935
+ totalSupply * exchangeRate / ONE_E1811,
57584
57936
  shareDec,
57585
57937
  underlyingDec
57586
57938
  ),
@@ -57616,9 +57968,9 @@ var readerAnkrRatio = (entry) => ({
57616
57968
  return void 0;
57617
57969
  }
57618
57970
  return {
57619
- totalAssets: totalSupply * ONE_E1810 / r,
57971
+ totalAssets: totalSupply * ONE_E1811 / r,
57620
57972
  totalSupply,
57621
- exchangeRate: ONE_E1810 * ONE_E1810 / r
57973
+ exchangeRate: ONE_E1811 * ONE_E1811 / r
57622
57974
  };
57623
57975
  }
57624
57976
  });
@@ -57648,7 +58000,7 @@ var readerBinanceWbeth = (entry) => ({
57648
58000
  return void 0;
57649
58001
  }
57650
58002
  return {
57651
- totalAssets: totalSupply * exchangeRate / ONE_E1810,
58003
+ totalAssets: totalSupply * exchangeRate / ONE_E1811,
57652
58004
  totalSupply,
57653
58005
  exchangeRate
57654
58006
  };
@@ -57694,7 +58046,7 @@ var readerCoreEarnRate = (entry) => {
57694
58046
  return {
57695
58047
  totalAssets: totalSupply * r / CORE_RATE_DENOM,
57696
58048
  totalSupply,
57697
- exchangeRate: r * ONE_E1810 / CORE_RATE_DENOM
58049
+ exchangeRate: r * ONE_E1811 / CORE_RATE_DENOM
57698
58050
  };
57699
58051
  }
57700
58052
  };
@@ -57716,7 +58068,7 @@ var readerCoreStakedRatio = (entry) => {
57716
58068
  return {
57717
58069
  totalAssets: totalStaked,
57718
58070
  totalSupply,
57719
- exchangeRate: totalStaked * ONE_E1810 / totalSupply
58071
+ exchangeRate: totalStaked * ONE_E1811 / totalSupply
57720
58072
  };
57721
58073
  }
57722
58074
  };
@@ -57751,7 +58103,7 @@ var readerKintsuSMon = (entry) => ({
57751
58103
  const totalAssets = toBigInt14(pooled);
57752
58104
  const totalSupply = toBigInt14(shares);
57753
58105
  if (totalAssets === void 0 || totalSupply === void 0) return void 0;
57754
- const exchangeRate = totalSupply > 0n ? totalAssets * ONE_E1810 / totalSupply : ONE_E1810;
58106
+ const exchangeRate = totalSupply > 0n ? totalAssets * ONE_E1811 / totalSupply : ONE_E1811;
57755
58107
  return { totalAssets, totalSupply, exchangeRate };
57756
58108
  }
57757
58109
  });
@@ -58187,7 +58539,7 @@ var getLstValidators = async (chainId, shareToken) => {
58187
58539
  };
58188
58540
 
58189
58541
  // src/vaults/lst/fetchPublic.ts
58190
- var ONE_E1811 = 10n ** 18n;
58542
+ var ONE_E1812 = 10n ** 18n;
58191
58543
  var ERC20_BALANCE_ABI = parseAbi([
58192
58544
  "function balanceOf(address) view returns (uint256)"
58193
58545
  ]);
@@ -58302,8 +58654,8 @@ var fetchLstShareTokens = async (chainId, multicallRetry, prices = {}, tokenList
58302
58654
  const underlyingUnit = 10n ** BigInt(underlyingDec);
58303
58655
  const totalAssetsFormatted = Number(state.totalAssets) / 10 ** underlyingDec;
58304
58656
  const totalAssetsUsd = priceUsd !== void 0 ? totalAssetsFormatted * priceUsd : 0;
58305
- const convertToAssets = state.exchangeRate * underlyingUnit / ONE_E1811;
58306
- const convertToShares = state.exchangeRate > 0n ? ONE_E1811 * shareUnit / state.exchangeRate : 0n;
58657
+ const convertToAssets = state.exchangeRate * underlyingUnit / ONE_E1812;
58658
+ const convertToShares = state.exchangeRate > 0n ? ONE_E1812 * shareUnit / state.exchangeRate : 0n;
58307
58659
  let liquidityRaw;
58308
58660
  if (state.liquidity !== void 0) {
58309
58661
  liquidityRaw = state.liquidity;
@@ -61755,6 +62107,29 @@ var CooldownDurationAbi = [
61755
62107
  outputs: [{ type: "uint24" }]
61756
62108
  }
61757
62109
  ];
62110
+ var WrenNavReadAbi = [
62111
+ {
62112
+ name: "navprice",
62113
+ type: "function",
62114
+ stateMutability: "view",
62115
+ inputs: [],
62116
+ outputs: [{ type: "uint256" }]
62117
+ },
62118
+ {
62119
+ name: "burncost",
62120
+ type: "function",
62121
+ stateMutability: "view",
62122
+ inputs: [],
62123
+ outputs: [{ type: "uint256" }]
62124
+ },
62125
+ {
62126
+ name: "burnable",
62127
+ type: "function",
62128
+ stateMutability: "view",
62129
+ inputs: [],
62130
+ outputs: [{ type: "uint256" }]
62131
+ }
62132
+ ];
61758
62133
  var NavOracleReadAbi = [
61759
62134
  {
61760
62135
  name: "latestRoundData",
@@ -61772,7 +62147,7 @@ var NavOracleReadAbi = [
61772
62147
  ];
61773
62148
 
61774
62149
  // src/vaults/savings/readers/shared.ts
61775
- var ONE_E1812 = 10n ** 18n;
62150
+ var ONE_E1813 = 10n ** 18n;
61776
62151
  var toBigInt16 = (v) => {
61777
62152
  if (v === void 0 || v === null) return void 0;
61778
62153
  if (typeof v === "bigint") return v;
@@ -61813,7 +62188,7 @@ var readerErc46262 = (entry) => {
61813
62188
  return {
61814
62189
  totalAssets,
61815
62190
  totalSupply,
61816
- exchangeRate: convertToAssetsRaw * ONE_E1812 / underlyingUnit
62191
+ exchangeRate: convertToAssetsRaw * ONE_E1813 / underlyingUnit
61817
62192
  };
61818
62193
  }
61819
62194
  };
@@ -61842,7 +62217,7 @@ var readerErc4626Cooldown = (entry) => {
61842
62217
  return {
61843
62218
  totalAssets,
61844
62219
  totalSupply,
61845
- exchangeRate: convertToAssetsRaw * ONE_E1812 / underlyingUnit,
62220
+ exchangeRate: convertToAssetsRaw * ONE_E1813 / underlyingUnit,
61846
62221
  withdrawalCooldownSeconds: cooldownSecs === void 0 ? void 0 : Number(cooldownSecs)
61847
62222
  };
61848
62223
  }
@@ -62032,7 +62407,7 @@ var readerErc4626Idle = (entry) => {
62032
62407
  return {
62033
62408
  totalAssets,
62034
62409
  totalSupply,
62035
- exchangeRate: convertToAssetsRaw * ONE_E1812 / underlyingUnit,
62410
+ exchangeRate: convertToAssetsRaw * ONE_E1813 / underlyingUnit,
62036
62411
  ...capacity !== void 0 ? {
62037
62412
  instantRedeemCapacity: capacity,
62038
62413
  instantRedeemEnabled: true,
@@ -62081,7 +62456,7 @@ var readerErc4626WithdrawLimit = (entry) => {
62081
62456
  return {
62082
62457
  totalAssets,
62083
62458
  totalSupply,
62084
- exchangeRate: convertToAssetsRaw * ONE_E1812 / underlyingUnit,
62459
+ exchangeRate: convertToAssetsRaw * ONE_E1813 / underlyingUnit,
62085
62460
  ...capacity !== void 0 ? {
62086
62461
  instantRedeemCapacity: capacity,
62087
62462
  instantRedeemEnabled: true,
@@ -62110,7 +62485,7 @@ var readerFrankencoinSavings = (entry) => ({
62110
62485
  // `fetchPublic` derives `convertToAssets` / `convertToShares` from
62111
62486
  // `exchangeRate`, and 1e18 makes them the identity.
62112
62487
  totalSupply: deposits,
62113
- exchangeRate: ONE_E1812
62488
+ exchangeRate: ONE_E1813
62114
62489
  };
62115
62490
  }
62116
62491
  });
@@ -62136,7 +62511,7 @@ var readerNavOracle = (entry) => {
62136
62511
  const exchangeRate = toBigInt16(raw);
62137
62512
  if (exchangeRate === void 0 || exchangeRate <= 0n) return void 0;
62138
62513
  return {
62139
- totalAssets: totalSupply * exchangeRate * underlyingUnit / (ONE_E1812 * shareUnit),
62514
+ totalAssets: totalSupply * exchangeRate * underlyingUnit / (ONE_E1813 * shareUnit),
62140
62515
  totalSupply,
62141
62516
  exchangeRate
62142
62517
  };
@@ -62150,7 +62525,7 @@ var readerNativeWnlp = (entry) => {
62150
62525
  return {
62151
62526
  calls: [
62152
62527
  { address, name: "totalSupply", params: [] },
62153
- { address, name: "getNlpByWnlp", params: [ONE_E1812] },
62528
+ { address, name: "getNlpByWnlp", params: [ONE_E1813] },
62154
62529
  { address, name: "instantRedeemFeeBips", params: [] },
62155
62530
  { address, name: "instantRedeemEnabled", params: [] },
62156
62531
  // Falls back to the vault itself when no CreditVault is pinned —
@@ -62184,7 +62559,7 @@ var readerNativeWnlp = (entry) => {
62184
62559
  const windowSeconds = toBigInt16(window);
62185
62560
  const bips = toBigInt16(feeBips);
62186
62561
  return {
62187
- totalAssets: totalSupply * exchangeRate / ONE_E1812,
62562
+ totalAssets: totalSupply * exchangeRate / ONE_E1813,
62188
62563
  totalSupply,
62189
62564
  exchangeRate,
62190
62565
  // `instantRedeemFeeBips` on-chain is already basis points, so it
@@ -62201,8 +62576,42 @@ var readerNativeWnlp = (entry) => {
62201
62576
  };
62202
62577
  };
62203
62578
 
62579
+ // src/vaults/savings/readers/wrenNav.ts
62580
+ var readerWrenNav = (entry) => {
62581
+ const shareUnit = 10n ** BigInt(entry.decimals);
62582
+ const underlyingUnit = 10n ** BigInt(entry.underlyingDecimals ?? entry.decimals);
62583
+ return {
62584
+ calls: [
62585
+ { address: entry.address, name: "totalSupply", params: [] },
62586
+ { address: entry.address, name: "burncost", params: [] },
62587
+ { address: entry.address, name: "navprice", params: [] },
62588
+ { address: entry.address, name: "burnable", params: [] }
62589
+ ],
62590
+ abis: [TotalSupplyAbi2, WrenNavReadAbi, WrenNavReadAbi, WrenNavReadAbi],
62591
+ parse: ([supply, burn, nav, burnable]) => {
62592
+ const totalSupply = toBigInt16(supply);
62593
+ const navPrice = toBigInt16(nav);
62594
+ if (totalSupply === void 0) return void 0;
62595
+ if (navPrice === void 0 || navPrice <= 0n) return void 0;
62596
+ const burncost = toBigInt16(burn);
62597
+ const hasBurncost = burncost !== void 0 && burncost > 0n;
62598
+ const exchangeRate = hasBurncost ? burncost : navPrice;
62599
+ const totalAssets = totalSupply * exchangeRate * underlyingUnit / (ONE_E1813 * shareUnit);
62600
+ const burnFlag = toBigInt16(burnable);
62601
+ const instantRedeemEnabled = burnFlag === void 0 ? true : burnFlag > 0n;
62602
+ return {
62603
+ totalAssets,
62604
+ totalSupply,
62605
+ exchangeRate,
62606
+ fundamentalExchangeRate: hasBurncost ? navPrice : void 0,
62607
+ instantRedeemEnabled
62608
+ };
62609
+ }
62610
+ };
62611
+ };
62612
+
62204
62613
  // src/vaults/savings/readers/yieldBasisLt.ts
62205
- var ONE_SHARE = ONE_E1812;
62614
+ var ONE_SHARE = ONE_E1813;
62206
62615
  var readerYieldBasisLt = (entry) => {
62207
62616
  const underlyingUnit = 10n ** BigInt(entry.underlyingDecimals ?? entry.decimals);
62208
62617
  const amm = entry.capacityContract ?? entry.address;
@@ -62230,7 +62639,7 @@ var readerYieldBasisLt = (entry) => {
62230
62639
  }
62231
62640
  if (totalSupply === 0n || redeemRaw === 0n) return void 0;
62232
62641
  const totalAssets = totalSupply * redeemRaw / ONE_SHARE;
62233
- const exchangeRate = redeemRaw * ONE_E1812 / underlyingUnit;
62642
+ const exchangeRate = redeemRaw * ONE_E1813 / underlyingUnit;
62234
62643
  const equity = Array.isArray(valueOracle) ? toBigInt16(valueOracle[1]) : toBigInt16(valueOracle?.value);
62235
62644
  const cap = toBigInt16(maxDebt);
62236
62645
  let depositCapacity;
@@ -62260,6 +62669,8 @@ var buildReader2 = (entry) => {
62260
62669
  return readerFrankencoinSavings(entry);
62261
62670
  case "yieldbasis-lt":
62262
62671
  return readerYieldBasisLt(entry);
62672
+ case "wren-nav":
62673
+ return readerWrenNav(entry);
62263
62674
  case "erc4626-cooldown":
62264
62675
  return readerErc4626Cooldown(entry);
62265
62676
  case "erc4626-idle":
@@ -62276,7 +62687,7 @@ var buildReader2 = (entry) => {
62276
62687
  var resolveYieldApr2 = async (entries) => (await resolveEntryApr(entries)).apr;
62277
62688
 
62278
62689
  // src/vaults/savings/fetchPublic.ts
62279
- var ONE_E1813 = 10n ** 18n;
62690
+ var ONE_E1814 = 10n ** 18n;
62280
62691
  var fetchSavingsVaults = async (chainId, multicallRetry, prices = {}, tokenList = {}) => {
62281
62692
  const entries = getSavingsRegistry(chainId);
62282
62693
  if (entries.length === 0) return {};
@@ -62325,8 +62736,8 @@ var fetchSavingsVaults = async (chainId, multicallRetry, prices = {}, tokenList
62325
62736
  1,
62326
62737
  Number(liquidityAmount * 1000000n / state.totalAssets) / 1e6
62327
62738
  ) : 1;
62328
- const convertToAssets = state.exchangeRate * underlyingUnit / ONE_E1813;
62329
- const convertToShares = state.exchangeRate > 0n ? ONE_E1813 * shareUnit / state.exchangeRate : 0n;
62739
+ const convertToAssets = state.exchangeRate * underlyingUnit / ONE_E1814;
62740
+ const convertToShares = state.exchangeRate > 0n ? ONE_E1814 * shareUnit / state.exchangeRate : 0n;
62330
62741
  const depositCapacity = state.depositCapacity?.toString();
62331
62742
  const depositCapacityFormatted = state.depositCapacity !== void 0 ? Number(state.depositCapacity) / 10 ** underlyingDec : void 0;
62332
62743
  const depositCapacityUsd = depositCapacityFormatted !== void 0 && priceUsd !== void 0 ? depositCapacityFormatted * priceUsd : void 0;
@@ -63477,6 +63888,11 @@ var STABLECOIN_SYMBOLS = /* @__PURE__ */ new Set([
63477
63888
  "ZCHF",
63478
63889
  "JPYC",
63479
63890
  "GBPT",
63891
+ // BCP Technologies' Tokenised GBP — cash + short-dated gilts, 1:1
63892
+ // redeemable. Drives `denomination` for Wren's wstGBP row, whose underlying
63893
+ // this is. NB `TGBP` is also TrueGBP's ticker; both are GBP stablecoins, so
63894
+ // the classification is right either way.
63895
+ "TGBP",
63480
63896
  "XSGD",
63481
63897
  "TRYB",
63482
63898
  // Brix iTRY — lira-pegged, backed by a regulated basket of Turkish
@@ -65466,9 +65882,8 @@ function borrowDescription(b) {
65466
65882
  b.rate.minApr != null && b.rate.maxApr != null ? `You choose your own rate between ${pct(b.rate.minApr)} and ${pct(b.rate.maxApr)}; a lower rate is cheaper but makes you redeemed first.` : "You choose your own interest rate; a lower rate is cheaper but makes you redeemed first."
65467
65883
  );
65468
65884
  } else {
65469
- parts.push(
65470
- `You pay ${pct(b.rate.apr)}${b.rate.isLocked ? ", locked for the term" : ", floating with utilization"}.`
65471
- );
65885
+ const how = b.rate.isLocked ? ", locked for the term" : b.rate.kind === "variable-curve" ? ", floating with utilization" : b.rate.kind === "variable-managed" ? ", set by the protocol rather than floating with utilization" : "";
65886
+ parts.push(`You pay ${pct(b.rate.apr)}${how}.`);
65472
65887
  }
65473
65888
  parts.push(
65474
65889
  b.debtShape === "static-face" ? "The amount owed is fixed at trade time and does not accrue." : b.debtShape === "prepaid" ? "The debt principal is static; the cost is the prepaid interest token burning down." : "The amount owed grows continuously as interest accrues."
@@ -65487,11 +65902,27 @@ function borrowDescription(b) {
65487
65902
  `It matures on ${shortDate(b.maturity.maturity)}${what ? `; if nothing is done then, ${what}` : ""}.`
65488
65903
  );
65489
65904
  }
65905
+ const withheld = (b.fees ?? []).filter(
65906
+ (f) => f.when === "entry" && f.basis === "principal" && f.unit === "percent" && f.value > 0
65907
+ );
65908
+ if (withheld.length > 0) {
65909
+ const total = withheld.reduce((a, f) => a + f.value, 0);
65910
+ const named = withheld.map((f) => `${f.label.toLowerCase()} ${pct(f.value)}`).join(" + ");
65911
+ parts.push(
65912
+ `${pct(total)} of anything you borrow is withheld at open` + (withheld.length > 1 ? ` (${named})` : "") + `, so you receive ${pct(100 - total)} of what you owe.`
65913
+ );
65914
+ }
65490
65915
  if (b.liquidation.trigger === "time") {
65491
65916
  parts.push(
65492
65917
  "Liquidation here is triggered by TIME, not price \u2014 being late is the trigger, and being over-collateralised does not protect you."
65493
65918
  );
65494
- } else if (b.liquidation.liquidationLtv != null) {
65919
+ } else if (b.liquidation.model === "auction" && !(b.liquidation.liquidationLtv > 0)) {
65920
+ const pen = b.liquidation.penalty;
65921
+ const win = b.liquidation.windowSecs;
65922
+ parts.push(
65923
+ "Liquidation is a public auction rather than a loan-to-value threshold" + (win ? `, open for ${duration(win)} once started` : "") + (pen != null ? `, and the liquidator is paid ${pct(pen * 100)}` : "") + "."
65924
+ );
65925
+ } else if (b.liquidation.liquidationLtv != null && b.liquidation.liquidationLtv > 0) {
65495
65926
  const pen = b.liquidation.penalty;
65496
65927
  parts.push(
65497
65928
  `Liquidation starts at ${pct(b.liquidation.liquidationLtv * 100)} LTV` + (pen != null ? `, with a ${pct(pen * 100)} penalty` : "") + "."