solidity language logo

Saving Gas in Solidity: Optimizing State Flags with Bitmaps

The Hidden Cost of Booleans

In Solidity development, storage is the most expensive operation. While a single boolean theoretically only needs one bit of information, the Ethereum Virtual Machine (EVM) operates on 32-byte (256-bit) words. When you declare multiple boolean variables, Solidity attempts to pack them into a single slot, but the gas overhead of reading and writing to those individual packed slots still adds up. If you are building a system that requires tracking dozens or hundreds of true/false statuses—such as a whitelist, a voting system, or feature toggles—using a bool[] array or multiple bool state variables is a gas-heavy anti-pattern.

Enter the Bitmap Pattern

A bitmap uses a single uint256 variable to store 256 individual boolean flags. Each bit represents a status: 0 for false and 1 for true. This approach allows you to update or check statuses using bitwise operators, which are among the cheapest opcodes in the EVM. Instead of paying for multiple storage updates, you can often flip multiple switches within a single 256-bit word for the price of one.

pragma solidity ^0.8.0;

contract GasEfficientFlags {
    // A single slot can hold 256 flags
    uint256 private _flags;

    // Sets the flag at a specific position to true
    function setFlag(uint8 pos) public {
        _flags |= (1 << pos);
    }

    // Sets the flag at a specific position to false
    function unsetFlag(uint8 pos) public {
        _flags &= ~(1 << pos);
    }

    // Checks if a flag is set
    function isSet(uint8 pos) public view returns (bool) {
        uint256 bit = (_flags >> pos) & 1;
        return bit == 1;
    }

    // Toggle a flag (True to False, or False to True)
    function toggleFlag(uint8 pos) public {
        _flags ^= (1 << pos);
    }
}

Why This Saves Gas

When you use the code above, the EVM performs simple arithmetic (bit-shifting and bitwise logic). This avoids the complex array-index calculations and bounds checking that bool[] requires. Furthermore, if you need to update multiple flags simultaneously, you can pass a "mask" to the contract and update all 256 flags in a single SSTORE operation. Comparing this to updating 256 individual boolean variables, the gas savings are astronomical.

When to Use Bitmaps

Bitmaps are ideal for high-frequency state management. Common use cases include:

  • Airdrop Whitelists: Tracking whether an address has already claimed their tokens.
  • DAO Voting: Keeping track of which members have cast a vote on a specific proposal.
  • Game State: Storing player achievements or unlocked levels efficiently.

While bitwise operations might look intimidating at first, they are a fundamental tool for any senior Solidity developer. By shifting your mindset from high-level arrays to low-level bits, you write contracts that are not only more professional but significantly cheaper for your users to interact with.