Skip to content

Commit

Permalink
Successfull Sepolia Deploy
Browse files Browse the repository at this point in the history
  • Loading branch information
Collin Pixley authored and Collin Pixley committed Oct 19, 2024
1 parent d0b74da commit 40ea363
Show file tree
Hide file tree
Showing 20 changed files with 1,081 additions and 6 deletions.
Binary file added .DS_Store
Binary file not shown.
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
[submodule "lib/chainlink-brownie-contracts"]
path = lib/chainlink-brownie-contracts
url = https://github.com/smartcontractkit/chainlink-brownie-contracts
[submodule "lib/foundry-devops"]
path = lib/foundry-devops
url = https://github.com/Cyfrin/foundry-devops
Expand Down
73 changes: 73 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
-include .env

.PHONY: all test clean deploy fund help install snapshot format anvil

DEFAULT_ANVIL_KEY := 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80

help:
@echo "Usage:"
@echo " make deploy [ARGS=...]\n example: make deploy ARGS=\"--network sepolia\""
@echo ""
@echo " make fund [ARGS=...]\n example: make deploy ARGS=\"--network sepolia\""

all: clean remove install update build

# Clean the repo
clean :; forge clean

# Remove modules
remove :; rm -rf .gitmodules && rm -rf .git/modules/* && rm -rf lib && touch .gitmodules && git add . && git commit -m "modules"

install :; forge install cyfrin/[email protected] --no-commit && forge install smartcontractkit/[email protected] --no-commit && forge install foundry-rs/[email protected] --no-commit && forge install transmissions11/solmate@v6 --no-commit

# Update Dependencies
update:; forge update

build:; forge build

test :; forge test

snapshot :; forge snapshot

format :; forge fmt

anvil :; anvil -m 'test test test test test test test test test test test junk' --steps-tracing --block-time 1

make test-fork:
forge test --fork-url $(SEPOLIA_RPC_URL) --etherscan-api-key $(ETHERSCAN_API_KEY) -vvvv

make deploy-mainnet:
forge script script/DeployRaffle.s.sol:DeployRaffle --rpc-url $(MAINNET_RPC_URL) --private-key $(PRIVATE_KEY) --broadcast --verify --etherscan-api-key $(ETHERSCAN_API_KEY) -vvvv

make deploy-sepolia:
forge script script/DeployRaffle.s.sol:DeployRaffle --rpc-url $(SEPOLIA_RPC_URL) --private-key $(PRIVATE_KEY) --broadcast --verify --etherscan-api-key $(ETHERSCAN_API_KEY) -vvvv

make deploy-anvil:
forge script script/DeployRaffle.s.sol:DeployRaffle --private-key $(PRIVATE_KEY) --broadcast --verify -vvvv

make create-sepolia-sub:
forge script script/Interactions.s.sol:CreateSubscription --rpc-url $(SEPOLIA_RPC_URL) --private-key $(PRIVATE_KEY) --broadcast

make add-sepolia-consumer:
forge script script/Interactions.s.sol:AddConsumer --rpc-url $(SEPOLIA_RPC_URL) --private-key $(PRIVATE_KEY) --broadcast

make fund-sepolia-subscription:
forge script script/Interactions.s.sol:FundSubscription --rpc-url $(SEPOLIA_RPC_URL) --private-key $(PRIVATE_KEY) --broadcast

make create-mainnet-sub:
forge script script/Interactions.s.sol:CreateSubscription --rpc-url $(MAINNET_RPC_URL) --private-key $(PRIVATE_KEY) --broadcast

make add-mainnet-consumer:
forge script script/Interactions.s.sol:AddConsumer --rpc-url $(MAINNET_RPC_URL) --private-key $(PRIVATE_KEY) --broadcast

make fund-mainnet-subscription:
forge script script/Interactions.s.sol:FundSubscription --rpc-url $(MAINNET_RPC_URL) --private-key $(PRIVATE_KEY) --broadcast

make enter-sepolia-raffle:
cast send 0x3282332b209D5E109475C4B4FC5ac7760d45EF0F "enterRaffle()" --value 0.01ether --private-key $(PRIVATE_KEY) --rpc-url $(SEPOLIA_RPC_URL)

make enter-mainnet-raffle:
cast send <Contract-Address> "enterRaffle()" --value 0.01ether --private-key $(PRIVATE_KEY) --rpc-url $(MAINNET_RPC_URL)

make enter-anvil-raffle:
cast send <Contract-Address> "enterRaffle()" --value 0.01ether --private-key $(PRIVATE_KEY)
73 changes: 73 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,85 @@
# Foundry Smart Contract Lottery

# Probably Random Raffle Contracts

## About

1. This code is to create a provably random lottery


## What we want it to do?

1. Users can pay for a ticket
1. The ticket fees are going to go to the winner
2. After some amount of time, the lottery will auto pick a winner
1. Programatically
2. Use Chainlink VRF (Randomness) & Chainlink Automation (Time-Based Trigger)

## Learning to create NatSpec Section in contract (Goes above contract, below pragma)

## Error handling
1. doesn't make sense to use require any more bc of gas
2. use revert

1. name error messages right under contract declaration
1. error Raffle__NotEnoughEthSent as an example (Two underscores after contract name then error)

## Create Chainlink VRF Subscription

https://vrf.chain.link/sepolia/new

1. Connect Wallet and approve transaction

## State Variables
1. cheaper to make all upper case (goes right under error message or contract name)

/**
* @title Sample Raffle Contract
* @author UEVGUY
* @notice creating a sample raffle
* @dev Using Chainlink VRFv2
*/


