This project delves into the concept of Merkle airdrops, developing a system that enables users to claim airdrops without incurring gas fees. It allows protocol owners to distribute tokens seamlessly, covering the gas costs on behalf of the users. The project also integrates zkSync, providing compatibility with both standard EVM chains and the zkSync network, enhancing usability and efficiency.
-
Git
You'll know you've set it up correctly if you can rungit --version
and see a response likegit version x.x.x
. -
Foundry
You'll know it's correctly installed if you can runforge --version
and see a response likeforge 0.2.0 (816e00b 2023-03-16T00:05:26.396218Z)
.
To get started, we are assuming you're working with vanilla Foundry and not Foundry-zkSync.
- Clone the repository:
git clone https://github.com/ciara/merkle-airdrop cd merkle-airdrop
- Install dependencies and build the project:
make # or forge install && forge build if you don't have make
To generate Merkle proofs for an array of addresses to airdrop funds to, follow these steps. If you'd like to work with the default addresses and proofs already created in this repo, skip to Deploy.
- Update the array of addresses in
GenerateInput.s.sol
. - Generate the input file, Merkle root, and proofs:
- Using
make
:make merkle
- Or using the commands directly:
forge script script/GenerateInput.s.sol:GenerateInput && forge script script/MakeMerkle.s.sol:MakeMerkle
- Using
- Retrieve the root from
script/target/output.json
and:- Paste it in the
Makefile
asROOT
(for zkSync deployments). - Update
s_merkleRoot
inDeployMerkleAirdrop.s.sol
for Ethereum/Anvil deployments.
- Paste it in the
- Optional: Ensure you're on vanilla Foundry:
foundryup
- Run a local Anvil node:
make anvil
- In a second terminal, deploy the contracts:
make deploy
-
Foundry-zkSync
Verify it's installed by running:forge --version
and check for a response like
forge 0.0.2 (816e00b 2023-03-16T00:05:26.396218Z)
. -
npx & npm
Verify by running:npm --version npx --version
and check for responses like
npm 7.24.0
andnpx 8.1.0
. -
Docker
Verify Docker is running:docker --version docker --info
-
Configure the zkSync node:
npx zksync-cli dev config
- Select: "In memory node".
- Do not select any additional modules.
-
Start the zkSync node:
npx zksync-cli dev start
You should see 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
-
To close the zkSync node in the future, run:
docker ps docker kill ${CONTAINER_ID}
- Optional: Ensure you're on Foundry-zkSync:
foundryup-zksync
- Deploy:
make deploy-zk
- Set up your environment:
- Ensure
ZKSYNC_SEPOLIA_RPC_URL
is set in your.env
file. - Ensure an account named
default
is set up forcast
.
- Ensure
- Deploy:
foundryup-zksync make deploy-zk-sepolia
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 receive the airdrop.
- Setup the zkSync node and deploy contracts:
foundryup-zksync chmod +x interactZk.sh && ./interactZk.sh
-
Setup Anvil and deploy contracts:
foundryup make anvil make deploy
-
Copy the BagelToken and Airdrop contract addresses, and paste them into the
AIRDROP_ADDRESS
andTOKEN_ADDRESS
variables in the Makefile. -
Sign your airdrop claim:
make sign
- Retrieve the signature bytes from the terminal and add them to
Interact.s.sol
(remove the0x
prefix).
- Retrieve the signature bytes from the terminal and add them to
-
Claim your airdrop:
make claim
-
Check the claim amount:
make balance
-
Run the tests:
foundryup forge test
-
For zkSync:
make zktest
To check test coverage:
forge coverage
To estimate gas costs:
forge snapshot
To format the code:
forge fmt