Skip to content

Commit 3bb7a25

Browse files
nicholaspaimrice32
authored andcommitted
fix(FillUtils): verifyFillRepayment should check that repayment chain has pool rebalance route
We cannot refund fills whose repayment chain doesn't exist for an input token.
1 parent 7faa5d1 commit 3bb7a25

File tree

2 files changed

+33
-24
lines changed

2 files changed

+33
-24
lines changed

src/clients/BundleDataClient/BundleDataClient.ts

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
Deposit,
1919
DepositWithBlock,
2020
} from "../../interfaces";
21-
import { AcrossConfigStoreClient, SpokePoolClient } from "..";
21+
import { AcrossConfigStoreClient, HubPoolClient, SpokePoolClient } from "..";
2222
import {
2323
BigNumber,
2424
bnZero,
@@ -91,7 +91,7 @@ function updateBundleFillsV3(
9191
lpFeePct: BigNumber,
9292
repaymentChainId: number,
9393
repaymentToken: string,
94-
repaymentAddress: string
94+
repaymentAddress: string,
9595
): void {
9696
// We shouldn't pass any unrepayable fills into this function, so we perform an extra safety check.
9797
assert(
@@ -355,11 +355,7 @@ export class BundleDataClient {
355355
fill,
356356
this.spokePoolClients[fill.destinationChainId].spokePool.provider,
357357
matchingDeposit,
358-
// @dev: to get valid repayment chain ID's, get all chain IDs for the bundle block range and remove
359-
// disabled block ranges.
360-
this.clients.configStoreClient
361-
.getChainIdIndicesForBlock(blockRanges[0][1])
362-
.filter((_chainId, i) => !isChainDisabled(blockRanges[i]))
358+
this.clients.hubPoolClient,
363359
);
364360
if (!isDefined(validRepayment)) {
365361
return false;
@@ -919,7 +915,7 @@ export class BundleDataClient {
919915
fill,
920916
destinationClient.spokePool.provider,
921917
v3RelayHashes[relayDataHash].deposits![0],
922-
allChainIds
918+
this.clients.hubPoolClient,
923919
);
924920
if (!isDefined(fillToRefund)) {
925921
bundleUnrepayableFillsV3.push(fill);
@@ -1013,7 +1009,7 @@ export class BundleDataClient {
10131009
fill,
10141010
destinationClient.spokePool.provider,
10151011
matchedDeposit,
1016-
allChainIds
1012+
this.clients.hubPoolClient,
10171013
);
10181014
if (!isDefined(fillToRefund)) {
10191015
bundleUnrepayableFillsV3.push(fill);
@@ -1187,7 +1183,7 @@ export class BundleDataClient {
11871183
fill,
11881184
destinationClient.spokePool.provider,
11891185
v3RelayHashes[relayDataHash].deposits![0],
1190-
allChainIds
1186+
this.clients.hubPoolClient,
11911187
);
11921188
if (!isDefined(fillToRefund)) {
11931189
bundleUnrepayableFillsV3.push(fill);
@@ -1241,7 +1237,7 @@ export class BundleDataClient {
12411237
prefill!,
12421238
destinationClient.spokePool.provider,
12431239
deposit,
1244-
allChainIds
1240+
this.clients.hubPoolClient,
12451241
);
12461242
if (!isDefined(verifiedFill)) {
12471243
bundleUnrepayableFillsV3.push(prefill!);
@@ -1415,7 +1411,16 @@ export class BundleDataClient {
14151411
chainIds,
14161412
associatedDeposit!.fromLiteChain
14171413
);
1418-
updateBundleFillsV3(bundleFillsV3, fill, realizedLpFeePct, chainToSendRefundTo, repaymentToken, fill.relayer);
1414+
updateBundleFillsV3(
1415+
bundleFillsV3,
1416+
fill,
1417+
realizedLpFeePct,
1418+
chainToSendRefundTo,
1419+
repaymentToken,
1420+
fill.relayer,
1421+
this.clients.hubPoolClient,
1422+
associatedDeposit.quoteBlockNumber
1423+
);
14191424
});
14201425
v3SlowFillLpFees.forEach(({ realizedLpFeePct: lpFeePct }, idx) => {
14211426
const deposit = validatedBundleSlowFills[idx];

src/clients/BundleDataClient/utils/FillUtils.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,11 @@ export function getRepaymentChainId(fill: Fill, matchedDeposit: Deposit): number
5252
return matchedDeposit.fromLiteChain ? fill.originChainId : fill.repaymentChainId;
5353
}
5454

55-
export function isEvmRepaymentValid(
56-
fill: Fill,
57-
repaymentChainId: number,
58-
possibleRepaymentChainIds: number[] = []
59-
): boolean {
55+
export function isEvmRepaymentValid(fill: Fill, repaymentChainId: number): boolean {
6056
// Slow fills don't result in repayments so they're always valid.
6157
if (isSlowFill(fill)) {
6258
return true;
6359
}
64-
// Return undefined if the requested repayment chain ID is not in a passed in set of eligible chains. This can
65-
// be used by the caller to narrow the chains to those that are not disabled in the config store.
66-
if (possibleRepaymentChainIds.length > 0 && !possibleRepaymentChainIds.includes(repaymentChainId)) {
67-
return false;
68-
}
6960
return chainIsEvm(repaymentChainId) && isValidEvmAddress(fill.relayer);
7061
}
7162

@@ -75,12 +66,25 @@ export async function verifyFillRepayment(
7566
_fill: FillWithBlock,
7667
destinationChainProvider: providers.Provider,
7768
matchedDeposit: DepositWithBlock,
78-
possibleRepaymentChainIds: number[] = []
69+
hubPoolClient: HubPoolClient
7970
): Promise<FillWithBlock | undefined> {
8071
const fill = _.cloneDeep(_fill);
8172

8273
const repaymentChainId = getRepaymentChainId(fill, matchedDeposit);
83-
const validEvmRepayment = isEvmRepaymentValid(fill, repaymentChainId, possibleRepaymentChainIds);
74+
const validEvmRepayment = isEvmRepaymentValid(fill, repaymentChainId);
75+
try {
76+
const l1TokenCounterpart = hubPoolClient.getL1TokenForL2TokenAtBlock(
77+
fill.inputToken,
78+
fill.originChainId,
79+
matchedDeposit.quoteBlockNumber
80+
);
81+
hubPoolClient.getL2TokenForL1TokenAtBlock(l1TokenCounterpart, repaymentChainId, matchedDeposit.quoteBlockNumber);
82+
// Repayment token could be found, this is a valid repayment chain.
83+
} catch {
84+
// Repayment token doesn't exist on repayment chain via PoolRebalanceRoutes, impossible to repay filler.
85+
return undefined;
86+
}
87+
8488

8589
// Case 1: Repayment chain is EVM and repayment address is valid EVM address.
8690
if (validEvmRepayment) {

0 commit comments

Comments
 (0)