Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add upgrades extension in hre #1414

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,18 @@ jobs:
pnpm hardhat run scripts/deploy-factory-uups.ts
pnpm hardhat run scripts/upgrade-factory-beacon.ts
pnpm hardhat run scripts/upgrade-factory-uups.ts
pnpm hardhat run scripts/upgrade-factory.ts

- name: Test upgradable example l1
run: |
cd examples/upgradable-example
pnpm hardhat compile
pnpm hardhat run scripts/deploy-box-beacon.ts
pnpm hardhat run scripts/deploy-box-proxy.ts
pnpm hardhat run scripts/deploy-box-uups.ts
pnpm hardhat run scripts/upgrade-box-beacon.ts
pnpm hardhat run scripts/upgrade-box-uups.ts
pnpm hardhat run scripts/upgrade-box.ts
pnpm hardhat run scripts/upgrade-factory.ts

- name: Test zksync-ethers example
Expand Down
2 changes: 1 addition & 1 deletion examples/basic-example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
},
"dependencies": {
"@matterlabs/hardhat-zksync-deploy": "workspace:^",
"@matterlabs/hardhat-zksync-solc": "^1.2.0",
"@matterlabs/hardhat-zksync-solc": "^1.2.2",
"chalk": "^4.1.2",
"hardhat": "^2.14.0",
"ethers": "~5.7.2",
Expand Down
2 changes: 1 addition & 1 deletion examples/deploy-example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
},
"dependencies": {
"@matterlabs/hardhat-zksync-deploy": "workspace:^",
"@matterlabs/hardhat-zksync-solc": "^1.2.0",
"@matterlabs/hardhat-zksync-solc": "^1.2.2",
"chalk": "^4.1.2",
"hardhat": "^2.14.0",
"ethers": "~5.7.2",
Expand Down
7 changes: 7 additions & 0 deletions examples/upgradable-example-l1/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
extends: [`${__dirname}/../../config/eslint/eslintrc.cjs`],
parserOptions: {
project: `${__dirname}/tsconfig.json`,
sourceType: "module",
},
};
67 changes: 67 additions & 0 deletions examples/upgradable-example-l1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# zkSync Era upgradable example

This project demonstrates how to compile and deploy upgadable smart contracts in zkSync Era using the Hardhat plugins.

## Prerequisites

- node.js 14.x or later.
- yarn.

## Configuration

Plugin configuration is located in [`hardhat.config.ts`](./hardhat.config.ts).
You should only change the zkSync network configuration.

`hardhat.config.ts` example with zkSync network configured with the name `zkTestnet` and `sepolia` used as the underlying layer 1 network:
```ts
import '@matterlabs/hardhat-zksync-solc';
import '@matterlabs/hardhat-zksync-deploy';
import '@matterlabs/hardhat-zksync-upgradable';

import { HardhatUserConfig } from 'hardhat/types';

const config: HardhatUserConfig = {
networks: {
sepolia: {
url: 'https://rpc.ankr.com/eth_sepolia' // you can use either the URL of the Ethereum Web3 RPC, or the identifier of the network (e.g. `mainnet` or `rinkeby`)
},
zkTestnet: {
url: 'https://sepolia.era.zksync.dev', // you should use the URL of the zkSync network RPC
ethNetwork: 'sepolia',
zksync: true
},
}
};

export default config;
```

If you don't specify zkSync network (`--network`), `local-setup` with <http://localhost:8545> (Ethereum RPC URL) and <http://localhost:3050> (zkSync RPC URL) will be used.

## Usage

Before using plugins, you need to build them first

```sh
# Run the following in the *root* of the repo.
yarn
yarn build
```

After that you should be able to run plugins:

```sh
# Run the following in `examples/upgradable-example` folder.
yarn
yarn hardhat compile
```

- `yarn hardhat compile`: compiles all the contracts in the `contracts` folder.

To run a specific end-to-end script in the `scripts` folder, use the following command

```
yarn hardhad run ./scipts/<SCRIPT_NAME>
```

- Example: `yarn hardhat run ./scripts/deploy-box-proxy.ts`
27 changes: 27 additions & 0 deletions examples/upgradable-example-l1/contracts/Box.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

contract Box is Initializable {
uint256 private value;
uint256 private secondValue;
uint256 private thirdValue;

function initialize(uint256 initValue) public initializer {
value = initValue;
}

// Reads the last stored value
function retrieve() public view returns (uint256) {
return value;
}

// Stores a new value in the contract
function store(uint256 newValue) public {
value = newValue;
emit ValueChanged(newValue);
}
// Emitted when the stored value changes
event ValueChanged(uint256 newValue);
}
33 changes: 33 additions & 0 deletions examples/upgradable-example-l1/contracts/BoxUups.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
import '@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol';
import '@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';

