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

Migrate to foundry #867

Merged
merged 27 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
1a7a131
add foundry changes without submodules
technophile-04 Jun 19, 2024
f0c14ec
forge install: forge-std
technophile-04 Jun 19, 2024
2b6a766
forge install: openzeppelin-contracts
technophile-04 Jun 19, 2024
f15c6d1
forge install: solidity-bytes-utils
technophile-04 Jun 19, 2024
941797a
update gh workflow file
technophile-04 Jun 19, 2024
5247608
fix gh-actions: unignore deployments 31337.json
technophile-04 Jun 19, 2024
ae36666
Revert "fix gh-actions: unignore deployments 31337.json"
technophile-04 Jun 19, 2024
d0755b9
add .gitignore inside deployemnts folder
technophile-04 Jun 19, 2024
b272a98
remove workflow file from foundry package
technophile-04 Jun 19, 2024
bc0323b
update .env.example
technophile-04 Jun 24, 2024
e68e0a7
use node es modules
technophile-04 Jun 24, 2024
72dc85d
move all js files inder scripts-js dir
technophile-04 Jun 24, 2024
96e9f18
update README
technophile-04 Jun 24, 2024
dac5c05
configure basic lint/formatting code
technophile-04 Jun 24, 2024
b8cc2d6
remove types devDependencies from foundry package
technophile-04 Jun 24, 2024
ad9b88c
minor tweak to README
technophile-04 Jun 24, 2024
40e0107
minor tweak to .env.example
technophile-04 Jun 24, 2024
3c1659a
Merge branch 'main' into foundry-main
carletex Jun 24, 2024
caff159
yarn.lock regenerate
carletex Jun 24, 2024
951f733
Use cpy-cli to create .env on postinstall
carletex Jun 24, 2024
5e43708
update .env.example
technophile-04 Jun 25, 2024
3257010
remove console.log from generateAccount.js
technophile-04 Jun 25, 2024
52882e7
update YourContract comment
technophile-04 Jun 26, 2024
46443fb
use shx instead of cpy-cli
carletex Jun 26, 2024
abf1e81
Merge remote-tracking branch 'origin/foundry-main--cp-env' into found…
technophile-04 Jun 27, 2024
b2d0cfc
remove cp command from readme
technophile-04 Jun 27, 2024
a126be9
Add installation note for windows users
Pabl0cks Jun 28, 2024
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: 8 additions & 4 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,18 @@ jobs:
- name: Install dependencies
run: yarn install --immutable

- name: Run hardhat node, deploy contracts (& generate contracts typescript output)
- name: Install foundry-toolchain
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly

- name: Run foundry node, deploy contracts (& generate contracts typescript output)
env:
ETHERSCAN_API_KEY: ${{ secrets.ETHERSCAN_API_KEY }}
run: yarn chain & yarn deploy

- name: Run nextjs lint
run: yarn next:lint --max-warnings=0

- name: Check typings on nextjs
run: yarn next:check-types

- name: Run hardhat lint
run: yarn hardhat:lint --max-warnings=0
9 changes: 9 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[submodule "packages/foundry/lib/forge-std"]
path = packages/foundry/lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "packages/foundry/lib/openzeppelin-contracts"]
path = packages/foundry/lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
[submodule "packages/foundry/lib/solidity-bytes-utils"]
path = packages/foundry/lib/solidity-bytes-utils
url = https://github.com/gnsps/solidity-bytes-utils
8 changes: 2 additions & 6 deletions .lintstagedrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,11 @@ const buildNextEslintCommand = (filenames) =>

const checkTypesNextCommand = () => "yarn next:check-types";

const buildHardhatEslintCommand = (filenames) =>
`yarn hardhat:lint-staged --fix ${filenames
.map((f) => path.relative(path.join("packages", "hardhat"), f))
.join(" ")}`;

module.exports = {
"packages/nextjs/**/*.{ts,tsx}": [
buildNextEslintCommand,
checkTypesNextCommand,
],
"packages/hardhat/**/*.{ts,tsx}": [buildHardhatEslintCommand],
"packages/foundry/**/*.sol": ["forge fmt --root packages/foundry"],
"packages/foundry/**/*.js": ["yarn workspace @se-2/foundry prettier --write"],
};
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

🧪 An open-source, up-to-date toolkit for building decentralized applications (dapps) on the Ethereum blockchain. It's designed to make it easier for developers to create and deploy smart contracts and build user interfaces that interact with those contracts.

⚙️ Built using NextJS, RainbowKit, Hardhat, Wagmi, Viem, and Typescript.
⚙️ Built using NextJS, RainbowKit, Foundry, Wagmi, Viem, and Typescript.