## Modulo function is goofy

1. It works more like take the first set of numbers and see what is left over 2334502 % 10 is just the 2 at the end bc it's what is left over

## CEI: Checks Effects and Interactions
1. do checks (require if--> error) early in function (more gas efficient)
2. do effect after checks
3. interactions with other contracts come later
1. events come before interactions

## You can make reverts with numerous variables in them
1. error My__Error(uint256 someVariable, uint256 anotherVariable);
2. revert My_Error(address(this.balance), anotherVariable.length);

# Tests

## Deploy Scripts
1.


This is a section from the Cyfrin Foundry Solidity Course.

Huge shout out to Patrick Collins for making all this!

*[⭐️ (3:04:09) | Lesson 9: Foundry Smart Contract Lottery](https://www.youtube.com/watch?v=sas02qSFZ74&t=11049s)*

- [Foundry Smart Contract Lottery](#foundry-smart-contract-lottery)
- [Probably Random Raffle Contracts](#probably-random-raffle-contracts)
- [About](#about)
- [What we want it to do?](#what-we-want-it-to-do)
- [Learning to create NatSpec Section in contract (Goes above contract, below pragma)](#learning-to-create-natspec-section-in-contract-goes-above-contract-below-pragma)
- [Error handling](#error-handling)
- [Create Chainlink VRF Subscription](#create-chainlink-vrf-subscription)
- [State Variables](#state-variables)
- [Modulo function is goofy](#modulo-function-is-goofy)
- [CEI: Checks Effects and Interactions](#cei-checks-effects-and-interactions)
- [You can make reverts with numerous variables in them](#you-can-make-reverts-with-numerous-variables-in-them)
- [Tests](#tests)
- [Deploy Scripts](#deploy-scripts)
- [Getting Started](#getting-started)
- [Requirements](#requirements)
- [Quickstart](#quickstart)
Expand Down
11 changes: 9 additions & 2 deletions foundry.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
out = "out"
src = "src"

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

[rpc_endpoints]
sepolia = "${SEPOLIA_RPC_ENDPOINT}"

# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
Binary file added lib/.DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions lib/chainlink
Submodule chainlink added at 505e43
2 changes: 1 addition & 1 deletion lib/chainlink-brownie-contracts
Submodule chainlink-brownie-contracts updated from c6d0ca to b0591b
56 changes: 56 additions & 0 deletions script/DeployRaffle.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.26;

import {Script} from "forge-std/Script.sol";
import {Raffle} from "../src/Raffle.sol";
import {HelperConfig} from "../script/HelperConfig.s.sol";
import {AddConsumer, CreateSubscription, FundSubscription} from "./Interactions.s.sol";

contract DeployRaffle is Script {
function run() external returns (Raffle, HelperConfig) {
HelperConfig helperConfig = new HelperConfig(); // This comes with our mocks!
AddConsumer addConsumer = new AddConsumer();
HelperConfig.NetworkConfig memory config = helperConfig.getConfig();

if (config.subscriptionId == 0) {
CreateSubscription createSubscription = new CreateSubscription();
(
config.subscriptionId,
config.vrfCoordinatorV2_5
) = createSubscription.createSubscription(
config.vrfCoordinatorV2_5,
config.account
);

FundSubscription fundSubscription = new FundSubscription();
fundSubscription.fundSubscription(
config.vrfCoordinatorV2_5,
config.subscriptionId,
config.link,
config.account
);

helperConfig.setConfig(block.chainid, config);
}

vm.startBroadcast(config.account);
Raffle raffle = new Raffle(
config.subscriptionId,
config.gasLane,
config.automationUpdateInterval,
config.raffleEntranceFee,
config.callbackGasLimit,
config.vrfCoordinatorV2_5
);
vm.stopBroadcast();

addConsumer.addConsumer(
address(raffle),
config.vrfCoordinatorV2_5,
config.subscriptionId,
config.account
);
return (raffle, helperConfig);
}
}
131 changes: 131 additions & 0 deletions script/HelperConfig.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
//SPDX-License-Identifier: MIT

pragma solidity ^0.8.26;

import {Script, console2} from "forge-std/Script.sol";
import {VRFCoordinatorV2_5Mock} from "../lib/chainlink/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2_5Mock.sol";
import {LinkToken} from "../test/mocks/LinkToken.sol";

abstract contract CodeConstants {
uint96 public MOCK_BASE_FEE = 0.25 ether;
uint96 public MOCK_GAS_PRICE_LINK = 1e9;
int256 public MOCK_WEI_PER_UINT_LINK = 4e15;

address public FOUNDRY_DEFAULT_SENDER =
0x7132F9c2a50e40BeC4a54B3B373537239A044a16;

uint256 public constant ETH_SEPOLIA_CHAIN_ID = 11155111;
uint256 public constant ETH_MAINNET_CHAIN_ID = 1;
uint256 public constant LOCAL_CHAIN_ID = 31337;
}

contract HelperConfig is CodeConstants, Script {
error HelperConfig__InvalidChainId();

struct NetworkConfig {
uint256 subscriptionId;
bytes32 gasLane;
uint256 automationUpdateInterval;
uint256 raffleEntranceFee;
uint32 callbackGasLimit;
address vrfCoordinatorV2_5;
address link;
address account;
}

NetworkConfig public localNetworkConfig;
mapping(uint256 chainId => NetworkConfig) public networkConfigs;

constructor() {
networkConfigs[ETH_SEPOLIA_CHAIN_ID] = getSepoliaEthConfig();
networkConfigs[ETH_MAINNET_CHAIN_ID] = getMainnetEthConfig();
}

function getConfig() public returns (NetworkConfig memory) {
return getConfigByChainId(block.chainid);
}

function setConfig(
uint256 chainId,
NetworkConfig memory networkConfig
) public {
networkConfigs[chainId] = networkConfig;
}

function getConfigByChainId(
uint256 chainId
) public returns (NetworkConfig memory) {
if (networkConfigs[chainId].vrfCoordinatorV2_5 != address(0)) {
return networkConfigs[chainId];
} else if (chainId == LOCAL_CHAIN_ID) {
return getOrCreateAnvilEthConfig();
} else {
revert HelperConfig__InvalidChainId();
}
}

function getMainnetEthConfig()
public
view
returns (NetworkConfig memory mainnetNetworkConfig)
{
mainnetNetworkConfig = NetworkConfig({
subscriptionId: 0, // Replace 0 with your subId from the Chainlink VRF UI here
gasLane: 0x9fe0eebf5e446e3c998ec9bb19951541aee00bb90ea201ae456421a2ded86805,
automationUpdateInterval: 604800, // 1 week
raffleEntranceFee: 0.01 ether,
callbackGasLimit: 500000, // 500,000 gas
vrfCoordinatorV2_5: 0x271682DEB8C4E0901D1a1550aD2e64D568E69909,
link: 0x514910771AF9Ca656af840dff83E8264EcF986CA,
account: FOUNDRY_DEFAULT_SENDER
});
}

function getSepoliaEthConfig()
public
view
returns (NetworkConfig memory sepoliaNetworkConfig)
{
sepoliaNetworkConfig = NetworkConfig({
subscriptionId: 4244416522498249141814610753008696399081896929023878836802545309793195337341, // Replace with your subId from the Chainlink VRF UI here
gasLane: 0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae,
automationUpdateInterval: 604800, // 1 week
raffleEntranceFee: 0.01 ether,
callbackGasLimit: 500000, // 500,000 gas
vrfCoordinatorV2_5: 0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B,
link: 0x779877A7B0D9E8603169DdbD7836e478b4624789,
account: FOUNDRY_DEFAULT_SENDER
});
}

function getOrCreateAnvilEthConfig() public returns (NetworkConfig memory) {
if (localNetworkConfig.vrfCoordinatorV2_5 != address(0)) {
return localNetworkConfig;
}

console2.log(unicode"⚠️ You have deployed a mock conract!");
console2.log("Make sure this was intentional");
vm.startBroadcast();
VRFCoordinatorV2_5Mock vrfCoordinatorV2_5Mock = new VRFCoordinatorV2_5Mock(
MOCK_BASE_FEE,
MOCK_GAS_PRICE_LINK,
MOCK_WEI_PER_UINT_LINK
);
LinkToken link = new LinkToken();
uint256 subscriptionId = vrfCoordinatorV2_5Mock.createSubscription();
vm.stopBroadcast();

localNetworkConfig = NetworkConfig({
subscriptionId: subscriptionId,
gasLane: 0x474e34a077df58807dbe9c96d3c009b23b3c6d0cce433e59bbf5b34f823bc56c, // doesn't really matter
automationUpdateInterval: 30, // 30 seconds
raffleEntranceFee: 0.01 ether,
callbackGasLimit: 500000, // 500,000 gas
vrfCoordinatorV2_5: address(vrfCoordinatorV2_5Mock),
link: address(link),
account: FOUNDRY_DEFAULT_SENDER
});
vm.deal(localNetworkConfig.account, 100 ether);
return localNetworkConfig;
}
}
Loading

0 comments on commit 40ea363

Please sign in to comment.