DEV Community

rim dinov
rim dinov

Posted on

How I Slashed Gas Costs by 25% for a Solidity Merkle Mixer

Gas Surgery: Reducing Merkle Mixer Costs by 25% on Base

Building a privacy mixer is a challenge of balance. You want strong anonymity, but you don't want the user to pay a fortune in gas for a single withdrawal. After stabilizing the Merkle Tree logic, I decided to put the contract on a strict gas diet.

The results? A drop from 72,332 to 53,897 average gas. Here is how I did it.

1. The Power of Bitmaps

Initially, I used a standard mapping(bytes32 => bool) to track nullifiers. Every bool in Solidity occupies a full 256-bit slot.

By switching to a Bitmap implementation, we pack 256 nullifiers into a single uint256 storage slot. Bitwise operations are significantly cheaper than cold storage writes.

2. Calldata: Stop Copying Data

In the first version, the Merkle Proof was passed as a memory array. This forced the EVM to copy the entire proof into memory.
By switching to calldata, the contract reads the proof directly from the input, saving thousands of gas units.

3. Custom Errors

Replacing require(condition, "Very long error message") with if (condition) revert AlreadySpent() reduces the deployment size and makes execution cheaper.

The Benchmarks (Foundry)

Implementation Avg Gas Max Gas
Initial 72,332 98,105
Optimized 53,897 81,204

Check out the full source code on my GitHub:
👉 https://github.com/rdin777/merkle-mixer-research

#solidity, #web3, #blockchain, #programming

Top comments (0)