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

[Update]: deployment tests and update task and documentation #282

Merged
merged 7 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from 5 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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,4 @@ If you believe you've identified a vulnerability in our smart contracts, we enco

Visit our [bounty page](https://immunefi.com/bounty/ssvnetwork/) to get detailed information on the types of vulnerabilities we're interested in, potential reward amounts, and the guidelines for participation.

Please note: Failing to abide by the participation guidelines may result in disqualification from the program and forfeiture of potential rewards.
Please note: Failing to abide by the participation guidelines may result in disqualification from the program and forfeiture of potential rewards.
48 changes: 42 additions & 6 deletions docs/local-dev.md
Original file line number Diff line number Diff line change
@@ -1,55 +1,66 @@
# SSV Network

### [Intro](../README.md) | [Architecture](architecture.md) | [Setup](setup.md) | [Tasks](tasks.md) | Local development | [Roles](roles.md)
### [Intro](../README.md) | [Architecture](architecture.md) | [Setup](setup.md) | [Tasks](tasks.md) | Local development | [Roles](roles.md)

## Running against a local node / testnet

You can deploy and run these contracts in a local node like Hardhat's, Ganache, or public testnets. This guide will cover the process.

### Run [Setup](setup.md)

Execute the steps to set up all tools needed.

### Configure Environment

Copy [.env.example](../.env.example) to `.env` and edit to suit.

- `[NETWORK]_ETH_NODE_URL` RPC URL of the node
- `[NETWORK]_OWNER_PRIVATE_KEY` Private key of the deployer account, without 0x prefix
- `GAS_PRICE` Example 30000000000
- `GAS` Example 8000000
- `ETHERSCAN_KEY` Etherescan API key to verify deployed contracts
- `SSV_TOKEN_ADDRESS` SSV Token contract address to be used in custom networks. Keep it empty to deploy a mocked SSV token.
- `MINIMUM_BLOCKS_BEFORE_LIQUIDATION` A number of blocks before the cluster enters into a liquidatable state. Example: 214800 = 30 days
- `OPERATOR_MAX_FEE_INCREASE` The fee increase limit in percentage with this format: 100% = 10000, 10% = 1000 - using 10000 to represent 2 digit precision
- `OPERATOR_MAX_FEE_INCREASE` The fee increase limit in percentage with this format: 100% = 10000, 10% = 1000 - using 10000 to represent 2 digit precision
- `DECLARE_OPERATOR_FEE_PERIOD` The period in which an operator can declare a fee change (seconds)
- `EXECUTE_OPERATOR_FEE_PERIOD` The period in which an operator fee change can be executed (seconds)
- `VALIDATORS_PER_OPERATOR_LIMIT` The number of validators an operator can manage
- `MINIMUM_LIQUIDATION_COLLATERAL` The lowest number in wei a cluster can have before its liquidatable


#### Network configuration

In [hardhat.config.ts](../hardhat.config.ts) you can find specific configs for different networks, that are taken into account only when the `[NETWORK]_ETH_NODE_URL` parameter in `.env` file is set.
For example, in `.env` file you can set:

```
GOERLI_ETH_NODE_URL="https://goerli.infura.io/v3/..."
GOERLI_OWNER_PRIVATE_KEY="d79d.."
```

That means Hardhat will pick `config.networks.goerli` section in `hardhat.config.ts` to set the network parameters.

### Start the local node

To run the local node, execute the command in a separate terminal.

```sh
npx hardhat node
```

For more details about it and how to use MainNet forking you can find [here](https://hardhat.org/hardhat-network/).

### Deployment

The inital deployment process involves the deployment of all main modules (SSVClusters, SSVOperators, SSVDAO and SSVViews), SSVNetwork and SSVNetworkViews contracts.

Note: The SSV token address used when deploying to live networks (goerli, mainnet) is set in the hardhat config file. To deploy the contracts to a custom network defined in the hardhat config file, leave `SSVTOKEN_ADDRESS` empty in the `.env` file. You can set a specific SSV token address for custom networks too, if needed.

To run the deployment, execute:

```sh
npx hardhat --network <network> deploy:all
```

Output of this action will be:

```sh
Expand All @@ -65,10 +76,13 @@ Deploying SSVNetworkViews with SSVNetwork 0x5FC8...
SSVNetworkViews proxy deployed to: 0xa513...
SSVNetworkViews implementation deployed to: 0x0165...
```
As general rule, you can target any network configured in the `hardhat.config.ts`, specifying the right [network]_ETH_NODE_URL and [network]_OWNER_PRIVATE_KEY in `.env` file.

As general rule, you can target any network configured in the `hardhat.config.ts`, specifying the right [network]\_ETH_NODE_URL and [network]\_OWNER_PRIVATE_KEY in `.env` file.

### Verification on etherscan (only public networks)

You can now go to Etherscan and see:

- `SSVNetwork` proxy contract is deployed to the address shown previously in `SSVNetwork proxy deployed to`
- `SSVNetwork` implementation contract is deployed to the address shown previously in `SSVNetwork implementation deployed to`
- `SSVNetworkViews` proxy contract is deployed to the address shown previously in `SSVNetworkViews proxy deployed to`
Expand All @@ -78,15 +92,26 @@ Open `.openzeppelin/<network>.json` file and find `[impls.<hash>.address]` value
You will find 2 `[impls.<hash>]` entries, one for `SSVNetwork` and another for `SSVNetworkViews`.
Run this verification process for both.

You can take it from the output of the `deploy-all.ts` script.
You can take it from the output of the `npx hardhat --network <network> deploy:all` command.

To verify a proxy contract (SSVNetwork, SSVNetworkViews), run this:

```sh
npx hardhat verify --network <network> <proxy-address>
```

By verifying a contract using its proxy address, the verification process for both the proxy and the implementation contracts is conducted seamlessly.
The proxy contract is automatically linked to the implementation contract.
As a result, users will be able to view interfaces of both the proxy and the implementation contracts on the Etherscan website's contract page, ensuring comprehensive visibility and transparency.

To verify an implementation contract (SSVNetwork, SSVNetworkViews or any module), run this:
To verify a module contract (SSVClusters, SSVOperators, SSVDAO, SSVViews), run this:

```sh
npx hardhat verify --network <network> <implementation-address>
```

Output of this action will be:

```sh
Nothing to compile
No need to generate any newer typings.
Expand All @@ -99,3 +124,14 @@ https://goerli.etherscan.io/address/0x227...#code
```

After this action, you can go to the proxy contract in Etherscan and start interacting with it.

### How to resolve issues during the verification

- Error: no such file or directory, open ‘…/artifacts/build-info/XXXX...XXXX.json’

This issue can be resolved by executing the following commands.

```sh
npx hardhat clean
npx hardhat compile
```
33 changes: 25 additions & 8 deletions docs/tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,62 @@
### [Intro](../README.md) | [Architecture](architecture.md) | [Setup](setup.md) | Tasks | [Local development](local-dev.md) | [Roles](roles.md)

## Development scripts

All scripts can be executed using `package.json` scripts.

### Build the contracts
### Build the contracts

This creates the build artifacts for deployment or testing

```
npm run build
```

### Test the contracts

This builds the contracts and runs the unit tests. It also runs the gas reporter and it outputs the report at the end of the tests.

```
npm run test
```

### Run the code coverage

This builds the contracts and runs the code coverage. This is slower than testing since it makes sure that every line of our contracts is tested. It outputs the report in folder `coverage`.

```
npm run solidity-coverage
```

### Slither

Runs the static analyzer [Slither](https://github.com/crytic/slither), to search for common solidity vulnerabilities. By default it analyzes all contracts.
```npm run slither```
`npm run slither`

### Size contracts

Compiles the contracts and report the size of each one. Useful to check to not surpass the 24k limit.

```
npm run size-contracts
```

## Development tasks

This project uses hardhat tasks to perform the deployment and upgrade of the main contracts and modules.

Following Hardhat's way of working, you must specify the network against which you want to run the task using the `--network` parameter. In all the following examples, the goerli network will be used, but you can specify any defined in your `hardhat.config` file.

### Deploy all contracts

Runs the deployment of the main SSVNetwork and SSVNetworkViews contracts, along with their associated modules:

```
npx hardhat --network goerli_testnet deploy:all
```

When deploying to live networks like Goerli or Mainnet, please double check the environment variables:

- MINIMUM_BLOCKS_BEFORE_LIQUIDATION
- MINIMUM_LIQUIDATION_COLLATERAL
- VALIDATORS_PER_OPERATOR_LIMIT
Expand All @@ -56,12 +67,15 @@ When deploying to live networks like Goerli or Mainnet, please double check the
- OPERATOR_MAX_FEE_INCREASE

## Upgrade process

We use [UUPS Proxy Upgrade pattern](https://docs.openzeppelin.com/contracts/4.x/api/proxy) for `SSVNetwork` and `SSVNetworkViews` contracts to have an ability to upgrade them later.

**Important**: It's critical to not add any state variable to `SSVNetwork` nor `SSVNetworkViews` when upgrading. All the state variables are managed by [SSVStorage](../contracts/libraries/SSVStorage.sol) and [SSVStorageProtocol](../contracts/libraries/SSVStorageProtocol.sol). Only modify the logic part of the main contracts or the modules.

### Upgrade SSVNetwork / SSVNetworkViews

#### Upgrade contract logic

In this case, the upgrade add / delete / modify a function, but no other piece in the system is changed (libraries or modules).

Set `SSVNETWORK_PROXY_ADDRESS` in `.env` file to the right value.
Expand All @@ -73,18 +87,22 @@ Usage: hardhat [GLOBAL OPTIONS] upgrade:proxy [--contract <STRING>] [--init-func

OPTIONS:
--contract New contract upgrade
--init-function Function to be executed after upgrading
--init-function Function to be executed after upgrading
--proxy-address Proxy address of SSVNetwork / SSVNetworkViews

POSITIONAL ARGUMENTS:
params Function parameters
params Function parameters

Example:
npx hardhat --network goerli_testnet upgrade:proxy --proxy-address 0x1234... --contract SSVNetworkV2 --init-function initializev2 param1 param2
```

It is crucial to verify the upgraded contract using its proxy address.
This ensures that users can interact with the correct, upgraded implementation on Etherscan.

### Update a module
Sometimes you only need to perform changes in the logic of a function of a module, add a private function or do something that doesn't affect other components in the architecture. Then you can use the task to update a module.

Sometimes you only need to perform changes in the logic of a function of a module, add a private function or do something that doesn't affect other components in the architecture. Then you can use the task to update a module.

This task first deploys a new version of a specified SSV module contract, and then updates the SSVNetwork contract to use this new module version only if `--attach-module` flag is set to `true`.

Expand All @@ -104,16 +122,17 @@ npx hardhat --network goerli_testnet update:module --module SSVOperators --attac
```

### Upgrade a library

When you change a library that `SSVNetwork` uses, you need to also update all modules where that library is used.

Set `SSVNETWORK_PROXY_ADDRESS` in `.env` file to the right value.

Run the task to upgrade SSVNetwork proxy contract as described in [Upgrade SSVNetwork / SSVNetworkViews](#upgrade-contract-logic)


Run the right script to update the module affected by the library change, as described in [Update a module](#update-a-module) section.

### Manual upgrade of SSVNetwork / SSVNetworkViews

Validates and deploys a new implementation contract. Use this task to prepare an upgrade to be run from an owner address you do not control directly or cannot use from Hardhat.

```
Expand All @@ -129,5 +148,3 @@ npx hardhat --network goerli_testnet upgrade:prepare --proxy-address 0x1234... -
```

The task will return the new implementation address. After that, you can run `upgradeTo` or `upgradeToAndCall` in SSVNetwork / SSVNetworkViews proxy address, providing it as a parameter.


Loading
Loading