@across-protocol/sdk 4.0.0-beta.2 → 4.0.0-beta.20

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 (102) hide show
  1. package/dist/cjs/clients/BundleDataClient/BundleDataClient.d.ts +5 -4
  2. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js +320 -179
  3. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  4. package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.d.ts +1 -2
  5. package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.js +1 -2
  6. package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.js.map +1 -1
  7. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.d.ts +3 -1
  8. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js +33 -1
  9. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
  10. package/dist/cjs/clients/SpokePoolClient.d.ts +1 -0
  11. package/dist/cjs/clients/SpokePoolClient.js +13 -4
  12. package/dist/cjs/clients/SpokePoolClient.js.map +1 -1
  13. package/dist/cjs/constants.d.ts +1 -0
  14. package/dist/cjs/constants.js +2 -1
  15. package/dist/cjs/constants.js.map +1 -1
  16. package/dist/cjs/providers/index.d.ts +1 -0
  17. package/dist/cjs/providers/index.js +2 -0
  18. package/dist/cjs/providers/index.js.map +1 -1
  19. package/dist/cjs/providers/mockProvider.d.ts +19 -0
  20. package/dist/cjs/providers/mockProvider.js +70 -0
  21. package/dist/cjs/providers/mockProvider.js.map +1 -0
  22. package/dist/cjs/utils/AddressUtils.d.ts +1 -0
  23. package/dist/cjs/utils/AddressUtils.js +14 -1
  24. package/dist/cjs/utils/AddressUtils.js.map +1 -1
  25. package/dist/cjs/utils/CachingUtils.js +1 -1
  26. package/dist/cjs/utils/CachingUtils.js.map +1 -1
  27. package/dist/cjs/utils/DepositUtils.d.ts +2 -1
  28. package/dist/cjs/utils/DepositUtils.js +12 -3
  29. package/dist/cjs/utils/DepositUtils.js.map +1 -1
  30. package/dist/cjs/utils/NetworkUtils.d.ts +1 -0
  31. package/dist/cjs/utils/NetworkUtils.js +6 -1
  32. package/dist/cjs/utils/NetworkUtils.js.map +1 -1
  33. package/dist/cjs/utils/SpokeUtils.js +3 -3
  34. package/dist/cjs/utils/SpokeUtils.js.map +1 -1
  35. package/dist/esm/clients/BundleDataClient/BundleDataClient.d.ts +5 -4
  36. package/dist/esm/clients/BundleDataClient/BundleDataClient.js +382 -218
  37. package/dist/esm/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  38. package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.d.ts +1 -2
  39. package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.js +2 -3
  40. package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.js.map +1 -1
  41. package/dist/esm/clients/BundleDataClient/utils/FillUtils.d.ts +3 -1
  42. package/dist/esm/clients/BundleDataClient/utils/FillUtils.js +42 -1
  43. package/dist/esm/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
  44. package/dist/esm/clients/SpokePoolClient.d.ts +8 -0
  45. package/dist/esm/clients/SpokePoolClient.js +20 -4
  46. package/dist/esm/clients/SpokePoolClient.js.map +1 -1
  47. package/dist/esm/constants.d.ts +1 -0
  48. package/dist/esm/constants.js +2 -1
  49. package/dist/esm/constants.js.map +1 -1
  50. package/dist/esm/providers/index.d.ts +1 -0
  51. package/dist/esm/providers/index.js +2 -0
  52. package/dist/esm/providers/index.js.map +1 -1
  53. package/dist/esm/providers/mockProvider.d.ts +23 -0
  54. package/dist/esm/providers/mockProvider.js +73 -0
  55. package/dist/esm/providers/mockProvider.js.map +1 -0
  56. package/dist/esm/utils/AddressUtils.d.ts +1 -0
  57. package/dist/esm/utils/AddressUtils.js +16 -0
  58. package/dist/esm/utils/AddressUtils.js.map +1 -1
  59. package/dist/esm/utils/CachingUtils.js +1 -1
  60. package/dist/esm/utils/CachingUtils.js.map +1 -1
  61. package/dist/esm/utils/DepositUtils.d.ts +2 -1
  62. package/dist/esm/utils/DepositUtils.js +12 -3
  63. package/dist/esm/utils/DepositUtils.js.map +1 -1
  64. package/dist/esm/utils/NetworkUtils.d.ts +6 -0
  65. package/dist/esm/utils/NetworkUtils.js +10 -0
  66. package/dist/esm/utils/NetworkUtils.js.map +1 -1
  67. package/dist/esm/utils/SpokeUtils.js +4 -4
  68. package/dist/esm/utils/SpokeUtils.js.map +1 -1
  69. package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts +5 -4
  70. package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts.map +1 -1
  71. package/dist/types/clients/BundleDataClient/utils/DataworkerUtils.d.ts +1 -2
  72. package/dist/types/clients/BundleDataClient/utils/DataworkerUtils.d.ts.map +1 -1
  73. package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts +3 -1
  74. package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts.map +1 -1
  75. package/dist/types/clients/SpokePoolClient.d.ts +8 -0
  76. package/dist/types/clients/SpokePoolClient.d.ts.map +1 -1
  77. package/dist/types/constants.d.ts +1 -0
  78. package/dist/types/constants.d.ts.map +1 -1
  79. package/dist/types/providers/index.d.ts +1 -0
  80. package/dist/types/providers/index.d.ts.map +1 -1
  81. package/dist/types/providers/mockProvider.d.ts +24 -0
  82. package/dist/types/providers/mockProvider.d.ts.map +1 -0
  83. package/dist/types/utils/AddressUtils.d.ts +1 -0
  84. package/dist/types/utils/AddressUtils.d.ts.map +1 -1
  85. package/dist/types/utils/DepositUtils.d.ts +2 -1
  86. package/dist/types/utils/DepositUtils.d.ts.map +1 -1
  87. package/dist/types/utils/NetworkUtils.d.ts +6 -0
  88. package/dist/types/utils/NetworkUtils.d.ts.map +1 -1
  89. package/dist/types/utils/SpokeUtils.d.ts.map +1 -1
  90. package/package.json +1 -1
  91. package/src/clients/BundleDataClient/BundleDataClient.ts +383 -217
  92. package/src/clients/BundleDataClient/utils/DataworkerUtils.ts +0 -8
  93. package/src/clients/BundleDataClient/utils/FillUtils.ts +47 -2
  94. package/src/clients/SpokePoolClient.ts +19 -6
  95. package/src/constants.ts +3 -1
  96. package/src/providers/index.ts +1 -0
  97. package/src/providers/mockProvider.ts +77 -0
  98. package/src/utils/AddressUtils.ts +16 -0
  99. package/src/utils/CachingUtils.ts +1 -1
  100. package/src/utils/DepositUtils.ts +12 -3
  101. package/src/utils/NetworkUtils.ts +11 -0
  102. package/src/utils/SpokeUtils.ts +6 -5
@@ -6,9 +6,13 @@ var lodash_1 = tslib_1.__importDefault(require("lodash"));
6
6
  var interfaces_1 = require("../../interfaces");
7
7
  var utils_1 = require("../../utils");
8
8
  var utils_2 = require("./utils");
9
+ var constants_1 = require("../../constants");
9
10
  exports.INFINITE_FILL_DEADLINE = utils_1.bnUint32Max;
