diff --git a/src/dataworker/Dataworker.ts b/src/dataworker/Dataworker.ts index 87b9a3319..35e3ca7b2 100644 --- a/src/dataworker/Dataworker.ts +++ b/src/dataworker/Dataworker.ts @@ -1802,6 +1802,11 @@ export class Dataworker { // Now, go through each L1 token and see if we need to update the exchange rate for it. await sdkUtils.forEachAsync(Object.keys(aggregateNetSendAmounts), async (l1Token) => { const requiredNetSendAmountForL1Token = aggregateNetSendAmounts[l1Token]; + // If netSendAmounts is 0, there is no need to update this exchange rate. + assert(requiredNetSendAmountForL1Token.gte(0), "Aggregate net send amount should be >= 0"); + if (requiredNetSendAmountForL1Token.eq(0)) { + return; + } // The "used" balance kept in the BalanceAllocator should have adjusted for the netSendAmounts and relayer refund leaf // executions above. Therefore, check if the current liquidReserves is less than the pool rebalance leaf's netSendAmount // and the virtual hubPoolBalance would be enough to execute it. If so, then add an update exchange rate call to make sure that @@ -1819,7 +1824,8 @@ export class Dataworker { if (currHubPoolLiquidReserves.gte(requiredNetSendAmountForL1Token)) { this.logger.debug({ at: "Dataworker#_updateExchangeRatesBeforeExecutingNonHubChainLeaves", - message: `Skipping exchange rate update for ${tokenSymbol} because current liquid reserves > required netSendAmount`, + message: `Skipping exchange rate update for ${tokenSymbol} because current liquid reserves > required netSendAmount for non-hubChain pool leaves`, + leavesToExecute: poolRebalanceLeaves.map((leaf) => leaf.chainId), currHubPoolLiquidReserves, requiredNetSendAmountForL1Token, l1Token, diff --git a/test/Dataworker.executePoolRebalances.ts b/test/Dataworker.executePoolRebalances.ts index ac655ba57..373a89e77 100644 --- a/test/Dataworker.executePoolRebalances.ts +++ b/test/Dataworker.executePoolRebalances.ts @@ -28,6 +28,7 @@ import { sinon, assertPromiseError, randomAddress, + lastSpyLogIncludes, } from "./utils"; // Tested @@ -296,6 +297,18 @@ describe("Dataworker: Execute pool rebalances", async function () { expect(updated.size).to.equal(0); expect(multiCallerClient.transactionCount()).to.equal(0); }); + it("exits early if total required net send amount is 0", async function () { + const updated = await dataworkerInstance._updateExchangeRatesBeforeExecutingNonHubChainLeaves( + {}, + [{ netSendAmounts: [toBNWei(0)], l1Tokens: [l1Token_1.address], chainId: 1 }], + true + ); + expect(updated.size).to.equal(0); + expect(multiCallerClient.transactionCount()).to.equal(0); + expect( + spy.getCalls().filter((call) => call.lastArg.message.includes("Skipping exchange rate update")).length + ).to.equal(0); + }); it("groups aggregate net send amounts by L1 token", async function () { // Total net send amount is 1 for each token but they are not summed together because they are different, // so the liquid reserves of 1 for each individual token is enough. @@ -344,7 +357,7 @@ describe("Dataworker: Execute pool rebalances", async function () { [ { netSendAmounts: [liquidReserves], l1Tokens: [l1Token_1.address], chainId: 1 }, // This negative liquid reserves doesn't offset the positive one, it just gets ignored. - { netSendAmounts: [liquidReserves.mul(-1)], l1Tokens: [l1Token_1.address], chainId: 10 }, + { netSendAmounts: [liquidReserves.mul(-10)], l1Tokens: [l1Token_1.address], chainId: 10 }, ], true ), @@ -367,6 +380,7 @@ describe("Dataworker: Execute pool rebalances", async function () { ); expect(updated.size).to.equal(0); expect(multiCallerClient.transactionCount()).to.equal(0); + expect(lastSpyLogIncludes(spy, "Skipping exchange rate update")).to.be.true; }); it("logs error if updated liquid reserves aren't enough to execute leaf", async function () { const netSendAmount = toBNWei("1");