Case Study: How We Built a Secure, Gas-Efficient Airdrop Solution

Airdrops are a powerful tool, but they're also a minefield of high gas fees and security risks. How do you send ETH to 10,000 people without getting rekt? When we set out to build our own airdrop application, we knew we had to get it right. This is the story of how we used our own professional toolchain to build the Batch Sender solution from start to finish.

Step 1: Financial Planning with gas-forecaster

The first critical decision was architectural. A simple loop that iterates through a list of addresses is easy to write, but it's enormously expensive on gas. The professional alternative is a Merkle tree, which shifts the cost burden from the sender to the individual claimants. But how much better is it, really? Before writing a single line of Solidity, we used gas-forecaster to model the cost.

We created two skeleton contracts and ran the numbers for an airdrop to 5,000 addresses.


# Forecasting the naive, loop-based approach
$ forecast function AirdropSimple.sol sendAirdrop --args 5000

[CRITICAL] Estimated gas cost for `sendAirdrop` is 125,000,000 units.
This will likely exceed the block gas limit and fail.
Estimated USD Cost (at 30 Gwei): ~$13,125.00

# Forecasting the Merkle-based approach
$ forecast deploy MerkleDistributor.sol

Deployment Cost Analysis (at 30 Gwei):
| Network  | Gas Units | Est. Fee   | Est. USD Cost |
|----------|-----------|------------|---------------|
| Ethereum | 950,000   | 0.0285 ETH | $89.77        |
                    

The data made the decision for us. A loop was not just expensive; it was technically unfeasible. A Merkle tree approach was the only viable path. This single command saved us days of wasted development on a flawed design.

Step 2: Rapid Prototyping with sol-console

With a clear architectural plan, we built the MerkleDistributor.sol contract. During development, we needed a tight feedback loop to test our logic. Setting up a complex Hardhat or Foundry scripting environment for every minor change is slow and cumbersome. Instead, we used sol-console to get an instant, interactive REPL.

After compiling the contract, we could immediately deploy a test version and interact with it:


$ sol-console --contract-path ./MerkleDistributor.sol

Welcome to Sol-Console!
✅ Compiled contract `MerkleDistributor`
🚀 Deploying a new instance...
✅ Deployed new instance `MerkleDistributor` at 0x5fb...d62

contract> contract.createCampaign("0xdead...beef", 1728192000, {value: "10 ETH"})
✅ Transaction Confirmed
 - Status: Success
 - Gas Used: 85,431

contract> contract.campaigns("0xdead...beef")
<- Return Value:
 - amount: 10000000000000000000
 - expiry: 1728192000
 - claimed: 0
                    

This interactive workflow allowed us to verify every function, test edge cases, and confirm state changes in seconds, not minutes. It was essential for building and debugging the contract logic efficiently.

Step 3: The Pre-Deployment Security Audit with sol-sentry

Before even thinking about mainnet, we ran our finished code through sol-sentry for a final security review. Confidence in your own code is good; automated, rigorous verification is better.

Sentry immediately flagged a subtle but critical issue in our fund withdrawal function:


$ sol-sentry scan ./MerkleDistributor.sol

✅ Sol-Sentry Scan Complete for MerkleDistributor.sol
Found 1 Critical Issue:

[CRITICAL] Reentrancy Vulnerability
- Function:     withdrawExpiredFunds()
- Line:         112
- Details:      The external call to `owner.call()` is made BEFORE the campaign's amount is set to zero. A malicious owner contract could call back into this function repeatedly, draining the contract of all funds from every campaign.

This contract is NOT safe to deploy.
                    

This is exactly the kind of subtle but devastating bug that automated analysis excels at finding. By failing to follow the "Checks-Effects-Interactions" pattern, we had left the contract vulnerable. We immediately corrected the issue by zeroing out the campaign's value *before* sending the funds. A major crisis was averted before it ever began.

Conclusion: A Toolchain for Professionals

From a napkin sketch to a mainnet-ready application, the journey was guided by a professional toolchain at every step. We started with a financial plan, iterated quickly, and passed a rigorous security check. The result is a secure, efficient, and battle-tested airdrop solution that we trust with our own funds.

You can use this exact airdrop contract on our Solutions page, or you can build your own robust applications by downloading the Blocktools suite today.