@defisaver/positions-sdk 2.1.169-custom-fetching-dev → 2.1.169-custom-fetching-3-dev

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 (145) hide show
  1. package/cjs/aaveV2/index.d.ts +4 -4
  2. package/cjs/aaveV2/index.js +7 -7
  3. package/cjs/aaveV3/index.d.ts +4 -3
  4. package/cjs/aaveV3/index.js +14 -10
  5. package/cjs/aaveV3/merkl.d.ts +5 -1
  6. package/cjs/aaveV3/merkl.js +8 -3
  7. package/cjs/aaveV4/index.d.ts +4 -3
  8. package/cjs/aaveV4/index.js +19 -16
  9. package/cjs/aaveV4/merkl.d.ts +10 -2
  10. package/cjs/aaveV4/merkl.js +15 -6
  11. package/cjs/claiming/aaveV3.d.ts +2 -2
  12. package/cjs/claiming/aaveV3.js +5 -4
  13. package/cjs/claiming/king.d.ts +2 -2
  14. package/cjs/claiming/king.js +3 -2
  15. package/cjs/claiming/spark.d.ts +3 -3
  16. package/cjs/claiming/spark.js +8 -7
  17. package/cjs/claiming/uniswap.d.ts +2 -2
  18. package/cjs/claiming/uniswap.js +3 -2
  19. package/cjs/compoundV2/index.d.ts +4 -4
  20. package/cjs/compoundV2/index.js +9 -9
  21. package/cjs/compoundV3/index.d.ts +5 -4
  22. package/cjs/compoundV3/index.js +17 -13
  23. package/cjs/compoundV3/merkl.d.ts +1 -1
  24. package/cjs/compoundV3/merkl.js +2 -5
  25. package/cjs/curveUsd/index.d.ts +5 -5
  26. package/cjs/curveUsd/index.js +17 -17
  27. package/cjs/fluid/index.d.ts +23 -22
  28. package/cjs/fluid/index.js +75 -72
  29. package/cjs/fluid/merkl.d.ts +5 -3
  30. package/cjs/fluid/merkl.js +11 -6
  31. package/cjs/liquity/index.d.ts +4 -4
  32. package/cjs/liquity/index.js +23 -23
  33. package/cjs/liquityV2/index.d.ts +10 -10
  34. package/cjs/liquityV2/index.js +59 -59
  35. package/cjs/llamaLend/index.d.ts +5 -5
  36. package/cjs/llamaLend/index.js +13 -13
  37. package/cjs/maker/index.d.ts +6 -6
  38. package/cjs/maker/index.js +16 -16
  39. package/cjs/morphoBlue/index.d.ts +7 -7
  40. package/cjs/morphoBlue/index.js +28 -26
  41. package/cjs/morphoBlue/merkl.d.ts +5 -3
  42. package/cjs/morphoBlue/merkl.js +6 -8
  43. package/cjs/morphoMidnight/index.d.ts +5 -5
  44. package/cjs/morphoMidnight/index.js +18 -18
  45. package/cjs/portfolio/customDeFiData.js +45 -40
  46. package/cjs/services/merkl.d.ts +36 -2
  47. package/cjs/services/merkl.js +142 -19
  48. package/cjs/services/priceService.d.ts +12 -12
  49. package/cjs/services/priceService.js +30 -29
  50. package/cjs/services/viem.d.ts +10 -2
  51. package/cjs/services/viem.js +27 -1
  52. package/cjs/spark/index.d.ts +4 -4
  53. package/cjs/spark/index.js +9 -9
  54. package/cjs/types/merkl.d.ts +18 -0
  55. package/cjs/types/portfolio.d.ts +2 -0
  56. package/cjs/umbrella/index.d.ts +2 -2
  57. package/cjs/umbrella/index.js +5 -4
  58. package/esm/aaveV2/index.d.ts +4 -4
  59. package/esm/aaveV2/index.js +8 -8
  60. package/esm/aaveV3/index.d.ts +4 -3
  61. package/esm/aaveV3/index.js +15 -11
  62. package/esm/aaveV3/merkl.d.ts +5 -1
  63. package/esm/aaveV3/merkl.js +9 -4
  64. package/esm/aaveV4/index.d.ts +4 -3
  65. package/esm/aaveV4/index.js +20 -17
  66. package/esm/aaveV4/merkl.d.ts +10 -2
  67. package/esm/aaveV4/merkl.js +16 -7
  68. package/esm/claiming/aaveV3.d.ts +2 -2
  69. package/esm/claiming/aaveV3.js +5 -4
  70. package/esm/claiming/king.d.ts +2 -2
  71. package/esm/claiming/king.js +3 -2
  72. package/esm/claiming/spark.d.ts +3 -3
  73. package/esm/claiming/spark.js +8 -7
  74. package/esm/claiming/uniswap.d.ts +2 -2
  75. package/esm/claiming/uniswap.js +3 -2
  76. package/esm/compoundV2/index.d.ts +4 -4
  77. package/esm/compoundV2/index.js +9 -9
  78. package/esm/compoundV3/index.d.ts +5 -4
  79. package/esm/compoundV3/index.js +19 -15
  80. package/esm/compoundV3/merkl.d.ts +1 -1
  81. package/esm/compoundV3/merkl.js +3 -6
  82. package/esm/curveUsd/index.d.ts +5 -5
  83. package/esm/curveUsd/index.js +17 -17
  84. package/esm/fluid/index.d.ts +23 -22
  85. package/esm/fluid/index.js +76 -73
  86. package/esm/fluid/merkl.d.ts +5 -3
  87. package/esm/fluid/merkl.js +12 -7
  88. package/esm/liquity/index.d.ts +4 -4
  89. package/esm/liquity/index.js +23 -23
  90. package/esm/liquityV2/index.d.ts +10 -10
  91. package/esm/liquityV2/index.js +60 -60
  92. package/esm/llamaLend/index.d.ts +5 -5
  93. package/esm/llamaLend/index.js +13 -13
  94. package/esm/maker/index.d.ts +6 -6
  95. package/esm/maker/index.js +16 -16
  96. package/esm/morphoBlue/index.d.ts +7 -7
  97. package/esm/morphoBlue/index.js +29 -27
  98. package/esm/morphoBlue/merkl.d.ts +5 -3
  99. package/esm/morphoBlue/merkl.js +7 -9
  100. package/esm/morphoMidnight/index.d.ts +5 -5
  101. package/esm/morphoMidnight/index.js +18 -18
  102. package/esm/portfolio/customDeFiData.js +47 -42
  103. package/esm/services/merkl.d.ts +36 -2
  104. package/esm/services/merkl.js +136 -18
  105. package/esm/services/priceService.d.ts +12 -12
  106. package/esm/services/priceService.js +31 -30
  107. package/esm/services/viem.d.ts +10 -2
  108. package/esm/services/viem.js +25 -0
  109. package/esm/spark/index.d.ts +4 -4
  110. package/esm/spark/index.js +10 -10
  111. package/esm/types/merkl.d.ts +18 -0
  112. package/esm/types/portfolio.d.ts +2 -0
  113. package/esm/umbrella/index.d.ts +2 -2
  114. package/esm/umbrella/index.js +5 -4
  115. package/package.json +1 -1
  116. package/src/aaveV2/index.ts +7 -7
  117. package/src/aaveV3/index.ts +15 -11
  118. package/src/aaveV3/merkl.ts +9 -4
  119. package/src/aaveV4/index.ts +19 -16
  120. package/src/aaveV4/merkl.ts +16 -7
  121. package/src/claiming/aaveV3.ts +5 -3
  122. package/src/claiming/king.ts +6 -3
  123. package/src/claiming/spark.ts +9 -6
  124. package/src/claiming/uniswap.ts +4 -3
  125. package/src/compoundV2/index.ts +10 -9
  126. package/src/compoundV3/index.ts +20 -14
  127. package/src/compoundV3/merkl.ts +5 -4
  128. package/src/curveUsd/index.ts +19 -17
  129. package/src/fluid/index.ts +88 -70
  130. package/src/fluid/merkl.ts +12 -7
  131. package/src/liquity/index.ts +23 -23
  132. package/src/liquityV2/index.ts +64 -56
  133. package/src/llamaLend/index.ts +15 -13
  134. package/src/maker/index.ts +19 -16
  135. package/src/morphoBlue/index.ts +23 -20
  136. package/src/morphoBlue/merkl.ts +9 -6
  137. package/src/morphoMidnight/index.ts +13 -13
  138. package/src/portfolio/customDeFiData.ts +48 -41
  139. package/src/services/merkl.ts +152 -19
  140. package/src/services/priceService.ts +33 -30
  141. package/src/services/viem.ts +16 -0
  142. package/src/spark/index.ts +11 -8
  143. package/src/types/merkl.ts +20 -0
  144. package/src/types/portfolio.ts +2 -0
  145. package/src/umbrella/index.ts +6 -5
