From 04fcec491b70c73e4a3c7ced12e88f227e6fe990 Mon Sep 17 00:00:00 2001 From: kyzooghost Date: Fri, 7 Feb 2025 16:48:14 +1100 Subject: [PATCH 1/8] fix tokenbridge init ordering given oz plugin warnings --- contracts/src/bridging/token/TokenBridge.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/src/bridging/token/TokenBridge.sol b/contracts/src/bridging/token/TokenBridge.sol index 175443740..010d5b37c 100644 --- a/contracts/src/bridging/token/TokenBridge.sol +++ b/contracts/src/bridging/token/TokenBridge.sol @@ -153,9 +153,9 @@ contract TokenBridge is nonZeroChainId(_initializationData.targetChainId) initializer { - __PauseManager_init(_initializationData.pauseTypeRoles, _initializationData.unpauseTypeRoles); - __MessageServiceBase_init(_initializationData.messageService); __ReentrancyGuard_init(); + __MessageServiceBase_init(_initializationData.messageService); + __PauseManager_init(_initializationData.pauseTypeRoles, _initializationData.unpauseTypeRoles); if (_initializationData.defaultAdmin == address(0)) { revert ZeroAddressNotAllowed(); From 7a683695de43707bdc7f1d70c8f69e19712f3423 Mon Sep 17 00:00:00 2001 From: kyzooghost Date: Fri, 7 Feb 2025 16:55:48 +1100 Subject: [PATCH 2/8] adjust solhint linting --- contracts/.solhintignore | 5 ++--- contracts/src/_testing/mocks/tokens/TestERC20.sol | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/contracts/.solhintignore b/contracts/.solhintignore index e60ed8fa8..99644921f 100644 --- a/contracts/.solhintignore +++ b/contracts/.solhintignore @@ -1,6 +1,5 @@ node_modules lib/forge-std -contracts/test-contracts test/foundry -/contracts/proxies -/contracts/tokenBridge/mocks \ No newline at end of file +src/_testing +src/proxies \ No newline at end of file diff --git a/contracts/src/_testing/mocks/tokens/TestERC20.sol b/contracts/src/_testing/mocks/tokens/TestERC20.sol index 5e764284f..ab8dedeb5 100644 --- a/contracts/src/_testing/mocks/tokens/TestERC20.sol +++ b/contracts/src/_testing/mocks/tokens/TestERC20.sol @@ -2,8 +2,8 @@ pragma solidity 0.8.19; -import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import "@openzeppelin/contracts/access/Ownable.sol"; +import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; /** * @title TestERC20 From 01970be76e2c0ab390c954eed669b6e75160d23d Mon Sep 17 00:00:00 2001 From: kyzooghost Date: Fri, 7 Feb 2025 20:38:20 +1100 Subject: [PATCH 3/8] fix scripts/tokenBridge/gasEstimation/gasEstimation.ts --- contracts/scripts/tokenBridge/gasEstimation/gasEstimation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/scripts/tokenBridge/gasEstimation/gasEstimation.ts b/contracts/scripts/tokenBridge/gasEstimation/gasEstimation.ts index 1fdc42d34..0900d5811 100644 --- a/contracts/scripts/tokenBridge/gasEstimation/gasEstimation.ts +++ b/contracts/scripts/tokenBridge/gasEstimation/gasEstimation.ts @@ -1,5 +1,5 @@ import { ethers, upgrades } from "hardhat"; -import { getPermitData } from "../../../test/tokenBridge/utils/permitHelper"; +import { getPermitData } from "../../../test/hardhat/bridging/token/utils/permitHelper"; import { BridgedToken, MockTokenBridge } from "../../../typechain-types"; import { deployBridgedTokenBeacon } from "../test/deployBridgedTokenBeacon"; import { deployTokens } from "../test/deployTokens"; From dea360db03aad1f954c24090e9bb6c15480e38d2 Mon Sep 17 00:00:00 2001 From: kyzooghost Date: Fri, 7 Feb 2025 22:27:02 +1100 Subject: [PATCH 4/8] added /// @custom:oz-upgrades-unsafe-allow incorrect-initializer-order --- contracts/src/_testing/unit/messaging/TestL1MessageService.sol | 1 + .../_testing/unit/messaging/TestL1MessageServiceMerkleProof.sol | 1 + contracts/src/messaging/l2/L2MessageService.sol | 1 + contracts/src/rollup/LineaRollup.sol | 1 + 4 files changed, 4 insertions(+) diff --git a/contracts/src/_testing/unit/messaging/TestL1MessageService.sol b/contracts/src/_testing/unit/messaging/TestL1MessageService.sol index 47b4dfa22..d5e0ceb24 100644 --- a/contracts/src/_testing/unit/messaging/TestL1MessageService.sol +++ b/contracts/src/_testing/unit/messaging/TestL1MessageService.sol @@ -13,6 +13,7 @@ contract TestL1MessageService is L1MessageService, TestSetPauseTypeRoles { address public originalSender; bool private reentryDone; + /// @custom:oz-upgrades-unsafe-allow incorrect-initializer-order function initialize( uint256 _rateLimitPeriod, uint256 _rateLimitAmount, diff --git a/contracts/src/_testing/unit/messaging/TestL1MessageServiceMerkleProof.sol b/contracts/src/_testing/unit/messaging/TestL1MessageServiceMerkleProof.sol index 5b71af5f4..c44d1bee9 100644 --- a/contracts/src/_testing/unit/messaging/TestL1MessageServiceMerkleProof.sol +++ b/contracts/src/_testing/unit/messaging/TestL1MessageServiceMerkleProof.sol @@ -18,6 +18,7 @@ contract TestL1MessageServiceMerkleProof is L1MessageService, TestSetPauseTypeRo */ error MessageAlreadyReceived(bytes32 messageHash); + /// @custom:oz-upgrades-unsafe-allow incorrect-initializer-order function initialize( uint256 _rateLimitPeriod, uint256 _rateLimitAmount, diff --git a/contracts/src/messaging/l2/L2MessageService.sol b/contracts/src/messaging/l2/L2MessageService.sol index 8a2c99bcd..7cf57fc32 100644 --- a/contracts/src/messaging/l2/L2MessageService.sol +++ b/contracts/src/messaging/l2/L2MessageService.sol @@ -33,6 +33,7 @@ contract L2MessageService is AccessControlUpgradeable, L2MessageServiceV1, L2Mes * @param _pauseTypeRoles The list of pause type roles. * @param _unpauseTypeRoles The list of unpause type roles. */ + /// @custom:oz-upgrades-unsafe-allow incorrect-initializer-order function initialize( uint256 _rateLimitPeriod, uint256 _rateLimitAmount, diff --git a/contracts/src/rollup/LineaRollup.sol b/contracts/src/rollup/LineaRollup.sol index 08f042f7e..103999b7b 100644 --- a/contracts/src/rollup/LineaRollup.sol +++ b/contracts/src/rollup/LineaRollup.sol @@ -93,6 +93,7 @@ contract LineaRollup is AccessControlUpgradeable, ZkEvmV2, L1MessageService, Per * @dev Note: This is used for new testnets and local/CI testing, and will not replace existing proxy based contracts. * @param _initializationData The initial data used for proof verification. */ + /// @custom:oz-upgrades-unsafe-allow incorrect-initializer-order function initialize(InitializationData calldata _initializationData) external initializer { if (_initializationData.defaultVerifier == address(0)) { revert ZeroAddressNotAllowed(); From 9bca927202b70bf1649e8e5fc0aa0255236d296a Mon Sep 17 00:00:00 2001 From: kyzooghost Date: Fri, 7 Feb 2025 23:21:41 +1100 Subject: [PATCH 5/8] fix for L2MessageService --- contracts/src/messaging/l2/L2MessageService.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contracts/src/messaging/l2/L2MessageService.sol b/contracts/src/messaging/l2/L2MessageService.sol index 7cf57fc32..9d11e347c 100644 --- a/contracts/src/messaging/l2/L2MessageService.sol +++ b/contracts/src/messaging/l2/L2MessageService.sol @@ -33,7 +33,6 @@ contract L2MessageService is AccessControlUpgradeable, L2MessageServiceV1, L2Mes * @param _pauseTypeRoles The list of pause type roles. * @param _unpauseTypeRoles The list of unpause type roles. */ - /// @custom:oz-upgrades-unsafe-allow incorrect-initializer-order function initialize( uint256 _rateLimitPeriod, uint256 _rateLimitAmount, @@ -47,8 +46,8 @@ contract L2MessageService is AccessControlUpgradeable, L2MessageServiceV1, L2Mes __AccessControl_init(); __RateLimiter_init(_rateLimitPeriod, _rateLimitAmount); - __ReentrancyGuard_init(); __PauseManager_init(_pauseTypeRoles, _unpauseTypeRoles); + __ReentrancyGuard_init(); if (_defaultAdmin == address(0)) { revert ZeroAddressNotAllowed(); From 4eccc3d0fc32501ab0e99f737e7b25daa8214601 Mon Sep 17 00:00:00 2001 From: kyzooghost Date: Fri, 7 Feb 2025 23:29:29 +1100 Subject: [PATCH 6/8] remove warning silencer for demo purpose --- contracts/src/_testing/unit/messaging/TestL1MessageService.sol | 1 - .../_testing/unit/messaging/TestL1MessageServiceMerkleProof.sol | 1 - contracts/src/rollup/LineaRollup.sol | 1 - 3 files changed, 3 deletions(-) diff --git a/contracts/src/_testing/unit/messaging/TestL1MessageService.sol b/contracts/src/_testing/unit/messaging/TestL1MessageService.sol index d5e0ceb24..47b4dfa22 100644 --- a/contracts/src/_testing/unit/messaging/TestL1MessageService.sol +++ b/contracts/src/_testing/unit/messaging/TestL1MessageService.sol @@ -13,7 +13,6 @@ contract TestL1MessageService is L1MessageService, TestSetPauseTypeRoles { address public originalSender; bool private reentryDone; - /// @custom:oz-upgrades-unsafe-allow incorrect-initializer-order function initialize( uint256 _rateLimitPeriod, uint256 _rateLimitAmount, diff --git a/contracts/src/_testing/unit/messaging/TestL1MessageServiceMerkleProof.sol b/contracts/src/_testing/unit/messaging/TestL1MessageServiceMerkleProof.sol index c44d1bee9..5b71af5f4 100644 --- a/contracts/src/_testing/unit/messaging/TestL1MessageServiceMerkleProof.sol +++ b/contracts/src/_testing/unit/messaging/TestL1MessageServiceMerkleProof.sol @@ -18,7 +18,6 @@ contract TestL1MessageServiceMerkleProof is L1MessageService, TestSetPauseTypeRo */ error MessageAlreadyReceived(bytes32 messageHash); - /// @custom:oz-upgrades-unsafe-allow incorrect-initializer-order function initialize( uint256 _rateLimitPeriod, uint256 _rateLimitAmount, diff --git a/contracts/src/rollup/LineaRollup.sol b/contracts/src/rollup/LineaRollup.sol index 103999b7b..08f042f7e 100644 --- a/contracts/src/rollup/LineaRollup.sol +++ b/contracts/src/rollup/LineaRollup.sol @@ -93,7 +93,6 @@ contract LineaRollup is AccessControlUpgradeable, ZkEvmV2, L1MessageService, Per * @dev Note: This is used for new testnets and local/CI testing, and will not replace existing proxy based contracts. * @param _initializationData The initial data used for proof verification. */ - /// @custom:oz-upgrades-unsafe-allow incorrect-initializer-order function initialize(InitializationData calldata _initializationData) external initializer { if (_initializationData.defaultVerifier == address(0)) { revert ZeroAddressNotAllowed(); From b65e51125f1229e273f65539b8f906dd87957d9e Mon Sep 17 00:00:00 2001 From: kyzooghost Date: Fri, 7 Feb 2025 23:42:17 +1100 Subject: [PATCH 7/8] Revert "remove warning silencer for demo purpose" This reverts commit 4eccc3d0fc32501ab0e99f737e7b25daa8214601. --- contracts/src/_testing/unit/messaging/TestL1MessageService.sol | 1 + .../_testing/unit/messaging/TestL1MessageServiceMerkleProof.sol | 1 + contracts/src/rollup/LineaRollup.sol | 1 + 3 files changed, 3 insertions(+) diff --git a/contracts/src/_testing/unit/messaging/TestL1MessageService.sol b/contracts/src/_testing/unit/messaging/TestL1MessageService.sol index 47b4dfa22..d5e0ceb24 100644 --- a/contracts/src/_testing/unit/messaging/TestL1MessageService.sol +++ b/contracts/src/_testing/unit/messaging/TestL1MessageService.sol @@ -13,6 +13,7 @@ contract TestL1MessageService is L1MessageService, TestSetPauseTypeRoles { address public originalSender; bool private reentryDone; + /// @custom:oz-upgrades-unsafe-allow incorrect-initializer-order function initialize( uint256 _rateLimitPeriod, uint256 _rateLimitAmount, diff --git a/contracts/src/_testing/unit/messaging/TestL1MessageServiceMerkleProof.sol b/contracts/src/_testing/unit/messaging/TestL1MessageServiceMerkleProof.sol index 5b71af5f4..c44d1bee9 100644 --- a/contracts/src/_testing/unit/messaging/TestL1MessageServiceMerkleProof.sol +++ b/contracts/src/_testing/unit/messaging/TestL1MessageServiceMerkleProof.sol @@ -18,6 +18,7 @@ contract TestL1MessageServiceMerkleProof is L1MessageService, TestSetPauseTypeRo */ error MessageAlreadyReceived(bytes32 messageHash); + /// @custom:oz-upgrades-unsafe-allow incorrect-initializer-order function initialize( uint256 _rateLimitPeriod, uint256 _rateLimitAmount, diff --git a/contracts/src/rollup/LineaRollup.sol b/contracts/src/rollup/LineaRollup.sol index 08f042f7e..103999b7b 100644 --- a/contracts/src/rollup/LineaRollup.sol +++ b/contracts/src/rollup/LineaRollup.sol @@ -93,6 +93,7 @@ contract LineaRollup is AccessControlUpgradeable, ZkEvmV2, L1MessageService, Per * @dev Note: This is used for new testnets and local/CI testing, and will not replace existing proxy based contracts. * @param _initializationData The initial data used for proof verification. */ + /// @custom:oz-upgrades-unsafe-allow incorrect-initializer-order function initialize(InitializationData calldata _initializationData) external initializer { if (_initializationData.defaultVerifier == address(0)) { revert ZeroAddressNotAllowed(); From 3d0077ce9ee2084c713dedc3e3b239a953251dc6 Mon Sep 17 00:00:00 2001 From: kyzooghost Date: Mon, 10 Feb 2025 18:55:51 +1100 Subject: [PATCH 8/8] add incorrect-initializer-flag to upgrades constructor function --- .../unit/messaging/TestL1MessageService.sol | 1 - .../TestL1MessageServiceMerkleProof.sol | 1 - contracts/src/rollup/LineaRollup.sol | 1 - contracts/test/hardhat/L1MessageService.ts | 37 +++++++++---------- contracts/test/hardhat/rollup/LineaRollup.ts | 17 +++++---- 5 files changed, 27 insertions(+), 30 deletions(-) diff --git a/contracts/src/_testing/unit/messaging/TestL1MessageService.sol b/contracts/src/_testing/unit/messaging/TestL1MessageService.sol index d5e0ceb24..47b4dfa22 100644 --- a/contracts/src/_testing/unit/messaging/TestL1MessageService.sol +++ b/contracts/src/_testing/unit/messaging/TestL1MessageService.sol @@ -13,7 +13,6 @@ contract TestL1MessageService is L1MessageService, TestSetPauseTypeRoles { address public originalSender; bool private reentryDone; - /// @custom:oz-upgrades-unsafe-allow incorrect-initializer-order function initialize( uint256 _rateLimitPeriod, uint256 _rateLimitAmount, diff --git a/contracts/src/_testing/unit/messaging/TestL1MessageServiceMerkleProof.sol b/contracts/src/_testing/unit/messaging/TestL1MessageServiceMerkleProof.sol index c44d1bee9..5b71af5f4 100644 --- a/contracts/src/_testing/unit/messaging/TestL1MessageServiceMerkleProof.sol +++ b/contracts/src/_testing/unit/messaging/TestL1MessageServiceMerkleProof.sol @@ -18,7 +18,6 @@ contract TestL1MessageServiceMerkleProof is L1MessageService, TestSetPauseTypeRo */ error MessageAlreadyReceived(bytes32 messageHash); - /// @custom:oz-upgrades-unsafe-allow incorrect-initializer-order function initialize( uint256 _rateLimitPeriod, uint256 _rateLimitAmount, diff --git a/contracts/src/rollup/LineaRollup.sol b/contracts/src/rollup/LineaRollup.sol index 103999b7b..08f042f7e 100644 --- a/contracts/src/rollup/LineaRollup.sol +++ b/contracts/src/rollup/LineaRollup.sol @@ -93,7 +93,6 @@ contract LineaRollup is AccessControlUpgradeable, ZkEvmV2, L1MessageService, Per * @dev Note: This is used for new testnets and local/CI testing, and will not replace existing proxy based contracts. * @param _initializationData The initial data used for proof verification. */ - /// @custom:oz-upgrades-unsafe-allow incorrect-initializer-order function initialize(InitializationData calldata _initializationData) external initializer { if (_initializationData.defaultVerifier == address(0)) { revert ZeroAddressNotAllowed(); diff --git a/contracts/test/hardhat/L1MessageService.ts b/contracts/test/hardhat/L1MessageService.ts index 410cbb1ab..eb4a30bd3 100644 --- a/contracts/test/hardhat/L1MessageService.ts +++ b/contracts/test/hardhat/L1MessageService.ts @@ -61,21 +61,19 @@ describe("L1MessageService", () => { let l2Sender: SignerWithAddress; async function deployTestL1MessageServiceFixture(): Promise { - return deployUpgradableFromFactory("TestL1MessageService", [ - ONE_DAY_IN_SECONDS, - INITIAL_WITHDRAW_LIMIT, - pauseTypeRoles, - unpauseTypeRoles, - ]) as unknown as Promise; + return deployUpgradableFromFactory( + "TestL1MessageService", + [ONE_DAY_IN_SECONDS, INITIAL_WITHDRAW_LIMIT, pauseTypeRoles, unpauseTypeRoles], + { unsafeAllow: ["incorrect-initializer-order"] }, + ) as unknown as Promise; } async function deployL1MessageServiceMerkleFixture(): Promise { - return deployUpgradableFromFactory("TestL1MessageServiceMerkleProof", [ - ONE_DAY_IN_SECONDS, - INITIAL_WITHDRAW_LIMIT, - pauseTypeRoles, - unpauseTypeRoles, - ]) as unknown as Promise; + return deployUpgradableFromFactory( + "TestL1MessageServiceMerkleProof", + [ONE_DAY_IN_SECONDS, INITIAL_WITHDRAW_LIMIT, pauseTypeRoles, unpauseTypeRoles], + { unsafeAllow: ["incorrect-initializer-order"] }, + ) as unknown as Promise; } async function deployL1TestRevertFixture(): Promise { @@ -146,7 +144,9 @@ describe("L1MessageService", () => { it("Should fail to deploy missing amount", async () => { await expectRevertWithCustomError( l1MessageService, - deployUpgradableFromFactory("TestL1MessageService", [ONE_DAY_IN_SECONDS, 0, pauseTypeRoles, unpauseTypeRoles]), + deployUpgradableFromFactory("TestL1MessageService", [ONE_DAY_IN_SECONDS, 0, pauseTypeRoles, unpauseTypeRoles], { + unsafeAllow: ["incorrect-initializer-order"], + }), "LimitIsZero", ); }); @@ -154,12 +154,11 @@ describe("L1MessageService", () => { it("Should fail to deploy missing limit period", async () => { await expectRevertWithCustomError( l1MessageService, - deployUpgradableFromFactory("TestL1MessageService", [ - 0, - INITIAL_WITHDRAW_LIMIT, - pauseTypeRoles, - unpauseTypeRoles, - ]), + deployUpgradableFromFactory( + "TestL1MessageService", + [0, INITIAL_WITHDRAW_LIMIT, pauseTypeRoles, unpauseTypeRoles], + { unsafeAllow: ["incorrect-initializer-order"] }, + ), "PeriodIsZero", ); }); diff --git a/contracts/test/hardhat/rollup/LineaRollup.ts b/contracts/test/hardhat/rollup/LineaRollup.ts index c092d8724..e6dd7b168 100644 --- a/contracts/test/hardhat/rollup/LineaRollup.ts +++ b/contracts/test/hardhat/rollup/LineaRollup.ts @@ -136,7 +136,7 @@ describe("Linea Rollup contract", () => { const lineaRollup = (await deployUpgradableFromFactory("TestLineaRollup", [initializationData], { initializer: LINEA_ROLLUP_INITIALIZE_SIGNATURE, - unsafeAllow: ["constructor"], + unsafeAllow: ["constructor", "incorrect-initializer-order"], })) as unknown as TestLineaRollup; return lineaRollup; @@ -198,7 +198,7 @@ describe("Linea Rollup contract", () => { const deployCall = deployUpgradableFromFactory("src/rollup/LineaRollup.sol:LineaRollup", [initializationData], { initializer: LINEA_ROLLUP_INITIALIZE_SIGNATURE, - unsafeAllow: ["constructor"], + unsafeAllow: ["constructor", "incorrect-initializer-order"], }); await expectRevertWithCustomError(lineaRollup, deployCall, "ZeroAddressNotAllowed"); @@ -221,7 +221,7 @@ describe("Linea Rollup contract", () => { const deployCall = deployUpgradableFromFactory("TestLineaRollup", [initializationData], { initializer: LINEA_ROLLUP_INITIALIZE_SIGNATURE, - unsafeAllow: ["constructor"], + unsafeAllow: ["constructor", "incorrect-initializer-order"], }); await expectRevertWithCustomError(lineaRollup, deployCall, "ZeroAddressNotAllowed"); @@ -244,7 +244,7 @@ describe("Linea Rollup contract", () => { const deployCall = deployUpgradableFromFactory("TestLineaRollup", [initializationData], { initializer: LINEA_ROLLUP_INITIALIZE_SIGNATURE, - unsafeAllow: ["constructor"], + unsafeAllow: ["constructor", "incorrect-initializer-order"], }); await expectRevertWithCustomError(lineaRollup, deployCall, "ZeroAddressNotAllowed"); @@ -267,7 +267,7 @@ describe("Linea Rollup contract", () => { const deployCall = deployUpgradableFromFactory("TestLineaRollup", [initializationData], { initializer: LINEA_ROLLUP_INITIALIZE_SIGNATURE, - unsafeAllow: ["constructor"], + unsafeAllow: ["constructor", "incorrect-initializer-order"], }); await expectRevertWithCustomError(lineaRollup, deployCall, "ZeroAddressNotAllowed"); @@ -313,7 +313,7 @@ describe("Linea Rollup contract", () => { [initializationData], { initializer: LINEA_ROLLUP_INITIALIZE_SIGNATURE, - unsafeAllow: ["constructor"], + unsafeAllow: ["constructor", "incorrect-initializer-order"], }, ); @@ -340,7 +340,7 @@ describe("Linea Rollup contract", () => { [initializationData], { initializer: LINEA_ROLLUP_INITIALIZE_SIGNATURE, - unsafeAllow: ["constructor"], + unsafeAllow: ["constructor", "incorrect-initializer-order"], }, ); @@ -1560,7 +1560,7 @@ describe("Linea Rollup contract", () => { const betaV1LineaRollup = (await deployUpgradableFromFactory("TestLineaRollup", [initializationData], { initializer: LINEA_ROLLUP_INITIALIZE_SIGNATURE, - unsafeAllow: ["constructor"], + unsafeAllow: ["constructor", "incorrect-initializer-order"], })) as unknown as TestLineaRollup; await betaV1LineaRollup.setupParentShnarf(betaV1FinalizationData.parentAggregationFinalShnarf); @@ -2268,6 +2268,7 @@ describe("Linea Rollup contract", () => { ); const newLineaRollup = await upgrades.upgradeProxy(lineaRollup, newLineaRollupFactory, { unsafeAllowRenames: true, + unsafeAllow: ["incorrect-initializer-order"], }); const upgradedContract = await newLineaRollup.waitForDeployment();