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 --versionand see a response likegit version x.x.x. -
Foundry
You'll know it's correctly installed if you can runforge --versionand 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.jsonand:- Paste it in the
MakefileasROOT(for zkSync deployments). - Update
s_merkleRootinDeployMerkleAirdrop.s.solfor 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.0andnpx 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_URLis set in your.envfile. - Ensure an account named
defaultis 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_ADDRESSandTOKEN_ADDRESSvariables in the Makefile. -
Sign your airdrop claim:
make sign
- Retrieve the signature bytes from the terminal and add them to
Interact.s.sol(remove the0xprefix).
- 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 coverageTo estimate gas costs:
forge snapshotTo format the code:
forge fmt