@across-protocol/sdk 4.0.0-beta.3 → 4.0.0-beta.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/clients/BundleDataClient/BundleDataClient.d.ts +5 -4
- package/dist/cjs/clients/BundleDataClient/BundleDataClient.js +336 -174
- package/dist/cjs/clients/BundleDataClient/BundleDataClient.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.d.ts +1 -2
- package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.js +1 -2
- package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/FillUtils.d.ts +5 -1
- package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js +47 -1
- package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.d.ts +4 -4
- package/dist/cjs/clients/SpokePoolClient.d.ts +1 -0
- package/dist/cjs/clients/SpokePoolClient.js +13 -4
- package/dist/cjs/clients/SpokePoolClient.js.map +1 -1
- package/dist/cjs/clients/mocks/MockSpokePoolClient.d.ts +2 -1
- package/dist/cjs/clients/mocks/MockSpokePoolClient.js +11 -0
- package/dist/cjs/clients/mocks/MockSpokePoolClient.js.map +1 -1
- package/dist/cjs/constants.d.ts +1 -1
- package/dist/cjs/constants.js +2 -2
- package/dist/cjs/constants.js.map +1 -1
- package/dist/cjs/providers/index.d.ts +1 -0
- package/dist/cjs/providers/index.js +2 -0
- package/dist/cjs/providers/index.js.map +1 -1
- package/dist/cjs/providers/mockProvider.d.ts +19 -0
- package/dist/cjs/providers/mockProvider.js +70 -0
- package/dist/cjs/providers/mockProvider.js.map +1 -0
- package/dist/cjs/utils/AddressUtils.d.ts +2 -0
- package/dist/cjs/utils/AddressUtils.js +19 -1
- package/dist/cjs/utils/AddressUtils.js.map +1 -1
- package/dist/cjs/utils/CachingUtils.js +1 -1
- package/dist/cjs/utils/CachingUtils.js.map +1 -1
- package/dist/cjs/utils/DepositUtils.d.ts +2 -1
- package/dist/cjs/utils/DepositUtils.js +13 -4
- package/dist/cjs/utils/DepositUtils.js.map +1 -1
- package/dist/cjs/utils/EventUtils.js +21 -0
- package/dist/cjs/utils/EventUtils.js.map +1 -1
- package/dist/cjs/utils/NetworkUtils.d.ts +1 -0
- package/dist/cjs/utils/NetworkUtils.js +6 -1
- package/dist/cjs/utils/NetworkUtils.js.map +1 -1
- package/dist/cjs/utils/SpokeUtils.d.ts +1 -0
- package/dist/cjs/utils/SpokeUtils.js +18 -11
- package/dist/cjs/utils/SpokeUtils.js.map +1 -1
- package/dist/cjs/utils/common.d.ts +1 -0
- package/dist/cjs/utils/common.js +2 -1
- package/dist/cjs/utils/common.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/BundleDataClient.d.ts +5 -4
- package/dist/esm/clients/BundleDataClient/BundleDataClient.js +405 -208
- package/dist/esm/clients/BundleDataClient/BundleDataClient.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.d.ts +1 -2
- package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.js +2 -3
- package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/utils/FillUtils.d.ts +5 -1
- package/dist/esm/clients/BundleDataClient/utils/FillUtils.js +54 -1
- package/dist/esm/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.d.ts +4 -4
- package/dist/esm/clients/SpokePoolClient.d.ts +8 -0
- package/dist/esm/clients/SpokePoolClient.js +20 -4
- package/dist/esm/clients/SpokePoolClient.js.map +1 -1
- package/dist/esm/clients/mocks/MockSpokePoolClient.d.ts +2 -1
- package/dist/esm/clients/mocks/MockSpokePoolClient.js +11 -0
- package/dist/esm/clients/mocks/MockSpokePoolClient.js.map +1 -1
- package/dist/esm/constants.d.ts +1 -1
- package/dist/esm/constants.js +2 -2
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/providers/index.d.ts +1 -0
- package/dist/esm/providers/index.js +2 -0
- package/dist/esm/providers/index.js.map +1 -1
- package/dist/esm/providers/mockProvider.d.ts +23 -0
- package/dist/esm/providers/mockProvider.js +73 -0
- package/dist/esm/providers/mockProvider.js.map +1 -0
- package/dist/esm/utils/AddressUtils.d.ts +2 -0
- package/dist/esm/utils/AddressUtils.js +25 -0
- package/dist/esm/utils/AddressUtils.js.map +1 -1
- package/dist/esm/utils/CachingUtils.js +1 -1
- package/dist/esm/utils/CachingUtils.js.map +1 -1
- package/dist/esm/utils/DepositUtils.d.ts +2 -1
- package/dist/esm/utils/DepositUtils.js +14 -5
- package/dist/esm/utils/DepositUtils.js.map +1 -1
- package/dist/esm/utils/EventUtils.js +29 -1
- package/dist/esm/utils/EventUtils.js.map +1 -1
- package/dist/esm/utils/NetworkUtils.d.ts +6 -0
- package/dist/esm/utils/NetworkUtils.js +10 -0
- package/dist/esm/utils/NetworkUtils.js.map +1 -1
- package/dist/esm/utils/SpokeUtils.d.ts +1 -0
- package/dist/esm/utils/SpokeUtils.js +17 -11
- package/dist/esm/utils/SpokeUtils.js.map +1 -1
- package/dist/esm/utils/common.d.ts +1 -0
- package/dist/esm/utils/common.js +1 -0
- package/dist/esm/utils/common.js.map +1 -1
- package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts +5 -4
- package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts.map +1 -1
- package/dist/types/clients/BundleDataClient/utils/DataworkerUtils.d.ts +1 -2
- package/dist/types/clients/BundleDataClient/utils/DataworkerUtils.d.ts.map +1 -1
- package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts +5 -1
- package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts.map +1 -1
- package/dist/types/clients/BundleDataClient/utils/SuperstructUtils.d.ts +4 -4
- package/dist/types/clients/SpokePoolClient.d.ts +8 -0
- package/dist/types/clients/SpokePoolClient.d.ts.map +1 -1
- package/dist/types/clients/mocks/MockSpokePoolClient.d.ts +2 -1
- package/dist/types/clients/mocks/MockSpokePoolClient.d.ts.map +1 -1
- package/dist/types/constants.d.ts +1 -1
- package/dist/types/constants.d.ts.map +1 -1
- package/dist/types/providers/index.d.ts +1 -0
- package/dist/types/providers/index.d.ts.map +1 -1
- package/dist/types/providers/mockProvider.d.ts +24 -0
- package/dist/types/providers/mockProvider.d.ts.map +1 -0
- package/dist/types/utils/AddressUtils.d.ts +2 -0
- package/dist/types/utils/AddressUtils.d.ts.map +1 -1
- package/dist/types/utils/DepositUtils.d.ts +2 -1
- package/dist/types/utils/DepositUtils.d.ts.map +1 -1
- package/dist/types/utils/EventUtils.d.ts.map +1 -1
- package/dist/types/utils/NetworkUtils.d.ts +6 -0
- package/dist/types/utils/NetworkUtils.d.ts.map +1 -1
- package/dist/types/utils/SpokeUtils.d.ts +1 -0
- package/dist/types/utils/SpokeUtils.d.ts.map +1 -1
- package/dist/types/utils/common.d.ts +1 -0
- package/dist/types/utils/common.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/clients/BundleDataClient/BundleDataClient.ts +414 -184
- package/src/clients/BundleDataClient/utils/DataworkerUtils.ts +0 -8
- package/src/clients/BundleDataClient/utils/FillUtils.ts +66 -2
- package/src/clients/SpokePoolClient.ts +19 -6
- package/src/clients/mocks/MockSpokePoolClient.ts +14 -0
- package/src/constants.ts +3 -3
- package/src/providers/index.ts +1 -0
- package/src/providers/mockProvider.ts +77 -0
- package/src/utils/AddressUtils.ts +26 -0
- package/src/utils/CachingUtils.ts +1 -1
- package/src/utils/DepositUtils.ts +14 -5
- package/src/utils/EventUtils.ts +29 -1
- package/src/utils/NetworkUtils.ts +11 -0
- package/src/utils/SpokeUtils.ts +27 -13
- package/src/utils/common.ts +2 -0
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { __assign, __awaiter, __generator } from "tslib";
|
|
2
2
|
import _ from "lodash";
|
|
3
3
|
import { FillType, FillStatus, } from "../../interfaces";
|
|
4
|
-
import { BigNumber, bnZero, queryHistoricalDepositForFill, assign, assert, fixedPointAdjustment, isDefined, toBN, forEachAsync, getBlockRangeForChain, getImpliedBundleBlockRanges, isSlowFill, mapAsync, bnUint32Max, isZeroValueDeposit, findFillEvent, isZeroValueFillOrSlowFillRequest, } from "../../utils";
|
|
5
|
-
import { _buildPoolRebalanceRoot, BundleDataSS, getEndBlockBuffers, getRefundInformationFromFill, getRefundsFromBundle, getWidestPossibleExpectedBlockRange, isChainDisabled, prettyPrintV3SpokePoolEvents, } from "./utils";
|
|
4
|
+
import { BigNumber, bnZero, queryHistoricalDepositForFill, assign, assert, fixedPointAdjustment, isDefined, toBN, forEachAsync, getBlockRangeForChain, getImpliedBundleBlockRanges, isSlowFill, mapAsync, filterAsync, bnUint32Max, isZeroValueDeposit, findFillEvent, isZeroValueFillOrSlowFillRequest, chainIsEvm, isValidEvmAddress, } from "../../utils";
|
|
5
|
+
import { _buildPoolRebalanceRoot, BundleDataSS, getEndBlockBuffers, getRefundInformationFromFill, getRefundsFromBundle, getWidestPossibleExpectedBlockRange, isChainDisabled, isEvmRepaymentValid, prettyPrintV3SpokePoolEvents, verifyFillRepayment, } from "./utils";
|
|
6
|
+
import { PRE_FILL_MIN_CONFIG_STORE_VERSION } from "../../constants";
|
|
6
7
|
// max(uint256) - 1
|
|
7
8
|
export var INFINITE_FILL_DEADLINE = bnUint32Max;
|
|
8
9
|
// V3 dictionary helper functions
|
|
9
10
|
function updateExpiredDepositsV3(dict, deposit) {
|
|
10
11
|
var _a;
|
|
12
|
+
assert(chainIsEvm(deposit.originChainId) && isValidEvmAddress(deposit.depositor), "expired depositor cannot be refunded");
|
|
11
13
|
var originChainId = deposit.originChainId, inputToken = deposit.inputToken;
|
|
12
14
|
if (!((_a = dict === null || dict === void 0 ? void 0 : dict[originChainId]) === null || _a === void 0 ? void 0 : _a[inputToken])) {
|
|
13
15
|
assign(dict, [originChainId, inputToken], []);
|
|
@@ -22,8 +24,10 @@ function updateBundleDepositsV3(dict, deposit) {
|
|
|
22
24
|
}
|
|
23
25
|
dict[originChainId][inputToken].push(deposit);
|
|
24
26
|
}
|
|
25
|
-
function updateBundleFillsV3(dict, fill, lpFeePct, repaymentChainId, repaymentToken) {
|
|
27
|
+
function updateBundleFillsV3(dict, fill, lpFeePct, repaymentChainId, repaymentToken, repaymentAddress) {
|
|
26
28
|
var _a, _b;
|
|
29
|
+
// We shouldn't pass any unrepayable fills into this function, so we perform an extra safety check.
|
|
30
|
+
assert(chainIsEvm(repaymentChainId) && isEvmRepaymentValid(fill, repaymentChainId), "validatedBundleV3Fills dictionary should only contain fills with valid repayment information");
|
|
27
31
|
if (!((_a = dict === null || dict === void 0 ? void 0 : dict[repaymentChainId]) === null || _a === void 0 ? void 0 : _a[repaymentToken])) {
|
|
28
32
|
assign(dict, [repaymentChainId, repaymentToken], {
|
|
29
33
|
fills: [],
|
|
@@ -32,26 +36,26 @@ function updateBundleFillsV3(dict, fill, lpFeePct, repaymentChainId, repaymentTo
|
|
|
32
36
|
refunds: {},
|
|
33
37
|
});
|
|
34
38
|
}
|
|
35
|
-
var bundleFill = __assign(__assign({}, fill), { lpFeePct: lpFeePct });
|
|
39
|
+
var bundleFill = __assign(__assign({}, fill), { lpFeePct: lpFeePct, relayer: repaymentAddress });
|
|
36
40
|
// Add all fills, slow and fast, to dictionary.
|
|
37
41
|
assign(dict, [repaymentChainId, repaymentToken, "fills"], [bundleFill]);
|
|
38
42
|
// All fills update the bundle LP fees.
|
|
39
43
|
var refundObj = dict[repaymentChainId][repaymentToken];
|
|
40
|
-
var realizedLpFee =
|
|
44
|
+
var realizedLpFee = bundleFill.inputAmount.mul(bundleFill.lpFeePct).div(fixedPointAdjustment);
|
|
41
45
|
refundObj.realizedLpFees = refundObj.realizedLpFees ? refundObj.realizedLpFees.add(realizedLpFee) : realizedLpFee;
|
|
42
46
|
// Only fast fills get refunded.
|
|
43
|
-
if (!isSlowFill(
|
|
44
|
-
var refundAmount =
|
|
47
|
+
if (!isSlowFill(bundleFill)) {
|
|
48
|
+
var refundAmount = bundleFill.inputAmount.mul(fixedPointAdjustment.sub(lpFeePct)).div(fixedPointAdjustment);
|
|
45
49
|
refundObj.totalRefundAmount = refundObj.totalRefundAmount
|
|
46
50
|
? refundObj.totalRefundAmount.add(refundAmount)
|
|
47
51
|
: refundAmount;
|
|
48
52
|
// Instantiate dictionary if it doesn't exist.
|
|
49
53
|
(_b = refundObj.refunds) !== null && _b !== void 0 ? _b : (refundObj.refunds = {});
|
|
50
|
-
if (refundObj.refunds[
|
|
51
|
-
refundObj.refunds[
|
|
54
|
+
if (refundObj.refunds[bundleFill.relayer]) {
|
|
55
|
+
refundObj.refunds[bundleFill.relayer] = refundObj.refunds[bundleFill.relayer].add(refundAmount);
|
|
52
56
|
}
|
|
53
57
|
else {
|
|
54
|
-
refundObj.refunds[
|
|
58
|
+
refundObj.refunds[bundleFill.relayer] = refundAmount;
|
|
55
59
|
}
|
|
56
60
|
}
|
|
57
61
|
}
|
|
@@ -65,6 +69,7 @@ function updateBundleExcessSlowFills(dict, deposit) {
|
|
|
65
69
|
}
|
|
66
70
|
function updateBundleSlowFills(dict, deposit) {
|
|
67
71
|
var _a;
|
|
72
|
+
assert(chainIsEvm(deposit.destinationChainId) && isValidEvmAddress(deposit.recipient), "slow fill recipient cannot be paid");
|
|
68
73
|
var destinationChainId = deposit.destinationChainId, outputToken = deposit.outputToken;
|
|
69
74
|
if (!((_a = dict === null || dict === void 0 ? void 0 : dict[destinationChainId]) === null || _a === void 0 ? void 0 : _a[outputToken])) {
|
|
70
75
|
assign(dict, [destinationChainId, outputToken], []);
|
|
@@ -162,8 +167,7 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
162
167
|
at: "BundleDataClient#loadPersistedDataFromArweave",
|
|
163
168
|
message: "Loaded persisted data from Arweave in ".concat(Math.round(performance.now() - start) / 1000, "s."),
|
|
164
169
|
blockRanges: JSON.stringify(blockRangesForChains),
|
|
165
|
-
bundleData: prettyPrintV3SpokePoolEvents(bundleData.bundleDepositsV3, bundleData.bundleFillsV3,
|
|
166
|
-
bundleData.bundleSlowFillsV3, bundleData.expiredDepositsToRefundV3, bundleData.unexecutableSlowFills),
|
|
170
|
+
bundleData: prettyPrintV3SpokePoolEvents(bundleData.bundleDepositsV3, bundleData.bundleFillsV3, bundleData.bundleSlowFillsV3, bundleData.expiredDepositsToRefundV3, bundleData.unexecutableSlowFills),
|
|
167
171
|
});
|
|
168
172
|
return [2 /*return*/, bundleData];
|
|
169
173
|
}
|
|
@@ -209,77 +213,124 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
209
213
|
return [4 /*yield*/, this.loadArweaveData(bundleEvaluationBlockRanges)];
|
|
210
214
|
case 1:
|
|
211
215
|
arweaveData = _a.sent();
|
|
212
|
-
if (arweaveData === undefined)
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
216
|
+
if (!(arweaveData === undefined)) return [3 /*break*/, 3];
|
|
217
|
+
return [4 /*yield*/, this.getApproximateRefundsForBlockRange(chainIds, bundleEvaluationBlockRanges)];
|
|
218
|
+
case 2:
|
|
219
|
+
combinedRefunds = _a.sent();
|
|
220
|
+
return [3 /*break*/, 4];
|
|
221
|
+
case 3:
|
|
222
|
+
bundleFillsV3 = arweaveData.bundleFillsV3, expiredDepositsToRefundV3 = arweaveData.expiredDepositsToRefundV3;
|
|
223
|
+
combinedRefunds = getRefundsFromBundle(bundleFillsV3, expiredDepositsToRefundV3);
|
|
224
|
+
// If we don't have a spoke pool client for a chain, then we won't be able to deduct refunds correctly for this
|
|
225
|
+
// chain. For most of the pending bundle's liveness period, these past refunds are already executed so this is
|
|
226
|
+
// a reasonable assumption. This empty refund chain also matches what the alternative
|
|
227
|
+
// `getApproximateRefundsForBlockRange` would return.
|
|
228
|
+
Object.keys(combinedRefunds).forEach(function (chainId) {
|
|
229
|
+
if (_this.spokePoolClients[Number(chainId)] === undefined) {
|
|
230
|
+
delete combinedRefunds[Number(chainId)];
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
_a.label = 4;
|
|
234
|
+
case 4:
|
|
235
|
+
// The latest proposed bundle's refund leaves might have already been partially or entirely executed.
|
|
236
|
+
// We have to deduct the executed amounts from the total refund amounts.
|
|
237
|
+
return [2 /*return*/, this.deductExecutedRefunds(combinedRefunds, bundle)];
|
|
231
238
|
}
|
|
232
239
|
});
|
|
233
240
|
});
|
|
234
241
|
};
|
|
235
242
|
// @dev This helper function should probably be moved to the InventoryClient
|
|
236
243
|
BundleDataClient.prototype.getApproximateRefundsForBlockRange = function (chainIds, blockRanges) {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
244
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
245
|
+
var refundsForChain, _loop_1, this_1, _i, chainIds_1, chainId;
|
|
246
|
+
var _this = this;
|
|
247
|
+
return __generator(this, function (_a) {
|
|
248
|
+
switch (_a.label) {
|
|
249
|
+
case 0:
|
|
250
|
+
refundsForChain = {};
|
|
251
|
+
_loop_1 = function (chainId) {
|
|
252
|
+
var chainIndex, fillsToCount;
|
|
253
|
+
return __generator(this, function (_b) {
|
|
254
|
+
switch (_b.label) {
|
|
255
|
+
case 0:
|
|
256
|
+
if (this_1.spokePoolClients[chainId] === undefined) {
|
|
257
|
+
return [2 /*return*/, "continue"];
|
|
258
|
+
}
|
|
259
|
+
chainIndex = chainIds.indexOf(chainId);
|
|
260
|
+
return [4 /*yield*/, filterAsync(this_1.spokePoolClients[chainId].getFills(), function (fill) { return __awaiter(_this, void 0, void 0, function () {
|
|
261
|
+
var matchingDeposit, hasMatchingDeposit, validRepayment;
|
|
262
|
+
return __generator(this, function (_a) {
|
|
263
|
+
switch (_a.label) {
|
|
264
|
+
case 0:
|
|
265
|
+
if (fill.blockNumber < blockRanges[chainIndex][0] ||
|
|
266
|
+
fill.blockNumber > blockRanges[chainIndex][1] ||
|
|
267
|
+
isZeroValueFillOrSlowFillRequest(fill)) {
|
|
268
|
+
return [2 /*return*/, false];
|
|
269
|
+
}
|
|
270
|
+
// If origin spoke pool client isn't defined, we can't validate it.
|
|
271
|
+
if (this.spokePoolClients[fill.originChainId] === undefined) {
|
|
272
|
+
return [2 /*return*/, false];
|
|
273
|
+
}
|
|
274
|
+
matchingDeposit = this.spokePoolClients[fill.originChainId].getDeposit(fill.depositId);
|
|
275
|
+
hasMatchingDeposit = matchingDeposit !== undefined &&
|
|
276
|
+
this.getRelayHashFromEvent(fill) === this.getRelayHashFromEvent(matchingDeposit);
|
|
277
|
+
if (!hasMatchingDeposit) return [3 /*break*/, 2];
|
|
278
|
+
return [4 /*yield*/, verifyFillRepayment(fill, this.spokePoolClients[fill.destinationChainId].spokePool.provider, matchingDeposit,
|
|
279
|
+
// @dev: to get valid repayment chain ID's, get all chain IDs for the bundle block range and remove
|
|
280
|
+
// disabled block ranges.
|
|
281
|
+
this.clients.configStoreClient
|
|
282
|
+
.getChainIdIndicesForBlock(blockRanges[0][1])
|
|
283
|
+
.filter(function (_chainId, i) { return !isChainDisabled(blockRanges[i]); }))];
|
|
284
|
+
case 1:
|
|
285
|
+
validRepayment = _a.sent();
|
|
286
|
+
if (!isDefined(validRepayment)) {
|
|
287
|
+
return [2 /*return*/, false];
|
|
288
|
+
}
|
|
289
|
+
_a.label = 2;
|
|
290
|
+
case 2: return [2 /*return*/, hasMatchingDeposit];
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
}); })];
|
|
294
|
+
case 1:
|
|
295
|
+
fillsToCount = _b.sent();
|
|
296
|
+
fillsToCount.forEach(function (fill) {
|
|
297
|
+
var _a, _b, _c;
|
|
298
|
+
var _d;
|
|
299
|
+
var matchingDeposit = _this.spokePoolClients[fill.originChainId].getDeposit(fill.depositId);
|
|
300
|
+
assert(isDefined(matchingDeposit), "Deposit not found for fill.");
|
|
301
|
+
var _e = getRefundInformationFromFill(fill, _this.clients.hubPoolClient, blockRanges, _this.chainIdListForBundleEvaluationBlockNumbers, matchingDeposit.fromLiteChain // Use ! because we've already asserted that matchingDeposit is defined.
|
|
302
|
+
), chainToSendRefundTo = _e.chainToSendRefundTo, repaymentToken = _e.repaymentToken;
|
|
303
|
+
// Assume that lp fees are 0 for the sake of speed. In the future we could batch compute
|
|
304
|
+
// these or make hardcoded assumptions based on the origin-repayment chain direction. This might result
|
|
305
|
+
// in slight over estimations of refunds, but its not clear whether underestimating or overestimating is
|
|
306
|
+
// worst from the relayer's perspective.
|
|
307
|
+
var relayer = fill.relayer, refundAmount = fill.inputAmount;
|
|
308
|
+
(_a = refundsForChain[chainToSendRefundTo]) !== null && _a !== void 0 ? _a : (refundsForChain[chainToSendRefundTo] = {});
|
|
309
|
+
(_b = (_d = refundsForChain[chainToSendRefundTo])[repaymentToken]) !== null && _b !== void 0 ? _b : (_d[repaymentToken] = {});
|
|
310
|
+
var existingRefundAmount = (_c = refundsForChain[chainToSendRefundTo][repaymentToken][relayer]) !== null && _c !== void 0 ? _c : bnZero;
|
|
311
|
+
refundsForChain[chainToSendRefundTo][repaymentToken][relayer] = existingRefundAmount.add(refundAmount);
|
|
312
|
+
});
|
|
313
|
+
return [2 /*return*/];
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
};
|
|
317
|
+
this_1 = this;
|
|
318
|
+
_i = 0, chainIds_1 = chainIds;
|
|
319
|
+
_a.label = 1;
|
|
320
|
+
case 1:
|
|
321
|
+
if (!(_i < chainIds_1.length)) return [3 /*break*/, 4];
|
|
322
|
+
chainId = chainIds_1[_i];
|
|
323
|
+
return [5 /*yield**/, _loop_1(chainId)];
|
|
324
|
+
case 2:
|
|
325
|
+
_a.sent();
|
|
326
|
+
_a.label = 3;
|
|
327
|
+
case 3:
|
|
328
|
+
_i++;
|
|
329
|
+
return [3 /*break*/, 1];
|
|
330
|
+
case 4: return [2 /*return*/, refundsForChain];
|
|
253
331
|
}
|
|
254
|
-
var matchingDeposit = _this.spokePoolClients[fill.originChainId].getDeposit(fill.depositId);
|
|
255
|
-
var hasMatchingDeposit = matchingDeposit !== undefined &&
|
|
256
|
-
_this.getRelayHashFromEvent(fill) === _this.getRelayHashFromEvent(matchingDeposit);
|
|
257
|
-
return hasMatchingDeposit;
|
|
258
|
-
})
|
|
259
|
-
.forEach(function (fill) {
|
|
260
|
-
var _a, _b, _c;
|
|
261
|
-
var _d;
|
|
262
|
-
var matchingDeposit = _this.spokePoolClients[fill.originChainId].getDeposit(fill.depositId);
|
|
263
|
-
assert(isDefined(matchingDeposit), "Deposit not found for fill.");
|
|
264
|
-
var _e = getRefundInformationFromFill(fill, _this.clients.hubPoolClient, blockRanges, _this.chainIdListForBundleEvaluationBlockNumbers, matchingDeposit.fromLiteChain // Use ! because we've already asserted that matchingDeposit is defined.
|
|
265
|
-
), chainToSendRefundTo = _e.chainToSendRefundTo, repaymentToken = _e.repaymentToken;
|
|
266
|
-
// Assume that lp fees are 0 for the sake of speed. In the future we could batch compute
|
|
267
|
-
// these or make hardcoded assumptions based on the origin-repayment chain direction. This might result
|
|
268
|
-
// in slight over estimations of refunds, but its not clear whether underestimating or overestimating is
|
|
269
|
-
// worst from the relayer's perspective.
|
|
270
|
-
var relayer = fill.relayer, refundAmount = fill.inputAmount;
|
|
271
|
-
(_a = refundsForChain[chainToSendRefundTo]) !== null && _a !== void 0 ? _a : (refundsForChain[chainToSendRefundTo] = {});
|
|
272
|
-
(_b = (_d = refundsForChain[chainToSendRefundTo])[repaymentToken]) !== null && _b !== void 0 ? _b : (_d[repaymentToken] = {});
|
|
273
|
-
var existingRefundAmount = (_c = refundsForChain[chainToSendRefundTo][repaymentToken][relayer]) !== null && _c !== void 0 ? _c : bnZero;
|
|
274
|
-
refundsForChain[chainToSendRefundTo][repaymentToken][relayer] = existingRefundAmount.add(refundAmount);
|
|
275
332
|
});
|
|
276
|
-
};
|
|
277
|
-
var this_1 = this;
|
|
278
|
-
for (var _i = 0, chainIds_1 = chainIds; _i < chainIds_1.length; _i++) {
|
|
279
|
-
var chainId = chainIds_1[_i];
|
|
280
|
-
_loop_1(chainId);
|
|
281
|
-
}
|
|
282
|
-
return refundsForChain;
|
|
333
|
+
});
|
|
283
334
|
};
|
|
284
335
|
BundleDataClient.prototype.getUpcomingDepositAmount = function (chainId, l2Token, latestBlockToSearch) {
|
|
285
336
|
if (this.spokePoolClients[chainId] === undefined) {
|
|
@@ -324,12 +375,10 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
324
375
|
case 1:
|
|
325
376
|
_a = _b.sent(), bundleData = _a.bundleData, blockRanges = _a.blockRanges;
|
|
326
377
|
hubPoolClient = this.clients.hubPoolClient;
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
case 2:
|
|
332
|
-
root = _b.sent();
|
|
378
|
+
root = _buildPoolRebalanceRoot(hubPoolClient.latestBlockSearched, blockRanges[0][1], bundleData.bundleDepositsV3, bundleData.bundleFillsV3, bundleData.bundleSlowFillsV3, bundleData.unexecutableSlowFills, bundleData.expiredDepositsToRefundV3, {
|
|
379
|
+
hubPoolClient: hubPoolClient,
|
|
380
|
+
configStoreClient: hubPoolClient.configStoreClient,
|
|
381
|
+
});
|
|
333
382
|
return [2 /*return*/, {
|
|
334
383
|
root: root,
|
|
335
384
|
blockRanges: blockRanges,
|
|
@@ -371,33 +420,40 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
371
420
|
return [initialBlockRange[1] + 1, blockRange[1]];
|
|
372
421
|
});
|
|
373
422
|
}
|
|
374
|
-
var hubPoolClient, nextBundleMainnetStartBlock, chainIds, combinedRefunds, widestBundleBlockRanges, pendingBundleBlockRanges, arweaveData, bundleFillsV3, expiredDepositsToRefundV3, start;
|
|
375
|
-
return __generator(this, function (
|
|
376
|
-
switch (
|
|
423
|
+
var hubPoolClient, nextBundleMainnetStartBlock, chainIds, combinedRefunds, widestBundleBlockRanges, pendingBundleBlockRanges, arweaveData, _a, _b, bundleFillsV3, expiredDepositsToRefundV3, start, _c, _d;
|
|
424
|
+
return __generator(this, function (_e) {
|
|
425
|
+
switch (_e.label) {
|
|
377
426
|
case 0:
|
|
378
427
|
hubPoolClient = this.clients.hubPoolClient;
|
|
379
428
|
nextBundleMainnetStartBlock = hubPoolClient.getNextBundleStartBlockNumber(this.chainIdListForBundleEvaluationBlockNumbers, hubPoolClient.latestBlockSearched, hubPoolClient.chainId);
|
|
380
429
|
chainIds = this.clients.configStoreClient.getChainIdIndicesForBlock(nextBundleMainnetStartBlock);
|
|
381
430
|
combinedRefunds = [];
|
|
382
431
|
widestBundleBlockRanges = getWidestPossibleExpectedBlockRange(chainIds, this.spokePoolClients, getEndBlockBuffers(chainIds, this.blockRangeEndBlockBuffer), this.clients, this.clients.hubPoolClient.latestBlockSearched, this.clients.configStoreClient.getEnabledChains(this.clients.hubPoolClient.latestBlockSearched));
|
|
383
|
-
if (!hubPoolClient.hasPendingProposal()) return [3 /*break*/,
|
|
432
|
+
if (!hubPoolClient.hasPendingProposal()) return [3 /*break*/, 5];
|
|
384
433
|
pendingBundleBlockRanges = getImpliedBundleBlockRanges(hubPoolClient, this.clients.configStoreClient, hubPoolClient.getLatestProposedRootBundle());
|
|
385
434
|
return [4 /*yield*/, this.loadArweaveData(pendingBundleBlockRanges)];
|
|
386
435
|
case 1:
|
|
387
|
-
arweaveData =
|
|
388
|
-
if (arweaveData === undefined)
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
436
|
+
arweaveData = _e.sent();
|
|
437
|
+
if (!(arweaveData === undefined)) return [3 /*break*/, 3];
|
|
438
|
+
_b = (_a = combinedRefunds).push;
|
|
439
|
+
return [4 /*yield*/, this.getApproximateRefundsForBlockRange(chainIds, pendingBundleBlockRanges)];
|
|
440
|
+
case 2:
|
|
441
|
+
_b.apply(_a, [_e.sent()]);
|
|
442
|
+
return [3 /*break*/, 4];
|
|
443
|
+
case 3:
|
|
444
|
+
bundleFillsV3 = arweaveData.bundleFillsV3, expiredDepositsToRefundV3 = arweaveData.expiredDepositsToRefundV3;
|
|
445
|
+
combinedRefunds.push(getRefundsFromBundle(bundleFillsV3, expiredDepositsToRefundV3));
|
|
446
|
+
_e.label = 4;
|
|
447
|
+
case 4:
|
|
395
448
|
// Shorten the widestBundleBlockRanges now to not double count the pending bundle blocks.
|
|
396
449
|
widestBundleBlockRanges = getBlockRangeDelta(pendingBundleBlockRanges);
|
|
397
|
-
|
|
398
|
-
case
|
|
450
|
+
_e.label = 5;
|
|
451
|
+
case 5:
|
|
399
452
|
start = performance.now();
|
|
400
|
-
combinedRefunds.push
|
|
453
|
+
_d = (_c = combinedRefunds).push;
|
|
454
|
+
return [4 /*yield*/, this.getApproximateRefundsForBlockRange(chainIds, widestBundleBlockRanges)];
|
|
455
|
+
case 6:
|
|
456
|
+
_d.apply(_c, [_e.sent()]);
|
|
401
457
|
this.logger.debug({
|
|
402
458
|
at: "BundleDataClient#getNextBundleRefunds",
|
|
403
459
|
message: "Loading approximate refunds for next bundle in ".concat(Math.round(performance.now() - start) / 1000, "s."),
|
|
@@ -540,7 +596,7 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
540
596
|
};
|
|
541
597
|
BundleDataClient.prototype.loadDataFromScratch = function (blockRangesForChains, spokePoolClients) {
|
|
542
598
|
return __awaiter(this, void 0, void 0, function () {
|
|
543
|
-
var start, key, chainIds, bundleDepositsV3, bundleFillsV3, bundleInvalidFillsV3, bundleSlowFillsV3, expiredDepositsToRefundV3, unexecutableSlowFills, _isChainDisabled, _canCreateSlowFillLeaf, _depositIsExpired, _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;
|
|
599
|
+
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;
|
|
544
600
|
var _this = this;
|
|
545
601
|
return __generator(this, function (_c) {
|
|
546
602
|
switch (_c.label) {
|
|
@@ -560,6 +616,7 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
560
616
|
bundleDepositsV3 = {};
|
|
561
617
|
bundleFillsV3 = {};
|
|
562
618
|
bundleInvalidFillsV3 = [];
|
|
619
|
+
bundleUnrepayableFillsV3 = [];
|
|
563
620
|
bundleSlowFillsV3 = {};
|
|
564
621
|
expiredDepositsToRefundV3 = {};
|
|
565
622
|
unexecutableSlowFills = {};
|
|
@@ -617,6 +674,13 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
617
674
|
v3RelayHashes = {};
|
|
618
675
|
bundleDepositHashes = [];
|
|
619
676
|
olderDepositHashes = [];
|
|
677
|
+
decodeBundleDepositHash = function (depositHash) {
|
|
678
|
+
var _a = depositHash.split("@"), relayDataHash = _a[0], i = _a[1];
|
|
679
|
+
return { relayDataHash: relayDataHash, index: Number(i) };
|
|
680
|
+
};
|
|
681
|
+
startBlockForMainnet = getBlockRangeForChain(blockRangesForChains, this.clients.hubPoolClient.chainId, this.chainIdListForBundleEvaluationBlockNumbers)[0];
|
|
682
|
+
versionAtProposalBlock = this.clients.configStoreClient.getConfigStoreVersionForBlock(startBlockForMainnet);
|
|
683
|
+
canRefundPrefills = versionAtProposalBlock >= PRE_FILL_MIN_CONFIG_STORE_VERSION || process.env.FORCE_REFUND_PREFILLS === "true";
|
|
620
684
|
depositCounter = 0;
|
|
621
685
|
_loop_2 = function (originChainId) {
|
|
622
686
|
var originClient = spokePoolClients[originChainId];
|
|
@@ -637,11 +701,14 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
637
701
|
var relayDataHash = _this.getRelayHashFromEvent(deposit);
|
|
638
702
|
if (!v3RelayHashes[relayDataHash]) {
|
|
639
703
|
v3RelayHashes[relayDataHash] = {
|
|
640
|
-
|
|
704
|
+
deposits: [deposit],
|
|
641
705
|
fill: undefined,
|
|
642
706
|
slowFillRequest: undefined,
|
|
643
707
|
};
|
|
644
708
|
}
|
|
709
|
+
else {
|
|
710
|
+
v3RelayHashes[relayDataHash].deposits.push(deposit);
|
|
711
|
+
}
|
|
645
712
|
// Once we've saved the deposit hash into v3RelayHashes, then we can exit early here if the inputAmount
|
|
646
713
|
// is 0 because there can be no expired amount to refund and no unexecutable slow fill amount to return
|
|
647
714
|
// if this deposit did expire. Input amount can only be zero at this point if the message is non-empty,
|
|
@@ -649,12 +716,18 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
649
716
|
if (deposit.inputAmount.eq(0)) {
|
|
650
717
|
return;
|
|
651
718
|
}
|
|
719
|
+
// Evaluate all expired deposits after fetching fill statuses,
|
|
720
|
+
// since we can't know for certain whether an expired deposit was filled a long time ago.
|
|
721
|
+
var newBundleDepositHash = "".concat(relayDataHash, "@").concat(v3RelayHashes[relayDataHash].deposits.length - 1);
|
|
722
|
+
var decodedBundleDepositHash = decodeBundleDepositHash(newBundleDepositHash);
|
|
723
|
+
assert(decodedBundleDepositHash.relayDataHash === relayDataHash &&
|
|
724
|
+
decodedBundleDepositHash.index === v3RelayHashes[relayDataHash].deposits.length - 1, "Not using correct bundle deposit hash key");
|
|
652
725
|
if (deposit.blockNumber >= originChainBlockRange[0]) {
|
|
653
|
-
bundleDepositHashes.push(
|
|
726
|
+
bundleDepositHashes.push(newBundleDepositHash);
|
|
654
727
|
updateBundleDepositsV3(bundleDepositsV3, deposit);
|
|
655
728
|
}
|
|
656
729
|
else if (deposit.blockNumber < originChainBlockRange[0]) {
|
|
657
|
-
olderDepositHashes.push(
|
|
730
|
+
olderDepositHashes.push(newBundleDepositHash);
|
|
658
731
|
}
|
|
659
732
|
});
|
|
660
733
|
}
|
|
@@ -679,7 +752,7 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
679
752
|
case 0:
|
|
680
753
|
originClient = spokePoolClients[originChainId];
|
|
681
754
|
_loop_4 = function (destinationChainId) {
|
|
682
|
-
var destinationClient, destinationChainBlockRange,
|
|
755
|
+
var destinationClient, destinationChainBlockRange, originChainBlockRange, fastFillsReplacingSlowFills;
|
|
683
756
|
return __generator(this, function (_g) {
|
|
684
757
|
switch (_g.label) {
|
|
685
758
|
case 0:
|
|
@@ -688,6 +761,7 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
688
761
|
}
|
|
689
762
|
destinationClient = spokePoolClients[destinationChainId];
|
|
690
763
|
destinationChainBlockRange = getBlockRangeForChain(blockRangesForChains, destinationChainId, chainIds);
|
|
764
|
+
originChainBlockRange = getBlockRangeForChain(blockRangesForChains, originChainId, chainIds);
|
|
691
765
|
fastFillsReplacingSlowFills = [];
|
|
692
766
|
return [4 /*yield*/, forEachAsync(destinationClient
|
|
693
767
|
.getFillsForOriginChain(originChainId)
|
|
@@ -695,40 +769,64 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
695
769
|
// tokens to the filler. We can't remove non-empty message deposit here in case there is a slow fill
|
|
696
770
|
// request for the deposit, we'd want to see the fill took place.
|
|
697
771
|
.filter(function (fill) { return fill.blockNumber <= destinationChainBlockRange[1] && !isZeroValueFillOrSlowFillRequest(fill); }), function (fill) { return __awaiter(_this, void 0, void 0, function () {
|
|
698
|
-
var relayDataHash, historicalDeposit, matchedDeposit;
|
|
772
|
+
var relayDataHash, fillToRefund_1, duplicateDeposits, historicalDeposit, matchedDeposit, fillToRefund;
|
|
699
773
|
return __generator(this, function (_a) {
|
|
700
774
|
switch (_a.label) {
|
|
701
775
|
case 0:
|
|
702
|
-
relayDataHash = this.getRelayHashFromEvent(fill);
|
|
703
776
|
fillCounter++;
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
777
|
+
relayDataHash = this.getRelayHashFromEvent(fill);
|
|
778
|
+
if (!v3RelayHashes[relayDataHash]) return [3 /*break*/, 5];
|
|
779
|
+
if (!!v3RelayHashes[relayDataHash].fill) return [3 /*break*/, 3];
|
|
780
|
+
assert(isDefined(v3RelayHashes[relayDataHash].deposits) && v3RelayHashes[relayDataHash].deposits.length > 0, "Deposit should exist in relay hash dictionary.");
|
|
781
|
+
// At this point, the v3RelayHashes entry already existed meaning that there is a matching deposit,
|
|
782
|
+
// so this fill can no longer be filled on-chain.
|
|
783
|
+
v3RelayHashes[relayDataHash].fill = fill;
|
|
784
|
+
if (!(fill.blockNumber >= destinationChainBlockRange[0])) return [3 /*break*/, 2];
|
|
785
|
+
return [4 /*yield*/, verifyFillRepayment(fill, destinationClient.spokePool.provider, v3RelayHashes[relayDataHash].deposits[0], allChainIds)];
|
|
786
|
+
case 1:
|
|
787
|
+
fillToRefund_1 = _a.sent();
|
|
788
|
+
if (!isDefined(fillToRefund_1)) {
|
|
789
|
+
// We won't repay the fill but the depositor has received funds so we don't need to make a
|
|
790
|
+
// payment.
|
|
791
|
+
bundleUnrepayableFillsV3.push(fill);
|
|
792
|
+
// We don't return here yet because we still need to mark unexecutable slow fill leaves
|
|
793
|
+
// or duplicate deposits. However, we won't issue a fast fill refund.
|
|
794
|
+
}
|
|
795
|
+
else {
|
|
796
|
+
v3RelayHashes[relayDataHash].fill = fillToRefund_1;
|
|
797
|
+
validatedBundleV3Fills.push(__assign(__assign({}, fillToRefund_1), { quoteTimestamp: v3RelayHashes[relayDataHash].deposits[0].quoteTimestamp }));
|
|
798
|
+
duplicateDeposits = v3RelayHashes[relayDataHash].deposits.slice(1);
|
|
799
|
+
duplicateDeposits.forEach(function (duplicateDeposit) {
|
|
800
|
+
// If fill is a slow fill, refund deposit to depositor, otherwise refund to filler.
|
|
801
|
+
if (isSlowFill(fill)) {
|
|
802
|
+
updateExpiredDepositsV3(expiredDepositsToRefundV3, duplicateDeposit);
|
|
720
803
|
}
|
|
721
|
-
|
|
722
|
-
|
|
804
|
+
else {
|
|
805
|
+
validatedBundleV3Fills.push(__assign(__assign({}, fillToRefund_1), { quoteTimestamp: duplicateDeposit.quoteTimestamp }));
|
|
806
|
+
}
|
|
807
|
+
});
|
|
808
|
+
}
|
|
809
|
+
// If fill replaced a slow fill request, then mark it as one that might have created an
|
|
810
|
+
// unexecutable slow fill. We can't know for sure until we check the slow fill request
|
|
811
|
+
// events.
|
|
812
|
+
// slow fill requests for deposits from or to lite chains are considered invalid
|
|
813
|
+
if (fill.relayExecutionInfo.fillType === FillType.ReplacedSlowFill &&
|
|
814
|
+
_canCreateSlowFillLeaf(v3RelayHashes[relayDataHash].deposits[0])) {
|
|
815
|
+
fastFillsReplacingSlowFills.push(relayDataHash);
|
|
723
816
|
}
|
|
817
|
+
_a.label = 2;
|
|
818
|
+
case 2: return [3 /*break*/, 4];
|
|
819
|
+
case 3: throw new Error("Duplicate fill detected");
|
|
820
|
+
case 4: return [2 /*return*/];
|
|
821
|
+
case 5:
|
|
724
822
|
// At this point, there is no relay hash dictionary entry for this fill, so we need to
|
|
725
|
-
// instantiate the entry.
|
|
823
|
+
// instantiate the entry. We won't modify the fill.relayer until we match it with a deposit.
|
|
726
824
|
v3RelayHashes[relayDataHash] = {
|
|
727
|
-
|
|
825
|
+
deposits: undefined,
|
|
728
826
|
fill: fill,
|
|
729
827
|
slowFillRequest: undefined,
|
|
730
828
|
};
|
|
731
|
-
if (!(fill.blockNumber >= destinationChainBlockRange[0])) return [3 /*break*/,
|
|
829
|
+
if (!(fill.blockNumber >= destinationChainBlockRange[0])) return [3 /*break*/, 9];
|
|
732
830
|
// Fill has a non-infinite expiry, and we can assume our spoke pool clients have old enough deposits
|
|
733
831
|
// to conclude that this fill is invalid if we haven't found a matching deposit in memory, so
|
|
734
832
|
// skip the historical query.
|
|
@@ -737,28 +835,46 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
737
835
|
return [2 /*return*/];
|
|
738
836
|
}
|
|
739
837
|
return [4 /*yield*/, queryHistoricalDepositForFill(originClient, fill)];
|
|
740
|
-
case
|
|
838
|
+
case 6:
|
|
741
839
|
historicalDeposit = _a.sent();
|
|
742
|
-
if (
|
|
840
|
+
if (!!historicalDeposit.found) return [3 /*break*/, 7];
|
|
841
|
+
bundleInvalidFillsV3.push(fill);
|
|
842
|
+
return [3 /*break*/, 9];
|
|
843
|
+
case 7:
|
|
844
|
+
matchedDeposit = historicalDeposit.deposit;
|
|
845
|
+
// If deposit is in a following bundle, then this fill will have to be refunded once that deposit
|
|
846
|
+
// is in the current bundle.
|
|
847
|
+
if (matchedDeposit.blockNumber > originChainBlockRange[1]) {
|
|
743
848
|
bundleInvalidFillsV3.push(fill);
|
|
849
|
+
return [2 /*return*/];
|
|
850
|
+
}
|
|
851
|
+
v3RelayHashes[relayDataHash].deposits = [matchedDeposit];
|
|
852
|
+
return [4 /*yield*/, verifyFillRepayment(fill, destinationClient.spokePool.provider, matchedDeposit, allChainIds)];
|
|
853
|
+
case 8:
|
|
854
|
+
fillToRefund = _a.sent();
|
|
855
|
+
if (!isDefined(fillToRefund)) {
|
|
856
|
+
bundleUnrepayableFillsV3.push(fill);
|
|
857
|
+
// Don't return yet as we still need to mark down any unexecutable slow fill leaves
|
|
858
|
+
// in case this fast fill replaced a slow fill request.
|
|
744
859
|
}
|
|
745
860
|
else {
|
|
746
|
-
matchedDeposit = historicalDeposit.deposit;
|
|
747
861
|
// @dev Since queryHistoricalDepositForFill validates the fill by checking individual
|
|
748
862
|
// object property values against the deposit's, we
|
|
749
863
|
// sanity check it here by comparing the full relay hashes. If there's an error here then the
|
|
750
864
|
// historical deposit query is not working as expected.
|
|
751
865
|
assert(this.getRelayHashFromEvent(matchedDeposit) === relayDataHash, "Relay hashes should match.");
|
|
752
|
-
validatedBundleV3Fills.push(__assign(__assign({},
|
|
753
|
-
v3RelayHashes[relayDataHash].
|
|
754
|
-
//
|
|
755
|
-
|
|
756
|
-
_canCreateSlowFillLeaf(matchedDeposit)) {
|
|
757
|
-
fastFillsReplacingSlowFills.push(relayDataHash);
|
|
758
|
-
}
|
|
866
|
+
validatedBundleV3Fills.push(__assign(__assign({}, fillToRefund), { quoteTimestamp: matchedDeposit.quoteTimestamp }));
|
|
867
|
+
v3RelayHashes[relayDataHash].fill = fillToRefund;
|
|
868
|
+
// No need to check for duplicate deposits here since duplicate deposits with
|
|
869
|
+
// infinite deadlines are impossible to send via unsafeDeposit().
|
|
759
870
|
}
|
|
760
|
-
|
|
761
|
-
|
|
871
|
+
// slow fill requests for deposits from or to lite chains are considered invalid
|
|
872
|
+
if (fill.relayExecutionInfo.fillType === FillType.ReplacedSlowFill &&
|
|
873
|
+
_canCreateSlowFillLeaf(matchedDeposit)) {
|
|
874
|
+
fastFillsReplacingSlowFills.push(relayDataHash);
|
|
875
|
+
}
|
|
876
|
+
_a.label = 9;
|
|
877
|
+
case 9: return [2 /*return*/];
|
|
762
878
|
}
|
|
763
879
|
});
|
|
764
880
|
}); })];
|
|
@@ -783,11 +899,13 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
783
899
|
v3RelayHashes[relayDataHash].slowFillRequest = slowFillRequest;
|
|
784
900
|
if (v3RelayHashes[relayDataHash].fill) {
|
|
785
901
|
// If there is a fill matching the relay hash, then this slow fill request can't be used
|
|
786
|
-
// to create a slow fill for a filled deposit.
|
|
902
|
+
// to create a slow fill for a filled deposit. This takes advantage of the fact that
|
|
903
|
+
// slow fill requests must precede fills, so if there is a matching fill for this request's
|
|
904
|
+
// relay data, then this slow fill will be unexecutable.
|
|
787
905
|
return [2 /*return*/];
|
|
788
906
|
}
|
|
789
|
-
assert(isDefined(v3RelayHashes[relayDataHash].
|
|
790
|
-
matchedDeposit = v3RelayHashes[relayDataHash].
|
|
907
|
+
assert(isDefined(v3RelayHashes[relayDataHash].deposits) && v3RelayHashes[relayDataHash].deposits.length > 0, "Deposit should exist in relay hash dictionary.");
|
|
908
|
+
matchedDeposit = v3RelayHashes[relayDataHash].deposits[0];
|
|
791
909
|
// If there is no fill matching the relay hash, then this might be a valid slow fill request
|
|
792
910
|
// that we should produce a slow fill leaf for. Check if the slow fill request is in the
|
|
793
911
|
// destination chain block range.
|
|
@@ -800,16 +918,19 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
800
918
|
validatedBundleSlowFills.push(matchedDeposit);
|
|
801
919
|
}
|
|
802
920
|
}
|
|
921
|
+
else {
|
|
922
|
+
throw new Error("Duplicate slow fill request detected.");
|
|
923
|
+
}
|
|
803
924
|
return [2 /*return*/];
|
|
804
925
|
}
|
|
805
926
|
// Instantiate dictionary if there is neither a deposit nor fill matching it.
|
|
806
927
|
v3RelayHashes[relayDataHash] = {
|
|
807
|
-
|
|
928
|
+
deposits: undefined,
|
|
808
929
|
fill: undefined,
|
|
809
930
|
slowFillRequest: slowFillRequest,
|
|
810
931
|
};
|
|
811
|
-
if (!(slowFillRequest.
|
|
812
|
-
|
|
932
|
+
if (!(INFINITE_FILL_DEADLINE.eq(slowFillRequest.fillDeadline) &&
|
|
933
|
+
slowFillRequest.blockNumber >= destinationChainBlockRange[0])) return [3 /*break*/, 2];
|
|
813
934
|
return [4 /*yield*/, queryHistoricalDepositForFill(originClient, slowFillRequest)];
|
|
814
935
|
case 1:
|
|
815
936
|
historicalDeposit = _a.sent();
|
|
@@ -818,12 +939,17 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
818
939
|
return [2 /*return*/];
|
|
819
940
|
}
|
|
820
941
|
matchedDeposit = historicalDeposit.deposit;
|
|
942
|
+
// If deposit is in a following bundle, then this slow fill request will have to be created
|
|
943
|
+
// once that deposit is in the current bundle.
|
|
944
|
+
if (matchedDeposit.blockNumber > originChainBlockRange[1]) {
|
|
945
|
+
return [2 /*return*/];
|
|
946
|
+
}
|
|
821
947
|
// @dev Since queryHistoricalDepositForFill validates the slow fill request by checking individual
|
|
822
948
|
// object property values against the deposit's, we
|
|
823
949
|
// sanity check it here by comparing the full relay hashes. If there's an error here then the
|
|
824
950
|
// historical deposit query is not working as expected.
|
|
825
951
|
assert(this.getRelayHashFromEvent(matchedDeposit) === relayDataHash, "Deposit relay hashes should match.");
|
|
826
|
-
v3RelayHashes[relayDataHash].
|
|
952
|
+
v3RelayHashes[relayDataHash].deposits = [matchedDeposit];
|
|
827
953
|
if (!_canCreateSlowFillLeaf(matchedDeposit) ||
|
|
828
954
|
// Deposit must not have expired in this bundle.
|
|
829
955
|
_depositIsExpired(matchedDeposit)) {
|
|
@@ -839,39 +965,53 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
839
965
|
// Process slow fill requests. One invariant we need to maintain is that we cannot create slow fill requests
|
|
840
966
|
// for deposits that would expire in this bundle.
|
|
841
967
|
_g.sent();
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
switch (_b.label) {
|
|
968
|
+
// Deposits can be submitted an arbitrary amount of time after matching fills and slow fill requests.
|
|
969
|
+
// Therefore, let's go through each deposit in this bundle again and check a few things in order:
|
|
970
|
+
// - Has the deposit been filled ? If so, then we need to issue a relayer refund for
|
|
971
|
+
// this "pre-fill" if the fill took place in a previous bundle.
|
|
972
|
+
// - Or, has the deposit expired in this bundle? If so, then we need to issue an expiry refund.
|
|
973
|
+
// - And finally, has the deposit been slow filled? If so, then we need to issue a slow fill leaf
|
|
974
|
+
// for this "pre-slow-fill-request" if this request took place in a previous bundle.
|
|
975
|
+
return [4 /*yield*/, mapAsync(bundleDepositHashes, function (depositHash) { return __awaiter(_this, void 0, void 0, function () {
|
|
976
|
+
var _a, relayDataHash, index, _b, deposits, fill, slowFillRequest, deposit, fillToRefund, fillStatus, prefill, verifiedFill;
|
|
977
|
+
var _this = this;
|
|
978
|
+
return __generator(this, function (_c) {
|
|
979
|
+
switch (_c.label) {
|
|
855
980
|
case 0:
|
|
856
|
-
_a =
|
|
981
|
+
_a = decodeBundleDepositHash(depositHash), relayDataHash = _a.relayDataHash, index = _a.index;
|
|
982
|
+
_b = v3RelayHashes[relayDataHash], deposits = _b.deposits, fill = _b.fill, slowFillRequest = _b.slowFillRequest;
|
|
983
|
+
if (!deposits || deposits.length === 0) {
|
|
984
|
+
throw new Error("Deposits should exist in relay hash dictionary.");
|
|
985
|
+
}
|
|
986
|
+
deposit = deposits[index];
|
|
857
987
|
if (!deposit)
|
|
858
988
|
throw new Error("Deposit should exist in relay hash dictionary.");
|
|
859
|
-
|
|
860
|
-
// This is because a duplicate deposit for a pre-fill cannot get
|
|
861
|
-
// refunded to the depositor anymore because its fill status on-chain has changed to Filled. Therefore
|
|
862
|
-
// any duplicate deposits result in a net loss of funds for the depositor and effectively pay out
|
|
863
|
-
// the pre-filler.
|
|
864
|
-
// If fill exists in memory, then the only case in which we need to create a refund is if the
|
|
865
|
-
// the fill occurred in a previous bundle. There are no expiry refunds for filled deposits.
|
|
866
|
-
if (fill) {
|
|
867
|
-
if (fill.blockNumber < destinationChainBlockRange[0] && !isSlowFill(fill)) {
|
|
868
|
-
// If fill is in the current bundle then we can assume there is already a refund for it, so only
|
|
869
|
-
// include this pre fill if the fill is in an older bundle. If fill is after this current bundle, then
|
|
870
|
-
// we won't consider it, following the previous treatment of fills after the bundle block range.
|
|
871
|
-
validatedBundleV3Fills.push(__assign(__assign({}, fill), { quoteTimestamp: deposit.quoteTimestamp }));
|
|
872
|
-
}
|
|
989
|
+
if (deposit.originChainId !== originChainId || deposit.destinationChainId !== destinationChainId) {
|
|
873
990
|
return [2 /*return*/];
|
|
874
991
|
}
|
|
992
|
+
if (!fill) return [3 /*break*/, 4];
|
|
993
|
+
if (!(canRefundPrefills && fill.blockNumber < destinationChainBlockRange[0])) return [3 /*break*/, 3];
|
|
994
|
+
if (!!isSlowFill(fill)) return [3 /*break*/, 2];
|
|
995
|
+
return [4 /*yield*/, verifyFillRepayment(fill, destinationClient.spokePool.provider, v3RelayHashes[relayDataHash].deposits[0], allChainIds)];
|
|
996
|
+
case 1:
|
|
997
|
+
fillToRefund = _c.sent();
|
|
998
|
+
if (!isDefined(fillToRefund)) {
|
|
999
|
+
// We won't repay the fill but the depositor has received funds so we don't need to make a
|
|
1000
|
+
// payment.
|
|
1001
|
+
bundleUnrepayableFillsV3.push(fill);
|
|
1002
|
+
}
|
|
1003
|
+
else {
|
|
1004
|
+
v3RelayHashes[relayDataHash].fill = fillToRefund;
|
|
1005
|
+
validatedBundleV3Fills.push(__assign(__assign({}, fillToRefund), { quoteTimestamp: deposit.quoteTimestamp }));
|
|
1006
|
+
}
|
|
1007
|
+
return [3 /*break*/, 3];
|
|
1008
|
+
case 2:
|
|
1009
|
+
// Slow fills cannot result in refunds to a relayer to refund the deposit. Slow fills also
|
|
1010
|
+
// were created after the deposit was sent, so we can assume this deposit is a duplicate.
|
|
1011
|
+
updateExpiredDepositsV3(expiredDepositsToRefundV3, deposit);
|
|
1012
|
+
_c.label = 3;
|
|
1013
|
+
case 3: return [2 /*return*/];
|
|
1014
|
+
case 4:
|
|
875
1015
|
// If a slow fill request exists in memory, then we know the deposit has not been filled because fills
|
|
876
1016
|
// must follow slow fill requests and we would have seen the fill already if it existed. Therefore,
|
|
877
1017
|
// we can conclude that either the deposit has expired and we need to create a deposit expiry refund, or
|
|
@@ -881,63 +1021,88 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
881
1021
|
if (_depositIsExpired(deposit)) {
|
|
882
1022
|
updateExpiredDepositsV3(expiredDepositsToRefundV3, deposit);
|
|
883
1023
|
}
|
|
884
|
-
else if (
|
|
885
|
-
|
|
1024
|
+
else if (canRefundPrefills &&
|
|
1025
|
+
slowFillRequest.blockNumber < destinationChainBlockRange[0] &&
|
|
1026
|
+
_canCreateSlowFillLeaf(deposit) &&
|
|
1027
|
+
validatedBundleSlowFills.every(function (d) { return _this.getRelayHashFromEvent(d) !== relayDataHash; })) {
|
|
886
1028
|
validatedBundleSlowFills.push(deposit);
|
|
887
1029
|
}
|
|
888
1030
|
return [2 /*return*/];
|
|
889
1031
|
}
|
|
890
1032
|
return [4 /*yield*/, _getFillStatusForDeposit(deposit, destinationChainBlockRange[1])];
|
|
891
|
-
case
|
|
892
|
-
fillStatus =
|
|
893
|
-
if (!(fillStatus === FillStatus.Filled)) return [3 /*break*/,
|
|
894
|
-
return [4 /*yield*/,
|
|
895
|
-
case
|
|
896
|
-
prefill =
|
|
897
|
-
|
|
898
|
-
|
|
1033
|
+
case 5:
|
|
1034
|
+
fillStatus = _c.sent();
|
|
1035
|
+
if (!(fillStatus === FillStatus.Filled)) return [3 /*break*/, 9];
|
|
1036
|
+
return [4 /*yield*/, this.findMatchingFillEvent(deposit, destinationClient)];
|
|
1037
|
+
case 6:
|
|
1038
|
+
prefill = _c.sent();
|
|
1039
|
+
assert(isDefined(prefill), "findFillEvent# Cannot find prefill: ".concat(relayDataHash));
|
|
1040
|
+
assert(this.getRelayHashFromEvent(prefill) === relayDataHash, "Relay hashes should match.");
|
|
1041
|
+
if (!canRefundPrefills) return [3 /*break*/, 8];
|
|
1042
|
+
return [4 /*yield*/, verifyFillRepayment(prefill, destinationClient.spokePool.provider, deposit, allChainIds)];
|
|
1043
|
+
case 7:
|
|
1044
|
+
verifiedFill = _c.sent();
|
|
1045
|
+
if (!isDefined(verifiedFill)) {
|
|
1046
|
+
bundleUnrepayableFillsV3.push(prefill);
|
|
1047
|
+
}
|
|
1048
|
+
else if (!isSlowFill(verifiedFill)) {
|
|
1049
|
+
validatedBundleV3Fills.push(__assign(__assign({}, verifiedFill), { quoteTimestamp: deposit.quoteTimestamp }));
|
|
899
1050
|
}
|
|
900
|
-
|
|
901
|
-
|
|
1051
|
+
else {
|
|
1052
|
+
// Slow fills cannot result in refunds to a relayer to refund the deposit. Slow fills also
|
|
1053
|
+
// were created after the deposit was sent, so we can assume this deposit is a duplicate.
|
|
1054
|
+
updateExpiredDepositsV3(expiredDepositsToRefundV3, deposit);
|
|
1055
|
+
}
|
|
1056
|
+
_c.label = 8;
|
|
1057
|
+
case 8: return [3 /*break*/, 10];
|
|
1058
|
+
case 9:
|
|
902
1059
|
if (_depositIsExpired(deposit)) {
|
|
903
1060
|
updateExpiredDepositsV3(expiredDepositsToRefundV3, deposit);
|
|
904
1061
|
}
|
|
905
1062
|
// If slow fill requested, then issue a slow fill leaf for the deposit.
|
|
906
|
-
else if (fillStatus === FillStatus.RequestedSlowFill
|
|
1063
|
+
else if (fillStatus === FillStatus.RequestedSlowFill &&
|
|
1064
|
+
validatedBundleSlowFills.every(function (d) { return _this.getRelayHashFromEvent(d) !== relayDataHash; })) {
|
|
907
1065
|
// Input and Output tokens must be equivalent on the deposit for this to be slow filled.
|
|
908
1066
|
// Slow fill requests for deposits from or to lite chains are considered invalid
|
|
909
|
-
if (_canCreateSlowFillLeaf(deposit)) {
|
|
1067
|
+
if (canRefundPrefills && _canCreateSlowFillLeaf(deposit)) {
|
|
910
1068
|
// If deposit newly expired, then we can't create a slow fill leaf for it but we can
|
|
911
1069
|
// create a deposit refund for it.
|
|
912
1070
|
validatedBundleSlowFills.push(deposit);
|
|
913
1071
|
}
|
|
914
1072
|
}
|
|
915
|
-
|
|
916
|
-
case
|
|
1073
|
+
_c.label = 10;
|
|
1074
|
+
case 10: return [2 /*return*/];
|
|
917
1075
|
}
|
|
918
1076
|
});
|
|
919
1077
|
}); })];
|
|
920
1078
|
case 3:
|
|
1079
|
+
// Deposits can be submitted an arbitrary amount of time after matching fills and slow fill requests.
|
|
1080
|
+
// Therefore, let's go through each deposit in this bundle again and check a few things in order:
|
|
1081
|
+
// - Has the deposit been filled ? If so, then we need to issue a relayer refund for
|
|
1082
|
+
// this "pre-fill" if the fill took place in a previous bundle.
|
|
1083
|
+
// - Or, has the deposit expired in this bundle? If so, then we need to issue an expiry refund.
|
|
1084
|
+
// - And finally, has the deposit been slow filled? If so, then we need to issue a slow fill leaf
|
|
1085
|
+
// for this "pre-slow-fill-request" if this request took place in a previous bundle.
|
|
921
1086
|
_g.sent();
|
|
922
1087
|
// For all fills that came after a slow fill request, we can now check if the slow fill request
|
|
923
1088
|
// was a valid one and whether it was created in a previous bundle. If so, then it created a slow fill
|
|
924
1089
|
// leaf that is now unexecutable.
|
|
925
1090
|
fastFillsReplacingSlowFills.forEach(function (relayDataHash) {
|
|
926
|
-
var _a = v3RelayHashes[relayDataHash],
|
|
1091
|
+
var _a = v3RelayHashes[relayDataHash], deposits = _a.deposits, slowFillRequest = _a.slowFillRequest, fill = _a.fill;
|
|
927
1092
|
assert((fill === null || fill === void 0 ? void 0 : fill.relayExecutionInfo.fillType) === FillType.ReplacedSlowFill, "Fill type should be ReplacedSlowFill.");
|
|
928
1093
|
// Needed for TSC - are implicitely checking that deposit exists by making it to this point.
|
|
929
|
-
if (!
|
|
1094
|
+
if (!deposits || deposits.length < 1) {
|
|
930
1095
|
throw new Error("Deposit should exist in relay hash dictionary.");
|
|
931
1096
|
}
|
|
932
1097
|
// We should never push fast fills involving lite chains here because slow fill requests for them are invalid:
|
|
933
|
-
assert(_canCreateSlowFillLeaf(
|
|
1098
|
+
assert(_canCreateSlowFillLeaf(deposits[0]), "fastFillsReplacingSlowFills should contain only deposits that can be slow filled");
|
|
934
1099
|
var destinationBlockRange = getBlockRangeForChain(blockRangesForChains, destinationChainId, chainIds);
|
|
935
1100
|
if (
|
|
936
1101
|
// If there is a slow fill request in this bundle that matches the relay hash, then there was no slow fill
|
|
937
1102
|
// created that would be considered excess.
|
|
938
1103
|
!slowFillRequest ||
|
|
939
1104
|
slowFillRequest.blockNumber < destinationBlockRange[0]) {
|
|
940
|
-
validatedBundleUnexecutableSlowFills.push(
|
|
1105
|
+
validatedBundleUnexecutableSlowFills.push(deposits[0]);
|
|
941
1106
|
}
|
|
942
1107
|
});
|
|
943
1108
|
return [2 /*return*/];
|
|
@@ -981,13 +1146,17 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
981
1146
|
// For all deposits older than this bundle, we need to check if they expired in this bundle and if they did,
|
|
982
1147
|
// whether there was a slow fill created for it in a previous bundle that is now unexecutable and replaced
|
|
983
1148
|
// by a new expired deposit refund.
|
|
984
|
-
return [4 /*yield*/, forEachAsync(olderDepositHashes, function (
|
|
985
|
-
var _a,
|
|
986
|
-
return __generator(this, function (
|
|
987
|
-
switch (
|
|
1149
|
+
return [4 /*yield*/, forEachAsync(olderDepositHashes, function (depositHash) { return __awaiter(_this, void 0, void 0, function () {
|
|
1150
|
+
var _a, relayDataHash, index, _b, deposits, slowFillRequest, fill, deposit, destinationChainId, destinationBlockRange, fillStatus;
|
|
1151
|
+
return __generator(this, function (_c) {
|
|
1152
|
+
switch (_c.label) {
|
|
988
1153
|
case 0:
|
|
989
|
-
_a =
|
|
990
|
-
|
|
1154
|
+
_a = decodeBundleDepositHash(depositHash), relayDataHash = _a.relayDataHash, index = _a.index;
|
|
1155
|
+
_b = v3RelayHashes[relayDataHash], deposits = _b.deposits, slowFillRequest = _b.slowFillRequest, fill = _b.fill;
|
|
1156
|
+
if (!deposits || deposits.length < 1) {
|
|
1157
|
+
throw new Error("Deposit should exist in relay hash dictionary.");
|
|
1158
|
+
}
|
|
1159
|
+
deposit = deposits[index];
|
|
991
1160
|
destinationChainId = deposit.destinationChainId;
|
|
992
1161
|
destinationBlockRange = getBlockRangeForChain(blockRangesForChains, destinationChainId, chainIds);
|
|
993
1162
|
if (!
|
|
@@ -1001,7 +1170,7 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
1001
1170
|
return [3 /*break*/, 2];
|
|
1002
1171
|
return [4 /*yield*/, _getFillStatusForDeposit(deposit, destinationBlockRange[1])];
|
|
1003
1172
|
case 1:
|
|
1004
|
-
fillStatus =
|
|
1173
|
+
fillStatus = _c.sent();
|
|
1005
1174
|
// If there is no matching fill and the deposit expired in this bundle and the fill status on-chain is not
|
|
1006
1175
|
// Filled, then we can to refund it as an expired deposit.
|
|
1007
1176
|
if (fillStatus !== FillStatus.Filled) {
|
|
@@ -1023,7 +1192,7 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
1023
1192
|
if (!slowFillRequest || slowFillRequest.blockNumber < destinationBlockRange[0]) {
|
|
1024
1193
|
validatedBundleUnexecutableSlowFills.push(deposit);
|
|
1025
1194
|
}
|
|
1026
|
-
|
|
1195
|
+
_c.label = 2;
|
|
1027
1196
|
case 2: return [2 /*return*/];
|
|
1028
1197
|
}
|
|
1029
1198
|
});
|
|
@@ -1038,7 +1207,7 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
1038
1207
|
promises = [
|
|
1039
1208
|
validatedBundleV3Fills.length > 0
|
|
1040
1209
|
? this.clients.hubPoolClient.batchComputeRealizedLpFeePct(validatedBundleV3Fills.map(function (fill) {
|
|
1041
|
-
var matchedDeposit = v3RelayHashes[_this.getRelayHashFromEvent(fill)].
|
|
1210
|
+
var matchedDeposit = v3RelayHashes[_this.getRelayHashFromEvent(fill)].deposits[0];
|
|
1042
1211
|
assert(isDefined(matchedDeposit), "Deposit should exist in relay hash dictionary.");
|
|
1043
1212
|
var paymentChainId = getRefundInformationFromFill(fill, _this.clients.hubPoolClient, blockRangesForChains, chainIds, matchedDeposit.fromLiteChain).chainToSendRefundTo;
|
|
1044
1213
|
return __assign(__assign({}, fill), { paymentChainId: paymentChainId });
|
|
@@ -1065,14 +1234,22 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
1065
1234
|
v3FillLpFees.forEach(function (_a, idx) {
|
|
1066
1235
|
var realizedLpFeePct = _a.realizedLpFeePct;
|
|
1067
1236
|
var fill = validatedBundleV3Fills[idx];
|
|
1068
|
-
var associatedDeposit = v3RelayHashes[_this.getRelayHashFromEvent(fill)].
|
|
1237
|
+
var associatedDeposit = v3RelayHashes[_this.getRelayHashFromEvent(fill)].deposits[0];
|
|
1069
1238
|
assert(isDefined(associatedDeposit), "Deposit should exist in relay hash dictionary.");
|
|
1070
1239
|
var _b = getRefundInformationFromFill(fill, _this.clients.hubPoolClient, blockRangesForChains, chainIds, associatedDeposit.fromLiteChain), chainToSendRefundTo = _b.chainToSendRefundTo, repaymentToken = _b.repaymentToken;
|
|
1071
|
-
updateBundleFillsV3(bundleFillsV3, fill, realizedLpFeePct, chainToSendRefundTo, repaymentToken);
|
|
1240
|
+
updateBundleFillsV3(bundleFillsV3, fill, realizedLpFeePct, chainToSendRefundTo, repaymentToken, fill.relayer);
|
|
1072
1241
|
});
|
|
1073
1242
|
v3SlowFillLpFees.forEach(function (_a, idx) {
|
|
1074
1243
|
var lpFeePct = _a.realizedLpFeePct;
|
|
1075
1244
|
var deposit = validatedBundleSlowFills[idx];
|
|
1245
|
+
// We should not create slow fill leaves for duplicate deposit hashes and we should only create a slow
|
|
1246
|
+
// fill leaf for the first deposit (the quote timestamp of the deposit determines the LP fee, so its
|
|
1247
|
+
// important we pick out the correct deposit). Deposits are pushed into validatedBundleSlowFills in ascending
|
|
1248
|
+
// order so the following slice will only match the first deposit.
|
|
1249
|
+
var relayDataHash = _this.getRelayHashFromEvent(deposit);
|
|
1250
|
+
if (validatedBundleSlowFills.slice(0, idx).some(function (d) { return _this.getRelayHashFromEvent(d) === relayDataHash; })) {
|
|
1251
|
+
return;
|
|
1252
|
+
}
|
|
1076
1253
|
updateBundleSlowFills(bundleSlowFillsV3, __assign(__assign({}, deposit), { lpFeePct: lpFeePct }));
|
|
1077
1254
|
});
|
|
1078
1255
|
v3UnexecutableSlowFillLpFees.forEach(function (_a, idx) {
|
|
@@ -1080,7 +1257,7 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
1080
1257
|
var deposit = validatedBundleUnexecutableSlowFills[idx];
|
|
1081
1258
|
updateBundleExcessSlowFills(unexecutableSlowFills, __assign(__assign({}, deposit), { lpFeePct: lpFeePct }));
|
|
1082
1259
|
});
|
|
1083
|
-
v3SpokeEventsReadable = prettyPrintV3SpokePoolEvents(bundleDepositsV3, bundleFillsV3,
|
|
1260
|
+
v3SpokeEventsReadable = prettyPrintV3SpokePoolEvents(bundleDepositsV3, bundleFillsV3, bundleSlowFillsV3, expiredDepositsToRefundV3, unexecutableSlowFills);
|
|
1084
1261
|
if (bundleInvalidFillsV3.length > 0) {
|
|
1085
1262
|
this.logger.debug({
|
|
1086
1263
|
at: "BundleDataClient#loadData",
|
|
@@ -1089,6 +1266,14 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
1089
1266
|
bundleInvalidFillsV3: bundleInvalidFillsV3,
|
|
1090
1267
|
});
|
|
1091
1268
|
}
|
|
1269
|
+
if (bundleUnrepayableFillsV3.length > 0) {
|
|
1270
|
+
this.logger.debug({
|
|
1271
|
+
at: "BundleDataClient#loadData",
|
|
1272
|
+
message: "Finished loading V3 spoke pool data and found some unrepayable V3 fills in range",
|
|
1273
|
+
blockRangesForChains: blockRangesForChains,
|
|
1274
|
+
bundleUnrepayableFillsV3: bundleUnrepayableFillsV3,
|
|
1275
|
+
});
|
|
1276
|
+
}
|
|
1092
1277
|
this.logger.debug({
|
|
1093
1278
|
at: "BundleDataClient#loadDataFromScratch",
|
|
1094
1279
|
message: "Computed bundle data in ".concat(Math.round(performance.now() - start) / 1000, "s."),
|
|
@@ -1111,7 +1296,17 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
1111
1296
|
// spoke pool contract. However, this internal function is used to uniquely identify a bridging event
|
|
1112
1297
|
// for speed since its easier to build a string from the event data than to hash it.
|
|
1113
1298
|
BundleDataClient.prototype.getRelayHashFromEvent = function (event) {
|
|
1114
|
-
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);
|
|
1299
|
+
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);
|
|
1300
|
+
};
|
|
1301
|
+
BundleDataClient.prototype.findMatchingFillEvent = function (deposit, spokePoolClient) {
|
|
1302
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1303
|
+
return __generator(this, function (_a) {
|
|
1304
|
+
switch (_a.label) {
|
|
1305
|
+
case 0: return [4 /*yield*/, findFillEvent(spokePoolClient.spokePool, deposit, spokePoolClient.deploymentBlock, spokePoolClient.latestBlockSearched)];
|
|
1306
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
1307
|
+
}
|
|
1308
|
+
});
|
|
1309
|
+
});
|
|
1115
1310
|
};
|
|
1116
1311
|
BundleDataClient.prototype.getBundleBlockTimestamps = function (chainIds, blockRangesForChains, spokePoolClients) {
|
|
1117
1312
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -1122,7 +1317,7 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
1122
1317
|
case 0:
|
|
1123
1318
|
_b = (_a = Object).fromEntries;
|
|
1124
1319
|
return [4 /*yield*/, mapAsync(chainIds, function (chainId, index) { return __awaiter(_this, void 0, void 0, function () {
|
|
1125
|
-
var blockRangeForChain, _startBlockForChain, _endBlockForChain, spokePoolClient, startBlockForChain, endBlockForChain, _a, startTime,
|
|
1320
|
+
var blockRangeForChain, _startBlockForChain, _endBlockForChain, spokePoolClient, startBlockForChain, endBlockForChain, _a, startTime, _endTime, _b, endBlockDelta, endTime;
|
|
1126
1321
|
return __generator(this, function (_c) {
|
|
1127
1322
|
switch (_c.label) {
|
|
1128
1323
|
case 0:
|
|
@@ -1137,7 +1332,7 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
1137
1332
|
return [2 /*return*/];
|
|
1138
1333
|
}
|
|
1139
1334
|
startBlockForChain = Math.min(_startBlockForChain, spokePoolClient.latestBlockSearched);
|
|
1140
|
-
endBlockForChain = Math.min(_endBlockForChain, spokePoolClient.latestBlockSearched);
|
|
1335
|
+
endBlockForChain = Math.min(_endBlockForChain + 1, spokePoolClient.latestBlockSearched);
|
|
1141
1336
|
return [4 /*yield*/, spokePoolClient.getTimestampForBlock(startBlockForChain)];
|
|
1142
1337
|
case 1:
|
|
1143
1338
|
_b = [
|
|
@@ -1147,9 +1342,11 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
1147
1342
|
case 2:
|
|
1148
1343
|
_a = _b.concat([
|
|
1149
1344
|
_c.sent()
|
|
1150
|
-
]), startTime = _a[0],
|
|
1345
|
+
]), startTime = _a[0], _endTime = _a[1];
|
|
1346
|
+
endBlockDelta = endBlockForChain > startBlockForChain ? 1 : 0;
|
|
1347
|
+
endTime = Math.max(0, _endTime - endBlockDelta);
|
|
1151
1348
|
// Sanity checks:
|
|
1152
|
-
assert(endTime >= startTime, "End time should be greater than start time.");
|
|
1349
|
+
assert(endTime >= startTime, "End time for block ".concat(endBlockForChain, " should be greater than start time for block ").concat(startBlockForChain, ": ").concat(endTime, " >= ").concat(startTime, "."));
|
|
1153
1350
|
assert(startBlockForChain === 0 || startTime > 0, "Start timestamp must be greater than 0 if the start block is greater than 0.");
|
|
1154
1351
|
return [2 /*return*/, [chainId, [startTime, endTime]]];
|
|
1155
1352
|
}
|