10
11
  function updateExpiredDepositsV3(dict, deposit) {
11
12
  var _a;
13
+ if ((0, utils_1.chainIsEvm)(deposit.originChainId) && !(0, utils_1.isValidEvmAddress)(deposit.depositor)) {
14
+ return;
15
+ }
12
16
  var originChainId = deposit.originChainId, inputToken = deposit.inputToken;
13
17
  if (!((_a = dict === null || dict === void 0 ? void 0 : dict[originChainId]) === null || _a === void 0 ? void 0 : _a[inputToken])) {
14
18
  (0, utils_1.assign)(dict, [originChainId, inputToken], []);
@@ -23,8 +27,11 @@ function updateBundleDepositsV3(dict, deposit) {
23
27
  }
24
28
  dict[originChainId][inputToken].push(deposit);
25
29
  }
26
- function updateBundleFillsV3(dict, fill, lpFeePct, repaymentChainId, repaymentToken) {
30
+ function updateBundleFillsV3(dict, fill, lpFeePct, repaymentChainId, repaymentToken, repaymentAddress) {
27
31
  var _a, _b;
32
+ if ((0, utils_1.chainIsEvm)(repaymentChainId) && !(0, utils_1.isValidEvmAddress)(repaymentAddress)) {
33
+ return;
34
+ }
28
35
  if (!((_a = dict === null || dict === void 0 ? void 0 : dict[repaymentChainId]) === null || _a === void 0 ? void 0 : _a[repaymentToken])) {
29
36
  (0, utils_1.assign)(dict, [repaymentChainId, repaymentToken], {
30
37
  fills: [],
@@ -33,22 +40,22 @@ function updateBundleFillsV3(dict, fill, lpFeePct, repaymentChainId, repaymentTo
33
40
  refunds: {},
34
41
  });
35
42
  }
36
- var bundleFill = tslib_1.__assign(tslib_1.__assign({}, fill), { lpFeePct: lpFeePct });
43
+ var bundleFill = tslib_1.__assign(tslib_1.__assign({}, fill), { lpFeePct: lpFeePct, relayer: repaymentAddress });
37
44
  (0, utils_1.assign)(dict, [repaymentChainId, repaymentToken, "fills"], [bundleFill]);
38
45
  var refundObj = dict[repaymentChainId][repaymentToken];
39
- var realizedLpFee = fill.inputAmount.mul(bundleFill.lpFeePct).div(utils_1.fixedPointAdjustment);
46
+ var realizedLpFee = bundleFill.inputAmount.mul(bundleFill.lpFeePct).div(utils_1.fixedPointAdjustment);
40
47
  refundObj.realizedLpFees = refundObj.realizedLpFees ? refundObj.realizedLpFees.add(realizedLpFee) : realizedLpFee;
41
- if (!(0, utils_1.isSlowFill)(fill)) {
42
- var refundAmount = fill.inputAmount.mul(utils_1.fixedPointAdjustment.sub(lpFeePct)).div(utils_1.fixedPointAdjustment);
48
+ if (!(0, utils_1.isSlowFill)(bundleFill)) {
49
+ var refundAmount = bundleFill.inputAmount.mul(utils_1.fixedPointAdjustment.sub(lpFeePct)).div(utils_1.fixedPointAdjustment);
43
50
  refundObj.totalRefundAmount = refundObj.totalRefundAmount
44
51
  ? refundObj.totalRefundAmount.add(refundAmount)
45
52
  : refundAmount;
46
53
  (_b = refundObj.refunds) !== null && _b !== void 0 ? _b : (refundObj.refunds = {});
47
- if (refundObj.refunds[fill.relayer]) {
48
- refundObj.refunds[fill.relayer] = refundObj.refunds[fill.relayer].add(refundAmount);
54
+ if (refundObj.refunds[bundleFill.relayer]) {
55
+ refundObj.refunds[bundleFill.relayer] = refundObj.refunds[bundleFill.relayer].add(refundAmount);
49
56
  }
50
57
  else {
51
- refundObj.refunds[fill.relayer] = refundAmount;
58
+ refundObj.refunds[bundleFill.relayer] = refundAmount;
52
59
  }
53
60
  }
54
61
  }
@@ -146,7 +153,7 @@ var BundleDataClient = (function () {
146
153
  at: "BundleDataClient#loadPersistedDataFromArweave",
147
154
  message: "Loaded persisted data from Arweave in ".concat(Math.round(performance.now() - start) / 1000, "s."),
148
155
  blockRanges: JSON.stringify(blockRangesForChains),
149
- bundleData: (0, utils_2.prettyPrintV3SpokePoolEvents)(bundleData.bundleDepositsV3, bundleData.bundleFillsV3, [], bundleData.bundleSlowFillsV3, bundleData.expiredDepositsToRefundV3, bundleData.unexecutableSlowFills),
156
+ bundleData: (0, utils_2.prettyPrintV3SpokePoolEvents)(bundleData.bundleDepositsV3, bundleData.bundleFillsV3, bundleData.bundleSlowFillsV3, bundleData.expiredDepositsToRefundV3, bundleData.unexecutableSlowFills),
150
157
  });
151
158
  return [2, bundleData];
152
159
  }
@@ -188,64 +195,107 @@ var BundleDataClient = (function () {
188
195
  return [4, this.loadArweaveData(bundleEvaluationBlockRanges)];
189
196
  case 1:
190
197
  arweaveData = _a.sent();
191
- if (arweaveData === undefined) {
192
- combinedRefunds = this.getApproximateRefundsForBlockRange(chainIds, bundleEvaluationBlockRanges);
193
- }
194
- else {
195
- bundleFillsV3 = arweaveData.bundleFillsV3, expiredDepositsToRefundV3 = arweaveData.expiredDepositsToRefundV3;
196
- combinedRefunds = (0, utils_2.getRefundsFromBundle)(bundleFillsV3, expiredDepositsToRefundV3);
197
- Object.keys(combinedRefunds).forEach(function (chainId) {
198
- if (_this.spokePoolClients[Number(chainId)] === undefined) {
199
- delete combinedRefunds[Number(chainId)];
200
- }
201
- });
202
- }
203
- return [2, this.deductExecutedRefunds(combinedRefunds, bundle)];
198
+ if (!(arweaveData === undefined)) return [3, 3];
199
+ return [4, this.getApproximateRefundsForBlockRange(chainIds, bundleEvaluationBlockRanges)];
200
+ case 2:
201
+ combinedRefunds = _a.sent();
202
+ return [3, 4];
203
+ case 3:
204
+ bundleFillsV3 = arweaveData.bundleFillsV3, expiredDepositsToRefundV3 = arweaveData.expiredDepositsToRefundV3;
205
+ combinedRefunds = (0, utils_2.getRefundsFromBundle)(bundleFillsV3, expiredDepositsToRefundV3);
206
+ Object.keys(combinedRefunds).forEach(function (chainId) {
207
+ if (_this.spokePoolClients[Number(chainId)] === undefined) {
208
+ delete combinedRefunds[Number(chainId)];
209
+ }
210
+ });
211
+ _a.label = 4;
212
+ case 4: return [2, this.deductExecutedRefunds(combinedRefunds, bundle)];
204
213
  }
205
214
  });
206
215
  });
207
216
  };
