Skip to content

Commit 9c7c410

Browse files
authored
improve: Handle deposits referencing input/output/repayment tokens that do not map to PoolRebalanceRoutes (#970)
1 parent 99a4fd3 commit 9c7c410

File tree

12 files changed

+571
-246
lines changed

12 files changed

+571
-246
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@across-protocol/sdk",
33
"author": "UMA Team",
4-
"version": "4.1.44",
4+
"version": "4.1.45",
55
"license": "AGPL-3.0",
66
"homepage": "https://docs.across.to/reference/sdk",
77
"files": [

src/clients/BundleDataClient/BundleDataClient.ts

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import {
4141
chainIsEvm,
4242
isValidEvmAddress,
4343
duplicateEvent,
44+
invalidOutputToken,
4445
} from "../../utils";
4546
import winston from "winston";
4647
import {
@@ -321,6 +322,7 @@ export class BundleDataClient {
321322
// @dev This helper function should probably be moved to the InventoryClient
322323
async getApproximateRefundsForBlockRange(chainIds: number[], blockRanges: number[][]): Promise<CombinedRefunds> {
323324
const refundsForChain: CombinedRefunds = {};
325+
const bundleEndBlockForMainnet = blockRanges[0][1];
324326
for (const chainId of chainIds) {
325327
if (this.spokePoolClients[chainId] === undefined) {
326328
continue;
@@ -335,7 +337,8 @@ export class BundleDataClient {
335337
if (
336338
fill.blockNumber < blockRanges[chainIndex][0] ||
337339
fill.blockNumber > blockRanges[chainIndex][1] ||
338-
isZeroValueFillOrSlowFillRequest(fill)
340+
isZeroValueFillOrSlowFillRequest(fill) ||
341+
invalidOutputToken(fill)
339342
) {
340343
return false;
341344
}
@@ -362,17 +365,19 @@ export class BundleDataClient {
362365
_fill,
363366
spokeClient.spokePool.provider,
364367
matchingDeposit,
365-
this.clients.hubPoolClient
368+
this.clients.hubPoolClient,
369+
bundleEndBlockForMainnet
366370
);
367371
if (!isDefined(fill)) {
368372
return;
369373
}
370374
const { chainToSendRefundTo, repaymentToken } = getRefundInformationFromFill(
371-
fill,
375+
{
376+
...fill,
377+
fromLiteChain: matchingDeposit.fromLiteChain,
378+
},
372379
this.clients.hubPoolClient,
373-
blockRanges,
374-
this.chainIdListForBundleEvaluationBlockNumbers,
375-
matchingDeposit.fromLiteChain
380+
bundleEndBlockForMainnet
376381
);
377382
// Assume that lp fees are 0 for the sake of speed. In the future we could batch compute
378383
// these or make hardcoded assumptions based on the origin-repayment chain direction. This might result
@@ -635,6 +640,7 @@ export class BundleDataClient {
635640
}
636641

637642
const chainIds = this.clients.configStoreClient.getChainIdIndicesForBlock(blockRangesForChains[0][0]);
643+
const bundleEndBlockForMainnet = blockRangesForChains[0][1];
638644

639645
if (blockRangesForChains.length > chainIds.length) {
640646
throw new Error(
@@ -671,7 +677,7 @@ export class BundleDataClient {
671677
deposit.originChainId,
672678
deposit.outputToken,
673679
deposit.destinationChainId,
674-
deposit.quoteBlockNumber
680+
bundleEndBlockForMainnet
675681
) &&
676682
// Cannot slow fill from or to a lite chain.
677683
!deposit.fromLiteChain &&
@@ -848,7 +854,10 @@ export class BundleDataClient {
848854
// tokens to the filler. We can't remove non-empty message deposit here in case there is a slow fill
849855
// request for the deposit, we'd want to see the fill took place.
850856
.filter(
851-
(fill) => fill.blockNumber <= destinationChainBlockRange[1] && !isZeroValueFillOrSlowFillRequest(fill)
857+
(fill) =>
858+
fill.blockNumber <= destinationChainBlockRange[1] &&
859+
!isZeroValueFillOrSlowFillRequest(fill) &&
860+
!invalidOutputToken(fill)
852861
),
853862
async (fill) => {
854863
fillCounter++;
@@ -867,7 +876,8 @@ export class BundleDataClient {
867876
fill,
868877
destinationClient.spokePool.provider,
869878
deposits[0],
870-
this.clients.hubPoolClient
879+
this.clients.hubPoolClient,
880+
bundleEndBlockForMainnet
871881
);
872882
if (!isDefined(fillToRefund)) {
873883
bundleUnrepayableFillsV3.push(fill);
@@ -971,7 +981,8 @@ export class BundleDataClient {
971981
fill,
972982
destinationClient.spokePool.provider,
973983
matchedDeposit,
974-
this.clients.hubPoolClient
984+
this.clients.hubPoolClient,
985+
bundleEndBlockForMainnet
975986
);
976987
if (!isDefined(fillToRefund)) {
977988
bundleUnrepayableFillsV3.push(fill);
@@ -1017,7 +1028,9 @@ export class BundleDataClient {
10171028
.getSlowFillRequestsForOriginChain(originChainId)
10181029
.filter(
10191030
(request) =>
1020-
request.blockNumber <= destinationChainBlockRange[1] && !isZeroValueFillOrSlowFillRequest(request)
1031+
request.blockNumber <= destinationChainBlockRange[1] &&
1032+
!isZeroValueFillOrSlowFillRequest(request) &&
1033+
!invalidOutputToken(request)
10211034
),
10221035
async (slowFillRequest: SlowFillRequestWithBlock) => {
10231036
const relayDataHash = getRelayEventKey(slowFillRequest);
@@ -1149,7 +1162,8 @@ export class BundleDataClient {
11491162
fill,
11501163
destinationClient.spokePool.provider,
11511164
deposits[0],
1152-
this.clients.hubPoolClient
1165+
this.clients.hubPoolClient,
1166+
bundleEndBlockForMainnet
11531167
);
11541168
if (!isDefined(fillToRefund)) {
11551169
bundleUnrepayableFillsV3.push(fill);
@@ -1205,7 +1219,8 @@ export class BundleDataClient {
12051219
prefill,
12061220
destinationClient.spokePool.provider,
12071221
deposit,
1208-
this.clients.hubPoolClient
1222+
this.clients.hubPoolClient,
1223+
bundleEndBlockForMainnet
12091224
);
12101225
if (!isDefined(verifiedFill)) {
12111226
bundleUnrepayableFillsV3.push(prefill);
@@ -1339,11 +1354,12 @@ export class BundleDataClient {
13391354
const matchedDeposit = deposits[0];
13401355
assert(isDefined(matchedDeposit), "Deposit should exist in relay hash dictionary.");
13411356
const { chainToSendRefundTo: paymentChainId } = getRefundInformationFromFill(
1342-
fill,
1357+
{
1358+
...fill,
1359+
fromLiteChain: matchedDeposit.fromLiteChain,
1360+
},
13431361
this.clients.hubPoolClient,
1344-
blockRangesForChains,
1345-
chainIds,
1346-
matchedDeposit.fromLiteChain
1362+
bundleEndBlockForMainnet
13471363
);
13481364
return {
13491365
...fill,
@@ -1385,11 +1401,12 @@ export class BundleDataClient {
13851401
const associatedDeposit = deposits[0];
13861402
assert(isDefined(associatedDeposit), "Deposit should exist in relay hash dictionary.");
13871403
const { chainToSendRefundTo, repaymentToken } = getRefundInformationFromFill(
1388-
fill,
1404+
{
1405+
...fill,
1406+
fromLiteChain: associatedDeposit.fromLiteChain,
1407+
},
13891408
this.clients.hubPoolClient,
1390-
blockRangesForChains,
1391-
chainIds,
1392-
associatedDeposit.fromLiteChain
1409+
bundleEndBlockForMainnet
13931410
);
13941411
updateBundleFillsV3(bundleFillsV3, fill, realizedLpFeePct, chainToSendRefundTo, repaymentToken, fill.relayer);
13951412
});

src/clients/BundleDataClient/utils/DataworkerUtils.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,13 @@ export function _buildPoolRebalanceRoot(
146146
const repaymentChainId = Number(_repaymentChainId);
147147
Object.entries(fillsForChain).forEach(
148148
([l2TokenAddress, { realizedLpFees: totalRealizedLpFee, totalRefundAmount }]) => {
149+
// If the repayment token and repayment chain ID do not map to a PoolRebalanceRoute graph, then
150+
// there are no relevant L1 running balances.
151+
if (
152+
!clients.hubPoolClient.l2TokenHasPoolRebalanceRoute(l2TokenAddress, repaymentChainId, mainnetBundleEndBlock)
153+
) {
154+
return;
155+
}
149156
const l1TokenCounterpart = clients.hubPoolClient.getL1TokenForL2TokenAtBlock(
150157
l2TokenAddress,
151158
repaymentChainId,
@@ -215,7 +222,24 @@ export function _buildPoolRebalanceRoot(
215222
Object.entries(bundleV3Deposits).forEach(([, depositsForChain]) => {
216223
Object.entries(depositsForChain).forEach(([, deposits]) => {
217224
deposits.forEach((deposit) => {
218-
updateRunningBalanceForDeposit(runningBalances, clients.hubPoolClient, deposit, deposit.inputAmount.mul(-1));
225+
// If the repayment token and repayment chain ID do not map to a PoolRebalanceRoute graph, then
226+
// there are no relevant L1 running balances.
227+
if (
228+
!clients.hubPoolClient.l2TokenHasPoolRebalanceRoute(
229+
deposit.inputToken,
230+
deposit.originChainId,
231+
mainnetBundleEndBlock
232+
)
233+
) {
234+
return;
235+
}
236+
updateRunningBalanceForDeposit(
237+
runningBalances,
238+
clients.hubPoolClient,
239+
deposit,
240+
deposit.inputAmount.mul(-1),
241+
mainnetBundleEndBlock
242+
);
219243
});
220244
});
221245
});
@@ -229,6 +253,17 @@ export function _buildPoolRebalanceRoot(
229253
const originChainId = Number(_originChainId);
230254
Object.entries(depositsForChain).forEach(([inputToken, deposits]) => {
231255
deposits.forEach((deposit) => {
256+
// If the repayment token and repayment chain ID do not map to a PoolRebalanceRoute graph, then
257+
// there are no relevant L1 running balances.
258+
if (
259+
!clients.hubPoolClient.l2TokenHasPoolRebalanceRoute(
260+
deposit.inputToken,
261+
deposit.originChainId,
262+
mainnetBundleEndBlock
263+
)
264+
) {
265+
return;
266+
}
232267
const l1TokenCounterpart = clients.hubPoolClient.getL1TokenForL2TokenAtBlock(
233268
inputToken,
234269
originChainId,

0 commit comments

Comments
 (0)