Skip to content

Commit

Permalink
[Feat] 191 improve documentation (#316)
Browse files Browse the repository at this point in the history
* initial changes for the contract readme

* testing guidelines wip

* add contract documentation

* add note on future deprecation

* add memory and CPU requirements for docker

* add audit references to documentation

* use tokenbridge make commands in documentation

* add additional comments to testing guidelines

* define contract style guide and link it

* address PR comments with better documentation

* document tweaks and traffic generation script

* catch error on failure of main()

* add precompute script and readme documentation

* use ethers address generation

---------

Co-authored-by: count-sum <andrei.alexandru@consensys.net>
  • Loading branch information
thedarkjester and count-sum authored Nov 22, 2024
1 parent 86616e6 commit 98291b5
Show file tree
Hide file tree
Showing 8 changed files with 428 additions and 37 deletions.
5 changes: 1 addition & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,6 @@ restart-shomei:
rm -rf tmp/local/shomei/*
docker compose -f docker/compose.yml -f docker/compose-local-dev.overrides.yml up zkbesu-shomei shomei -d

fresh-start-all-smc-v4:
make clean-environment
make start-all-smc-v4

fresh-start-all:
make clean-environment
make start-all
Expand All @@ -182,6 +178,7 @@ start-all:
start-all-traces-v2:
L1_GENESIS_TIME=$(get_future_time) make start-whole-environment-traces-v2
make deploy-contracts

deploy-contracts:
cd contracts/; \
export L1_NONCE=$$(npx ts-node local-deployments-artifacts/get-wallet-nonce.ts --wallet-priv-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --rpc-url http://localhost:8445) && \
Expand Down
154 changes: 121 additions & 33 deletions contracts/README.md
Original file line number Diff line number Diff line change
@@ -1,66 +1,154 @@
Readme.md
# Smart Contracts

# Smart Contract
Contains Ethereum smart contract code for the Linea Rollup and Message Service.

Contains Ethereum smart contract code for ConsenSys Rollups.
## LineaRollup (L1MessageService)
The Linea Rollup, which contains the L1MessageService, is the smart contract that is responsible for:

- Submitting messages to be sent to Linea (L2) for later claiming.
- Anchoring of L2 message Merkle roots to allow later claiming.
- Claiming of messages sent from L2 to Ethereum mainnet (L1).
- Submission of L2 compressed data using EIP-4844 blobs or via calldata.
- Finalization of L2 state on L1 using a Zero Knowledge Proof.

## L2MessageService
The L2MessageService is the L2 smart contract that is responsible for:

- Submitting messages to be sent to L1 for later claiming.
- Anchoring of L1 to L2 Message hashes for later claiming.
- Claiming of messages sent from L1 to L2.

## Linea Canonical Token Bridge

The Canonical Token Bridge (TokenBridge) is a canonical ERC20 token brige between Ethereum and Linea networks.

The TokenBridge utilises the L1MessageService and the L2MessageService for the transmission of messages between each layer's TokenBridge.

Documentation: [Token Bridge](./docs/linea-token-bridge.md)

# Style Guide
Please see the [Smart Contract Style Guide](./docs/contract-style-guide.md) for in depth smart contract layout and styling.

# Audit reports
Please see [Audits](./docs/audits.md) for a historical list of all the smart contract audits.

# Development & Testing

This project uses following libraries
Please see [Testing guidelines](./test/README.md) for in depth testing layout and styling.

This project uses the following libraries
- [PNPM](https://pnpm.io/) as the Package Manager
- [Ethers](https://github.com/ethers-io/ethers.js/) as Ethereum library
- [Hardhat](https://hardhat.org/getting-started/) as development environment
- [Chai](https://www.chaijs.com/) for assertions
- [GoLang](https://go.dev/) for the compilation of code to autogenerate data for L2 data and proofs (not strictly required)
- [Docker](https://www.docker.com/) for the local stack to run in

If you already have an understanding of the tech stack, use our [Get Started](../docs/get-started.md) guide.

To run the tests:

## Testing without coverage

```bash
make test
cd contracts # from the root folder
pnpm install
npx hardhat test
```

# Useful scripts

Most of the scripts need to know address of Ethereum RPC. This is controlled via `BLOCKCHAIN_NODE` environment variable,

for example run this before all the scripts in the same terminal:
## Testing with coverage

```bash
export BLOCKCHAIN_NODE=http://localhost:5000
cd contracts # from the root folder
pnpm install

npx hardhat coverage
```
## Deploying the contracts to the local stack
Prerequisites:
- Be sure Docker is running.

## Balance of ERC 20 token
Some caveats:
- The L2 chain will not produce empty blocks if there are no transactions, so it would be useful to execute a script to keep the chain "moving".
- The following script can be run with the expectation the local stack is running: [generateL2Traffic.ts](../e2e/src/common/generateL2Traffic.ts)
- To execute it run the following from the `e2e` folder: `npx ts-node src/common/generateL2Traffic.ts`
- For blob submission and finalization, there needs to be sufficient blocks to trigger it. Keeping the chain moving on L2 is vital for this to take place.

From the root of the repository:

Please read the MakeFile: [MakeFile](../Makefile)

```
export BLOCKCHAIN_NODE="http://localhost:8545"
ts-node scripts/balanceOf.ts \
data/rollup.json \
../node-data/test/keys/eth_account_3.acc \
1 \
../node-data/test/keys/eth_account_3.acc \
../node-data/test/keys/eth_account_4.acc \
../node-data/test/keys/eth_account_5.acc
# This will deploy all the relevant services and smart contracts
make fresh-start-all-traces-v2
```

### To deploy ZkEvm to local docker compose
### To deploy all the contracts

If the stack is *already running*, to redeploy the contracts, the following commands can be used:

Run in ./contracts with running docker-compose stack.
Note: The addresses change per deployment due to nonce increments, so be sure to validate the correct ones are being used.

```shell
sed "s/BLOCKCHAIN_NODE=.*/BLOCKCHAIN_NODE=http:\/\/localhost:8445/" .env.template > .env
npx hardhat run ./scripts/deployment/deployZkEVM.ts --network zkevm_dev
**NB:** The end to end tests run against a fresh stack and deploy with predetermined addresses.

If there is a need to get predetermined addresses for contract deployments, the following script can be used [precomputeDeployedAddresses.ts](./scripts/operational/precomputeDeployedAddress.ts).

This can be used by altering the values in the script file and running the script (from the `/contracts` folder) with: `npx ts-node scripts/operational/precomputeDeployedAddress.ts`

*Note the following nonce values for a fresh stack deploy:*

The LineaRollup deploy uses nonce 3 as the following are deployed beforehand:
- The verifier contract
- The implementation LineaRollup.sol contract
- The proxy admin contract

The L2MessageService deploy uses nonce 2 as the following are deployed beforehand:
- The implementation L2MessageService.sol contract
- The proxy admin contract


**Deploying the L1 contracts**
```
# This will deploy the Linea Rollup that is currently deployed on Mainnet - the current version is the LineaRollupV5.
# Some end to end tests will test future upgrades to validate the stack remains functional.
# Note: By default a test/placeholder verifier contract is used `IntegrationTestTrueVerifier` if you wish to use a proper verifier, adjust the
# PLONKVERIFIER_NAME=IntegrationTestTrueVerifier in the make command to be something like PLONKVERIFIER_NAME=PlonkVerifierForDataAggregation .
# Be sure to check the parameter values in the Makefile before executing the command.
### To deploy ZkEvm to local docker compose
# Deploy v5
make deploy-linea-rollup-v5
Run in ./contracts with running docker-compose stack.
# Or deploy v6
make deploy-linea-rollup-v6
```shell
sed "s/BLOCKCHAIN_NODE=.*/BLOCKCHAIN_NODE=http:\/\/localhost:8445/" .env.template > .env
npx hardhat run ./scripts/deployment/deployZkEVM.ts --network zkevm_dev
make deploy-token-bridge-l1
```

**Deploying the L2 contracts**
```
# This will deploy the current L2 Message Service.
# Some end to end tests will test future upgrades to validate the stack remains functional.
make deploy-l2messageservice
make deploy-token-bridge-l2
```

**Deploying L1 and L2 together**
```
make deploy-contracts
```

## Linea Token Bridge
The above command will trigger the following commands to deploy:

Token Bridge is a canonical brige between Ethereum and Linea networks.
- deploy-linea-rollup-v5
- deploy-token-bridge-l1
- deploy-l1-test-erc20
- deploy-l2messageservice
- deploy-token-bridge-l2
- deploy-l2-test-erc20

Documentation: [./docs/linea-token-bridge.md](./docs/linea-token-bridge.md)
Note: the deploy-l1-test-erc20 and deploy-l1-test-erc20 commands are executed for use in the end to end tests.
56 changes: 56 additions & 0 deletions contracts/docs/audits.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Audits
## Fourth Audit Round (Latest)
**Diligence**
- Differential audit since second audit round: https://consensys.io/diligence/audits/2024/07/linea-rollup-update/

**Open Zeppelin**
- Gas optimization audit: https://blog.openzeppelin.com/linea-gas-optimizations-audit

**Cyfrin**
- Full codebase audit including gas optimizations and TokenBridge updates: https://github.com/Cyfrin/cyfrin-audit-reports/blob/main/reports/2024-05-24-cyfrin-linea-v2.0.pdf

## Third Audit Round
**Open Zeppelin**

- Blob submission audit: https://blog.openzeppelin.com/linea-blob-submission-audit

## Second Audit Round

**Diligence**
- Proof aggregation, data compression and message service updates Audit: https://consensys.io/diligence/audits/2024/01/linea-contracts-update/

**Open Zeppelin**

- Proof aggregation, data compression and message service updates Audit: https://blog.openzeppelin.com/linea-v2-audit

## First Audit Round

**Diligence**

- Plonk Verifier: https://consensys.io/diligence/audits/2023/06/linea-plonk-verifier/
- Message Service & Rollup: https://consensys.io/diligence/audits/2023/06/linea-message-service/
- Canonical Token Bridge: https://consensys.io/diligence/audits/2023/06/linea-canonical-token-bridge/

**Open Zeppelin**

- Linea Bridge Audit: https://blog.openzeppelin.com/linea-bridge-audit-1
- Linea Verifier Audit: https://blog.openzeppelin.com/linea-verifier-audit-1



---

## Installation and testing

To run the solution's tests, coverage and gas reporting, be sure to install pnpm and then
```
# Install all the dependencies
pnpm install
pnpm run test
pnpm run test:reportgas
pnpm run coverage
```
110 changes: 110 additions & 0 deletions contracts/docs/contract-style-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Smart Contract Style Guide

The following document serves as the expected style guide for the Linea smart contracts:

## Licenses
- All interfaces will use `// SPDX-License-Identifier: Apache-2.0` for others to potentially consume
- All contracts other than specific ones will use `// SPDX-License-Identifier: AGPL-3.0`

## Imports
All imports should be in the format of:
```
import { ImportType } from "../ImportType.sol";
```

## NatSpec
Contracts and interfaces will use the [NatSpec](https://docs.soliditylang.org/en/develop/natspec-format.html) formatting.

**Note:** Interfaces and their implementations have duplicated NatSpec because consumers might just use the interface, and block explorers might use either the interface or implementation for the documentation. The documentation should always be available.

- use `DEPRECATED` in the NatSpec for deprecated variables, errors, events and functions if they need to remain

## Visibility
- CONSTANTS should be internal unless there is an explicit reason for it to be public
- External and public functions should be limited
- If there is a function calling itself using `this.` or a function is made public to do this, reconsider the design and refactor.

## Naming
- Public state variables are `camelCase`
- Internal and private state variables are `_camelCase` starting with the `_`
- Mappings contain key and value descriptors e.g. `mapping(uint256 id=>bytes32 messageHash)`
- CONSTANTS are all in upper case separated by `_` e.g. `DEFAULT_MESSAGE_STATUS`
- Public and External function names are `camelCase` - e.g. `function hashMessage(uint256 _messageNumber) external {}`
- Internal and Private function names are `_camelCase` starting with the `_` - e.g. `function _calculateY() internal`
- All function parameters start with an `_` e.g. `function hashMessage(uint256 _messageNumber) external {}`
- Return variables should be named and are `camelCase`
- Inherited contract initialization functions should be named `__ContractName_init`. e.g. `__PauseManager_init`

## General
- Avoid magic numbers by using constants
- Name variables so that their intent is easy to understand
- In assembly memory mappings use hexidecimal values for memory offsets - e.g `mstore(add(mPtr, 0x20), _varName)`

## Linting
Be sure to run `pnpm run lint:fix` in the contracts folder or `pnpm run -F contracts lint:fix` from the repository root.

## File layout
### Interface Structure
All interfaces should be laid out in the following format from top to bottom:

```
// SPDX-License-Identifier: Apache-2.0
pragma solidity >=0.8.19 <=0.8.26;
// imports here
import { ImportType } from "../ImportType.sol";
/**
* @title Title explaining interface contents.
* @author Author here.
* @custom:security-contact security-report@linea.build
*/
interface ISampleContract {
// All items have NatSpec
// 1. Structs
// 2. Enums
// 3. Events with NatSpec (including parameters)
// 4. Errors with NatSpec explaining when thrown
// 5. External Functions
}
```

### Library Structure
All libraries should be laid out in the following format from top to bottom:

```
// SPDX-License-Identifier: AGPL-3.0
pragma solidity >=0.8.19 <=0.8.26;
// imports here
import { ImportType } from "../ImportType.sol";
library SampleLibrary {
// All items have NatSpec
// 1. CONSTANTS (Public, internal and then private)
// 2. Structs
// 3. Enums
// 4. Events with NatSpec (including parameters)
// 5. Errors with NatSpec explaining when thrown
// 6. Modifiers
// 7. Functions (Public, external, internal and then private)
}
```

### Contract Structure

All contracts should be laid out in the following format from top to bottom:

```
// SPDX-License-Identifier: AGPL-3.0
pragma solidity >=0.8.19 <=0.8.26;
contract SampleContract {
// All items have NatSpec
// 1. CONSTANTS (Public, internal and then private)
// 2. Structs
// 3. Enums
// 4. Events with NatSpec (including parameters)
// 5. Errors with NatSpec explaining when thrown
// 6. Modifiers
// 7. Functions (Public, external, internal and then private)
}
```
7 changes: 7 additions & 0 deletions contracts/scripts/operational/precomputeDeployedAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { ethers } from "ethers";

const from = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; // Replace with your deployer address
const nonce = 3; // Replace with the actual nonce
const computedAddress = ethers.getCreateAddress({ from, nonce });

console.log("Computed Address:", computedAddress);
Loading

0 comments on commit 98291b5

Please sign in to comment.