@@ -17,7 +17,7 @@ import {
17
17
  getBorrowRate, getMorphoBlueAggregatedPositionData, getRewardsForMarket, getSupplyRate,
18
18
  } from '../helpers/morphoBlueHelpers';
19
19
  import { getChainlinkAssetAddress } from '../services/priceService';
20
- import { getViemProvider, setViemBlockNumber } from '../services/viem';
20
+ import { getBlockTimestamp, getViemProvider, setViemBlockNumber } from '../services/viem';
21
21
 
22
22
  import { addMorphoBlueMerklOpportunitiesToMarketInfo, getMorphoBlueMerklOpportunities } from './merkl';
23
23
 
@@ -62,6 +62,7 @@ async function getMorphoBlueMarketDataInternal(
62
62
  provider: Client,
63
63
  network: NetworkNumber,
64
64
  selectedMarket: MorphoBlueMarketData,
65
+ blockNumber: Blockish = 'latest',
65
66
  ): Promise<MorphoBlueMarketInfo> {
66
67
  const {
67
68
  loanToken, collateralToken, oracle, irm, lltv, oracleType,
@@ -82,8 +83,8 @@ async function getMorphoBlueMarketDataInternal(
82
83
  if (isMainnet) {
83
84
  const feedRegistryContract = FeedRegistryContractViem(provider, NetworkNumber.Eth);
84
85
  const [_loanTokenPrice, _marketInfo] = await Promise.all([
85
- isHardcodedUsdStable ? Promise.resolve(HARDCODED_USD_STABLE_PRICE) : feedRegistryContract.read.latestAnswer([loanTokenFeedAddress, USD_QUOTE]),
86
- morphoBlueViewContract.read.getMarketInfoNotTuple([loanToken, collateralToken, oracle, irm, BigInt(lltvInWei)]),
86
+ isHardcodedUsdStable ? Promise.resolve(HARDCODED_USD_STABLE_PRICE) : feedRegistryContract.read.latestAnswer([loanTokenFeedAddress, USD_QUOTE], setViemBlockNumber(blockNumber)),
87
+ morphoBlueViewContract.read.getMarketInfoNotTuple([loanToken, collateralToken, oracle, irm, BigInt(lltvInWei)], setViemBlockNumber(blockNumber)),
87
88
  ]);
88
89
  marketInfo = _marketInfo;
89
90
  loanTokenPrice = _loanTokenPrice;
@@ -93,8 +94,8 @@ async function getMorphoBlueMarketDataInternal(
93
94
 
94
95
  const [loanTokenPriceRound, _marketInfo] = await Promise.all([
95
96
  isHardcodedUsdStable ? Promise.resolve([0, HARDCODED_USD_STABLE_PRICE]) // Normalize to match the expected object structure
96
- : feedRegistryContract.read.latestRoundData([loanTokenFeedAddress, USD_QUOTE]),
97
- morphoBlueViewContract.read.getMarketInfoNotTuple([loanToken, collateralToken, oracle, irm, BigInt(lltvInWei)]),
97
+ : feedRegistryContract.read.latestRoundData([loanTokenFeedAddress, USD_QUOTE], setViemBlockNumber(blockNumber)),
98
+ morphoBlueViewContract.read.getMarketInfoNotTuple([loanToken, collateralToken, oracle, irm, BigInt(lltvInWei)], setViemBlockNumber(blockNumber)),
98
99
  ]);
99
100
  marketInfo = _marketInfo;
100
101
  loanTokenPrice = loanTokenPriceRound[1].toString();
@@ -159,14 +160,16 @@ async function getMorphoBlueMarketDataInternal(
159
160
  };
160
161
  }
161
162
 
162
- export async function _getMorphoBlueMarketData(provider: Client, network: NetworkNumber, selectedMarket: MorphoBlueMarketData): Promise<MorphoBlueMarketInfo> {
163
+ export async function _getMorphoBlueMarketData(provider: Client, network: NetworkNumber, selectedMarket: MorphoBlueMarketData, blockNumber: Blockish = 'latest'): Promise<MorphoBlueMarketInfo> {
163
164
  const [marketInfo, rewards, merklOpportunities] = await Promise.all([
164
- getMorphoBlueMarketDataInternal(provider, network, selectedMarket),
165
+ getMorphoBlueMarketDataInternal(provider, network, selectedMarket, blockNumber),
165
166
  getRewardsForMarket(selectedMarket.marketId, network).catch((error) => {
166
167
  console.error(error);
167
168
  return { supplyApy: '0', borrowApy: '0' };
168
169
  }),
169
- getMorphoBlueMerklOpportunities(),
170
+ // Merkl rewards are keyed by time: a historical block resolves to its timestamp first (one RPC
171
+ // call, none for 'latest') so the rewards in force at that moment are attached.
172
+ getBlockTimestamp(provider, blockNumber).then((asOfTimestamp) => getMorphoBlueMerklOpportunities(asOfTimestamp, network)),
170
173
  ]);
171
174
 
172
175
  return addMorphoBlueMerklOpportunitiesToMarketInfo(
@@ -177,16 +180,16 @@ export async function _getMorphoBlueMarketData(provider: Client, network: Networ
177
180
  );
178
181
  }
179
182
 
180
- export function _getMorphoBluePortfolioMarketData(provider: Client, network: NetworkNumber, selectedMarket: MorphoBlueMarketData): Promise<MorphoBlueMarketInfo> {
181
- return getMorphoBlueMarketDataInternal(provider, network, selectedMarket);
183
+ export function _getMorphoBluePortfolioMarketData(provider: Client, network: NetworkNumber, selectedMarket: MorphoBlueMarketData, blockNumber: Blockish = 'latest'): Promise<MorphoBlueMarketInfo> {
184
+ return getMorphoBlueMarketDataInternal(provider, network, selectedMarket, blockNumber);
182
185
  }
183
186
 
184
- export async function getMorphoBlueMarketData(provider: EthereumProvider, network: NetworkNumber, selectedMarket: MorphoBlueMarketData): Promise<MorphoBlueMarketInfo> {
185
- return _getMorphoBlueMarketData(getViemProvider(provider, network), network, selectedMarket);
187
+ export async function getMorphoBlueMarketData(provider: EthereumProvider, network: NetworkNumber, selectedMarket: MorphoBlueMarketData, blockNumber: Blockish = 'latest'): Promise<MorphoBlueMarketInfo> {
188
+ return _getMorphoBlueMarketData(getViemProvider(provider, network), network, selectedMarket, blockNumber);
186
189
  }
187
190
 
188
- export function getMorphoBluePortfolioMarketData(provider: EthereumProvider, network: NetworkNumber, selectedMarket: MorphoBlueMarketData): Promise<MorphoBlueMarketInfo> {
189
- return _getMorphoBluePortfolioMarketData(getViemProvider(provider, network), network, selectedMarket);
191
+ export function getMorphoBluePortfolioMarketData(provider: EthereumProvider, network: NetworkNumber, selectedMarket: MorphoBlueMarketData, blockNumber: Blockish = 'latest'): Promise<MorphoBlueMarketInfo> {
192
+ return _getMorphoBluePortfolioMarketData(getViemProvider(provider, network), network, selectedMarket, blockNumber);
190
193
  }
191
194
 
192
195
  export const getMorphoBluePositionDataWithMarketInfo = (
@@ -273,7 +276,7 @@ export const getMorphoBlueAccountBalances = async (
273
276
  selectedMarket: MorphoBlueMarketData,
274
277
  ): Promise<PositionBalances> => _getMorphoBlueAccountBalances(getViemProvider(provider, network), network, block, addressMapping, address, selectedMarket);
275
278
 
276
- export async function _getMorphoBlueAccountData(provider: Client, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoBlueMarketData, marketInfo: MorphoBlueMarketInfo): Promise<MorphoBluePositionData> {
279
+ export async function _getMorphoBlueAccountData(provider: Client, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoBlueMarketData, marketInfo: MorphoBlueMarketInfo, blockNumber: Blockish = 'latest'): Promise<MorphoBluePositionData> {
277
280
  const {
278
281
  loanToken, collateralToken, oracle, irm, lltv,
279
282
  } = selectedMarket;
@@ -283,7 +286,7 @@ export async function _getMorphoBlueAccountData(provider: Client, network: Netwo
283
286
  {
284
287
  loanToken, collateralToken, oracle, irm, lltv: BigInt(lltvInWei),
285
288
  },
286
- account]));
289
+ account], setViemBlockNumber(blockNumber)));
287
290
  const usedAssets: MMUsedAssets = {};
288
291
 
289
292
  const loanTokenInfo = marketInfo.assetsData[marketInfo.loanToken];
@@ -321,11 +324,11 @@ export async function _getMorphoBlueAccountData(provider: Client, network: Netwo
321
324
  };
322
325
  }
323
326
 
324
- export async function getMorphoBlueAccountData(provider: EthereumProvider, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoBlueMarketData, marketInfo: MorphoBlueMarketInfo): Promise<MorphoBluePositionData> {
325
- return _getMorphoBlueAccountData(getViemProvider(provider, network), network, account, selectedMarket, marketInfo);
327
+ export async function getMorphoBlueAccountData(provider: EthereumProvider, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoBlueMarketData, marketInfo: MorphoBlueMarketInfo, blockNumber: Blockish = 'latest'): Promise<MorphoBluePositionData> {
328
+ return _getMorphoBlueAccountData(getViemProvider(provider, network), network, account, selectedMarket, marketInfo, blockNumber);
326
329
  }
327
330
 
328
- export async function getMorphoEarn(provider: Client, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoBlueMarketData, marketInfo: MorphoBlueMarketInfo): Promise<MorphoBlueEarnData> {
331
+ export async function getMorphoEarn(provider: Client, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoBlueMarketData, marketInfo: MorphoBlueMarketInfo, blockNumber: Blockish = 'latest'): Promise<MorphoBlueEarnData> {
329
332
  const {
330
333
  loanToken, collateralToken, oracle, irm, lltv,
331
334
  } = selectedMarket;
@@ -336,7 +339,7 @@ export async function getMorphoEarn(provider: Client, network: NetworkNumber, ac
336
339
  {
337
340
  loanToken, collateralToken, oracle, irm, lltv: BigInt(lltvInWei),
338
341
  },
339
- account]));
342
+ account], setViemBlockNumber(blockNumber)));
340
343
 
341
344
  const loanTokenInfo = marketInfo.assetsData[marketInfo.loanToken];
342
345
  const loanTokenSupplied = assetAmountInEth(loanInfo.suppliedInAssets.toString(), marketInfo.loanToken);
@@ -1,5 +1,5 @@
1
1
  import { aprToApy } from '../moneymarket';
2
- import { fetchAllMerklOpportunities } from '../services/merkl';
2
+ import { fetchMerklOpportunities } from '../services/merkl';
3
3
  import {
4
4
  IncentiveData,
5
5
  IncentiveKind,
@@ -94,16 +94,19 @@ export const addMorphoBlueMerklOpportunitiesToMarketInfo = (
94
94
  };
95
95
 
96
96
  /**
97
- * Fetches live market-scoped Morpho Blue campaigns for all chains. Never throws — on any failure
98
- * it returns an empty list, so Merkl being down can't break market data.
97
+ * Fetches live market-scoped Morpho Blue campaigns for all chains (or one, when `chainId` is given).
98
+ * With `asOfTimestamp` (unix seconds) the campaigns and APRs are the ones Merkl had at that moment
99
+ * instead. Never throws — on any failure it returns an empty list, so Merkl being down can't break
100
+ * market data.
99
101
  */
100
- export const getMorphoBlueMerklOpportunities = async (): Promise<MerklOpportunity[]> => {
102
+ export const getMorphoBlueMerklOpportunities = async (asOfTimestamp?: number, chainId?: NetworkNumber): Promise<MerklOpportunity[]> => {
101
103
  try {
102
- return await fetchAllMerklOpportunities({
104
+ return await fetchMerklOpportunities({
103
105
  mainProtocolId: 'morpho',
104
106
  type: Object.values(MorphoBlueMerklOpportunityType).join(','),
105
107
  status: OpportunityStatus.LIVE,
106
- });
108
+ ...(chainId ? { chainId: chainId.toString() } : {}),
109
+ }, asOfTimestamp);
107
110
  } catch (e) {
108
111
  console.error('Failed to fetch Morpho Blue Merkl campaigns', e);
109
112
  return [];
@@ -20,7 +20,7 @@ import { getViemProvider, setViemBlockNumber } from '../services/viem';
20
20
  const HARDCODED_USD_STABLE_PRICE = '100000000'; // $1 with 8 decimals
21
21
  const nowInSeconds = () => Math.floor(Date.now() / 1000);
22
22
 
23
- export async function _getMorphoMidnightMarketData(provider: Client, network: NetworkNumber, selectedMarket: MorphoMidnightMarketData): Promise<MorphoMidnightMarketInfo> {
23
+ export async function _getMorphoMidnightMarketData(provider: Client, network: NetworkNumber, selectedMarket: MorphoMidnightMarketData, blockNumber: Blockish = 'latest'): Promise<MorphoMidnightMarketInfo> {
24
24
  const { loanToken, collaterals, marketId } = selectedMarket;
25
25
  const loanTokenInfo = getAssetInfoByAddress(loanToken, network);
26
26
  const loanSym = wethToEth(loanTokenInfo.symbol);
@@ -34,8 +34,8 @@ export async function _getMorphoMidnightMarketData(provider: Client, network: Ne
34
34
  if (isMainnetNetwork(network)) {
35
35
  const feedRegistryContract = FeedRegistryContractViem(provider, NetworkNumber.Eth);
36
36
  const [_loanTokenPrice, _marketInfo] = await Promise.all([
37
- isHardcodedUsdStable ? Promise.resolve(HARDCODED_USD_STABLE_PRICE) : feedRegistryContract.read.latestAnswer([loanTokenFeedAddress, USD_QUOTE]),
38
- viewContract.read.getMarketInfo([marketId as `0x${string}`]),
37
+ isHardcodedUsdStable ? Promise.resolve(HARDCODED_USD_STABLE_PRICE) : feedRegistryContract.read.latestAnswer([loanTokenFeedAddress, USD_QUOTE], setViemBlockNumber(blockNumber)),
38
+ viewContract.read.getMarketInfo([marketId as `0x${string}`], setViemBlockNumber(blockNumber)),
39
39
  ]);
40
40
  marketInfo = _marketInfo;
41
41
  loanTokenPrice = _loanTokenPrice;
@@ -43,8 +43,8 @@ export async function _getMorphoMidnightMarketData(provider: Client, network: Ne
43
43
  // Currently only Base is supported
44
44
  const feedRegistryContract = DFSFeedRegistryContractViem(provider, network);
45
45
  const [loanTokenPriceRound, _marketInfo] = await Promise.all([
46
- isHardcodedUsdStable ? Promise.resolve([0, HARDCODED_USD_STABLE_PRICE]) : feedRegistryContract.read.latestRoundData([loanTokenFeedAddress, USD_QUOTE]),
47
- viewContract.read.getMarketInfo([marketId as `0x${string}`]),
46
+ isHardcodedUsdStable ? Promise.resolve([0, HARDCODED_USD_STABLE_PRICE]) : feedRegistryContract.read.latestRoundData([loanTokenFeedAddress, USD_QUOTE], setViemBlockNumber(blockNumber)),
47
+ viewContract.read.getMarketInfo([marketId as `0x${string}`], setViemBlockNumber(blockNumber)),
48
48
  ]);
49
49
  marketInfo = _marketInfo;
50
50
  loanTokenPrice = loanTokenPriceRound[1].toString();
@@ -119,14 +119,14 @@ export async function _getMorphoMidnightMarketData(provider: Client, network: Ne
119
119
  };
120
120
  }
121
121
 
122
- export async function getMorphoMidnightMarketData(provider: EthereumProvider, network: NetworkNumber, selectedMarket: MorphoMidnightMarketData): Promise<MorphoMidnightMarketInfo> {
123
- return _getMorphoMidnightMarketData(getViemProvider(provider, network), network, selectedMarket);
122
+ export async function getMorphoMidnightMarketData(provider: EthereumProvider, network: NetworkNumber, selectedMarket: MorphoMidnightMarketData, blockNumber: Blockish = 'latest'): Promise<MorphoMidnightMarketInfo> {
123
+ return _getMorphoMidnightMarketData(getViemProvider(provider, network), network, selectedMarket, blockNumber);
124
124
  }
125
125
 
126
- export async function _getMorphoMidnightAccountData(provider: Client, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoMidnightMarketData, marketInfo: MorphoMidnightMarketInfo): Promise<MorphoMidnightPositionData> {
126
+ export async function _getMorphoMidnightAccountData(provider: Client, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoMidnightMarketData, marketInfo: MorphoMidnightMarketInfo, blockNumber: Blockish = 'latest'): Promise<MorphoMidnightPositionData> {
127
127
  const { marketId, collaterals } = selectedMarket;
128
128
  const viewContract = MorphoMidnightViewContractViem(provider, network);
129
- const positionInfo = await viewContract.read.getPositionInfo([marketId as `0x${string}`, account]);
129
+ const positionInfo = await viewContract.read.getPositionInfo([marketId as `0x${string}`, account], setViemBlockNumber(blockNumber));
130
130
 
131
131
  const usedAssets: MMUsedAssets = {};
132
132
 
@@ -218,8 +218,8 @@ export async function _getMorphoMidnightAccountData(provider: Client, network: N
218
218
  };
219
219
  }
220
220
 
221
- export async function getMorphoMidnightAccountData(provider: EthereumProvider, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoMidnightMarketData, marketInfo: MorphoMidnightMarketInfo): Promise<MorphoMidnightPositionData> {
222
- return _getMorphoMidnightAccountData(getViemProvider(provider, network), network, account, selectedMarket, marketInfo);
221
+ export async function getMorphoMidnightAccountData(provider: EthereumProvider, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoMidnightMarketData, marketInfo: MorphoMidnightMarketInfo, blockNumber: Blockish = 'latest'): Promise<MorphoMidnightPositionData> {
222
+ return _getMorphoMidnightAccountData(getViemProvider(provider, network), network, account, selectedMarket, marketInfo, blockNumber);
223
223
  }
224
224
 
225
225
  export const _getMorphoMidnightAccountBalances = async (provider: Client, network: NetworkNumber, block: Blockish, addressMapping: boolean, address: EthAddress, selectedMarket: MorphoMidnightMarketData, includeCredit = false): Promise<PositionBalances> => {
@@ -263,10 +263,10 @@ export const getMorphoMidnightAccountBalances = async (
263
263
 
264
264
  // Lender-side (credit-only) supply position, mirroring getMorphoEarn. `amount` is the credit face value
265
265
  // redeemable at maturity; `apy` is '0' in MVP because the fixed yield is orderbook-derived, not on-chain.
266
- export async function getMorphoMidnightEarn(provider: Client, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoMidnightMarketData, marketInfo: MorphoMidnightMarketInfo): Promise<{ apy: string, amount: string, amountUsd: string }> {
266
+ export async function getMorphoMidnightEarn(provider: Client, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoMidnightMarketData, marketInfo: MorphoMidnightMarketInfo, blockNumber: Blockish = 'latest'): Promise<{ apy: string, amount: string, amountUsd: string }> {
267
267
  const { marketId } = selectedMarket;
268
268
  const viewContract = MorphoMidnightViewContractViem(provider, network);
269
- const positionInfo = await viewContract.read.getPositionInfo([marketId as `0x${string}`, account]);
269
+ const positionInfo = await viewContract.read.getPositionInfo([marketId as `0x${string}`, account], setViemBlockNumber(blockNumber));
270
270
 
271
271
  const loanTokenData = marketInfo.assetsData[marketInfo.loanToken];
272
272
  const credit = assetAmountInEth(positionInfo.credit.toString(), marketInfo.loanToken);
@@ -1,5 +1,7 @@
1
1
  import Dec from 'decimal.js';
2
- import { EthAddress, EthereumProvider, NetworkNumber } from '../types/common';
2
+ import {
3
+ Blockish, EthAddress, EthereumProvider, NetworkNumber,
4
+ } from '../types/common';
3
5
  import {
4
6
  AaveMarkets,
5
7
  AaveV4Spokes,
@@ -22,7 +24,7 @@ import {
22
24
  PortfolioPositionsData,
23
25
  PortfolioProtocol,
24
26
  } from '../types';
25
- import { getViemProvider } from '../services/viem';
27
+ import { getBlockTimestamp, getViemProvider } from '../services/viem';
26
28
  import { ZERO_ADDRESS } from '../constants';
27
29
  import { _getAaveV2AccountData, _getAaveV2MarketsData } from '../aaveV2';
28
30
  import { _getAaveV3AccountData, _getAaveV3MarketData, getStakeAaveData } from '../aaveV3';
@@ -76,6 +78,11 @@ export async function getCustomDeFiData(
76
78
 
77
79
  const client = getViemProvider(provider, network, { batch: { multicall: { batchSize } } });
78
80
  const defaultClient = getViemProvider(defaultProvider, network, { batch: { multicall: { batchSize } } });
81
+ // Every fetch below takes the block explicitly and passes it to each of its contract reads.
82
+ // Time-keyed sources (Merkl rewards) need the block's timestamp instead, resolved once here (no
83
+ // RPC call for 'latest') and handed to the market fetches so they don't each look it up.
84
+ const blockNumber: Blockish = options.blockNumber ?? 'latest';
85
+ const blockTimestamp = await getBlockTimestamp(client, blockNumber);
79
86
 
80
87
  const aaveV3Markets = has(PortfolioProtocol.AaveV3)
81
88
  ? [AaveVersions.AaveV3, AaveVersions.AaveV3Lido, AaveVersions.AaveV3Etherfi].map((v) => AaveMarkets(network)[v]).filter((m) => m.chainIds.includes(network))
@@ -169,33 +176,33 @@ export async function getCustomDeFiData(
169
176
  })();
170
177
 
171
178
  await Promise.allSettled([
172
- ...morphoMarkets.map(async (m) => { markets.morphoMarketsData[m.value] = await _getMorphoBluePortfolioMarketData(client, network, m); }),
173
- ...morphoMidnightMarkets.map(async (m) => { markets.morphoMidnightMarketsData[m.value] = await _getMorphoMidnightMarketData(client, network, m); }),
174
- ...compoundV3Markets.map(async (m) => { markets.compoundV3MarketsData[m.value] = await _getCompoundV3MarketsData(client, network, m, defaultClient); }),
175
- ...sparkMarkets.map(async (m) => { markets.sparkMarketsData[m.value] = await _getSparkMarketsData(client, network, m); }),
176
- ...aaveV3Markets.map(async (m) => { markets.aaveV3MarketsData[m.value] = await _getAaveV3MarketData(client, network, m); }),
177
- ...aaveV4Spokes.map(async (s) => { markets.aaveV4SpokesData[s.value] = await _getAaveV4SpokeData(client, network, s); }),
178
- ...aaveV2Markets.map(async (m) => { markets.aaveV2MarketsData[m.value] = await _getAaveV2MarketsData(client, network, m); }),
179
- ...compoundV2Markets.map(async (m) => { markets.compoundV2MarketsData[m.value] = await _getCompoundV2MarketsData(client, network); }),
180
- ...crvUsdMarkets.map(async (m) => { markets.crvUsdMarketsData[m.value] = await _getCurveUsdGlobalData(client, network, m); }),
181
- ...llamaLendMarkets.map(async (m) => { markets.llamaLendMarketsData[m.value] = await _getLlamaLendGlobalData(client, network, m); }),
182
- ...liquityV2Markets.map(async (m) => { markets.liquityV2MarketsData[m.value] = await _getLiquityV2MarketData(client, network, m); }),
179
+ ...morphoMarkets.map(async (m) => { markets.morphoMarketsData[m.value] = await _getMorphoBluePortfolioMarketData(client, network, m, blockNumber); }),
180
+ ...morphoMidnightMarkets.map(async (m) => { markets.morphoMidnightMarketsData[m.value] = await _getMorphoMidnightMarketData(client, network, m, blockNumber); }),
181
+ ...compoundV3Markets.map(async (m) => { markets.compoundV3MarketsData[m.value] = await _getCompoundV3MarketsData(client, network, m, defaultClient, blockNumber, blockTimestamp); }),
182
+ ...sparkMarkets.map(async (m) => { markets.sparkMarketsData[m.value] = await _getSparkMarketsData(client, network, m, blockNumber); }),
183
+ ...aaveV3Markets.map(async (m) => { markets.aaveV3MarketsData[m.value] = await _getAaveV3MarketData(client, network, m, blockNumber, blockTimestamp); }),
184
+ ...aaveV4Spokes.map(async (s) => { markets.aaveV4SpokesData[s.value] = await _getAaveV4SpokeData(client, network, s, blockNumber, blockTimestamp); }),
185
+ ...aaveV2Markets.map(async (m) => { markets.aaveV2MarketsData[m.value] = await _getAaveV2MarketsData(client, network, m, blockNumber); }),
186
+ ...compoundV2Markets.map(async (m) => { markets.compoundV2MarketsData[m.value] = await _getCompoundV2MarketsData(client, network, blockNumber); }),
187
+ ...crvUsdMarkets.map(async (m) => { markets.crvUsdMarketsData[m.value] = await _getCurveUsdGlobalData(client, network, m, blockNumber); }),
188
+ ...llamaLendMarkets.map(async (m) => { markets.llamaLendMarketsData[m.value] = await _getLlamaLendGlobalData(client, network, m, blockNumber); }),
189
+ ...liquityV2Markets.map(async (m) => { markets.liquityV2MarketsData[m.value] = await _getLiquityV2MarketData(client, network, m, blockNumber); }),
183
190
  (async () => {
184
191
  if (!fetchFluid || !fetchFluidMarkets) return;
185
- try { markets.fluidMarketsData = await _getAllFluidMarketDataPortfolio(client, network); } catch (error) { console.error('Error fetching Fluid markets data:', error); }
192
+ try { markets.fluidMarketsData = await _getAllFluidMarketDataPortfolio(client, network, blockNumber, blockTimestamp); } catch (error) { console.error('Error fetching Fluid markets data:', error); }
186
193
  })(),
187
194
  (async () => {
188
195
  if (!fetchMaker) return;
189
- try { markets.makerMarketsData = await _getMakerIlksData(client, network, MakerActiveIlks); } catch (error) { console.error('Error fetching Maker ilks data:', error); }
196
+ try { markets.makerMarketsData = await _getMakerIlksData(client, network, MakerActiveIlks, blockNumber); } catch (error) { console.error('Error fetching Maker ilks data:', error); }
190
197
  })(),
191
198
 
192
199
  ...addresses.map(async (address) => {
193
200
  if (!fetchMaker) return;
194
- makerCdps[lower(address)] = await _getUserCdps(client, network, address);
201
+ makerCdps[lower(address)] = await _getUserCdps(client, network, address, blockNumber);
195
202
  }),
196
203
  ...addresses.map((address) => fetchFluid && run(
197
204
  `Fluid positions for address ${address}`,
198
- () => _getUserPositionsPortfolio(client, network, address),
205
+ () => _getUserPositionsPortfolio(client, network, address, blockNumber),
199
206
  (userPositions) => {
200
207
  for (const position of userPositions) {
201
208
  if (position.userData && positive(position.userData.suppliedUsd)) positions[lower(address)].fluid.data[position.userData.nftId] = position.userData;
@@ -207,40 +214,40 @@ export async function getCustomDeFiData(
207
214
  ...(fetchStaking ? [
208
215
  ...addresses.map((address) => fetchFluid && run(
209
216
  `Fluid lend data for address ${address}`,
210
- () => _getAllUserEarnPositionsWithFTokens(client, network, address),
217
+ () => _getAllUserEarnPositionsWithFTokens(client, network, address, blockNumber),
211
218
  (data) => { stakingPositions[lower(address)].fluid = data; },
212
219
  (err) => { stakingPositions[lower(address)].fluid = err; },
213
220
  )),
214
221
  ...addresses.map((address) => fetchLiquity && run(
215
222
  `Liquity staking data for address ${address}`,
216
- () => getLiquityStakingData(client, network, address),
223
+ () => getLiquityStakingData(client, network, address, blockNumber),
217
224
  (data) => { stakingPositions[lower(address)].liquity = data; },
218
225
  (err) => { stakingPositions[lower(address)].liquity = err; },
219
226
  )),
220
227
  ...addresses.map((address) => has(PortfolioProtocol.AaveV3) && isMainnet && run(
221
228
  `Aave V3 staking data for address ${address}`,
222
- () => getStakeAaveData(client, network, address),
229
+ () => getStakeAaveData(client, network, address, blockNumber),
223
230
  (data) => { stakingPositions[lower(address)].aaveV3 = data; },
224
231
  (err) => { stakingPositions[lower(address)].aaveV3 = err; },
225
232
  )),
226
233
  ...addresses.map((address) => has(PortfolioProtocol.AaveV3) && isMainnet && run(
227
234
  `Umbrella staking data for address ${address}`,
228
- () => getUmbrellaData(client, network, address),
235
+ () => getUmbrellaData(client, network, address, blockNumber),
229
236
  (data) => { stakingPositions[lower(address)].umbrella = data; },
230
237
  (err) => { stakingPositions[lower(address)].umbrella = err; },
231
238
  )),
232
239
  ...perAddress(liquityV2StakingMarkets, (market, address) => run(
233
240
  `Liquity V2 staking data for address ${address}, market ${market.value}`,
234
- () => getLiquityV2Staking(client, network, market.value, address),
241
+ () => getLiquityV2Staking(client, network, market.value, address, blockNumber),
235
242
  (data) => { stakingPositions[lower(address)].liquityV2[market.value] = { error: '', data }; },
236
243
  (err) => { stakingPositions[lower(address)].liquityV2[market.value] = err; },
237
244
  )),
238
245
  ] : []),
239
246
 
240
247
  ...(fetchRewards ? [
241
- batchRewards('king', 'King rewards data', () => getKingRewards(client, network, addresses), isMainnet),
242
- batchRewards('uniswap', 'Uniswap rewards data', () => getUniswapRewards(client, network, addresses), isMainnet),
243
- batchRewards('spk', 'Spark Airdrop rewards data', () => fetchSparkAirdropRewards(client, network, addresses), isMainnet && has(PortfolioProtocol.Spark)),
248
+ batchRewards('king', 'King rewards data', () => getKingRewards(client, network, addresses, blockNumber), isMainnet),
249
+ batchRewards('uniswap', 'Uniswap rewards data', () => getUniswapRewards(client, network, addresses, blockNumber), isMainnet),
250
+ batchRewards('spk', 'Spark Airdrop rewards data', () => fetchSparkAirdropRewards(client, network, addresses, blockNumber), isMainnet && has(PortfolioProtocol.Spark)),
244
251
  batchRewards('ethena', 'Ethena Airdrop rewards data', () => fetchEthenaAirdropRewards(addresses), isMainnet),
245
252
  ...addresses.map((address) => run(
246
253
  `Merkl rewards data for address ${address}`,
@@ -250,7 +257,7 @@ export async function getCustomDeFiData(
250
257
  )),
251
258
  ...perAddress(aaveV3Markets, (market, address) => run(
252
259
  `Aave V3 rewards data for address ${address}, market ${market.value}`,
253
- () => getUnclaimedRewardsForAllMarkets(client, network, address, market.providerAddress),
260
+ () => getUnclaimedRewardsForAllMarkets(client, network, address, market.providerAddress, blockNumber),
254
261
  (data) => { rewardsData[lower(address)].aaveV3[market.value] = { error: '', data }; },
255
262
  (err) => { rewardsData[lower(address)].aaveV3[market.value] = err; },
256
263
  )),
@@ -261,7 +268,7 @@ export async function getCustomDeFiData(
261
268
  }
262
269
  return run(
263
270
  `Spark rewards data for address ${address}, market ${market.value}`,
264
- () => fetchSparkRewards(client, network, address, market.providerAddress),
271
+ () => fetchSparkRewards(client, network, address, market.providerAddress, blockNumber),
265
272
  (data) => { rewardsData[lower(address)].spark[market.value] = { error: '', data }; },
266
273
  (err) => { rewardsData[lower(address)].spark[market.value] = err; },
267
274
  );
@@ -272,31 +279,31 @@ export async function getCustomDeFiData(
272
279
  await Promise.all([
273
280
  ...perAddress(aaveV3Markets, (market, address) => run(
274
281
  `AaveV3 account data for address ${address} on market ${market.value}`,
275
- () => _getAaveV3AccountData(client, network, address, { selectedMarket: market, ...markets.aaveV3MarketsData[market.value] }),
282
+ () => _getAaveV3AccountData(client, network, address, { selectedMarket: market, ...markets.aaveV3MarketsData[market.value] }, blockNumber),
276
283
  (data) => { if (returnEmptyEModePositions || positive(data.suppliedUsd)) positions[lower(address)].aaveV3[market.value] = { error: '', data }; },
277
284
  (err) => { positions[lower(address)].aaveV3[market.value] = err; },
278
285
  )),
279
286
  ...perAddress(sparkMarkets, (market, address) => run(
280
287
  `Spark account data for address ${address} on market ${market.value}`,
281
- () => _getSparkAccountData(client, network, address, { selectedMarket: market, assetsData: markets.sparkMarketsData[market.value].assetsData, eModeCategoriesData: markets.sparkMarketsData[market.value].eModeCategoriesData }),
288
+ () => _getSparkAccountData(client, network, address, { selectedMarket: market, assetsData: markets.sparkMarketsData[market.value].assetsData, eModeCategoriesData: markets.sparkMarketsData[market.value].eModeCategoriesData }, blockNumber),
282
289
  (data) => { if (returnEmptyEModePositions || positive(data.suppliedUsd)) positions[lower(address)].spark[market.value] = { error: '', data }; },
283
290
  (err) => { positions[lower(address)].spark[market.value] = err; },
284
291
  )),
285
292
  ...perAddress(aaveV4Spokes, (spoke, address) => run(
286
293
  `AaveV4 account data for address ${address} on spoke ${spoke.value}`,
287
- () => _getAaveV4AccountData(client, network, markets.aaveV4SpokesData[spoke.value], address),
294
+ () => _getAaveV4AccountData(client, network, markets.aaveV4SpokesData[spoke.value], address, blockNumber),
288
295
  (data) => { if (positive(data.suppliedUsd)) positions[lower(address)].aaveV4[spoke.value] = { error: '', data }; },
289
296
  (err) => { positions[lower(address)].aaveV4[spoke.value] = err; },
290
297
  )),
291
298
  ...perAddress(morphoMarkets, (market, address) => run(
292
299
  `MorphoBlue account data for address ${address} on market ${market.value}`,
293
- () => _getMorphoBlueAccountData(client, network, address, market, markets.morphoMarketsData[market.value]),
300
+ () => _getMorphoBlueAccountData(client, network, address, market, markets.morphoMarketsData[market.value], blockNumber),
294
301
  (data) => { if (positive(data.suppliedUsd)) positions[lower(address)].morphoBlue[market.value] = { error: '', data }; },
295
302
  (err) => { positions[lower(address)].morphoBlue[market.value] = err; },
296
303
  )),
297
304
  ...(fetchStaking ? perAddress(morphoMarkets, (market, address) => run(
298
305
  `MorphoBlue earn data for address ${address} on market ${market.value}`,
299
- () => getMorphoEarn(client, network, address, market, markets.morphoMarketsData[market.value]),
306
+ () => getMorphoEarn(client, network, address, market, markets.morphoMarketsData[market.value], blockNumber),
300
307
  (data) => { if (data && positive(data.amount)) stakingPositions[lower(address)].morphoBlue[market.value] = { error: '', data }; },
301
308
  (err) => { stakingPositions[lower(address)].morphoBlue[market.value] = err; },
302
309
  )) : []),
@@ -304,38 +311,38 @@ export async function getCustomDeFiData(
304
311
  if (!markets.morphoMidnightMarketsData[market.value]?.isCreated) return Promise.resolve();
305
312
  return run(
306
313
  `MorphoMidnight account data for address ${address} on market ${market.value}`,
307
- () => _getMorphoMidnightAccountData(client, network, address, market, markets.morphoMidnightMarketsData[market.value]),
314
+ () => _getMorphoMidnightAccountData(client, network, address, market, markets.morphoMidnightMarketsData[market.value], blockNumber),
308
315
  (data) => { if (positive(data.suppliedUsd)) positions[lower(address)].morphoMidnight[market.value] = { error: '', data }; },
309
316
  (err) => { positions[lower(address)].morphoMidnight[market.value] = err; },
310
317
  );
311
318
  }),
312
319
  ...perAddress(compoundV3Markets, (market, address) => run(
313
320
  `CompoundV3 account data for address ${address} on market ${market.value}`,
314
- () => _getCompoundV3AccountData(client, network, address, ZERO_ADDRESS, { selectedMarket: market, assetsData: markets.compoundV3MarketsData[market.value].assetsData }),
321
+ () => _getCompoundV3AccountData(client, network, address, ZERO_ADDRESS, { selectedMarket: market, assetsData: markets.compoundV3MarketsData[market.value].assetsData }, blockNumber),
315
322
  (data) => { if (positive(data.suppliedUsd)) positions[lower(address)].compoundV3[market.value] = { error: '', data }; },
316
323
  (err) => { positions[lower(address)].compoundV3[market.value] = err; },
317
324
  )),
318
325
  ...perAddress(compoundV2Markets, (market, address) => run(
319
326
  `CompoundV2 account data for address ${address}`,
320
- () => _getCompoundV2AccountData(client, network, address, markets.compoundV2MarketsData[market.value].assetsData),
327
+ () => _getCompoundV2AccountData(client, network, address, markets.compoundV2MarketsData[market.value].assetsData, blockNumber),
321
328
  (data) => { if (positive(data.suppliedUsd)) positions[lower(address)].compoundV2[market.value] = { error: '', data }; },
322
329
  (err) => { positions[lower(address)].compoundV2[market.value] = err; },
323
330
  )),
324
331
  ...perAddress(aaveV2Markets, (market, address) => run(
325
332
  `AaveV2 account data for address ${address}`,
326
- () => _getAaveV2AccountData(client, network, address, markets.aaveV2MarketsData[market.value].assetsData, market),
333
+ () => _getAaveV2AccountData(client, network, address, markets.aaveV2MarketsData[market.value].assetsData, market, blockNumber),
327
334
  (data) => { if (positive(data.suppliedUsd)) positions[lower(address)].aaveV2[market.value] = { error: '', data }; },
328
335
  (err) => { positions[lower(address)].aaveV2[market.value] = err; },
329
336
  )),
330
337
  ...perAddress(crvUsdMarkets, (market, address) => run(
331
338
  `Curve USD account data for address ${address} on market ${market.value}`,
332
- () => _getCurveUsdUserData(client, network, address, market, markets.crvUsdMarketsData[market.value].activeBand, markets.crvUsdMarketsData[market.value].borrowRate),
339
+ () => _getCurveUsdUserData(client, network, address, market, markets.crvUsdMarketsData[market.value].activeBand, markets.crvUsdMarketsData[market.value].borrowRate, blockNumber),
333
340
  (data) => { if (positive(data.suppliedUsd) || positive(data.borrowedUsd)) positions[lower(address)].crvUsd[market.value] = { error: '', data }; },
334
341
  (err) => { positions[lower(address)].crvUsd[market.value] = err; },
335
342
  )),
336
343
  ...perAddress(llamaLendMarkets, (market, address) => run(
337
344
  `LlamaLend account data for address ${address} on market ${market.value}`,
338
- () => _getLlamaLendUserData(client, network, address, market, markets.llamaLendMarketsData[market.value]),
345
+ () => _getLlamaLendUserData(client, network, address, market, markets.llamaLendMarketsData[market.value], blockNumber),
339
346
  (data) => {
340
347
  if (positive(data.suppliedUsd) || positive(data.borrowedUsd)) {
341
348
  positions[lower(address)].llamaLend[market.value] = { error: '', data: { ...data, borrowRate: markets.llamaLendMarketsData[market.value].borrowRate } };
@@ -345,13 +352,13 @@ export async function getCustomDeFiData(
345
352
  )),
346
353
  ...addresses.map((address) => (makerCdps[lower(address)] || []).map((cdpInfo) => run(
347
354
  `Maker CDP data for address ${address} with ID ${cdpInfo.id}`,
348
- () => _getMakerCdpData(client, network, cdpInfo, markets.makerMarketsData[cdpInfo.ilkLabel]),
355
+ () => _getMakerCdpData(client, network, cdpInfo, markets.makerMarketsData[cdpInfo.ilkLabel], blockNumber),
349
356
  (data) => { if (data) positions[lower(address)].maker[cdpInfo.id] = { error: '', data }; },
350
357
  (err) => { positions[lower(address)].maker[cdpInfo.id] = err; },
351
358
  ))).flat(),
352
359
  ...addresses.map((address) => fetchLiquity && run(
353
360
  `Liquity trove info for address ${address}`,
354
- () => _getLiquityTroveInfo(client, network, address),
361
+ () => _getLiquityTroveInfo(client, network, address, blockNumber),
355
362
  (data) => { if (positive(data.collateral)) positions[lower(address)].liquity = { error: '', data }; },
356
363
  (err) => { positions[lower(address)].liquity = err; },
357
364
  )),
@@ -362,7 +369,7 @@ export async function getCustomDeFiData(
362
369
  }
363
370
  return run(
364
371
  `sBold/yBold data for address ${address}`,
365
- () => getLiquitySAndYBold(client, network, stakingPositions[lower(address)].liquityV2, address),
372
+ () => getLiquitySAndYBold(client, network, stakingPositions[lower(address)].liquityV2, address, blockNumber),
366
373
  (data) => { stakingPositions[lower(address)].liquityV2SBoldYBold = { error: '', data }; },
367
374
  (err) => { stakingPositions[lower(address)].liquityV2SBoldYBold = err; },
368
375
  );