@across-protocol/sdk 4.0.0-beta.9 → 4.0.1
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 +345 -187
- 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 +10 -1
- 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 +0 -1
- package/dist/cjs/constants.js +1 -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 +1 -0
- package/dist/cjs/utils/AddressUtils.js +6 -1
- package/dist/cjs/utils/AddressUtils.js.map +1 -1
- package/dist/cjs/utils/BlockUtils.js +1 -0
- package/dist/cjs/utils/BlockUtils.js.map +1 -1
- package/dist/cjs/utils/DepositUtils.js +1 -1
- 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.js +2 -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 +15 -8
- 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 +448 -281
- 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 +17 -1
- 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 +0 -1
- package/dist/esm/constants.js +0 -1
- 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 +1 -0
- package/dist/esm/utils/AddressUtils.js +9 -0
- package/dist/esm/utils/AddressUtils.js.map +1 -1
- package/dist/esm/utils/BlockUtils.js +1 -0
- package/dist/esm/utils/BlockUtils.js.map +1 -1
- package/dist/esm/utils/DepositUtils.js +2 -2
- 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.js +2 -1
- package/dist/esm/utils/NetworkUtils.js.map +1 -1
- package/dist/esm/utils/SpokeUtils.d.ts +1 -0
- package/dist/esm/utils/SpokeUtils.js +13 -7
- package/dist/esm/utils/SpokeUtils.js.map +1 -1
- package/dist/esm/utils/abi/typechain/Multicall3.d.ts +4 -1
- package/dist/esm/utils/abi/typechain/factories/Multicall3__factory.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 +0 -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 +1 -0
- package/dist/types/utils/AddressUtils.d.ts.map +1 -1
- package/dist/types/utils/BlockUtils.d.ts.map +1 -1
- package/dist/types/utils/EventUtils.d.ts.map +1 -1
- 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/abi/typechain/Multicall3.d.ts +4 -1
- package/dist/types/utils/abi/typechain/Multicall3.d.ts.map +1 -1
- package/dist/types/utils/abi/typechain/common.d.ts.map +1 -1
- package/dist/types/utils/abi/typechain/factories/Multicall3__factory.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 +3 -3
- package/src/clients/BundleDataClient/BundleDataClient.ts +406 -249
- package/src/clients/BundleDataClient/utils/DataworkerUtils.ts +0 -8
- package/src/clients/BundleDataClient/utils/FillUtils.ts +66 -2
- package/src/clients/SpokePoolClient.ts +16 -3
- package/src/clients/mocks/MockSpokePoolClient.ts +14 -0
- package/src/constants.ts +0 -2
- package/src/providers/index.ts +1 -0
- package/src/providers/mockProvider.ts +77 -0
- package/src/utils/AddressUtils.ts +10 -0
- package/src/utils/BlockUtils.ts +1 -0
- package/src/utils/DepositUtils.ts +2 -2
- package/src/utils/EventUtils.ts +29 -1
- package/src/utils/NetworkUtils.ts +2 -1
- package/src/utils/SpokeUtils.ts +21 -8
- package/src/utils/common.ts +2 -0
|
@@ -1,8 +1,8 @@
|
|
|
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, chainIsEvm, isValidEvmAddress, } 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
6
|
import { PRE_FILL_MIN_CONFIG_STORE_VERSION } from "../../constants";
|
|
7
7
|
// max(uint256) - 1
|
|
8
8
|
export var INFINITE_FILL_DEADLINE = bnUint32Max;
|
|
@@ -27,12 +27,10 @@ function updateBundleDepositsV3(dict, deposit) {
|
|
|
27
27
|
}
|
|
28
28
|
dict[originChainId][inputToken].push(deposit);
|
|
29
29
|
}
|
|
30
|
-
function updateBundleFillsV3(dict, fill, lpFeePct, repaymentChainId, repaymentToken) {
|
|
30
|
+
function updateBundleFillsV3(dict, fill, lpFeePct, repaymentChainId, repaymentToken, repaymentAddress) {
|
|
31
31
|
var _a, _b;
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
32
|
+
// We shouldn't pass any unrepayable fills into this function, so we perform an extra safety check.
|
|
33
|
+
assert(chainIsEvm(repaymentChainId) && isEvmRepaymentValid(fill, repaymentChainId), "validatedBundleV3Fills dictionary should only contain fills with valid repayment information");
|
|
36
34
|
if (!((_a = dict === null || dict === void 0 ? void 0 : dict[repaymentChainId]) === null || _a === void 0 ? void 0 : _a[repaymentToken])) {
|
|
37
35
|
assign(dict, [repaymentChainId, repaymentToken], {
|
|
38
36
|
fills: [],
|
|
@@ -41,26 +39,26 @@ function updateBundleFillsV3(dict, fill, lpFeePct, repaymentChainId, repaymentTo
|
|
|
41
39
|
refunds: {},
|
|
42
40
|
});
|
|
43
41
|
}
|
|
44
|
-
var bundleFill = __assign(__assign({}, fill), { lpFeePct: lpFeePct });
|
|
42
|
+
var bundleFill = __assign(__assign({}, fill), { lpFeePct: lpFeePct, relayer: repaymentAddress });
|
|
45
43
|
// Add all fills, slow and fast, to dictionary.
|
|
46
44
|
assign(dict, [repaymentChainId, repaymentToken, "fills"], [bundleFill]);
|
|
47
45
|
// All fills update the bundle LP fees.
|
|
48
46
|
var refundObj = dict[repaymentChainId][repaymentToken];
|
|
49
|
-
var realizedLpFee =
|
|
47
|
+
var realizedLpFee = bundleFill.inputAmount.mul(bundleFill.lpFeePct).div(fixedPointAdjustment);
|
|
50
48
|
refundObj.realizedLpFees = refundObj.realizedLpFees ? refundObj.realizedLpFees.add(realizedLpFee) : realizedLpFee;
|
|
51
49
|
// Only fast fills get refunded.
|
|
52
|
-
if (!isSlowFill(
|
|
53
|
-
var refundAmount =
|
|
50
|
+
if (!isSlowFill(bundleFill)) {
|
|
51
|
+
var refundAmount = bundleFill.inputAmount.mul(fixedPointAdjustment.sub(lpFeePct)).div(fixedPointAdjustment);
|
|
54
52
|
refundObj.totalRefundAmount = refundObj.totalRefundAmount
|
|
55
53
|
? refundObj.totalRefundAmount.add(refundAmount)
|
|
56
54
|
: refundAmount;
|
|
57
55
|
// Instantiate dictionary if it doesn't exist.
|
|
58
56
|
(_b = refundObj.refunds) !== null && _b !== void 0 ? _b : (refundObj.refunds = {});
|
|
59
|
-
if (refundObj.refunds[
|
|
60
|
-
refundObj.refunds[
|
|
57
|
+
if (refundObj.refunds[bundleFill.relayer]) {
|
|
58
|
+
refundObj.refunds[bundleFill.relayer] = refundObj.refunds[bundleFill.relayer].add(refundAmount);
|
|
61
59
|
}
|
|
62
60
|
else {
|
|
63
|
-
refundObj.refunds[
|
|
61
|
+
refundObj.refunds[bundleFill.relayer] = refundAmount;
|
|
64
62
|
}
|
|
65
63
|
}
|
|
66
64
|
}
|
|
@@ -74,6 +72,9 @@ function updateBundleExcessSlowFills(dict, deposit) {
|
|
|
74
72
|
}
|
|
75
73
|
function updateBundleSlowFills(dict, deposit) {
|
|
76
74
|
var _a;
|
|
75
|
+
if (chainIsEvm(deposit.destinationChainId) && !isValidEvmAddress(deposit.recipient)) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
77
78
|
var destinationChainId = deposit.destinationChainId, outputToken = deposit.outputToken;
|
|
78
79
|
if (!((_a = dict === null || dict === void 0 ? void 0 : dict[destinationChainId]) === null || _a === void 0 ? void 0 : _a[outputToken])) {
|
|
79
80
|
assign(dict, [destinationChainId, outputToken], []);
|
|
@@ -171,8 +172,7 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
171
172
|
at: "BundleDataClient#loadPersistedDataFromArweave",
|
|
172
173
|
message: "Loaded persisted data from Arweave in ".concat(Math.round(performance.now() - start) / 1000, "s."),
|
|
173
174
|
blockRanges: JSON.stringify(blockRangesForChains),
|
|
174
|
-
bundleData: prettyPrintV3SpokePoolEvents(bundleData.bundleDepositsV3, bundleData.bundleFillsV3,
|
|
175
|
-
bundleData.bundleSlowFillsV3, bundleData.expiredDepositsToRefundV3, bundleData.unexecutableSlowFills),
|
|
175
|
+
bundleData: prettyPrintV3SpokePoolEvents(bundleData.bundleDepositsV3, bundleData.bundleFillsV3, bundleData.bundleSlowFillsV3, bundleData.expiredDepositsToRefundV3, bundleData.unexecutableSlowFills),
|
|
176
176
|
});
|
|
177
177
|
return [2 /*return*/, bundleData];
|
|
178
178
|
}
|
|
@@ -218,82 +218,124 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
218
218
|
return [4 /*yield*/, this.loadArweaveData(bundleEvaluationBlockRanges)];
|
|
219
219
|
case 1:
|
|
220
220
|
arweaveData = _a.sent();
|
|
221
|
-
if (arweaveData === undefined)
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
221
|
+
if (!(arweaveData === undefined)) return [3 /*break*/, 3];
|
|
222
|
+
return [4 /*yield*/, this.getApproximateRefundsForBlockRange(chainIds, bundleEvaluationBlockRanges)];
|
|
223
|
+
case 2:
|
|
224
|
+
combinedRefunds = _a.sent();
|
|
225
|
+
return [3 /*break*/, 4];
|
|
226
|
+
case 3:
|
|
227
|
+
bundleFillsV3 = arweaveData.bundleFillsV3, expiredDepositsToRefundV3 = arweaveData.expiredDepositsToRefundV3;
|
|
228
|
+
combinedRefunds = getRefundsFromBundle(bundleFillsV3, expiredDepositsToRefundV3);
|
|
229
|
+
// If we don't have a spoke pool client for a chain, then we won't be able to deduct refunds correctly for this
|
|
230
|
+
// chain. For most of the pending bundle's liveness period, these past refunds are already executed so this is
|
|
231
|
+
// a reasonable assumption. This empty refund chain also matches what the alternative
|
|
232
|
+
// `getApproximateRefundsForBlockRange` would return.
|
|
233
|
+
Object.keys(combinedRefunds).forEach(function (chainId) {
|
|
234
|
+
if (_this.spokePoolClients[Number(chainId)] === undefined) {
|
|
235
|
+
delete combinedRefunds[Number(chainId)];
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
_a.label = 4;
|
|
239
|
+
case 4:
|
|
240
|
+
// The latest proposed bundle's refund leaves might have already been partially or entirely executed.
|
|
241
|
+
// We have to deduct the executed amounts from the total refund amounts.
|
|
242
|
+
return [2 /*return*/, this.deductExecutedRefunds(combinedRefunds, bundle)];
|
|
240
243
|
}
|
|
241
244
|
});
|
|
242
245
|
});
|
|
243
246
|
};
|
|
244
247
|
// @dev This helper function should probably be moved to the InventoryClient
|
|
245
248
|
BundleDataClient.prototype.getApproximateRefundsForBlockRange = function (chainIds, blockRanges) {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
249
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
250
|
+
var refundsForChain, _loop_1, this_1, _i, chainIds_1, chainId;
|
|
251
|
+
var _this = this;
|
|
252
|
+
return __generator(this, function (_a) {
|
|
253
|
+
switch (_a.label) {
|
|
254
|
+
case 0:
|
|
255
|
+
refundsForChain = {};
|
|
256
|
+
_loop_1 = function (chainId) {
|
|
257
|
+
var chainIndex, fillsToCount;
|
|
258
|
+
return __generator(this, function (_b) {
|
|
259
|
+
switch (_b.label) {
|
|
260
|
+
case 0:
|
|
261
|
+
if (this_1.spokePoolClients[chainId] === undefined) {
|
|
262
|
+
return [2 /*return*/, "continue"];
|
|
263
|
+
}
|
|
264
|
+
chainIndex = chainIds.indexOf(chainId);
|
|
265
|
+
return [4 /*yield*/, filterAsync(this_1.spokePoolClients[chainId].getFills(), function (fill) { return __awaiter(_this, void 0, void 0, function () {
|
|
266
|
+
var matchingDeposit, hasMatchingDeposit, validRepayment;
|
|
267
|
+
return __generator(this, function (_a) {
|
|
268
|
+
switch (_a.label) {
|
|
269
|
+
case 0:
|
|
270
|
+
if (fill.blockNumber < blockRanges[chainIndex][0] ||
|
|
271
|
+
fill.blockNumber > blockRanges[chainIndex][1] ||
|
|
272
|
+
isZeroValueFillOrSlowFillRequest(fill)) {
|
|
273
|
+
return [2 /*return*/, false];
|
|
274
|
+
}
|
|
275
|
+
// If origin spoke pool client isn't defined, we can't validate it.
|
|
276
|
+
if (this.spokePoolClients[fill.originChainId] === undefined) {
|
|
277
|
+
return [2 /*return*/, false];
|
|
278
|
+
}
|
|
279
|
+
matchingDeposit = this.spokePoolClients[fill.originChainId].getDeposit(fill.depositId);
|
|
280
|
+
hasMatchingDeposit = matchingDeposit !== undefined &&
|
|
281
|
+
this.getRelayHashFromEvent(fill) === this.getRelayHashFromEvent(matchingDeposit);
|
|
282
|
+
if (!hasMatchingDeposit) return [3 /*break*/, 2];
|
|
283
|
+
return [4 /*yield*/, verifyFillRepayment(fill, this.spokePoolClients[fill.destinationChainId].spokePool.provider, matchingDeposit,
|
|
284
|
+
// @dev: to get valid repayment chain ID's, get all chain IDs for the bundle block range and remove
|
|
285
|
+
// disabled block ranges.
|
|
286
|
+
this.clients.configStoreClient
|
|
287
|
+
.getChainIdIndicesForBlock(blockRanges[0][1])
|
|
288
|
+
.filter(function (_chainId, i) { return !isChainDisabled(blockRanges[i]); }))];
|
|
289
|
+
case 1:
|
|
290
|
+
validRepayment = _a.sent();
|
|
291
|
+
if (!isDefined(validRepayment)) {
|
|
292
|
+
return [2 /*return*/, false];
|
|
293
|
+
}
|
|
294
|
+
_a.label = 2;
|
|
295
|
+
case 2: return [2 /*return*/, hasMatchingDeposit];
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
}); })];
|
|
299
|
+
case 1:
|
|
300
|
+
fillsToCount = _b.sent();
|
|
301
|
+
fillsToCount.forEach(function (fill) {
|
|
302
|
+
var _a, _b, _c;
|
|
303
|
+
var _d;
|
|
304
|
+
var matchingDeposit = _this.spokePoolClients[fill.originChainId].getDeposit(fill.depositId);
|
|
305
|
+
assert(isDefined(matchingDeposit), "Deposit not found for fill.");
|
|
306
|
+
var _e = getRefundInformationFromFill(fill, _this.clients.hubPoolClient, blockRanges, _this.chainIdListForBundleEvaluationBlockNumbers, matchingDeposit.fromLiteChain // Use ! because we've already asserted that matchingDeposit is defined.
|
|
307
|
+
), chainToSendRefundTo = _e.chainToSendRefundTo, repaymentToken = _e.repaymentToken;
|
|
308
|
+
// Assume that lp fees are 0 for the sake of speed. In the future we could batch compute
|
|
309
|
+
// these or make hardcoded assumptions based on the origin-repayment chain direction. This might result
|
|
310
|
+
// in slight over estimations of refunds, but its not clear whether underestimating or overestimating is
|
|
311
|
+
// worst from the relayer's perspective.
|
|
312
|
+
var relayer = fill.relayer, refundAmount = fill.inputAmount;
|
|
313
|
+
(_a = refundsForChain[chainToSendRefundTo]) !== null && _a !== void 0 ? _a : (refundsForChain[chainToSendRefundTo] = {});
|
|
314
|
+
(_b = (_d = refundsForChain[chainToSendRefundTo])[repaymentToken]) !== null && _b !== void 0 ? _b : (_d[repaymentToken] = {});
|
|
315
|
+
var existingRefundAmount = (_c = refundsForChain[chainToSendRefundTo][repaymentToken][relayer]) !== null && _c !== void 0 ? _c : bnZero;
|
|
316
|
+
refundsForChain[chainToSendRefundTo][repaymentToken][relayer] = existingRefundAmount.add(refundAmount);
|
|
317
|
+
});
|
|
318
|
+
return [2 /*return*/];
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
};
|
|
322
|
+
this_1 = this;
|
|
323
|
+
_i = 0, chainIds_1 = chainIds;
|
|
324
|
+
_a.label = 1;
|
|
325
|
+
case 1:
|
|
326
|
+
if (!(_i < chainIds_1.length)) return [3 /*break*/, 4];
|
|
327
|
+
chainId = chainIds_1[_i];
|
|
328
|
+
return [5 /*yield**/, _loop_1(chainId)];
|
|
329
|
+
case 2:
|
|
330
|
+
_a.sent();
|
|
331
|
+
_a.label = 3;
|
|
332
|
+
case 3:
|
|
333
|
+
_i++;
|
|
334
|
+
return [3 /*break*/, 1];
|
|
335
|
+
case 4: return [2 /*return*/, refundsForChain];
|
|
267
336
|
}
|
|
268
|
-
var matchingDeposit = _this.spokePoolClients[fill.originChainId].getDeposit(fill.depositId);
|
|
269
|
-
var hasMatchingDeposit = matchingDeposit !== undefined &&
|
|
270
|
-
_this.getRelayHashFromEvent(fill) === _this.getRelayHashFromEvent(matchingDeposit);
|
|
271
|
-
return hasMatchingDeposit;
|
|
272
|
-
})
|
|
273
|
-
.forEach(function (fill) {
|
|
274
|
-
var _a, _b, _c;
|
|
275
|
-
var _d;
|
|
276
|
-
var matchingDeposit = _this.spokePoolClients[fill.originChainId].getDeposit(fill.depositId);
|
|
277
|
-
assert(isDefined(matchingDeposit), "Deposit not found for fill.");
|
|
278
|
-
var _e = getRefundInformationFromFill(fill, _this.clients.hubPoolClient, blockRanges, _this.chainIdListForBundleEvaluationBlockNumbers, matchingDeposit.fromLiteChain // Use ! because we've already asserted that matchingDeposit is defined.
|
|
279
|
-
), chainToSendRefundTo = _e.chainToSendRefundTo, repaymentToken = _e.repaymentToken;
|
|
280
|
-
// Assume that lp fees are 0 for the sake of speed. In the future we could batch compute
|
|
281
|
-
// these or make hardcoded assumptions based on the origin-repayment chain direction. This might result
|
|
282
|
-
// in slight over estimations of refunds, but its not clear whether underestimating or overestimating is
|
|
283
|
-
// worst from the relayer's perspective.
|
|
284
|
-
var relayer = fill.relayer, refundAmount = fill.inputAmount;
|
|
285
|
-
(_a = refundsForChain[chainToSendRefundTo]) !== null && _a !== void 0 ? _a : (refundsForChain[chainToSendRefundTo] = {});
|
|
286
|
-
(_b = (_d = refundsForChain[chainToSendRefundTo])[repaymentToken]) !== null && _b !== void 0 ? _b : (_d[repaymentToken] = {});
|
|
287
|
-
var existingRefundAmount = (_c = refundsForChain[chainToSendRefundTo][repaymentToken][relayer]) !== null && _c !== void 0 ? _c : bnZero;
|
|
288
|
-
refundsForChain[chainToSendRefundTo][repaymentToken][relayer] = existingRefundAmount.add(refundAmount);
|
|
289
337
|
});
|
|
290
|
-
};
|
|
291
|
-
var this_1 = this;
|
|
292
|
-
for (var _i = 0, chainIds_1 = chainIds; _i < chainIds_1.length; _i++) {
|
|
293
|
-
var chainId = chainIds_1[_i];
|
|
294
|
-
_loop_1(chainId);
|
|
295
|
-
}
|
|
296
|
-
return refundsForChain;
|
|
338
|
+
});
|
|
297
339
|
};
|
|
298
340
|
BundleDataClient.prototype.getUpcomingDepositAmount = function (chainId, l2Token, latestBlockToSearch) {
|
|
299
341
|
if (this.spokePoolClients[chainId] === undefined) {
|
|
@@ -338,12 +380,10 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
338
380
|
case 1:
|
|
339
381
|
_a = _b.sent(), bundleData = _a.bundleData, blockRanges = _a.blockRanges;
|
|
340
382
|
hubPoolClient = this.clients.hubPoolClient;
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
case 2:
|
|
346
|
-
root = _b.sent();
|
|
383
|
+
root = _buildPoolRebalanceRoot(hubPoolClient.latestBlockSearched, blockRanges[0][1], bundleData.bundleDepositsV3, bundleData.bundleFillsV3, bundleData.bundleSlowFillsV3, bundleData.unexecutableSlowFills, bundleData.expiredDepositsToRefundV3, {
|
|
384
|
+
hubPoolClient: hubPoolClient,
|
|
385
|
+
configStoreClient: hubPoolClient.configStoreClient,
|
|
386
|
+
});
|
|
347
387
|
return [2 /*return*/, {
|
|
348
388
|
root: root,
|
|
349
389
|
blockRanges: blockRanges,
|
|
@@ -385,33 +425,40 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
385
425
|
return [initialBlockRange[1] + 1, blockRange[1]];
|
|
386
426
|
});
|
|
387
427
|
}
|
|
388
|
-
var hubPoolClient, nextBundleMainnetStartBlock, chainIds, combinedRefunds, widestBundleBlockRanges, pendingBundleBlockRanges, arweaveData, bundleFillsV3, expiredDepositsToRefundV3, start;
|
|
389
|
-
return __generator(this, function (
|
|
390
|
-
switch (
|
|
428
|
+
var hubPoolClient, nextBundleMainnetStartBlock, chainIds, combinedRefunds, widestBundleBlockRanges, pendingBundleBlockRanges, arweaveData, _a, _b, bundleFillsV3, expiredDepositsToRefundV3, start, _c, _d;
|
|
429
|
+
return __generator(this, function (_e) {
|
|
430
|
+
switch (_e.label) {
|
|
391
431
|
case 0:
|
|
392
432
|
hubPoolClient = this.clients.hubPoolClient;
|
|
393
433
|
nextBundleMainnetStartBlock = hubPoolClient.getNextBundleStartBlockNumber(this.chainIdListForBundleEvaluationBlockNumbers, hubPoolClient.latestBlockSearched, hubPoolClient.chainId);
|
|
394
434
|
chainIds = this.clients.configStoreClient.getChainIdIndicesForBlock(nextBundleMainnetStartBlock);
|
|
395
435
|
combinedRefunds = [];
|
|
396
436
|
widestBundleBlockRanges = getWidestPossibleExpectedBlockRange(chainIds, this.spokePoolClients, getEndBlockBuffers(chainIds, this.blockRangeEndBlockBuffer), this.clients, this.clients.hubPoolClient.latestBlockSearched, this.clients.configStoreClient.getEnabledChains(this.clients.hubPoolClient.latestBlockSearched));
|
|
397
|
-
if (!hubPoolClient.hasPendingProposal()) return [3 /*break*/,
|
|
437
|
+
if (!hubPoolClient.hasPendingProposal()) return [3 /*break*/, 5];
|
|
398
438
|
pendingBundleBlockRanges = getImpliedBundleBlockRanges(hubPoolClient, this.clients.configStoreClient, hubPoolClient.getLatestProposedRootBundle());
|
|
399
439
|
return [4 /*yield*/, this.loadArweaveData(pendingBundleBlockRanges)];
|
|
400
440
|
case 1:
|
|
401
|
-
arweaveData =
|
|
402
|
-
if (arweaveData === undefined)
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
441
|
+
arweaveData = _e.sent();
|
|
442
|
+
if (!(arweaveData === undefined)) return [3 /*break*/, 3];
|
|
443
|
+
_b = (_a = combinedRefunds).push;
|
|
444
|
+
return [4 /*yield*/, this.getApproximateRefundsForBlockRange(chainIds, pendingBundleBlockRanges)];
|
|
445
|
+
case 2:
|
|
446
|
+
_b.apply(_a, [_e.sent()]);
|
|
447
|
+
return [3 /*break*/, 4];
|
|
448
|
+
case 3:
|
|
449
|
+
bundleFillsV3 = arweaveData.bundleFillsV3, expiredDepositsToRefundV3 = arweaveData.expiredDepositsToRefundV3;
|
|
450
|
+
combinedRefunds.push(getRefundsFromBundle(bundleFillsV3, expiredDepositsToRefundV3));
|
|
451
|
+
_e.label = 4;
|
|
452
|
+
case 4:
|
|
409
453
|
// Shorten the widestBundleBlockRanges now to not double count the pending bundle blocks.
|
|
410
454
|
widestBundleBlockRanges = getBlockRangeDelta(pendingBundleBlockRanges);
|
|
411
|
-
|
|
412
|
-
case
|
|
455
|
+
_e.label = 5;
|
|
456
|
+
case 5:
|
|
413
457
|
start = performance.now();
|
|
414
|
-
combinedRefunds.push
|
|
458
|
+
_d = (_c = combinedRefunds).push;
|
|
459
|
+
return [4 /*yield*/, this.getApproximateRefundsForBlockRange(chainIds, widestBundleBlockRanges)];
|
|
460
|
+
case 6:
|
|
461
|
+
_d.apply(_c, [_e.sent()]);
|
|
415
462
|
this.logger.debug({
|
|
416
463
|
at: "BundleDataClient#getNextBundleRefunds",
|
|
417
464
|
message: "Loading approximate refunds for next bundle in ".concat(Math.round(performance.now() - start) / 1000, "s."),
|
|
@@ -554,7 +601,7 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
554
601
|
};
|
|
555
602
|
BundleDataClient.prototype.loadDataFromScratch = function (blockRangesForChains, spokePoolClients) {
|
|
556
603
|
return __awaiter(this, void 0, void 0, function () {
|
|
557
|
-
var start, key, chainIds, bundleDepositsV3, bundleFillsV3, bundleInvalidFillsV3, bundleSlowFillsV3, expiredDepositsToRefundV3, unexecutableSlowFills, _isChainDisabled, _canCreateSlowFillLeaf, _depositIsExpired, _getFillStatusForDeposit, allChainIds, _cachedBundleTimestamps, bundleBlockTimestamps, v3RelayHashes, bundleDepositHashes, olderDepositHashes, startBlockForMainnet, versionAtProposalBlock, canRefundPrefills,
|
|
604
|
+
var start, key, chainIds, bundleDepositsV3, bundleFillsV3, bundleInvalidFillsV3, bundleUnrepayableFillsV3, bundleInvalidSlowFillRequests, bundleSlowFillsV3, expiredDepositsToRefundV3, unexecutableSlowFills, _isChainDisabled, _canCreateSlowFillLeaf, _depositIsExpired, _getFillStatusForDeposit, allChainIds, _cachedBundleTimestamps, bundleBlockTimestamps, v3RelayHashes, bundleDepositHashes, olderDepositHashes, decodeBundleDepositHash, startBlockForMainnet, versionAtProposalBlock, canRefundPrefills, _loop_2, _i, allChainIds_1, originChainId, validatedBundleV3Fills, validatedBundleSlowFills, validatedBundleUnexecutableSlowFills, fillCounter, _loop_3, _a, allChainIds_2, originChainId, promises, _b, v3FillLpFees, v3SlowFillLpFees, v3UnexecutableSlowFillLpFees, v3SpokeEventsReadable;
|
|
558
605
|
var _this = this;
|
|
559
606
|
return __generator(this, function (_c) {
|
|
560
607
|
switch (_c.label) {
|
|
@@ -574,6 +621,8 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
574
621
|
bundleDepositsV3 = {};
|
|
575
622
|
bundleFillsV3 = {};
|
|
576
623
|
bundleInvalidFillsV3 = [];
|
|
624
|
+
bundleUnrepayableFillsV3 = [];
|
|
625
|
+
bundleInvalidSlowFillRequests = [];
|
|
577
626
|
bundleSlowFillsV3 = {};
|
|
578
627
|
expiredDepositsToRefundV3 = {};
|
|
579
628
|
unexecutableSlowFills = {};
|
|
@@ -631,10 +680,13 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
631
680
|
v3RelayHashes = {};
|
|
632
681
|
bundleDepositHashes = [];
|
|
633
682
|
olderDepositHashes = [];
|
|
683
|
+
decodeBundleDepositHash = function (depositHash) {
|
|
684
|
+
var _a = depositHash.split("@"), relayDataHash = _a[0], i = _a[1];
|
|
685
|
+
return { relayDataHash: relayDataHash, index: Number(i) };
|
|
686
|
+
};
|
|
634
687
|
startBlockForMainnet = getBlockRangeForChain(blockRangesForChains, this.clients.hubPoolClient.chainId, this.chainIdListForBundleEvaluationBlockNumbers)[0];
|
|
635
688
|
versionAtProposalBlock = this.clients.configStoreClient.getConfigStoreVersionForBlock(startBlockForMainnet);
|
|
636
689
|
canRefundPrefills = versionAtProposalBlock >= PRE_FILL_MIN_CONFIG_STORE_VERSION || process.env.FORCE_REFUND_PREFILLS === "true";
|
|
637
|
-
depositCounter = 0;
|
|
638
690
|
_loop_2 = function (originChainId) {
|
|
639
691
|
var originClient = spokePoolClients[originChainId];
|
|
640
692
|
var originChainBlockRange = getBlockRangeForChain(blockRangesForChains, originChainId, chainIds);
|
|
@@ -644,48 +696,45 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
644
696
|
continue;
|
|
645
697
|
}
|
|
646
698
|
originClient.getDepositsForDestinationChainWithDuplicates(destinationChainId).forEach(function (deposit) {
|
|
647
|
-
// Only evaluate deposits that are in this bundle or in previous bundles. This means we cannot issue fill
|
|
648
|
-
// refunds or slow fills here for deposits that are in future bundles (i.e. "pre-fills"). Instead, we'll
|
|
649
|
-
// evaluate these pre-fills once the deposit is inside the "current" bundle block range.
|
|
650
699
|
if (deposit.blockNumber > originChainBlockRange[1] || isZeroValueDeposit(deposit)) {
|
|
651
700
|
return;
|
|
652
701
|
}
|
|
653
|
-
depositCounter++;
|
|
654
702
|
var relayDataHash = _this.getRelayHashFromEvent(deposit);
|
|
655
|
-
// Duplicate deposits are treated like normal deposits.
|
|
656
703
|
if (!v3RelayHashes[relayDataHash]) {
|
|
657
704
|
v3RelayHashes[relayDataHash] = {
|
|
658
|
-
|
|
705
|
+
deposits: [deposit],
|
|
659
706
|
fill: undefined,
|
|
660
707
|
slowFillRequest: undefined,
|
|
661
708
|
};
|
|
662
709
|
}
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
// if this deposit did expire. Input amount can only be zero at this point if the message is non-empty,
|
|
666
|
-
// but the message doesn't matter for expired deposits and unexecutable slow fills.
|
|
667
|
-
if (deposit.inputAmount.eq(0)) {
|
|
668
|
-
return;
|
|
710
|
+
else {
|
|
711
|
+
v3RelayHashes[relayDataHash].deposits.push(deposit);
|
|
669
712
|
}
|
|
670
|
-
//
|
|
671
|
-
//
|
|
713
|
+
// Account for duplicate deposits by concatenating the relayDataHash with the count of the number of times
|
|
714
|
+
// we have seen it so far.
|
|
715
|
+
var newBundleDepositHash = "".concat(relayDataHash, "@").concat(v3RelayHashes[relayDataHash].deposits.length - 1);
|
|
716
|
+
var decodedBundleDepositHash = decodeBundleDepositHash(newBundleDepositHash);
|
|
717
|
+
assert(decodedBundleDepositHash.relayDataHash === relayDataHash &&
|
|
718
|
+
decodedBundleDepositHash.index === v3RelayHashes[relayDataHash].deposits.length - 1, "Not using correct bundle deposit hash key");
|
|
672
719
|
if (deposit.blockNumber >= originChainBlockRange[0]) {
|
|
673
|
-
bundleDepositHashes.push(
|
|
720
|
+
bundleDepositHashes.push(newBundleDepositHash);
|
|
674
721
|
updateBundleDepositsV3(bundleDepositsV3, deposit);
|
|
675
722
|
}
|
|
676
723
|
else if (deposit.blockNumber < originChainBlockRange[0]) {
|
|
677
|
-
olderDepositHashes.push(
|
|
724
|
+
olderDepositHashes.push(newBundleDepositHash);
|
|
678
725
|
}
|
|
679
726
|
});
|
|
680
727
|
}
|
|
681
728
|
};
|
|
729
|
+
// Prerequisite step: Load all deposit events from the current or older bundles into the v3RelayHashes dictionary
|
|
730
|
+
// for convenient matching with fills.
|
|
682
731
|
for (_i = 0, allChainIds_1 = allChainIds; _i < allChainIds_1.length; _i++) {
|
|
683
732
|
originChainId = allChainIds_1[_i];
|
|
684
733
|
_loop_2(originChainId);
|
|
685
734
|
}
|
|
686
735
|
this.logger.debug({
|
|
687
736
|
at: "BundleDataClient#loadData",
|
|
688
|
-
message: "Processed ".concat(
|
|
737
|
+
message: "Processed ".concat(bundleDepositHashes.length + olderDepositHashes.length, " deposits in ").concat(performance.now() - start, "ms."),
|
|
689
738
|
});
|
|
690
739
|
start = performance.now();
|
|
691
740
|
validatedBundleV3Fills = [];
|
|
@@ -699,7 +748,7 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
699
748
|
case 0:
|
|
700
749
|
originClient = spokePoolClients[originChainId];
|
|
701
750
|
_loop_4 = function (destinationChainId) {
|
|
702
|
-
var destinationClient, destinationChainBlockRange, fastFillsReplacingSlowFills;
|
|
751
|
+
var destinationClient, destinationChainBlockRange, originChainBlockRange, fastFillsReplacingSlowFills;
|
|
703
752
|
return __generator(this, function (_g) {
|
|
704
753
|
switch (_g.label) {
|
|
705
754
|
case 0:
|
|
@@ -708,6 +757,7 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
708
757
|
}
|
|
709
758
|
destinationClient = spokePoolClients[destinationChainId];
|
|
710
759
|
destinationChainBlockRange = getBlockRangeForChain(blockRangesForChains, destinationChainId, chainIds);
|
|
760
|
+
originChainBlockRange = getBlockRangeForChain(blockRangesForChains, originChainId, chainIds);
|
|
711
761
|
fastFillsReplacingSlowFills = [];
|
|
712
762
|
return [4 /*yield*/, forEachAsync(destinationClient
|
|
713
763
|
.getFillsForOriginChain(originChainId)
|
|
@@ -715,40 +765,58 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
715
765
|
// tokens to the filler. We can't remove non-empty message deposit here in case there is a slow fill
|
|
716
766
|
// request for the deposit, we'd want to see the fill took place.
|
|
717
767
|
.filter(function (fill) { return fill.blockNumber <= destinationChainBlockRange[1] && !isZeroValueFillOrSlowFillRequest(fill); }), function (fill) { return __awaiter(_this, void 0, void 0, function () {
|
|
718
|
-
var relayDataHash,
|
|
768
|
+
var relayDataHash, fillToRefund_1, duplicateDeposits, historicalDeposit, matchedDeposit, fillToRefund;
|
|
719
769
|
return __generator(this, function (_a) {
|
|
720
770
|
switch (_a.label) {
|
|
721
771
|
case 0:
|
|
722
|
-
relayDataHash = this.getRelayHashFromEvent(fill);
|
|
723
772
|
fillCounter++;
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
773
|
+
relayDataHash = this.getRelayHashFromEvent(fill);
|
|
774
|
+
if (!v3RelayHashes[relayDataHash]) return [3 /*break*/, 5];
|
|
775
|
+
if (!!v3RelayHashes[relayDataHash].fill) return [3 /*break*/, 3];
|
|
776
|
+
assert(isDefined(v3RelayHashes[relayDataHash].deposits) && v3RelayHashes[relayDataHash].deposits.length > 0, "Deposit should exist in relay hash dictionary.");
|
|
777
|
+
v3RelayHashes[relayDataHash].fill = fill;
|
|
778
|
+
if (!(fill.blockNumber >= destinationChainBlockRange[0])) return [3 /*break*/, 2];
|
|
779
|
+
return [4 /*yield*/, verifyFillRepayment(fill, destinationClient.spokePool.provider, v3RelayHashes[relayDataHash].deposits[0], allChainIds)];
|
|
780
|
+
case 1:
|
|
781
|
+
fillToRefund_1 = _a.sent();
|
|
782
|
+
if (!isDefined(fillToRefund_1)) {
|
|
783
|
+
bundleUnrepayableFillsV3.push(fill);
|
|
784
|
+
// We don't return here yet because we still need to mark unexecutable slow fill leaves
|
|
785
|
+
// or duplicate deposits. However, we won't issue a fast fill refund.
|
|
786
|
+
}
|
|
787
|
+
else {
|
|
788
|
+
v3RelayHashes[relayDataHash].fill = fillToRefund_1;
|
|
789
|
+
validatedBundleV3Fills.push(__assign(__assign({}, fillToRefund_1), { quoteTimestamp: v3RelayHashes[relayDataHash].deposits[0].quoteTimestamp }));
|
|
790
|
+
duplicateDeposits = v3RelayHashes[relayDataHash].deposits.slice(1);
|
|
791
|
+
duplicateDeposits.forEach(function (duplicateDeposit) {
|
|
792
|
+
if (isSlowFill(fill)) {
|
|
793
|
+
updateExpiredDepositsV3(expiredDepositsToRefundV3, duplicateDeposit);
|
|
740
794
|
}
|
|
741
|
-
|
|
742
|
-
|
|
795
|
+
else {
|
|
796
|
+
validatedBundleV3Fills.push(__assign(__assign({}, fillToRefund_1), { quoteTimestamp: duplicateDeposit.quoteTimestamp }));
|
|
797
|
+
}
|
|
798
|
+
});
|
|
743
799
|
}
|
|
800
|
+
// If fill replaced a slow fill request, then mark it as one that might have created an
|
|
801
|
+
// unexecutable slow fill. We can't know for sure until we check the slow fill request
|
|
802
|
+
// events.
|
|
803
|
+
if (fill.relayExecutionInfo.fillType === FillType.ReplacedSlowFill &&
|
|
804
|
+
_canCreateSlowFillLeaf(v3RelayHashes[relayDataHash].deposits[0])) {
|
|
805
|
+
fastFillsReplacingSlowFills.push(relayDataHash);
|
|
806
|
+
}
|
|
807
|
+
_a.label = 2;
|
|
808
|
+
case 2: return [3 /*break*/, 4];
|
|
809
|
+
case 3: throw new Error("Duplicate fill detected");
|
|
810
|
+
case 4: return [2 /*return*/];
|
|
811
|
+
case 5:
|
|
744
812
|
// At this point, there is no relay hash dictionary entry for this fill, so we need to
|
|
745
|
-
// instantiate the entry.
|
|
813
|
+
// instantiate the entry. We won't modify the fill.relayer until we match it with a deposit.
|
|
746
814
|
v3RelayHashes[relayDataHash] = {
|
|
747
|
-
|
|
815
|
+
deposits: undefined,
|
|
748
816
|
fill: fill,
|
|
749
817
|
slowFillRequest: undefined,
|
|
750
818
|
};
|
|
751
|
-
if (!(fill.blockNumber >= destinationChainBlockRange[0])) return [3 /*break*/,
|
|
819
|
+
if (!(fill.blockNumber >= destinationChainBlockRange[0])) return [3 /*break*/, 9];
|
|
752
820
|
// Fill has a non-infinite expiry, and we can assume our spoke pool clients have old enough deposits
|
|
753
821
|
// to conclude that this fill is invalid if we haven't found a matching deposit in memory, so
|
|
754
822
|
// skip the historical query.
|
|
@@ -756,49 +824,58 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
756
824
|
bundleInvalidFillsV3.push(fill);
|
|
757
825
|
return [2 /*return*/];
|
|
758
826
|
}
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
827
|
+
return [4 /*yield*/, queryHistoricalDepositForFill(originClient, fill)];
|
|
828
|
+
case 6:
|
|
829
|
+
historicalDeposit = _a.sent();
|
|
830
|
+
if (!!historicalDeposit.found) return [3 /*break*/, 7];
|
|
831
|
+
bundleInvalidFillsV3.push(fill);
|
|
832
|
+
return [3 /*break*/, 9];
|
|
833
|
+
case 7:
|
|
834
|
+
matchedDeposit = historicalDeposit.deposit;
|
|
835
|
+
// If deposit is in a following bundle, then this fill will have to be refunded once that deposit
|
|
836
|
+
// is in the current bundle.
|
|
837
|
+
if (matchedDeposit.blockNumber > originChainBlockRange[1]) {
|
|
766
838
|
bundleInvalidFillsV3.push(fill);
|
|
767
839
|
return [2 /*return*/];
|
|
768
840
|
}
|
|
769
|
-
|
|
770
|
-
fill.
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
841
|
+
v3RelayHashes[relayDataHash].deposits = [matchedDeposit];
|
|
842
|
+
return [4 /*yield*/, verifyFillRepayment(fill, destinationClient.spokePool.provider, matchedDeposit, allChainIds)];
|
|
843
|
+
case 8:
|
|
844
|
+
fillToRefund = _a.sent();
|
|
845
|
+
if (!isDefined(fillToRefund)) {
|
|
846
|
+
bundleUnrepayableFillsV3.push(fill);
|
|
847
|
+
// Don't return yet as we still need to mark down any unexecutable slow fill leaves
|
|
848
|
+
// in case this fast fill replaced a slow fill request.
|
|
777
849
|
}
|
|
778
850
|
else {
|
|
779
|
-
matchedDeposit = historicalDeposit.deposit;
|
|
780
851
|
// @dev Since queryHistoricalDepositForFill validates the fill by checking individual
|
|
781
852
|
// object property values against the deposit's, we
|
|
782
853
|
// sanity check it here by comparing the full relay hashes. If there's an error here then the
|
|
783
854
|
// historical deposit query is not working as expected.
|
|
784
855
|
assert(this.getRelayHashFromEvent(matchedDeposit) === relayDataHash, "Relay hashes should match.");
|
|
785
|
-
validatedBundleV3Fills.push(__assign(__assign({},
|
|
786
|
-
v3RelayHashes[relayDataHash].
|
|
787
|
-
//
|
|
788
|
-
|
|
789
|
-
_canCreateSlowFillLeaf(matchedDeposit)) {
|
|
790
|
-
fastFillsReplacingSlowFills.push(relayDataHash);
|
|
791
|
-
}
|
|
856
|
+
validatedBundleV3Fills.push(__assign(__assign({}, fillToRefund), { quoteTimestamp: matchedDeposit.quoteTimestamp }));
|
|
857
|
+
v3RelayHashes[relayDataHash].fill = fillToRefund;
|
|
858
|
+
// No need to check for duplicate deposits here since duplicate deposits with
|
|
859
|
+
// infinite deadlines are impossible to send via unsafeDeposit().
|
|
792
860
|
}
|
|
793
|
-
|
|
794
|
-
|
|
861
|
+
if (fill.relayExecutionInfo.fillType === FillType.ReplacedSlowFill &&
|
|
862
|
+
_canCreateSlowFillLeaf(matchedDeposit)) {
|
|
863
|
+
fastFillsReplacingSlowFills.push(relayDataHash);
|
|
864
|
+
}
|
|
865
|
+
_a.label = 9;
|
|
866
|
+
case 9: return [2 /*return*/];
|
|
795
867
|
}
|
|
796
868
|
});
|
|
797
869
|
}); })];
|
|
798
870
|
case 1:
|
|
799
871
|
_g.sent();
|
|
800
|
-
// Process slow fill requests
|
|
801
|
-
// for deposits that
|
|
872
|
+
// Process slow fill requests and produce slow fill leaves while maintaining the following the invariants:
|
|
873
|
+
// - Slow fill leaves cannot be produced for deposits that have expired in this bundle.
|
|
874
|
+
// - Slow fill leaves cannot be produced for deposits that have been filled.
|
|
875
|
+
// Assumptions about fills:
|
|
876
|
+
// - Duplicate slow fill requests for the same relay data hash are impossible to send.
|
|
877
|
+
// - Slow fill requests can only be sent before the deposit's fillDeadline.
|
|
878
|
+
// - Slow fill requests for a deposit that has been filled.
|
|
802
879
|
return [4 /*yield*/, forEachAsync(destinationClient
|
|
803
880
|
.getSlowFillRequestsForOriginChain(originChainId)
|
|
804
881
|
.filter(function (request) {
|
|
@@ -811,55 +888,58 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
811
888
|
relayDataHash = this.getRelayHashFromEvent(slowFillRequest);
|
|
812
889
|
if (v3RelayHashes[relayDataHash]) {
|
|
813
890
|
if (!v3RelayHashes[relayDataHash].slowFillRequest) {
|
|
814
|
-
// At this point, the v3RelayHashes entry already existed meaning that there is either a matching
|
|
815
|
-
// fill or deposit.
|
|
816
891
|
v3RelayHashes[relayDataHash].slowFillRequest = slowFillRequest;
|
|
817
892
|
if (v3RelayHashes[relayDataHash].fill) {
|
|
818
|
-
//
|
|
819
|
-
//
|
|
893
|
+
// Exiting here assumes that slow fill requests must precede fills, so if there was a fill
|
|
894
|
+
// following this slow fill request, then we would have already seen it. We don't need to check
|
|
895
|
+
// for a fill older than this slow fill request.
|
|
820
896
|
return [2 /*return*/];
|
|
821
897
|
}
|
|
822
|
-
assert(isDefined(v3RelayHashes[relayDataHash].
|
|
823
|
-
matchedDeposit = v3RelayHashes[relayDataHash].
|
|
824
|
-
// If there is no fill matching the relay hash, then this might be a valid slow fill request
|
|
825
|
-
// that we should produce a slow fill leaf for. Check if the slow fill request is in the
|
|
826
|
-
// destination chain block range.
|
|
898
|
+
assert(isDefined(v3RelayHashes[relayDataHash].deposits) && v3RelayHashes[relayDataHash].deposits.length > 0, "Deposit should exist in relay hash dictionary.");
|
|
899
|
+
matchedDeposit = v3RelayHashes[relayDataHash].deposits[0];
|
|
827
900
|
if (slowFillRequest.blockNumber >= destinationChainBlockRange[0] &&
|
|
828
901
|
_canCreateSlowFillLeaf(matchedDeposit) &&
|
|
829
|
-
// Deposit must not have expired in this bundle.
|
|
830
902
|
!_depositIsExpired(matchedDeposit)) {
|
|
831
|
-
// At this point, the v3RelayHashes entry already existed meaning that there is a matching deposit,
|
|
832
|
-
// so this slow fill request relay data is correct.
|
|
833
903
|
validatedBundleSlowFills.push(matchedDeposit);
|
|
834
904
|
}
|
|
835
905
|
}
|
|
906
|
+
else {
|
|
907
|
+
throw new Error("Duplicate slow fill request detected.");
|
|
908
|
+
}
|
|
836
909
|
return [2 /*return*/];
|
|
837
910
|
}
|
|
838
911
|
// Instantiate dictionary if there is neither a deposit nor fill matching it.
|
|
839
912
|
v3RelayHashes[relayDataHash] = {
|
|
840
|
-
|
|
913
|
+
deposits: undefined,
|
|
841
914
|
fill: undefined,
|
|
842
915
|
slowFillRequest: slowFillRequest,
|
|
843
916
|
};
|
|
844
|
-
if (!(slowFillRequest.blockNumber >= destinationChainBlockRange[0]
|
|
845
|
-
|
|
917
|
+
if (!(slowFillRequest.blockNumber >= destinationChainBlockRange[0])) return [3 /*break*/, 2];
|
|
918
|
+
if (!INFINITE_FILL_DEADLINE.eq(slowFillRequest.fillDeadline)) {
|
|
919
|
+
bundleInvalidSlowFillRequests.push(slowFillRequest);
|
|
920
|
+
return [2 /*return*/];
|
|
921
|
+
}
|
|
846
922
|
return [4 /*yield*/, queryHistoricalDepositForFill(originClient, slowFillRequest)];
|
|
847
923
|
case 1:
|
|
848
924
|
historicalDeposit = _a.sent();
|
|
849
925
|
if (!historicalDeposit.found) {
|
|
850
|
-
|
|
926
|
+
bundleInvalidSlowFillRequests.push(slowFillRequest);
|
|
851
927
|
return [2 /*return*/];
|
|
852
928
|
}
|
|
853
929
|
matchedDeposit = historicalDeposit.deposit;
|
|
930
|
+
// If deposit is in a following bundle, then this slow fill request will have to be created
|
|
931
|
+
// once that deposit is in the current bundle.
|
|
932
|
+
if (matchedDeposit.blockNumber > originChainBlockRange[1]) {
|
|
933
|
+
bundleInvalidSlowFillRequests.push(slowFillRequest);
|
|
934
|
+
return [2 /*return*/];
|
|
935
|
+
}
|
|
854
936
|
// @dev Since queryHistoricalDepositForFill validates the slow fill request by checking individual
|
|
855
937
|
// object property values against the deposit's, we
|
|
856
938
|
// sanity check it here by comparing the full relay hashes. If there's an error here then the
|
|
857
939
|
// historical deposit query is not working as expected.
|
|
858
940
|
assert(this.getRelayHashFromEvent(matchedDeposit) === relayDataHash, "Deposit relay hashes should match.");
|
|
859
|
-
v3RelayHashes[relayDataHash].
|
|
860
|
-
if (!_canCreateSlowFillLeaf(matchedDeposit) ||
|
|
861
|
-
// Deposit must not have expired in this bundle.
|
|
862
|
-
_depositIsExpired(matchedDeposit)) {
|
|
941
|
+
v3RelayHashes[relayDataHash].deposits = [matchedDeposit];
|
|
942
|
+
if (!_canCreateSlowFillLeaf(matchedDeposit) || _depositIsExpired(matchedDeposit)) {
|
|
863
943
|
return [2 /*return*/];
|
|
864
944
|
}
|
|
865
945
|
validatedBundleSlowFills.push(matchedDeposit);
|
|
@@ -869,121 +949,167 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
869
949
|
});
|
|
870
950
|
}); })];
|
|
871
951
|
case 2:
|
|
872
|
-
// Process slow fill requests
|
|
873
|
-
// for deposits that
|
|
952
|
+
// Process slow fill requests and produce slow fill leaves while maintaining the following the invariants:
|
|
953
|
+
// - Slow fill leaves cannot be produced for deposits that have expired in this bundle.
|
|
954
|
+
// - Slow fill leaves cannot be produced for deposits that have been filled.
|
|
955
|
+
// Assumptions about fills:
|
|
956
|
+
// - Duplicate slow fill requests for the same relay data hash are impossible to send.
|
|
957
|
+
// - Slow fill requests can only be sent before the deposit's fillDeadline.
|
|
958
|
+
// - Slow fill requests for a deposit that has been filled.
|
|
874
959
|
_g.sent();
|
|
875
|
-
//
|
|
876
|
-
//
|
|
877
|
-
//
|
|
878
|
-
//
|
|
879
|
-
//
|
|
880
|
-
// -
|
|
881
|
-
//
|
|
882
|
-
//
|
|
883
|
-
//
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
960
|
+
// Process deposits and maintain the following invariants:
|
|
961
|
+
// - Deposits matching fills that are not type SlowFill from previous bundle block ranges should produce
|
|
962
|
+
// refunds for those fills.
|
|
963
|
+
// - Deposits matching fills that are type SlowFill from previous bundle block ranges should be refunded to the
|
|
964
|
+
// depositor.
|
|
965
|
+
// - All deposits expiring in this bundle, even those sent in prior bundle block ranges, should be refunded
|
|
966
|
+
// to the depositor.
|
|
967
|
+
// - An expired deposit cannot be refunded if the deposit was filled.
|
|
968
|
+
// - If a deposit from a prior bundle expired in this bundle, had a slow fill request created for it
|
|
969
|
+
// in a prior bundle, and has not been filled yet, then an unexecutable slow fill leaf has been created
|
|
970
|
+
// and needs to be refunded to the HubPool.
|
|
971
|
+
// - Deposits matching slow fill requests from previous bundle block ranges should produce slow fills
|
|
972
|
+
// if the deposit has not been filled.
|
|
973
|
+
// Assumptions:
|
|
974
|
+
// - If the deposit has a matching fill or slow fill request in the bundle then we have already stored
|
|
975
|
+
// it in the relay hashes dictionary.
|
|
976
|
+
// - We've created refunds for all fills in this bundle matching a deposit.
|
|
977
|
+
// - We've created slow fill leaves for all slow fill requests in this bundle matching an unfilled deposit.
|
|
978
|
+
// - Deposits for the same relay data hash can be sent an arbitrary amount of times.
|
|
979
|
+
// - Deposits can be sent an arbitrary amount of time after a fill has been sent for the matching relay data.
|
|
980
|
+
return [4 /*yield*/, mapAsync(bundleDepositHashes, function (depositHash) { return __awaiter(_this, void 0, void 0, function () {
|
|
981
|
+
var _a, relayDataHash, index, _b, deposits, fill, slowFillRequest, deposit, fillToRefund, fillStatus, prefill, verifiedFill;
|
|
982
|
+
var _this = this;
|
|
983
|
+
return __generator(this, function (_c) {
|
|
984
|
+
switch (_c.label) {
|
|
891
985
|
case 0:
|
|
892
|
-
_a =
|
|
986
|
+
_a = decodeBundleDepositHash(depositHash), relayDataHash = _a.relayDataHash, index = _a.index;
|
|
987
|
+
_b = v3RelayHashes[relayDataHash], deposits = _b.deposits, fill = _b.fill, slowFillRequest = _b.slowFillRequest;
|
|
988
|
+
if (!deposits || deposits.length === 0) {
|
|
989
|
+
throw new Error("Deposits should exist in relay hash dictionary.");
|
|
990
|
+
}
|
|
991
|
+
deposit = deposits[index];
|
|
893
992
|
if (!deposit)
|
|
894
993
|
throw new Error("Deposit should exist in relay hash dictionary.");
|
|
895
|
-
|
|
896
|
-
// This is because a duplicate deposit for a pre-fill cannot get
|
|
897
|
-
// refunded to the depositor anymore because its fill status on-chain has changed to Filled. Therefore
|
|
898
|
-
// any duplicate deposits result in a net loss of funds for the depositor and effectively pay out
|
|
899
|
-
// the pre-filler.
|
|
900
|
-
// If fill exists in memory, then the only case in which we need to create a refund is if the
|
|
901
|
-
// the fill occurred in a previous bundle. There are no expiry refunds for filled deposits.
|
|
902
|
-
if (fill) {
|
|
903
|
-
if (canRefundPrefills && fill.blockNumber < destinationChainBlockRange[0] && !isSlowFill(fill)) {
|
|
904
|
-
// If fill is in the current bundle then we can assume there is already a refund for it, so only
|
|
905
|
-
// include this pre fill if the fill is in an older bundle. If fill is after this current bundle, then
|
|
906
|
-
// we won't consider it, following the previous treatment of fills after the bundle block range.
|
|
907
|
-
validatedBundleV3Fills.push(__assign(__assign({}, fill), { quoteTimestamp: deposit.quoteTimestamp }));
|
|
908
|
-
}
|
|
994
|
+
if (deposit.originChainId !== originChainId || deposit.destinationChainId !== destinationChainId) {
|
|
909
995
|
return [2 /*return*/];
|
|
910
996
|
}
|
|
997
|
+
if (!fill) return [3 /*break*/, 3];
|
|
998
|
+
if (!(canRefundPrefills && fill.blockNumber < destinationChainBlockRange[0])) return [3 /*break*/, 2];
|
|
999
|
+
return [4 /*yield*/, verifyFillRepayment(fill, destinationClient.spokePool.provider, v3RelayHashes[relayDataHash].deposits[0], allChainIds)];
|
|
1000
|
+
case 1:
|
|
1001
|
+
fillToRefund = _c.sent();
|
|
1002
|
+
if (!isDefined(fillToRefund)) {
|
|
1003
|
+
bundleUnrepayableFillsV3.push(fill);
|
|
1004
|
+
}
|
|
1005
|
+
else if (!isSlowFill(fill)) {
|
|
1006
|
+
v3RelayHashes[relayDataHash].fill = fillToRefund;
|
|
1007
|
+
validatedBundleV3Fills.push(__assign(__assign({}, fillToRefund), { quoteTimestamp: deposit.quoteTimestamp }));
|
|
1008
|
+
}
|
|
1009
|
+
else {
|
|
1010
|
+
updateExpiredDepositsV3(expiredDepositsToRefundV3, deposit);
|
|
1011
|
+
}
|
|
1012
|
+
_c.label = 2;
|
|
1013
|
+
case 2: return [2 /*return*/];
|
|
1014
|
+
case 3:
|
|
911
1015
|
// If a slow fill request exists in memory, then we know the deposit has not been filled because fills
|
|
912
|
-
// must follow slow fill requests and we would have seen the fill already if it existed
|
|
913
|
-
//
|
|
914
|
-
//
|
|
915
|
-
//
|
|
1016
|
+
// must follow slow fill requests and we would have seen the fill already if it existed.,
|
|
1017
|
+
// We can conclude that either the deposit has expired or we need to create a slow fill leaf for the
|
|
1018
|
+
// deposit because it has not been filled. Slow fill leaves were already created for requests sent
|
|
1019
|
+
// in the current bundle so only create new slow fill leaves for prior bundle deposits.
|
|
916
1020
|
if (slowFillRequest) {
|
|
917
1021
|
if (_depositIsExpired(deposit)) {
|
|
918
1022
|
updateExpiredDepositsV3(expiredDepositsToRefundV3, deposit);
|
|
919
1023
|
}
|
|
920
1024
|
else if (canRefundPrefills &&
|
|
921
1025
|
slowFillRequest.blockNumber < destinationChainBlockRange[0] &&
|
|
922
|
-
_canCreateSlowFillLeaf(deposit)
|
|
1026
|
+
_canCreateSlowFillLeaf(deposit) &&
|
|
1027
|
+
validatedBundleSlowFills.every(function (d) { return _this.getRelayHashFromEvent(d) !== relayDataHash; })) {
|
|
923
1028
|
validatedBundleSlowFills.push(deposit);
|
|
924
1029
|
}
|
|
925
1030
|
return [2 /*return*/];
|
|
926
1031
|
}
|
|
927
1032
|
return [4 /*yield*/, _getFillStatusForDeposit(deposit, destinationChainBlockRange[1])];
|
|
928
|
-
case
|
|
929
|
-
fillStatus =
|
|
930
|
-
if (!(fillStatus === FillStatus.Filled)) return [3 /*break*/,
|
|
931
|
-
return [4 /*yield*/,
|
|
932
|
-
case
|
|
933
|
-
prefill =
|
|
934
|
-
|
|
935
|
-
|
|
1033
|
+
case 4:
|
|
1034
|
+
fillStatus = _c.sent();
|
|
1035
|
+
if (!(fillStatus === FillStatus.Filled)) return [3 /*break*/, 8];
|
|
1036
|
+
return [4 /*yield*/, this.findMatchingFillEvent(deposit, destinationClient)];
|
|
1037
|
+
case 5:
|
|
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*/, 7];
|
|
1042
|
+
return [4 /*yield*/, verifyFillRepayment(prefill, destinationClient.spokePool.provider, deposit, allChainIds)];
|
|
1043
|
+
case 6:
|
|
1044
|
+
verifiedFill = _c.sent();
|
|
1045
|
+
if (!isDefined(verifiedFill)) {
|
|
1046
|
+
bundleUnrepayableFillsV3.push(prefill);
|
|
936
1047
|
}
|
|
937
|
-
|
|
938
|
-
|
|
1048
|
+
else if (!isSlowFill(verifiedFill)) {
|
|
1049
|
+
validatedBundleV3Fills.push(__assign(__assign({}, verifiedFill), { quoteTimestamp: deposit.quoteTimestamp }));
|
|
1050
|
+
}
|
|
1051
|
+
else {
|
|
1052
|
+
updateExpiredDepositsV3(expiredDepositsToRefundV3, deposit);
|
|
1053
|
+
}
|
|
1054
|
+
_c.label = 7;
|
|
1055
|
+
case 7: return [3 /*break*/, 9];
|
|
1056
|
+
case 8:
|
|
939
1057
|
if (_depositIsExpired(deposit)) {
|
|
940
1058
|
updateExpiredDepositsV3(expiredDepositsToRefundV3, deposit);
|
|
941
1059
|
}
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
// Slow fill requests for deposits from or to lite chains are considered invalid
|
|
1060
|
+
else if (fillStatus === FillStatus.RequestedSlowFill &&
|
|
1061
|
+
// Don't create duplicate slow fill requests for the same deposit.
|
|
1062
|
+
validatedBundleSlowFills.every(function (d) { return _this.getRelayHashFromEvent(d) !== relayDataHash; })) {
|
|
946
1063
|
if (canRefundPrefills && _canCreateSlowFillLeaf(deposit)) {
|
|
947
|
-
// If deposit newly expired, then we can't create a slow fill leaf for it but we can
|
|
948
|
-
// create a deposit refund for it.
|
|
949
1064
|
validatedBundleSlowFills.push(deposit);
|
|
950
1065
|
}
|
|
951
1066
|
}
|
|
952
|
-
|
|
953
|
-
case
|
|
1067
|
+
_c.label = 9;
|
|
1068
|
+
case 9: return [2 /*return*/];
|
|
954
1069
|
}
|
|
955
1070
|
});
|
|
956
1071
|
}); })];
|
|
957
1072
|
case 3:
|
|
958
|
-
//
|
|
959
|
-
//
|
|
960
|
-
//
|
|
961
|
-
//
|
|
962
|
-
//
|
|
963
|
-
// -
|
|
964
|
-
//
|
|
965
|
-
//
|
|
966
|
-
//
|
|
1073
|
+
// Process deposits and maintain the following invariants:
|
|
1074
|
+
// - Deposits matching fills that are not type SlowFill from previous bundle block ranges should produce
|
|
1075
|
+
// refunds for those fills.
|
|
1076
|
+
// - Deposits matching fills that are type SlowFill from previous bundle block ranges should be refunded to the
|
|
1077
|
+
// depositor.
|
|
1078
|
+
// - All deposits expiring in this bundle, even those sent in prior bundle block ranges, should be refunded
|
|
1079
|
+
// to the depositor.
|
|
1080
|
+
// - An expired deposit cannot be refunded if the deposit was filled.
|
|
1081
|
+
// - If a deposit from a prior bundle expired in this bundle, had a slow fill request created for it
|
|
1082
|
+
// in a prior bundle, and has not been filled yet, then an unexecutable slow fill leaf has been created
|
|
1083
|
+
// and needs to be refunded to the HubPool.
|
|
1084
|
+
// - Deposits matching slow fill requests from previous bundle block ranges should produce slow fills
|
|
1085
|
+
// if the deposit has not been filled.
|
|
1086
|
+
// Assumptions:
|
|
1087
|
+
// - If the deposit has a matching fill or slow fill request in the bundle then we have already stored
|
|
1088
|
+
// it in the relay hashes dictionary.
|
|
1089
|
+
// - We've created refunds for all fills in this bundle matching a deposit.
|
|
1090
|
+
// - We've created slow fill leaves for all slow fill requests in this bundle matching an unfilled deposit.
|
|
1091
|
+
// - Deposits for the same relay data hash can be sent an arbitrary amount of times.
|
|
1092
|
+
// - Deposits can be sent an arbitrary amount of time after a fill has been sent for the matching relay data.
|
|
967
1093
|
_g.sent();
|
|
968
1094
|
// For all fills that came after a slow fill request, we can now check if the slow fill request
|
|
969
1095
|
// was a valid one and whether it was created in a previous bundle. If so, then it created a slow fill
|
|
970
1096
|
// leaf that is now unexecutable.
|
|
971
1097
|
fastFillsReplacingSlowFills.forEach(function (relayDataHash) {
|
|
972
|
-
var _a = v3RelayHashes[relayDataHash],
|
|
1098
|
+
var _a = v3RelayHashes[relayDataHash], deposits = _a.deposits, slowFillRequest = _a.slowFillRequest, fill = _a.fill;
|
|
973
1099
|
assert((fill === null || fill === void 0 ? void 0 : fill.relayExecutionInfo.fillType) === FillType.ReplacedSlowFill, "Fill type should be ReplacedSlowFill.");
|
|
974
1100
|
// Needed for TSC - are implicitely checking that deposit exists by making it to this point.
|
|
975
|
-
if (!
|
|
1101
|
+
if (!deposits || deposits.length < 1) {
|
|
976
1102
|
throw new Error("Deposit should exist in relay hash dictionary.");
|
|
977
1103
|
}
|
|
978
1104
|
// We should never push fast fills involving lite chains here because slow fill requests for them are invalid:
|
|
979
|
-
assert(_canCreateSlowFillLeaf(
|
|
1105
|
+
assert(_canCreateSlowFillLeaf(deposits[0]), "fastFillsReplacingSlowFills should contain only deposits that can be slow filled");
|
|
980
1106
|
var destinationBlockRange = getBlockRangeForChain(blockRangesForChains, destinationChainId, chainIds);
|
|
981
1107
|
if (
|
|
982
1108
|
// If there is a slow fill request in this bundle that matches the relay hash, then there was no slow fill
|
|
983
1109
|
// created that would be considered excess.
|
|
984
1110
|
!slowFillRequest ||
|
|
985
1111
|
slowFillRequest.blockNumber < destinationBlockRange[0]) {
|
|
986
|
-
validatedBundleUnexecutableSlowFills.push(
|
|
1112
|
+
validatedBundleUnexecutableSlowFills.push(deposits[0]);
|
|
987
1113
|
}
|
|
988
1114
|
});
|
|
989
1115
|
return [2 /*return*/];
|
|
@@ -1027,13 +1153,17 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
1027
1153
|
// For all deposits older than this bundle, we need to check if they expired in this bundle and if they did,
|
|
1028
1154
|
// whether there was a slow fill created for it in a previous bundle that is now unexecutable and replaced
|
|
1029
1155
|
// by a new expired deposit refund.
|
|
1030
|
-
return [4 /*yield*/, forEachAsync(olderDepositHashes, function (
|
|
1031
|
-
var _a,
|
|
1032
|
-
return __generator(this, function (
|
|
1033
|
-
switch (
|
|
1156
|
+
return [4 /*yield*/, forEachAsync(olderDepositHashes, function (depositHash) { return __awaiter(_this, void 0, void 0, function () {
|
|
1157
|
+
var _a, relayDataHash, index, _b, deposits, slowFillRequest, fill, deposit, destinationChainId, destinationBlockRange, fillStatus;
|
|
1158
|
+
return __generator(this, function (_c) {
|
|
1159
|
+
switch (_c.label) {
|
|
1034
1160
|
case 0:
|
|
1035
|
-
_a =
|
|
1036
|
-
|
|
1161
|
+
_a = decodeBundleDepositHash(depositHash), relayDataHash = _a.relayDataHash, index = _a.index;
|
|
1162
|
+
_b = v3RelayHashes[relayDataHash], deposits = _b.deposits, slowFillRequest = _b.slowFillRequest, fill = _b.fill;
|
|
1163
|
+
if (!deposits || deposits.length < 1) {
|
|
1164
|
+
throw new Error("Deposit should exist in relay hash dictionary.");
|
|
1165
|
+
}
|
|
1166
|
+
deposit = deposits[index];
|
|
1037
1167
|
destinationChainId = deposit.destinationChainId;
|
|
1038
1168
|
destinationBlockRange = getBlockRangeForChain(blockRangesForChains, destinationChainId, chainIds);
|
|
1039
1169
|
if (!
|
|
@@ -1047,7 +1177,7 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
1047
1177
|
return [3 /*break*/, 2];
|
|
1048
1178
|
return [4 /*yield*/, _getFillStatusForDeposit(deposit, destinationBlockRange[1])];
|
|
1049
1179
|
case 1:
|
|
1050
|
-
fillStatus =
|
|
1180
|
+
fillStatus = _c.sent();
|
|
1051
1181
|
// If there is no matching fill and the deposit expired in this bundle and the fill status on-chain is not
|
|
1052
1182
|
// Filled, then we can to refund it as an expired deposit.
|
|
1053
1183
|
if (fillStatus !== FillStatus.Filled) {
|
|
@@ -1069,7 +1199,7 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
1069
1199
|
if (!slowFillRequest || slowFillRequest.blockNumber < destinationBlockRange[0]) {
|
|
1070
1200
|
validatedBundleUnexecutableSlowFills.push(deposit);
|
|
1071
1201
|
}
|
|
1072
|
-
|
|
1202
|
+
_c.label = 2;
|
|
1073
1203
|
case 2: return [2 /*return*/];
|
|
1074
1204
|
}
|
|
1075
1205
|
});
|
|
@@ -1084,7 +1214,7 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
1084
1214
|
promises = [
|
|
1085
1215
|
validatedBundleV3Fills.length > 0
|
|
1086
1216
|
? this.clients.hubPoolClient.batchComputeRealizedLpFeePct(validatedBundleV3Fills.map(function (fill) {
|
|
1087
|
-
var matchedDeposit = v3RelayHashes[_this.getRelayHashFromEvent(fill)].
|
|
1217
|
+
var matchedDeposit = v3RelayHashes[_this.getRelayHashFromEvent(fill)].deposits[0];
|
|
1088
1218
|
assert(isDefined(matchedDeposit), "Deposit should exist in relay hash dictionary.");
|
|
1089
1219
|
var paymentChainId = getRefundInformationFromFill(fill, _this.clients.hubPoolClient, blockRangesForChains, chainIds, matchedDeposit.fromLiteChain).chainToSendRefundTo;
|
|
1090
1220
|
return __assign(__assign({}, fill), { paymentChainId: paymentChainId });
|
|
@@ -1111,14 +1241,23 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
1111
1241
|
v3FillLpFees.forEach(function (_a, idx) {
|
|
1112
1242
|
var realizedLpFeePct = _a.realizedLpFeePct;
|
|
1113
1243
|
var fill = validatedBundleV3Fills[idx];
|
|
1114
|
-
var associatedDeposit = v3RelayHashes[_this.getRelayHashFromEvent(fill)].
|
|
1244
|
+
var associatedDeposit = v3RelayHashes[_this.getRelayHashFromEvent(fill)].deposits[0];
|
|
1115
1245
|
assert(isDefined(associatedDeposit), "Deposit should exist in relay hash dictionary.");
|
|
1116
1246
|
var _b = getRefundInformationFromFill(fill, _this.clients.hubPoolClient, blockRangesForChains, chainIds, associatedDeposit.fromLiteChain), chainToSendRefundTo = _b.chainToSendRefundTo, repaymentToken = _b.repaymentToken;
|
|
1117
|
-
updateBundleFillsV3(bundleFillsV3, fill, realizedLpFeePct, chainToSendRefundTo, repaymentToken);
|
|
1247
|
+
updateBundleFillsV3(bundleFillsV3, fill, realizedLpFeePct, chainToSendRefundTo, repaymentToken, fill.relayer);
|
|
1118
1248
|
});
|
|
1119
1249
|
v3SlowFillLpFees.forEach(function (_a, idx) {
|
|
1120
1250
|
var lpFeePct = _a.realizedLpFeePct;
|
|
1121
1251
|
var deposit = validatedBundleSlowFills[idx];
|
|
1252
|
+
// We should not create slow fill leaves for duplicate deposit hashes and we should only create a slow
|
|
1253
|
+
// fill leaf for the first deposit (the quote timestamp of the deposit determines the LP fee, so its
|
|
1254
|
+
// important we pick out the correct deposit). Deposits are pushed into validatedBundleSlowFills in ascending
|
|
1255
|
+
// order so the following slice will only match the first deposit.
|
|
1256
|
+
var relayDataHash = _this.getRelayHashFromEvent(deposit);
|
|
1257
|
+
if (validatedBundleSlowFills.slice(0, idx).some(function (d) { return _this.getRelayHashFromEvent(d) === relayDataHash; })) {
|
|
1258
|
+
return;
|
|
1259
|
+
}
|
|
1260
|
+
assert(!_depositIsExpired(deposit), "Cannot create slow fill leaf for expired deposit.");
|
|
1122
1261
|
updateBundleSlowFills(bundleSlowFillsV3, __assign(__assign({}, deposit), { lpFeePct: lpFeePct }));
|
|
1123
1262
|
});
|
|
1124
1263
|
v3UnexecutableSlowFillLpFees.forEach(function (_a, idx) {
|
|
@@ -1126,15 +1265,31 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
1126
1265
|
var deposit = validatedBundleUnexecutableSlowFills[idx];
|
|
1127
1266
|
updateBundleExcessSlowFills(unexecutableSlowFills, __assign(__assign({}, deposit), { lpFeePct: lpFeePct }));
|
|
1128
1267
|
});
|
|
1129
|
-
v3SpokeEventsReadable = prettyPrintV3SpokePoolEvents(bundleDepositsV3, bundleFillsV3,
|
|
1268
|
+
v3SpokeEventsReadable = prettyPrintV3SpokePoolEvents(bundleDepositsV3, bundleFillsV3, bundleSlowFillsV3, expiredDepositsToRefundV3, unexecutableSlowFills);
|
|
1130
1269
|
if (bundleInvalidFillsV3.length > 0) {
|
|
1131
1270
|
this.logger.debug({
|
|
1132
1271
|
at: "BundleDataClient#loadData",
|
|
1133
|
-
message: "Finished loading V3 spoke pool data and found some invalid
|
|
1272
|
+
message: "Finished loading V3 spoke pool data and found some invalid fills in range",
|
|
1134
1273
|
blockRangesForChains: blockRangesForChains,
|
|
1135
1274
|
bundleInvalidFillsV3: bundleInvalidFillsV3,
|
|
1136
1275
|
});
|
|
1137
1276
|
}
|
|
1277
|
+
if (bundleUnrepayableFillsV3.length > 0) {
|
|
1278
|
+
this.logger.debug({
|
|
1279
|
+
at: "BundleDataClient#loadData",
|
|
1280
|
+
message: "Finished loading V3 spoke pool data and found some unrepayable fills in range",
|
|
1281
|
+
blockRangesForChains: blockRangesForChains,
|
|
1282
|
+
bundleUnrepayableFillsV3: bundleUnrepayableFillsV3,
|
|
1283
|
+
});
|
|
1284
|
+
}
|
|
1285
|
+
if (bundleInvalidSlowFillRequests.length > 0) {
|
|
1286
|
+
this.logger.debug({
|
|
1287
|
+
at: "BundleDataClient#loadData",
|
|
1288
|
+
message: "Finished loading V3 spoke pool data and found some invalid slow fill requests in range",
|
|
1289
|
+
blockRangesForChains: blockRangesForChains,
|
|
1290
|
+
bundleInvalidSlowFillRequests: bundleInvalidSlowFillRequests,
|
|
1291
|
+
});
|
|
1292
|
+
}
|
|
1138
1293
|
this.logger.debug({
|
|
1139
1294
|
at: "BundleDataClient#loadDataFromScratch",
|
|
1140
1295
|
message: "Computed bundle data in ".concat(Math.round(performance.now() - start) / 1000, "s."),
|
|
@@ -1159,6 +1314,16 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
1159
1314
|
BundleDataClient.prototype.getRelayHashFromEvent = function (event) {
|
|
1160
1315
|
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);
|
|
1161
1316
|
};
|
|
1317
|
+
BundleDataClient.prototype.findMatchingFillEvent = function (deposit, spokePoolClient) {
|
|
1318
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1319
|
+
return __generator(this, function (_a) {
|
|
1320
|
+
switch (_a.label) {
|
|
1321
|
+
case 0: return [4 /*yield*/, findFillEvent(spokePoolClient.spokePool, deposit, spokePoolClient.deploymentBlock, spokePoolClient.latestBlockSearched)];
|
|
1322
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
1323
|
+
}
|
|
1324
|
+
});
|
|
1325
|
+
});
|
|
1326
|
+
};
|
|
1162
1327
|
BundleDataClient.prototype.getBundleBlockTimestamps = function (chainIds, blockRangesForChains, spokePoolClients) {
|
|
1163
1328
|
return __awaiter(this, void 0, void 0, function () {
|
|
1164
1329
|
var _a, _b;
|
|
@@ -1168,7 +1333,7 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
1168
1333
|
case 0:
|
|
1169
1334
|
_b = (_a = Object).fromEntries;
|
|
1170
1335
|
return [4 /*yield*/, mapAsync(chainIds, function (chainId, index) { return __awaiter(_this, void 0, void 0, function () {
|
|
1171
|
-
var blockRangeForChain, _startBlockForChain, _endBlockForChain, spokePoolClient, startBlockForChain, endBlockForChain, _a, startTime,
|
|
1336
|
+
var blockRangeForChain, _startBlockForChain, _endBlockForChain, spokePoolClient, startBlockForChain, endBlockForChain, _a, startTime, _endTime, _b, endBlockDelta, endTime;
|
|
1172
1337
|
return __generator(this, function (_c) {
|
|
1173
1338
|
switch (_c.label) {
|
|
1174
1339
|
case 0:
|
|
@@ -1183,7 +1348,7 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
1183
1348
|
return [2 /*return*/];
|
|
1184
1349
|
}
|
|
1185
1350
|
startBlockForChain = Math.min(_startBlockForChain, spokePoolClient.latestBlockSearched);
|
|
1186
|
-
endBlockForChain = Math.min(_endBlockForChain, spokePoolClient.latestBlockSearched);
|
|
1351
|
+
endBlockForChain = Math.min(_endBlockForChain + 1, spokePoolClient.latestBlockSearched);
|
|
1187
1352
|
return [4 /*yield*/, spokePoolClient.getTimestampForBlock(startBlockForChain)];
|
|
1188
1353
|
case 1:
|
|
1189
1354
|
_b = [
|
|
@@ -1193,9 +1358,11 @@ var BundleDataClient = /** @class */ (function () {
|
|
|
1193
1358
|
case 2:
|
|
1194
1359
|
_a = _b.concat([
|
|
1195
1360
|
_c.sent()
|
|
1196
|
-
]), startTime = _a[0],
|
|
1361
|
+
]), startTime = _a[0], _endTime = _a[1];
|
|
1362
|
+
endBlockDelta = endBlockForChain > startBlockForChain ? 1 : 0;
|
|
1363
|
+
endTime = Math.max(0, _endTime - endBlockDelta);
|
|
1197
1364
|
// Sanity checks:
|
|
1198
|
-
assert(endTime >= startTime, "End time should be greater than start time.");
|
|
1365
|
+
assert(endTime >= startTime, "End time for block ".concat(endBlockForChain, " should be greater than start time for block ").concat(startBlockForChain, ": ").concat(endTime, " >= ").concat(startTime, "."));
|
|
1199
1366
|
assert(startBlockForChain === 0 || startTime > 0, "Start timestamp must be greater than 0 if the start block is greater than 0.");
|
|
1200
1367
|
return [2 /*return*/, [chainId, [startTime, endTime]]];
|
|
1201
1368
|
}
|