Awesome
Merkle Airdrop Extravaganza
This is a section of the Cyfrin Updraft Advanced Foundry Course. In this repo, we will learn about signatures, merkle drops, and more.
- Merkle Airdrop Extravaganza
- Getting Started
- Usage
- Deploy
- Formatting
- Thank you!
Getting Started
Requirements
- git
- You'll know you did it right if you can run
git --version
and you see a response likegit version x.x.x
- You'll know you did it right if you can run
- foundry
- You'll know you did it right if you can run
forge --version
and you see a response likeforge 0.2.0 (816e00b 2023-03-16T00:05:26.396218Z)
- You'll know you did it right if you can run
To get started, we are assuming you're working with vanilla foundry
and not foundry-zksync
to start.
Quickstart
git clone https://github.com/ciara/merkle-airdrop
cd merkle-airdrop
make # or forge install && forge build if you don't have make
Usage
Pre-deploy: Generate merkle proofs
We are going to generate merkle proofs for an array of addresses to airdrop funds to. If you'd like to work with the default addresses and proofs already created in this repo, skip to deploy
If you'd like to work with a different array of addresses (the whitelist
list in GenerateInput.s.sol
), you will need to follow the following:
First, the array of addresses to airdrop to needs to be updated in `GenerateInput.s.sol. To generate the input file and then the merkle root and proofs, run the following:
Using make:
make merkle
Or using the commands directly:
forge script script/GenerateInput.s.sol:GenerateInput && forge script script/MakeMerkle.s.sol:MakeMerkle
Then, retrieve the root
(there may be more than 1, but they will all be the same) from script/target/output.json
and paste it in the Makefile
as ROOT
(for zkSync deployments) and update s_merkleRoot
in DeployMerkleAirdrop.s.sol
for Ethereum/Anvil deployments.
Deploy
Deploy to Anvil
# Optional, ensure you're on vanilla foundry
foundryup
# Run a local anvil node
make anvil
# Then, in a second terminal
make deploy
Deploy to a zkSync local node
zkSync prerequisites
- foundry-zksync
- You'll know you did it right if you can run
forge --version
and you see a response likeforge 0.0.2 (816e00b 2023-03-16T00:05:26.396218Z)
.
- You'll know you did it right if you can run
- npx & npm
- You'll know you did it right if you can run
npm --version
and you see a response like7.24.0
andnpx --version
and you see a response like8.1.0
.
- You'll know you did it right if you can run
- docker
- You'll know you did it right if you can run
docker --version
and you see a response likeDocker version 20.10.7, build f0df350
. - Then, you'll want the daemon running, you'll know it's running if you can run
docker --info
and in the output you'll see something like the following to know it's running:
- You'll know you did it right if you can run
Client:
Context: default
Debug Mode: false
Setup local zkSync node
Run the following:
npx zksync-cli dev config
And select: In memory node
and do not select any additional modules.
Then run:
npx zksync-cli dev start
And you'll get an output like:
In memory node started v0.1.0-alpha.22:
- zkSync Node (L2):
- Chain ID: 260
- RPC URL: http://127.0.0.1:8011
- Rich accounts: https://era.zksync.io/docs/tools/testing/era-test-node.html#use-pre-configured-rich-wallets
This will save your zkSync configuration so you won't have to run npx zksync-cli dev config
again.
In the future, you can just run:
make zk-anvil
To close the zkSync node (in the future, leave it running for now), run:
docker ps
To get the container ID from the result. If there is no result, then docker might not be running, and you're all set. Otherwise run:
docker kill ${CONTAINER_ID}
Deploy to a local zkSync network
# Optional, ensure you're on foundry-zksync
foundryup-zksync
# Setup a docker container for zkSync (if you haven't already)
# make zk-anvil
# deploy
make deploy-zk
Deploy to zkSync Sepolia
Be sure you have the following:
ZKSYNC_SEPOLIA_RPC_URL
set in your.env
file- An account named
default
set up yourcast
# Optional, ensure you're on foundry-zksync
foundryup-zksync
# Deploy
make deploy-zk-sepolia
# You'll be prompted to enter your password
Interacting - zkSync local network
The following steps allow the second default anvil address (0x70997970C51812dc3A010C7d01b50e0d17dc79C8) to call claim and pay for the gas on behalf of the first default anvil address (0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266) which will recieve the airdrop.
Setup local zksync node, deploy contracts, and run airdrop claim
See Deploy to a zkSync local node prerequisites for prerequisites.
On foundry-zksync
, setup a local node and deploy the zkSync contracts. You can do both steps with this two commands:
foundryup-zksync
chmod +x interactZk.sh && ./interactZk.sh
You'll see the output of:
- Deploying zkSync smart contracts
- Signing your airdrop claim
- Claiming the airdrop
All from the ./interactZk.sh
script.
Interacting - Local anvil network
Setup anvil and deploy contracts
Swap back to vanilla foundry and run an anvil node:
foundryup
make anvil
make deploy
# Copy the BagelToken address & Airdrop contract address
Copy the Bagel Token and Aidrop contract addresses and paste them into the AIRDROP_ADDRESS
and TOKEN_ADDRESS
variables in the MakeFile
The following steps allow the second default anvil address (0x70997970C51812dc3A010C7d01b50e0d17dc79C8
) to call claim and pay for the gas on behalf of the first default anvil address (0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
) which will recieve the airdrop.
Sign your airdrop claim
# in another terminal
make sign
Retrieve the signature bytes outputted to the terminal and add them to Interact.s.sol
making sure to remove the 0x
prefix.
Additionally, if you have modified the claiming addresses in the merkle tree, you will need to update the proofs in this file too (which you can get from output.json
)
Claim your airdrop
Then run the following command:
make claim
Check claim amount
Then, check the claiming address balance has increased by running
make balance
NOTE: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
is the default anvil address which has recieved the airdropped tokens.
Testing
foundryup
forge test
for for zkSync
# This will run `foundryup-zksync && forge test --zksync && foundryup`
make zktest
Test Coverage
forge coverage
Estimate gas
You can estimate how much gas things cost by running:
forge snapshot
And you'll see an output file called .gas-snapshot
Formatting
To run code formatting:
forge fmt
Thank you!
If you appreciated this, please follow Cyfrin Updraft!