Skip to content

Commit

Permalink
upgraded SC
Browse files Browse the repository at this point in the history
  • Loading branch information
invocamanman committed Jun 26, 2023
1 parent 30a1467 commit 96b4acd
Show file tree
Hide file tree
Showing 4 changed files with 308 additions and 0 deletions.
66 changes: 66 additions & 0 deletions contracts/mainnetUpgraded/PolygonZkEVMUpgraded.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// SPDX-License-Identifier: AGPL-3.0
pragma solidity 0.8.17;

import "../PolygonZkEVM.sol";

/**
* Contract responsible for managing the state and the updates of the L2 network
* This contract will NOT BE USED IN PRODUCTION, will be used only in testnet enviroment
*/
contract PolygonZkEVMUpgraded is PolygonZkEVM {
// Indicates the current version
uint256 public version;

// Last batch before the last upgrade, should check it inside the _proofDifferentState function
uint256 public lastBatchBeforeUpgrade;

// Indicates the last version before upgrade
uint256 public immutable VERSION_BEFORE_UPGRADE;

/**
* @param _globalExitRootManager Global exit root manager address
* @param _matic MATIC token address
* @param _rollupVerifier Rollup verifier address
* @param _bridgeAddress Bridge address
* @param _chainID L2 chainID
*/
constructor(
IPolygonZkEVMGlobalExitRoot _globalExitRootManager,
IERC20Upgradeable _matic,
IVerifierRollup _rollupVerifier,
IPolygonZkEVMBridge _bridgeAddress,
uint64 _chainID,
uint64 _forkID,
uint256 versionBeforeUpgrade
)
PolygonZkEVM(
_globalExitRootManager,
_matic,
_rollupVerifier,
_bridgeAddress,
_chainID,
_forkID
)
{
VERSION_BEFORE_UPGRADE = versionBeforeUpgrade;
}

/**
* @dev Thrown when try to update version when it's already updated
*/
error VersionAlreadyUpdated();

/**
* @notice Update version of the zkEVM
* @param _versionString New version string
*/
function updateVersion(string memory _versionString) public {
if (version != VERSION_BEFORE_UPGRADE) {
revert VersionAlreadyUpdated();
}
version++;

lastBatchBeforeUpgrade = lastVerifiedBatch;
emit UpdateZkEVMVersion(lastVerifiedBatch, forkID, _versionString);
}
}
1 change: 1 addition & 0 deletions docker/scripts/deploy-docker.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/bin/bash
sudo rm -rf docker/gethData/geth_data
rm deployment/deploy_ongoing.json
DEV_PERIOD=1 docker-compose -f docker/docker-compose.geth.yml up -d geth
sleep 5
node docker/scripts/fund-accounts.js
Expand Down
40 changes: 40 additions & 0 deletions docs/mainnetUpgraded/PolygonZkEVMUpgraded.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
Contract responsible for managing the state and the updates of the L2 network
This contract will NOT BE USED IN PRODUCTION, will be used only in testnet enviroment


## Functions
### constructor
```solidity
function constructor(
contract IPolygonZkEVMGlobalExitRoot _globalExitRootManager,
contract IERC20Upgradeable _matic,
contract IVerifierRollup _rollupVerifier,
contract IPolygonZkEVMBridge _bridgeAddress,
uint64 _chainID
) public
```


#### Parameters:
| Name | Type | Description |
| :--- | :--- | :------------------------------------------------------------------- |
|`_globalExitRootManager` | contract IPolygonZkEVMGlobalExitRoot | Global exit root manager address
|`_matic` | contract IERC20Upgradeable | MATIC token address
|`_rollupVerifier` | contract IVerifierRollup | Rollup verifier address
|`_bridgeAddress` | contract IPolygonZkEVMBridge | Bridge address
|`_chainID` | uint64 | L2 chainID

### updateVersion
```solidity
function updateVersion(
string _versionString
) public
```
Update version of the zkEVM


#### Parameters:
| Name | Type | Description |
| :--- | :--- | :------------------------------------------------------------------- |
|`_versionString` | string | New version string

201 changes: 201 additions & 0 deletions test/contracts/polygonZkEVMUpgraded.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
/* eslint-disable no-plusplus, no-await-in-loop */
const { expect } = require('chai');
const { ethers, upgrades } = require('hardhat');

