diff --git a/contracts/AgglayerManager.sol b/contracts/AgglayerManager.sol index b6206e438..c290f0aa6 100644 --- a/contracts/AgglayerManager.sol +++ b/contracts/AgglayerManager.sol @@ -14,7 +14,6 @@ import "./lib/PolygonTransparentProxy.sol"; import "./lib/PolygonAccessControlUpgradeable.sol"; import "./lib/LegacyZKEVMStateVariables.sol"; import "./lib/PolygonConstantsBase.sol"; -import "./interfaces/IPolygonPessimisticConsensus.sol"; import "./interfaces/ISP1Verifier.sol"; import "./interfaces/IAgglayerManager.sol"; import "./interfaces/IAggchainBase.sol"; @@ -528,10 +527,7 @@ contract AgglayerManager is uint32 rollupTypeID = ++rollupTypeCount; - if (rollupVerifierType == VerifierType.Pessimistic) { - // No genesis on pessimistic rollups - if (genesis != bytes32(0)) revert InvalidRollupType(); - } else if (rollupVerifierType == VerifierType.ALGateway) { + if (rollupVerifierType == VerifierType.ALGateway) { // Those params should be zero for ALGateway rollup types if ( verifier != address(0) || @@ -778,14 +774,7 @@ contract AgglayerManager is rollup.rollupVerifierType = rollupVerifierType; // Check verifier type - if (rollupVerifierType == VerifierType.Pessimistic) { - rollup.programVKey = programVKey; - rollup.lastPessimisticRoot = initPessimisticRoot; - rollup.lastLocalExitRoot = initRoot; - if (verifier.code.length == 0) { - revert InvalidVerifierAddress(); - } - } else if (rollupVerifierType == VerifierType.ALGateway) { + if (rollupVerifierType == VerifierType.ALGateway) { if ( verifier != address(0) || forkID != 0 || @@ -990,11 +979,11 @@ contract AgglayerManager is revert AllSequencedMustBeVerified(); } - // NewRollupType must be pessimistic or ALGateway + // NewRollupType must be ALGateway require( - rollupTypeMap[newRollupTypeID].rollupVerifierType != - VerifierType.StateTransition, - NewRollupTypeMustBePessimisticOrALGateway() + rollupTypeMap[newRollupTypeID].rollupVerifierType == + VerifierType.ALGateway, + InvalidRollupType() ); // Add rollupID to migration mapping @@ -1312,14 +1301,6 @@ contract AgglayerManager is revert StateTransitionChainsNotAllowed(); } - // Not aggchainData for VerifierType.Pessimistic - if ( - rollup.rollupVerifierType == VerifierType.Pessimistic && - aggchainData.length != 0 - ) { - revert AggchainDataMustBeZeroForPessimisticVerifierType(); - } - // Check l1InfoTreeLeafCount has a valid l1InfoTreeRoot bytes32 l1InfoRoot = globalExitRootManager.l1InfoRootMap( l1InfoTreeLeafCount @@ -1361,23 +1342,14 @@ contract AgglayerManager is aggchainData ); - if (rollup.rollupVerifierType == VerifierType.ALGateway) { - // Verify proof. The pessimistic proof selector is attached at the first 4 bytes of the proof - // proof[0:4]: 4 bytes selector pp - // proof[4:8]: 4 bytes selector SP1 verifier - // proof[8:]: proof - aggLayerGateway.verifyPessimisticProof( - inputPessimisticBytes, - proof - ); - } else { - // Verify proof - ISP1Verifier(rollup.verifier).verifyProof( - rollup.programVKey, - inputPessimisticBytes, - proof - ); - } + // Verify proof. The pessimistic proof selector is attached at the first 4 bytes of the proof + // proof[0:4]: 4 bytes selector pp + // proof[4:8]: 4 bytes selector SP1 verifier + // proof[8:]: proof + aggLayerGateway.verifyPessimisticProof( + inputPessimisticBytes, + proof + ); // Update aggregation parameters lastAggregationTimestamp = uint64(block.timestamp); @@ -1413,13 +1385,11 @@ contract AgglayerManager is msg.sender ); - if (rollup.rollupVerifierType == VerifierType.ALGateway) { - // Allow chains to manage customData - // Callback to the rollup address - IAggchainBase(rollup.rollupContract).onVerifyPessimistic( - aggchainData - ); - } + // Allow chains to manage customData + // Callback to the rollup address + IAggchainBase(rollup.rollupContract).onVerifyPessimistic( + aggchainData + ); } //////////////////////// @@ -1660,35 +1630,18 @@ contract AgglayerManager is bytes32 newPessimisticRoot, bytes calldata aggchainData ) internal view returns (bytes memory inputPessimisticBytes) { - // Different consensusHash and encoding if the rollup is ALGateway or pessimistic - if (rollup.rollupVerifierType == VerifierType.ALGateway) { - bytes32 aggchainHash = IAggchainBase(rollup.rollupContract) - .getAggchainHash(aggchainData); + bytes32 aggchainHash = IAggchainBase(rollup.rollupContract) + .getAggchainHash(aggchainData); - inputPessimisticBytes = abi.encodePacked( - rollup.lastLocalExitRoot, - rollup.lastPessimisticRoot, - l1InfoTreeRoot, - rollupID, - aggchainHash, - newLocalExitRoot, - newPessimisticRoot - ); - } else { - bytes32 consensusHash = IPolygonPessimisticConsensus( - address(rollup.rollupContract) - ).getConsensusHash(); - - inputPessimisticBytes = abi.encodePacked( - rollup.lastLocalExitRoot, - rollup.lastPessimisticRoot, - l1InfoTreeRoot, - rollupID, - consensusHash, - newLocalExitRoot, - newPessimisticRoot - ); - } + inputPessimisticBytes = abi.encodePacked( + rollup.lastLocalExitRoot, + rollup.lastPessimisticRoot, + l1InfoTreeRoot, + rollupID, + aggchainHash, + newLocalExitRoot, + newPessimisticRoot + ); } /** diff --git a/contracts/interfaces/IAgglayerManager.sol b/contracts/interfaces/IAgglayerManager.sol index a2629c508..3a602ed07 100644 --- a/contracts/interfaces/IAgglayerManager.sol +++ b/contracts/interfaces/IAgglayerManager.sol @@ -304,11 +304,6 @@ interface IAgglayerManager { */ error StateTransitionChainsNotAllowed(); - /** - * @dev Custom chain data must be zero for pessimistic verifier type - */ - error AggchainDataMustBeZeroForPessimisticVerifierType(); - /** * @dev Invalid Pessimistic proof */ @@ -339,11 +334,6 @@ interface IAgglayerManager { */ error InvalidVerifierAddress(); - /** - * @dev Thrown when trying to migrate a rollup to a non pessimistic rollup type with `initMigration` function. - */ - error NewRollupTypeMustBePessimisticOrALGateway(); - /** * @dev Thrown when trying to finish a migration of a rollup to a pessimistic rollup type with `verifyPessimisticTrustedAggregator` function and the proposed new local exit root does not match the expected new local exit root */ @@ -351,6 +341,7 @@ interface IAgglayerManager { enum VerifierType { StateTransition, + // Deprecated: Pessimistic rollup type is deprecated. Now new rollups can be created with such types nor migrated to/from it. Pessimistic, ALGateway } diff --git a/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts b/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts deleted file mode 100644 index ff9a59aa8..000000000 --- a/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts +++ /dev/null @@ -1,1017 +0,0 @@ -/* eslint-disable no-plusplus, no-await-in-loop */ -import { expect } from 'chai'; -import { ethers, upgrades } from 'hardhat'; -import { setCode } from '@nomicfoundation/hardhat-network-helpers'; - -import { - VerifierRollupHelperMock, - ERC20PermitMock, - AgglayerManagerMock, - AgglayerGER, - AgglayerBridge, - Address, - PolygonPessimisticConsensus, -} from '../../typechain-types'; - -import { - VerifierType, - computeInputPessimisticBytes, - computeConsensusHashEcdsa, - computeRandomBytes, -} from '../../src/pessimistic-utils'; -import { encodeInitializeBytesLegacy } from '../../src/utils-common-aggchain'; -import { - DEFAULT_ADMIN_ROLE, - ADD_ROLLUP_TYPE_ROLE, - OBSOLETE_ROLLUP_TYPE_ROLE, - CREATE_ROLLUP_ROLE, - ADD_EXISTING_ROLLUP_ROLE, - UPDATE_ROLLUP_ROLE, - TRUSTED_AGGREGATOR_ROLE, - TRUSTED_AGGREGATOR_ROLE_ADMIN, - TWEAK_PARAMETERS_ROLE, - SET_FEE_ROLE, - STOP_EMERGENCY_ROLE, - EMERGENCY_COUNCIL_ROLE, - EMERGENCY_COUNCIL_ADMIN, -} from '../../src/constants'; - -describe('Polygon Rollup Manager with Polygon Pessimistic Consensus', () => { - let deployer: any; - let timelock: any; - let emergencyCouncil: any; - let trustedAggregator: any; - let trustedSequencer: any; - let admin: any; - let beneficiary: any; - - let verifierContract: VerifierRollupHelperMock; - let polygonZkEVMBridgeContract: AgglayerBridge; - let polTokenContract: ERC20PermitMock; - let polygonZkEVMGlobalExitRoot: AgglayerGER; - let rollupManagerContract: AgglayerManagerMock; - let PolygonPPConsensusContract: PolygonPessimisticConsensus; - - const polTokenName = 'POL Token'; - const polTokenSymbol = 'POL'; - const polTokenInitialBalance = ethers.parseEther('20000000'); - - // Bridge constants - const networkIDMainnet = 0; - let firstDeployment = true; - - beforeEach('Deploy contract', async () => { - upgrades.silenceWarnings(); - - // load signers - [deployer, trustedAggregator, trustedSequencer, admin, timelock, emergencyCouncil, beneficiary] = - await ethers.getSigners(); - - // deploy mock verifier - const VerifierRollupHelperFactory = await ethers.getContractFactory('VerifierRollupHelperMock'); - verifierContract = await VerifierRollupHelperFactory.deploy(); - - // deploy pol - const polTokenFactory = await ethers.getContractFactory('ERC20PermitMock'); - polTokenContract = await polTokenFactory.deploy( - polTokenName, - polTokenSymbol, - deployer.address, - polTokenInitialBalance, - ); - - /* - * deploy global exit root manager - * In order to not have trouble with nonce deploy first proxy admin - */ - await upgrades.deployProxyAdmin(); - - if ((await upgrades.admin.getInstance()).target !== '0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0') { - firstDeployment = false; - } - - // deploy AgglayerGateway - const AgglayerGatewayFactory = await ethers.getContractFactory('AgglayerGateway'); - const aggLayerGatewayContract = await upgrades.deployProxy(AgglayerGatewayFactory, [], { - initializer: false, - unsafeAllow: ['constructor'], - }); - - const nonceProxyBridge = - Number(await ethers.provider.getTransactionCount(deployer.address)) + (firstDeployment ? 3 : 2); - - const nonceProxyZkevm = nonceProxyBridge + 2; // Always have to redeploy impl since the polygonZkEVMGlobalExitRoot address changes - - const precalculateBridgeAddress = ethers.getCreateAddress({ - from: deployer.address, - nonce: nonceProxyBridge, - }); - const precalculateRollupManagerAddress = ethers.getCreateAddress({ - from: deployer.address, - nonce: nonceProxyZkevm, - }); - firstDeployment = false; - - // deploy globalExitRoot - const PolygonZkEVMGlobalExitRootFactory = await ethers.getContractFactory('AgglayerGER'); - polygonZkEVMGlobalExitRoot = await upgrades.deployProxy(PolygonZkEVMGlobalExitRootFactory, [], { - constructorArgs: [precalculateRollupManagerAddress, precalculateBridgeAddress], - unsafeAllow: ['constructor', 'state-variable-immutable'], - }); - - // deploy PolygonZkEVMBridge - const polygonZkEVMBridgeFactory = await ethers.getContractFactory('AgglayerBridge'); - polygonZkEVMBridgeContract = await upgrades.deployProxy(polygonZkEVMBridgeFactory, [], { - initializer: false, - unsafeAllow: ['constructor', 'missing-initializer', 'missing-initializer-call'], - }); - - // deploy polygon rollup manager mock - const PolygonRollupManagerFactory = await ethers.getContractFactory('AgglayerManagerMock'); - - rollupManagerContract = (await upgrades.deployProxy(PolygonRollupManagerFactory, [], { - initializer: false, - constructorArgs: [ - polygonZkEVMGlobalExitRoot.target, - polTokenContract.target, - polygonZkEVMBridgeContract.target, - aggLayerGatewayContract.target, - ], - unsafeAllow: ['constructor', 'missing-initializer', 'missing-initializer-call', 'state-variable-immutable'], - })) as unknown as AgglayerManagerMock; - - await rollupManagerContract.waitForDeployment(); - - // check precalculated address - // expect(precalculateBridgeAddress).to.be.equal(polygonZkEVMBridgeContract.target); - // expect(precalculateRollupManagerAddress).to.be.equal(rollupManagerContract.target); - - await polygonZkEVMBridgeContract.initialize( - networkIDMainnet, - ethers.ZeroAddress, // zero for ether - ethers.ZeroAddress, // zero for ether - polygonZkEVMGlobalExitRoot.target, - rollupManagerContract.target, - '0x', - ); - - // Initialize Mock - await expect( - rollupManagerContract.initializeMock( - trustedAggregator.address, - admin.address, - timelock.address, - emergencyCouncil.address, - ), - ).to.emit(rollupManagerContract, 'UpdateRollupManagerVersion'); - - // fund sequencer address with Matic tokens - await polTokenContract.transfer(trustedSequencer.address, ethers.parseEther('1000')); - }); - - it('should check the initalized parameters', async () => { - expect(await rollupManagerContract.globalExitRootManager()).to.be.equal(polygonZkEVMGlobalExitRoot.target); - expect(await rollupManagerContract.pol()).to.be.equal(polTokenContract.target); - expect(await rollupManagerContract.bridgeAddress()).to.be.equal(polygonZkEVMBridgeContract.target); - - expect(await rollupManagerContract.getBatchFee()).to.be.equal(ethers.parseEther('0.1')); - expect(await rollupManagerContract.getForcedBatchFee()).to.be.equal(ethers.parseEther('10')); - expect(await rollupManagerContract.calculateRewardPerBatch()).to.be.equal(0); - - // Check roles - expect(await rollupManagerContract.hasRole(DEFAULT_ADMIN_ROLE, timelock.address)).to.be.equal(true); - expect(await rollupManagerContract.hasRole(ADD_ROLLUP_TYPE_ROLE, timelock.address)).to.be.equal(true); - expect(await rollupManagerContract.hasRole(UPDATE_ROLLUP_ROLE, timelock.address)).to.be.equal(true); - expect(await rollupManagerContract.hasRole(ADD_EXISTING_ROLLUP_ROLE, timelock.address)).to.be.equal(true); - - expect(await rollupManagerContract.hasRole(TRUSTED_AGGREGATOR_ROLE, trustedAggregator.address)).to.be.equal( - true, - ); - - expect(await rollupManagerContract.hasRole(OBSOLETE_ROLLUP_TYPE_ROLE, admin.address)).to.be.equal(true); - expect(await rollupManagerContract.hasRole(CREATE_ROLLUP_ROLE, admin.address)).to.be.equal(true); - expect(await rollupManagerContract.hasRole(TRUSTED_AGGREGATOR_ROLE_ADMIN, admin.address)).to.be.equal(true); - expect(await rollupManagerContract.hasRole(TWEAK_PARAMETERS_ROLE, admin.address)).to.be.equal(true); - expect(await rollupManagerContract.hasRole(SET_FEE_ROLE, admin.address)).to.be.equal(true); - expect(await rollupManagerContract.hasRole(STOP_EMERGENCY_ROLE, admin.address)).to.be.equal(true); - - expect(await rollupManagerContract.hasRole(EMERGENCY_COUNCIL_ROLE, emergencyCouncil.address)).to.be.equal(true); - expect(await rollupManagerContract.hasRole(EMERGENCY_COUNCIL_ADMIN, emergencyCouncil.address)).to.be.equal( - true, - ); - }); - - it('should add a new rollup type: PolygonConsensusPessimistic', async () => { - // deploy consensus - // create polygonPessimisticConsensus implementation - const ppConsensusFactory = await ethers.getContractFactory('PolygonPessimisticConsensus'); - PolygonPPConsensusContract = await ppConsensusFactory.deploy( - polygonZkEVMGlobalExitRoot.target, - polTokenContract.target, - polygonZkEVMBridgeContract.target, - rollupManagerContract.target, - ); - await PolygonPPConsensusContract.waitForDeployment(); - - // Try to add a new rollup type - const forkID = 11; // just metadata for pessimistic consensus - const genesis = ethers.ZeroHash; - const description = 'new pessimistic consensus'; - const programVKey = '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'; - const newRollupTypeID = 1; - const nonZeroGenesis = '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'; - - // sender does not have _ADD_ROLLUP_TYPE_ROLE role - await expect( - rollupManagerContract.addNewRollupType( - PolygonPPConsensusContract.target, - verifierContract.target, - forkID, - VerifierType.Pessimistic, - genesis, - description, - programVKey, - ), - ).to.be.revertedWithCustomError(rollupManagerContract, 'AddressDoNotHaveRequiredRole'); - - // genesis != 0 on Pessimistic Verifier type - await expect( - rollupManagerContract - .connect(timelock) - .addNewRollupType( - PolygonPPConsensusContract.target, - verifierContract.target, - forkID, - VerifierType.Pessimistic, - nonZeroGenesis, - description, - programVKey, - ), - ).to.be.revertedWithCustomError(rollupManagerContract, 'InvalidRollupType'); - - // correct add new rollup via timelock - await expect( - rollupManagerContract - .connect(timelock) - .addNewRollupType( - PolygonPPConsensusContract.target, - verifierContract.target, - forkID, - VerifierType.Pessimistic, - genesis, - description, - programVKey, - ), - ) - .to.emit(rollupManagerContract, 'AddNewRollupType') - .withArgs( - newRollupTypeID, - PolygonPPConsensusContract.target, - verifierContract.target, - forkID, - VerifierType.Pessimistic, - genesis, - description, - programVKey, - ); - - // assert new rollup type - const createdRollupType = await rollupManagerContract.rollupTypeMap(newRollupTypeID); - - const expectedRollupType = [ - PolygonPPConsensusContract.target, - verifierContract.target, - forkID, - VerifierType.Pessimistic, - false, - genesis, - programVKey, - ]; - - expect(createdRollupType).to.be.deep.equal(expectedRollupType); - - // do obsoleteRollupType - await expect(rollupManagerContract.obsoleteRollupType(newRollupTypeID)).to.be.revertedWithCustomError( - rollupManagerContract, - 'AddressDoNotHaveRequiredRole', - ); - - await expect(rollupManagerContract.connect(admin).obsoleteRollupType(newRollupTypeID)) - .to.emit(rollupManagerContract, 'ObsoleteRollupType') - .withArgs(newRollupTypeID); - }); - - it('should create a new rollup: PolygonConsensusPessimistic', async () => { - // deploy consensus - // create polygonPessimisticConsensus implementation - const ppConsensusFactory = await ethers.getContractFactory('PolygonPessimisticConsensus'); - PolygonPPConsensusContract = await ppConsensusFactory.deploy( - polygonZkEVMGlobalExitRoot.target, - polTokenContract.target, - polygonZkEVMBridgeContract.target, - rollupManagerContract.target, - ); - await PolygonPPConsensusContract.waitForDeployment(); - - // Try to add a new rollup type - const forkID = 11; // just metadata for pessimistic consensus - const genesis = ethers.ZeroHash; - const description = 'new pessimistic consensus'; - const programVKey = '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'; - const newRollupTypeID = 1; - - // correct add new rollup via timelock - await expect( - rollupManagerContract - .connect(timelock) - .addNewRollupType( - PolygonPPConsensusContract.target, - verifierContract.target, - forkID, - VerifierType.Pessimistic, - genesis, - description, - programVKey, - ), - ) - .to.emit(rollupManagerContract, 'AddNewRollupType') - .withArgs( - newRollupTypeID, - PolygonPPConsensusContract.target, - verifierContract.target, - forkID, - VerifierType.Pessimistic, - genesis, - description, - programVKey, - ); - - // create new pessimsitic: only admin - const chainID = 1; - const gasTokenAddress = ethers.ZeroAddress; - const urlSequencer = 'https://pessimistic:8545'; - const networkName = 'testPessimistic'; - const newCreatedRollupID = 1; - const nonExistentRollupID = 4; - - // Only admin can create new zkEVMs - const initializeBytesAggchain = encodeInitializeBytesLegacy( - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName, - ); - await expect( - rollupManagerContract.attachAggchainToAL(newRollupTypeID, chainID, initializeBytesAggchain), - ).to.be.revertedWithCustomError(rollupManagerContract, 'AddressDoNotHaveRequiredRole'); - - // rollupTypeID does not exist - await expect( - rollupManagerContract - .connect(admin) - .attachAggchainToAL(nonExistentRollupID, chainID, initializeBytesAggchain), - ).to.be.revertedWithCustomError(rollupManagerContract, 'RollupTypeDoesNotExist'); - - // create new pessimistic - const newZKEVMAddress = ethers.getCreateAddress({ - from: rollupManagerContract.target as string, - nonce: 1, - }); - const newZkEVMContract = ppConsensusFactory.attach(newZKEVMAddress) as PolygonPessimisticConsensus; - - await expect( - rollupManagerContract.connect(admin).attachAggchainToAL(newRollupTypeID, chainID, initializeBytesAggchain), - ) - .to.emit(rollupManagerContract, 'CreateNewRollup') - .withArgs(newCreatedRollupID, newRollupTypeID, newZKEVMAddress, chainID, gasTokenAddress); - - // assert new rollup created - 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); - - // assert new rollup - const resRollupData = await rollupManagerContract.rollupIDToRollupDataV2(newCreatedRollupID); - - const expectedRollupData = [ - newZKEVMAddress, - chainID, - verifierContract.target, - forkID, - ethers.ZeroHash, - 0, - 0, - 0, - newRollupTypeID, - VerifierType.Pessimistic, - ethers.ZeroHash, - programVKey, - ]; - - expect(expectedRollupData).to.be.deep.equal(resRollupData); - }); - - it('should add an existing rollup: PolygonConsensusPessimistic', async () => { - // add existing rollup - const rollupAddress = '0xAa000000000000000000000000000000000000Bb'; - const forkID = 1; - const chainID = 1; - const initLER = '0xff000000000000000000000000000000000000000000000000000000000000ff'; - const programVKey = '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'; - const initPessimisticRoot = ethers.id('initPessimisticRoot'); - - // add existing rollup: pessimistic type - const newCreatedRollupID = 1; - // Add arbitrary bytecode to the implementation - await setCode(rollupAddress, computeRandomBytes(32)); - await expect( - rollupManagerContract.connect(timelock).addExistingRollup( - rollupAddress, - verifierContract.target, - forkID, - chainID, - initLER, - VerifierType.Pessimistic, - programVKey, - initPessimisticRoot, // initPessimisticRoot - ), - ) - .to.emit(rollupManagerContract, 'AddExistingRollup') - .withArgs( - newCreatedRollupID, - forkID, - rollupAddress, - chainID, - VerifierType.Pessimistic, - 0, - programVKey, - initPessimisticRoot, - ); - }); - - it('should prevent to update rollup with different VerifierTypes', async () => { - // deploy consensus - // create polygonPessimisticConsensus implementation - const ppConsensusFactory = await ethers.getContractFactory('PolygonPessimisticConsensus'); - PolygonPPConsensusContract = await ppConsensusFactory.deploy( - polygonZkEVMGlobalExitRoot.target, - polTokenContract.target, - polygonZkEVMBridgeContract.target, - rollupManagerContract.target, - ); - await PolygonPPConsensusContract.waitForDeployment(); - - // Try to add a new rollup type - const forkID = 11; // just metadata for pessimistic consensus - const genesis = ethers.ZeroHash; - const description = 'new pessimistic consensus'; - const programVKey = '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'; - const newRollupTypeID = 1; - - // correct add new rollup via timelock - await rollupManagerContract - .connect(timelock) - .addNewRollupType( - PolygonPPConsensusContract.target, - verifierContract.target, - forkID, - VerifierType.Pessimistic, - genesis, - description, - programVKey, - ); - - // create new pessimsitic: only admin - const chainID = 1; - const gasTokenAddress = ethers.ZeroAddress; - const urlSequencer = 'https://pessimistic:8545'; - const networkName = 'testPessimistic'; - - // create new pessimistic - const initializeBytesAggchain = encodeInitializeBytesLegacy( - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName, - ); - - rollupManagerContract.connect(admin).attachAggchainToAL(newRollupTypeID, chainID, initializeBytesAggchain); - - // 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(); - - // Add a new rollup type with timelock - const genesisRandom = '0x0000000000000000000000000000000000000000000000000000000000000001'; - const description2 = 'description'; - const chainID2 = 2; - const stateTransistionRollupID = 2; - - // add new rollup type StateTransistion with programVKey != 0 - await expect( - rollupManagerContract - .connect(timelock) - .addNewRollupType( - PolygonZKEVMV2Contract.target, - verifierContract.target, - forkID, - VerifierType.StateTransition, - genesisRandom, - description2, - programVKey, - ), - ).to.be.revertedWithCustomError(rollupManagerContract, 'InvalidRollupType'); - - // add new rollup type stateTranstion correctly - const newRollupTypeID2 = 2; - - await rollupManagerContract - .connect(timelock) - .addNewRollupType( - PolygonZKEVMV2Contract.target, - verifierContract.target, - forkID, - VerifierType.StateTransition, - genesisRandom, - description2, - ethers.ZeroHash, - ); - - // create new rollup - await rollupManagerContract - .connect(admin) - .attachAggchainToAL(newRollupTypeID2, chainID2, initializeBytesAggchain); - - // get rollup data - const rollupStateTransition = await rollupManagerContract.rollupIDToRollupData(stateTransistionRollupID); - - // try to update rollup from Pessimistic to stateTransition - // await expect( - // rollupManagerContract.connect(timelock).updateRollup(rollupPessimistic[0] as unknown as Address, 2, "0x") - // ).to.be.revertedWithCustomError(rollupManagerContract, "UpdateNotCompatible"); - - // // try to update rollup from StateTransition to Pessimistic - // await expect( - // rollupManagerContract - // .connect(timelock) - // .updateRollup(rollupStateTransition[0] as unknown as Address, 1, "0x") - // ).to.be.revertedWithCustomError(rollupManagerContract, "UpdateNotCompatible"); - - // try to update rollup with rollupType = 0 - await expect( - rollupManagerContract - .connect(timelock) - .updateRollup(rollupStateTransition[0] as unknown as Address, 0, '0x'), - ).to.be.revertedWithCustomError(rollupManagerContract, 'RollupTypeDoesNotExist'); - - // try to update rollup with a greater rollupType that the last created - await expect( - rollupManagerContract - .connect(timelock) - .updateRollup(rollupStateTransition[0] as unknown as Address, 4, '0x'), - ).to.be.revertedWithCustomError(rollupManagerContract, 'RollupTypeDoesNotExist'); - }); - - it('should update rollup: pessismsitic type', async () => { - // deploy consensus - // create polygonPessimisticConsensus implementation - const ppConsensusFactory = await ethers.getContractFactory('PolygonPessimisticConsensus'); - PolygonPPConsensusContract = await ppConsensusFactory.deploy( - polygonZkEVMGlobalExitRoot.target, - polTokenContract.target, - polygonZkEVMBridgeContract.target, - rollupManagerContract.target, - ); - await PolygonPPConsensusContract.waitForDeployment(); - - // Try to add a new rollup type - const forkID = 11; // just metadata for pessimistic consensus - const genesis = ethers.ZeroHash; - const description = 'new pessimistic consensus'; - const programVKey = '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'; - const rollupTypeID = 1; - - // correct add new rollup via timelock - await rollupManagerContract - .connect(timelock) - .addNewRollupType( - PolygonPPConsensusContract.target, - verifierContract.target, - forkID, - VerifierType.Pessimistic, - genesis, - description, - programVKey, - ); - - // create new pessimsitic: only admin - const chainID = 1; - const gasTokenAddress = ethers.ZeroAddress; - const urlSequencer = 'https://pessimistic:8545'; - const networkName = 'testPessimistic'; - const pessimisticRollupID = 1; - - // create new pessimistic - const newZKEVMAddress = ethers.getCreateAddress({ - from: rollupManagerContract.target as string, - nonce: 1, - }); - - const initializeBytesAggchain = encodeInitializeBytesLegacy( - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName, - ); - await rollupManagerContract.connect(admin).attachAggchainToAL(rollupTypeID, chainID, initializeBytesAggchain); - - // Try to add a new rollup type - const newForkID = 11; // just metadata for pessimistic consensus - const newProgramVKey = '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'; - const newRollupTypeID = 2; - const newVerifier = '0xaa000000000000000000000000000000000000bb' as unknown as Address; - - // correct add new rollup via timelock - await rollupManagerContract - .connect(timelock) - .addNewRollupType( - PolygonPPConsensusContract.target, - newVerifier, - newForkID, - VerifierType.Pessimistic, - genesis, - description, - newProgramVKey, - ); - - // get rollup data - const rollupPessimistic = await rollupManagerContract.rollupIDToRollupDataV2(pessimisticRollupID); - - // try to update rollup from StateTransition to Pessimistic - await rollupManagerContract - .connect(timelock) - .updateRollup(rollupPessimistic[0] as unknown as Address, newRollupTypeID, '0x'); - - // assert new rollup - const resRollupData = await rollupManagerContract.rollupIDToRollupDataV2(pessimisticRollupID); - - const expectedRollupData = [ - newZKEVMAddress, - chainID, - newVerifier, - newForkID, - ethers.ZeroHash, - 0, - 0, - 0, - newRollupTypeID, - VerifierType.Pessimistic, - ethers.ZeroHash, - newProgramVKey, - ]; - - expect(expectedRollupData).to.be.deep.equal(resRollupData); - }); - - it('should not allow rollback sequences: pessismsitic type', async () => { - // deploy consensus - // create polygonPessimisticConsensus implementation - const ppConsensusFactory = await ethers.getContractFactory('PolygonPessimisticConsensus'); - PolygonPPConsensusContract = await ppConsensusFactory.deploy( - polygonZkEVMGlobalExitRoot.target, - polTokenContract.target, - polygonZkEVMBridgeContract.target, - rollupManagerContract.target, - ); - await PolygonPPConsensusContract.waitForDeployment(); - - // Try to add a new rollup type - const forkID = 11; // just metadata for pessimistic consensus - const genesis = ethers.ZeroHash; - const description = 'new pessimistic consensus'; - const programVKey = '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'; - const rollupTypeID = 1; - - // correct add new rollup via timelock - await rollupManagerContract - .connect(timelock) - .addNewRollupType( - PolygonPPConsensusContract.target, - verifierContract.target, - forkID, - VerifierType.Pessimistic, - genesis, - description, - programVKey, - ); - - // create new pessimsitic: only admin - const chainID = 1; - const gasTokenAddress = ethers.ZeroAddress; - const urlSequencer = 'https://pessimistic:8545'; - const networkName = 'testPessimistic'; - const pessimisticRollupID = 1; - - // create new pessimistic - const initializeBytesAggchain = encodeInitializeBytesLegacy( - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName, - ); - - await rollupManagerContract.connect(admin).attachAggchainToAL(rollupTypeID, chainID, initializeBytesAggchain); - - // get rollup data - const rollupPessimistic = await rollupManagerContract.rollupIDToRollupDataV2(pessimisticRollupID); - - // try to rollback sequences - await expect( - rollupManagerContract.connect(admin).rollbackBatches(rollupPessimistic[0] as unknown as Address, 2), - ).to.be.revertedWithCustomError(rollupManagerContract, 'OnlyStateTransitionChains'); - }); - - it('should verify pessimistic proof: pessimistic type', async () => { - // deploy consensus - // create polygonPessimisticConsensus implementation - const ppConsensusFactory = await ethers.getContractFactory('PolygonPessimisticConsensus'); - PolygonPPConsensusContract = await ppConsensusFactory.deploy( - polygonZkEVMGlobalExitRoot.target, - polTokenContract.target, - polygonZkEVMBridgeContract.target, - rollupManagerContract.target, - ); - await PolygonPPConsensusContract.waitForDeployment(); - - // Try to add a new rollup type - const forkID = 11; // just metadata for pessimistic consensus - const genesis = ethers.ZeroHash; - const description = 'new pessimistic consensus'; - const programVKey = '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'; - const rollupTypeID = 1; - - // correct add new rollup via timelock - await rollupManagerContract - .connect(timelock) - .addNewRollupType( - PolygonPPConsensusContract.target, - verifierContract.target, - forkID, - VerifierType.Pessimistic, - genesis, - description, - programVKey, - ); - - // create new pessimsitic: only admin - const chainID = 1; - const gasTokenAddress = ethers.ZeroAddress; - const urlSequencer = 'https://pessimistic:8545'; - const networkName = 'testPessimistic'; - const pessimisticRollupID = 1; - - // create new pessimistic - const newZKEVMAddress = ethers.getCreateAddress({ - from: rollupManagerContract.target as string, - nonce: 1, - }); - - const initializeBytesAggchain = encodeInitializeBytesLegacy( - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName, - ); - await rollupManagerContract.connect(admin).attachAggchainToAL(rollupTypeID, chainID, initializeBytesAggchain); - - // select unexistent global exit root - const unexistentL1InfoTreeCount = 2; - const newLER = '0x0000000000000000000000000000000000000000000000000000000000000001'; - const newPPRoot = '0x0000000000000000000000000000000000000000000000000000000000000002'; - const proofPP = '0x00'; - - // not trusted aggregator - await expect( - rollupManagerContract.verifyPessimisticTrustedAggregator( - pessimisticRollupID, - unexistentL1InfoTreeCount, - newLER, - newPPRoot, - proofPP, - '0x', // aggchainData - ), - ).to.be.revertedWithCustomError(rollupManagerContract, 'AddressDoNotHaveRequiredRole'); - - // global exit root does not exist - await expect( - rollupManagerContract.connect(trustedAggregator).verifyPessimisticTrustedAggregator( - pessimisticRollupID, - unexistentL1InfoTreeCount, - newLER, - newPPRoot, - proofPP, - '0x', // aggchainData - ), - ).to.be.revertedWithCustomError(rollupManagerContract, 'L1InfoTreeLeafCountInvalid'); - - // Check AggchainDataMustBeZeroForPessimisticVerifierType - await expect( - rollupManagerContract.connect(trustedAggregator).verifyPessimisticTrustedAggregator( - pessimisticRollupID, - unexistentL1InfoTreeCount, - newLER, - newPPRoot, - proofPP, - computeRandomBytes(32), // customChainData random bytes, invalid - ), - ).to.be.revertedWithCustomError(rollupManagerContract, 'AggchainDataMustBeZeroForPessimisticVerifierType'); - - // create a bridge to generate a new GER and add another value in the l1IfoRootMap - const tokenAddress = ethers.ZeroAddress; - const amount = ethers.parseEther('1'); - await polygonZkEVMBridgeContract.bridgeAsset( - pessimisticRollupID, - polTokenContract.target, - amount, - tokenAddress, - true, - '0x', - { - value: amount, - }, - ); - - // get last L1InfoTreeLeafCount - const lastL1InfoTreeLeafCount = await polygonZkEVMGlobalExitRoot.depositCount(); - const lastL1InfoTreeRoot = await polygonZkEVMGlobalExitRoot.l1InfoRootMap(0); - - // check JS function computeInputPessimisticBytes - const inputPessimisticBytes = await rollupManagerContract.getInputPessimisticBytes( - pessimisticRollupID, - lastL1InfoTreeRoot, - newLER, - newPPRoot, - '0x', // aggchainData - ); - - const infoRollup = await rollupManagerContract.rollupIDToRollupDataV2(pessimisticRollupID); - - const consensusHash = computeConsensusHashEcdsa(trustedSequencer.address); - - const expectedInputPessimsiticBytes = computeInputPessimisticBytes( - infoRollup[4], - infoRollup[10], - lastL1InfoTreeRoot, - pessimisticRollupID, - consensusHash, - newLER, - newPPRoot, - ); - - expect(inputPessimisticBytes).to.be.equal(expectedInputPessimsiticBytes); - - // verify pessimistic - await expect( - rollupManagerContract.connect(trustedAggregator).verifyPessimisticTrustedAggregator( - pessimisticRollupID, - lastL1InfoTreeLeafCount, - newLER, - newPPRoot, - proofPP, - '0x', // aggchainData - ), - ) - .to.emit(rollupManagerContract, 'VerifyBatchesTrustedAggregator') - .withArgs(pessimisticRollupID, 0, ethers.ZeroHash, newLER, trustedAggregator.address); - - // assert rollup data - const resRollupData = await rollupManagerContract.rollupIDToRollupDataV2(pessimisticRollupID); - - const expectedRollupData = [ - newZKEVMAddress, - chainID, - verifierContract.target, - forkID, - newLER, - 0, - 0, - 0, - rollupTypeID, - VerifierType.Pessimistic, - newPPRoot, - programVKey, - ]; - - expect(expectedRollupData).to.be.deep.equal(resRollupData); - - // not allow verifyBatchesTrustedAggregator from a Pessimistic chain - await expect( - rollupManagerContract - .connect(trustedAggregator) - .verifyBatchesTrustedAggregator( - pessimisticRollupID, - 0, - 0, - 0, - newLER, - newPPRoot, - beneficiary.address, - new Array(24).fill(ethers.ZeroHash), - ), - ).to.be.revertedWithCustomError(rollupManagerContract, 'OnlyStateTransitionChains'); - - // pendingstate != 0 - await expect( - rollupManagerContract - .connect(trustedAggregator) - .verifyBatchesTrustedAggregator( - pessimisticRollupID, - 42, - 0, - 0, - newLER, - newPPRoot, - beneficiary.address, - new Array(24).fill(ethers.ZeroHash), - ), - ).to.be.revertedWithCustomError(rollupManagerContract, 'PendingStateNumExist'); - }); - - it('should not verify pessimistic proof from stateTransistion chain', async () => { - // 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(); - - // Add a new rollup type with timelock - const gasTokenAddress = ethers.ZeroAddress; - const urlSequencer = 'https://pessimistic:8545'; - const networkName = 'testPessimistic'; - const genesisRandom = '0x0000000000000000000000000000000000000000000000000000000000000001'; - const description = 'description'; - const forkID = 1; - const chainID = 1; - const stateTransistionRollupID = 1; - - // add new rollup type stateTranstion correctly - const newRollupTypeID = 1; - - await rollupManagerContract - .connect(timelock) - .addNewRollupType( - PolygonZKEVMV2Contract.target, - verifierContract.target, - forkID, - VerifierType.StateTransition, - genesisRandom, - description, - ethers.ZeroHash, - ); - - // create new rollup - const initializeBytesAggchain = encodeInitializeBytesLegacy( - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName, - ); - await rollupManagerContract - .connect(admin) - .attachAggchainToAL(newRollupTypeID, chainID, initializeBytesAggchain); - - // try to verify - const unexistentL1InfoTreeLeafcount = 2; - const newLER = '0x0000000000000000000000000000000000000000000000000000000000000001'; - const newPPRoot = '0x0000000000000000000000000000000000000000000000000000000000000002'; - const proofPP = '0x00'; - - await expect( - rollupManagerContract.connect(trustedAggregator).verifyPessimisticTrustedAggregator( - stateTransistionRollupID, - unexistentL1InfoTreeLeafcount, - newLER, - newPPRoot, - proofPP, - '0x', // aggchainData - ), - ).to.be.revertedWithCustomError(rollupManagerContract, 'StateTransitionChainsNotAllowed'); - }); -}); diff --git a/test/contractsv2/PolygonRollupManager.test.ts b/test/contractsv2/PolygonRollupManager.test.ts index 17d6797a0..7ef840385 100644 --- a/test/contractsv2/PolygonRollupManager.test.ts +++ b/test/contractsv2/PolygonRollupManager.test.ts @@ -2459,48 +2459,6 @@ describe('Polygon Rollup Manager', () => { programVKey, ); - // Add a new rollup type (pessimistic) with timelock - const newRandomTypeID = 3; - const rollupVerifierTypeNew = 1; - await expect( - rollupManagerContract - .connect(timelock) - .addNewRollupType( - PolygonZKEVMEtrogContract.target, - verifierContract.target, - forkID, - rollupVerifierTypeNew, - programVKey, - description, - genesisRandom, - ), - ) - .to.emit(rollupManagerContract, 'AddNewRollupType') - .withArgs( - newRandomTypeID, - PolygonZKEVMEtrogContract.target, - verifierContract.target, - forkID, - rollupVerifierTypeNew, - programVKey, - description, - genesisRandom, - ); - - // assert new rollup type - const createdEtrogRollupType = await rollupManagerContract.rollupTypeMap(newRandomTypeID); - - const expectedEtrogRollupType = [ - PolygonZKEVMEtrogContract.target, - verifierContract.target, - forkID, - rollupVerifierTypeNew, - false, - programVKey, - genesisRandom, - ]; - expect(createdEtrogRollupType).to.be.deep.equal(expectedEtrogRollupType); - // Validate upgrade OZ const PolygonPreviousFactory = await ethers.getContractFactory('PolygonZkEVMEtrogPrevious'); diff --git a/test/contractsv2/PolygonRollupManagerAL-ECDSAMultisig.test.ts b/test/contractsv2/PolygonRollupManagerAL-ECDSAMultisig.test.ts index 8b3c25f4d..a01017180 100644 --- a/test/contractsv2/PolygonRollupManagerAL-ECDSAMultisig.test.ts +++ b/test/contractsv2/PolygonRollupManagerAL-ECDSAMultisig.test.ts @@ -11,14 +11,12 @@ import { AgglayerBridge, AggchainECDSAMultisig, VerifierRollupHelperMock, - PolygonPessimisticConsensus, } from '../../typechain-types'; import { VerifierType, computeRandomBytes } from '../../src/pessimistic-utils'; import { CONSENSUS_TYPE, encodeInitAggchainManager, - encodeInitializeBytesLegacy, computeAggchainHash, computeSignersHash, } from '../../src/utils-common-aggchain'; @@ -48,7 +46,6 @@ describe('Polygon rollup manager aggregation layer v3: ECDSA Multisig', () => { let aggLayerGatewayContract: AgglayerGateway; let aggchainECDSAMultisigImplementationContract: AggchainECDSAMultisig; let verifierContract: VerifierRollupHelperMock; - let PolygonPPConsensusContract: PolygonPessimisticConsensus; /// CONSTANTS const POL_TOKEN_NAME = 'POL Token'; const POL_TOKEN_SYMBOL = 'POL'; @@ -65,35 +62,6 @@ describe('Polygon rollup manager aggregation layer v3: ECDSA Multisig', () => { upgrades.silenceWarnings(); - async function createPessimisticRollupType() { - // Create rollup type for pessimistic - const lastRollupTypeID = await rollupManagerContract.rollupTypeCount(); - await expect( - rollupManagerContract.connect(timelock).addNewRollupType( - PolygonPPConsensusContract.target, - verifierContract.target, - 0, // fork id - VerifierType.Pessimistic, - ethers.ZeroHash, // genesis - '', // description - ethers.ZeroHash, // programVKey - ), - ) - .to.emit(rollupManagerContract, 'AddNewRollupType') - .withArgs( - Number(lastRollupTypeID) + 1 /* rollupTypeID */, - PolygonPPConsensusContract.target, - verifierContract.target, - 0, // fork id - VerifierType.Pessimistic, - ethers.ZeroHash, // genesis - '', // description - ethers.ZeroHash, // programVKey - ); - - return Number(lastRollupTypeID) + 1; - } - async function createECDSAMultisigRollupType() { // Create rollup type for ECDSA const lastRollupTypeID = await rollupManagerContract.rollupTypeCount(); @@ -310,15 +278,6 @@ describe('Polygon rollup manager aggregation layer v3: ECDSA Multisig', () => { rollupManagerContract.target, aggLayerGatewayContract.target, ); - - // Deploy pessimistic consensus contract - const ppConsensusFactory = await ethers.getContractFactory('PolygonPessimisticConsensus'); - PolygonPPConsensusContract = await ppConsensusFactory.deploy( - polygonZkEVMGlobalExitRoot.target, - polTokenContract.target, - polygonZkEVMBridgeContract.target, - rollupManagerContract.target, - ); }); it('should check initializers and deploy parameters', async () => { @@ -603,191 +562,6 @@ describe('Polygon rollup manager aggregation layer v3: ECDSA Multisig', () => { .to.emit(ECDSAMultisigRollupContract, 'OnVerifyPessimisticECDSAMultisig'); }); - it('should create a rollup with pessimistic consensus and upgrade it to aggchainECDSA', async () => { - // Deploy pessimistic consensus contract - const ppConsensusFactory = await ethers.getContractFactory('PolygonPessimisticConsensus'); - - // Create new rollup type with pessimistic consensus - const pessimisticRollupTypeID = await createPessimisticRollupType(); - - // Create new rollup with pessimistic consensus - const precomputedRollupAddress = ethers.getCreateAddress({ - from: rollupManagerContract.target as string, - nonce: await ethers.provider.getTransactionCount(rollupManagerContract.target), - }); - const pessimisticRollupContract = ppConsensusFactory.attach( - precomputedRollupAddress, - ) as PolygonPessimisticConsensus; - const chainID = 5; - const gasTokenAddress = ethers.ZeroAddress; - const urlSequencer = 'https://pessimistic:8545'; - const networkName = 'testPessimistic'; - const pessimisticRollupID = 1; // Already aggchainECDSA rollup created created - const initializeBytesPessimistic = encodeInitializeBytesLegacy( - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName, - ); - await expect( - rollupManagerContract - .connect(admin) - .attachAggchainToAL(pessimisticRollupTypeID, chainID, initializeBytesPessimistic), - ) - .to.emit(rollupManagerContract, 'CreateNewRollup') - .withArgs(pessimisticRollupID, pessimisticRollupTypeID, precomputedRollupAddress, chainID, gasTokenAddress); - - // Verify pessimist proof with pessimistic rollup - // create a bridge to generate a new GER and add another value in the l1IfoRootMap - const tokenAddress = ethers.ZeroAddress; - const amount = ethers.parseEther('1'); - await polygonZkEVMBridgeContract.bridgeAsset( - pessimisticRollupID, - polTokenContract.target, - amount, - tokenAddress, - true, - '0x', - { - value: amount, - }, - ); - // get last L1InfoTreeLeafCount - const lastL1InfoTreeLeafCount = await polygonZkEVMGlobalExitRoot.depositCount(); - - // check JS function computeInputPessimisticBytes - const newLER = '0x0000000000000000000000000000000000000000000000000000000000000001'; - const newPPRoot = '0x0000000000000000000000000000000000000000000000000000000000000002'; - const proofPP = '0x00'; - - // verify pessimistic from the created pessimistic rollup - await expect( - rollupManagerContract.connect(trustedAggregator).verifyPessimisticTrustedAggregator( - pessimisticRollupID, - lastL1InfoTreeLeafCount, - newLER, - newPPRoot, - proofPP, - '0x', // aggchainData - ), - ) - .to.emit(rollupManagerContract, 'VerifyBatchesTrustedAggregator') - .withArgs( - pessimisticRollupID, - 0, // numBatch - ethers.ZeroHash, // stateRoot - newLER, - trustedAggregator.address, - ); - - // Create rollup type ECDSA - const rollupTypeECDSAId = await createECDSAMultisigRollupType(); - // Update the rollup to ECDSA and initialize the new rollup type - // Compute initialize upgrade data - const aggchainECDSAMultisigFactory = await ethers.getContractFactory('AggchainECDSAMultisig'); - - // For migration from PessimisticConsensus, the migrateFromLegacyConsensus function - // will be called automatically by the RollupManager - // No initialization bytes needed for migration - - const upgradeData = aggchainECDSAMultisigFactory.interface.encodeFunctionData('initAggchainManager(address)', [ - aggchainManager.address, - ]); - - await expect( - rollupManagerContract - .connect(timelock) - .updateRollup(pessimisticRollupContract.target, rollupTypeECDSAId, upgradeData), - ) - .to.emit(rollupManagerContract, 'UpdateRollup') - .withArgs(pessimisticRollupID, rollupTypeECDSAId, 0 /* lastVerifiedBatch */); - const ECDSAMultisigRollupContract = aggchainECDSAMultisigFactory.attach(pessimisticRollupContract.target); - - const aggchainManagerSC = await ECDSAMultisigRollupContract.aggchainManager(); - expect(aggchainManagerSC).to.be.equal(aggchainManager.address); - - // migrate from PessimisticConsensus - // Impersonate rollup manager to call migrateFromLegacyConsensus - await ethers.provider.send('hardhat_impersonateAccount', [rollupManagerContract.target]); - const rollupManagerSigner = await ethers.getSigner(rollupManagerContract.target as any); - await ECDSAMultisigRollupContract.connect(rollupManagerSigner).migrateFromLegacyConsensus({ gasPrice: 0 }); - // assert that the rollup is migrated, check the signershash is coorect, threshold 1 and trusted sequencer - expect(await ECDSAMultisigRollupContract.aggchainMultisigHash()).to.be.equal( - computeSignersHash(1, [trustedSequencer.address]), - ); - // Try update rollup by rollupAdmin but trigger UpdateToOldRollupTypeID - // Create a new pessimistic rollup type - await createPessimisticRollupType(); - - // Check rollup data deserialized - const resRollupData = await rollupManagerContract.rollupIDToRollupDataDeserialized(pessimisticRollupID); - const expectedRollupData = [ - ECDSAMultisigRollupContract.target, - chainID, - ethers.ZeroAddress, // newVerifier address, for ECDSA is zero because it is internally replaced by aggLayerGateway address - 0, // newForkID - newLER, // lastLocalExitRoot - 0, // lastBatchSequenced - 0, // lastBatchVerified - 0, // _legacyLastPendingState - 0, // _legacyLastPendingStateConsolidated - 0, // lastVerifiedBatchBeforeUpgrade - rollupTypeECDSAId, - VerifierType.ALGateway, - ]; - - expect(expectedRollupData).to.be.deep.equal(resRollupData); - - // Check rollup data deserialized V2 - const resRollupDataV2 = await rollupManagerContract.rollupIDToRollupDataV2Deserialized(pessimisticRollupID); - const expectedRollupDataV2 = [ - ECDSAMultisigRollupContract.target, - chainID, - ethers.ZeroAddress, // newVerifier address, for ECDSA is zero because it is internally replaced by aggLayerGateway address - 0, // newForkID - newLER, // lastLocalExitRoot - 0, // lastBatchSequenced - 0, // lastBatchVerified - 0, // lastVerifiedBatchBeforeUpgrade - rollupTypeECDSAId, - VerifierType.ALGateway, - newPPRoot, // lastPessimisticRoot - ethers.ZeroHash, // newProgramVKey - ]; - - expect(expectedRollupDataV2).to.be.deep.equal(resRollupDataV2); - - // Verify pessimist proof with the new ECDSA rollup - const randomNewLocalExitRoot = computeRandomBytes(32); - const randomNewPessimisticRoot = computeRandomBytes(32); - const randomProof = computeRandomBytes(128); - // append first 4 bytes to the proof to select the pessimistic vkey - const proofWithSelector = `${PESSIMISTIC_SELECTOR}${randomProof.slice(2)}`; - - // Add default AggchainVKey (needed for verification) - const aggchainVKey = computeRandomBytes(32); - await expect( - aggLayerGatewayContract.connect(aggLayerAdmin).addDefaultAggchainVKey(AGGCHAIN_VKEY_SELECTOR, aggchainVKey), - ) - .to.emit(aggLayerGatewayContract, 'AddDefaultAggchainVKey') - .withArgs(AGGCHAIN_VKEY_SELECTOR, aggchainVKey); - - // verify pessimist proof with the new ECDSA Multisig rollup - await expect( - rollupManagerContract.connect(trustedAggregator).verifyPessimisticTrustedAggregator( - pessimisticRollupID, // rollupID - lastL1InfoTreeLeafCount, // l1InfoTreeCount - randomNewLocalExitRoot, - randomNewPessimisticRoot, - proofWithSelector, - CUSTOM_DATA_ECDSA, - ), - ) - .to.emit(rollupManagerContract, 'VerifyBatchesTrustedAggregator') - .to.emit(ECDSAMultisigRollupContract, 'OnVerifyPessimisticECDSAMultisig'); - }); - it('should add existing rollup to ECDSA', async () => { // add existing rollup const rollupAddress = '0xAa000000000000000000000000000000000000Bb'; @@ -874,59 +648,4 @@ describe('Polygon rollup manager aggregation layer v3: ECDSA Multisig', () => { initPessimisticRoot, ); }); - - it('should throw reverts UpdateToOldRollupTypeID and UpdateNotCompatible', async () => { - // create two pessimistic rollup types - const pessimisticRollupTypeID1 = await createPessimisticRollupType(); - const pessimisticRollupTypeID2 = await createPessimisticRollupType(); - - const rollupManagerNonce = await ethers.provider.getTransactionCount(rollupManagerContract.target); - const pessimisticRollupAddress = ethers.getCreateAddress({ - from: rollupManagerContract.target as string, - nonce: rollupManagerNonce, - }); - // Create pessimistic rollup - const initializeBytesAggchain = encodeInitializeBytesLegacy( - admin.address, - trustedSequencer.address, - ethers.ZeroAddress, - '', - '', - ); - await rollupManagerContract.connect(admin).attachAggchainToAL( - pessimisticRollupTypeID2, - 2, // chainID - initializeBytesAggchain, - ); - expect(await rollupManagerContract.rollupAddressToID(pessimisticRollupAddress)).to.be.equal(1); - - // Try to upgrade from rollupType1 to rollupType2 should revert (lowest rollup typed id) - await expect( - rollupManagerContract - .connect(admin) - .updateRollupByRollupAdmin(pessimisticRollupAddress, pessimisticRollupTypeID1), - ).to.be.revertedWithCustomError(rollupManagerContract, 'UpdateToOldRollupTypeID'); - - // Try to upgrade to a rollup type with different verifier type, should revert - const ecdsaRollupType = await createECDSAMultisigRollupType(); - await expect( - rollupManagerContract.connect(admin).updateRollupByRollupAdmin(pessimisticRollupAddress, ecdsaRollupType), - ).to.be.revertedWithCustomError(rollupManagerContract, 'UpdateNotCompatible'); - - // Try to upgrade to a pessimistic from an ecdsa rollup type, should revert - const [, ecdsaRollupAddress] = await createECDSAMultisigRollup(ecdsaRollupType); - await expect( - rollupManagerContract - .connect(timelock) - .updateRollup(ecdsaRollupAddress as string, pessimisticRollupTypeID1, '0x'), - ).to.be.revertedWithCustomError(rollupManagerContract, 'UpdateNotCompatible'); - - // Trigger OnlyStateTransitionChains from onSequenceBatches - await ethers.provider.send('hardhat_setBalance', [pessimisticRollupAddress, '0x100000000000000']); - await ethers.provider.send('hardhat_impersonateAccount', [pessimisticRollupAddress]); - const pessimisticRollupContract = await ethers.getSigner(pessimisticRollupAddress); - await expect( - rollupManagerContract.connect(pessimisticRollupContract).onSequenceBatches(3, computeRandomBytes(32)), - ).to.be.revertedWithCustomError(rollupManagerContract, 'OnlyStateTransitionChains'); - }); }); diff --git a/test/contractsv2/PolygonRollupManagerAL-FEP.test.ts b/test/contractsv2/PolygonRollupManagerAL-FEP.test.ts index 7759fa13f..dd23b45d7 100644 --- a/test/contractsv2/PolygonRollupManagerAL-FEP.test.ts +++ b/test/contractsv2/PolygonRollupManagerAL-FEP.test.ts @@ -10,7 +10,6 @@ import { AgglayerBridge, AggchainFEP, VerifierRollupHelperMock, - PolygonPessimisticConsensus, } from '../../typechain-types'; import { VerifierType, computeRandomBytes } from '../../src/pessimistic-utils'; @@ -18,7 +17,6 @@ import { VerifierType, computeRandomBytes } from '../../src/pessimistic-utils'; import { CONSENSUS_TYPE, encodeInitAggchainManager, - encodeInitializeBytesLegacy, computeAggchainHash, computeSignersHash, } from '../../src/utils-common-aggchain'; @@ -48,7 +46,6 @@ describe('Polygon rollup manager aggregation layer v3: FEP', () => { let aggLayerGatewayContract: AgglayerGateway; let aggchainFEPImplementationContract: AggchainFEP; let verifierContract: VerifierRollupHelperMock; - let PolygonPPConsensusContract: PolygonPessimisticConsensus; /// CONSTANTS const POL_TOKEN_NAME = 'POL Token'; const POL_TOKEN_SYMBOL = 'POL'; @@ -118,35 +115,6 @@ describe('Polygon rollup manager aggregation layer v3: FEP', () => { return [Number(rollupsCount) + 1, precomputedAggchainFEPAddress]; } - - async function createPessimisticRollupType() { - // Create rollup type for pessimistic - const lastRollupTypeID = await rollupManagerContract.rollupTypeCount(); - await expect( - rollupManagerContract.connect(timelock).addNewRollupType( - PolygonPPConsensusContract.target, - verifierContract.target, - 0, // fork id - VerifierType.Pessimistic, - ethers.ZeroHash, // genesis - '', // description - ethers.ZeroHash, // programVKey - ), - ) - .to.emit(rollupManagerContract, 'AddNewRollupType') - .withArgs( - Number(lastRollupTypeID) + 1 /* rollupTypeID */, - PolygonPPConsensusContract.target, - verifierContract.target, - 0, // fork id - VerifierType.Pessimistic, - ethers.ZeroHash, // genesis - '', // description - ethers.ZeroHash, // programVKey - ); - - return Number(lastRollupTypeID) + 1; - } async function createFEPRollupType() { // Create rollup type for FEP const lastRollupTypeID = await rollupManagerContract.rollupTypeCount(); @@ -319,15 +287,6 @@ describe('Polygon rollup manager aggregation layer v3: FEP', () => { rollupManagerContract.target, aggLayerGatewayContract.target, ); - - // Deploy pessimistic consensus contract - const ppConsensusFactory = await ethers.getContractFactory('PolygonPessimisticConsensus'); - PolygonPPConsensusContract = await ppConsensusFactory.deploy( - polygonZkEVMGlobalExitRoot.target, - polTokenContract.target, - polygonZkEVMBridgeContract.target, - rollupManagerContract.target, - ); }); it('should check initializers and deploy parameters', async () => { @@ -633,234 +592,6 @@ describe('Polygon rollup manager aggregation layer v3: FEP', () => { .withArgs(newStateRoot, 1, newl2BlockNumber, blockDataTimestamp); }); - it('should create a rollup with pessimistic consensus and upgrade it to aggchainFEP', async () => { - // Deploy pessimistic consensus contract - const ppConsensusFactory = await ethers.getContractFactory('PolygonPessimisticConsensus'); - - // Create new rollup type with pessimistic consensus - const pessimisticRollupTypeID = await createPessimisticRollupType(); - - // Create new rollup with pessimistic consensus - const precomputedRollupAddress = ethers.getCreateAddress({ - from: rollupManagerContract.target as string, - nonce: await ethers.provider.getTransactionCount(rollupManagerContract.target), - }); - const pessimisticRollupContract = ppConsensusFactory.attach( - precomputedRollupAddress, - ) as PolygonPessimisticConsensus; - const chainID = 5; - const gasTokenAddress = ethers.ZeroAddress; - const urlSequencer = 'https://pessimistic:8545'; - const networkName = 'testPessimistic'; - const pessimisticRollupID = 1; // Already aggchainFEP rollup created created - const initializeBytesPessimistic = encodeInitializeBytesLegacy( - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName, - ); - await expect( - rollupManagerContract - .connect(admin) - .attachAggchainToAL(pessimisticRollupTypeID, chainID, initializeBytesPessimistic), - ) - .to.emit(rollupManagerContract, 'CreateNewRollup') - .withArgs(pessimisticRollupID, pessimisticRollupTypeID, precomputedRollupAddress, chainID, gasTokenAddress); - - // Verify pessimist proof with pessimistic rollup - // create a bridge to generate a new GER and add another value in the l1IfoRootMap - const tokenAddress = ethers.ZeroAddress; - const amount = ethers.parseEther('1'); - await polygonZkEVMBridgeContract.bridgeAsset( - pessimisticRollupID, - polTokenContract.target, - amount, - tokenAddress, - true, - '0x', - { - value: amount, - }, - ); - // get last L1InfoTreeLeafCount - const lastL1InfoTreeLeafCount = await polygonZkEVMGlobalExitRoot.depositCount(); - - // check JS function computeInputPessimisticBytes - const newLER = '0x0000000000000000000000000000000000000000000000000000000000000001'; - const newPPRoot = '0x0000000000000000000000000000000000000000000000000000000000000002'; - const proofPP = '0x00'; - - // verify pessimistic from the created pessimistic rollup - await expect( - rollupManagerContract.connect(trustedAggregator).verifyPessimisticTrustedAggregator( - pessimisticRollupID, - lastL1InfoTreeLeafCount, - newLER, - newPPRoot, - proofPP, - '0x', // aggchainData - ), - ) - .to.emit(rollupManagerContract, 'VerifyBatchesTrustedAggregator') - .withArgs( - pessimisticRollupID, - 0, // numBatch - ethers.ZeroHash, // stateRoot - newLER, - trustedAggregator.address, - ); - - // Create rollup type FEP - const rollupTypeFEPId = await createFEPRollupType(); - // Update the rollup to FEP and initialize the new rollup type - // Compute initialize upgrade data - const aggchainFEPFactory = await ethers.getContractFactory('AggchainFEP'); - - // Define the struct values - // eslint-disable-next-line @typescript-eslint/no-shadow - const initParams = { - l2BlockTime: 10, - rollupConfigHash: ethers.id('rollupConfigHash'), - startingOutputRoot: ethers.id('startingOutputRoot'), - startingBlockNumber: 100, - startingTimestamp: 0, - submissionInterval: 5, - optimisticModeManager: optModeManager.address, - aggregationVkey: ethers.id('aggregationVkey'), - rangeVkeyCommitment: ethers.id('rangeVkeyCommitment'), - }; - - // Initialize parameters will be passed directly to the contract - // Note: Wrong aggchain type will be tested with '0x00010002' selector - - const upgradeData = aggchainFEPFactory.interface.encodeFunctionData('initAggchainManager(address)', [ - aggchainManager.address, - ]); - - await expect( - rollupManagerContract - .connect(timelock) - .updateRollup(pessimisticRollupContract.target, rollupTypeFEPId, upgradeData), - ) - .to.emit(rollupManagerContract, 'UpdateRollup') - .withArgs(pessimisticRollupID, rollupTypeFEPId, 0 /* lastVerifiedBatch */); - const FEPRollupContract = aggchainFEPFactory.attach(pessimisticRollupContract.target); - - const aggchainManagerSC = await FEPRollupContract.aggchainManager(); - expect(aggchainManagerSC).to.be.equal(aggchainManager.address); - - // initialize the FEP aggchain - test wrong aggchain type - await expect( - FEPRollupContract.connect(aggchainManager).initializeFromLegacyConsensus( - initParams, - false, // useDefaultVkeys (set to false to test aggchain type validation) - false, // useDefaultSigners - ethers.ZeroHash, // ownedAggchainVKey - '0x00010002', // aggchainVkeySelector (wrong type - should be 0x0001 for FEP) - [], // No signers to add initially - 0, // Threshold of 0 initially - ), - ).to.be.revertedWithCustomError(FEPRollupContract, 'InvalidAggchainType'); - - await FEPRollupContract.connect(aggchainManager).initializeFromLegacyConsensus( - initParams, - false, // useDefaultVkeys (set to false to avoid needing gateway vkey) - false, // useDefaultSigners - ethers.id('ownedAggchainVKey'), // ownedAggchainVKey - '0x00010001', // aggchainVkeySelector (valid FEP selector) - [], // No signers to add initially - 0, // Threshold of 0 initially - ); - - // Try update rollup by rollupAdmin but trigger UpdateToOldRollupTypeID - // Create a new pessimistic rollup type - await createPessimisticRollupType(); - - // Check rollup data deserialized - const resRollupData = await rollupManagerContract.rollupIDToRollupDataDeserialized(pessimisticRollupID); - const expectedRollupData = [ - FEPRollupContract.target, - chainID, - ethers.ZeroAddress, // newVerifier address, for FEP is zero because it is internally replaced by aggLayerGateway address - 0, // newForkID - newLER, // lastLocalExitRoot - 0, // lastBatchSequenced - 0, // lastBatchVerified - 0, // _legacyLastPendingState - 0, // _legacyLastPendingStateConsolidated - 0, // lastVerifiedBatchBeforeUpgrade - rollupTypeFEPId, - VerifierType.ALGateway, - ]; - - expect(expectedRollupData).to.be.deep.equal(resRollupData); - - // Check rollup data deserialized V2 - const resRollupDataV2 = await rollupManagerContract.rollupIDToRollupDataV2Deserialized(pessimisticRollupID); - const expectedRollupDataV2 = [ - FEPRollupContract.target, - chainID, - ethers.ZeroAddress, // newVerifier address, for FEP is zero because it is internally replaced by aggLayerGateway address - 0, // newForkID - newLER, // lastLocalExitRoot - 0, // lastBatchSequenced - 0, // lastBatchVerified - 0, // lastVerifiedBatchBeforeUpgrade - rollupTypeFEPId, - VerifierType.ALGateway, - newPPRoot, // lastPessimisticRoot - ethers.ZeroHash, // newProgramVKey - ]; - - expect(expectedRollupDataV2).to.be.deep.equal(resRollupDataV2); - - // Verify pessimist proof with the new FEP rollup - const randomNewLocalExitRoot = computeRandomBytes(32); - const randomNewPessimisticRoot = computeRandomBytes(32); - const randomProof = computeRandomBytes(128); - // append first 4 bytes to the proof to select the pessimistic vkey - const proofWithSelector = `${PESSIMISTIC_SELECTOR}${randomProof.slice(2)}`; - // Should revert due to aggchain vkey not found (0x12340001 doesn't match the initialized 0x00010001) - await expect( - rollupManagerContract.connect(trustedAggregator).verifyPessimisticTrustedAggregator( - pessimisticRollupID, // rollupID - lastL1InfoTreeLeafCount, // l1InfoTreeCount - randomNewLocalExitRoot, - randomNewPessimisticRoot, - proofWithSelector, - CUSTOM_DATA_FEP, - ), - ).to.be.revertedWithCustomError(FEPRollupContract, 'AggchainVKeyNotFound'); - - // Initialize signers hash with empty signers to move past the signers hash check - await FEPRollupContract.connect(aggchainManager).updateSignersAndThreshold([], [], 0); - - // Create CUSTOM_DATA_FEP with the correct selector that was used during initialization - const correctSelector = '0x00010001'; // This matches what was used in initializeFromLegacyConsensus - const CUSTOM_DATA_FEP_CORRECT = encodeAggchainDataFEP(correctSelector, newStateRoot, newl2BlockNumber); - - // verify pessimist proof with the new FEP rollup - const onVerifyPessimisticTx = await rollupManagerContract - .connect(trustedAggregator) - .verifyPessimisticTrustedAggregator( - pessimisticRollupID, // rollupID - lastL1InfoTreeLeafCount, // l1InfoTreeCount - randomNewLocalExitRoot, - randomNewPessimisticRoot, - proofWithSelector, - CUSTOM_DATA_FEP_CORRECT, - ); - - const lastBlock = await ethers.provider.getBlock('latest'); - const blockDataTimestamp = lastBlock?.timestamp; - - await expect(onVerifyPessimisticTx) - .to.emit(rollupManagerContract, 'VerifyBatchesTrustedAggregator') - .to.emit(FEPRollupContract, 'OutputProposed') - .withArgs(newStateRoot, 1, newl2BlockNumber, blockDataTimestamp); - }); - it('should add existing rollup to FEP', async () => { // add existing rollup const rollupAddress = '0xAa000000000000000000000000000000000000Bb'; @@ -935,59 +666,4 @@ describe('Polygon rollup manager aggregation layer v3: FEP', () => { initPessimisticRoot, ); }); - - it('should throw reverts UpdateToOldRollupTypeID and UpdateNotCompatible', async () => { - // create two pessimistic rollup types - const pessimisticRollupTypeID1 = await createPessimisticRollupType(); - const pessimisticRollupTypeID2 = await createPessimisticRollupType(); - - const rollupManagerNonce = await ethers.provider.getTransactionCount(rollupManagerContract.target); - const pessimisticRollupAddress = ethers.getCreateAddress({ - from: rollupManagerContract.target as string, - nonce: rollupManagerNonce, - }); - // Create pessimistic rollup - const initializeBytesAggchain = encodeInitializeBytesLegacy( - admin.address, - trustedSequencer.address, - ethers.ZeroAddress, - '', - '', - ); - await rollupManagerContract.connect(admin).attachAggchainToAL( - pessimisticRollupTypeID2, - 2, // chainID - initializeBytesAggchain, - ); - expect(await rollupManagerContract.rollupAddressToID(pessimisticRollupAddress)).to.be.equal(1); - - // Try to upgrade from rollupType1 to rollupType2 should revert (lowest rollup typed id) - await expect( - rollupManagerContract - .connect(admin) - .updateRollupByRollupAdmin(pessimisticRollupAddress, pessimisticRollupTypeID1), - ).to.be.revertedWithCustomError(rollupManagerContract, 'UpdateToOldRollupTypeID'); - - // Try to upgrade to a rollup type with different verifier type, should revert - const rollupTypeFEP = await createFEPRollupType(); - await expect( - rollupManagerContract.connect(admin).updateRollupByRollupAdmin(pessimisticRollupAddress, rollupTypeFEP), - ).to.be.revertedWithCustomError(rollupManagerContract, 'UpdateNotCompatible'); - - // Try to upgrade to a pessimistic from an fep rollup type, should revert - const [, rollupFEPAddress] = await createFEPRollup(rollupTypeFEP); - await expect( - rollupManagerContract - .connect(timelock) - .updateRollup(rollupFEPAddress as string, pessimisticRollupTypeID1, '0x'), - ).to.be.revertedWithCustomError(rollupManagerContract, 'UpdateNotCompatible'); - - // Trigger OnlyStateTransitionChains from onSequenceBatches - await ethers.provider.send('hardhat_setBalance', [pessimisticRollupAddress, '0x100000000000000']); - await ethers.provider.send('hardhat_impersonateAccount', [pessimisticRollupAddress]); - const pessimisticRollupContract = await ethers.getSigner(pessimisticRollupAddress); - await expect( - rollupManagerContract.connect(pessimisticRollupContract).onSequenceBatches(3, computeRandomBytes(32)), - ).to.be.revertedWithCustomError(rollupManagerContract, 'OnlyStateTransitionChains'); - }); }); diff --git a/test/contractsv2/PolygonRollupManagerALUpgrade.test.ts b/test/contractsv2/PolygonRollupManagerALUpgrade.test.ts index 74c1b0f05..703dd5a4e 100644 --- a/test/contractsv2/PolygonRollupManagerALUpgrade.test.ts +++ b/test/contractsv2/PolygonRollupManagerALUpgrade.test.ts @@ -12,13 +12,11 @@ import { AggchainECDSAMultisig, AggchainFEP, VerifierRollupHelperMock, - PolygonPessimisticConsensus, } from '../../typechain-types'; import { CONSENSUS_TYPE, encodeInitAggchainManager, - encodeInitializeBytesLegacy, computeAggchainHash, computeSignersHash, } from '../../src/utils-common-aggchain'; @@ -50,7 +48,6 @@ describe('Polygon rollup manager aggregation layer v3 UPGRADED', () => { let aggLayerGatewayContract: AgglayerGateway; let aggchainECDSAImplementationContract: AggchainECDSAMultisig; let verifierContract: VerifierRollupHelperMock; - let PolygonPPConsensusImplementationContract: PolygonPessimisticConsensus; let aggchainFEPImplementationContract: AggchainFEP; let aggchainFEPPreviousImplementationContract: AggchainECDSAMultisig; @@ -69,33 +66,6 @@ describe('Polygon rollup manager aggregation layer v3 UPGRADED', () => { const CUSTOM_DATA_ECDSA = '0x'; // ECDSA Multisig expects empty aggchainData upgrades.silenceWarnings(); - async function createPessimisticRollupType() { - // Create rollup type for pessimistic - const lastRollupTypeID = await rollupManagerContract.rollupTypeCount(); - await expect( - rollupManagerContract.connect(timelock).addNewRollupType( - PolygonPPConsensusImplementationContract.target, - verifierContract.target, - 0, // fork id - VerifierType.Pessimistic, - ethers.ZeroHash, // genesis - '', // description - ethers.ZeroHash, // programVKey - ), - ) - .to.emit(rollupManagerContract, 'AddNewRollupType') - .withArgs( - Number(lastRollupTypeID) + 1 /* rollupTypeID */, - PolygonPPConsensusImplementationContract.target, - verifierContract.target, - 0, // fork id - VerifierType.Pessimistic, - ethers.ZeroHash, // genesis - '', // description - ethers.ZeroHash, // programVKey - ); - return Number(lastRollupTypeID) + 1; - } async function createAggchainRollupType(implementationContract: any) { // Create rollup type for ECDSA const lastRollupTypeID = await rollupManagerContract.rollupTypeCount(); @@ -422,15 +392,6 @@ describe('Polygon rollup manager aggregation layer v3 UPGRADED', () => { aggLayerGatewayContract.target, ); - // Deploy pessimistic consensus contract - const ppConsensusFactory = await ethers.getContractFactory('PolygonPessimisticConsensus'); - PolygonPPConsensusImplementationContract = await ppConsensusFactory.deploy( - polygonZkEVMGlobalExitRoot.target, - polTokenContract.target, - polygonZkEVMBridgeContract.target, - rollupManagerContract.target, - ); - // Deploy FEP consensus contract const aggchainFEPFactory = await ethers.getContractFactory('AggchainFEP'); aggchainFEPImplementationContract = await aggchainFEPFactory.deploy( @@ -604,177 +565,6 @@ describe('Polygon rollup manager aggregation layer v3 UPGRADED', () => { .withArgs(randomNewStateRoot); }); - it('should create a rollup with pessimistic consensus and upgrade it to aggchainECDSA', async () => { - // Ensure VKey is not set for this test (remove it if it was added by previous tests) - try { - await aggLayerGatewayContract.connect(aggLayerAdmin).unsetDefaultAggchainVKey(AGGCHAIN_VKEY_SELECTOR); - } catch (e) { - // VKey might not exist, which is fine - } - - // Deploy pessimistic consensus contract - const ppConsensusFactory = await ethers.getContractFactory('PolygonPessimisticConsensus'); - - // Create new rollup type with pessimistic consensus - const pessimisticRollupTypeID = await createPessimisticRollupType(); - - // Create new rollup with pessimistic consensus - const precomputedRollupAddress = ethers.getCreateAddress({ - from: rollupManagerContract.target as string, - nonce: await ethers.provider.getTransactionCount(rollupManagerContract.target), - }); - const pessimisticRollupContract = ppConsensusFactory.attach( - precomputedRollupAddress, - ) as PolygonPessimisticConsensus; - const chainID = 5; - const gasTokenAddress = ethers.ZeroAddress; - const urlSequencer = 'https://pessimistic:8545'; - const networkName = 'testPessimistic'; - const pessimisticRollupID = 1; // Already aggchainECDSA rollup created created - const initializeBytesPessimistic = encodeInitializeBytesLegacy( - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName, - ); - await expect( - rollupManagerContract - .connect(admin) - .attachAggchainToAL(pessimisticRollupTypeID, chainID, initializeBytesPessimistic), - ) - .to.emit(rollupManagerContract, 'CreateNewRollup') - .withArgs(pessimisticRollupID, pessimisticRollupTypeID, precomputedRollupAddress, chainID, gasTokenAddress); - - // Verify pessimist proof with pessimistic rollup - // create a bridge to generate a new GER and add another value in the l1IfoRootMap - const tokenAddress = ethers.ZeroAddress; - const amount = ethers.parseEther('1'); - await polygonZkEVMBridgeContract.bridgeAsset( - pessimisticRollupID, - polTokenContract.target, - amount, - tokenAddress, - true, - '0x', - { - value: amount, - }, - ); - // get last L1InfoTreeLeafCount - const lastL1InfoTreeLeafCount = await polygonZkEVMGlobalExitRoot.depositCount(); - - // check JS function computeInputPessimisticBytes - const newLER = '0x0000000000000000000000000000000000000000000000000000000000000001'; - const newPPRoot = '0x0000000000000000000000000000000000000000000000000000000000000002'; - const proofPP = '0x00'; - - // verify pessimistic from the created pessimistic rollup - await expect( - rollupManagerContract.connect(trustedAggregator).verifyPessimisticTrustedAggregator( - pessimisticRollupID, - lastL1InfoTreeLeafCount, - newLER, - newPPRoot, - proofPP, - '0x', // aggchainData - ), - ) - .to.emit(rollupManagerContract, 'VerifyBatchesTrustedAggregator') - .withArgs( - pessimisticRollupID, - 0, // numBatch - ethers.ZeroHash, // stateRoot - newLER, - trustedAggregator.address, - ); - - // Create rollup type ECDSA - const rollupTypeECDSAId = await createAggchainRollupType(aggchainECDSAImplementationContract); - // Update the rollup to ECDSA and initialize the new rollup type - // Compute initialize upgrade data - const aggchainECDSAFactory = await ethers.getContractFactory('AggchainECDSAMultisig'); - - // For migration from PessimisticConsensus, the migrateFromLegacyConsensus function - // will be called automatically by the RollupManager - // No initialization bytes needed for migration - - const upgradeData = aggchainECDSAFactory.interface.encodeFunctionData('initAggchainManager(address)', [ - aggchainManager.address, - ]); - - await expect( - rollupManagerContract - .connect(timelock) - .updateRollup(pessimisticRollupContract.target, rollupTypeECDSAId, upgradeData), - ) - .to.emit(rollupManagerContract, 'UpdateRollup') - .withArgs(pessimisticRollupID, rollupTypeECDSAId, 0 /* lastVerifiedBatch */); - const ECDSARollupContract = aggchainECDSAFactory.attach(pessimisticRollupContract.target) as any; - - const aggchainManagerSC = await ECDSARollupContract.aggchainManager(); - expect(aggchainManagerSC).to.be.equal(aggchainManager.address); - - // migrate from PessimisticConsensus - // Impersonate rollup manager to call migrateFromLegacyConsensus - await ethers.provider.send('hardhat_impersonateAccount', [rollupManagerContract.target]); - const rollupManagerSigner = await ethers.getSigner(rollupManagerContract.target as any); - await ECDSARollupContract.connect(rollupManagerSigner).migrateFromLegacyConsensus({ gasPrice: 0 }); - - // Try update rollup by rollupAdmin but trigger UpdateToOldRollupTypeID - // Create a new pessimistic rollup type - await createPessimisticRollupType(); - - // Check new rollup data - const resRollupData = await rollupManagerContract.rollupIDToRollupDataV2Deserialized(pessimisticRollupID); - const expectedRollupData = [ - ECDSARollupContract.target, - chainID, - ethers.ZeroAddress, // newVerifier address, for ECDSA is zero because it is internally replaced by aggLayerGateway address - 0, // newForkID - newLER, // lastLocalExitRoot - 0, // lastBatchSequenced - 0, // lastBatchVerified - 0, // lastVerifiedBatchBeforeUpgrade - rollupTypeECDSAId, - VerifierType.ALGateway, - newPPRoot, // lastPessimisticRoot - ethers.ZeroHash, // newProgramVKey - ]; - - expect(expectedRollupData).to.be.deep.equal(resRollupData); - - // Verify pessimist proof with the new ECDSA rollup - const randomNewLocalExitRoot = computeRandomBytes(32); - const randomNewPessimisticRoot = computeRandomBytes(32); - const randomProof = computeRandomBytes(128); - // append first 4 bytes to the proof to select the pessimistic vkey - const proofWithSelector = `${PESSIMISTIC_SELECTOR}${randomProof.slice(2)}`; - - // Add default AggchainVKey (needed for verification) - const aggchainVKey = computeRandomBytes(32); - - await expect( - aggLayerGatewayContract.connect(aggLayerAdmin).addDefaultAggchainVKey(AGGCHAIN_VKEY_SELECTOR, aggchainVKey), - ) - .to.emit(aggLayerGatewayContract, 'AddDefaultAggchainVKey') - .withArgs(AGGCHAIN_VKEY_SELECTOR, aggchainVKey); - - // verify pessimist proof with the new ECDSA rollup - await expect( - rollupManagerContract.connect(trustedAggregator).verifyPessimisticTrustedAggregator( - pessimisticRollupID, // rollupID - lastL1InfoTreeLeafCount, // l1InfoTreeCount - randomNewLocalExitRoot, - randomNewPessimisticRoot, - proofWithSelector, - CUSTOM_DATA_ECDSA, - ), - ) - .to.emit(rollupManagerContract, 'VerifyBatchesTrustedAggregator') - .to.emit(ECDSARollupContract, 'OnVerifyPessimisticECDSAMultisig'); - }); - it('should add existing rollup to ECDSA', async () => { // add existing rollup const rollupAddress = '0xAa000000000000000000000000000000000000Bb'; @@ -825,306 +615,6 @@ describe('Polygon rollup manager aggregation layer v3 UPGRADED', () => { ); }); - it('should throw reverts UpdateToOldRollupTypeID and UpdateNotCompatible', async () => { - // create two pessimistic rollup types - const pessimisticRollupTypeID1 = await createPessimisticRollupType(); - const pessimisticRollupTypeID2 = await createPessimisticRollupType(); - - const rollupManagerNonce = await ethers.provider.getTransactionCount(rollupManagerContract.target); - const pessimisticRollupAddress = ethers.getCreateAddress({ - from: rollupManagerContract.target as string, - nonce: rollupManagerNonce, - }); - // Create pessimistic rollup - const initializeBytesAggchain = encodeInitializeBytesLegacy( - admin.address, - trustedSequencer.address, - ethers.ZeroAddress, - '', - '', - ); - await rollupManagerContract.connect(admin).attachAggchainToAL( - pessimisticRollupTypeID2, - 2, // chainID - initializeBytesAggchain, - ); - expect(await rollupManagerContract.rollupAddressToID(pessimisticRollupAddress)).to.be.equal(1); - - // Try to upgrade from rollupType1 to rollupType2 should revert (lowest rollup typed id) - await expect( - rollupManagerContract - .connect(admin) - .updateRollupByRollupAdmin(pessimisticRollupAddress, pessimisticRollupTypeID1), - ).to.be.revertedWithCustomError(rollupManagerContract, 'UpdateToOldRollupTypeID'); - - // Try to upgrade to a rollup type with different verifier type, should revert - const ecdsaRollupType = await createAggchainRollupType(aggchainECDSAImplementationContract); - await expect( - rollupManagerContract.connect(admin).updateRollupByRollupAdmin(pessimisticRollupAddress, ecdsaRollupType), - ).to.be.revertedWithCustomError(rollupManagerContract, 'UpdateNotCompatible'); - - // Try to upgrade to a pessimistic from an ecdsa rollup type, should revert - const [, ecdsaRollupAddress] = await createECDSARollup(ecdsaRollupType); - await expect( - rollupManagerContract - .connect(timelock) - .updateRollup(ecdsaRollupAddress as string, pessimisticRollupTypeID1, '0x'), - ).to.be.revertedWithCustomError(rollupManagerContract, 'UpdateNotCompatible'); - - // Trigger OnlyStateTransitionChains from onSequenceBatches - await ethers.provider.send('hardhat_setBalance', [pessimisticRollupAddress, '0x100000000000000']); - await ethers.provider.send('hardhat_impersonateAccount', [pessimisticRollupAddress]); - const pessimisticRollupContract = await ethers.getSigner(pessimisticRollupAddress); - await expect( - rollupManagerContract.connect(pessimisticRollupContract).onSequenceBatches(3, computeRandomBytes(32)), - ).to.be.revertedWithCustomError(rollupManagerContract, 'OnlyStateTransitionChains'); - }); - - it('should upgrade from Pessimistic consensus to ECDSA', async () => { - // Create pessimistic rollup type - const pessimisticRollupTypeID = await createPessimisticRollupType(); - - // Create pessimistic rollup - const precomputedRollupAddress = ethers.getCreateAddress({ - from: rollupManagerContract.target as string, - nonce: await ethers.provider.getTransactionCount(rollupManagerContract.target), - }); - const ppConsensusFactory = await ethers.getContractFactory('PolygonPessimisticConsensus'); - const pessimisticRollupContract = ppConsensusFactory.attach( - precomputedRollupAddress, - ) as PolygonPessimisticConsensus; - - const chainID = 100; - const gasTokenAddress = ethers.ZeroAddress; - const urlSequencer = 'https://pessimistic:8545'; - const networkName = 'testPessimistic'; - const pessimisticRollupID = 1; - - const initializeBytesPessimistic = encodeInitializeBytesLegacy( - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName, - ); - - await expect( - rollupManagerContract - .connect(admin) - .attachAggchainToAL(pessimisticRollupTypeID, chainID, initializeBytesPessimistic), - ) - .to.emit(rollupManagerContract, 'CreateNewRollup') - .withArgs(pessimisticRollupID, pessimisticRollupTypeID, precomputedRollupAddress, chainID, gasTokenAddress); - - // Create ECDSA rollup type - const rollupTypeECDSAId = await createAggchainRollupType(aggchainECDSAImplementationContract); - - // Upgrade from pessimistic to ECDSA - const aggchainECDSAFactory = await ethers.getContractFactory('AggchainECDSAMultisig'); - - const initializeBytesWrongECDSA = aggchainECDSAFactory.interface.encodeFunctionData( - 'initialize(address,address,address,string,string,bool,(address,string)[],uint256)', - [ - admin.address, - trustedSequencer.address, - ethers.ZeroAddress, // gas token address - '', // trusted sequencer url - '', // network name - false, // useDefaultSigners - [], // No signers to add initially - 0, // Threshold of 0 initially - ], - ); - - const ECDSARollupContract = aggchainECDSAFactory.attach(pessimisticRollupContract.target) as any; - - await expect( - rollupManagerContract - .connect(timelock) - .updateRollup(pessimisticRollupContract.target, rollupTypeECDSAId, initializeBytesWrongECDSA), - ).to.be.revertedWithCustomError(ECDSARollupContract, 'OnlyAggchainManager'); - - // For ECDSA upgrade, we use initAggchainManager as ECDSA doesn't have special migration from pessimistic - const upgradeData = aggchainECDSAFactory.interface.encodeFunctionData('migrateFromLegacyConsensus()'); - - // Do not redeclare those variables, update the name - const signersECDSA = [trustedSequencer.address]; - const thresholdECDSA = 1; - const aggchainMultisigHashECDSA = computeSignersHash(thresholdECDSA, signersECDSA); - - await expect( - rollupManagerContract - .connect(timelock) - .updateRollup(pessimisticRollupContract.target, rollupTypeECDSAId, upgradeData), - ) - .to.emit(rollupManagerContract, 'UpdateRollup') - .withArgs(pessimisticRollupID, rollupTypeECDSAId, 0) - .to.emit(ECDSARollupContract, 'SignersAndThresholdUpdated') - .withArgs(signersECDSA, thresholdECDSA, aggchainMultisigHashECDSA); - - expect(await ECDSARollupContract.aggchainManager()).to.be.equal(admin.address); - - // check the signers and threshold and all the previosu params are coherent - const signersECDSAFromContract = await ECDSARollupContract.getAggchainSigners(); - expect(signersECDSAFromContract).to.be.deep.equal(signersECDSA); - const thresholdECDSAFromContract = await ECDSARollupContract.threshold(); - expect(thresholdECDSAFromContract).to.be.equal(thresholdECDSA); - const aggchainMultisigHashECDSAFromContract = await ECDSARollupContract.getAggchainMultisigHash(); - expect(aggchainMultisigHashECDSAFromContract).to.be.equal(aggchainMultisigHashECDSA); - const aggchainManagerFromContract = await ECDSARollupContract.aggchainManager(); - expect(aggchainManagerFromContract).to.be.equal(admin.address); - }); - - it('should upgrade from Pessimistic consensus to FEP', async () => { - // Create pessimistic rollup type - const pessimisticRollupTypeID = await createPessimisticRollupType(); - - // Create pessimistic rollup - const precomputedRollupAddress = ethers.getCreateAddress({ - from: rollupManagerContract.target as string, - nonce: await ethers.provider.getTransactionCount(rollupManagerContract.target), - }); - const ppConsensusFactory = await ethers.getContractFactory('PolygonPessimisticConsensus'); - const pessimisticRollupContract = ppConsensusFactory.attach( - precomputedRollupAddress, - ) as PolygonPessimisticConsensus; - - const chainID = 200; - const gasTokenAddress = ethers.ZeroAddress; - const urlSequencer = 'https://pessimistic-fep:8545'; - const networkName = 'testPessimisticToFEP'; - const pessimisticRollupID = 1; - - const initializeBytesPessimistic = encodeInitializeBytesLegacy( - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName, - ); - - await expect( - rollupManagerContract - .connect(admin) - .attachAggchainToAL(pessimisticRollupTypeID, chainID, initializeBytesPessimistic), - ) - .to.emit(rollupManagerContract, 'CreateNewRollup') - .withArgs(pessimisticRollupID, pessimisticRollupTypeID, precomputedRollupAddress, chainID, gasTokenAddress); - - // Create FEP rollup type - const rollupTypeFEPId = await createAggchainRollupType(aggchainFEPImplementationContract); - - // Upgrade from pessimistic to FEP - const aggchainFEPFactory = await ethers.getContractFactory('AggchainFEP'); - - // Prepare InitParams for FEP initialization - const initParams = { - l2BlockTime: 2, // 2 seconds per block - rollupConfigHash: computeRandomBytes(32), - startingOutputRoot: computeRandomBytes(32), - startingBlockNumber: 0, - startingTimestamp: (await ethers.provider.getBlock('latest'))?.timestamp || 0, - submissionInterval: 100, // Every 100 blocks - optimisticModeManager: admin.address, - aggregationVkey: computeRandomBytes(32), - rangeVkeyCommitment: computeRandomBytes(32), - }; - - // Encode upgrade data for initializeFromLegacyConsensus - const wrongUpgradeData = aggchainFEPFactory.interface.encodeFunctionData( - 'initializeFromLegacyConsensus((uint256,bytes32,bytes32,uint256,uint256,uint256,address,bytes32,bytes32),bool,bool,bytes32,bytes4,(address,string)[],uint256)', - [ - initParams, - false, // useDefaultVkeys - false, // useDefaultSigners - ethers.ZeroHash, // initOwnedAggchainVKey - '0x00010001', // initAggchainVKeySelector for FEP (AGGCHAIN_TYPE = 0x0001) - [], // signersToAdd - 0, // newThreshold - ], - ); - - const FEPRollupContract = aggchainFEPFactory.attach(pessimisticRollupContract.target) as AggchainFEP; - - await expect( - rollupManagerContract - .connect(timelock) - .updateRollup(pessimisticRollupContract.target, rollupTypeFEPId, wrongUpgradeData), - ).to.be.revertedWithCustomError(FEPRollupContract, 'OnlyAggchainManager'); - - const upgradeData = FEPRollupContract.interface.encodeFunctionData('initAggchainManager', [ - aggchainManager.address, - ]); - - await expect( - rollupManagerContract - .connect(timelock) - .updateRollup(pessimisticRollupContract.target, rollupTypeFEPId, upgradeData), - ) - .to.emit(rollupManagerContract, 'UpdateRollup') - .withArgs(pessimisticRollupID, rollupTypeFEPId, 0); - - // Migrate from PessimisticConsensus - await ethers.provider.send('hardhat_setBalance', [rollupManagerContract.target, '0x100000000000000']); - await ethers.provider.send('hardhat_impersonateAccount', [rollupManagerContract.target]); - const rollupManagerSigner = await ethers.getSigner(rollupManagerContract.target as any); - - await expect( - FEPRollupContract.connect(aggchainManager).initializeFromECDSAMultisig( - initParams, - false, // useDefaultVkeys - ethers.ZeroHash, // initOwnedAggchainVKey - '0x00010001', // initAggchainVKeySelector for FEP - ), - ).to.be.revertedWithCustomError(FEPRollupContract, 'InvalidInitializer'); - - await expect( - FEPRollupContract.connect(rollupManagerSigner).initializeFromECDSAMultisig( - initParams, - false, // useDefaultVkeys - ethers.ZeroHash, // initOwnedAggchainVKey - '0x00010001', // initAggchainVKeySelector for FEP - ), - ).to.be.revertedWithCustomError(FEPRollupContract, 'OnlyAggchainManager'); - - await expect( - FEPRollupContract.connect(rollupManagerSigner).upgradeFromPreviousFEP(), - ).to.be.revertedWithCustomError(FEPRollupContract, 'InvalidInitializer'); - - const signersECDSA = [trustedSequencer.address]; - const thresholdECDSA = 1; - const aggchainMultisigHashECDSA = computeSignersHash(thresholdECDSA, signersECDSA); - - await expect( - FEPRollupContract.connect(rollupManagerSigner).initializeFromLegacyConsensus( - initParams, - false, // useDefaultVkeys - false, // useDefaultSigners - ethers.ZeroHash, // initOwnedAggchainVKey - '0x00010001', // initAggchainVKeySelector for FEP (AGGCHAIN_TYPE = 0x0001) - [{ addr: trustedSequencer.address, url: 'http://signer1' }], - thresholdECDSA, // newThreshold - { gasPrice: 0 }, - ), - ).to.be.revertedWithCustomError(FEPRollupContract, 'OnlyAggchainManager'); - - await FEPRollupContract.connect(aggchainManager).initializeFromLegacyConsensus( - initParams, - false, // useDefaultVkeys - false, // useDefaultSigners - ethers.ZeroHash, // initOwnedAggchainVKey - '0x00010001', // initAggchainVKeySelector for FEP (AGGCHAIN_TYPE = 0x0001) - [{ addr: trustedSequencer.address, url: 'http://signer1' }], - thresholdECDSA, // newThreshold - { gasPrice: 0 }, - ); - - expect(await FEPRollupContract.aggchainManager()).to.be.equal(aggchainManager.address); - expect(await FEPRollupContract.getAggchainMultisigHash()).to.be.equal(aggchainMultisigHashECDSA); - expect(await FEPRollupContract.threshold()).to.be.equal(thresholdECDSA); - expect(await FEPRollupContract.getAggchainSigners()).to.be.deep.equal(signersECDSA); - }); - it('should upgrade from ECDSA to FEP', async () => { // Create ECDSA rollup type and rollup const rollupTypeECDSAId = await createAggchainRollupType(aggchainECDSAImplementationContract); diff --git a/test/contractsv2/UpgradeToPP.test.ts b/test/contractsv2/UpgradeToPP.test.ts index 5796fb121..d14bb2c9a 100644 --- a/test/contractsv2/UpgradeToPP.test.ts +++ b/test/contractsv2/UpgradeToPP.test.ts @@ -4,7 +4,6 @@ /* eslint-disable no-plusplus, no-await-in-loop */ import { expect } from 'chai'; import { ethers, upgrades } from 'hardhat'; -import { MTBridge, mtBridgeUtils } from '@0xpolygonhermez/zkevm-commonjs'; import { ERC20PermitMock, VerifierRollupHelperMock, @@ -12,16 +11,12 @@ import { AgglayerGER, AgglayerManagerMock, PolygonValidiumEtrog, - PolygonPessimisticConsensus, AggchainECDSAMultisig, } from '../../typechain-types'; import { encodeInitializeBytesLegacy } from '../../src/utils-common-aggchain'; import { VerifierType, computeRandomBytes } from '../../src/pessimistic-utils'; import { AL_MULTISIG_ROLE } from '../../src/constants'; -const MerkleTreeBridge = MTBridge; -const { getLeafValue } = mtBridgeUtils; - describe('Upgradeable to PPV2 or ALGateway', () => { let deployer: any; let timelock: any; @@ -29,11 +24,9 @@ describe('Upgradeable to PPV2 or ALGateway', () => { let trustedAggregator: any; let trustedSequencer: any; let admin: any; - let beneficiary: any; let aggLayerAdmin: any; let polTokenContract: ERC20PermitMock; - let PolygonPPConsensusContract: PolygonPessimisticConsensus; let verifierContract: VerifierRollupHelperMock; let polygonZkEVMBridgeContract: AgglayerBridge; let polygonZkEVMGlobalExitRoot: AgglayerGER; @@ -48,8 +41,7 @@ describe('Upgradeable to PPV2 or ALGateway', () => { const polTokenSymbol = 'POL'; const polTokenInitialBalance = ethers.parseEther('20000000'); - const rollupTypeIDPessimistic = 1; - const rollupTypeIDAlGateway = 2; + const rollupTypeIDAlGateway = 1; const PESSIMISTIC_SELECTOR = '0x00000001'; // calculate aggchainHash @@ -61,7 +53,7 @@ describe('Upgradeable to PPV2 or ALGateway', () => { upgrades.silenceWarnings(); // load signers - [deployer, trustedAggregator, trustedSequencer, admin, timelock, emergencyCouncil, beneficiary, aggLayerAdmin] = + [deployer, trustedAggregator, trustedSequencer, admin, timelock, emergencyCouncil, aggLayerAdmin] = await ethers.getSigners(); // deploy mock verifier @@ -167,34 +159,8 @@ describe('Upgradeable to PPV2 or ALGateway', () => { // fund sequencer address with Matic tokens await polTokenContract.transfer(trustedSequencer.address, ethers.parseEther('1000')); - // deploy consensus - // create polygonPessimisticConsensus implementation - const ppConsensusFactory = await ethers.getContractFactory('PolygonPessimisticConsensus'); - PolygonPPConsensusContract = await ppConsensusFactory.deploy( - polygonZkEVMGlobalExitRoot.target, - polTokenContract.target, - polygonZkEVMBridgeContract.target, - rollupManagerContract.target, - ); - - // Create pessimistic rollup type - const forkID = 0; // just metadata for pessimistic consensus - const genesis = ethers.ZeroHash; - const description = 'new pessimistic consensus'; const programVKey = '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'; - await rollupManagerContract - .connect(timelock) - .addNewRollupType( - PolygonPPConsensusContract.target, - verifierContract.target, - forkID, - VerifierType.Pessimistic, - genesis, - description, - programVKey, - ); - // Create ALGateway rollup type // Initialize aggLayerGateway await aggLayerGatewayContract.initialize( @@ -241,7 +207,7 @@ describe('Upgradeable to PPV2 or ALGateway', () => { ) .to.emit(rollupManagerContract, 'AddNewRollupType') .withArgs( - 2, + 1, aggchainECDSAContract.target, ethers.ZeroAddress, // verifier 0, // fork id @@ -261,7 +227,7 @@ describe('Upgradeable to PPV2 or ALGateway', () => { .withArgs(aggchainVKeySelector, aggchainVKey); }); - it('should create rollup type validium & migrate to PP', async () => { + it('should create rollup type validium & migrate to ALGateway', async () => { // Create etrog state transition chain const urlSequencer = 'http://zkevm-json-rpc:8123'; const chainID = 1000; @@ -286,7 +252,7 @@ describe('Upgradeable to PPV2 or ALGateway', () => { await validiumEtrogContract.waitForDeployment(); // Create new rollup type validium - const newRollupTypeID = 3; + const newRollupTypeID = 2; await expect( rollupManagerContract .connect(timelock) @@ -446,13 +412,18 @@ describe('Upgradeable to PPV2 or ALGateway', () => { const lastBatchVerified = rollupData[6]; expect(lastBatchSequenced).to.be.equal(lastBatchVerified); + const aggchainECDSAFactory = await ethers.getContractFactory('AggchainECDSAMultisig'); + const upgradeData = aggchainECDSAFactory.interface.encodeFunctionData('migrateFromLegacyConsensus()'); + await expect( - rollupManagerContract.connect(timelock).initMigration(newCreatedRollupID, rollupTypeIDPessimistic, '0x'), + rollupManagerContract + .connect(timelock) + .initMigration(newCreatedRollupID, rollupTypeIDAlGateway, upgradeData), ) .to.emit(rollupManagerContract, 'InitMigration') - .withArgs(newCreatedRollupID, rollupTypeIDPessimistic) + .withArgs(newCreatedRollupID, rollupTypeIDAlGateway) .to.emit(rollupManagerContract, 'UpdateRollup') - .withArgs(newCreatedRollupID, rollupTypeIDPessimistic, newVerifiedBatch); + .withArgs(newCreatedRollupID, rollupTypeIDAlGateway, newVerifiedBatch); expect(await rollupManagerContract.isRollupMigrating(newCreatedRollupID)).to.be.equal(true); @@ -462,30 +433,38 @@ describe('Upgradeable to PPV2 or ALGateway', () => { const lastLER = rollupData[4]; const newPPRoot = computeRandomBytes(32); const proofPP = '0x00'; + const proofWithSelector = `${PESSIMISTIC_SELECTOR}${proofPP.slice(2)}`; await expect( - rollupManagerContract.connect(trustedAggregator).verifyPessimisticTrustedAggregator( - newCreatedRollupID, - lastL1InfoTreeLeafCount, - newWrongLER, - newPPRoot, - proofPP, - '0x', // aggchainData is zero for pessimistic - ), + rollupManagerContract + .connect(trustedAggregator) + .verifyPessimisticTrustedAggregator( + newCreatedRollupID, + lastL1InfoTreeLeafCount, + newWrongLER, + newPPRoot, + proofWithSelector, + CUSTOM_DATA_ECDSA, + ), ).to.be.revertedWithCustomError(rollupManagerContract, 'InvalidNewLocalExitRoot'); + // // Ensure signers hash initialized (empty) + // await aggchainECDSARollupContract.connect(aggchainManager).updateSignersAndThreshold([], [], 0); + const prevPP = ethers.ZeroHash; const prevLER = ethers.ZeroHash; const lastL1InfoTreeRoot = await polygonZkEVMGlobalExitRoot.l1InfoRootMap(lastL1InfoTreeLeafCount); await expect( - rollupManagerContract.connect(trustedAggregator).verifyPessimisticTrustedAggregator( - newCreatedRollupID, - lastL1InfoTreeLeafCount, - lastLER, - newPPRoot, - proofPP, - '0x', // aggchainData is zero for pessimistic - ), + rollupManagerContract + .connect(trustedAggregator) + .verifyPessimisticTrustedAggregator( + newCreatedRollupID, + lastL1InfoTreeLeafCount, + lastLER, + newPPRoot, + proofWithSelector, + CUSTOM_DATA_ECDSA, + ), ) .to.emit(rollupManagerContract, 'CompletedMigration') .withArgs(newCreatedRollupID) @@ -505,919 +484,28 @@ describe('Upgradeable to PPV2 or ALGateway', () => { expect(await rollupManagerContract.isRollupMigrating(newCreatedRollupID)).to.be.equal(false); }); - it('should create rollup type validium & migrate to PP all checks', async () => { - // Validate upgrade - const validiumEtrogFactory = await ethers.getContractFactory('PolygonValidiumEtrog'); - const ppConsensusFactory = await ethers.getContractFactory('PolygonPessimisticConsensus'); - - await upgrades.validateUpgrade(validiumEtrogFactory, ppConsensusFactory, { - constructorArgs: [ - polygonZkEVMGlobalExitRoot.target, - polTokenContract.target, - polygonZkEVMBridgeContract.target, - rollupManagerContract.target, - ], - unsafeAllow: ['constructor', 'state-variable-immutable'], - } as any); - - // Create etrog state transition chain - const urlSequencer = 'http://zkevm-json-rpc:8123'; - const chainID = 1000; - const networkName = 'zkevm'; - const forkID = 0; - const genesisRandom = '0x0000000000000000000000000000000000000000000000000000000000000001'; - const rollupVerifierType = 0; - const description = 'zkevm test'; - const programVKey = '0x0000000000000000000000000000000000000000000000000000000000000000'; - - // Native token will be ether - const gasTokenAddress = ethers.ZeroAddress; - - // deploy validium consensus - const validiumEtrogContract = await validiumEtrogFactory.deploy( - polygonZkEVMGlobalExitRoot.target, - polTokenContract.target, - polygonZkEVMBridgeContract.target, - rollupManagerContract.target, - ); - await validiumEtrogContract.waitForDeployment(); - - // Create new rollup type validium - const newRollupTypeID = 3; - await expect( - rollupManagerContract - .connect(timelock) - .addNewRollupType( - validiumEtrogContract.target, - verifierContract.target, - forkID, - rollupVerifierType, - genesisRandom, - description, - programVKey, - ), - ) - .to.emit(rollupManagerContract, 'AddNewRollupType') - .withArgs( - newRollupTypeID, - validiumEtrogContract.target, - verifierContract.target, - forkID, - rollupVerifierType, - genesisRandom, - description, - programVKey, - ); - - // Create rollup - const newSequencedBatch = 1; - const initializeBytesLegacy = encodeInitializeBytesLegacy( - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName, - ); - const rollupAddress = ethers.getCreateAddress({ - from: rollupManagerContract.target as string, - nonce: 1, - }); - const validiumContract = validiumEtrogFactory.attach(rollupAddress) as PolygonValidiumEtrog; - - await expect( - rollupManagerContract.connect(admin).attachAggchainToAL(newRollupTypeID, chainID, initializeBytesLegacy), - ) - .to.emit(rollupManagerContract, 'CreateNewRollup') - .withArgs(newCreatedRollupID, newRollupTypeID, rollupAddress, chainID, gasTokenAddress) - .to.emit(validiumContract, 'InitialSequenceBatches') - .to.emit(rollupManagerContract, 'OnSequenceBatches') - .withArgs(newCreatedRollupID, newSequencedBatch); - - // Set data availability protocol - // Create PolygonDataCommittee - const PolygonDataCommitteeFactory = await ethers.getContractFactory('PolygonDataCommittee'); - const PolygonDataCommittee = (await upgrades.deployProxy(PolygonDataCommitteeFactory, [], { - unsafeAllow: ['constructor'], - })) as any as PolygonDataCommittee; - await expect(validiumContract.connect(admin).setDataAvailabilityProtocol(PolygonDataCommittee.target)) - .to.emit(validiumContract, 'SetDataAvailabilityProtocol') - .withArgs(PolygonDataCommittee.target); - - // Sequence a batch - const currentTime = Number((await ethers.provider.getBlock('latest'))?.timestamp); - const l1InfoTreeLeafCount = 0; - - const l2txData = '0x123456'; - const hashedData = ethers.keccak256(l2txData) as any; - const sequenceValidium = { - transactionsHash: hashedData, - forcedGlobalExitRoot: ethers.ZeroHash, - forcedTimestamp: 0, - forcedBlockHashL1: ethers.ZeroHash, - } as PolygonValidiumEtrog.ValidiumBatchDataStruct; - - const expectedAccInputHash = calculateAccInputHashEtrog( - await validiumContract.lastAccInputHash(), - hashedData, - await polygonZkEVMGlobalExitRoot.getRoot(), - currentTime, - trustedSequencer.address, - ethers.ZeroHash, - ); - let message = '0x'; - const walletsDataCommittee = [] as any; - for (let i = 0; i < 3; i++) { - const newWallet = ethers.HDNodeWallet.fromMnemonic( - ethers.Mnemonic.fromPhrase('test test test test test test test test test test test junk'), - `m/44'/60'/0'/0/${i}`, - ); - walletsDataCommittee.push(newWallet); - } - // sort wallets - walletsDataCommittee.sort((walleta: any, walletb: any) => { - if (ethers.toBigInt(walleta.address) > ethers.toBigInt(walletb.address)) { - return 1; - } - return -1; - }); - const signedData = expectedAccInputHash; - for (let i = 0; i < walletsDataCommittee.length; i++) { - const newSignature = walletsDataCommittee[i].signingKey.sign(signedData); - message += newSignature.serialized.slice(2); - } - let addrBytes = '0x'; - for (let i = 0; i < walletsDataCommittee.length; i++) { - addrBytes += walletsDataCommittee[i].address.slice(2); - } - const dataAvailabilityMessage = message + addrBytes.slice(2); - - const requiredAmountOfSignatures = 3; - const urls = ['onurl', 'twourl', 'threeurl']; - const committeeHash = ethers.keccak256(addrBytes); - await expect(PolygonDataCommittee.setupCommittee(requiredAmountOfSignatures, urls, addrBytes)) - .to.emit(PolygonDataCommittee, 'CommitteeUpdated') - .withArgs(committeeHash); - - // Approve tokens - const maticAmount = await rollupManagerContract.getBatchFee(); - await expect(polTokenContract.connect(trustedSequencer).approve(validiumContract.target, maticAmount)).to.emit( - polTokenContract, - 'Approval', - ); - await expect( - validiumContract - .connect(trustedSequencer) - .sequenceBatchesValidium( - [sequenceValidium], - l1InfoTreeLeafCount, - currentTime, - expectedAccInputHash, - trustedSequencer.address, - dataAvailabilityMessage, - ), - ).to.emit(validiumContract, 'SequenceBatches'); - - // create new pessimistic - const initializeBytesLegacyPP = encodeInitializeBytesLegacy( - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName, - ); - await rollupManagerContract - .connect(admin) - .attachAggchainToAL(rollupTypeIDPessimistic, chainID + 1, initializeBytesLegacyPP); - - const newPessimiticRollupID = 2; - - // Call initMigration - - await expect( - rollupManagerContract.connect(admin).initMigration(newCreatedRollupID, rollupTypeIDPessimistic, '0x'), - ).to.be.revertedWithCustomError(rollupManagerContract, 'AddressDoNotHaveRequiredRole'); - - // Check OnlyStateTransitionChains - await expect( - rollupManagerContract.connect(timelock).initMigration(newPessimiticRollupID, rollupTypeIDPessimistic, '0x'), - ).to.be.revertedWithCustomError(rollupManagerContract, 'OnlyStateTransitionChains'); - - // Verify pending sequenced batches - const pendingState = 0; - const newLocalExitRoot = '0x0000000000000000000000000000000000000000000000000000000000000123'; - const currentVerifiedBatch = 0; - const newVerifiedBatch = newSequencedBatch + 1; - const zkProofFFlonk = new Array(24).fill(ethers.ZeroHash); - await rollupManagerContract - .connect(trustedAggregator) - .verifyBatchesTrustedAggregator( - newCreatedRollupID, - pendingState, - currentVerifiedBatch, - newVerifiedBatch, - newLocalExitRoot, - newStateRoot, - trustedAggregator.address, - zkProofFFlonk, - ); - - const rollupData = await rollupManagerContract.rollupIDToRollupDataV2Deserialized(newCreatedRollupID); - const lastBatchSequenced = rollupData[5]; - const lastBatchVerified = rollupData[6]; - expect(lastBatchSequenced).to.be.equal(lastBatchVerified); - - // Check NewRollupTypeMustBePessimisticOrAlGateway - await expect( - rollupManagerContract.connect(timelock).initMigration(newCreatedRollupID, newRollupTypeID, '0x'), // validium - ).to.be.revertedWithCustomError(rollupManagerContract, 'NewRollupTypeMustBePessimisticOrALGateway'); - - await expect( - rollupManagerContract.connect(timelock).initMigration(newCreatedRollupID, rollupTypeIDPessimistic, '0x'), - ) - .to.emit(rollupManagerContract, 'InitMigration') - .withArgs(newCreatedRollupID, rollupTypeIDPessimistic) - .to.emit(rollupManagerContract, 'UpdateRollup') - .withArgs(newCreatedRollupID, rollupTypeIDPessimistic, newVerifiedBatch); - - expect(await rollupManagerContract.isRollupMigrating(newCreatedRollupID)).to.be.equal(true); - - // Verify PP with mock "bootstrapBatch" - const lastL1InfoTreeLeafCount = await polygonZkEVMGlobalExitRoot.depositCount(); - const newWrongLER = '0x0000000000000000000000000000000000000000000000000000000000000001'; - const lastLER = rollupData[4]; - const newPPRoot = computeRandomBytes(32); - const proofPP = '0x00'; - - await expect( - rollupManagerContract.connect(trustedAggregator).verifyPessimisticTrustedAggregator( - newCreatedRollupID, - lastL1InfoTreeLeafCount, - newWrongLER, - newPPRoot, - proofPP, - '0x', // aggchainData is zero for pessimistic - ), - ).to.be.revertedWithCustomError(rollupManagerContract, 'InvalidNewLocalExitRoot'); - - const prevPP = ethers.ZeroHash; - const prevLER = ethers.ZeroHash; - const lastL1InfoTreeRoot = await polygonZkEVMGlobalExitRoot.l1InfoRootMap(lastL1InfoTreeLeafCount); - await expect( - rollupManagerContract.connect(trustedAggregator).verifyPessimisticTrustedAggregator( - newCreatedRollupID, - lastL1InfoTreeLeafCount, - lastLER, - newPPRoot, - proofPP, - '0x', // aggchainData is zero for pessimistic - ), - ) - .to.emit(rollupManagerContract, 'CompletedMigration') - .withArgs(newCreatedRollupID) - .to.emit(rollupManagerContract, 'VerifyBatchesTrustedAggregator') - .withArgs(newCreatedRollupID, 0, ethers.ZeroHash, lastLER, trustedAggregator.address) - .to.emit(rollupManagerContract, 'VerifyPessimisticStateTransition') - .withArgs( - newCreatedRollupID, - prevPP, - newPPRoot, - prevLER, - lastLER, - lastL1InfoTreeRoot, - trustedAggregator.address, - ); - - expect(await rollupManagerContract.isRollupMigrating(newCreatedRollupID)).to.be.equal(false); - }); - - it('should create rollup type zkevm etrog & migrate to PP', async () => { - // Validate upgrade - const PolygonZKEVMV2Factory = await ethers.getContractFactory('PolygonZkEVMEtrog'); - const ppConsensusFactory = await ethers.getContractFactory('PolygonPessimisticConsensus'); - - await upgrades.validateUpgrade(PolygonZKEVMV2Factory, ppConsensusFactory, { - constructorArgs: [ - polygonZkEVMGlobalExitRoot.target, - polTokenContract.target, - polygonZkEVMBridgeContract.target, - rollupManagerContract.target, - ], - unsafeAllow: ['constructor', 'state-variable-immutable'], - } as any); - - // Create constants - const FORCE_BATCH_TIMEOUT = 60 * 60 * 24 * 5; // 5 days - const LEAF_TYPE_ASSET = 0; - const networkIDRollup = 1; - - // Create etrog state transition chain - const urlSequencer = 'http://zkevm-json-rpc:8123'; - const chainID = 1000; - const networkName = 'zkevm'; - const forkID = 0; - const genesisRandom = '0x0000000000000000000000000000000000000000000000000000000000000001'; - const rollupVerifierType = 0; - const description = 'zkevm test'; - const programVKey = '0x0000000000000000000000000000000000000000000000000000000000000000'; - - const gasTokenNetwork = 0; // 0 for native token - const gasTokenAddress = '0x0000000000000000000000000000000000000000'; - - // Create zkEVM implementation - const PolygonZKEVMV2Contract = await PolygonZKEVMV2Factory.deploy( - polygonZkEVMGlobalExitRoot.target, - polTokenContract.target, - polygonZkEVMBridgeContract.target, - rollupManagerContract.target, - ); - await PolygonZKEVMV2Contract.waitForDeployment(); - - // Create new rollup type zkevm etrog - const newRollupTypeID = 3; - await expect( - rollupManagerContract - .connect(timelock) - .addNewRollupType( - PolygonZKEVMV2Contract.target, - verifierContract.target, - forkID, - rollupVerifierType, - genesisRandom, - description, - programVKey, - ), - ) - .to.emit(rollupManagerContract, 'AddNewRollupType') - .withArgs( - newRollupTypeID, - PolygonZKEVMV2Contract.target, - verifierContract.target, - forkID, - rollupVerifierType, - genesisRandom, - description, - programVKey, - ); - - // Create rollup - const newSequencedBatch = 1; - const initializeBytesLegacy = encodeInitializeBytesLegacy( - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName, - ); - const rollupAddress = ethers.getCreateAddress({ - from: rollupManagerContract.target as string, - nonce: 1, - }); - const zkevmContract = PolygonZKEVMV2Factory.attach(rollupAddress) as PolygonValidiumEtrog; - - await expect( - rollupManagerContract.connect(admin).attachAggchainToAL(newRollupTypeID, chainID, initializeBytesLegacy), - ) - .to.emit(rollupManagerContract, 'CreateNewRollup') - .withArgs(newCreatedRollupID, newRollupTypeID, rollupAddress, chainID, gasTokenAddress) - .to.emit(zkevmContract, '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 zkevmContract.admin()).to.be.equal(admin.address); - expect(await zkevmContract.trustedSequencer()).to.be.equal(trustedSequencer.address); - expect(await zkevmContract.trustedSequencerURL()).to.be.equal(urlSequencer); - expect(await zkevmContract.networkName()).to.be.equal(networkName); - expect(await zkevmContract.forceBatchTimeout()).to.be.equal(FORCE_BATCH_TIMEOUT); - - // Cannot create 2 chains with the same chainID - await expect( - rollupManagerContract.connect(admin).attachAggchainToAL(newRollupTypeID, chainID, initializeBytesLegacy), - ).to.be.revertedWithCustomError(rollupManagerContract, 'ChainIDAlreadyExist'); - - const transaction = await zkevmContract.generateInitializeTransaction( - newCreatedRollupID, - gasTokenAddress, - gasTokenNetwork, - '0x', // empty metadata - ); - - const expectedAccInputHash = calculateAccInputHashEtrog( - ethers.ZeroHash, - ethers.keccak256(transaction), - await polygonZkEVMGlobalExitRoot.getLastGlobalExitRoot(), - timestampCreatedRollup, - trustedSequencer.address, - blockCreatedRollup?.parentHash, - ); - - // calcualte accINputHash - expect(await zkevmContract.lastAccInputHash()).to.be.equal(expectedAccInputHash); - - 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 sequence = { - transactions: l2txData, - forcedGlobalExitRoot: ethers.ZeroHash, - forcedTimestamp: 0, - forcedBlockHashL1: ethers.ZeroHash, - } as BatchDataStructEtrog; - - // Approve tokens - await expect(polTokenContract.connect(trustedSequencer).approve(zkevmContract.target, maticAmount)).to.emit( - polTokenContract, - 'Approval', - ); - - // Sequence Batches - const currentTime = Number((await ethers.provider.getBlock('latest'))?.timestamp); - const l1InfoTreeLeafCount = 0; - - const lastBlock = await ethers.provider.getBlock('latest'); - - const rootSC = await polygonZkEVMGlobalExitRoot.getRoot(); - - const expectedAccInputHash2 = calculateAccInputHashEtrog( - expectedAccInputHash, - ethers.keccak256(l2txData), - rootSC, - lastBlock?.timestamp, - trustedSequencer.address, - ethers.ZeroHash, - ); - - await expect( - zkevmContract - .connect(trustedSequencer) - .sequenceBatches( - [sequence], - l1InfoTreeLeafCount, - currentTime, - expectedAccInputHash2, - trustedSequencer.address, - ), - ).to.emit(zkevmContract, 'SequenceBatches'); - - // calcualte accINputHash - expect(await zkevmContract.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 height = 32; - 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 newVerifiedBatch = newSequencedBatch + 1; - const zkProofFFlonk = new Array(24).fill(ethers.ZeroHash); - const currentVerifiedBatch = 0; - - // Calcualte new globalExitroot - const merkleTreeRollups = new MerkleTreeBridge(height); - merkleTreeRollups.add(newLocalExitRoot); - const rootRollups = merkleTreeRollups.getRoot(); - - const lastGlobalExitRootS2 = calculateGlobalExitRoot(ethers.ZeroHash, rootRollups); - const lastBlock2 = await ethers.provider.getBlock('latest'); - const lastBlockHash2 = lastBlock2?.hash; - const leafValueUpdateGER2 = calculateGlobalExitRootLeaf( - lastGlobalExitRootS2, - lastBlockHash2, - lastBlock2?.timestamp + 5, - ); - const merkleTreeGLobalExitRoot = new MerkleTreeBridge(height); - merkleTreeGLobalExitRoot.add(leafValueUpdateGER2); - - await ethers.provider.send('evm_setNextBlockTimestamp', [lastBlock2?.timestamp + 5]); - - // Verify batch - const verifyBatchesTrustedAggregator = await rollupManagerContract - .connect(trustedAggregator) - .verifyBatchesTrustedAggregator( - newCreatedRollupID, - pendingState, - currentVerifiedBatch, - newVerifiedBatch, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk, - ); - - const rollupData = await rollupManagerContract.rollupIDToRollupDataV2Deserialized(newCreatedRollupID); - - // Retrieve l1InfoRoot - const newL1InfoRoot = await polygonZkEVMGlobalExitRoot.getRoot(); - // Retrieve depositCount - const depositCount = await polygonZkEVMGlobalExitRoot.depositCount(); - // Retrieve parentHash and timestamp - const blockInfo = await ethers.provider.getBlock(verifyBatchesTrustedAggregator?.blockHash as any); - - await expect(verifyBatchesTrustedAggregator) - .to.emit(rollupManagerContract, 'VerifyBatchesTrustedAggregator') - .withArgs(newCreatedRollupID, newVerifiedBatch, newStateRoot, newLocalExitRoot, trustedAggregator.address) - .to.emit(polygonZkEVMGlobalExitRoot, 'UpdateL1InfoTree') - .withArgs(ethers.ZeroHash, rootRollups) - .to.emit(polygonZkEVMGlobalExitRoot, 'UpdateL1InfoTreeV2') - .withArgs(newL1InfoRoot, depositCount, blockInfo?.parentHash, blockInfo?.timestamp); - - // Call initMigration - await expect( - rollupManagerContract.connect(timelock).initMigration(newCreatedRollupID, rollupTypeIDPessimistic, '0x'), - ) - .to.emit(rollupManagerContract, 'InitMigration') - .withArgs(newCreatedRollupID, rollupTypeIDPessimistic) - .to.emit(rollupManagerContract, 'UpdateRollup') - .withArgs(newCreatedRollupID, rollupTypeIDPessimistic, newVerifiedBatch); - - expect(await rollupManagerContract.isRollupMigrating(newCreatedRollupID)).to.be.equal(true); - - // Verify PP with mock "bootstrapBatch" - const lastL1InfoTreeLeafCount = await polygonZkEVMGlobalExitRoot.depositCount(); - const newWrongLER = '0x0000000000000000000000000000000000000000000000000000000000000001'; - const lastLER = rollupData[4]; - const newPPRoot = computeRandomBytes(32); - const proofPP = '0x00'; - - await expect( - rollupManagerContract.connect(trustedAggregator).verifyPessimisticTrustedAggregator( - newCreatedRollupID, - lastL1InfoTreeLeafCount, - newWrongLER, - newPPRoot, - proofPP, - '0x', // aggchainData is zero for pessimistic - ), - ).to.be.revertedWithCustomError(rollupManagerContract, 'InvalidNewLocalExitRoot'); - - const prevPP = ethers.ZeroHash; - const prevLER = ethers.ZeroHash; - const lastL1InfoTreeRoot = await polygonZkEVMGlobalExitRoot.l1InfoRootMap(lastL1InfoTreeLeafCount); - await expect( - rollupManagerContract.connect(trustedAggregator).verifyPessimisticTrustedAggregator( - newCreatedRollupID, - lastL1InfoTreeLeafCount, - lastLER, - newPPRoot, - proofPP, - '0x', // aggchainData is zero for pessimistic - ), - ) - .to.emit(rollupManagerContract, 'CompletedMigration') - .withArgs(newCreatedRollupID) - .to.emit(rollupManagerContract, 'VerifyBatchesTrustedAggregator') - .withArgs(newCreatedRollupID, 0, ethers.ZeroHash, lastLER, trustedAggregator.address) - .to.emit(rollupManagerContract, 'VerifyPessimisticStateTransition') - .withArgs( - newCreatedRollupID, - prevPP, - newPPRoot, - prevLER, - lastLER, - lastL1InfoTreeRoot, - trustedAggregator.address, - ); - - expect(await rollupManagerContract.isRollupMigrating(newCreatedRollupID)).to.be.equal(false); - }); - - it('should create rollup type validium & migrate to ALGateway', async () => { - // Create etrog state transition chain - const urlSequencer = 'http://zkevm-json-rpc:8123'; - const chainID = 1000; - const networkName = 'zkevm'; - const forkID = 0; - const genesisRandom = '0x0000000000000000000000000000000000000000000000000000000000000001'; - const rollupVerifierType = 0; - const description = 'zkevm test'; - const programVKey = '0x0000000000000000000000000000000000000000000000000000000000000000'; - - // Native token will be ether - const gasTokenAddress = ethers.ZeroAddress; - - // deploy validium consensus - const validiumEtrogFactory = await ethers.getContractFactory('PolygonValidiumEtrog'); - const validiumEtrogContract = await validiumEtrogFactory.deploy( - polygonZkEVMGlobalExitRoot.target, - polTokenContract.target, - polygonZkEVMBridgeContract.target, - rollupManagerContract.target, - ); - await validiumEtrogContract.waitForDeployment(); - - // Create new rollup type validium - const newRollupTypeID = 3; - await expect( - rollupManagerContract - .connect(timelock) - .addNewRollupType( - validiumEtrogContract.target, - verifierContract.target, - forkID, - rollupVerifierType, - genesisRandom, - description, - programVKey, - ), - ) - .to.emit(rollupManagerContract, 'AddNewRollupType') - .withArgs( - newRollupTypeID, - validiumEtrogContract.target, - verifierContract.target, - forkID, - rollupVerifierType, - genesisRandom, - description, - programVKey, - ); - - // Create rollup - const newSequencedBatch = 1; - const initializeBytesLegacy = encodeInitializeBytesLegacy( - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName, - ); - const rollupAddress = ethers.getCreateAddress({ - from: rollupManagerContract.target as string, - nonce: 1, - }); - const validiumContract = validiumEtrogFactory.attach(rollupAddress) as PolygonValidiumEtrog; - - await expect( - rollupManagerContract.connect(admin).attachAggchainToAL(newRollupTypeID, chainID, initializeBytesLegacy), - ) - .to.emit(rollupManagerContract, 'CreateNewRollup') - .withArgs(newCreatedRollupID, newRollupTypeID, rollupAddress, chainID, gasTokenAddress) - .to.emit(validiumContract, 'InitialSequenceBatches') - .to.emit(rollupManagerContract, 'OnSequenceBatches') - .withArgs(newCreatedRollupID, newSequencedBatch); - - // Set data availability protocol - // Create PolygonDataCommittee - const PolygonDataCommitteeFactory = await ethers.getContractFactory('PolygonDataCommittee'); - const PolygonDataCommittee = (await upgrades.deployProxy(PolygonDataCommitteeFactory, [], { - unsafeAllow: ['constructor'], - })) as any as PolygonDataCommittee; - await expect(validiumContract.connect(admin).setDataAvailabilityProtocol(PolygonDataCommittee.target)) - .to.emit(validiumContract, 'SetDataAvailabilityProtocol') - .withArgs(PolygonDataCommittee.target); - - // Sequence a batch - const currentTime = Number((await ethers.provider.getBlock('latest'))?.timestamp); - const l1InfoTreeLeafCount = 0; - - const l2txData = '0x123456'; - const hashedData = ethers.keccak256(l2txData) as any; - const sequenceValidium = { - transactionsHash: hashedData, - forcedGlobalExitRoot: ethers.ZeroHash, - forcedTimestamp: 0, - forcedBlockHashL1: ethers.ZeroHash, - } as PolygonValidiumEtrog.ValidiumBatchDataStruct; - - const expectedAccInputHash = calculateAccInputHashEtrog( - await validiumContract.lastAccInputHash(), - hashedData, - await polygonZkEVMGlobalExitRoot.getRoot(), - currentTime, - trustedSequencer.address, - ethers.ZeroHash, - ); - let message = '0x'; - const walletsDataCommittee = [] as any; - for (let i = 0; i < 3; i++) { - const newWallet = ethers.HDNodeWallet.fromMnemonic( - ethers.Mnemonic.fromPhrase('test test test test test test test test test test test junk'), - `m/44'/60'/0'/0/${i}`, - ); - walletsDataCommittee.push(newWallet); - } - // sort wallets - walletsDataCommittee.sort((walleta: any, walletb: any) => { - if (ethers.toBigInt(walleta.address) > ethers.toBigInt(walletb.address)) { - return 1; - } - return -1; - }); - const signedData = expectedAccInputHash; - for (let i = 0; i < walletsDataCommittee.length; i++) { - const newSignature = walletsDataCommittee[i].signingKey.sign(signedData); - message += newSignature.serialized.slice(2); - } - let addrBytes = '0x'; - for (let i = 0; i < walletsDataCommittee.length; i++) { - addrBytes += walletsDataCommittee[i].address.slice(2); - } - const dataAvailabilityMessage = message + addrBytes.slice(2); - - const requiredAmountOfSignatures = 3; - const urls = ['onurl', 'twourl', 'threeurl']; - const committeeHash = ethers.keccak256(addrBytes); - await expect(PolygonDataCommittee.setupCommittee(requiredAmountOfSignatures, urls, addrBytes)) - .to.emit(PolygonDataCommittee, 'CommitteeUpdated') - .withArgs(committeeHash); - - // Approve tokens - const maticAmount = await rollupManagerContract.getBatchFee(); - await expect(polTokenContract.connect(trustedSequencer).approve(validiumContract.target, maticAmount)).to.emit( - polTokenContract, - 'Approval', - ); - await expect( - validiumContract - .connect(trustedSequencer) - .sequenceBatchesValidium( - [sequenceValidium], - l1InfoTreeLeafCount, - currentTime, - expectedAccInputHash, - trustedSequencer.address, - dataAvailabilityMessage, - ), - ).to.emit(validiumContract, 'SequenceBatches'); - - // Call initMigration - - // Verify pending sequenced batches - const pendingState = 0; - const newLocalExitRoot = '0x0000000000000000000000000000000000000000000000000000000000000123'; - const currentVerifiedBatch = 0; - const newVerifiedBatch = newSequencedBatch + 1; - const zkProofFFlonk = new Array(24).fill(ethers.ZeroHash); - await rollupManagerContract - .connect(trustedAggregator) - .verifyBatchesTrustedAggregator( - newCreatedRollupID, - pendingState, - currentVerifiedBatch, - newVerifiedBatch, - newLocalExitRoot, - newStateRoot, - trustedAggregator.address, - zkProofFFlonk, - ); - - const rollupData = await rollupManagerContract.rollupIDToRollupDataV2Deserialized(newCreatedRollupID); - const lastBatchSequenced = rollupData[5]; - const lastBatchVerified = rollupData[6]; - expect(lastBatchSequenced).to.be.equal(lastBatchVerified); - - const aggchainECDSAFactory = await ethers.getContractFactory('AggchainECDSAMultisig'); - const upgradeData = aggchainECDSAFactory.interface.encodeFunctionData('migrateFromLegacyConsensus()'); - - await expect( - rollupManagerContract - .connect(timelock) - .initMigration(newCreatedRollupID, rollupTypeIDAlGateway, upgradeData), - ) - .to.emit(rollupManagerContract, 'InitMigration') - .withArgs(newCreatedRollupID, rollupTypeIDAlGateway) - .to.emit(rollupManagerContract, 'UpdateRollup') - .withArgs(newCreatedRollupID, rollupTypeIDAlGateway, newVerifiedBatch); - - expect(await rollupManagerContract.isRollupMigrating(newCreatedRollupID)).to.be.equal(true); - - // Verify PP with mock "bootstrapBatch" - const lastL1InfoTreeLeafCount = await polygonZkEVMGlobalExitRoot.depositCount(); - const newWrongLER = '0x0000000000000000000000000000000000000000000000000000000000000001'; - const lastLER = rollupData[4]; - const newPPRoot = computeRandomBytes(32); - const proofPP = '0x00'; - const proofWithSelector = `${PESSIMISTIC_SELECTOR}${proofPP.slice(2)}`; - - await expect( - rollupManagerContract - .connect(trustedAggregator) - .verifyPessimisticTrustedAggregator( - newCreatedRollupID, - lastL1InfoTreeLeafCount, - newWrongLER, - newPPRoot, - proofWithSelector, - CUSTOM_DATA_ECDSA, - ), - ).to.be.revertedWithCustomError(rollupManagerContract, 'InvalidNewLocalExitRoot'); - - // // Ensure signers hash initialized (empty) - // await aggchainECDSARollupContract.connect(aggchainManager).updateSignersAndThreshold([], [], 0); - - const prevPP = ethers.ZeroHash; - const prevLER = ethers.ZeroHash; - const lastL1InfoTreeRoot = await polygonZkEVMGlobalExitRoot.l1InfoRootMap(lastL1InfoTreeLeafCount); - await expect( - rollupManagerContract - .connect(trustedAggregator) - .verifyPessimisticTrustedAggregator( - newCreatedRollupID, - lastL1InfoTreeLeafCount, - lastLER, - newPPRoot, - proofWithSelector, - CUSTOM_DATA_ECDSA, - ), - ) - .to.emit(rollupManagerContract, 'CompletedMigration') - .withArgs(newCreatedRollupID) - .to.emit(rollupManagerContract, 'VerifyBatchesTrustedAggregator') - .withArgs(newCreatedRollupID, 0, ethers.ZeroHash, lastLER, trustedAggregator.address) - .to.emit(rollupManagerContract, 'VerifyPessimisticStateTransition') - .withArgs( - newCreatedRollupID, - prevPP, - newPPRoot, - prevLER, - lastLER, - lastL1InfoTreeRoot, - trustedAggregator.address, - ); - - expect(await rollupManagerContract.isRollupMigrating(newCreatedRollupID)).to.be.equal(false); - }); - - /** - * Compute accumulateInputHash = Keccak256(oldAccInputHash, batchHashData, l1InfoTreeRoot, timestamp, seqAddress) - * @param {String} oldAccInputHash - old accumulateInputHash - * @param {String} batchHashData - Batch hash data - * @param {String} globalExitRoot - Global Exit Root - * @param {Number} timestamp - Block timestamp - * @param {String} sequencerAddress - Sequencer address - * @returns {String} - accumulateInputHash in hex encoding - */ - function calculateAccInputHashEtrog( - oldAccInputHash: any, - batchHashData: any, - l1InfoTreeRoot: any, - timestamp: any, - sequencerAddress: any, - forcedBlockHash: any, - ) { - const hashKeccak = ethers.solidityPackedKeccak256( - ['bytes32', 'bytes32', 'bytes32', 'uint64', 'address', 'bytes32'], - [oldAccInputHash, batchHashData, l1InfoTreeRoot, timestamp, sequencerAddress, forcedBlockHash], + /** + * Compute accumulateInputHash = Keccak256(oldAccInputHash, batchHashData, l1InfoTreeRoot, timestamp, seqAddress) + * @param {String} oldAccInputHash - old accumulateInputHash + * @param {String} batchHashData - Batch hash data + * @param {String} globalExitRoot - Global Exit Root + * @param {Number} timestamp - Block timestamp + * @param {String} sequencerAddress - Sequencer address + * @returns {String} - accumulateInputHash in hex encoding + */ + function calculateAccInputHashEtrog( + oldAccInputHash: any, + batchHashData: any, + l1InfoTreeRoot: any, + timestamp: any, + sequencerAddress: any, + forcedBlockHash: any, + ) { + const hashKeccak = ethers.solidityPackedKeccak256( + ['bytes32', 'bytes32', 'bytes32', 'uint64', 'address', 'bytes32'], + [oldAccInputHash, batchHashData, l1InfoTreeRoot, timestamp, sequencerAddress, forcedBlockHash], ); return hashKeccak; } - - function calculateGlobalExitRoot(mainnetExitRoot: any, rollupExitRoot: any) { - return ethers.solidityPackedKeccak256(['bytes32', 'bytes32'], [mainnetExitRoot, rollupExitRoot]); - } - - function calculateGlobalExitRootLeaf(newGlobalExitRoot: any, lastBlockHash: any, timestamp: any) { - return ethers.solidityPackedKeccak256( - ['bytes32', 'bytes32', 'uint64'], - [newGlobalExitRoot, lastBlockHash, timestamp], - ); - } }); diff --git a/test/contractsv2/real-prover-sp1/e2e-verify-proof.test.ts b/test/contractsv2/real-prover-sp1/e2e-verify-proof.test.ts index 468e63e8b..b8a761355 100644 --- a/test/contractsv2/real-prover-sp1/e2e-verify-proof.test.ts +++ b/test/contractsv2/real-prover-sp1/e2e-verify-proof.test.ts @@ -7,33 +7,17 @@ import { AgglayerManagerMock, AgglayerGERMock, AgglayerBridge, - PolygonPessimisticConsensus, PolygonZkEVMEtrog, VerifierRollupHelperMock, AggchainECDSAMultisig, } from '../../../typechain-types'; -import { VerifierType, computeInputPessimisticBytes, computeConsensusHashEcdsa } from '../../../src/pessimistic-utils'; +import { VerifierType } from '../../../src/pessimistic-utils'; import inputProof from './test-inputs/input.json'; import inputZkevmMigration from './test-inputs/input-zkevm-migration.json'; import { encodeInitializeBytesLegacy } from '../../../src/utils-common-aggchain'; -import { - DEFAULT_ADMIN_ROLE, - ADD_ROLLUP_TYPE_ROLE, - OBSOLETE_ROLLUP_TYPE_ROLE, - CREATE_ROLLUP_ROLE, - ADD_EXISTING_ROLLUP_ROLE, - UPDATE_ROLLUP_ROLE, - TRUSTED_AGGREGATOR_ROLE, - TRUSTED_AGGREGATOR_ROLE_ADMIN, - TWEAK_PARAMETERS_ROLE, - SET_FEE_ROLE, - STOP_EMERGENCY_ROLE, - EMERGENCY_COUNCIL_ROLE, - EMERGENCY_COUNCIL_ADMIN, -} from '../../../src/constants'; - -describe('Polygon Rollup Manager with Polygon Pessimistic Consensus', () => { + +describe('Polygon Rollup Manager with zkevm etrog migration to ECDSA Multisig with real prover', () => { let deployer: any; let timelock: any; let emergencyCouncil: any; @@ -47,7 +31,6 @@ describe('Polygon Rollup Manager with Polygon Pessimistic Consensus', () => { let polTokenContract: ERC20PermitMock; let polygonZkEVMGlobalExitRoot: AgglayerGERMock; let rollupManagerContract: AgglayerManagerMock; - let PolygonPPConsensusContract: PolygonPessimisticConsensus; let aggLayerGatewayContract: any; const polTokenName = 'POL Token'; @@ -181,184 +164,6 @@ describe('Polygon Rollup Manager with Polygon Pessimistic Consensus', () => { await polTokenContract.transfer(trustedSequencer, ethers.parseEther('1000')); }); - it('should check the initialized parameters', async () => { - expect(await rollupManagerContract.globalExitRootManager()).to.be.equal(polygonZkEVMGlobalExitRoot.target); - expect(await rollupManagerContract.pol()).to.be.equal(polTokenContract.target); - expect(await rollupManagerContract.bridgeAddress()).to.be.equal(polygonZkEVMBridgeContract.target); - - expect(await rollupManagerContract.getBatchFee()).to.be.equal(ethers.parseEther('0.1')); - expect(await rollupManagerContract.getForcedBatchFee()).to.be.equal(ethers.parseEther('10')); - expect(await rollupManagerContract.calculateRewardPerBatch()).to.be.equal(0); - - // Check roles - expect(await rollupManagerContract.hasRole(DEFAULT_ADMIN_ROLE, timelock.address)).to.be.equal(true); - expect(await rollupManagerContract.hasRole(ADD_ROLLUP_TYPE_ROLE, timelock.address)).to.be.equal(true); - expect(await rollupManagerContract.hasRole(UPDATE_ROLLUP_ROLE, timelock.address)).to.be.equal(true); - expect(await rollupManagerContract.hasRole(ADD_EXISTING_ROLLUP_ROLE, timelock.address)).to.be.equal(true); - - expect(await rollupManagerContract.hasRole(TRUSTED_AGGREGATOR_ROLE, trustedAggregator.address)).to.be.equal( - true, - ); - - expect(await rollupManagerContract.hasRole(OBSOLETE_ROLLUP_TYPE_ROLE, admin.address)).to.be.equal(true); - expect(await rollupManagerContract.hasRole(CREATE_ROLLUP_ROLE, admin.address)).to.be.equal(true); - expect(await rollupManagerContract.hasRole(TRUSTED_AGGREGATOR_ROLE_ADMIN, admin.address)).to.be.equal(true); - expect(await rollupManagerContract.hasRole(TWEAK_PARAMETERS_ROLE, admin.address)).to.be.equal(true); - expect(await rollupManagerContract.hasRole(SET_FEE_ROLE, admin.address)).to.be.equal(true); - expect(await rollupManagerContract.hasRole(STOP_EMERGENCY_ROLE, admin.address)).to.be.equal(true); - - expect(await rollupManagerContract.hasRole(EMERGENCY_COUNCIL_ROLE, emergencyCouncil.address)).to.be.equal(true); - expect(await rollupManagerContract.hasRole(EMERGENCY_COUNCIL_ADMIN, emergencyCouncil.address)).to.be.equal( - true, - ); - }); - - it('should verify pessimistic proof: pessimistic type, with a real verifier (not mock)', async () => { - // deploy consensus - // create polygonPessimisticConsensus implementation - const ppConsensusFactory = await ethers.getContractFactory('PolygonPessimisticConsensus'); - PolygonPPConsensusContract = await ppConsensusFactory.deploy( - polygonZkEVMGlobalExitRoot.target, - polTokenContract.target, - polygonZkEVMBridgeContract.target, - rollupManagerContract.target, - ); - await PolygonPPConsensusContract.waitForDeployment(); - - // Try to add a new rollup type - const forkID = 11; // just metadata for pessimistic consensus - const genesis = ethers.ZeroHash; - const description = 'new pessimistic consensus'; - const programVKey = inputProof.vkey; - const rollupTypeID = 1; - - // correct add new rollup via timelock - await rollupManagerContract - .connect(timelock) - .addNewRollupType( - PolygonPPConsensusContract.target, - verifierContract.target, - forkID, - VerifierType.Pessimistic, - genesis, - description, - programVKey, - ); - - // create new pessimistic: only admin - const chainID = 1; - const gasTokenAddress = ethers.ZeroAddress; - const urlSequencer = 'https://pessimistic:8545'; - const networkName = 'testPessimistic'; - const pessimisticRollupID = inputProof['pp-inputs']['origin-network']; - const initializeBytesAggchain = encodeInitializeBytesLegacy( - admin.address, - trustedSequencer, - gasTokenAddress, - urlSequencer, - networkName, - ); - // create new pessimistic - const newZKEVMAddress = ethers.getCreateAddress({ - from: rollupManagerContract.target as string, - nonce: 1, - }); - - await rollupManagerContract.connect(admin).attachAggchainToAL(rollupTypeID, chainID, initializeBytesAggchain); - - // select not existent global exit root - const l1InfoTreeLeafCount = 2; - const newLER = inputProof['pp-inputs']['new-local-exit-root']; - const newPPRoot = inputProof['pp-inputs']['new-pessimistic-root']; - const proofPP = inputProof.proof; - - // not trusted aggregator - await expect( - rollupManagerContract.verifyPessimisticTrustedAggregator( - pessimisticRollupID, - l1InfoTreeLeafCount, - newLER, - newPPRoot, - proofPP, - '0x', // aggchainData - ), - ).to.be.revertedWithCustomError(rollupManagerContract, 'AddressDoNotHaveRequiredRole'); - - // global exit root does not exist - await expect( - rollupManagerContract.connect(trustedAggregator).verifyPessimisticTrustedAggregator( - pessimisticRollupID, - l1InfoTreeLeafCount, - newLER, - newPPRoot, - proofPP, - '0x', // aggchainData - ), - ).to.be.revertedWithCustomError(rollupManagerContract, 'L1InfoTreeLeafCountInvalid'); - - const l1InfoRoot = inputProof['pp-inputs']['l1-info-root']; - // check JS function computeInputPessimisticBytes - const inputPessimisticBytes = await rollupManagerContract.getInputPessimisticBytes( - pessimisticRollupID, - l1InfoRoot, - inputProof['pp-inputs']['new-local-exit-root'], - inputProof['pp-inputs']['new-pessimistic-root'], - '0x', // aggchainData - ); - - const infoRollup = await rollupManagerContract.rollupIDToRollupDataV2(pessimisticRollupID); - - const consensusHash = computeConsensusHashEcdsa(trustedSequencer); - - const expectedInputPessimisticBytes = computeInputPessimisticBytes( - infoRollup[4], - infoRollup[10], - l1InfoRoot, - pessimisticRollupID, - consensusHash, - newLER, - newPPRoot, - ); - - expect(inputPessimisticBytes).to.be.equal(expectedInputPessimisticBytes); - // Mock selected GER - await polygonZkEVMGlobalExitRoot.injectGER(l1InfoRoot, l1InfoTreeLeafCount); - - // verify pessimistic - await expect( - rollupManagerContract.connect(trustedAggregator).verifyPessimisticTrustedAggregator( - pessimisticRollupID, - l1InfoTreeLeafCount, - newLER, - newPPRoot, - proofPP, - '0x', // aggchainData - ), - ) - .to.emit(rollupManagerContract, 'VerifyBatchesTrustedAggregator') - .withArgs(pessimisticRollupID, 0, ethers.ZeroHash, newLER, trustedAggregator.address); - - // assert rollup data - const resRollupData = await rollupManagerContract.rollupIDToRollupDataV2(pessimisticRollupID); - - const expectedRollupData = [ - newZKEVMAddress, - chainID, - verifierContract.target, - forkID, - newLER, - 0, - 0, - 0, - rollupTypeID, - VerifierType.Pessimistic, - newPPRoot, - programVKey, - ]; - - expect(expectedRollupData).to.be.deep.equal(resRollupData); - }); - it('should create rollup type zkevm etrog & migrate to ECDSA Multisig no bridges sequenced', async () => { // deploy mock verifier for zkEVM rollups const VerifierRollupHelperFactory = await ethers.getContractFactory('VerifierRollupHelperMock');