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

Add create2 factory router #1

Merged
merged 21 commits into from
Oct 16, 2024
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
35 changes: 25 additions & 10 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,11 +1,26 @@
export API_KEY_ALCHEMY="YOUR_API_KEY_ALCHEMY"
export API_KEY_ARBISCAN="YOUR_API_KEY_ARBISCAN"
export API_KEY_BSCSCAN="YOUR_API_KEY_BSCSCAN"
export API_KEY_ETHERSCAN="YOUR_API_KEY_ETHERSCAN"
export API_KEY_GNOSISSCAN="YOUR_API_KEY_GNOSISSCAN"
export API_KEY_INFURA="YOUR_API_KEY_INFURA"
export API_KEY_OPTIMISTIC_ETHERSCAN="YOUR_API_KEY_OPTIMISTIC_ETHERSCAN"
export API_KEY_POLYGONSCAN="YOUR_API_KEY_POLYGONSCAN"
export API_KEY_SNOWTRACE="YOUR_API_KEY_SNOWTRACE"
export MNEMONIC="YOUR_MNEMONIC"
export FOUNDRY_PROFILE="default"

export CREATEX_ADDRESS="the address of a CreateX present on all the chain you going to deploy"
export NETWORK="network where the script is run"
export API_KEY_ALCHEMY="YOUR_API_KEY_ALCHEMY"

# DeployRouter
export ETHERSCAN_API_KEY="your etherscar or whateverscarn api key"
export DEPLOYER_PK="your deployer private key"
export ISM_SALT="salt for deploying ISM"
export MAILBOX="local mailbox address"
export PROXY_ADMIN="address of the proxy admin"
export ROUTER_OWNER="address of the router owner"
export ROUTER_IMPLEMENTATION="optional address of the router implementation, if not provided it will be deployed"
export ISM="optional address of the ISM, if not provided it will be deployed"
export CUSTOM_HOOK="optional address of the ISM, if not provided ZERO ADDRESS is used and messages will use the mailbox default hook"

# EnrollRouters
export ROUTER_OWNER_PK="router owner private key"
export ROUTERS="addresses of the routers to enroll, separated by commas"
export DOMAINS="domains of the routers to enroll, separated by commas"
export ROUTER="address of the local router"

# Deploy Example
export DESTINATION="network id where the example contract will be deployed"
export EXAMPLE_SALT="a salt for deployng the example contract on destination network"
32 changes: 19 additions & 13 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@ jobs:
- name: "Install Foundry"
uses: "foundry-rs/foundry-toolchain@v1"

- name: "Install Bun"
uses: "oven-sh/setup-bun@v1"
- name: Set Node.js
uses: actions/setup-node@v3

- name: "Install the Node.js dependencies"
run: "bun install"
- name: Run install
uses: borales/actions-yarn@v4
with:
cmd: install # will run `yarn install` command

- name: "Lint the code"
run: "bun run lint"
run: "yarn lint"

- name: "Add lint summary"
run: |
Expand All @@ -44,11 +46,13 @@ jobs:
- name: "Install Foundry"
uses: "foundry-rs/foundry-toolchain@v1"

- name: "Install Bun"
uses: "oven-sh/setup-bun@v1"
- name: Set Node.js
uses: actions/setup-node@v3

- name: "Install the Node.js dependencies"
run: "bun install"
- name: Run install
uses: borales/actions-yarn@v4
with:
cmd: install # will run `yarn install` command

- name: "Build the contracts and print their size"
run: "forge build --sizes"
Expand All @@ -68,11 +72,13 @@ jobs:
- name: "Install Foundry"
uses: "foundry-rs/foundry-toolchain@v1"

- name: "Install Bun"
uses: "oven-sh/setup-bun@v1"
- name: Set Node.js
uses: actions/setup-node@v3

- name: "Install the Node.js dependencies"
run: "bun install"
- name: Run install
uses: borales/actions-yarn@v4
with:
cmd: install # will run `yarn install` command

- name: "Show the Foundry config"
run: "forge config"
Expand Down
52 changes: 0 additions & 52 deletions .github/workflows/use-template.yml

