Skip to content

Commit ecce28c

Browse files
committed
final version
1 parent ed6b9ab commit ecce28c

1 file changed

Lines changed: 97 additions & 229 deletions

File tree

README.md

Lines changed: 97 additions & 229 deletions
Original file line numberDiff line numberDiff line change
@@ -1,271 +1,139 @@
1-
# 🏗 Scaffold-ETH 2
1+
# 🏗️ Ethereum Staking Challenge
22

3-
<h4 align="center">
4-
<a href="https://docs.scaffoldeth.io">Documentation</a> |
5-
<a href="https://scaffoldeth.io">Website</a>
6-
</h4>
3+
A decentralized staking application built on Ethereum that demonstrates smart contract development, time-based logic, and threshold mechanisms. This project is part of the SpeedRunEthereum challenges.
74

8-
🧪 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.
5+
## 🎯 Project Overview
96

10-
⚙️ Built using NextJS, RainbowKit, Hardhat, Wagmi, Viem, and Typescript.
7+
This staking dApp allows users to pool Ether together with a deadline and threshold mechanism. If the threshold is met before the deadline, all funds are sent to an external contract for completion. If not, users can withdraw their individual contributions.
118

12-
-**Contract Hot Reload**: Your frontend auto-adapts to your smart contract as you edit it.
13-
- 🪝 **[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.
14-
- 🧱 [**Components**](https://docs.scaffoldeth.io/components/): Collection of common web3 components to quickly build your frontend.
15-
- 🔥 **Burner Wallet & Local Faucet**: Quickly test your application with a burner wallet and local faucet.
16-
- 🔐 **Integration with Wallet Providers**: Connect to different wallet providers and interact with the Ethereum network.
9+
### Key Features
1710

18-
![Debug Contracts tab](https://github.com/scaffold-eth/scaffold-eth-2/assets/55535804/b237af0c-5027-4849-a5c1-2e31495cccb1)
11+
- **Time-bound Staking**: 72-hour staking period from contract deployment
12+
- **Threshold Mechanism**: Requires 1 ETH minimum to complete successfully
13+
- **Conditional Execution**: Automatic fund distribution or withdrawal enablement
14+
- **Event Emission**: Full transparency of staking activities
15+
- **Direct ETH Transfers**: Users can stake by simply sending ETH to the contract
1916

20-
## Requirements
17+
## 🔧 Smart Contract Architecture
2118

22-
Before you begin, you need to install the following tools:
19+
The project consists of two main contracts:
2320

24-
- [Node (>= v20.18.3)](https://nodejs.org/en/download/)
25-
- Yarn ([v1](https://classic.yarnpkg.com/en/docs/install/) or [v2+](https://yarnpkg.com/getting-started/install))
26-
- [Git](https://git-scm.com/downloads)
21+
### 1. Staker Contract
22+
The main contract that handles all staking logic, including:
23+
- User balance tracking
24+
- Deadline and threshold validation
25+
- Conditional execution based on success criteria
26+
- Withdrawal mechanism for failed stakes
2727

28-
# 🚩 Challenge 1: 🔏 Decentralized Staking App
28+
### 2. ExampleExternalContract
29+
A simple contract that serves as the completion target when staking succeeds.
2930

30-
![readme-1](https://raw.githubusercontent.com/scaffold-eth/se-2-challenges/challenge-1-decentralized-staking/extension/packages/nextjs/public/hero.png)
31+
## 🎮 How It Works
3132

32-
🦸 A superpower of Ethereum is allowing you, the builder, to create a simple set of rules that an adversarial group of players can use to work together. In this challenge, you create a decentralized application where users can coordinate a group funding effort. If the users cooperate, the money is collected in a second smart contract. If they defect, the worst that can happen is everyone gets their money back. The users only have to trust the code.
33+
1. **Staking Phase**: Users can stake ETH during the 72-hour window
34+
2. **Execution Phase**: After the deadline, anyone can call `execute()`
35+
- If ≥ 1 ETH was staked: All funds go to the external contract ✅
36+
- If < 1 ETH was staked: Withdrawals become available ❌
37+
3. **Withdrawal Phase**: Users can reclaim their ETH if the threshold wasn't met
3338

34-
🏦 Build a `Staker.sol` contract that collects **ETH** from numerous addresses using a payable `stake()` function and keeps track of `balances`. After some `deadline` if it has at least some `threshold` of ETH, it sends it to an `ExampleExternalContract` and triggers the `complete()` action sending the full balance. If not enough **ETH** is collected, allow users to `withdraw()`.
39+
## 🛠️ Technical Implementation
3540

36-
🎛 Building the frontend to display the information and UI is just as important as writing the contract. The goal is to deploy the contract and the app to allow anyone to stake using your app. Use a `Stake(address, uint256)` event to list all stakes.
41+
### Key Functions
3742

38-
> 📝 Note: If you use named arguments in your event (e.g. `event Stake(address indexed staker, uint256 amount)`), you'll need to update `/packages/nextjs/app/stakings/page.tsx` to reference event parameters by their names instead of numeric indices.
43+
- `stake()`: Accept ETH deposits and update user balances
44+
- `execute()`: Determine success/failure and distribute funds accordingly
45+
- `withdraw()`: Allow users to reclaim funds if staking failed
46+
- `timeLeft()`: Display remaining time in the staking period
47+
- `receive()`: Enable direct ETH transfers to stake automatically
3948

40-
🌟 The final deliverable is deploying a Dapp that lets users send ether to a contract and stake if the conditions are met, then `yarn vercel` your app to a public webserver. Submit the url on [SpeedRunEthereum.com](https://speedrunethereum.com)!
49+
### Security Features
4150

42-
> 💬 Meet other builders working on this challenge and get help in the [Challenge 1 Telegram](https://t.me/joinchat/E6r91UFt4oMJlt01)!
51+
- **Access Control**: `notCompleted` modifier prevents actions after completion
52+
- **Input Validation**: Zero address checks and proper require statements
53+
- **Reentrancy Protection**: Simple transfer patterns without callbacks
54+
- **State Management**: Clear separation between staking and withdrawal phases
4355

44-
---
45-
46-
## Checkpoint 0: 📦 Environment 📚
47-
48-
> Start your local network (a blockchain emulator in your computer):
49-
50-
```sh
51-
yarn chain
52-
```
53-
54-
> in a second terminal window, 🛰 deploy your contract (locally):
55-
56-
```sh
57-
yarn deploy
58-
```
59-
60-
> in a third terminal window, start your 📱 frontend:
61-
62-
```sh
63-
yarn start
64-
```
65-
66-
📱 Open http://localhost:3000 to see the app.
56+
## 🔍 Contract Details
6757

68-
> 👩‍💻 Rerun `yarn deploy` whenever you want to deploy new contracts to the frontend. If you haven't made any contract changes, you can run `yarn deploy --reset` for a completely fresh deploy.
58+
### State Variables
59+
- `threshold`: Constant 1 ETH requirement
60+
- `deadline`: 72 hours from deployment
61+
- `balances`: Individual user stake tracking
62+
- `openForWithdraw`: Withdrawal availability flag
6963

70-
🔏 Now you are ready to edit your smart contract `Staker.sol` in `packages/hardhat/contracts`
64+
### Events
65+
- `Stake(address indexed staker, uint256 deposit)`: Tracks all staking activity
7166

72-
---
67+
## 🚀 Deployment & Testing
7368

74-
⚗️ At this point you will need to know basic Solidity syntax. If not, you can pick it up quickly by tinkering with concepts from [📑 Solidity By Example](https://solidity-by-example.org/) using [🏗️ Scaffold-ETH-2](https://scaffoldeth.io). (In particular: global units, primitive data types, mappings, sending ether, and payable functions.)
69+
### Prerequisites
70+
- Node.js (v16 or higher) and yarn
71+
- Scaffold-ETH 2 framework
72+
- MetaMask or similar wallet
73+
- Git for version control
7574

76-
---
75+
### Setup
76+
```bash
77+
# Clone the scaffold-eth 2 repository
78+
git clone https://github.com/scaffold-eth/scaffold-eth-2.git staking-challenge
79+
cd staking-challenge
7780

78-
## Checkpoint 1: 🔏 Staking 💵
81+
# Install dependencies
82+
yarn install
7983

80-
You'll need to track individual `balances` using a mapping:
81-
82-
```solidity
83-
mapping ( address => uint256 ) public balances;
84-
```
84+
# Start your local blockchain
85+
yarn chain
8586

86-
And also track a constant `threshold` at `1 ether`
87+
# In a new terminal, deploy the contracts
88+
yarn deploy
8789

88-
```solidity
89-
uint256 public constant threshold = 1 ether;
90+
# In another terminal, start the frontend
91+
yarn start
9092
```
9193

92-
> 👩‍💻 Write your `stake()` function and test it with the `Debug Contracts` tab in the frontend.
93-
94-
![debugContracts](https://github.com/scaffold-eth/se-2-challenges/assets/55535804/1a888e31-a79b-49ef-9848-357c5cee445a)
95-
96-
> 💸 Need more funds from the faucet? Click on _"Grab funds from faucet"_, or use the Faucet feature at the bottom left of the page to get as much as you need!
97-
98-
![Faucet](https://github.com/scaffold-eth/se-2-challenges/assets/55535804/e82e3100-20fb-4886-a6bf-4113c3729f53)
99-
100-
> ✏ Need to troubleshoot your code? If you import `hardhat/console.sol` to your contract, you can call `console.log()` right in your Solidity code. The output will appear in your `yarn chain` terminal.
101-
102-
### 🥅 Goals
103-
104-
- [ ] Do you see the balance of the `Staker` contract go up when you `stake()`?
105-
- [ ] Is your `balance` correctly tracked?
106-
- [ ] Do you see the events in the `Stake Events` tab?
107-
108-
![allStakings](https://github.com/scaffold-eth/se-2-challenges/assets/55535804/80bcc843-034c-4547-8535-129ed494a204)
109-
110-
---
111-
112-
## Checkpoint 2: 🔬 State Machine / Timing ⏱
113-
114-
### State Machine
115-
116-
> ⚙️ Think of your smart contract like a _state machine_. First, there is a **stake** period. Then, if you have gathered the `threshold` worth of ETH, there is a **success** state. Or, we go into a **withdraw** state to let users withdraw their funds.
117-
118-
Set a `deadline` of `block.timestamp + 30 seconds`
119-
120-
```solidity
121-
uint256 public deadline = block.timestamp + 30 seconds;
94+
### Test Coverage
95+
```bash
96+
# Run all tests
97+
yarn test
12298
```
12399

124-
👨‍🏫 Smart contracts can't execute automatically, you always need to have a transaction execute to change state. Because of this, you will need to have an `execute()` function that _anyone_ can call, just once, after the `deadline` has expired.
125-
126-
> 👩‍💻 Write your `execute()` function and test it with the `Debug Contracts` tab
127-
128-
> Check the `ExampleExternalContract.sol` for the bool you can use to test if it has been completed or not. But do not edit the `ExampleExternalContract.sol` as it can slow the auto grading.
129-
130-
If the `address(this).balance` of the contract is over the `threshold` by the `deadline`, you will want to call: `exampleExternalContract.complete{value: address(this).balance}()`
100+
- Successful staking scenarios
101+
- Failed staking and withdrawal flows
102+
- Time-based execution logic
103+
- Edge cases and error conditions
131104

132-
If the balance is less than the `threshold`, you want to set a `openForWithdraw` bool to `true` which will allow users to `withdraw()` their funds.
105+
## 🎓 Learning Outcomes
133106

134-
### Timing
107+
This project demonstrates proficiency in:
135108

136-
You'll have 30 seconds after deploying until the deadline is reached, you can adjust this in the contract.
109+
- **Solidity Development**: Advanced contract patterns and modifiers
110+
- **Time-based Logic**: Deadline mechanisms and conditional execution
111+
- **State Management**: Complex multi-phase contract workflows
112+
- **Event Handling**: Proper logging and frontend integration
113+
- **Security Best Practices**: Input validation and access control
114+
- **Gas Optimization**: Efficient storage patterns and function design
137115

138-
> 👩‍💻 Create a `timeLeft()` function including `public view returns (uint256)` that returns how much time is left.
116+
## 🔗 Links & Deployment
139117

140-
⚠️ Be careful! If `block.timestamp >= deadline` you want to `return 0;`
118+
- [SpeedRunEthereum Challenge](https://speedrunethereum.com/)
119+
- [Live Demo](#) (https://stakingdapp-az0c7q6ro-einarmigs-projects.vercel.app)
141120

142-
_"Time Left"_ will only update if a transaction occurs. You can see the time update by getting funds from the faucet button in navbar just to trigger a new block.
121+
### Contract Addresses
122+
- **Staker Contract**: `0x333935AC52d6ecb67407478841D778B52E04d9b8`
123+
- **ExampleExternalContract**: `0x8aaB1AdFd7e261b0E5b852Efc4a93251a27AE3b4`
143124

144-
![stakerUI](https://github.com/scaffold-eth/se-2-challenges/assets/55535804/7d85badb-3ea3-4f3c-b5f8-43d5b64f6714)
145-
146-
> 👩‍💻 You can call `yarn deploy --reset` any time you want a fresh contract, it will get re-deployed even if there are no changes on it.
147-
> You may need it when you want to reload the _"Time Left"_ of your tests.
148-
149-
Your `Staker UI` tab should be almost done and working at this point.
150-
151-
---
152-
153-
### 🥅 Goals
154-
155-
- [ ] Can you see `timeLeft` counting down in the `Staker UI` tab when you trigger a transaction with the faucet button?
156-
- [ ] If enough ETH is staked by the deadline, does your `execute()` function correctly call `complete()` and stake the ETH?
157-
- [ ] If the threshold isn't met by the deadline, are you able to `withdraw()` your funds?
158-
159-
---
160-
161-
## Checkpoint 3: 💵 Receive Function / UX 🙎
162-
163-
🎀 To improve the user experience, set your contract up so it accepts ETH sent to it and calls `stake()`. You will use what is called the `receive()` function.
164-
165-
> Use the [receive()](https://docs.soliditylang.org/en/v0.8.9/contracts.html?highlight=receive#receive-ether-function) function in solidity to "catch" ETH sent to the contract and call `stake()` to update `balances`.
166-
167-
---
125+
### Contract Verification
126+
- [Staker Contract on Etherscan](#) *(sepolia.etherscan.io/address/0x333935AC52d6ecb67407478841D778B52E04d9b8)*
127+
- [ExampleExternalContract on Etherscan](#) *(sepolia.etherscan.io/address/0x8aaB1AdFd7e261b0E5b852Efc4a93251a27AE3b4)*
168128

169-
### 🥅 Goals
129+
## 🏆 Challenge Completion
170130

171-
- [ ] If you send ETH directly to the contract address does it update your `balance` and the `balance` of the contract?
131+
- ✅ Smart contracts deployed and verified
132+
- ✅ Frontend integration complete
133+
- ✅ All tests passing
134+
- ✅ Proper documentation and comments
135+
- ✅ Gas optimizations implemented
172136

173137
---
174138

175-
### ⚔️ Side Quests
176-
177-
- [ ] Can `execute()` get called more than once, and is that okay?
178-
- [ ] Can you stake and withdraw freely after the `deadline`, and is that okay?
179-
- [ ] What are other implications of _anyone_ being able to withdraw for someone?
180-
181-
---
182-
183-
### 🐸 It's a trap!
184-
185-
- [ ] Make sure funds can't get trapped in the contract! **Try sending funds after you have executed! What happens?**
186-
- [ ] Try to create a [modifier](https://solidity-by-example.org/function-modifier/) called `notCompleted`. It will check that `ExampleExternalContract` is not completed yet. Use it to protect your `execute` and `withdraw` functions.
187-
188-
### ⚠️ Test it!
189-
190-
- Now is a good time to run `yarn test` to run the automated testing function. It will test that you hit the core checkpoints. You are looking for all green checkmarks and passing tests!
191-
192-
---
193-
194-
## Checkpoint 4: 💾 Deploy your contract! 🛰
195-
196-
📡 Edit the `defaultNetwork` to [your choice of public EVM networks](https://ethereum.org/en/developers/docs/networks/) in `packages/hardhat/hardhat.config.ts`
197-
198-
🔐 You will need to generate a **deployer address** using `yarn generate` This creates a mnemonic and saves it locally.
199-
200-
👩‍🚀 Use `yarn account` to view your deployer account balances.
201-
202-
⛽️ You will need to send ETH to your deployer address with your wallet, or get it from a public faucet of your chosen network.
203-
204-
> 📝 If you plan on submitting this challenge, be sure to set your `deadline` to at least `block.timestamp + 72 hours`
205-
206-
🚀 Run `yarn deploy` to deploy your smart contract to a public network (selected in `hardhat.config.ts`)
207-
208-
> 💬 Hint: You can set the `defaultNetwork` in `hardhat.config.ts` to `sepolia` or `optimismSepolia` **OR** you can `yarn deploy --network sepolia` or `yarn deploy --network optimismSepolia`.
209-
210-
![allStakings-blockFrom](https://github.com/scaffold-eth/se-2-challenges/assets/55535804/04725dc8-4a8d-4089-ba82-90f9b94bfbda)
211-
212-
> 💬 Hint: For faster loading of your _"Stake Events"_ page, consider updating the `fromBlock` passed to `useScaffoldEventHistory` in [`packages/nextjs/app/stakings/page.tsx`](https://github.com/scaffold-eth/se-2-challenges/blob/challenge-1-decentralized-staking/packages/nextjs/app/stakings/page.tsx) to `blocknumber - 10` at which your contract was deployed. Example: `fromBlock: 3750241n` (where `n` represents its a [BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt)). To find this blocknumber, search your contract's address on Etherscan, find the `More Info` box, find the `Contract Creator` line, click on the `txn`, and find the value for `Block`.
213-
214-
---
215-
216-
## Checkpoint 5: 🚢 Ship your frontend! 🚁
217-
218-
✏️ Edit your frontend config in `packages/nextjs/scaffold.config.ts` to change the `targetNetwork` to `chains.sepolia` (or `chains.optimismSepolia` if you deployed to OP Sepolia)
219-
220-
💻 View your frontend at http://localhost:3000/staker-ui and verify you see the correct network.
221-
222-
📡 When you are ready to ship the frontend app...
223-
224-
📦 Run `yarn vercel` to package up your frontend and deploy.
225-
226-
> You might need to log in to Vercel first by running `yarn vercel:login`. Once you log in (email, GitHub, etc), the default options should work.
227-
228-
> If you want to redeploy to the same production URL you can run `yarn vercel --prod`. If you omit the `--prod` flag it will deploy it to a preview/test URL.
229-
230-
> Follow the steps to deploy to Vercel. It'll give you a public URL.
231-
232-
> 🦊 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 `onlyLocalBurnerWallet: false` in your frontend config (`scaffold.config.ts` in `packages/nextjs/`)
233-
234-
#### Configuration of Third-Party Services for Production-Grade Apps.
235-
236-
By default, 🏗 Scaffold-ETH 2 provides predefined API keys for popular services such as Alchemy and Etherscan. This allows you to begin developing and testing your applications more easily, avoiding the need to register for these services.
237-
This is great to complete your **SpeedRunEthereum**.
238-
239-
For production-grade applications, it's recommended to obtain your own API keys (to prevent rate limiting issues). You can configure these at:
240-
241-
- 🔷`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/).
242-
243-
- 📃`ETHERSCAN_API_KEY` variable in `packages/hardhat/.env` with your generated API key. You can get your key [here](https://etherscan.io/myapikey).
244-
245-
> 💬 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.
246-
247-
---
248-
249-
## Checkpoint 6: 📜 Contract Verification
250-
251-
Run the `yarn verify --network your_network` command to verify your contracts on etherscan 🛰
252-
253-
👉 Search this address on [Sepolia Etherscan](https://sepolia.etherscan.io/) (or [Optimism Sepolia Etherscan](https://sepolia-optimism.etherscan.io/) if you deployed to OP Sepolia) to get the URL you submit to 🏃‍♀️[SpeedRunEthereum.com](https://speedrunethereum.com).
254-
255-
---
256-
257-
> 🏃 Head to your next challenge [here](https://speedrunethereum.com).
258-
259-
> 💬 Problems, questions, comments on the stack? Post them to the [🏗 scaffold-eth developers chat](https://t.me/joinchat/F7nCRK3kI93PoCOk)
260-
261-
## Documentation
262-
263-
Visit our [docs](https://docs.scaffoldeth.io) to learn how to start building with Scaffold-ETH 2.
264-
265-
To know more about its features, check out our [website](https://scaffoldeth.io).
266-
267-
## Contributing to Scaffold-ETH 2
268-
269-
We welcome contributions to Scaffold-ETH 2!
270-
271-
Please see [CONTRIBUTING.MD](https://github.com/scaffold-eth/scaffold-eth-2/blob/main/CONTRIBUTING.md) for more information and guidelines for contributing to Scaffold-ETH 2.
139+
*Built with ❤️ as part of the Ethereum developer journey*

0 commit comments

Comments
 (0)