diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index 0706e43ab..4f5729da2 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -5,9 +5,9 @@ name: Main CI on: push: - branches: [feature/ongoingPP] + branches: [main, develop, feature/ongoingPP] pull_request: - branches: [feature/ongoingPP] + branches: [main, develop, feature/ongoingPP] jobs: lint-and-test: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2e004f443..d72f97ca9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -5,9 +5,9 @@ name: Main CI on: push: - branches: [main, develop] + branches: [main, develop, feature/ongoingPP] pull_request: - branches: [main, develop] + branches: [main, develop, feature/ongoingPP] jobs: lint-and-test: diff --git a/contracts/v2/PolygonRollupManager.sol b/contracts/v2/PolygonRollupManager.sol index dd537a270..b732a27a4 100644 --- a/contracts/v2/PolygonRollupManager.sol +++ b/contracts/v2/PolygonRollupManager.sol @@ -45,6 +45,7 @@ contract PolygonRollupManager is address consensusImplementation; address verifier; uint64 forkID; + /// @custom:oz-retyped-from uint8 VerifierType rollupVerifierType; bool obsolete; bytes32 genesis; @@ -79,15 +80,74 @@ contract PolygonRollupManager is uint64 forkID; mapping(uint64 batchNum => bytes32) batchNumToStateRoot; mapping(uint64 batchNum => SequencedBatchData) sequencedBatches; + /// @custom:oz-renamed-from pendingStateTransitions mapping(uint256 pendingStateNum => PendingState) _legacyPendingStateTransitions; bytes32 lastLocalExitRoot; uint64 lastBatchSequenced; uint64 lastVerifiedBatch; - uint128 _legacyPendingStateGap; - // uint64 _legacyLastPendingState; - // uint64 _legacyLastPendingStateConsolidated; + /// @custom:oz-renamed-from lastPendingState + uint64 _legacyLastPendingState; + /// @custom:oz-renamed-from lastPendingStateConsolidated + uint64 _legacyLastPendingStateConsolidated; uint64 lastVerifiedBatchBeforeUpgrade; uint64 rollupTypeID; + /// @custom:oz-retyped-from uint8 + VerifierType rollupVerifierType; + bytes32 lastPessimisticRoot; + bytes32 programVKey; + } + + /** + * @notice Struct to return all the necessary rollup info: VerifierType StateTransition + * @param rollupContract Rollup consensus contract, which manages everything + * related to sequencing transactions + * @param chainID Chain ID of the rollup + * @param verifier Verifier contract + * @param forkID ForkID of the rollup + * @param lastLocalExitRoot Last exit root verified, used for compute the rollupExitRoot + * @param lastBatchSequenced Last batch sent by the consensus contract + * @param lastVerifiedBatch Last batch verified + * @param _legacyLastPendingState Last pending state (deprecated) + * @param _legacyLastPendingStateConsolidated Last pending state consolidated (deprecated) + * @param lastVerifiedBatchBeforeUpgrade Last batch verified before the last upgrade + * @param rollupTypeID Rollup type ID, can be 0 if it was added as an existing rollup + * @param rollupVerifierType Rollup ID used for compatibility checks when upgrading + */ + struct RollupDataReturnStateTransistion { + IPolygonRollupBase rollupContract; + uint64 chainID; + address verifier; + uint64 forkID; + bytes32 lastLocalExitRoot; + uint64 lastBatchSequenced; + uint64 lastVerifiedBatch; + uint64 _legacyLastPendingState; + uint64 _legacyLastPendingStateConsolidated; + uint64 lastVerifiedBatchBeforeUpgrade; + uint64 rollupTypeID; + VerifierType rollupVerifierType; + } + + /** + * @notice Struct to return all the necessary rollup info: VerifierType Pessimistic + * @param rollupContract Rollup consensus contract, which manages everything + * related to sequencing transactions + * @param chainID Chain ID of the rollup + * @param verifier Verifier contract + * @param forkID ForkID of the rollup + * @param lastLocalExitRoot Last exit root verified, used for compute the rollupExitRoot + * @param rollupTypeID Rollup type ID, can be 0 if it was added as an existing rollup + * @param rollupVerifierType Rollup ID used for compatibility checks when upgrading + * @param lastPessimisticRoot Pessimistic info, currently contains the local balance tree and the local nullifier tree hashed + * @param programVKey Hashed program that will be executed in case of using a "general porpuse ZK verifier" e.g SP1 + */ + struct RollupDataReturnPessimistic { + IPolygonRollupBase rollupContract; + uint64 chainID; + address verifier; + uint64 forkID; + bytes32 lastLocalExitRoot; + uint64 rollupTypeID; VerifierType rollupVerifierType; bytes32 lastPessimisticRoot; bytes32 programVKey; @@ -175,13 +235,15 @@ contract PolygonRollupManager is uint32 public rollupTypeCount; // Rollup type mapping + // @custom:oz-retyped-from PolygonRollupManagerPrevious.RollupType mapping(uint32 rollupTypeID => RollupType) public rollupTypeMap; // Number of rollups added, every new rollup will be assigned sequencially a new ID uint32 public rollupCount; // Rollups ID mapping - mapping(uint32 rollupID => RollupData) public rollupIDToRollupData; + /// @custom:oz-renamed-from rollupIDToRollupData + mapping(uint32 rollupID => RollupData) internal legacyRollupIDToRollupData; // Rollups address mapping mapping(address rollupAddress => uint32 rollupID) public rollupAddressToID; @@ -201,16 +263,20 @@ contract PolygonRollupManager is // Trusted aggregator timeout, if a sequence is not verified in this time frame, // everyone can verify that sequence + /// @custom:oz-renamed-from trustedAggregatorTimeout uint64 internal __legacyTrustedAggregatorTimeout; // Once a pending state exceeds this timeout it can be consolidated (deprecated) + /// @custom:oz-renamed-from pendingStateTimeout uint64 internal __legacyPendingStateTimeout; // Time target of the verification of a batch // Adaptively the batchFee will be updated to achieve this target + /// @custom:oz-renamed-from verifyBatchTimeTarget uint64 internal __legacyVerifyBatchTimeTarget; // Batch fee multiplier with 3 decimals that goes from 1000 - 1023 + /// @custom:oz-renamed-from multiplierBatchFee uint16 internal __legacyMultiplierBatchFee; // Current POL fee per batch sequenced @@ -461,7 +527,7 @@ contract PolygonRollupManager is // Store rollup data rollupAddressToID[rollupAddress] = rollupID; - RollupData storage rollup = rollupIDToRollupData[rollupID]; + RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; rollup.rollupContract = IPolygonRollupBase(rollupAddress); rollup.forkID = rollupType.forkID; @@ -536,7 +602,7 @@ contract PolygonRollupManager is // Store rollup data rollupAddressToID[address(rollupAddress)] = rollupID; - RollupData storage rollup = rollupIDToRollupData[rollupID]; + RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; rollup.rollupContract = rollupAddress; rollup.forkID = forkID; rollup.verifier = verifier; @@ -579,7 +645,7 @@ contract PolygonRollupManager is } // Check all sequences are verified before upgrading - RollupData storage rollup = rollupIDToRollupData[ + RollupData storage rollup = legacyRollupIDToRollupData[ rollupAddressToID[address(rollupContract)] ]; @@ -632,7 +698,7 @@ contract PolygonRollupManager is revert RollupMustExist(); } - RollupData storage rollup = rollupIDToRollupData[rollupID]; + RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; // The update must be to a new rollup type if (rollup.rollupTypeID == newRollupTypeID) { @@ -694,7 +760,7 @@ contract PolygonRollupManager is } // Load rollup - RollupData storage rollup = rollupIDToRollupData[rollupID]; + RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; if (rollup.rollupVerifierType != VerifierType.StateTransition) { revert OnlyStateTransitionChains(); @@ -774,7 +840,7 @@ contract PolygonRollupManager is revert MustSequenceSomeBatch(); } - RollupData storage rollup = rollupIDToRollupData[rollupID]; + RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; // Update total sequence parameters totalSequencedBatches += newSequencedBatches; @@ -823,7 +889,7 @@ contract PolygonRollupManager is revert PendingStateNumExist(); } - RollupData storage rollup = rollupIDToRollupData[rollupID]; + RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; if (rollup.rollupVerifierType != VerifierType.StateTransition) { revert OnlyStateTransitionChains(); @@ -871,7 +937,7 @@ contract PolygonRollupManager is bytes32 newPessimisticRoot, bytes calldata proof ) external onlyRole(_TRUSTED_AGGREGATOR_ROLE) { - RollupData storage rollup = rollupIDToRollupData[rollupID]; + RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; // Only for pessimistic verifiers if (rollup.rollupVerifierType != VerifierType.Pessimistic) { @@ -1101,7 +1167,8 @@ contract PolygonRollupManager is // In the first iteration the nodes will be the leafs which are the local exit roots of each network for (uint256 i = 0; i < currentNodes; i++) { // The first rollup ID starts on 1 - tmpTree[i] = rollupIDToRollupData[uint32(i + 1)].lastLocalExitRoot; + tmpTree[i] = legacyRollupIDToRollupData[uint32(i + 1)] + .lastLocalExitRoot; } // This variable will keep track of the zero hashes @@ -1156,7 +1223,7 @@ contract PolygonRollupManager is function getLastVerifiedBatch( uint32 rollupID ) public view returns (uint64) { - return _getLastVerifiedBatch(rollupIDToRollupData[rollupID]); + return _getLastVerifiedBatch(legacyRollupIDToRollupData[rollupID]); } /** @@ -1213,7 +1280,7 @@ contract PolygonRollupManager is ) public view returns (bytes memory) { return _getInputPessimisticBytes( - rollupIDToRollupData[rollupID], + legacyRollupIDToRollupData[rollupID], selectedGlobalExitRoot, newLocalExitRoot, newPessimisticRoot @@ -1268,7 +1335,7 @@ contract PolygonRollupManager is ) public view returns (bytes memory) { return _getInputSnarkBytes( - rollupIDToRollupData[rollupID], + legacyRollupIDToRollupData[rollupID], initNumBatch, finalNewBatch, newLocalExitRoot, @@ -1361,7 +1428,8 @@ contract PolygonRollupManager is uint32 rollupID, uint64 batchNum ) public view returns (bytes32) { - return rollupIDToRollupData[rollupID].batchNumToStateRoot[batchNum]; + return + legacyRollupIDToRollupData[rollupID].batchNumToStateRoot[batchNum]; } /** @@ -1373,6 +1441,59 @@ contract PolygonRollupManager is uint32 rollupID, uint64 batchNum ) public view returns (SequencedBatchData memory) { - return rollupIDToRollupData[rollupID].sequencedBatches[batchNum]; + return legacyRollupIDToRollupData[rollupID].sequencedBatches[batchNum]; + } + + /** + * @notice Get rollup data: VerifierType StateTransition + * @param rollupID Rollup identifier + */ + function rollupIDToRollupData( + uint32 rollupID + ) public view returns (RollupDataReturnStateTransistion memory rollupData) { + RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; + + if (rollup.rollupVerifierType != VerifierType.StateTransition) { + revert InvalidVerifierType(); + } + + rollupData.rollupContract = rollup.rollupContract; + rollupData.chainID = rollup.chainID; + rollupData.verifier = rollup.verifier; + rollupData.forkID = rollup.forkID; + rollupData.lastLocalExitRoot = rollup.lastLocalExitRoot; + rollupData.lastBatchSequenced = rollup.lastBatchSequenced; + rollupData.lastVerifiedBatch = rollup.lastVerifiedBatch; + rollupData._legacyLastPendingState = rollup._legacyLastPendingState; + rollupData._legacyLastPendingStateConsolidated = rollup + ._legacyLastPendingStateConsolidated; + rollupData.lastVerifiedBatchBeforeUpgrade = rollup + .lastVerifiedBatchBeforeUpgrade; + rollupData.rollupTypeID = rollup.rollupTypeID; + rollupData.rollupVerifierType = rollup.rollupVerifierType; + } + + /** + * @notice Get rollup data: VerifierType Pessimistic + * @param rollupID Rollup identifier + */ + function rollupIDToRollupDataPessimistic( + uint32 rollupID + ) public view returns (RollupDataReturnPessimistic memory rollupData) { + RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; + + if (rollup.rollupVerifierType != VerifierType.Pessimistic) { + revert InvalidVerifierType(); + } + + rollupData.rollupContract = rollup.rollupContract; + rollupData.chainID = rollup.chainID; + rollupData.verifier = rollup.verifier; + rollupData.forkID = rollup.forkID; + rollupData.lastLocalExitRoot = rollup.lastLocalExitRoot; + rollupData.rollupTypeID = rollup.rollupTypeID; + rollupData.rollupVerifierType = rollup.rollupVerifierType; + rollupData.lastPessimisticRoot = rollup.lastPessimisticRoot; + rollupData.programVKey = rollup.programVKey; } } diff --git a/contracts/v2/interfaces/IPolygonRollupManager.sol b/contracts/v2/interfaces/IPolygonRollupManager.sol index 10a8a8531..16cb7cae8 100644 --- a/contracts/v2/interfaces/IPolygonRollupManager.sol +++ b/contracts/v2/interfaces/IPolygonRollupManager.sol @@ -302,6 +302,11 @@ interface IPolygonRollupManager { */ error InvalidPessimisticProof(); + /** + * @dev Invalid Verifier Type when getting rollup data + */ + error InvalidVerifierType(); + enum VerifierType { StateTransition, Pessimistic diff --git a/contracts/v2/mocks/PolygonRollupManagerMock.sol b/contracts/v2/mocks/PolygonRollupManagerMock.sol index 1d2a249d4..87190f306 100644 --- a/contracts/v2/mocks/PolygonRollupManagerMock.sol +++ b/contracts/v2/mocks/PolygonRollupManagerMock.sol @@ -74,7 +74,7 @@ contract PolygonRollupManagerMock is PolygonRollupManager { // Add local Exit roots; for (uint256 i = 0; i < localExitRoots.length; i++) { - rollupIDToRollupData[uint32(i + 1)] + legacyRollupIDToRollupData[uint32(i + 1)] .lastLocalExitRoot = localExitRoots[i]; } } diff --git a/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts b/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts index 9d955cb7f..58ae7684d 100644 --- a/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts +++ b/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts @@ -401,7 +401,7 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { expect(await newZkEVMContract.networkName()).to.be.equal(networkName); // assert new rollup - const resRollupData = await rollupManagerContract.rollupIDToRollupData(newCreatedRollupID); + const resRollupData = await rollupManagerContract.rollupIDToRollupDataPessimistic(newCreatedRollupID); const expectedRollupData = [ newZKEVMAddress, @@ -409,10 +409,6 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { verifierContract.target, forkID, ethers.ZeroHash, - 0, - 0, - 0, - 0, newRollupTypeID, VerifierType.Pessimistic, ethers.ZeroHash, @@ -562,7 +558,7 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { ); // get rollup data - const rollupPessimistic = await rollupManagerContract.rollupIDToRollupData(pessimisticRollupID); + const rollupPessimistic = await rollupManagerContract.rollupIDToRollupDataPessimistic(pessimisticRollupID); const rollupStateTransition = await rollupManagerContract.rollupIDToRollupData(stateTransistionRollupID); // try to update rollup from Pessimistic to stateTransition @@ -655,7 +651,7 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { ); // get rollup data - const rollupPessimistic = await rollupManagerContract.rollupIDToRollupData(pessimisticRollupID); + const rollupPessimistic = await rollupManagerContract.rollupIDToRollupDataPessimistic(pessimisticRollupID); // try to update rollup from StateTransition to Pessimistic await rollupManagerContract @@ -663,7 +659,7 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { .updateRollup(rollupPessimistic[0] as unknown as Address, newRollupTypeID, "0x"); // assert new rollup - const resRollupData = await rollupManagerContract.rollupIDToRollupData(pessimisticRollupID); + const resRollupData = await rollupManagerContract.rollupIDToRollupDataPessimistic(pessimisticRollupID); const expectedRollupData = [ newZKEVMAddress, @@ -671,10 +667,6 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { newVerifier, newForkID, ethers.ZeroHash, - 0, - 0, - 0, - 0, newRollupTypeID, VerifierType.Pessimistic, ethers.ZeroHash, @@ -780,7 +772,7 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { .withArgs(pessimisticRollupID, 0, ethers.ZeroHash, newLER, trustedAggregator.address); // assert rollup data - const resRollupData = await rollupManagerContract.rollupIDToRollupData(pessimisticRollupID); + const resRollupData = await rollupManagerContract.rollupIDToRollupDataPessimistic(pessimisticRollupID); const expectedRollupData = [ newZKEVMAddress, @@ -788,10 +780,6 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { verifierContract.target, forkID, newLER, - 0, - 0, - 0, - 0, rollupTypeID, VerifierType.Pessimistic, newPPRoot, diff --git a/test/contractsv2/PolygonRollupManager.test.ts b/test/contractsv2/PolygonRollupManager.test.ts index e79c40513..288474fb0 100644 --- a/test/contractsv2/PolygonRollupManager.test.ts +++ b/test/contractsv2/PolygonRollupManager.test.ts @@ -57,7 +57,7 @@ describe("Polygon Rollup Manager", () => { const LEAF_TYPE_MESSAGE = 1; const globalExitRootL2Address = "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa" as unknown as Address; - + let firstDeployment = true; //roles @@ -252,7 +252,6 @@ describe("Polygon Rollup Manager", () => { const rollupVerifierType = 0; const description = "zkevm test"; const programVKey = "0x0000000000000000000000000000000000000000000000000000000000000000"; - const lastPessimisticRoot = "0x0000000000000000000000000000000000000000000000000000000000000000"; // Native token will be ether const gasTokenAddress = ethers.ZeroAddress; @@ -320,7 +319,7 @@ describe("Polygon Rollup Manager", () => { rollupVerifierType, false, genesisRandom, - programVKey + programVKey, ]; expect(createdRollupType).to.be.deep.equal(expectedRollupType); @@ -343,7 +342,7 @@ describe("Polygon Rollup Manager", () => { rollupVerifierType, true, genesisRandom, - programVKey + programVKey, ]).to.be.deep.equal(await rollupManagerContract.rollupTypeMap(newRollupTypeID)); await snapshot.restore(); @@ -517,12 +516,11 @@ describe("Polygon Rollup Manager", () => { expect(rollupData.lastLocalExitRoot).to.be.equal(ethers.ZeroHash); expect(rollupData.lastBatchSequenced).to.be.equal(newSequencedBatch); expect(rollupData.lastVerifiedBatch).to.be.equal(0); - expect(rollupData._legacyPendingStateGap).to.be.equal(0); + expect(rollupData._legacyLastPendingState).to.be.equal(0); + expect(rollupData._legacyLastPendingStateConsolidated).to.be.equal(0); expect(rollupData.lastVerifiedBatchBeforeUpgrade).to.be.equal(0); expect(rollupData.rollupTypeID).to.be.equal(1); expect(rollupData.rollupVerifierType).to.be.equal(0); - expect(rollupData.lastPessimisticRoot).to.be.equal(lastPessimisticRoot); - expect(rollupData.programVKey).to.be.equal(programVKey); const sequencedBatchData = await rollupManagerContract.getRollupSequencedBatches( newCreatedRollupID, @@ -1136,7 +1134,7 @@ describe("Polygon Rollup Manager", () => { rollupVerifierType, false, genesisRandom, - programVKey + programVKey, ]; expect(createdRollupType).to.be.deep.equal(expectedRollupType); @@ -1159,7 +1157,7 @@ describe("Polygon Rollup Manager", () => { rollupVerifierType, true, genesisRandom, - programVKey + programVKey, ]).to.be.deep.equal(await rollupManagerContract.rollupTypeMap(newRollupTypeID)); await snapshot.restore(); @@ -1333,12 +1331,11 @@ describe("Polygon Rollup Manager", () => { expect(rollupData.lastLocalExitRoot).to.be.equal(ethers.ZeroHash); expect(rollupData.lastBatchSequenced).to.be.equal(newSequencedBatch); expect(rollupData.lastVerifiedBatch).to.be.equal(0); - expect(rollupData._legacyPendingStateGap).to.be.equal(0); + expect(rollupData._legacyLastPendingState).to.be.equal(0); + expect(rollupData._legacyLastPendingStateConsolidated).to.be.equal(0); expect(rollupData.lastVerifiedBatchBeforeUpgrade).to.be.equal(0); expect(rollupData.rollupTypeID).to.be.equal(1); expect(rollupData.rollupVerifierType).to.be.equal(0); - expect(rollupData.lastPessimisticRoot).to.be.equal(lastPessimisticRoot); - expect(rollupData.programVKey).to.be.equal(programVKey); const sequencedBatchData = await rollupManagerContract.getRollupSequencedBatches( newCreatedRollupID, @@ -1761,7 +1758,7 @@ describe("Polygon Rollup Manager", () => { rollupVerifierType, false, genesisRandom, - programVKey + programVKey, ]; expect(createdRollupType).to.be.deep.equal(expectedRollupType); @@ -1784,7 +1781,7 @@ describe("Polygon Rollup Manager", () => { rollupVerifierType, true, genesisRandom, - programVKey + programVKey, ]).to.be.deep.equal(await rollupManagerContract.rollupTypeMap(newRollupTypeID)); await snapshot.restore(); @@ -1959,12 +1956,11 @@ describe("Polygon Rollup Manager", () => { expect(rollupData.lastLocalExitRoot).to.be.equal(ethers.ZeroHash); expect(rollupData.lastBatchSequenced).to.be.equal(newSequencedBatch); expect(rollupData.lastVerifiedBatch).to.be.equal(0); - expect(rollupData._legacyPendingStateGap).to.be.equal(0); + expect(rollupData._legacyLastPendingState).to.be.equal(0); + expect(rollupData._legacyLastPendingStateConsolidated).to.be.equal(0); expect(rollupData.lastVerifiedBatchBeforeUpgrade).to.be.equal(0); expect(rollupData.rollupTypeID).to.be.equal(1); expect(rollupData.rollupVerifierType).to.be.equal(0); - expect(rollupData.lastPessimisticRoot).to.be.equal(lastPessimisticRoot); - expect(rollupData.programVKey).to.be.equal(programVKey); const sequencedBatchData = await rollupManagerContract.getRollupSequencedBatches( newCreatedRollupID, @@ -2360,7 +2356,7 @@ describe("Polygon Rollup Manager", () => { rollupVerifierTypeNew, false, programVKey, - genesisRandom + genesisRandom, ]; expect(createdEtrogRollupType).to.be.deep.equal(expectedEtrogRollupType); @@ -2441,12 +2437,11 @@ describe("Polygon Rollup Manager", () => { expect(rollupDataFinal.lastLocalExitRoot).to.be.equal(newLocalExitRoot); expect(rollupDataFinal.lastBatchSequenced).to.be.equal(newVerifiedBatch); expect(rollupDataFinal.lastVerifiedBatch).to.be.equal(newVerifiedBatch); - expect(rollupDataFinal._legacyPendingStateGap).to.be.equal(0); + expect(rollupData._legacyLastPendingState).to.be.equal(0); + expect(rollupData._legacyLastPendingStateConsolidated).to.be.equal(0); expect(rollupDataFinal.lastVerifiedBatchBeforeUpgrade).to.be.equal(newVerifiedBatch); expect(rollupDataFinal.rollupTypeID).to.be.equal(etrogRollupType); expect(rollupDataFinal.rollupVerifierType).to.be.equal(0); - expect(rollupDataFinal.lastPessimisticRoot).to.be.equal(lastPessimisticRoot); - expect(rollupDataFinal.programVKey).to.be.equal(programVKey); expect(await upgrades.erc1967.getImplementationAddress(newZKEVMAddress as string)).to.be.equal( PolygonZKEVMEtrogContract.target @@ -2537,7 +2532,7 @@ describe("Polygon Rollup Manager", () => { rollupVerifierType, false, genesisRandom, - programVKey + programVKey, ]; expect(createdRollupType).to.be.deep.equal(expectedRollupType); @@ -2634,12 +2629,12 @@ describe("Polygon Rollup Manager", () => { expect(rollupData.lastLocalExitRoot).to.be.equal(ethers.ZeroHash); expect(rollupData.lastBatchSequenced).to.be.equal(newSequencedBatch); expect(rollupData.lastVerifiedBatch).to.be.equal(0); - expect(rollupData._legacyPendingStateGap).to.be.equal(0); + expect(rollupData._legacyLastPendingState).to.be.equal(0); + expect(rollupData._legacyLastPendingStateConsolidated).to.be.equal(0); expect(rollupData.lastVerifiedBatchBeforeUpgrade).to.be.equal(0); expect(rollupData.rollupTypeID).to.be.equal(1); expect(rollupData.rollupVerifierType).to.be.equal(0); - expect(rollupData.lastPessimisticRoot).to.be.equal(lastPessimisticRoot); - expect(rollupData.programVKey).to.be.equal(programVKey); + const sequencedBatchData = await rollupManagerContract.getRollupSequencedBatches( newCreatedRollupID, newSequencedBatch @@ -3306,7 +3301,7 @@ describe("Polygon Rollup Manager", () => { rollupVerifierType, false, genesisRandom, - programVKey + programVKey, ]; expect(createdRollupType).to.be.deep.equal(expectedRollupType); diff --git a/test/contractsv2/PolygonRollupManagerUpgrade.test.ts.ignore b/test/contractsv2/PolygonRollupManagerUpgrade.test.ts similarity index 53% rename from test/contractsv2/PolygonRollupManagerUpgrade.test.ts.ignore rename to test/contractsv2/PolygonRollupManagerUpgrade.test.ts index 745641356..014696e08 100644 --- a/test/contractsv2/PolygonRollupManagerUpgrade.test.ts.ignore +++ b/test/contractsv2/PolygonRollupManagerUpgrade.test.ts @@ -226,7 +226,8 @@ describe("Polygon Rollup manager upgraded", () => { polygonZkEVMBridgeContract.target, ], unsafeAllow: ["constructor", "state-variable-immutable"], - unsafeAllowRenames: false, + unsafeAllowRenames: true, + unsafeSkipStorageCheck: true, call: { fn: "initialize", args: [ @@ -254,7 +255,8 @@ describe("Polygon Rollup manager upgraded", () => { polygonZkEVMBridgeContract.target, ], unsafeAllow: ["constructor", "state-variable-immutable"], - unsafeAllowRenames: false, + unsafeAllowRenames: true, + unsafeSkipStorageCheck: true, } ); }); @@ -264,9 +266,6 @@ describe("Polygon Rollup manager upgraded", () => { expect(await rollupManagerContract.pol()).to.be.equal(polTokenContract.target); expect(await rollupManagerContract.bridgeAddress()).to.be.equal(polygonZkEVMBridgeContract.target); - expect(await rollupManagerContract.pendingStateTimeout()).to.be.equal(pendingStateTimeoutDefault); - expect(await rollupManagerContract.trustedAggregatorTimeout()).to.be.equal(trustedAggregatorTimeout); - expect(await rollupManagerContract.getBatchFee()).to.be.equal(ethers.parseEther("0.1")); expect(await rollupManagerContract.getForcedBatchFee()).to.be.equal(ethers.parseEther("10")); @@ -294,38 +293,6 @@ describe("Polygon Rollup manager upgraded", () => { }); it("Check admin parameters", async () => { - expect(await rollupManagerContract.multiplierBatchFee()).to.be.equal(1002); - await expect(rollupManagerContract.setMultiplierBatchFee(1023)).to.be.revertedWithCustomError( - rollupManagerContract, - "AddressDoNotHaveRequiredRole" - ); - await expect(rollupManagerContract.connect(admin).setMultiplierBatchFee(0)).to.be.revertedWithCustomError( - rollupManagerContract, - "InvalidRangeMultiplierBatchFee" - ); - - await expect(rollupManagerContract.connect(admin).setMultiplierBatchFee(1020)) - .to.emit(rollupManagerContract, "SetMultiplierBatchFee") - .withArgs(1020); - - expect(await rollupManagerContract.multiplierBatchFee()).to.be.equal(1020); - - // verifyBatchTImetarget - expect(await rollupManagerContract.verifyBatchTimeTarget()).to.be.equal(60 * 30); - - await expect(rollupManagerContract.setVerifyBatchTimeTarget(0)).to.be.revertedWithCustomError( - rollupManagerContract, - "AddressDoNotHaveRequiredRole" - ); - await expect( - rollupManagerContract.connect(admin).setVerifyBatchTimeTarget(60 * 60 * 24 + 1) - ).to.be.revertedWithCustomError(rollupManagerContract, "InvalidRangeBatchTimeTarget"); - - await expect(rollupManagerContract.connect(admin).setVerifyBatchTimeTarget(60)) - .to.emit(rollupManagerContract, "SetVerifyBatchTimeTarget") - .withArgs(60); - expect(await rollupManagerContract.verifyBatchTimeTarget()).to.be.equal(60); - // batch Fee // verifyBatchTImetarget expect(await rollupManagerContract.getBatchFee()).to.be.equal(ethers.parseEther("0.1")); @@ -351,9 +318,11 @@ describe("Polygon Rollup manager upgraded", () => { const chainID2 = chainID + 1; const networkName = "zkevm"; const forkID = 0; + const rollupVerifierType = 0; const genesisRandom = "0x0000000000000000000000000000000000000000000000000000000000000001"; - const rollupCompatibilityID = 0; - const descirption = "zkevm test"; + const description = "zkevm test"; + const programVKey = "0x0000000000000000000000000000000000000000000000000000000000000000"; + // Native token will be ether const gasTokenAddress = ethers.ZeroAddress; const gasTokenNetwork = 0; @@ -375,9 +344,10 @@ describe("Polygon Rollup manager upgraded", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ) ).to.be.revertedWithCustomError(rollupManagerContract, "AddressDoNotHaveRequiredRole"); @@ -390,9 +360,10 @@ describe("Polygon Rollup manager upgraded", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ) ) .to.emit(rollupManagerContract, "AddNewRollupType") @@ -401,9 +372,10 @@ describe("Polygon Rollup manager upgraded", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ); // assert new rollup type @@ -413,9 +385,10 @@ describe("Polygon Rollup manager upgraded", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, false, genesisRandom, + programVKey, ]; expect(createdRollupType).to.be.deep.equal(expectedRollupType); @@ -435,9 +408,10 @@ describe("Polygon Rollup manager upgraded", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, true, genesisRandom, + programVKey, ]).to.be.deep.equal(await rollupManagerContract.rollupTypeMap(newRollupTypeID)); await snapshot.restore(); @@ -598,11 +572,11 @@ describe("Polygon Rollup manager upgraded", () => { expect(rollupData.lastLocalExitRoot).to.be.equal(ethers.ZeroHash); expect(rollupData.lastBatchSequenced).to.be.equal(newSequencedBatch); expect(rollupData.lastVerifiedBatch).to.be.equal(0); - expect(rollupData.lastPendingState).to.be.equal(0); - expect(rollupData.lastPendingStateConsolidated).to.be.equal(0); + expect(rollupData._legacyLastPendingState).to.be.equal(0); + expect(rollupData._legacyLastPendingStateConsolidated).to.be.equal(0); expect(rollupData.lastVerifiedBatchBeforeUpgrade).to.be.equal(0); expect(rollupData.rollupTypeID).to.be.equal(1); - expect(rollupData.rollupCompatibilityID).to.be.equal(0); + expect(rollupData.rollupVerifierType).to.be.equal(0); const sequencedBatchData = await rollupManagerContract.getRollupSequencedBatches( newCreatedRollupID, @@ -1066,959 +1040,12 @@ describe("Polygon Rollup manager upgraded", () => { .withArgs(deployer.address); }); - it("should check full flow no trusted aggreagtor", async () => { - const urlSequencer = "http://zkevm-json-rpc:8123"; - const chainID2 = chainID + 1; - const networkName = "zkevm"; - const forkID = 0; - const genesisRandom = "0x0000000000000000000000000000000000000000000000000000000000000001"; - const rollupCompatibilityID = 0; - const descirption = "zkevm test"; - // Native token will be ether - const gasTokenAddress = ethers.ZeroAddress; - const gasTokenNetwork = 0; - - // In order to create a new rollup type, create an implementation of the contract - - // Create zkEVM implementation - const PolygonZKEVMV2Factory = await ethers.getContractFactory("PolygonZkEVMEtrog"); - const PolygonZKEVMV2Contract = await PolygonZKEVMV2Factory.deploy( - polygonZkEVMGlobalExitRoot.target, - polTokenContract.target, - polygonZkEVMBridgeContract.target, - rollupManagerContract.target - ); - await PolygonZKEVMV2Contract.waitForDeployment(); - - // Try to add a new rollup type - await expect( - rollupManagerContract.addNewRollupType( - PolygonZKEVMV2Contract.target, - verifierContract.target, - forkID, - rollupCompatibilityID, - genesisRandom, - descirption - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "AddressDoNotHaveRequiredRole"); - - // Add a new rollup type with timelock - const newRollupTypeID = 1; - await expect( - rollupManagerContract - .connect(timelock) - .addNewRollupType( - PolygonZKEVMV2Contract.target, - verifierContract.target, - forkID, - rollupCompatibilityID, - genesisRandom, - descirption - ) - ) - .to.emit(rollupManagerContract, "AddNewRollupType") - .withArgs( - newRollupTypeID, - PolygonZKEVMV2Contract.target, - verifierContract.target, - forkID, - rollupCompatibilityID, - genesisRandom, - descirption - ); - - // assert new rollup type - const createdRollupType = await rollupManagerContract.rollupTypeMap(newRollupTypeID); - - const expectedRollupType = [ - PolygonZKEVMV2Contract.target, - verifierContract.target, - forkID, - rollupCompatibilityID, - false, - genesisRandom, - ]; - expect(createdRollupType).to.be.deep.equal(expectedRollupType); - - // obsoleteRollupType, take snapshot for it - const snapshot = await takeSnapshot(); - - await expect(rollupManagerContract.obsoleteRollupType(newRollupTypeID)).to.be.revertedWithCustomError( - rollupManagerContract, - "AddressDoNotHaveRequiredRole" - ); - - await expect(rollupManagerContract.connect(admin).obsoleteRollupType(newRollupTypeID)) - .to.emit(rollupManagerContract, "ObsoleteRollupType") - .withArgs(newRollupTypeID); - - expect([ - PolygonZKEVMV2Contract.target, - verifierContract.target, - forkID, - rollupCompatibilityID, - true, - genesisRandom, - ]).to.be.deep.equal(await rollupManagerContract.rollupTypeMap(newRollupTypeID)); - await snapshot.restore(); - - expect(expectedRollupType).to.be.deep.equal(await rollupManagerContract.rollupTypeMap(newRollupTypeID)); - // Create a - - // Only admin can create new zkEVMs - await expect( - rollupManagerContract.createNewRollup( - newRollupTypeID, - chainID2, - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "AddressDoNotHaveRequiredRole"); - - // UNexisting rollupType - await expect( - rollupManagerContract - .connect(admin) - .createNewRollup( - 0, - chainID2, - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "RollupTypeDoesNotExist"); - - // Obsolete rollup type and test that fails - const snapshot2 = await takeSnapshot(); - await expect(rollupManagerContract.connect(admin).obsoleteRollupType(newRollupTypeID)) - .to.emit(rollupManagerContract, "ObsoleteRollupType") - .withArgs(newRollupTypeID); - - await expect( - rollupManagerContract - .connect(admin) - .createNewRollup( - newRollupTypeID, - chainID2, - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "RollupTypeObsolete"); - await snapshot2.restore(); - - const newCreatedRollupID = 2; // 1 is zkEVM - const newZKEVMAddress = ethers.getCreateAddress({ - from: rollupManagerContract.target as string, - nonce: 1, - }); - - const newZkEVMContract = PolygonZKEVMV2Factory.attach(newZKEVMAddress) as PolygonZkEVMEtrog; - const newSequencedBatch = 1; - - await expect( - rollupManagerContract - .connect(admin) - .createNewRollup( - newRollupTypeID, - chainID2, - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName - ) - ) - .to.emit(rollupManagerContract, "CreateNewRollup") - .withArgs(newCreatedRollupID, newRollupTypeID, newZKEVMAddress, chainID2, gasTokenAddress) - .to.emit(newZkEVMContract, "InitialSequenceBatches") - .to.emit(rollupManagerContract, "OnSequenceBatches") - .withArgs(newCreatedRollupID, newSequencedBatch); - - const blockCreatedRollup = await ethers.provider.getBlock("latest"); - - // Assert new rollup created - const timestampCreatedRollup = blockCreatedRollup?.timestamp; - expect(await newZkEVMContract.admin()).to.be.equal(admin.address); - expect(await newZkEVMContract.trustedSequencer()).to.be.equal(trustedSequencer.address); - expect(await newZkEVMContract.trustedSequencerURL()).to.be.equal(urlSequencer); - expect(await newZkEVMContract.networkName()).to.be.equal(networkName); - expect(await newZkEVMContract.forceBatchTimeout()).to.be.equal(FORCE_BATCH_TIMEOUT); - - // Cannot create 2 chains with the same chainID2 - await expect( - rollupManagerContract - .connect(admin) - .createNewRollup( - newRollupTypeID, - chainID2, - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "ChainIDAlreadyExist"); - - const transaction = await newZkEVMContract.generateInitializeTransaction( - newCreatedRollupID, - gasTokenAddress, - gasTokenNetwork, - "0x" // empty metadata - ); - - // Check transaction - const bridgeL2Factory = await ethers.getContractFactory("PolygonZkEVMBridgeV2"); - const encodedData = bridgeL2Factory.interface.encodeFunctionData("initialize", [ - newCreatedRollupID, - gasTokenAddress, - gasTokenNetwork, - globalExitRootL2Address, - ethers.ZeroAddress, - "0x", - ]); - - const rawTx = processorUtils.customRawTxToRawTx(transaction); - const tx = ethers.Transaction.from(rawTx); - const rlpSignData = transaction.slice(0, -(SIGNATURE_BYTES * 2 + EFFECTIVE_PERCENTAGE_BYTES * 2)); - expect(rlpSignData).to.be.equal(tx.unsignedSerialized); - - expect(tx.to).to.be.equal(polygonZkEVMBridgeContract.target); - expect(tx.value).to.be.equal(0); - expect(tx.data).to.be.equal(encodedData); - expect(tx.gasPrice).to.be.equal(0); - expect(tx.gasLimit).to.be.equal(30000000); - expect(tx.nonce).to.be.equal(0); - expect(tx.chainId).to.be.equal(0); - - const expectedAccInputHash = calculateAccInputHashetrog( - ethers.ZeroHash, - ethers.keccak256(transaction), - await polygonZkEVMGlobalExitRoot.getLastGlobalExitRoot(), - timestampCreatedRollup, - trustedSequencer.address, - blockCreatedRollup?.parentHash - ); - // calcualte accINputHash - expect(await newZkEVMContract.lastAccInputHash()).to.be.equal(expectedAccInputHash); - - // Check mapping on rollup Manager - const rollupData = await rollupManagerContract.rollupIDToRollupData(newCreatedRollupID); - expect(rollupData.rollupContract).to.be.equal(newZKEVMAddress); - expect(rollupData.chainID).to.be.equal(chainID2); - expect(rollupData.verifier).to.be.equal(verifierContract.target); - expect(rollupData.forkID).to.be.equal(forkID); - expect(rollupData.lastLocalExitRoot).to.be.equal(ethers.ZeroHash); - expect(rollupData.lastBatchSequenced).to.be.equal(newSequencedBatch); - expect(rollupData.lastVerifiedBatch).to.be.equal(0); - expect(rollupData.lastPendingState).to.be.equal(0); - expect(rollupData.lastPendingStateConsolidated).to.be.equal(0); - expect(rollupData.lastVerifiedBatchBeforeUpgrade).to.be.equal(0); - expect(rollupData.rollupTypeID).to.be.equal(1); - expect(rollupData.rollupCompatibilityID).to.be.equal(0); - - const sequencedBatchData = await rollupManagerContract.getRollupSequencedBatches( - newCreatedRollupID, - newSequencedBatch - ); - - expect(sequencedBatchData.accInputHash).to.be.equal(expectedAccInputHash); - expect(sequencedBatchData.sequencedTimestamp).to.be.equal(timestampCreatedRollup); - expect(sequencedBatchData.previousLastBatchSequenced).to.be.equal(0); - - // try verify batches - const l2txData = "0x123456"; - const maticAmount = await rollupManagerContract.getBatchFee(); - const currentTimestamp = (await ethers.provider.getBlock("latest"))?.timestamp; - - const sequence = { - transactions: l2txData, - forcedGlobalExitRoot: ethers.ZeroHash, - forcedTimestamp: 0, - forcedBlockHashL1: ethers.ZeroHash, - } as BatchDataStructEtrog; - - // Approve tokens - await expect(polTokenContract.connect(trustedSequencer).approve(newZkEVMContract.target, maticAmount)).to.emit( - polTokenContract, - "Approval" - ); - - // Sequence Batches - const currentTime = Number((await ethers.provider.getBlock("latest"))?.timestamp); - const currentLastBatchSequenced = 1; - - const height = 32; - const merkleTreeGLobalExitRoot = new MerkleTreeBridge(height); - - const rootSC = await polygonZkEVMGlobalExitRoot.getRoot(); - const rootJS = merkleTreeGLobalExitRoot.getRoot(); - const indexL1infoRoot = 0; - - expect(rootSC).to.be.equal(rootJS); - - const expectedAccInputHash2 = calculateAccInputHashetrog( - expectedAccInputHash, - ethers.keccak256(l2txData), - rootSC, - currentTime, - trustedSequencer.address, - ethers.ZeroHash - ); - - await expect( - newZkEVMContract - .connect(trustedSequencer) - .sequenceBatches( - [sequence], - indexL1infoRoot, - currentTime, - expectedAccInputHash2, - trustedSequencer.address - ) - ).to.emit(newZkEVMContract, "SequenceBatches"); - - const currnetRollup = await rollupManagerContract.rollupIDToRollupData(newCreatedRollupID); - expect(currnetRollup.lastBatchSequenced).to.be.equal(2); - - // calcualte accINputHash - expect(await newZkEVMContract.lastAccInputHash()).to.be.equal(expectedAccInputHash2); - - // Create a new local exit root mocking some bridge - const tokenName = "Matic Token"; - const tokenSymbol = "MATIC"; - const decimals = 18; - const metadataToken = ethers.AbiCoder.defaultAbiCoder().encode( - ["string", "string", "uint8"], - [tokenName, tokenSymbol, decimals] - ); - - const originNetwork = networkIDRollup; - const tokenAddress = ethers.getAddress(ethers.hexlify(ethers.randomBytes(20))); - const amount = ethers.parseEther("10"); - const destinationNetwork = networkIDMainnet; - const destinationAddress = beneficiary.address; - const metadata = metadataToken; // since we are inserting in the exit root can be anything - const metadataHash = ethers.solidityPackedKeccak256(["bytes"], [metadata]); - - // compute root merkle tree in Js - const merkleTreezkEVM = new MerkleTreeBridge(height); - const leafValue = getLeafValue( - LEAF_TYPE_ASSET, - originNetwork, - tokenAddress, - destinationNetwork, - destinationAddress, - amount, - metadataHash - ); - - // Add 2 leafs - merkleTreezkEVM.add(leafValue); - merkleTreezkEVM.add(leafValue); - - // check merkle root with SC - const rootzkEVM = merkleTreezkEVM.getRoot(); - - // trustedAggregator forge the batch - const pendingState = 0; - const newLocalExitRoot = rootzkEVM; - const newStateRoot = "0x0000000000000000000000000000000000000000000000000000000000000123"; - const newVerifiedBatch = newSequencedBatch; - const zkProofFFlonk = new Array(24).fill(ethers.ZeroHash); - const currentVerifiedBatch = 0; - - const initialAggregatorMatic = await polTokenContract.balanceOf(beneficiary.address); - - await expect( - rollupManagerContract.getInputSnarkBytes( - newCreatedRollupID, - 3, - 4, - newLocalExitRoot, - ethers.ZeroHash, - newStateRoot - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "OldAccInputHashDoesNotExist"); - - await expect( - rollupManagerContract.getInputSnarkBytes( - newCreatedRollupID, - 2, - 3, - newLocalExitRoot, - ethers.ZeroHash, - newStateRoot - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "NewAccInputHashDoesNotExist"); - - await expect( - rollupManagerContract - .connect(trustedAggregator) - .verifyBatches( - newCreatedRollupID, - pendingState, - currentVerifiedBatch, - newVerifiedBatch, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "TrustedAggregatorTimeoutNotExpired"); - - await rollupManagerContract.connect(admin).setTrustedAggregatorTimeout(0); - - await expect( - rollupManagerContract - .connect(trustedAggregator) - .verifyBatches( - newCreatedRollupID, - pendingState, - currentVerifiedBatch, - currentVerifiedBatch + _MAX_VERIFY_BATCHES + 1, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "ExceedMaxVerifyBatches"); - - await expect( - rollupManagerContract - .connect(trustedAggregator) - .verifyBatches( - newCreatedRollupID, - pendingState, - currentVerifiedBatch, - currentVerifiedBatch, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "FinalNumBatchBelowLastVerifiedBatch"); - - await expect( - rollupManagerContract.verifyBatches( - newCreatedRollupID, - pendingState, - currentVerifiedBatch, - 3, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "NewAccInputHashDoesNotExist"); - - // Calcualte new globalExitroot - const merkleTreeRollups = new MerkleTreeBridge(height); - merkleTreeRollups.add(ethers.ZeroHash); - merkleTreeRollups.add(newLocalExitRoot); - const rootRollups = merkleTreeRollups.getRoot(); - - // Verify batch - await expect( - rollupManagerContract.verifyBatches( - newCreatedRollupID, - pendingState, - currentVerifiedBatch, - newVerifiedBatch, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ) - .to.emit(rollupManagerContract, "VerifyBatches") - .withArgs(newCreatedRollupID, newVerifiedBatch, newStateRoot, newLocalExitRoot, deployer.address); - - const timestampVerifyBatches = (await ethers.provider.getBlock("latest"))?.timestamp; - const finalAggregatorMatic = await polTokenContract.balanceOf(beneficiary.address); - expect(finalAggregatorMatic).to.equal(((initialAggregatorMatic + maticAmount) * 1n) / 3n); - const createdPendingState = 1; - - const snapshotVerify = await takeSnapshot(); - await rollupManagerContract.connect(admin).setPendingStateTimeout(0); - - await expect( - rollupManagerContract.verifyBatches( - newCreatedRollupID, - 0, - 5, - 6, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "OldStateRootDoesNotExist"); - - await expect( - rollupManagerContract.verifyBatches( - newCreatedRollupID, - 0, - newVerifiedBatch, - 0, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ).to.be.reverted; - - await expect( - rollupManagerContract.verifyBatches( - newCreatedRollupID, - createdPendingState + 1, - currentVerifiedBatch, - newVerifiedBatch + 1, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "PendingStateDoesNotExist"); - - await expect( - rollupManagerContract.verifyBatches( - newCreatedRollupID, - createdPendingState, - currentVerifiedBatch, - newVerifiedBatch + 1, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "InitNumBatchDoesNotMatchPendingState"); - - await expect( - rollupManagerContract.verifyBatches( - newCreatedRollupID, - createdPendingState, - newVerifiedBatch, - newVerifiedBatch + 1, - newLocalExitRoot, - ethers.toQuantity(ethers.MaxUint256), - beneficiary.address, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "NewStateRootNotInsidePrime"); - - await expect( - rollupManagerContract.verifyBatches( - newCreatedRollupID, - createdPendingState, - newVerifiedBatch, - newVerifiedBatch + 1, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ) - .to.emit(rollupManagerContract, "VerifyBatches") - .withArgs(newCreatedRollupID, newVerifiedBatch + 1, newStateRoot, newLocalExitRoot, deployer.address); - - let rollupDataV = await rollupManagerContract.rollupIDToRollupData(newCreatedRollupID); - expect(rollupDataV.lastPendingState).to.be.equal(0); - expect(rollupDataV.lastLocalExitRoot).to.be.equal(newLocalExitRoot); - expect(rollupDataV.lastBatchSequenced).to.be.equal(2); - expect(rollupDataV.lastVerifiedBatch).to.be.equal(newVerifiedBatch + 1); - expect(rollupDataV.lastPendingState).to.be.equal(0); - expect(rollupDataV.lastPendingStateConsolidated).to.be.equal(0); - expect(rollupDataV.lastVerifiedBatchBeforeUpgrade).to.be.equal(0); - - await expect( - rollupManagerContract - .connect(trustedAggregator) - .verifyBatchesTrustedAggregator( - newCreatedRollupID, - 0, - 0, - newVerifiedBatch, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "FinalNumBatchBelowLastVerifiedBatch"); - - await snapshotVerify.restore(); - await rollupManagerContract.connect(admin).setPendingStateTimeout(1); - - await expect( - rollupManagerContract.verifyBatches( - newCreatedRollupID, - createdPendingState, - newVerifiedBatch, - newVerifiedBatch + 1, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ) - .to.emit(rollupManagerContract, "VerifyBatches") - .withArgs(newCreatedRollupID, newVerifiedBatch + 1, newStateRoot, newLocalExitRoot, deployer.address); - - rollupDataV = await rollupManagerContract.rollupIDToRollupData(newCreatedRollupID); - expect(rollupDataV.lastPendingState).to.be.equal(2); - expect(rollupDataV.lastLocalExitRoot).to.be.equal(newLocalExitRoot); - expect(rollupDataV.lastBatchSequenced).to.be.equal(2); - expect(rollupDataV.lastVerifiedBatch).to.be.equal(newVerifiedBatch); - expect(rollupDataV.lastPendingStateConsolidated).to.be.equal(1); - expect(rollupDataV.lastVerifiedBatchBeforeUpgrade).to.be.equal(0); - - await snapshotVerify.restore(); - - await expect( - rollupManagerContract - .connect(trustedAggregator) - .verifyBatchesTrustedAggregator( - newCreatedRollupID, - pendingState, - currentVerifiedBatch, - newVerifiedBatch + 1, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ) - .to.emit(rollupManagerContract, "VerifyBatchesTrustedAggregator") - .withArgs( - newCreatedRollupID, - newVerifiedBatch + 1, - newStateRoot, - newLocalExitRoot, - trustedAggregator.address - ); - - rollupDataV = await rollupManagerContract.rollupIDToRollupData(newCreatedRollupID); - expect(rollupDataV.lastPendingState).to.be.equal(0); - expect(rollupDataV.lastLocalExitRoot).to.be.equal(newLocalExitRoot); - expect(rollupDataV.lastBatchSequenced).to.be.equal(2); - expect(rollupDataV.lastVerifiedBatch).to.be.equal(newVerifiedBatch + 1); - expect(rollupDataV.lastPendingState).to.be.equal(0); - expect(rollupDataV.lastPendingStateConsolidated).to.be.equal(0); - expect(rollupDataV.lastVerifiedBatchBeforeUpgrade).to.be.equal(0); - - await snapshotVerify.restore(); - await expect( - rollupManagerContract.proveNonDeterministicPendingState( - newCreatedRollupID, - 0, - createdPendingState, - 0, - newVerifiedBatch, - newLocalExitRoot, - newStateRoot, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "StoredRootMustBeDifferentThanNewRoot"); - - await expect( - rollupManagerContract.proveNonDeterministicPendingState( - newCreatedRollupID, - 0, - createdPendingState, - 5, - newVerifiedBatch, - newLocalExitRoot, - newStateRoot, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "OldStateRootDoesNotExist"); - - await expect( - rollupManagerContract.proveNonDeterministicPendingState( - newCreatedRollupID, - 3, // init pending state - 2, - 0, - newVerifiedBatch, - newLocalExitRoot, - newStateRoot, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "PendingStateDoesNotExist"); - - await expect( - rollupManagerContract.proveNonDeterministicPendingState( - newCreatedRollupID, - createdPendingState, - createdPendingState, - 0, - newVerifiedBatch, - newLocalExitRoot, - newStateRoot, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "InitNumBatchDoesNotMatchPendingState"); - - await expect( - rollupManagerContract.proveNonDeterministicPendingState( - newCreatedRollupID, - createdPendingState, - createdPendingState, - newVerifiedBatch, - newVerifiedBatch, - newLocalExitRoot, - newStateRoot, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "FinalPendingStateNumInvalid"); - - await expect( - rollupManagerContract.proveNonDeterministicPendingState( - newCreatedRollupID, - 0, - createdPendingState, - 0, - newVerifiedBatch + 1, - newLocalExitRoot, - ethers.ZeroHash, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "FinalNumBatchDoesNotMatchPendingState"); - - await expect( - rollupManagerContract.proveNonDeterministicPendingState( - newCreatedRollupID, - 0, - createdPendingState, - 0, - newVerifiedBatch, - newLocalExitRoot, - ethers.ZeroHash, - zkProofFFlonk - ) - ) - .to.emit(rollupManagerContract, "ProveNonDeterministicPendingState") - .withArgs(newStateRoot, ethers.ZeroHash); - - expect(await rollupManagerContract.isEmergencyState()).to.be.equal(true); - - await snapshotVerify.restore(); - - const randomSTateRoot = ethers.hexlify(ethers.randomBytes(32)); - const randomlocalRoot = ethers.hexlify(ethers.randomBytes(32)); - - await expect( - rollupManagerContract.connect(trustedAggregator).overridePendingState( - newCreatedRollupID, - 0, - createdPendingState, - 0, - newVerifiedBatch, - randomlocalRoot, // local exit root - randomSTateRoot, // state root - zkProofFFlonk - ) - ) - .to.emit(rollupManagerContract, "OverridePendingState") - .withArgs( - newCreatedRollupID, - newVerifiedBatch, - randomSTateRoot, - randomlocalRoot, - trustedAggregator.address - ); - - expect( - await rollupManagerContract.getRollupBatchNumToStateRoot(newCreatedRollupID, newVerifiedBatch) - ).to.be.equal(randomSTateRoot); - - rollupDataV = await rollupManagerContract.rollupIDToRollupData(newCreatedRollupID); - expect(rollupDataV.lastPendingState).to.be.equal(0); - expect(rollupDataV.lastLocalExitRoot).to.be.equal(randomlocalRoot); - expect(rollupDataV.lastBatchSequenced).to.be.equal(2); - expect(rollupDataV.lastVerifiedBatch).to.be.equal(newVerifiedBatch); - expect(rollupDataV.lastPendingState).to.be.equal(0); - expect(rollupDataV.lastPendingStateConsolidated).to.be.equal(0); - - expect(await rollupManagerContract.isEmergencyState()).to.be.equal(false); - expect(await rollupManagerContract.trustedAggregatorTimeout()).to.be.equal(_HALT_AGGREGATION_TIMEOUT); - - await snapshotVerify.restore(); - - const pendingStateNum = 1; - // check revert reasons: - - expect( - await rollupManagerContract.isPendingStateConsolidable(newCreatedRollupID, createdPendingState) - ).to.be.equal(false); - - const currentPendingStateTransition = await rollupManagerContract.getRollupPendingStateTransitions( - newCreatedRollupID, - createdPendingState - ); - - expect(currentPendingStateTransition.timestamp).to.be.equal(timestampVerifyBatches); - expect(currentPendingStateTransition.lastVerifiedBatch).to.be.equal(newVerifiedBatch); - expect(currentPendingStateTransition.exitRoot).to.be.equal(newLocalExitRoot); - expect(currentPendingStateTransition.stateRoot).to.be.equal(newStateRoot); - - await expect( - rollupManagerContract.consolidatePendingState(newCreatedRollupID, pendingStateNum) - ).to.be.revertedWithCustomError(rollupManagerContract, "PendingStateNotConsolidable"); - - // try emergency - await rollupManagerContract.connect(emergencyCouncil).activateEmergencyState(); - await rollupManagerContract.connect(admin).setPendingStateTimeout(0); - - await expect( - rollupManagerContract.consolidatePendingState(newCreatedRollupID, pendingStateNum) - ).to.be.revertedWithCustomError(rollupManagerContract, "OnlyNotEmergencyState"); - await snapshotVerify.restore(); - - await expect( - rollupManagerContract - .connect(trustedAggregator) - .consolidatePendingState(newCreatedRollupID, pendingStateNum + 1) - ).to.be.revertedWithCustomError(rollupManagerContract, "PendingStateInvalid"); - - await expect( - rollupManagerContract - .connect(trustedAggregator) - .consolidatePendingState(newCreatedRollupID, pendingStateNum) - ) - .to.emit(rollupManagerContract, "ConsolidatePendingState") - .withArgs(newCreatedRollupID, newVerifiedBatch, newStateRoot, newLocalExitRoot, pendingStateNum); - - // Assert new root - expect( - await rollupManagerContract.getRollupBatchNumToStateRoot(newCreatedRollupID, newVerifiedBatch) - ).to.be.equal(newStateRoot); - - // Assert global exit root - expect(await polygonZkEVMGlobalExitRoot.lastRollupExitRoot()).to.be.equal(rootRollups); - expect(await polygonZkEVMGlobalExitRoot.lastMainnetExitRoot()).to.be.equal(ethers.ZeroHash); - - expect(await polygonZkEVMGlobalExitRoot.getLastGlobalExitRoot()).to.be.equal( - calculateGlobalExitRoot(ethers.ZeroHash, rootRollups) - ); - - const indexLeaf = 0; - const indexRollup = 1; - const proofZkEVM = merkleTreezkEVM.getProofTreeByIndex(indexLeaf); - const proofRollups = merkleTreeRollups.getProofTreeByIndex(indexRollup); - - // verify merkle proof - expect(verifyMerkleProof(leafValue, proofZkEVM, indexLeaf, rootzkEVM)).to.be.equal(true); - expect(verifyMerkleProof(rootzkEVM, proofRollups, indexRollup, rootRollups)).to.be.equal(true); - - expect( - await polygonZkEVMBridgeContract.verifyMerkleProof(leafValue, proofZkEVM, indexLeaf, rootzkEVM) - ).to.be.equal(true); - - expect( - await polygonZkEVMBridgeContract.verifyMerkleProof(newLocalExitRoot, proofRollups, indexRollup, rootRollups) - ).to.be.equal(true); - - // claim - const tokenWrappedFactory = await ethers.getContractFactory("TokenWrapped"); - // create2 parameters - const salt = ethers.solidityPackedKeccak256(["uint32", "address"], [networkIDRollup, tokenAddress]); - const minimalBytecodeProxy = await polygonZkEVMBridgeContract.BASE_INIT_BYTECODE_WRAPPED_TOKEN(); - const hashInitCode = ethers.solidityPackedKeccak256(["bytes", "bytes"], [minimalBytecodeProxy, metadataToken]); - const precalculateWrappedErc20 = await ethers.getCreate2Address( - polygonZkEVMBridgeContract.target as string, - salt, - hashInitCode - ); - const newWrappedToken = tokenWrappedFactory.attach(precalculateWrappedErc20) as TokenWrapped; - - // Use precalculatedWrapperAddress and check if matches - expect( - await polygonZkEVMBridgeContract.precalculatedWrapperAddress( - networkIDRollup, - tokenAddress, - tokenName, - tokenSymbol, - decimals - ) - ).to.be.equal(precalculateWrappedErc20); - - // index leaf is 0 bc, does not have mainnet flag, and it's rollup 0 on leaf 0 - const globalIndex = computeGlobalIndex(indexLeaf, indexRollup, false); - await expect( - polygonZkEVMBridgeContract.claimAsset( - proofZkEVM, - proofRollups, - globalIndex, - ethers.ZeroHash, - rootRollups, - originNetwork, - tokenAddress, - destinationNetwork, - destinationAddress, - amount, - metadata - ) - ) - .to.emit(polygonZkEVMBridgeContract, "ClaimEvent") - .withArgs(globalIndex, originNetwork, tokenAddress, destinationAddress, amount) - .to.emit(polygonZkEVMBridgeContract, "NewWrappedToken") - .withArgs(originNetwork, tokenAddress, precalculateWrappedErc20, metadata) - .to.emit(newWrappedToken, "Transfer") - .withArgs(ethers.ZeroAddress, beneficiary.address, amount); - - // Assert maps created - const newTokenInfo = await polygonZkEVMBridgeContract.wrappedTokenToTokenInfo(precalculateWrappedErc20); - - expect(newTokenInfo.originNetwork).to.be.equal(networkIDRollup); - expect(newTokenInfo.originTokenAddress).to.be.equal(tokenAddress); - expect(await polygonZkEVMBridgeContract.getTokenWrappedAddress(networkIDRollup, tokenAddress)).to.be.equal( - precalculateWrappedErc20 - ); - expect(await polygonZkEVMBridgeContract.getTokenWrappedAddress(networkIDRollup, tokenAddress)).to.be.equal( - precalculateWrappedErc20 - ); - - expect(await polygonZkEVMBridgeContract.tokenInfoToWrappedToken(salt)).to.be.equal(precalculateWrappedErc20); - - // Check the wrapper info - expect(await newWrappedToken.name()).to.be.equal(tokenName); - expect(await newWrappedToken.symbol()).to.be.equal(tokenSymbol); - expect(await newWrappedToken.decimals()).to.be.equal(decimals); - - // Can't claim because nullifier - await expect( - polygonZkEVMBridgeContract.claimAsset( - proofZkEVM, - proofRollups, - globalIndex, - ethers.ZeroHash, - rootRollups, - originNetwork, - tokenAddress, - destinationNetwork, - destinationAddress, - amount, - metadata - ) - ).to.be.revertedWithCustomError(polygonZkEVMBridgeContract, "AlreadyClaimed"); - - // Check new token - expect(await newWrappedToken.totalSupply()).to.be.equal(amount); - }); - it("Should test obsolete rollup", async () => { const forkID = 0; const genesisRandom = "0x0000000000000000000000000000000000000000000000000000000000000001"; - const rollupCompatibilityID = 0; - const descirption = "zkevm test"; + const rollupVerifierType = 0; + const description = "zkevm test"; + const programVKey = "0x0000000000000000000000000000000000000000000000000000000000000000"; // In order to create a new rollup type, create an implementation of the contract @@ -2041,9 +1068,10 @@ describe("Polygon Rollup manager upgraded", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ) ) .to.emit(rollupManagerContract, "AddNewRollupType") @@ -2052,9 +1080,10 @@ describe("Polygon Rollup manager upgraded", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ); // assert new rollup type @@ -2064,9 +1093,10 @@ describe("Polygon Rollup manager upgraded", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, false, genesisRandom, + programVKey, ]; expect(createdRollupType).to.be.deep.equal(expectedRollupType);