Packing

Storage & deploys

storage layout & packing

Paste a contract’s state variables or a struct and see its storage layout slot by slot (same as solc’s storageLayout), the bytes wasted between variables, and a reordering that packs them into fewer slots, with the gas it saves.

try

not in storage: MAX_FEE (constant)

as written · 6 slots · 57 bytes wasted
  1. 0
    decimals
    31 bytes free
  2. 1
    totalAssets
  3. 2
    ownerpaused
    11 bytes free
  4. 3
    shares
  5. 4
    lastHarvestcap
    8 bytes free
  6. 5
    strategyfeeBpsinitialized
    7 bytes free
layout (like forge inspect … storageLayout)
name type slot offset bytes decimals uint8 0 0 1 totalAssets uint256 1 0 32 owner address 2 0 20 paused bool 2 20 1 shares mapping(address => uint256) 3 0 32 lastHarvest uint64 4 0 8 cap uint128 4 8 16 strategy address 5 0 20 feeBps uint32 5 20 4 initialized bool 5 24 1
packed · 5 slots · saves 1
  1. 0
    strategydecimalspausedinitialized
    9 bytes free
  2. 1
    ownerlastHarvestfeeBps
  3. 2
    cap
    16 bytes free
  4. 3
    totalAssets
  5. 4
    shares
reordered declarations
address public strategy; uint8 public decimals; bool public paused; bool public initialized; address public owner; uint64 public lastHarvest; uint32 public feeBps; uint128 public cap; uint256 public totalAssets; mapping(address => uint256) public shares;1 fewer slot: about 20,000 less gas the first time they are all set, and 2,100 per cold read when used together

only reorder storage before the first deploy. an upgradeable contract that's live has its slots fixed forever: append new variables at the end instead.

good to know

how does solidity pack storage?

variables are placed in declaration order. value types smaller than 32 bytes share a slot while they fit; mappings, dynamic arrays, strings, structs and fixed arrays always start a new slot, and the next variable starts another.

how much gas does a slot save?

writing a fresh slot costs 20,000 gas (zero to non-zero), and a cold read 2,100. packing values that are used together means one write and one read instead of several.

can i reorder an upgradeable contract?

no. once deployed behind a proxy the slots are fixed; moving a variable makes it read another one’s data. only add new variables at the end (or use erc-7201 namespaced storage).