describe('PolygonZkEVMUpgraded', () => {
let deployer;
let trustedAggregator;
let trustedSequencer;
let admin;

let verifierContract;
let polygonZkEVMBridgeContract;
let polygonZkEVMContract;
let maticTokenContract;
let polygonZkEVMGlobalExitRoot;

const maticTokenName = 'Matic Token';
const maticTokenSymbol = 'MATIC';
const maticTokenInitialBalance = ethers.utils.parseEther('20000000');

const genesisRoot = '0x0000000000000000000000000000000000000000000000000000000000000001';

const networkIDMainnet = 0;
const urlSequencer = 'http://zkevm-json-rpc:8123';
const chainID = 1000;
const networkName = 'zkevm';
const version = '0.0.1';
const forkID = 0;
const pendingStateTimeoutDefault = 100;
const trustedAggregatorTimeoutDefault = 10;
let firstDeployment = true;
const currentVersion = 0;

beforeEach('Deploy contract', async () => {
upgrades.silenceWarnings();

// load signers
[deployer, trustedAggregator, trustedSequencer, admin] = await ethers.getSigners();

// deploy mock verifier
const VerifierRollupHelperFactory = await ethers.getContractFactory(
'VerifierRollupHelperMock',
);
verifierContract = await VerifierRollupHelperFactory.deploy();

// deploy MATIC
const maticTokenFactory = await ethers.getContractFactory('ERC20PermitMock');
maticTokenContract = await maticTokenFactory.deploy(
maticTokenName,
maticTokenSymbol,
deployer.address,
maticTokenInitialBalance,
);
await maticTokenContract.deployed();

/*
* 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()).address !== '0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0') {
firstDeployment = false;
}
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.utils.getContractAddress({ from: deployer.address, nonce: nonceProxyBridge });
const precalculateZkevmAddress = ethers.utils.getContractAddress({ from: deployer.address, nonce: nonceProxyZkevm });
firstDeployment = false;

const PolygonZkEVMGlobalExitRootFactory = await ethers.getContractFactory('PolygonZkEVMGlobalExitRoot');
polygonZkEVMGlobalExitRoot = await upgrades.deployProxy(PolygonZkEVMGlobalExitRootFactory, [], {
initializer: false,
constructorArgs: [precalculateZkevmAddress, precalculateBridgeAddress],
unsafeAllow: ['constructor', 'state-variable-immutable'],
});

// deploy PolygonZkEVMBridge
const polygonZkEVMBridgeFactory = await ethers.getContractFactory('PolygonZkEVMBridge');
polygonZkEVMBridgeContract = await upgrades.deployProxy(polygonZkEVMBridgeFactory, [], { initializer: false });

// deploy PolygonZkEVMTestnet
const PolygonZkEVMFactory = await ethers.getContractFactory('PolygonZkEVMUpgraded');
polygonZkEVMContract = await upgrades.deployProxy(PolygonZkEVMFactory, [], {
initializer: false,
constructorArgs: [
polygonZkEVMGlobalExitRoot.address,
maticTokenContract.address,
verifierContract.address,
polygonZkEVMBridgeContract.address,
chainID,
forkID,
currentVersion,
],
unsafeAllow: ['constructor', 'state-variable-immutable'],
});

expect(precalculateBridgeAddress).to.be.equal(polygonZkEVMBridgeContract.address);
expect(precalculateZkevmAddress).to.be.equal(polygonZkEVMContract.address);

await polygonZkEVMBridgeContract.initialize(networkIDMainnet, polygonZkEVMGlobalExitRoot.address, polygonZkEVMContract.address);
await polygonZkEVMContract.initialize(
{
admin: admin.address,
trustedSequencer: trustedSequencer.address,
pendingStateTimeout: pendingStateTimeoutDefault,
trustedAggregator: trustedAggregator.address,
trustedAggregatorTimeout: trustedAggregatorTimeoutDefault,
},
genesisRoot,
urlSequencer,
networkName,
version,
);

// fund sequencer address with Matic tokens
await maticTokenContract.transfer(trustedSequencer.address, ethers.utils.parseEther('1000'));
});

it('should check the constructor parameters', async () => {
expect(await polygonZkEVMContract.version()).to.be.equal(0);
});

it('should check updateVersion', async () => {
const newVersionString = '0.0.2';

const lastVerifiedBatch = 0;
await expect(polygonZkEVMContract.updateVersion(newVersionString))
.to.emit(polygonZkEVMContract, 'UpdateZkEVMVersion').withArgs(lastVerifiedBatch, forkID, newVersionString);

expect(await polygonZkEVMContract.version()).to.be.equal(1);

await expect(polygonZkEVMContract.updateVersion(newVersionString))
.to.be.revertedWith('VersionAlreadyUpdated');
});

it('should upgrade polygonKEVM', async () => {
// deploy PolygonZkEVMTestnet
const PolygonZkEVMFactory = await ethers.getContractFactory('PolygonZkEVM');
const oldPolygonZkEVMContract = await upgrades.deployProxy(PolygonZkEVMFactory, [], {
initializer: false,
constructorArgs: [
polygonZkEVMGlobalExitRoot.address,
maticTokenContract.address,
verifierContract.address,
polygonZkEVMBridgeContract.address,
chainID,
forkID,
],
unsafeAllow: ['constructor', 'state-variable-immutable'],
});

// initialize
await oldPolygonZkEVMContract.initialize(
{
admin: admin.address,
trustedSequencer: trustedSequencer.address,
pendingStateTimeout: pendingStateTimeoutDefault,
trustedAggregator: trustedAggregator.address,
trustedAggregatorTimeout: trustedAggregatorTimeoutDefault,
},
genesisRoot,
urlSequencer,
networkName,
version,
);

/*
* Upgrade the contract
*/
const PolygonZkEVMUpgradedFactory = await ethers.getContractFactory('PolygonZkEVMUpgraded');
const polygonZkEVMUpgradedContract = PolygonZkEVMUpgradedFactory.attach(oldPolygonZkEVMContract.address);

// Check that is the v0 contract
await expect(polygonZkEVMUpgradedContract.version()).to.be.reverted;

// Upgrade the contract
const newVersionString = '0.0.2';

await upgrades.upgradeProxy(
polygonZkEVMContract.address,
PolygonZkEVMUpgradedFactory,
{
constructorArgs: [
polygonZkEVMGlobalExitRoot.address,
maticTokenContract.address,
verifierContract.address,
polygonZkEVMBridgeContract.address,
chainID,
forkID,
currentVersion],
unsafeAllow: ['constructor', 'state-variable-immutable'],
call: { fn: 'updateVersion', args: [newVersionString] },
},
);

expect(await polygonZkEVMContract.version()).to.be.equal(1);
await expect(polygonZkEVMContract.updateVersion(newVersionString))
.to.be.revertedWith('VersionAlreadyUpdated');
});
});

0 comments on commit 96b4acd

Please sign in to comment.