Skip to content

Commit 4b3ff14

Browse files
committed
Update contracts, style Cypherpunk, script deploy and pages UI token-vendor
1 parent 51f71ca commit 4b3ff14

File tree

16 files changed

+1764
-172
lines changed

16 files changed

+1764
-172
lines changed

README.md

Lines changed: 228 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1-
# 🚩 Challenge {challengeNum}: {challengeEmoji} {challengeTitle}
1+
# 🚩 Challenge #2: 🏵 Token Vendor 🤖
22

3-
{challengeHeroImage}
3+
![readme-2](https://raw.githubusercontent.com/Quantum3-Labs/speedrunstark/token-vendor/packages/nextjs/public/hero2.png)
44

5-
A {challengeDescription}.
5+
🤖 Smart contracts are kind of like "always on" _vending machines_ that **anyone** can access. Let's make a decentralized, digital currency. Then, let's build an unstoppable vending machine that will buy and sell the currency. We'll learn about the "approve" pattern for ERC20s and how contract to contract interactions work.
66

7-
🌟 The final deliverable is an app that {challengeDeliverable}.
8-
Deploy your contracts to a testnet then build and upload your app to a public web server. Submit the url on [SpeedRunStark.com](https://speedrunstark.com/)!
7+
🏵 Create `YourToken.cairo` smart contract that inherits the **ERC20** token standard from OpenZeppelin. Set `your token` to `_mint()` **1000** \* (10^18) tokens to the `recipient` account address. Then create a `Vendor.cairo` contract that sells `your token` using a `buy_tokens()` function.
98

10-
💬 Meet other builders working on this challenge and get help in the {challengeTelegramLink}
9+
🎛 Edit the frontend that invites the user to input an amount of tokens they want to buy. We'll display a preview of the amount of ETH it will cost with a confirm button.
10+
11+
🌟 The final deliverable is an app that lets users purchase your ERC20 token, transfer it, and sell it back to the vendor. Deploy your contracts on your public chain of choice and then `yarn vercel` your app to a public web server.
12+
13+
> 💬 Meet other builders working on this challenge or get help in the [Builders telegram chat](https://t.me/+wO3PtlRAreo4MDI9)!
1114
1215
---
1316

@@ -30,44 +33,250 @@ Make sure you have the compatible versions otherwise refer to [Scaffold-Stark Re
3033
Then download the challenge to your computer and install dependencies by running:
3134

3235
```sh
33-
git clone https://github.com/Quantum3-Labs/speedrunstark.git --recurse-submodules {challengeName}
34-
cd {challengeName}
35-
git checkout {challengeName}
36+
git clone https://github.com/Quantum3-Labs/speedrunstark.git --recurse-submodules token-vendor
37+
cd token-vendor
38+
git checkout token-vendor
3639
yarn install
3740
```
3841

39-
> in the same terminal, start your local network (a local instance of a blockchain):
42+
> in the same terminal, start your local network (a blockchain emulator in your computer):
4043
41-
```sh
44+
```bash
4245
yarn chain
4346
```
4447

4548
> in a second terminal window, 🛰 deploy your contract (locally):
4649
4750
```sh
48-
cd <challenge_folder_name>
51+
cd token-vendor
4952
yarn deploy
5053
```
5154

5255
> in a third terminal window, start your 📱 frontend:
5356
5457
```sh
55-
cd <challenge_folder_name>
58+
cd token-vendor
5659
yarn start
5760
```
5861

59-
📱 Open http://localhost:3000 to see the app.
62+
📱 Open <http://localhost:3000> to see the app.
63+
64+
> 👩‍💻 Rerun `yarn deploy` whenever you want to deploy new contracts to the frontend.
65+
---
66+
67+
## Checkpoint 1: 🏵Your Token 💵
68+
69+
> 👩‍💻 Edit `YourToken.cairo` to reuse the **ERC20** token standard from OpenZeppelin. To accomplish this, you can use [`Cairo Components`](https://book.cairo-lang.org/ch16-02-00-composability-and-components.html) to embed the `ERC20` logic inside your contract.
70+
71+
> Mint **1000** (\* 10 \*\* 18) to your frontend address using the `constructor()`. In devnet, by default we choose the first pre-deployed account: `0x64b48806902a367c8598f4f95c305e8c1a1acba5f082d294a43793113115691`, to deploy the contracts. In order to complete this checkpoint, you need to connect to devnet using the same address.
72+
73+
(Your frontend address is the address in the top right of <http://localhost:3000>)
74+
75+
> You can `yarn deploy` to deploy your contract until you get it right.
76+
77+
### 🥅 Goals
78+
79+
- [ ] Can you check the `balance_of()` your frontend address in the `Debug Contracts` tab? (**YourToken** contract)
80+
- [ ] Can you `transfer()` your token to another account and check _that_ account's `balance_of`?
6081

61-
> 👩‍💻 Rerun `yarn deploy --reset` whenever you want to deploy new contracts to the frontend, update your current contracts with changes, or re-deploy it to get a fresh contract address.
82+
![debugContractsYourToken](https://raw.githubusercontent.com/Quantum3-Labs/speedrunstark/token-vendor/packages/nextjs/public/ch2-YourToken.png)
6283

63-
🔏 Now you are ready to edit your smart contract `{YourCollectible.cairo}` in `packages/snfoundry/contracts`
84+
> 💬 Hint: In Devnet, use the `switch account` feature to select a different pre-deployed account address and try sending to that new address. Can use the `transfer()` function in the `Debug Contracts` tab.
6485
6586
---
6687

88+
## Checkpoint 2: ⚖️ Vendor 🤖
89+
90+
> 👩‍💻 Edit the `Vendor.cairo` contract with a `buy_tokens()` function
91+
92+
Use a price variable named `tokensPerEth` set to **100**:
93+
94+
```cairo
95+
const TokensPerEth: u256 = 100;
96+
```
97+
98+
> 📝 The `buy_tokens()` function in `Vendor.cairo` should use `eth_amount_wei` value and `tokensPerEth` to calculate an amount of tokens to `transfer`(self.your_token.read().transfer()) to `recipient`.
99+
100+
> 📟 Emit **event** `BuyTokens {buyer: ContractAddress, eth_amount: u256, tokens_amount: u256}` when tokens are purchased.
101+
102+
Edit `packages/snfoundry/scripts-ts/deploy.ts` to deploy the `Vendor` (uncomment Vendor deploy lines).
103+
104+
Create a `tokens_per_eth` function in `Vendor.cairo` that returns the `tokensPerEth` value.
105+
106+
Uncomment the `Buy Tokens` sections in `packages/nextjs/app/token-vendor/page.tsx` to show the UI to buy tokens on the Token Vendor tab.
107+
108+
### 🥅 Goals
109+
110+
- [ ] When you try to buy tokens from the vendor, you should get an error: **'u256_sub Overflow'**. This error is related to the `transfer_from`, `transfer`, approve function in the `YourToken` contract.
111+
112+
⚠️ You might face this error because the Vendor contract doesn't have any `YourToken` yet!. You can create an `assert` in the `buy_tokens()` function to check if the Vendor has enough tokens to sell.
113+
114+
⚔️ Side Quest: send tokens from your frontend address to the Vendor contract address and _then_ try to buy them.
115+
116+
> ✏️ We can't hard code the vendor address like we did above when deploying to the network because we won't know the vendor address at the time we create the token contract.
117+
118+
> ✏️ So instead, edit `YourToken.cairo` to mint the tokens to the `recipient` (deployer) in the **constructor()**.
119+
120+
> ✏️ Then, edit `packages/snfoundry/scripts-ts/deploy.ts` to transfer 1000 tokens to vendor address.
121+
122+
```ts
123+
await deployer_v6.execute(
124+
[
125+
{
126+
contractAddress: your_token.address,
127+
calldata: [
128+
vendor.address,
129+
{
130+
low: 1_000_000_000_000_000_000_000n, //1000 * 10^18
131+
high: 0,
132+
}
133+
],
134+
entrypoint: "transfer",
135+
}
136+
],
137+
{
138+
maxFee: 1e18
139+
}
140+
);
141+
```
142+
143+
> 🔎 Look in `packages/nextjs/app/token-vendor/page.tsx` for code to uncomment to display the Vendor ETH and Token balances.
144+
145+
> You can `yarn deploy` to deploy your contract until you get it right.
146+
147+
![TokenVendorBuy](https://raw.githubusercontent.com/Quantum3-Labs/speedrunstark/token-vendor/packages/nextjs/public/ch2-TokenVendorBalance.png)
148+
149+
### 🥅 Goals
150+
151+
- [ ] Does the `Vendor` address start with a `balanceOf` **1000** in `YourToken` on the `Debug Contracts` tab?
152+
- [ ] Can you buy **10** tokens for **0.1** ETH?
153+
- [ ] Can you transfer tokens to a different account?
154+
155+
> 📝 Edit `Vendor.cairo` to reuse _Ownable_ component from OpenZeppelin.
156+
157+
```cairo
158+
#[storage]
159+
struct Storage {
160+
...
161+
#[substorage(v0)]
162+
ownable: OwnableComponent::Storage,
163+
}
164+
```
165+
166+
In `Vendor.cairo` you will need to add one more input parameter to setup the `owner` in the `constructor()`.
167+
168+
> ✏️ Then, edit `packages/snfoundry/scripts-ts/deploy.ts` to deploy the `Vendor` contract with the `owner` address.
169+
170+
```ts
171+
const vendor = await deployContract(
172+
{
173+
token_address: your_token.address,
174+
owner: deployer.address,
175+
},
176+
"Vendor"
177+
);
178+
```
179+
180+
### 🥅 Goals
181+
182+
- [ ] Is your frontend address the `owner` of the `Vendor`?
183+
184+
> 📝 Finally, add a `withdraw()` function in `Vendor.cairo` that lets the owner withdraw all the ETH from the vendor contract.
185+
186+
### 🥅 Goals
187+
188+
- [ ] Can **only** the `owner` withdraw the ETH from the `Vendor`?
189+
67190
### ⚔️ Side Quests
68191

69-
_To finish your README, can add these links_
192+
- [ ] What if you minted **2000** and only sent **1000** to the `Vendor`?
193+
194+
---
195+
196+
## Checkpoint 3: 🤔 Vendor Buyback 🤯
197+
198+
👩‍🏫 The hardest part of this challenge is to build your `Vendor` to buy the tokens back.
199+
200+
🧐 The reason why this is hard is the `approve()` pattern in ERC20s.
201+
202+
😕 First, the user has to call `approve()` on the `YourToken` contract, approving the `Vendor` contract address to take some amount of tokens.
203+
204+
🤨 Then, the user makes a _second transaction_ to the `Vendor` contract to `sellTokens(amount_tokens: u256)`.
205+
206+
🤓 The `Vendor` should call `fn transfer_from(ref self: ContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256) -> bool` and if the user has approved the `Vendor` correctly, tokens should transfer to the `Vendor` and ETH should be sent to the user.
207+
208+
🤩 You can use `useScaffoldMultiWriteContract.ts` to call `approve` and `buy / sell tokens`
209+
210+
> 📝 Edit `Vendor.cairo` and add a `sellTokens(amount_tokens: u256)` function!
211+
212+
🔨 Use the `Debug Contracts` tab to call the approve and sellTokens() at first but then...
213+
214+
🔍 Look in the `packages/nextjs/app/token-vendor/page.tsx` for the extra approve/sell UI to uncomment!
215+
216+
![VendorBuyBack](https://raw.githubusercontent.com/Quantum3-Labs/speedrunstark/token-vendor/packages/nextjs/public/ch2-VendorBuySell.png)
217+
218+
### 🥅 Goal
219+
220+
- [ ] Can you sell tokens back to the vendor?
221+
- [ ] Do you receive the right amount of ETH for the tokens?
222+
223+
### ⚔️ Side Quests
224+
225+
- [ ] Should we disable the `owner` withdraw to keep liquidity in the `Vendor`?
226+
- [ ] It would be a good idea to display Sell Token Events. Create an **event**
227+
`SellTokens {seller: ContractAddress, tokens_amount: u256, eth_amount: u256}`
228+
and `emit` it in your `Vendor.cairo` and uncomment `SellTokens Events` section in your `packages/nextjs/app/events/page.tsx` to update your frontend.
229+
230+
![Events](https://raw.githubusercontent.com/Quantum3-Labs/speedrunstark/2812ab21de5d261ef670b0ef5a211fdfbae3b8d8/packages/nextjs/public/events.png)
231+
232+
### ⚠️ Test it
233+
234+
- 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!
235+
236+
---
237+
238+
## Checkpoint 4: 💾 Deploy your contracts! 🛰
239+
240+
📡 Edit the `defaultNetwork` to your choice of Starknet networks in `packages/nextjs/scaffold.config.ts`
241+
242+
🔐 In devnet you can choose a burner wallet auto-generated
243+
244+
⛽️ You will need to send ETH to your deployer address with your wallet if not in devnet, or get it from a public faucet of your chosen network.
245+
246+
🚀 Run `yarn deploy` to deploy your smart contract to a public network (selected in `scaffold.config.ts`)
247+
248+
> 💬 Hint: For faster loading of your _"Events"_ page, consider updating the `fromBlock` passed to `useScaffoldEventHistory` in [`packages/nextjs/app/events/page.tsx`](https://github.com/Quantum3-Labs/speedrunstark/blob/token-vendor/packages/nextjs/app/events/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 Starkscan and find the `Contract Creation` transaction line.
249+
250+
---
251+
252+
## Checkpoint 5: 🚢 Ship your frontend! 🚁
253+
254+
✏️ Edit your frontend config in `packages/nextjs/scaffold.config.ts` to change the `targetNetwork` to `chains.sepolia`.
255+
256+
💻 View your frontend at <http://localhost:3000/stakerUI> and verify you see the correct network.
70257

71-
> 🏃 Head to your next challenge [here](https://speedrunstark.com/).
258+
📡 When you are ready to ship the frontend app...
259+
260+
📦 Run `yarn vercel` to package up your frontend and deploy.
261+
262+
> Follow the steps to deploy to Vercel. Once you log in (email, github, etc), the default options should work. It'll give you a public URL.
263+
264+
> 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.
265+
266+
> 🦊 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 `devnet` . You can enable them on every chain by setting `onlyLocalBurnerWallet: false` in your frontend config (`scaffold.config.ts` in `packages/nextjs/`)
267+
268+
#### Configuration of Third-Party Services for Production-Grade Apps
269+
270+
By default, 🏗 Scaffold-Stark provides predefined API keys for some services such as Infura. This allows you to begin developing and testing your applications more easily, avoiding the need to register for these services.
271+
This is great to complete your **SpeedRunStark**.
272+
273+
For production-grade applications, it's recommended to obtain your own API keys (to prevent rate limiting issues). You can configure these at:
274+
275+
🔷 `RPC_URL_SEPOLIA` variable in `packages/snfoundry/.env` and `packages/nextjs/.env.local`. You can create API keys from the [Infura dashboard](https://www.infura.io/).
276+
277+
> 💬 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.
278+
279+
---
72280

73-
> 💬 Problems, questions, comments on the stack? Post them to the [🏗 Scaffold-Stark developers chat](https://t.me/+wO3PtlRAreo4MDI9)
281+
> 🏃 Head to your next challenge [here](https://github.com/Quantum3-Labs/speedrunstark/tree/dice-game).
282+
> � Problems, questions, comments on the stack? Post them to the [🏗 Scaffold-Stark developers chat](https://t.me/+wO3PtlRAreo4MDI9)

0 commit comments

Comments
 (0)