contract BoxUups is Initializable, UUPSUpgradeable, OwnableUpgradeable {
uint256 private value;
uint256 private secondValue;
uint256 private thirdValue;

function initialize(uint256 initValue) public initializer {
value = initValue;
__Ownable_init();
__UUPSUpgradeable_init();
}

// Reads the last stored value
function retrieve() public view returns (uint256) {
return value;
}

// Stores a new value in the contract
function store(uint256 newValue) public {
value = newValue;
emit ValueChanged(newValue);
}

function _authorizeUpgrade(address) internal override onlyOwner {}

// Emitted when the stored value changes
event ValueChanged(uint256 newValue);
}
54 changes: 54 additions & 0 deletions examples/upgradable-example-l1/contracts/BoxUupsV2.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
import '@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol';
import '@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';

contract BoxUupsV2 is Initializable, UUPSUpgradeable, OwnableUpgradeable {
uint256 private value;
uint256 private secondValue;
uint256 private thirdValue;

function initialize(uint256 initValue) public initializer {
value = initValue;
}

// Reads the last stored value and returns it with a prefix
function retrieve() public view returns (string memory) {
return string(abi.encodePacked('V2: ', uint2str(value)));
}

// Converts a uint to a string
function uint2str(uint _i) internal pure returns (string memory) {
if (_i == 0) {
return '0';
}
uint j = _i;
uint len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint k = len;
while (_i != 0) {
k = k - 1;
uint8 temp = (48 + uint8(_i - (_i / 10) * 10));
bytes1 b1 = bytes1(temp);
bstr[k] = b1;
_i /= 10;
}
return string(bstr);
}

// Stores a new value in the contract
function store(uint256 newValue) public {
value = newValue;
emit ValueChanged(newValue);
}

function _authorizeUpgrade(address) internal override onlyOwner {}

// Emitted when the stored value changes
event ValueChanged(uint256 newValue);
}
51 changes: 51 additions & 0 deletions examples/upgradable-example-l1/contracts/BoxV2.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

contract BoxV2 is Initializable{
uint256 private value;
uint256 private secondValue;
uint256 private thirdValue;

// Emitted when the stored value changes
event ValueChanged(uint256 newValue);

function initialize(uint256 initValue) public initializer {
value = initValue;
}

// Stores a new value in the contract
function store(uint256 newValue) public {
value = newValue;
emit ValueChanged(newValue);
}

// Reads the last stored value and returns it with a prefix
function retrieve() public view returns (string memory) {
return string(abi.encodePacked("V2: ", uint2str(value)));
}

// Converts a uint to a string
function uint2str(uint _i) internal pure returns (string memory) {
if (_i == 0) {
return "0";
}
uint j = _i;
uint len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint k = len;
while (_i != 0) {
k = k - 1;
uint8 temp = (48 + uint8(_i - (_i / 10) * 10));
bytes1 b1 = bytes1(temp);
bstr[k] = b1;
_i /= 10;
}
return string(bstr);
}
}
5 changes: 5 additions & 0 deletions examples/upgradable-example-l1/contracts/Empty.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract EmptyContract {
}
21 changes: 21 additions & 0 deletions examples/upgradable-example-l1/contracts/Factory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./Empty.sol";

contract Factory {
address[] public deployedContracts;

function initialize() public{
deployEmptyContract();
}

function deployEmptyContract() public {
EmptyContract newContract = new EmptyContract();
deployedContracts.push(address(newContract));
}

function getNumberOfDeployedContracts() public view returns (uint) {
return deployedContracts.length;
}
}
33 changes: 33 additions & 0 deletions examples/upgradable-example-l1/contracts/FactoryUups.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import '@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol';
import "./Empty.sol";


contract FactoryUups is Initializable, UUPSUpgradeable, OwnableUpgradeable {
address[] public deployedContracts;

function initialize() public initializer{
__Ownable_init();
__UUPSUpgradeable_init();
deployEmptyContract();
}

function deployEmptyContract() public {
EmptyContract newContract = new EmptyContract();
deployedContracts.push(address(newContract));
}

function getNumberOfDeployedContracts() public view returns (uint) {
return deployedContracts.length;
}

function storeNothing() public pure {

}

function _authorizeUpgrade(address) internal override onlyOwner {}
}
Loading
Loading