Skip to content

Commit 397e21d

Browse files
authored
Merge pull request #440 from scaffold-eth/challenge-oracles-foundry-v2
Foundry support - Challenge-oracles
2 parents 8c256ac + 4d7b3c2 commit 397e21d

36 files changed

Lines changed: 4606 additions & 574 deletions

README.md

Lines changed: 185 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,25 @@ Oracles are bridges between blockchains and the external world. They solve a fun
4646

4747
## Checkpoint 0: 📦 Environment 📚
4848

49+
Before you begin, you need to install the following tools:
50+
51+
- [Node (>= v18.18)](https://nodejs.org/en/download/)
52+
- Yarn ([v1](https://classic.yarnpkg.com/en/docs/install/) or [v2+](https://yarnpkg.com/getting-started/install))
53+
- [Git](https://git-scm.com/downloads)
54+
- [Foundry](https://book.getfoundry.sh/getting-started/installation) (only if choosing Foundry as your solidity framework)
55+
4956
> 💻 Start your local network (a blockchain emulator in your computer):
5057
5158
```sh
5259

53-
npx create-eth@2.0.13 -e challenge-oracles challenge-oracles
60+
npx create-eth@2.0.18 -e challenge-oracles challenge-oracles
5461

5562
cd challenge-oracles
5663

5764
```
5865

66+
> When prompted to choose a Solidity framework, you can pick either **Hardhat** or **Foundry**. Both are fully supported. The screenshots in this guide may show one or the other, but the concepts are identical.
67+
5968
> 💻 In the same terminal, start your local network (a blockchain emulator in your computer):
6069
6170
```sh
@@ -98,8 +107,19 @@ yarn start
98107

99108
### 🔗 Simple Oracle - The Building Block
100109

110+
<Tabs>
111+
<Tab label="Hardhat">
112+
101113
🔍 Open the `packages/hardhat/contracts/00_Whitelist/SimpleOracle.sol` file to examine the basic oracle functionality.
102114

115+
</Tab>
116+
<Tab label="Foundry">
117+
118+
🔍 Open the `packages/foundry/contracts/00_Whitelist/SimpleOracle.sol` file to examine the basic oracle functionality.
119+
120+
</Tab>
121+
</Tabs>
122+
103123
#### 📖 Understanding the Code:
104124

105125
🧩 The `SimpleOracle` contract is the fundamental building block of this oracle system:
@@ -128,8 +148,19 @@ yarn start
128148

129149
🎯 **Your Mission**: Complete the missing function implementations in the `WhitelistOracle.sol` contract.
130150

151+
<Tabs>
152+
<Tab label="Hardhat">
153+
131154
🔍 Open the `packages/hardhat/contracts/00_Whitelist/WhitelistOracle.sol` file to implement the whitelist oracle functionality.
132155

156+
</Tab>
157+
<Tab label="Foundry">
158+
159+
🔍 Open the `packages/foundry/contracts/00_Whitelist/WhitelistOracle.sol` file to implement the whitelist oracle functionality.
160+
161+
</Tab>
162+
</Tabs>
163+
133164
#### 📖 Understanding the Relationship:
134165

135166
The `WhitelistOracle` contract **creates and manages multiple SimpleOracle contracts**:
@@ -335,7 +366,7 @@ function getActiveOracleNodes() public view returns (address[] memory) {
335366
336367
for (uint256 i = 0; i < oracles.length; i++) {
337368
(, uint256 timestamp) = oracles[i].getPrice();
338-
if (timestamp > block.timestamp - STALE_DATA_WINDOW) {
369+
if (block.timestamp - timestamp < STALE_DATA_WINDOW) {
339370
tempNodes[count] = address(oracles[i]);
340371
count++;
341372
}
@@ -430,14 +461,31 @@ WhitelistOracle → getPrice() → [100, 102, 98] → sort → [98, 100, 102]
430461

431462
🔍 Run the following command to check if you implemented the functions correctly.
432463

433-
```sh
464+
<Tabs>
465+
<Tab label="Hardhat">
434466

435-
yarn test --grep "Checkpoint1"
467+
**Hardhat**
436468

469+
```shell
470+
yarn test --grep "Checkpoint1"
437471
```
438472

439473
✅ Did the tests pass? You can dig into any errors by viewing the tests at `packages/hardhat/test/WhitelistOracle.ts`.
440474

475+
</Tab>
476+
<Tab label="Foundry">
477+
478+
**Foundry**
479+
480+
```shell
481+
yarn test --match-test "Checkpoint1"
482+
```
483+
484+
✅ Did the tests pass? You can dig into any errors by viewing the tests at `packages/foundry/test/WhitelistOracle.t.sol`.
485+
486+
</Tab>
487+
</Tabs>
488+
441489
### Try it out!
442490

443491
🔄 Run `yarn deploy --reset` then test the whitelist oracle. Try adding and removing oracles, and observing how the aggregated price changes.
@@ -486,8 +534,19 @@ yarn simulate:whitelist
486534

487535
🎯 **Your Mission**: Complete the missing function implementations in the `StakingOracle.sol` contract. The contract skeleton is already provided with all the necessary structs, events, and modifiers but you need to fill in the logic.
488536

537+
<Tabs>
538+
<Tab label="Hardhat">
539+
489540
🔍 Open the `packages/hardhat/contracts/01_Staking/StakingOracle.sol` file to implement the staking oracle functionality.
490541

542+
</Tab>
543+
<Tab label="Foundry">
544+
545+
🔍 Open the `packages/foundry/contracts/01_Staking/StakingOracle.sol` file to implement the staking oracle functionality.
546+
547+
</Tab>
548+
</Tabs>
549+
491550
### ✏️ Tasks:
492551

493552
1. **Implement `getCurrentBucketNumber()`**
@@ -1179,14 +1238,31 @@ function exitNode(uint256 index) public onlyNode {
11791238

11801239
🔍 Run the following command to check if you implemented the functions correctly.
11811240

1182-
```sh
1241+
<Tabs>
1242+
<Tab label="Hardhat">
11831243

1184-
yarn test --grep "Checkpoint2"
1244+
**Hardhat**
11851245

1246+
```shell
1247+
yarn test --grep "Checkpoint2"
11861248
```
11871249

11881250
✅ Did the tests pass? You can dig into any errors by viewing the tests at `packages/hardhat/test/StakingOracle.ts`.
11891251

1252+
</Tab>
1253+
<Tab label="Foundry">
1254+
1255+
**Foundry**
1256+
1257+
```shell
1258+
yarn test --match-test "Checkpoint2"
1259+
```
1260+
1261+
✅ Did the tests pass? You can dig into any errors by viewing the tests at `packages/foundry/test/StakingOracle.t.sol`.
1262+
1263+
</Tab>
1264+
</Tabs>
1265+
11901266
### Try it out!
11911267

11921268
🔄 Run `yarn deploy --reset` then test the staking oracle. Go to the `Staking` page and try registering your own node and reporting prices.
@@ -1302,8 +1378,19 @@ AUTO_SLASH=true yarn simulate:staking
13021378

13031379
🧪 **Testing Strategy**: Each function you implement can be tested individually using the provided test suite. Run `yarn test` after implementing each function to verify your solution works correctly.
13041380

1381+
<Tabs>
1382+
<Tab label="Hardhat">
1383+
13051384
🔍 Open the `packages/hardhat/contracts/02_Optimistic/OptimisticOracle.sol` file to implement the optimistic oracle functionality.
13061385

1386+
</Tab>
1387+
<Tab label="Foundry">
1388+
1389+
🔍 Open the `packages/foundry/contracts/02_Optimistic/OptimisticOracle.sol` file to implement the optimistic oracle functionality.
1390+
1391+
</Tab>
1392+
</Tabs>
1393+
13071394
### ✏️ Tasks:
13081395

13091396
1. **Implement `assertEvent(string memory description, uint256 startTime, uint256 endTime)`**
@@ -1485,12 +1572,27 @@ The bond amount should be the bond set on the assertion. The same amount that th
14851572

14861573
🔍 Run the following command to check if you implemented the functions correctly.
14871574

1488-
```sh
1575+
<Tabs>
1576+
<Tab label="Hardhat">
14891577

1578+
**Hardhat**
1579+
1580+
```shell
14901581
yarn test --grep "Checkpoint4"
1582+
```
1583+
1584+
</Tab>
1585+
<Tab label="Foundry">
14911586

1587+
**Foundry**
1588+
1589+
```shell
1590+
yarn test --match-test "Checkpoint4"
14921591
```
14931592

1593+
</Tab>
1594+
</Tabs>
1595+
14941596
### 🥅 Goals:
14951597

14961598
- You can assert events with descriptions and time windows
@@ -1733,12 +1835,27 @@ Then set the winner to the proposer if the proposer was correct _or_ set it to t
17331835

17341836
🔍 Run the following command to check if you implemented the functions correctly.
17351837

1736-
```sh
1838+
<Tabs>
1839+
<Tab label="Hardhat">
1840+
1841+
**Hardhat**
17371842

1843+
```shell
17381844
yarn test --grep "Checkpoint5"
1845+
```
1846+
1847+
</Tab>
1848+
<Tab label="Foundry">
1849+
1850+
**Foundry**
17391851

1852+
```shell
1853+
yarn test --match-test "Checkpoint5"
17401854
```
17411855

1856+
</Tab>
1857+
</Tabs>
1858+
17421859
### 🥅 Goals:
17431860

17441861
- Proposers can claim rewards for undisputed assertions
@@ -1861,14 +1978,31 @@ The important thing here is that it reverts if it is not settled and if it has b
18611978

18621979
🔍 Run the following command to check if you implemented the functions correctly.
18631980

1864-
```sh
1981+
<Tabs>
1982+
<Tab label="Hardhat">
18651983

1866-
yarn test --grep "Checkpoint6"
1984+
**Hardhat**
18671985

1986+
```shell
1987+
yarn test --grep "Checkpoint6"
18681988
```
18691989

18701990
✅ Did the tests pass? You can dig into any errors by viewing the tests at `packages/hardhat/test/OptimisticOracle.ts`.
18711991

1992+
</Tab>
1993+
<Tab label="Foundry">
1994+
1995+
**Foundry**
1996+
1997+
```shell
1998+
yarn test --match-test "Checkpoint6"
1999+
```
2000+
2001+
✅ Did the tests pass? You can dig into any errors by viewing the tests at `packages/foundry/test/OptimisticOracle.t.sol`.
2002+
2003+
</Tab>
2004+
</Tabs>
2005+
18722006
### Try it out!
18732007

18742008
🔄 Run `yarn deploy --reset` then test the optimistic oracle. Try creating assertions, proposing outcomes, and disputing them.
@@ -1980,18 +2114,29 @@ Each oracle design solves different problems:
19802114

19812115
🎉 Well done on building the optimistic oracle system! Now, let's get it on a public testnet.
19822116

1983-
📡 Edit the `defaultNetwork` to [your choice of public EVM networks](https://ethereum.org/en/developers/docs/networks/) in `packages/hardhat/hardhat.config.ts` (e.g., `sepolia`).
1984-
19852117
🔐 You will need to generate a **deployer address** using `yarn generate`. This creates a mnemonic and saves it locally.
19862118

19872119
👩‍🚀 Use `yarn account` to view your deployer account balances.
19882120

19892121
⛽️ You will need to send ETH to your **deployer address** with your wallet, or get it from a public faucet of your chosen network.
19902122

2123+
<Tabs>
2124+
<Tab label="Hardhat">
2125+
2126+
📡 Edit the `defaultNetwork` to [your choice of public EVM networks](https://ethereum.org/en/developers/docs/networks/) in `packages/hardhat/hardhat.config.ts` (e.g., `sepolia`).
2127+
19912128
🚀 Run `yarn deploy` to deploy your optimistic oracle contracts to a public network (selected in `hardhat.config.ts`)
19922129

19932130
> 💬 Hint: You can set the `defaultNetwork` in `hardhat.config.ts` to `sepolia` **OR** you can `yarn deploy --network sepolia`.
19942131
2132+
</Tab>
2133+
<Tab label="Foundry">
2134+
2135+
🚀 Run `yarn deploy --network sepolia` to deploy your optimistic oracle contracts to Sepolia testnet.
2136+
2137+
</Tab>
2138+
</Tabs>
2139+
19952140
---
19962141

19972142
## Checkpoint 9: 🚢 Ship your frontend! 🚁
@@ -2010,7 +2155,7 @@ Each oracle design solves different problems:
20102155
20112156
> Follow the steps to deploy to Vercel. It'll give you a public URL.
20122157
2013-
> 🦊 Since we have deployed to a public testnet, you will now need to connect using a wallet you own or use a burner wallet. By default 🔥 `burner wallets` are only available on `hardhat` . You can enable them on every chain by setting `burnerWalletMode: "allNetworks"` in your frontend config (`scaffold.config.ts` in `packages/nextjs/`)
2158+
> 🦊 Since we have deployed to a public testnet, you will now need to connect using a wallet you own or use a burner wallet. By default 🔥 `burner wallets` are only available on `localhost`. You can enable them on every chain by setting `burnerWalletMode: "allNetworks"` in your frontend config (`scaffold.config.ts` in `packages/nextjs/`)
20142159
20152160
#### Configuration of Third-Party Services for Production-Grade Apps.
20162161

@@ -2020,9 +2165,21 @@ This is great to complete your **Speedrun Ethereum**.
20202165

20212166
For production-grade applications, it's recommended to obtain your own API keys (to prevent rate limiting issues). You can configure these at:
20222167

2168+
<Tabs>
2169+
<Tab label="Hardhat">
2170+
20232171
- 🔷`ALCHEMY_API_KEY` variable in `packages/hardhat/.env` and `packages/nextjs/.env.local`. You can create API keys from the [Alchemy dashboard](https://dashboard.alchemy.com/).
20242172
- 📃`ETHERSCAN_API_KEY` variable in `packages/hardhat/.env` with your generated API key. You can get your key [here](https://etherscan.io/myapikey).
20252173

2174+
</Tab>
2175+
<Tab label="Foundry">
2176+
2177+
- 🔷`ALCHEMY_API_KEY` variable in `packages/foundry/.env` and `packages/nextjs/.env.local`. You can create API keys from the [Alchemy dashboard](https://dashboard.alchemy.com/).
2178+
- 📃`ETHERSCAN_API_KEY` variable in `packages/foundry/.env` with your generated API key. You can get your key [here](https://etherscan.io/myapikey).
2179+
2180+
</Tab>
2181+
</Tabs>
2182+
20262183
> 💬 Hint: It's recommended to store env's for nextjs in Vercel/system env config for live apps and use .env.local for local testing.
20272184
20282185
---
@@ -2054,3 +2211,18 @@ Oracles are fundamental infrastructure for the decentralized web. They enable sm
20542211
🚀 As you continue your blockchain development journey, you'll encounter many variations and combinations of these patterns. Understanding the fundamental trade-offs will help you choose the right oracle design for your specific use case.
20552212

20562213
🧠 Remember: the best oracle is the one that provides the right balance of security, speed, flexibility and cost for your application's needs!
2214+
2215+
## 🤖 AI-Guided Learning Mode (Optional)
2216+
2217+
This challenge supports an interactive AI learning mode. Instead of working through the checkpoints on your own, you can have an AI guide you step-by-step.
2218+
2219+
### Quick Start
2220+
Run `/start` in your AI-enabled IDE (Cursor, VS Code with Claude, etc.) to begin.
2221+
2222+
### Commands
2223+
- `/start` — Begin or resume the challenge
2224+
- `/skip` — Skip current task (AI writes + explains the solution)
2225+
- `hint` — Get contextual help anytime
2226+
- `check` — Validate your current code
2227+
2228+
> 📝 Your progress is saved automatically in `.challenge-ai/progress.json`.

0 commit comments

Comments
 (0)