This file was deleted.

1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ out
lcov.info
package-lock.json
pnpm-lock.yaml
yarn.lock

# broadcasts
!broadcast
Expand Down
130 changes: 36 additions & 94 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,79 +1,50 @@
# Foundry Template [![Open in Gitpod][gitpod-badge]][gitpod] [![Github Actions][gha-badge]][gha] [![Foundry][foundry-badge]][foundry] [![License: MIT][license-badge]][license]
# Hyperlane InterchainCreate2FactoryRouter

[gitpod]: https://gitpod.io/#https://github.com/BootNodeDev/hyperlane-create2-factory-router
[gitpod-badge]: https://img.shields.io/badge/Gitpod-Open%20in%20Gitpod-FFB45B?logo=gitpod
[gha]: https://github.com/BootNodeDev/hyperlane-create2-factory-router/actions
[gha-badge]: https://github.com/BootNodeDev/hyperlane-create2-factory-router/actions/workflows/ci.yml/badge.svg
[foundry]: https://getfoundry.sh/
[foundry-badge]: https://img.shields.io/badge/Built%20with-Foundry-FFDB1C.svg
[license]: https://opensource.org/licenses/MIT
[license-badge]: https://img.shields.io/badge/License-MIT-blue.svg
This repo contains a possible solution for https://github.com/hyperlane-xyz/hyperlane-monorepo/issues/2232.

A Foundry-based template for developing Solidity smart contracts, with sensible defaults.
The `InterchainCreate2FactoryRouter` would allow to deploy a contract on any given chain Hyperlane and the router are
deployed from another chain with the same conditions. This allows developers to just have a balance on one chain but
deploy contracts on multiple chains.

## What's Inside
## Deploy the router