208
217
  BundleDataClient.prototype.getApproximateRefundsForBlockRange = function (chainIds, blockRanges) {
209
- var _this = this;
210
- var refundsForChain = {};
211
- var _loop_1 = function (chainId) {
212
- if (this_1.spokePoolClients[chainId] === undefined) {
213
- return "continue";
214
- }
215
- var chainIndex = chainIds.indexOf(chainId);
216
- this_1.spokePoolClients[chainId]
217
- .getFills()
218
- .filter(function (fill) {
219
- if (fill.blockNumber < blockRanges[chainIndex][0] || fill.blockNumber > blockRanges[chainIndex][1]) {
220
- return false;
221
- }
222
- if (_this.spokePoolClients[fill.originChainId] === undefined) {
223
- return false;
218
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
219
+ var refundsForChain, _loop_1, this_1, _i, chainIds_1, chainId;
220
+ var _this = this;
221
+ return tslib_1.__generator(this, function (_a) {
222
+ switch (_a.label) {
223
+ case 0:
224
+ refundsForChain = {};
225
+ _loop_1 = function (chainId) {
226
+ var chainIndex, fillsToCount;
227
+ return tslib_1.__generator(this, function (_b) {
228
+ switch (_b.label) {
229
+ case 0:
230
+ if (this_1.spokePoolClients[chainId] === undefined) {
231
+ return [2, "continue"];
232
+ }
233
+ chainIndex = chainIds.indexOf(chainId);
234
+ return [4, (0, utils_1.filterAsync)(this_1.spokePoolClients[chainId].getFills(), function (fill) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
235
+ var matchingDeposit, hasMatchingDeposit, validRepayment;
236
+ return tslib_1.__generator(this, function (_a) {
237
+ switch (_a.label) {
238
+ case 0:
239
+ if (fill.blockNumber < blockRanges[chainIndex][0] ||
240
+ fill.blockNumber > blockRanges[chainIndex][1] ||
241
+ (0, utils_1.isZeroValueFillOrSlowFillRequest)(fill)) {
242
+ return [2, false];
243
+ }
244
+ if (this.spokePoolClients[fill.originChainId] === undefined) {
245
+ return [2, false];
246
+ }
247
+ matchingDeposit = this.spokePoolClients[fill.originChainId].getDeposit(fill.depositId);
248
+ hasMatchingDeposit = matchingDeposit !== undefined &&
249
+ this.getRelayHashFromEvent(fill) === this.getRelayHashFromEvent(matchingDeposit);
250
+ if (!hasMatchingDeposit) return [3, 2];
251
+ return [4, (0, utils_2.verifyFillRepayment)(fill, this.spokePoolClients[fill.destinationChainId].spokePool.provider, matchingDeposit, this.clients.configStoreClient
252
+ .getChainIdIndicesForBlock(blockRanges[0][1])
253
+ .filter(function (_chainId, i) { return !(0, utils_2.isChainDisabled)(blockRanges[i]); }))];
254
+ case 1:
255
+ validRepayment = _a.sent();
256
+ if (!(0, utils_1.isDefined)(validRepayment)) {
257
+ return [2, false];
258
+ }
259
+ _a.label = 2;
260
+ case 2: return [2, hasMatchingDeposit];
261
+ }
262
+ });
263
+ }); })];
264
+ case 1:
265
+ fillsToCount = _b.sent();
266
+ fillsToCount.forEach(function (fill) {
267
+ var _a, _b, _c;
268
+ var _d;
269
+ var matchingDeposit = _this.spokePoolClients[fill.originChainId].getDeposit(fill.depositId);
270
+ (0, utils_1.assert)((0, utils_1.isDefined)(matchingDeposit), "Deposit not found for fill.");
271
+ var _e = (0, utils_2.getRefundInformationFromFill)(fill, _this.clients.hubPoolClient, blockRanges, _this.chainIdListForBundleEvaluationBlockNumbers, matchingDeposit.fromLiteChain), chainToSendRefundTo = _e.chainToSendRefundTo, repaymentToken = _e.repaymentToken;
272
+ var relayer = fill.relayer, refundAmount = fill.inputAmount;
273
+ (_a = refundsForChain[chainToSendRefundTo]) !== null && _a !== void 0 ? _a : (refundsForChain[chainToSendRefundTo] = {});
274
+ (_b = (_d = refundsForChain[chainToSendRefundTo])[repaymentToken]) !== null && _b !== void 0 ? _b : (_d[repaymentToken] = {});
275
+ var existingRefundAmount = (_c = refundsForChain[chainToSendRefundTo][repaymentToken][relayer]) !== null && _c !== void 0 ? _c : utils_1.bnZero;
276
+ refundsForChain[chainToSendRefundTo][repaymentToken][relayer] = existingRefundAmount.add(refundAmount);
277
+ });
278
+ return [2];
279
+ }
280
+ });
281
+ };
282
+ this_1 = this;
283
+ _i = 0, chainIds_1 = chainIds;
284
+ _a.label = 1;
285
+ case 1:
286
+ if (!(_i < chainIds_1.length)) return [3, 4];
287
+ chainId = chainIds_1[_i];
288
+ return [5, _loop_1(chainId)];
289
+ case 2:
290
+ _a.sent();
291
+ _a.label = 3;
292
+ case 3:
293
+ _i++;
294
+ return [3, 1];
295
+ case 4: return [2, refundsForChain];
224
296
  }
225
- var matchingDeposit = _this.spokePoolClients[fill.originChainId].getDeposit(fill.depositId);
226
- var hasMatchingDeposit = matchingDeposit !== undefined &&
227
- _this.getRelayHashFromEvent(fill) === _this.getRelayHashFromEvent(matchingDeposit);
228
- return hasMatchingDeposit;
229
- })
230
- .forEach(function (fill) {
231
- var _a, _b, _c;
232
- var _d;
233
- var matchingDeposit = _this.spokePoolClients[fill.originChainId].getDeposit(fill.depositId);
234
- (0, utils_1.assert)((0, utils_1.isDefined)(matchingDeposit), "Deposit not found for fill.");
235
- var _e = (0, utils_2.getRefundInformationFromFill)(fill, _this.clients.hubPoolClient, blockRanges, _this.chainIdListForBundleEvaluationBlockNumbers, matchingDeposit.fromLiteChain), chainToSendRefundTo = _e.chainToSendRefundTo, repaymentToken = _e.repaymentToken;
236
- var relayer = fill.relayer, refundAmount = fill.inputAmount;
237
- (_a = refundsForChain[chainToSendRefundTo]) !== null && _a !== void 0 ? _a : (refundsForChain[chainToSendRefundTo] = {});
238
- (_b = (_d = refundsForChain[chainToSendRefundTo])[repaymentToken]) !== null && _b !== void 0 ? _b : (_d[repaymentToken] = {});
239
- var existingRefundAmount = (_c = refundsForChain[chainToSendRefundTo][repaymentToken][relayer]) !== null && _c !== void 0 ? _c : utils_1.bnZero;
240
- refundsForChain[chainToSendRefundTo][repaymentToken][relayer] = existingRefundAmount.add(refundAmount);
241
297
  });
242
- };
243
- var this_1 = this;
244
- for (var _i = 0, chainIds_1 = chainIds; _i < chainIds_1.length; _i++) {
245
- var chainId = chainIds_1[_i];
246
- _loop_1(chainId);
247
- }
248
- return refundsForChain;
298
+ });
249
299
  };
