Skip to content

Commit

Permalink
improve(dataworker): Import verify fill fix (#2030)
Browse files Browse the repository at this point in the history
* improve(dataworker): Import verify fill fix

* Update Dataworker.loadData.fill.ts

* import real sdk
  • Loading branch information
nicholaspai authored Jan 31, 2025
1 parent 98e4c8c commit f860d08
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 9 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"dependencies": {
"@across-protocol/constants": "^3.1.30",
"@across-protocol/contracts": "^3.0.25",
"@across-protocol/sdk": "^3.4.17",
"@across-protocol/sdk": "^3.4.18",
"@arbitrum/sdk": "^4.0.2",
"@consensys/linea-sdk": "^0.2.1",
"@defi-wonderland/smock": "^2.3.5",
Expand Down
4 changes: 2 additions & 2 deletions test/Dataworker.loadData.fill.ts
Original file line number Diff line number Diff line change
Expand Up @@ -903,7 +903,7 @@ describe("Dataworker: Load data used in all functions", async function () {
expect(data1.bundleFillsV3[repaymentChainId][l1Token_1.address].fills.map((e) => e.lpFeePct)).to.deep.equal(
fillV3Events.slice(0, nValidFills).map(() => lpFeePct)
);
expect(spyLogIncludes(spy, -2, "invalid V3 fills in range")).to.be.true;
expect(spy.getCalls().filter((e) => e.lastArg.message.includes("unrepayable")).length).to.equal(1);
});
// This is essentially a copy of the first test in this block, with the addition of the change to the config store.
it("Fill with bytes32 relayer with lite chain deposit is refunded on lite chain to msg.sender", async function () {
Expand Down Expand Up @@ -1014,7 +1014,7 @@ describe("Dataworker: Load data used in all functions", async function () {
expect(data1.bundleFillsV3[originChainId][erc20_1.address].fills.map((e) => e.lpFeePct)).to.deep.equal(
fillV3Events.slice(0, nValidFills).map(() => lpFeePct)
);
expect(spyLogIncludes(spy, -2, "invalid V3 fills in range")).to.be.true;
expect(spy.getCalls().filter((e) => e.lastArg.message.includes("unrepayable")).length).to.equal(1);
});
});
});
Expand Down
87 changes: 85 additions & 2 deletions test/Dataworker.loadData.slowFill.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ import {
} from "./utils";

import { Dataworker } from "../src/dataworker/Dataworker"; // Tested
import { getCurrentTime, Event, toBNWei, assert, ZERO_ADDRESS } from "../src/utils";
import { getCurrentTime, Event, toBNWei, assert, ZERO_ADDRESS, bnZero } from "../src/utils";
import { MockConfigStoreClient, MockHubPoolClient, MockSpokePoolClient } from "./mocks";
import { interfaces, utils as sdkUtils } from "@across-protocol/sdk";
import { interfaces, providers, utils as sdkUtils } from "@across-protocol/sdk";
import { cloneDeep } from "lodash";
import { INFINITE_FILL_DEADLINE } from "../src/common";

Expand Down Expand Up @@ -429,6 +429,89 @@ describe("BundleDataClient: Slow fill handling & validation", async function ()
expect(data1.unexecutableSlowFills).to.deep.equal({});
});

it("Creates unexecutable slow fill even if fast fill repayment information is invalid", async function () {
generateV3Deposit({ outputToken: erc20_2.address });
await mockOriginSpokePoolClient.update(["V3FundsDeposited"]);
const deposits = mockOriginSpokePoolClient.getDeposits();

// Fill deposit but don't mine requested slow fill event. This makes BundleDataClient think that deposit's slow
// fill request was sent in a prior bundle. This simulates the situation where the slow fill request
// was sent in a prior bundle to the fast fill.

// Fill deposits with invalid repayment information
const invalidRelayer = ethers.utils.randomBytes(32);
const invalidFillEvent = generateV3FillFromDeposit(
deposits[0],
{},
invalidRelayer,
undefined,
interfaces.FillType.ReplacedSlowFill
);
await mockDestinationSpokePoolClient.update(["FilledV3Relay"]);
// Replace the dataworker providers to use mock providers. We need to explicitly do this since we do not actually perform a contract call, so
// we must inject a transaction response into the provider to simulate the case when the relayer repayment address is invalid. In this case,
// set the msg.sender as an invalid address.
const provider = new providers.mocks.MockedProvider(bnZero, bnZero, destinationChainId);
const spokeWrapper = new Contract(
mockDestinationSpokePoolClient.spokePool.address,
mockDestinationSpokePoolClient.spokePool.interface,
provider
);
provider._setTransaction(invalidFillEvent.transactionHash, { from: invalidRelayer });
mockDestinationSpokePoolClient.spokePool = spokeWrapper;

const data1 = await dataworkerInstance.clients.bundleDataClient.loadData(getDefaultBlockRange(5), spokePoolClients);

// The fill cannot be refunded but there is still an unexecutable slow fill leaf we need to refund.
expect(data1.bundleFillsV3).to.deep.equal({});
expect(data1.bundleDepositsV3[originChainId][erc20_1.address].length).to.equal(1);
expect(data1.unexecutableSlowFills[destinationChainId][erc20_2.address].length).to.equal(1);
const logs = spy.getCalls().filter((x) => x.lastArg.message.includes("unrepayable"));
expect(logs.length).to.equal(1);
});