- ✅ **Contract Hot Reload**: Your frontend auto-adapts to your smart contract as you edit it.
- 🪝 **[Custom hooks](https://docs.scaffoldeth.io/hooks/)**: Collection of React hooks wrapper around [wagmi](https://wagmi.sh/) to simplify interactions with smart contracts with typescript autocompletion.
Expand All @@ -24,6 +24,9 @@ Before you begin, you need to install the following tools:
- [Node (>= v18.17)](https://nodejs.org/en/download/)
- Yarn ([v1](https://classic.yarnpkg.com/en/docs/install/) or [v2+](https://yarnpkg.com/getting-started/install))
- [Git](https://git-scm.com/downloads)
- [Foundryup](https://book.getfoundry.sh/getting-started/installation)

> **Note for Windows users**. Foundryup is not currently supported by Powershell or Cmd. You will need to use [Git BASH](https://gitforwindows.org/) or [WSL](https://learn.microsoft.com/en-us/windows/wsl/install) as your terminal.

## Quickstart

Expand All @@ -34,7 +37,7 @@ To get started with Scaffold-ETH 2, follow the steps below:
```
git clone https://github.com/scaffold-eth/scaffold-eth-2.git
cd scaffold-eth-2
yarn install
yarn install && forge install --root packages/foundry
```

2. Run a local network in the first terminal:
Expand All @@ -43,15 +46,15 @@ yarn install
yarn chain
```

This command starts a local Ethereum network using Hardhat. The network runs on your local machine and can be used for testing and development. You can customize the network configuration in `hardhat.config.ts`.
This command starts a local Ethereum network using anvil. The network runs on your local machine and can be used for testing and development. You can customize the network configuration in `packages/foundry/foundry.toml`.

3. On a second terminal, deploy the test contract:

```
yarn deploy
```

This command deploys a test smart contract to the local network. The contract is located in `packages/hardhat/contracts` and can be modified to suit your needs. The `yarn deploy` command uses the deploy script located in `packages/hardhat/deploy` to deploy the contract to the network. You can also customize the deploy script.
This command deploys a test smart contract to the local network. The contract is located in `packages/foundry/contracts` and can be modified to suit your needs. The `yarn deploy` command uses the deploy script located in `packages/foundry/script/Deploy.s.sol` to deploy the contract to the network. You can also customize the deploy script.

4. On a third terminal, start your NextJS app:

Expand All @@ -63,10 +66,10 @@ Visit your app on: `http://localhost:3000`. You can interact with your smart con

**What's next**:

- Edit your smart contract `YourContract.sol` in `packages/hardhat/contracts`
- Edit your smart contract `YourContract.sol` in `packages/foundry/contracts`
- Edit your frontend homepage at `packages/nextjs/app/page.tsx`. For guidance on [routing](https://nextjs.org/docs/app/building-your-application/routing/defining-routes) and configuring [pages/layouts](https://nextjs.org/docs/app/building-your-application/routing/pages-and-layouts) checkout the Next.js documentation.
- Edit your deployment scripts in `packages/hardhat/deploy`
- Edit your smart contract test in: `packages/hardhat/test`. To run test use `yarn hardhat:test`
- Edit your deployment scripts in `packages/script/deploy/Deploy.s.sol`
- Edit your smart contract test in: `packages/foundry/test`. To run test use `yarn foundry:test`

## Documentation

Expand Down
31 changes: 15 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,25 @@
"private": true,
"workspaces": {
"packages": [
"packages/hardhat",
"packages/foundry",
"packages/nextjs"
]
},
"scripts": {
"account": "yarn workspace @se-2/hardhat account",
"chain": "yarn workspace @se-2/hardhat chain",
"fork": "yarn workspace @se-2/hardhat fork",
"deploy": "yarn workspace @se-2/hardhat deploy",
"verify": "yarn workspace @se-2/hardhat verify",
"hardhat-verify": "yarn workspace @se-2/hardhat hardhat-verify",
"compile": "yarn workspace @se-2/hardhat compile",
"generate": "yarn workspace @se-2/hardhat generate",
"flatten": "yarn workspace @se-2/hardhat flatten",
"hardhat:lint": "yarn workspace @se-2/hardhat lint",
"hardhat:lint-staged": "yarn workspace @se-2/hardhat lint-staged",
"hardhat:format": "yarn workspace @se-2/hardhat format",
"hardhat:test": "yarn workspace @se-2/hardhat test",
"test": "yarn hardhat:test",
"format": "yarn next:format && yarn hardhat:format",
"account": "yarn workspace @se-2/foundry account",
"chain": "yarn workspace @se-2/foundry chain",
"fork": "yarn workspace @se-2/foundry fork",
"deploy": "yarn workspace @se-2/foundry deploy",
"verify": "yarn workspace @se-2/foundry verify",
"deploy:verify": "yarn workspace @se-2/foundry deploy:verify",
"compile": "yarn workspace @se-2/foundry compile",
"generate": "yarn workspace @se-2/foundry generate",
"flatten": "yarn workspace @se-2/foundry flatten",
"foundry:format": "yarn workspace @se-2/foundry format",
"foundry:lint": "yarn workspace @se-2/foundry lint",
"foundry:test": "yarn workspace @se-2/foundry test",
"test": "yarn foundry:test",
"format": "yarn next:format && yarn foundry:format",
"start": "yarn workspace @se-2/nextjs dev",
"next:lint": "yarn workspace @se-2/nextjs lint",
"next:format": "yarn workspace @se-2/nextjs format",
Expand Down
21 changes: 21 additions & 0 deletions packages/foundry/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Template for foundry environment variables.

# For local development, copy this file, rename it to .env, and fill in the values.

# We provide default values so developers can start prototyping out of the box,
# but we recommend getting your own API Keys for Production Apps.

# DEPLOYER_PRIVATE_KEY is used while deploying contract.
# On anvil chain the value of it can be empty since we use the prefunded account
# which comes with anvil chain to deploy contract.
# NOTE: You don't need to manually change the value of DEPLOYER_PRIVATE_KEY, it should
# be auto filled when run `yarn generate`.
# Although `.env` is ignored by git, it's still important that you don't paste your
# actual account private key and use the generated one.
DEPLOYER_PRIVATE_KEY=

# Alchemy rpc URL is used while deploying the contracts to some testnets/mainnets, checkout `foundry.toml` for it's use.
ALCHEMY_API_KEY=oKxs-03sij-U_N0iOlrSsZFr29-IqbuF

# Etherscan API key is used to verify the contract on etherscan.
ETHERSCAN_API_KEY=DNXJA8RX2Q3VZ4URQIWP7Z68CJXQZSC6AW
14 changes: 14 additions & 0 deletions packages/foundry/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Compiler files
cache/
out/

# Ignores development broadcast logs
/broadcast/*/31337/
/broadcast/**/dry-run/

# Docs
docs/

# Dotenv file
.env
localhost.json
6 changes: 6 additions & 0 deletions packages/foundry/.prettier.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"arrowParens": "avoid",
"printWidth": 120,
"tabWidth": 2,
"trailingComma": "all"
}
84 changes: 84 additions & 0 deletions packages/foundry/contracts/YourContract.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 <0.9.0;

// Useful for debugging. Remove when deploying to a live network.
import "forge-std/console.sol";

// Use openzeppelin to inherit battle-tested implementations (ERC20, ERC721, etc)
// import "@openzeppelin/contracts/access/Ownable.sol";

/**
* A smart contract that allows changing a state variable of the contract and tracking the changes
* It also allows the owner to withdraw the Ether from the contract
* @author BuidlGuidl
*/
contract YourContract {
// State Variables
address public immutable owner;
string public greeting = "Building Unstoppable Apps!!!";
bool public premium = false;
uint256 public totalCounter = 0;
mapping(address => uint256) public userGreetingCounter;

// Events: a way to emit log statements from smart contract that can be listened to by external parties
event GreetingChange(
address indexed greetingSetter,
string newGreeting,
bool premium,
uint256 value
);

// Constructor: Called once on contract deployment
// Check packages/foundry/deploy/Deploy.s.sol
constructor(address _owner) {
owner = _owner;
}

// Modifier: used to define a set of rules that must be met before or after a function is executed
// Check the withdraw() function
modifier isOwner() {
// msg.sender: predefined variable that represents address of the account that called the current function
require(msg.sender == owner, "Not the Owner");
_;
}

/**
* Function that allows anyone to change the state variable "greeting" of the contract and increase the counters
*
* @param _newGreeting (string memory) - new greeting to save on the contract
*/
function setGreeting(string memory _newGreeting) public payable {
// Print data to the anvil chain console. Remove when deploying to a live network.

console.logString("Setting new greeting");
console.logString(_newGreeting);

greeting = _newGreeting;
totalCounter += 1;
userGreetingCounter[msg.sender] += 1;

// msg.value: built-in global variable that represents the amount of ether sent with the transaction
if (msg.value > 0) {
premium = true;
} else {
premium = false;
}

// emit: keyword used to trigger an event
emit GreetingChange(msg.sender, _newGreeting, msg.value > 0, msg.value);
}

/**
* Function that allows the owner to withdraw all the Ether in the contract
* The function can only be called by the owner of the contract as defined by the isOwner modifier
*/
function withdraw() public isOwner {
(bool success,) = owner.call{ value: address(this).balance }("");
require(success, "Failed to send Ether");
}

/**
* Function that allows the contract to receive ETH
*/
receive() external payable { }
}
2 changes: 2 additions & 0 deletions packages/foundry/deployments/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Ignore 31337 deployments
31337.json
44 changes: 44 additions & 0 deletions packages/foundry/foundry.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
[profile.default]
src = 'contracts'
out = 'out'
libs = ['lib']
fs_permissions = [{ access = "read-write", path = "./"}]

[rpc_endpoints]
default_network = "http://127.0.0.1:8545"
localhost = "http://127.0.0.1:8545"

mainnet = "https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_API_KEY}"
sepolia = "https://eth-sepolia.g.alchemy.com/v2/${ALCHEMY_API_KEY}"
arbitrum = "https://arb-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}"
arbitrumSepolia = "https://arb-sepolia.g.alchemy.com/v2/${ALCHEMY_API_KEY}"
optimism = "https://opt-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}"
optimismSepolia = "https://opt-sepolia.g.alchemy.com/v2/${ALCHEMY_API_KEY}"
polygon = "https://polygon-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}"
polygonMumbai = "https://polygon-mumbai.g.alchemy.com/v2/${ALCHEMY_API_KEY}"
gnosis = "https://rpc.gnosischain.com"
chiado = "https://rpc.chiadochain.net"
base = "https://mainnet.base.org"
baseGoerli = "https://goerli.base.org"
baseSepolia = "https://sepolia.base.org"
polygonZkEvm = "https://polygonzkevm-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}"
polygonZkEvmTestnet = "https://polygonzkevm-testnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}"
zkSyncTestnet = "https://testnet.era.zksync.dev"
zkSync = "https://mainnet.era.zksync.io"
scrollSepolia = "https://sepolia-rpc.scroll.io"
scroll = "https://rpc.scroll.io"

[etherscan]
polygonMumbai = { key = "${ETHERSCAN_API_KEY}" }
sepolia = { key = "${ETHERSCAN_API_KEY}" }


[fmt]
multiline_func_header = "params_first"
line_length = 80
tab_width = 2
quote_style = "double"
bracket_spacing = true
int_types = "long"

# See more config options https://github.com/foundry-rs/foundry/tree/master/config
1 change: 1 addition & 0 deletions packages/foundry/lib/forge-std
Submodule forge-std added at 978ac6
1 change: 1 addition & 0 deletions packages/foundry/lib/openzeppelin-contracts
Submodule openzeppelin-contracts added at dbb610
1 change: 1 addition & 0 deletions packages/foundry/lib/solidity-bytes-utils
Submodule solidity-bytes-utils added at e0115c
31 changes: 31 additions & 0 deletions packages/foundry/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "@se-2/foundry",
"version": "0.0.1",
"type": "module",
"scripts": {
"account": "node scripts-js/ListAccount.js",
"chain": "anvil --config-out localhost.json",
"compile": "forge compile",
"deploy": "forge build --build-info --build-info-path out/build-info/ && forge script script/Deploy.s.sol --rpc-url ${1:-default_network} --broadcast --legacy && node scripts-js/generateTsAbis.js",
"deploy:verify": "forge build --build-info --build-info-path out/build-info/ && forge script script/Deploy.s.sol --rpc-url ${1:-default_network} --broadcast --legacy --verify ; node scripts-js/generateTsAbis.js",
"flatten": "forge flatten",
"fork": "anvil --fork-url ${0:-mainnet} --chain-id 31337 --config-out localhost.json",
"format": "forge fmt && prettier --write ./script/**/*.js",
"generate": "node scripts-js/generateAccount.js",
"lint": "forge fmt --check && prettier --check ./script/**/*.js",
"postinstall": "shx cp -n .env.example .env",
"test": "forge test",
"verify": "forge build --build-info --build-info-path out/build-info/ && forge script script/VerifyAll.s.sol --ffi --rpc-url ${1:-default_network}"
},
"dependencies": {
"dotenv": "~16.3.1",
"envfile": "~6.18.0",
"ethers": "~5.7.1",
"prettier": "~2.8.8",
"qrcode": "~1.5.3",
"toml": "~3.0.0"
},
"devDependencies": {
"shx": "^0.3.4"
}
}
1 change: 1 addition & 0 deletions packages/foundry/remappings.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts
Loading