250
300
  BundleDataClient.prototype.getUpcomingDepositAmount = function (chainId, l2Token, latestBlockToSearch) {
251
301
  if (this.spokePoolClients[chainId] === undefined) {
@@ -317,32 +367,39 @@ var BundleDataClient = (function () {
317
367
  return [initialBlockRange[1] + 1, blockRange[1]];
318
368
  });
319
369
  }
320
- var hubPoolClient, nextBundleMainnetStartBlock, chainIds, combinedRefunds, widestBundleBlockRanges, pendingBundleBlockRanges, arweaveData, bundleFillsV3, expiredDepositsToRefundV3, start;
321
- return tslib_1.__generator(this, function (_a) {
322
- switch (_a.label) {
370
+ var hubPoolClient, nextBundleMainnetStartBlock, chainIds, combinedRefunds, widestBundleBlockRanges, pendingBundleBlockRanges, arweaveData, _a, _b, bundleFillsV3, expiredDepositsToRefundV3, start, _c, _d;
371
+ return tslib_1.__generator(this, function (_e) {
372
+ switch (_e.label) {
323
373
  case 0:
324
374
  hubPoolClient = this.clients.hubPoolClient;
325
375
  nextBundleMainnetStartBlock = hubPoolClient.getNextBundleStartBlockNumber(this.chainIdListForBundleEvaluationBlockNumbers, hubPoolClient.latestBlockSearched, hubPoolClient.chainId);
326
376
  chainIds = this.clients.configStoreClient.getChainIdIndicesForBlock(nextBundleMainnetStartBlock);
327
377
  combinedRefunds = [];
328
378
  widestBundleBlockRanges = (0, utils_2.getWidestPossibleExpectedBlockRange)(chainIds, this.spokePoolClients, (0, utils_2.getEndBlockBuffers)(chainIds, this.blockRangeEndBlockBuffer), this.clients, this.clients.hubPoolClient.latestBlockSearched, this.clients.configStoreClient.getEnabledChains(this.clients.hubPoolClient.latestBlockSearched));
329
- if (!hubPoolClient.hasPendingProposal()) return [3, 2];
379
+ if (!hubPoolClient.hasPendingProposal()) return [3, 5];
330
380
  pendingBundleBlockRanges = (0, utils_1.getImpliedBundleBlockRanges)(hubPoolClient, this.clients.configStoreClient, hubPoolClient.getLatestProposedRootBundle());
331
381
  return [4, this.loadArweaveData(pendingBundleBlockRanges)];
332
382
  case 1:
333
- arweaveData = _a.sent();
334
- if (arweaveData === undefined) {
335
- combinedRefunds.push(this.getApproximateRefundsForBlockRange(chainIds, pendingBundleBlockRanges));
336
- }
337
- else {
338
- bundleFillsV3 = arweaveData.bundleFillsV3, expiredDepositsToRefundV3 = arweaveData.expiredDepositsToRefundV3;
339
- combinedRefunds.push((0, utils_2.getRefundsFromBundle)(bundleFillsV3, expiredDepositsToRefundV3));
340
- }
341
- widestBundleBlockRanges = getBlockRangeDelta(pendingBundleBlockRanges);
342
- _a.label = 2;
383
+ arweaveData = _e.sent();
384
+ if (!(arweaveData === undefined)) return [3, 3];
385
+ _b = (_a = combinedRefunds).push;
386
+ return [4, this.getApproximateRefundsForBlockRange(chainIds, pendingBundleBlockRanges)];
343
387
  case 2:
388
+ _b.apply(_a, [_e.sent()]);
389
+ return [3, 4];
390
+ case 3:
391
+ bundleFillsV3 = arweaveData.bundleFillsV3, expiredDepositsToRefundV3 = arweaveData.expiredDepositsToRefundV3;
392
+ combinedRefunds.push((0, utils_2.getRefundsFromBundle)(bundleFillsV3, expiredDepositsToRefundV3));
393
+ _e.label = 4;
394
+ case 4:
395
+ widestBundleBlockRanges = getBlockRangeDelta(pendingBundleBlockRanges);
396
+ _e.label = 5;
397
+ case 5:
344
398
  start = performance.now();
345
- combinedRefunds.push(this.getApproximateRefundsForBlockRange(chainIds, widestBundleBlockRanges));
399
+ _d = (_c = combinedRefunds).push;
400
+ return [4, this.getApproximateRefundsForBlockRange(chainIds, widestBundleBlockRanges)];
401
+ case 6:
402
+ _d.apply(_c, [_e.sent()]);
346
403
  this.logger.debug({
347
404
  at: "BundleDataClient#getNextBundleRefunds",
348
405
  message: "Loading approximate refunds for next bundle in ".concat(Math.round(performance.now() - start) / 1000, "s."),
@@ -473,7 +530,7 @@ var BundleDataClient = (function () {
473
530
  };
474
531
  BundleDataClient.prototype.loadDataFromScratch = function (blockRangesForChains, spokePoolClients) {
475
532
  return tslib_1.__awaiter(this, void 0, void 0, function () {
476
- var start, key, chainIds, bundleDepositsV3, bundleFillsV3, bundleInvalidFillsV3, bundleSlowFillsV3, expiredDepositsToRefundV3, unexecutableSlowFills, _isChainDisabled, _canCreateSlowFillLeaf, _getFillStatusForDeposit, allChainIds, _cachedBundleTimestamps, bundleBlockTimestamps, v3RelayHashes, bundleDepositHashes, olderDepositHashes, depositCounter, _loop_2, _i, allChainIds_1, originChainId, validatedBundleV3Fills, validatedBundleSlowFills, validatedBundleUnexecutableSlowFills, fillCounter, _loop_3, _a, allChainIds_2, originChainId, promises, _b, v3FillLpFees, v3SlowFillLpFees, v3UnexecutableSlowFillLpFees, v3SpokeEventsReadable;
533
+ var start, key, chainIds, bundleDepositsV3, bundleFillsV3, bundleInvalidFillsV3, bundleUnrepayableFillsV3, bundleSlowFillsV3, expiredDepositsToRefundV3, unexecutableSlowFills, _isChainDisabled, _canCreateSlowFillLeaf, _depositIsExpired, _getFillStatusForDeposit, allChainIds, _cachedBundleTimestamps, bundleBlockTimestamps, v3RelayHashes, bundleDepositHashes, olderDepositHashes, decodeBundleDepositHash, startBlockForMainnet, versionAtProposalBlock, canRefundPrefills, depositCounter, _loop_2, _i, allChainIds_1, originChainId, validatedBundleV3Fills, validatedBundleSlowFills, validatedBundleUnexecutableSlowFills, fillCounter, _loop_3, _a, allChainIds_2, originChainId, promises, _b, v3FillLpFees, v3SlowFillLpFees, v3UnexecutableSlowFillLpFees, v3SpokeEventsReadable;
477
534
  var _this = this;
478
535
  return tslib_1.__generator(this, function (_c) {
479
536
  switch (_c.label) {
@@ -493,6 +550,7 @@ var BundleDataClient = (function () {
493
550
  bundleDepositsV3 = {};
494
551
  bundleFillsV3 = {};
495
552
  bundleInvalidFillsV3 = [];
553
+ bundleUnrepayableFillsV3 = [];
496
554
  bundleSlowFillsV3 = {};
497
555
  expiredDepositsToRefundV3 = {};
498
556
  unexecutableSlowFills = {};
@@ -505,6 +563,9 @@ var BundleDataClient = (function () {
505
563
  !deposit.fromLiteChain &&
506
564
  !deposit.toLiteChain);
507
565
  };
566
+ _depositIsExpired = function (deposit) {
567
+ return deposit.fillDeadline < bundleBlockTimestamps[deposit.destinationChainId][1];
568
+ };
508
569
  _getFillStatusForDeposit = function (deposit, queryBlock) {
509
570
  return spokePoolClients[deposit.destinationChainId].relayFillStatus(deposit, Math.min(queryBlock, spokePoolClients[deposit.destinationChainId].latestBlockSearched), deposit.destinationChainId);
510
571
  };
@@ -538,6 +599,13 @@ var BundleDataClient = (function () {
538
599
  v3RelayHashes = {};
539
600
  bundleDepositHashes = [];
540
601
  olderDepositHashes = [];
602
+ decodeBundleDepositHash = function (depositHash) {
603
+ var _a = depositHash.split("@"), relayDataHash = _a[0], i = _a[1];
604
+ return { relayDataHash: relayDataHash, index: Number(i) };
605
+ };
606
+ startBlockForMainnet = (0, utils_1.getBlockRangeForChain)(blockRangesForChains, this.clients.hubPoolClient.chainId, this.chainIdListForBundleEvaluationBlockNumbers)[0];
607
+ versionAtProposalBlock = this.clients.configStoreClient.getConfigStoreVersionForBlock(startBlockForMainnet);
608
+ canRefundPrefills = versionAtProposalBlock >= constants_1.PRE_FILL_MIN_CONFIG_STORE_VERSION || process.env.FORCE_REFUND_PREFILLS === "true";
541
609
  depositCounter = 0;
542
610
  _loop_2 = function (originChainId) {
543
611
  var originClient = spokePoolClients[originChainId];
@@ -548,27 +616,34 @@ var BundleDataClient = (function () {
548
616
  continue;
549
617
  }
550
618
  originClient.getDepositsForDestinationChainWithDuplicates(destinationChainId).forEach(function (deposit) {
551
- if ((0, utils_1.isZeroValueDeposit)(deposit) || deposit.blockNumber > originChainBlockRange[1]) {
619
+ if (deposit.blockNumber > originChainBlockRange[1] || (0, utils_1.isZeroValueDeposit)(deposit)) {
552
620
  return;
553
621
  }
554
622
  depositCounter++;
555
623
  var relayDataHash = _this.getRelayHashFromEvent(deposit);
556
624
  if (!v3RelayHashes[relayDataHash]) {
557
625
  v3RelayHashes[relayDataHash] = {
558
- deposit: deposit,
626
+ deposits: [deposit],
559
627
  fill: undefined,
560
628
  slowFillRequest: undefined,
561
629
  };
562
630
  }
631
+ else {
632
+ v3RelayHashes[relayDataHash].deposits.push(deposit);
633
+ }
563
634
  if (deposit.inputAmount.eq(0)) {
564
635
  return;
565
636
  }
637
+ var newBundleDepositHash = "".concat(relayDataHash, "@").concat(v3RelayHashes[relayDataHash].deposits.length - 1);
638
+ var decodedBundleDepositHash = decodeBundleDepositHash(newBundleDepositHash);
639
+ (0, utils_1.assert)(decodedBundleDepositHash.relayDataHash === relayDataHash &&
640
+ decodedBundleDepositHash.index === v3RelayHashes[relayDataHash].deposits.length - 1, "Not using correct bundle deposit hash key");
566
641
  if (deposit.blockNumber >= originChainBlockRange[0]) {
567
- bundleDepositHashes.push(relayDataHash);
642
+ bundleDepositHashes.push(newBundleDepositHash);
568
643
  updateBundleDepositsV3(bundleDepositsV3, deposit);
569
644
  }
570
645
  else if (deposit.blockNumber < originChainBlockRange[0]) {
571
- olderDepositHashes.push(relayDataHash);
646
+ olderDepositHashes.push(newBundleDepositHash);
572
647
  }
573
648
  });
574
649
  }
@@ -593,7 +668,7 @@ var BundleDataClient = (function () {
593
668
  case 0:
594
669
  originClient = spokePoolClients[originChainId];
595
670
  _loop_4 = function (destinationChainId) {
596
- var destinationClient, destinationChainBlockRange, fastFillsReplacingSlowFills, originBlockRange;
671
+ var destinationClient, destinationChainBlockRange, fastFillsReplacingSlowFills;
597
672
  return tslib_1.__generator(this, function (_g) {
598
673
  switch (_g.label) {
599
674
  case 0:
@@ -606,56 +681,76 @@ var BundleDataClient = (function () {
606
681
  return [4, (0, utils_1.forEachAsync)(destinationClient
607
682
  .getFillsForOriginChain(originChainId)
608
683
  .filter(function (fill) { return fill.blockNumber <= destinationChainBlockRange[1] && !(0, utils_1.isZeroValueFillOrSlowFillRequest)(fill); }), function (fill) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
609
- var relayDataHash, historicalDeposit, matchedDeposit;
684
+ var relayDataHash, fillToRefund, duplicateDeposits, historicalDeposit, matchedDeposit, fillToRefund;
610
685
  return tslib_1.__generator(this, function (_a) {
611
686
  switch (_a.label) {
612
687
  case 0:
613
- relayDataHash = this.getRelayHashFromEvent(fill);
614
688
  fillCounter++;
615
- if (v3RelayHashes[relayDataHash]) {
616
- if (!v3RelayHashes[relayDataHash].fill) {
617
- (0, utils_1.assert)((0, utils_1.isDefined)(v3RelayHashes[relayDataHash].deposit), "Deposit should exist in relay hash dictionary.");
618
- v3RelayHashes[relayDataHash].fill = fill;
619
- if (fill.blockNumber >= destinationChainBlockRange[0]) {
620
- validatedBundleV3Fills.push(tslib_1.__assign(tslib_1.__assign({}, fill), { quoteTimestamp: v3RelayHashes[relayDataHash].deposit.quoteTimestamp }));
621
- if (fill.relayExecutionInfo.fillType === interfaces_1.FillType.ReplacedSlowFill &&
622
- !v3RelayHashes[relayDataHash].deposit.fromLiteChain &&
623
- !v3RelayHashes[relayDataHash].deposit.toLiteChain) {
624
- fastFillsReplacingSlowFills.push(relayDataHash);
625
- }
626
- }
627
- }
628
- return [2];
689
+ relayDataHash = this.getRelayHashFromEvent(fill);
690
+ if (!v3RelayHashes[relayDataHash]) return [3, 5];
691
+ if (!!v3RelayHashes[relayDataHash].fill) return [3, 3];
692
+ (0, utils_1.assert)((0, utils_1.isDefined)(v3RelayHashes[relayDataHash].deposits) && v3RelayHashes[relayDataHash].deposits.length > 0, "Deposit should exist in relay hash dictionary.");
693
+ v3RelayHashes[relayDataHash].fill = fill;
694
+ if (!(fill.blockNumber >= destinationChainBlockRange[0])) return [3, 2];
695
+ return [4, (0, utils_2.verifyFillRepayment)(fill, destinationClient.spokePool.provider, v3RelayHashes[relayDataHash].deposits[0], allChainIds)];
696
+ case 1:
697
+ fillToRefund = _a.sent();
698
+ if (!(0, utils_1.isDefined)(fillToRefund)) {
699
+ bundleUnrepayableFillsV3.push(fill);
700
+ }
701
+ else {
702
+ v3RelayHashes[relayDataHash].fill = fillToRefund;
703
+ validatedBundleV3Fills.push(tslib_1.__assign(tslib_1.__assign({}, fillToRefund), { quoteTimestamp: v3RelayHashes[relayDataHash].deposits[0].quoteTimestamp }));
704
+ }
705
+ if (fill.relayExecutionInfo.fillType === interfaces_1.FillType.ReplacedSlowFill &&
706
+ _canCreateSlowFillLeaf(v3RelayHashes[relayDataHash].deposits[0])) {
707
+ fastFillsReplacingSlowFills.push(relayDataHash);
629
708
  }
709
+ duplicateDeposits = v3RelayHashes[relayDataHash].deposits.slice(1);
710
+ duplicateDeposits.forEach(function (duplicateDeposit) {
711
+ updateExpiredDepositsV3(expiredDepositsToRefundV3, duplicateDeposit);
712
+ });
713
+ _a.label = 2;
714
+ case 2: return [3, 4];
715
+ case 3: throw new Error("Duplicate fill detected");
716
+ case 4: return [2];
717
+ case 5:
630
718
  v3RelayHashes[relayDataHash] = {
631
- deposit: undefined,
719
+ deposits: undefined,
632
720
  fill: fill,
633
721
  slowFillRequest: undefined,
634
722
  };
635
- if (!(fill.blockNumber >= destinationChainBlockRange[0])) return [3, 2];
723
+ if (!(fill.blockNumber >= destinationChainBlockRange[0])) return [3, 9];
636
724
  if (!exports.INFINITE_FILL_DEADLINE.eq(fill.fillDeadline)) {
637
725
  bundleInvalidFillsV3.push(fill);
638
726
  return [2];
639
727
  }
640
728
  return [4, (0, utils_1.queryHistoricalDepositForFill)(originClient, fill)];
641
- case 1:
729
+ case 6:
642
730
  historicalDeposit = _a.sent();
643
- if (!historicalDeposit.found) {
644
- bundleInvalidFillsV3.push(fill);
731
+ if (!!historicalDeposit.found) return [3, 7];
732
+ bundleInvalidFillsV3.push(fill);
733
+ return [3, 9];
734
+ case 7:
735
+ matchedDeposit = historicalDeposit.deposit;
736
+ v3RelayHashes[relayDataHash].deposits = [matchedDeposit];
737
+ return [4, (0, utils_2.verifyFillRepayment)(fill, destinationClient.spokePool.provider, matchedDeposit, allChainIds)];
738
+ case 8:
739
+ fillToRefund = _a.sent();
740
+ if (!(0, utils_1.isDefined)(fillToRefund)) {
741
+ bundleUnrepayableFillsV3.push(fill);
645
742
  }
646
743
  else {
647
- matchedDeposit = historicalDeposit.deposit;
648
744
  (0, utils_1.assert)(this.getRelayHashFromEvent(matchedDeposit) === relayDataHash, "Relay hashes should match.");
649
- validatedBundleV3Fills.push(tslib_1.__assign(tslib_1.__assign({}, fill), { quoteTimestamp: matchedDeposit.quoteTimestamp }));
650
- v3RelayHashes[relayDataHash].deposit = matchedDeposit;
651
- if (fill.relayExecutionInfo.fillType === interfaces_1.FillType.ReplacedSlowFill &&
652
- !matchedDeposit.fromLiteChain &&
653
- !matchedDeposit.toLiteChain) {
654
- fastFillsReplacingSlowFills.push(relayDataHash);
655
- }
745
+ validatedBundleV3Fills.push(tslib_1.__assign(tslib_1.__assign({}, fillToRefund), { quoteTimestamp: matchedDeposit.quoteTimestamp }));
746
+ v3RelayHashes[relayDataHash].fill = fillToRefund;
656
747
  }
657
- _a.label = 2;
658
- case 2: return [2];
748
+ if (fill.relayExecutionInfo.fillType === interfaces_1.FillType.ReplacedSlowFill &&
749
+ _canCreateSlowFillLeaf(matchedDeposit)) {
750
+ fastFillsReplacingSlowFills.push(relayDataHash);
751
+ }
752
+ _a.label = 9;
753
+ case 9: return [2];
659
754
  }
660
755
  });
661
756
  }); })];
@@ -677,20 +772,21 @@ var BundleDataClient = (function () {
677
772
  if (v3RelayHashes[relayDataHash].fill) {
678
773
  return [2];
679
774
  }
680
- (0, utils_1.assert)((0, utils_1.isDefined)(v3RelayHashes[relayDataHash].deposit), "Deposit should exist in relay hash dictionary.");
681
- matchedDeposit = v3RelayHashes[relayDataHash].deposit;
682
- if (!_canCreateSlowFillLeaf(matchedDeposit)) {
683
- return [2];
684
- }
775
+ (0, utils_1.assert)((0, utils_1.isDefined)(v3RelayHashes[relayDataHash].deposits) && v3RelayHashes[relayDataHash].deposits.length > 0, "Deposit should exist in relay hash dictionary.");
776
+ matchedDeposit = v3RelayHashes[relayDataHash].deposits[0];
685
777
  if (slowFillRequest.blockNumber >= destinationChainBlockRange[0] &&
686
- slowFillRequest.fillDeadline >= bundleBlockTimestamps[destinationChainId][1]) {
778
+ _canCreateSlowFillLeaf(matchedDeposit) &&
779
+ !_depositIsExpired(matchedDeposit)) {
687
780
  validatedBundleSlowFills.push(matchedDeposit);
688
781
  }
689
782
  }
783
+ else {
784
+ throw new Error("Duplicate slow fill request detected.");
785
+ }
690
786
  return [2];
691
787
  }
692
788
  v3RelayHashes[relayDataHash] = {
693
- deposit: undefined,
789
+ deposits: undefined,
694
790
  fill: undefined,
695
791
  slowFillRequest: slowFillRequest,
696
792
  };
@@ -704,9 +800,9 @@ var BundleDataClient = (function () {
704
800
  }
705
801
  matchedDeposit = historicalDeposit.deposit;
706
802
  (0, utils_1.assert)(this.getRelayHashFromEvent(matchedDeposit) === relayDataHash, "Deposit relay hashes should match.");
707
- v3RelayHashes[relayDataHash].deposit = matchedDeposit;
803
+ v3RelayHashes[relayDataHash].deposits = [matchedDeposit];
708
804
  if (!_canCreateSlowFillLeaf(matchedDeposit) ||
709
- slowFillRequest.fillDeadline < bundleBlockTimestamps[destinationChainId][1]) {
805
+ _depositIsExpired(matchedDeposit)) {
710
806
  return [2];
711
807
  }
712
808
  validatedBundleSlowFills.push(matchedDeposit);
@@ -717,77 +813,99 @@ var BundleDataClient = (function () {
717
813
  }); })];
718
814
  case 2:
719
815
  _g.sent();
720
- originBlockRange = (0, utils_1.getBlockRangeForChain)(blockRangesForChains, originChainId, chainIds);
721
- return [4, (0, utils_1.mapAsync)(bundleDepositHashes.filter(function (depositHash) {
722
- var deposit = v3RelayHashes[depositHash].deposit;
723
- return (deposit &&
724
- deposit.originChainId === originChainId &&
725
- deposit.destinationChainId === destinationChainId &&
726
- deposit.blockNumber >= originBlockRange[0] &&
727
- deposit.blockNumber <= originBlockRange[1] &&
728
- !(0, utils_1.isZeroValueDeposit)(deposit));
729
- }), function (depositHash) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
730
- var _a, deposit, fill, slowFillRequest, fillStatus, prefill;
731
- return tslib_1.__generator(this, function (_b) {
732
- switch (_b.label) {
816
+ return [4, (0, utils_1.mapAsync)(bundleDepositHashes, function (depositHash, currentBundleDepositHashIndex) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
817
+ var _a, relayDataHash, index, _b, deposits, fill, slowFillRequest, deposit, isDuplicateDepositInBundle, duplicateDepositsInBundle, fillStatus, prefill, verifiedFill;
818
+ return tslib_1.__generator(this, function (_c) {
819
+ switch (_c.label) {
733
820
  case 0:
734
- _a = v3RelayHashes[depositHash], deposit = _a.deposit, fill = _a.fill, slowFillRequest = _a.slowFillRequest;
821
+ _a = decodeBundleDepositHash(depositHash), relayDataHash = _a.relayDataHash, index = _a.index;
822
+ _b = v3RelayHashes[relayDataHash], deposits = _b.deposits, fill = _b.fill, slowFillRequest = _b.slowFillRequest;
823
+ deposit = deposits[index];
735
824
  if (!deposit)
736
825
  throw new Error("Deposit should exist in relay hash dictionary.");
826
+ if (deposit.originChainId !== originChainId || deposit.destinationChainId !== destinationChainId) {
827
+ return [2];
828
+ }
829
+ isDuplicateDepositInBundle = bundleDepositHashes
830
+ .slice(0, currentBundleDepositHashIndex)
831
+ .some(function (_depositHash) {
832
+ var _relayDataHash = decodeBundleDepositHash(_depositHash).relayDataHash;
833
+ return _relayDataHash === relayDataHash;
834
+ });
835
+ duplicateDepositsInBundle = deposits.slice(index + 1);
737
836
  if (fill) {
738
- if (!(0, utils_1.isSlowFill)(fill) && fill.blockNumber < destinationChainBlockRange[0]) {
739
- validatedBundleV3Fills.push(tslib_1.__assign(tslib_1.__assign({}, fill), { quoteTimestamp: deposit.quoteTimestamp }));
837
+ if (!isDuplicateDepositInBundle && fill.blockNumber < destinationChainBlockRange[0]) {
838
+ duplicateDepositsInBundle.forEach(function (duplicateDeposit) {
839
+ updateExpiredDepositsV3(expiredDepositsToRefundV3, duplicateDeposit);
840
+ });
841
+ if (canRefundPrefills) {
842
+ if (!(0, utils_1.isSlowFill)(fill)) {
843
+ validatedBundleV3Fills.push(tslib_1.__assign(tslib_1.__assign({}, fill), { quoteTimestamp: deposit.quoteTimestamp }));
844
+ }
845
+ }
740
846
  }
741
847
  return [2];
742
848
  }
743
849
  if (slowFillRequest) {
744
- if (deposit.fillDeadline < bundleBlockTimestamps[destinationChainId][1]) {
850
+ if (_depositIsExpired(deposit)) {
745
851
  updateExpiredDepositsV3(expiredDepositsToRefundV3, deposit);
746
852
  }
747
- else if (_canCreateSlowFillLeaf(deposit) &&
748
- slowFillRequest.blockNumber < destinationChainBlockRange[0]) {
853
+ else if (!isDuplicateDepositInBundle &&
854
+ canRefundPrefills &&
855
+ slowFillRequest.blockNumber < destinationChainBlockRange[0] &&
856
+ _canCreateSlowFillLeaf(deposit)) {
749
857
  validatedBundleSlowFills.push(deposit);
750
858
  }
751
859
  return [2];
752
860
  }
753
861
  return [4, _getFillStatusForDeposit(deposit, destinationChainBlockRange[1])];
754
862
  case 1:
755
- fillStatus = _b.sent();
756
- if (!(fillStatus === interfaces_1.FillStatus.Filled)) return [3, 3];
757
- return [4, (0, utils_1.findFillEvent)(destinationClient.spokePool, deposit, destinationClient.deploymentBlock, destinationClient.latestBlockSearched)];
863
+ fillStatus = _c.sent();
864
+ if (!(fillStatus === interfaces_1.FillStatus.Filled)) return [3, 5];
865
+ return [4, this.findMatchingFillEvent(deposit, destinationClient)];
758
866
  case 2:
759
- prefill = (_b.sent());
760
- if (!(0, utils_1.isSlowFill)(prefill)) {
761
- validatedBundleV3Fills.push(tslib_1.__assign(tslib_1.__assign({}, prefill), { quoteTimestamp: deposit.quoteTimestamp }));
762
- }
763
- return [3, 4];
867
+ prefill = _c.sent();
868
+ (0, utils_1.assert)((0, utils_1.isDefined)(prefill), "findFillEvent# Cannot find prefill: ".concat(relayDataHash));
869
+ (0, utils_1.assert)(this.getRelayHashFromEvent(prefill) === relayDataHash, "Relay hashes should match.");
870
+ if (!!isDuplicateDepositInBundle) return [3, 4];
871
+ duplicateDepositsInBundle.forEach(function (duplicateDeposit) {
872
+ updateExpiredDepositsV3(expiredDepositsToRefundV3, duplicateDeposit);
873
+ });
874
+ return [4, (0, utils_2.verifyFillRepayment)(prefill, destinationClient.spokePool.provider, deposit, allChainIds)];
764
875
  case 3:
765
- if (deposit.fillDeadline < bundleBlockTimestamps[destinationChainId][1]) {
876
+ verifiedFill = _c.sent();
877
+ if (canRefundPrefills && (0, utils_1.isDefined)(verifiedFill) && !(0, utils_1.isSlowFill)(verifiedFill)) {
878
+ validatedBundleV3Fills.push(tslib_1.__assign(tslib_1.__assign({}, verifiedFill), { quoteTimestamp: deposit.quoteTimestamp }));
879
+ }
880
+ _c.label = 4;
881
+ case 4: return [3, 6];
882
+ case 5:
883
+ if (_depositIsExpired(deposit)) {
766
884
  updateExpiredDepositsV3(expiredDepositsToRefundV3, deposit);
767
885
  }
768
886
  else if (fillStatus === interfaces_1.FillStatus.RequestedSlowFill) {
769
- if (_canCreateSlowFillLeaf(deposit)) {
887
+ if (!isDuplicateDepositInBundle && canRefundPrefills && _canCreateSlowFillLeaf(deposit)) {
770
888
  validatedBundleSlowFills.push(deposit);
771
889
  }
772
890
  }
773
- _b.label = 4;
774
- case 4: return [2];
891
+ _c.label = 6;
892
+ case 6: return [2];
775
893
  }
776
894
  });
777
895
  }); })];
778
896
  case 3:
779
897
  _g.sent();
780
898
  fastFillsReplacingSlowFills.forEach(function (relayDataHash) {
781
- var _a = v3RelayHashes[relayDataHash], deposit = _a.deposit, slowFillRequest = _a.slowFillRequest, fill = _a.fill;
899
+ var _a = v3RelayHashes[relayDataHash], deposits = _a.deposits, slowFillRequest = _a.slowFillRequest, fill = _a.fill;
782
900
  (0, utils_1.assert)((fill === null || fill === void 0 ? void 0 : fill.relayExecutionInfo.fillType) === interfaces_1.FillType.ReplacedSlowFill, "Fill type should be ReplacedSlowFill.");
783
- if (!deposit) {
901
+ if (!deposits || deposits.length < 1) {
784
902
  throw new Error("Deposit should exist in relay hash dictionary.");
785
903
  }
786
- (0, utils_1.assert)(!deposit.fromLiteChain && !deposit.toLiteChain, "fastFillsReplacingSlowFills should not contain lite chain deposits");
904
+ (0, utils_1.assert)(_canCreateSlowFillLeaf(deposits[0]), "fastFillsReplacingSlowFills should contain only deposits that can be slow filled");
787
905
  var destinationBlockRange = (0, utils_1.getBlockRangeForChain)(blockRangesForChains, destinationChainId, chainIds);
788
- if (_this.clients.hubPoolClient.areTokensEquivalent(deposit.inputToken, deposit.originChainId, deposit.outputToken, deposit.destinationChainId, deposit.quoteBlockNumber) &&
789
- (!slowFillRequest || slowFillRequest.blockNumber < destinationBlockRange[0])) {
790
- validatedBundleUnexecutableSlowFills.push(deposit);
906
+ if (!slowFillRequest ||
907
+ slowFillRequest.blockNumber < destinationBlockRange[0]) {
908
+ validatedBundleUnexecutableSlowFills.push(deposits[0]);
791
909
  }
792
910
  });
793
911
  return [2];
@@ -828,34 +946,37 @@ var BundleDataClient = (function () {
828
946
  message: "Processed ".concat(fillCounter, " fills in ").concat(performance.now() - start, "ms."),
829
947
  });
830
948
  start = performance.now();
831
- return [4, (0, utils_1.forEachAsync)(olderDepositHashes, function (relayDataHash) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
832
- var _a, deposit, slowFillRequest, fill, destinationChainId, destinationBlockRange, fillStatus;
833
- return tslib_1.__generator(this, function (_b) {
834
- switch (_b.label) {
949
+ return [4, (0, utils_1.forEachAsync)(olderDepositHashes, function (depositHash) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
950
+ var _a, relayDataHash, index, _b, deposits, slowFillRequest, fill, deposit, destinationChainId, destinationBlockRange, fillStatus;
951
+ return tslib_1.__generator(this, function (_c) {
952
+ switch (_c.label) {
835
953
  case 0:
836
- _a = v3RelayHashes[relayDataHash], deposit = _a.deposit, slowFillRequest = _a.slowFillRequest, fill = _a.fill;
837
- (0, utils_1.assert)((0, utils_1.isDefined)(deposit), "Deposit should exist in relay hash dictionary.");
954
+ _a = decodeBundleDepositHash(depositHash), relayDataHash = _a.relayDataHash, index = _a.index;
955
+ _b = v3RelayHashes[relayDataHash], deposits = _b.deposits, slowFillRequest = _b.slowFillRequest, fill = _b.fill;
956
+ if (!deposits || deposits.length < 1) {
957
+ throw new Error("Deposit should exist in relay hash dictionary.");
958
+ }
959
+ deposit = deposits[index];
838
960
  destinationChainId = deposit.destinationChainId;
839
961
  destinationBlockRange = (0, utils_1.getBlockRangeForChain)(blockRangesForChains, destinationChainId, chainIds);
840
962
  if (!(!fill &&
841
963
  (0, utils_1.isDefined)(deposit) &&
842
- deposit.fillDeadline < bundleBlockTimestamps[destinationChainId][1] &&
964
+ _depositIsExpired(deposit) &&
843
965
  deposit.fillDeadline >= bundleBlockTimestamps[destinationChainId][0] &&
844
966
  spokePoolClients[destinationChainId] !== undefined)) return [3, 2];
845
967
  return [4, _getFillStatusForDeposit(deposit, destinationBlockRange[1])];
846
968
  case 1:
847
- fillStatus = _b.sent();
969
+ fillStatus = _c.sent();
848
970
  if (fillStatus !== interfaces_1.FillStatus.Filled) {
849
971
  updateExpiredDepositsV3(expiredDepositsToRefundV3, deposit);
850
972
  }
851
- if (fillStatus !== interfaces_1.FillStatus.RequestedSlowFill || deposit.fromLiteChain || deposit.toLiteChain) {
973
+ if (fillStatus !== interfaces_1.FillStatus.RequestedSlowFill || !_canCreateSlowFillLeaf(deposit)) {
852
974
  return [2];
853
975
  }
854
- if (this.clients.hubPoolClient.areTokensEquivalent(deposit.inputToken, deposit.originChainId, deposit.outputToken, deposit.destinationChainId, deposit.quoteBlockNumber) &&
855
- (!slowFillRequest || slowFillRequest.blockNumber < destinationBlockRange[0])) {
976
+ if (!slowFillRequest || slowFillRequest.blockNumber < destinationBlockRange[0]) {
856
977
  validatedBundleUnexecutableSlowFills.push(deposit);
857
978
  }
858
- _b.label = 2;
979
+ _c.label = 2;
859
980
  case 2: return [2];
860
981
  }
861
982
  });
@@ -866,7 +987,7 @@ var BundleDataClient = (function () {
866
987
  promises = [
867
988
  validatedBundleV3Fills.length > 0
868
989
  ? this.clients.hubPoolClient.batchComputeRealizedLpFeePct(validatedBundleV3Fills.map(function (fill) {
869
- var matchedDeposit = v3RelayHashes[_this.getRelayHashFromEvent(fill)].deposit;
990
+ var matchedDeposit = v3RelayHashes[_this.getRelayHashFromEvent(fill)].deposits[0];
870
991
  (0, utils_1.assert)((0, utils_1.isDefined)(matchedDeposit), "Deposit should exist in relay hash dictionary.");
871
992
  var paymentChainId = (0, utils_2.getRefundInformationFromFill)(fill, _this.clients.hubPoolClient, blockRangesForChains, chainIds, matchedDeposit.fromLiteChain).chainToSendRefundTo;
872
993
  return tslib_1.__assign(tslib_1.__assign({}, fill), { paymentChainId: paymentChainId });
@@ -893,10 +1014,10 @@ var BundleDataClient = (function () {
893
1014
  v3FillLpFees.forEach(function (_a, idx) {
894
1015
  var realizedLpFeePct = _a.realizedLpFeePct;
895
1016
  var fill = validatedBundleV3Fills[idx];
896
- var associatedDeposit = v3RelayHashes[_this.getRelayHashFromEvent(fill)].deposit;
1017
+ var associatedDeposit = v3RelayHashes[_this.getRelayHashFromEvent(fill)].deposits[0];
897
1018
  (0, utils_1.assert)((0, utils_1.isDefined)(associatedDeposit), "Deposit should exist in relay hash dictionary.");
898
1019
  var _b = (0, utils_2.getRefundInformationFromFill)(fill, _this.clients.hubPoolClient, blockRangesForChains, chainIds, associatedDeposit.fromLiteChain), chainToSendRefundTo = _b.chainToSendRefundTo, repaymentToken = _b.repaymentToken;
899
- updateBundleFillsV3(bundleFillsV3, fill, realizedLpFeePct, chainToSendRefundTo, repaymentToken);
1020
+ updateBundleFillsV3(bundleFillsV3, fill, realizedLpFeePct, chainToSendRefundTo, repaymentToken, fill.relayer);
900
1021
  });
901
1022
  v3SlowFillLpFees.forEach(function (_a, idx) {
902
1023
  var lpFeePct = _a.realizedLpFeePct;
@@ -908,7 +1029,7 @@ var BundleDataClient = (function () {
908
1029
  var deposit = validatedBundleUnexecutableSlowFills[idx];
909
1030
  updateBundleExcessSlowFills(unexecutableSlowFills, tslib_1.__assign(tslib_1.__assign({}, deposit), { lpFeePct: lpFeePct }));
910
1031
  });
911
- v3SpokeEventsReadable = (0, utils_2.prettyPrintV3SpokePoolEvents)(bundleDepositsV3, bundleFillsV3, bundleInvalidFillsV3, bundleSlowFillsV3, expiredDepositsToRefundV3, unexecutableSlowFills);
1032
+ v3SpokeEventsReadable = (0, utils_2.prettyPrintV3SpokePoolEvents)(bundleDepositsV3, bundleFillsV3, bundleSlowFillsV3, expiredDepositsToRefundV3, unexecutableSlowFills);
912
1033
  if (bundleInvalidFillsV3.length > 0) {
913
1034
  this.logger.debug({
914
1035
  at: "BundleDataClient#loadData",
@@ -917,6 +1038,14 @@ var BundleDataClient = (function () {
917
1038
  bundleInvalidFillsV3: bundleInvalidFillsV3,
918
1039
  });
919
1040
  }
1041
+ if (bundleUnrepayableFillsV3.length > 0) {
1042
+ this.logger.debug({
1043
+ at: "BundleDataClient#loadData",
1044
+ message: "Finished loading V3 spoke pool data and found some unrepayable V3 fills in range",
1045
+ blockRangesForChains: blockRangesForChains,
1046
+ bundleUnrepayableFillsV3: bundleUnrepayableFillsV3,
1047
+ });
1048
+ }
920
1049
  this.logger.debug({
921
1050
  at: "BundleDataClient#loadDataFromScratch",
922
1051
  message: "Computed bundle data in ".concat(Math.round(performance.now() - start) / 1000, "s."),
@@ -935,7 +1064,17 @@ var BundleDataClient = (function () {
935
1064
  });
936
1065
  };
937
1066
  BundleDataClient.prototype.getRelayHashFromEvent = function (event) {
938
- return "".concat(event.depositor, "-").concat(event.recipient, "-").concat(event.exclusiveRelayer, "-").concat(event.inputToken, "-").concat(event.outputToken, "-").concat(event.inputAmount, "-").concat(event.outputAmount, "-").concat(event.originChainId, "-").concat(event.depositId, "-").concat(event.fillDeadline, "-").concat(event.exclusivityDeadline, "-").concat(event.message, "-").concat(event.destinationChainId);
1067
+ return "".concat(event.depositor, "-").concat(event.recipient, "-").concat(event.exclusiveRelayer, "-").concat(event.inputToken, "-").concat(event.outputToken, "-").concat(event.inputAmount, "-").concat(event.outputAmount, "-").concat(event.originChainId, "-").concat(event.depositId.toString(), "-").concat(event.fillDeadline, "-").concat(event.exclusivityDeadline, "-").concat(event.message, "-").concat(event.destinationChainId);
1068
+ };
1069
+ BundleDataClient.prototype.findMatchingFillEvent = function (deposit, spokePoolClient) {
1070
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
1071
+ return tslib_1.__generator(this, function (_a) {
1072
+ switch (_a.label) {
1073
+ case 0: return [4, (0, utils_1.findFillEvent)(spokePoolClient.spokePool, deposit, spokePoolClient.deploymentBlock, spokePoolClient.latestBlockSearched)];
1074
+ case 1: return [2, _a.sent()];
1075
+ }
1076
+ });
1077
+ });
939
1078
  };
940
1079
  BundleDataClient.prototype.getBundleBlockTimestamps = function (chainIds, blockRangesForChains, spokePoolClients) {
941
1080
  return tslib_1.__awaiter(this, void 0, void 0, function () {
@@ -946,7 +1085,7 @@ var BundleDataClient = (function () {
946
1085
  case 0:
947
1086
  _b = (_a = Object).fromEntries;
948
1087
  return [4, (0, utils_1.mapAsync)(chainIds, function (chainId, index) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
949
- var blockRangeForChain, _startBlockForChain, _endBlockForChain, spokePoolClient, startBlockForChain, endBlockForChain, _a, startTime, endTime, _b;
1088
+ var blockRangeForChain, _startBlockForChain, _endBlockForChain, spokePoolClient, startBlockForChain, endBlockForChain, _a, startTime, _endTime, _b, endBlockDelta, endTime;
950
1089
  return tslib_1.__generator(this, function (_c) {
951
1090
  switch (_c.label) {
952
1091
  case 0:
@@ -960,7 +1099,7 @@ var BundleDataClient = (function () {
960
1099
  return [2];
961
1100
  }
962
1101
  startBlockForChain = Math.min(_startBlockForChain, spokePoolClient.latestBlockSearched);
963
- endBlockForChain = Math.min(_endBlockForChain, spokePoolClient.latestBlockSearched);
1102
+ endBlockForChain = Math.min(_endBlockForChain + 1, spokePoolClient.latestBlockSearched);
964
1103
  return [4, spokePoolClient.getTimestampForBlock(startBlockForChain)];
965
1104
  case 1:
966
1105
  _b = [
@@ -970,8 +1109,10 @@ var BundleDataClient = (function () {
970
1109
  case 2:
971
1110
  _a = _b.concat([
972
1111
  _c.sent()
973
- ]), startTime = _a[0], endTime = _a[1];
974
- (0, utils_1.assert)(endTime >= startTime, "End time should be greater than start time.");
1112
+ ]), startTime = _a[0], _endTime = _a[1];
1113
+ endBlockDelta = endBlockForChain > startBlockForChain ? 1 : 0;
1114
+ endTime = Math.max(0, _endTime - endBlockDelta);
1115
+ (0, utils_1.assert)(endTime >= startTime, "End time for block ".concat(endBlockForChain, " should be greater than start time for block ").concat(startBlockForChain, ": ").concat(endTime, " >= ").concat(startTime, "."));
975
1116
  (0, utils_1.assert)(startBlockForChain === 0 || startTime > 0, "Start timestamp must be greater than 0 if the start block is greater than 0.");
976
1117
  return [2, [chainId, [startTime, endTime]]];
977
1118
  }