it("Does not create a slow fill leaf if fast fill follows slow fill request but repayment information is invalid", async function () {
generateV3Deposit({ outputToken: erc20_2.address });
await mockOriginSpokePoolClient.update(["V3FundsDeposited"]);
const deposits = mockOriginSpokePoolClient.getDeposits();

generateSlowFillRequestFromDeposit(deposits[0]);

// Fill deposits with invalid repayment information
const invalidRelayer = ethers.utils.randomBytes(32);
const invalidFillEvent = generateV3FillFromDeposit(
deposits[0],
{},
invalidRelayer,
undefined,
interfaces.FillType.ReplacedSlowFill
);
await mockDestinationSpokePoolClient.update(["FilledV3Relay", "RequestedV3SlowFill"]);
// Replace the dataworker providers to use mock providers. We need to explicitly do this since we do not actually perform a contract call, so
// we must inject a transaction response into the provider to simulate the case when the relayer repayment address is invalid. In this case,
// set the msg.sender as an invalid address.
const provider = new providers.mocks.MockedProvider(bnZero, bnZero, destinationChainId);
const spokeWrapper = new Contract(
mockDestinationSpokePoolClient.spokePool.address,
mockDestinationSpokePoolClient.spokePool.interface,
provider
);
provider._setTransaction(invalidFillEvent.transactionHash, { from: invalidRelayer });
mockDestinationSpokePoolClient.spokePool = spokeWrapper;

const data1 = await dataworkerInstance.clients.bundleDataClient.loadData(getDefaultBlockRange(5), spokePoolClients);

// Slow fill request, fast fill and deposit should all be in same bundle. Test that the bundle data client is
// aware of the fill, even if its invalid, and therefore doesn't create a slow fill leaf.

// The fill cannot be refunded but there is still an unexecutable slow fill leaf we need to refund.
expect(data1.bundleFillsV3).to.deep.equal({});
expect(data1.bundleDepositsV3[originChainId][erc20_1.address].length).to.equal(1);
expect(data1.bundleSlowFillsV3).to.deep.equal({});
const logs = spy.getCalls().filter((x) => x.lastArg.message.includes("unrepayable"));
expect(logs.length).to.equal(1);
});

it("Replacing a slow fill request with a fast fill in same bundle doesn't create unexecutable slow fill", async function () {
generateV3Deposit({ outputToken: erc20_2.address });
await mockOriginSpokePoolClient.update(["V3FundsDeposited"]);
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@
yargs "^17.7.2"
zksync-web3 "^0.14.3"

"@across-protocol/sdk@^3.4.17":
version "3.4.17"
resolved "https://registry.yarnpkg.com/@across-protocol/sdk/-/sdk-3.4.17.tgz#00e1291437dc0d22201765f32e31b1d5ab11bccf"
integrity sha512-aWg4JG3z8srN1NkxBF/T9tdr0KgXecs/5zpB1DGujC5Fpo+Blpv0jguhK/taSdmx+hf1Ez0HY8Blxz6YBR66fw==
"@across-protocol/sdk@^3.4.18":
version "3.4.18"
resolved "https://registry.yarnpkg.com/@across-protocol/sdk/-/sdk-3.4.18.tgz#a01efad8c24b36a4a725aace4edb307b8fab8083"
integrity sha512-KQG4BEWIxKYUF12B529E7FAvwVZg84T1c+4RJFClRlxGpV7Kk8jydFbFqWWee4bG1eOaIgFbX26Nq9DQOFK7lA==
dependencies:
"@across-protocol/across-token" "^1.0.0"
"@across-protocol/constants" "^3.1.30"
Expand Down

0 comments on commit f860d08

Please sign in to comment.