- [Forge](https://github.com/foundry-rs/foundry/blob/master/forge): compile, test, fuzz, format, and deploy smart
contracts
- [Forge Std](https://github.com/foundry-rs/forge-std): collection of helpful contracts and utilities for testing
- [Prettier](https://github.com/prettier/prettier): code formatter for non-Solidity files
- [Solhint](https://github.com/protofire/solhint): linter for Solidity code
- Run `yarn install` to install all the dependencies
- Create a `.env` file base on the [.env.example file](./.env.example) file, and set the required variables depending
which script you are going to run.

## Getting Started
Set the following environment variables required for running all the scripts, on each network.

Click the [`Use this template`](https://github.com/PaulRBerg/foundry-template/generate) button at the top of the page to
create a new repository with this repo as the initial state.
- `NETWORK`: the name of the network you want to run the script
- `API_KEY_ALCHEMY`: you Alchemy API key

Or, if you prefer to install the template manually:
If the network is not listed under the `rpc_endpoints` section of the [foundry.toml file](./foundry.toml) you'll have to
add a new entry for it.

```sh
$ mkdir my-project
$ cd my-project
$ forge init --template PaulRBerg/foundry-template
$ bun install # install Solhint, Prettier, and other Node.js deps
```

If this is your first time with Foundry, check out the
[installation](https://github.com/foundry-rs/foundry#installation) instructions.

## Features

This template builds upon the frameworks and libraries mentioned above, so please consult their respective documentation
for details about their specific features.

For example, if you're interested in exploring Foundry in more detail, you should look at the
[Foundry Book](https://book.getfoundry.sh/). In particular, you may be interested in reading the
[Writing Tests](https://book.getfoundry.sh/forge/writing-tests.html) tutorial.
For deploying the router you have to run the `yarn run:deployRouter`. Make sure the following environment variable are
set:

### Sensible Defaults
- `DEPLOYER_PK`: deployer private key
- `MAILBOX`: address of Hyperlane Mailbox contract on the chain
- `ROUTER_OWNER`: address of the router owner
- `PROXY_ADMIN`: address of the proxy admin. The router is deployed using a `TransparentUpgradeableProxy`
- `ISM_SALT`: a salt for deploying the ISM the router uses. The provided in this repo is an `RoutingIsm` which allows
the user indicate the ISM used when sending the message
- `ROUTER_IMPLEMENTATION`: the address of an existing implementation in the network
- `ISM`: the address of an existing implementation in the network
- `CUSTOM_HOOK`: some custom hook address to be set, address zero indicates the Mailbox default hook should be used

This template comes with a set of sensible default configurations for you to use. These defaults can be found in the
following files:
For enrolling routers you have to run `yarn run:enrollRouters`. Make sure the following environment variable are set:

```text
├── .editorconfig
├── .gitignore
├── .prettierignore
├── .prettierrc.yml
├── .solhint.json
├── foundry.toml
└── remappings.txt
```

### VSCode Integration

This template is IDE agnostic, but for the best user experience, you may want to use it in VSCode alongside Nomic
Foundation's [Solidity extension](https://marketplace.visualstudio.com/items?itemName=NomicFoundation.hardhat-solidity).
- `ROUTER_OWNER_PK`: the router's owner private key. Only the owner can enroll routers
- `ROUTER`: address of the local router
- `ROUTERS`: a list of routes addresses, separated by commas
- `DOMAINS`: the domains list of the routers to enroll, separated by commas

For guidance on how to integrate a Foundry project in VSCode, please refer to this
[guide](https://book.getfoundry.sh/config/vscode).
## Example usage

### GitHub Actions

This template comes with GitHub Actions pre-configured. Your contracts will be linted and tested on every push and pull
request made to the `main` branch.

You can edit the CI script in [.github/workflows/ci.yml](./.github/workflows/ci.yml).
Running the example script `yarn run:interchainDeploy` would deploy a
[TestDeployContract](./script/utils/TestDeployContract.sol) from the chain you set on `NETWORK` to the one you set on
`DESTINATION_NETWORK` using the router set on `ROUTER` and the salt on `EXAMPLE_SALT`

## Installing Dependencies

Expand All @@ -82,22 +53,13 @@ Foundry typically uses git submodules to manage dependencies, but this template

This is how to install dependencies:

1. Install the dependency using your preferred package manager, e.g. `bun install dependency-name`
- Use this syntax to install from GitHub: `bun install github:username/repo-name`
1. Install the dependency using your preferred package manager, e.g. `yarn install dependency-name`
- Use this syntax to install from GitHub: `yarn install github:username/repo-name`
2. Add a remapping for the dependency in [remappings.txt](./remappings.txt), e.g.
`dependency-name=node_modules/dependency-name`

Note that OpenZeppelin Contracts is pre-installed, so you can follow that as an example.

## Writing Tests

To write a new test contract, you start by importing `Test` from `forge-std`, and then you inherit it in your test
contract. Forge Std comes with a pre-instantiated [cheatcodes](https://book.getfoundry.sh/cheatcodes/) environment
accessible via the `vm` property. If you would like to view the logs in the terminal output, you can add the `-vvv` flag
and use [console.log](https://book.getfoundry.sh/faq?highlight=console.log#how-do-i-use-consolelog).

This template comes with an example test contract [Foo.t.sol](./test/Foo.t.sol)

## Usage

This is a list of the most frequently needed commands.
Expand Down Expand Up @@ -180,26 +142,6 @@ Run the tests:
$ forge test
```

Generate test coverage and output result to the terminal:

```sh
$ bun run test:coverage
```

Generate test coverage with lcov report (you'll have to open the `./coverage/index.html` file in your browser, to do so
simply copy paste the path):

```sh
$ bun run test:coverage:report
```

## Related Efforts

- [abigger87/femplate](https://github.com/abigger87/femplate)
- [cleanunicorn/ethereum-smartcontract-template](https://github.com/cleanunicorn/ethereum-smartcontract-template)
- [foundry-rs/forge-template](https://github.com/foundry-rs/forge-template)
- [FrankieIsLost/forge-template](https://github.com/FrankieIsLost/forge-template)

## License

This project is licensed under MIT.
15 changes: 7 additions & 8 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
base = { key = "${API_KEY_BASESCAN}" }
bnb_smart_chain = { key = "${API_KEY_BSCSCAN}" }
gnosis_chain = { key = "${API_KEY_GNOSISSCAN}" }
goerli = { key = "${API_KEY_ETHERSCAN}" }
mainnet = { key = "${API_KEY_ETHERSCAN}" }
optimism = { key = "${API_KEY_OPTIMISTIC_ETHERSCAN}" }
polygon = { key = "${API_KEY_POLYGONSCAN}" }
Expand All @@ -42,14 +41,14 @@
wrap_comments = true

[rpc_endpoints]
arbitrum = "https://arbitrum-mainnet.infura.io/v3/${API_KEY_INFURA}"
avalanche = "https://avalanche-mainnet.infura.io/v3/${API_KEY_INFURA}"
mainnet = "https://eth-mainnet.g.alchemy.com/v2/${API_KEY_ALCHEMY}"
arbitrum = "https://arbitrum-mainnet.g.alchemy.com/v2/${API_KEY_ALCHEMY}"
avalanche = "https://avalanche-mainnet.g.alchemy.com/v2/${API_KEY_ALCHEMY}"
base = "https://mainnet.base.org"
bnb_smart_chain = "https://bsc-dataseed.binance.org"
gnosis_chain = "https://rpc.gnosischain.com"
goerli = "https://goerli.infura.io/v3/${API_KEY_INFURA}"
localhost = "http://localhost:8545"
mainnet = "https://eth-mainnet.g.alchemy.com/v2/${API_KEY_ALCHEMY}"
optimism = "https://optimism-mainnet.infura.io/v3/${API_KEY_INFURA}"
polygon = "https://polygon-mainnet.infura.io/v3/${API_KEY_INFURA}"
sepolia = "https://sepolia.infura.io/v3/${API_KEY_INFURA}"
optimism = "https://optimism-mainnet.g.alchemy.com/v2/${API_KEY_ALCHEMY}"
polygon = "https://polygon-mainnet.g.alchemy.com/v2/${API_KEY_ALCHEMY}"
optimism-sepolia = "https://opt-sepolia.g.alchemy.com/v2/${API_KEY_ALCHEMY}"
sepolia = "https://eth-sepolia.g.alchemy.com/v2/${API_KEY_ALCHEMY}"
13 changes: 10 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"dependencies": {
"@hyperlane-xyz/core": "^5.1.0",
"@openzeppelin/contracts": "^4.9.3",
"@openzeppelin/contracts-upgradeable": "^v4.9.3"
"@openzeppelin/contracts-upgradeable": "^v4.9.3",
"dotenv-run-script": "^0.4.1"
},
"devDependencies": {
"forge-std": "github:foundry-rs/forge-std#v1.8.1",
Expand All @@ -27,7 +28,7 @@
],
"private": true,
"scripts": {
"clean": "rm -rf cache out",
"clean": "rm -rf cache out && forge clean",
"build": "forge build",
"lint": "yarn run lint:sol && yarn run prettier:check",
"lint:sol": "forge fmt --check && yarn solhint '{script,src,test}/**/*.sol'",
Expand All @@ -36,6 +37,12 @@
"prettier:write": "prettier --write \"**/*.{json,md,yml}\" --ignore-path \".prettierignore\"",
"test": "forge test -vvv",
"test:coverage": "forge coverage",
"test:coverage:report": "forge coverage --report lcov && genhtml lcov.info --branch-coverage --output-dir coverage"
"test:coverage:report": "forge coverage --report lcov && genhtml lcov.info --branch-coverage --output-dir coverage",
"deployRouter": "forge script script/DeployRouter.s.sol:DeployRouter -f $NETWORK --broadcast --verify --etherscan-api-key $ETHERSCAN_API_KEY --chain $NETWORK --slow -vvvv",
"run:deployRouter": "dotenv-run-script deployRouter",
"enrollRouters": "forge script script/EnrollRouters.s.sol:EnrollRouters -f $NETWORK --broadcast --slow -vvvv",
"run:enrollRouters": "dotenv-run-script enrollRouters",
"interchainDeploy": "forge script script/InterchainDeployExample.s.sol:InterchainDeployExample -f $NETWORK --broadcast --slow -vvvv",
"run:interchainDeploy": "dotenv-run-script interchainDeploy"
}
}
Loading
Loading