---
description: Gas Optimization
alwaysApply: false
---

# Gas Optimization

Gas-efficient smart contract patterns. Never sacrifice security for gas savings.

## Storage Optimization

- **Variable packing**: arrange variables to fill 32-byte slots (e.g., `uint128 + uint64 + uint32 + bool` = 1 slot)
- **Cache storage reads**: read storage into memory before loops, write back once after

```solidity
// Bad: writes storage each iteration (5,000 gas/write)
for (uint256 i = 0; i < 10; i++) { s_counter += 1; }

// Good: cache in memory, write once
uint256 counter = s_counter;
for (uint256 i = 0; i < 10;) { counter++; unchecked { ++i; } }
s_counter = counter;
```

## Calldata vs Memory

- Use `calldata` for read-only array/string params (no copy cost)
- Use `memory` only when you need to modify the data

## Loop Optimizations

- Cache `array.length` before loops
- Use `unchecked { ++i; }` when overflow is impossible
- Put cheaper/more-likely-to-fail checks first (short-circuit)

## Function Optimizations

- `external` over `public` for functions only called externally
- Custom errors over `require` strings (cheaper deployment + runtime)

```solidity
// Bad: string storage is expensive
require(balance >= amount, "Insufficient balance");

// Good: custom errors
error InsufficientBalance(uint256 requested, uint256 available);
if (balance < amount) revert InsufficientBalance(amount, balance);
```

## Constants and Immutables

- `constant` — replaced at compile time (~3 gas)
- `immutable` — set in constructor, embedded in bytecode (~3 gas)
- Storage variables cost ~2,100 gas (cold read)

## Batching

- Batch multiple operations into single transactions to amortize base tx cost
- Use `unchecked` increments in batch loops

## Bit Manipulation

- Pack multiple booleans into a single `uint256` using bitmasks
- Use shifts (`>> 1`, `<< 1`) for powers-of-2 multiply/divide

## Benchmarking

```bash
forge test --gas-report        # per-function gas
forge snapshot                 # baseline
forge snapshot --diff          # compare after changes
```

## When NOT to Optimize

- Never sacrifice security or readability for marginal gas savings
- Optimize after profiling, not before — premature optimization creates audit risk
