Skip to content

Commit b2b06a1

Browse files
committed
Updated README.md
1 parent b212c26 commit b2b06a1

18 files changed

+811
-99
lines changed

.gitmodules

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
11
[submodule "lib/forge-std"]
22
path = lib/forge-std
33
url = https://github.com/foundry-rs/forge-std
4+
[submodule "lib/chainlink-brownie-contracts"]
5+
path = lib/chainlink-brownie-contracts
6+
url = https://github.com/smartcontractkit/chainlink-brownie-contracts
7+
[submodule "lib/solmate"]
8+
path = lib/solmate
9+
url = https://github.com/transmissions11/solmate
10+
[submodule "lib/foundry-devops"]
11+
path = lib/foundry-devops

Makefile

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
-include .env
2+
3+
.PHONY: all test clean deploy fund help install snapshot format anvil
4+
5+
DEFAULT_ANVIL_KEY := 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
6+
7+
help:
8+
@echo "Usage:"
9+
@echo " make deploy [ARGS=...]\n example: make deploy ARGS=\"--network sepolia\""
10+
@echo ""
11+
@echo " make fund [ARGS=...]\n example: make deploy ARGS=\"--network sepolia\""
12+
13+
all: clean remove install update build
14+
15+
# Clean the repo
16+
clean :; forge clean
17+
18+
# Remove modules
19+
remove :; rm -rf .gitmodules && rm -rf .git/modules/* && rm -rf lib && touch .gitmodules && git add . && git commit -m "modules"
20+
21+
install :; forge install cyfrin/foundry-devops@0.2.2 --no-commit && forge install smartcontractkit/chainlink-brownie-contracts@1.1.1 --no-commit && forge install foundry-rs/forge-std@v1.8.2 --no-commit && forge install transmissions11/solmate@v6 --no-commit
22+
23+
# Update Dependencies
24+
update:; forge update
25+
26+
build:; forge build
27+
28+
test :; forge test
29+
30+
snapshot :; forge snapshot
31+
32+
format :; forge fmt
33+
34+
anvil :; anvil -m 'test test test test test test test test test test test junk' --steps-tracing --block-time 1
35+
36+
NETWORK_ARGS := --rpc-url http://localhost:8545 --private-key $(DEFAULT_ANVIL_KEY) --broadcast
37+
38+
ifeq ($(findstring --network sepolia,$(ARGS)),--network sepolia)
39+
NETWORK_ARGS := --rpc-url $(SEPOLIA_RPC_URL) --private-key $(PRIVATE_KEY) --broadcast --verify --etherscan-api-key $(ETHERSCAN_API_KEY) -vvvv
40+
endif
41+
42+
deploy:
43+
@forge script script/DeployRaffle.s.sol:DeployRaffle $(NETWORK_ARGS)
44+
45+
createSubscription:
46+
@forge script script/Interactions.s.sol:CreateSubscription $(NETWORK_ARGS)
47+
48+
addConsumer:
49+
@forge script script/Interactions.s.sol:AddConsumer $(NETWORK_ARGS)
50+
51+
fundSubscription:
52+
@forge script script/Interactions.s.sol:FundSubscription $(NETWORK_ARGS)
53+
54+

README.md

Lines changed: 32 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,56 @@
1-
## Foundry
1+
# Getting Started
22

3-
**Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.**
3+
## Requirements
44

5-
Foundry consists of:
5+
- [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
6+
- You'll know you did it right if you can run `git --version` and you see a response like `git version x.x.x`
7+
- [foundry](https://getfoundry.sh/)
8+
- You'll know you did it right if you can run `forge --version` and you see a response like `forge 0.2.0 (816e00b 2023-03-16T00:05:26.396218Z)`
69

7-
- **Forge**: Ethereum testing framework (like Truffle, Hardhat and DappTools).
8-
- **Cast**: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data.
9-
- **Anvil**: Local Ethereum node, akin to Ganache, Hardhat Network.
10-
- **Chisel**: Fast, utilitarian, and verbose solidity REPL.
10+
## Quickstart
1111

12-
## Documentation
13-
14-
https://book.getfoundry.sh/
12+
```
13+
git clone https://github.com/Cyfrin/foundry-smart-contract-lottery-cu
14+
cd foundry-smart-contract-lottery-cu
15+
forge build
16+
```
1517

16-
## Usage
18+
# Usage
1719

18-
### Build
20+
## Start a local node
1921

20-
```shell
21-
$ forge build
2222
```
23-
24-
### Test
25-
26-
```shell
27-
$ forge test
23+
make anvil
2824
```
2925

30-
### Format
31-
32-
```shell
33-
$ forge fmt
34-
```
26+
## Library
3527

36-
### Gas Snapshots
28+
If you're having a hard time installing the chainlink library, you can optionally run this command.
3729

38-
```shell
39-
$ forge snapshot
30+
```
31+
forge install smartcontractkit/chainlink-brownie-contracts@1.3.0 --no-commit
4032
```
4133

42-
### Anvil
34+
## Deploy
4335

44-
```shell
45-
$ anvil
46-
```
36+
This will default to your local node. You need to have it running in another terminal in order for it to deploy.
4737

48-
### Deploy
38+
```
39+
make deploy
40+
```
4941

50-
```shell
51-
$ forge script script/Counter.s.sol:CounterScript --rpc-url <your_rpc_url> --private-key <your_private_key>
42+
```
43+
forge test
5244
```
5345

54-
### Cast
46+
or
5547

56-
```shell
57-
$ cast <subcommand>
48+
```
49+
forge test --fork-url $SEPOLIA_RPC_URL
5850
```
5951

60-
### Help
52+
### Test Coverage
6153

62-
```shell
63-
$ forge --help
64-
$ anvil --help
65-
$ cast --help
54+
```
55+
forge coverage
6656
```

foundry.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,15 @@
22
src = "src"
33
out = "out"
44
libs = ["lib"]
5+
remappings = [
6+
'@chainlink/contracts@1.2.0/=lib/chainlink-brownie-contracts/contracts/',
7+
'@solmate/=lib/solmate/src',
8+
]
9+
fs_permissions = [
10+
{ access = "read", path = "./broadcast" },
11+
{ access = "read", path = "./reports" },
12+
]
13+
[fuzz]
14+
runs = 256
515

616
# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options

lib/chainlink-brownie-contracts

lib/foundry-devops

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit 70b1a82acb8452382347e5244227b9e0fddb411f

lib/solmate

Submodule solmate added at a9e3ea2

script/Counter.s.sol

Lines changed: 0 additions & 19 deletions
This file was deleted.

script/DeployRaffle.s.sol

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.0;
3+
4+
import {Script} from "forge-std/Script.sol";
5+
import {Raffle} from "src/Raffle.sol";
6+
import {HelperConfig} from "script/HelperConfig.s.sol";
7+
import {CreateSubscription, FundSubscription, AddConsumer} from "script/Interactions.s.sol";
8+
9+
contract DeployRaffle is Script {
10+
function run() public {}
11+
12+
function deployContract() public returns (Raffle, HelperConfig) {
13+
HelperConfig helperConfig = new HelperConfig();
14+
HelperConfig.NetworkConfig memory config = helperConfig.getConfig();
15+
16+
// Create Subscriprion
17+
if (config.subscriptionId == 0) {
18+
CreateSubscription createSubscription = new CreateSubscription();
19+
(config.subscriptionId, config.vrfCoordinator) =
20+
createSubscription.createSubscription(config.vrfCoordinator, config.account);
21+
}
22+
23+
// Fund Subscription!
24+
FundSubscription fundSubscription = new FundSubscription();
25+
fundSubscription.fundSubscription(config.vrfCoordinator, config.subscriptionId, config.link, config.account);
26+
27+
// deploy the contract
28+
vm.startBroadcast(config.account);
29+
Raffle raffle = new Raffle(
30+
config.entranceFee,
31+
config.interval,
32+
config.vrfCoordinator,
33+
config.gasLane,
34+
config.subscriptionId,
35+
config.callbackGasLimit
36+
);
37+
vm.stopBroadcast();
38+
39+
// Adding Consumer, don't need broadcast this...
40+
AddConsumer addConsumer = new AddConsumer();
41+
addConsumer.addConsumer(address(raffle), config.vrfCoordinator, config.subscriptionId, config.account);
42+
return (raffle, helperConfig);
43+
}
44+
}

script/HelperConfig.s.sol

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.0;
3+
4+
import {Script} from "forge-std/Script.sol";
5+
import {VRFCoordinatorV2_5Mock} from "@chainlink/contracts@1.2.0/src/v0.8/vrf/mocks/VRFCoordinatorV2_5Mock.sol";
6+
import {LinkToken} from "test/mocks/LinkToken.sol";
7+
8+
abstract contract CodeConstants {
9+
/* VRF Mock Values */
10+
uint96 public MOCK_BASE_FEE = 0.25 ether;
11+
uint96 public MOCK_GAS_PRICE_LINK = 1e9;
12+
// LINK / ETH price
13+
int256 public MOCK_WEI_PER_UINT_LINK = 4e15 * 100;
14+
15+
uint256 public constant ETH_SEPOLIA_CHAIN_ID = 11155111;
16+
uint256 public constant LOCAL_CHAIN_ID = 31337;
17+
}
18+
19+
contract HelperConfig is CodeConstants, Script {
20+
error HelperConfig_InvalidChainId();
21+
22+
NetworkConfig public localNetworkConfig;
23+
24+
struct NetworkConfig {
25+
uint256 entranceFee;
26+
uint256 interval;
27+
address vrfCoordinator;
28+
bytes32 gasLane;
29+
uint32 callbackGasLimit;
30+
uint256 subscriptionId;
31+
address link;
32+
address account;
33+
}
34+
35+
mapping(uint256 chainId => NetworkConfig) public networkConfigs;
36+
37+
constructor() {
38+
networkConfigs[ETH_SEPOLIA_CHAIN_ID] = getSepoliaEthConfig();
39+
}
40+
41+
function getSepoliaEthConfig() public pure returns (NetworkConfig memory) {
42+
return NetworkConfig({
43+
entranceFee: 0.01 ether,
44+
interval: 30,
45+
vrfCoordinator: 0xD7f86b4b8Cae7D942340FF628F82735b7a20893a,
46+
gasLane: 0x8077df514608a09f83e4e8d300645594e5d7234665448ba83f51a50f842bd3d9,
47+
callbackGasLimit: 500000,
48+
subscriptionId: 0,
49+
link: 0x779877A7B0D9E8603169DdbD7836e478b4624789,
50+
account: 0x3E685957dDd8d988f4C2C9834e5eaD361B5B6a35
51+
});
52+
}
53+
54+
function getConfig() public returns (NetworkConfig memory) {
55+
return getConfigByChainId(block.chainid);
56+
}
57+
58+
function getConfigByChainId(uint256 chainId) public returns (NetworkConfig memory) {
59+
if (networkConfigs[chainId].vrfCoordinator != address(0)) {
60+
return networkConfigs[chainId];
61+
} else if (chainId == LOCAL_CHAIN_ID) {
62+
return getOrCreateAnvilEthConfig();
63+
} else {
64+
revert HelperConfig_InvalidChainId();
65+
}
66+
}
67+
68+
function getOrCreateAnvilEthConfig() public returns (NetworkConfig memory) {
69+
if (localNetworkConfig.vrfCoordinator != address(0)) {
70+
return localNetworkConfig;
71+
}
72+
73+
vm.startBroadcast();
74+
VRFCoordinatorV2_5Mock vrfCoordinatorMock =
75+
new VRFCoordinatorV2_5Mock(MOCK_BASE_FEE, MOCK_GAS_PRICE_LINK, MOCK_WEI_PER_UINT_LINK);
76+
LinkToken link = new LinkToken();
77+
vm.stopBroadcast();
78+
79+
localNetworkConfig = NetworkConfig({
80+
entranceFee: 0.01 ether,
81+
interval: 30,
82+
vrfCoordinator: address(vrfCoordinatorMock),
83+
gasLane: 0x8077df514608a09f83e4e8d300645594e5d7234665448ba83f51a50f842bd3d9,
84+
callbackGasLimit: 500000,
85+
subscriptionId: 0, //fix this one
86+
link: address(link),
87+
account: 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38
88+
});
89+
return localNetworkConfig;
90+
}
91+
}

0 commit comments

Comments
 (0)