Skip to content

Storage Layout

DISCLAIMER // NFA // DYOR

This analysis is based on observations of the contract behavior. We are not smart contract security experts. This document aims to explain what the contract appears to do based on the code. It should not be considered a comprehensive security audit or financial advice. Always verify critical information independently and consult with blockchain security professionals for important decisions.

⊙ generated by robots | curated by humans

METADATA
Contract Address 0x643A45B5...0673C1 (etherscan)
Network Ethereum Mainnet
Analysis Date 2026-08-18

Reading This Document

The address above is the Moloch implementation. It holds no governance state of its own — every DAO is a separate ERC-1167 clone with its own storage, and the implementation's slots are never written through the implementation address itself. The CURRENT VALUE column therefore reports a sampled live clone — the zOrg DAO at 0x5E58BA0e...74053E (etherscan), read at block height on the analysis date — so that the decoded layout can be checked against real data. Those values belong to that DAO and are not framework defaults; a second clone, FWC at 0xE7Aa6cA3...F49853 (etherscan), is cited where the two differ.

Four values do not appear in any storage table below because they are not in storage. SUMMONER, sharesImpl, badgesImpl and lootImpl are Solidity immutables, compiled into the implementation's runtime bytecode at its own deployment. Every clone reads the same four values, and no clone can change them. Each appears exactly once in the deployed runtime bytecode, which is how they were confirmed:

IMMUTABLE VALUE VERIFIED
SUMMONER 0x00000000...eE9138 (etherscan) Present once in runtime bytecode
sharesImpl 0x71E9b38d...Acf600 (etherscan) Present once in runtime bytecode
lootImpl 0x6f1f2aF7...7bc6A5 (etherscan) Present once in runtime bytecode
badgesImpl 0x47C175Ce...eD96d5 (etherscan) Present once in runtime bytecode

Because init() requires msg.sender == SUMMONER and both live DAOs were successfully initialised in transactions originating from 0x00000000...eE9138 (etherscan), the SUMMONER immutable resolves to that factory. No other address can call init on any clone of this implementation.


Variables

Moloch

Thirty-eight declared variables across thirty-two slots, 0 to 31. Slots 2, 3 and 4 are packed, and all three packings were confirmed by reading raw storage rather than by trusting the declaration order.

SLOT VARIABLE NAME TYPE CURRENT VALUE PURPOSE
0 _orgName string "zOrg" Organisation display name, served to Shares, Loot and Badges
1 _orgSymbol string "ZORG" Organisation symbol, inherited by the satellite tokens
2 (offset 0) proposalThreshold uint96 1000000000000000000 Minimum votes required to open a proposal; 0 disables
2 (offset 12) minYesVotesAbsolute uint96 0 Absolute floor on FOR votes; 0 disables
3 (offset 0) quorumAbsolute uint96 0 Absolute turnout floor; 0 disables
3 (offset 12) proposalTTL uint64 86400 Seconds from creation until an unqueued proposal expires; 0 disables
3 (offset 20) timelockDelay uint64 86400 Seconds between queueing and execution; 0 disables
4 (offset 0) config uint64 0 Version salt mixed into every proposal id; incrementing it invalidates all pending ids
4 (offset 8) quorumBps uint16 1000 Turnout quorum as basis points of snapshot supply (10%)
4 (offset 10) ragequittable bool true Whether holders may exit with a pro-rata share of the treasury
4 (offset 11) renderer address 0x00000000...D6E654 (etherscan) External metadata renderer for tokenURI and contractURI
5 shares contract Shares 0x00a6bA94...2dCb12 (etherscan) This DAO's voting token clone
6 badges contract Badges 0x2809A7EB...01c221 (etherscan) This DAO's soulbound badge clone
7 loot contract Loot 0x62eC8675...359016 (etherscan) This DAO's non-voting economic token clone
8 executed mapping(uint256 => bool) mapping Execution latch per proposal id; also set by cancelProposal as a tombstone
9 createdAt mapping(uint256 => uint64) mapping Timestamp of first open or vote, the origin for TTL
10 snapshotBlock mapping(uint256 => uint48) mapping Vote-weight snapshot block, fixed at block.number - 1 on open
11 supplySnapshot mapping(uint256 => uint256) mapping Total share supply at the snapshot block, the quorum denominator
12 queuedAt mapping(uint256 => uint64) mapping Timelock start; a non-zero value permanently disables TTL for that proposal
13 tallies mapping(uint256 => Tally) mapping Packed FOR / AGAINST / ABSTAIN vote totals
14 proposalIds uint256[] length 22 Append-only registry of opened proposal ids
15 proposerOf mapping(uint256 => address) mapping Address that opened each proposal; the only address permitted to cancel it
16 hasVoted mapping(uint256 => mapping(address => uint8)) mapping Vote record, stored as support + 1 so that 0 means "not voted"
17 voteWeight mapping(uint256 => mapping(address => uint96)) mapping Weight credited per voter, retained so cancelVote can subtract exactly what it added
18 isPermitReceipt mapping(uint256 => bool) mapping Marks an ERC-6909 id as a permit rather than a vote receipt, which makes it non-transferable
19 allowance mapping(address => mapping(address => uint256)) mapping Token spending allowances granted by governance, keyed token then spender
20 sales mapping(address => Sale) mapping Per-payment-token share sale configuration
21 messages string[] length 116 Badge-gated on-chain chat log
22 _orgURI string empty Contract-level metadata override; when empty the renderer is consulted
23 balanceOf mapping(address => mapping(uint256 => uint256)) mapping ERC-6909 balances for vote receipts and permits
24 totalSupply mapping(uint256 => uint256) mapping ERC-6909 supply per id; the futarchy payout denominator
25 receiptSupport mapping(uint256 => uint8) mapping Decodes a receipt id back to the side it represents
26 receiptProposal mapping(uint256 => uint256) mapping Decodes a receipt id back to its proposal
27 futarchy mapping(uint256 => FutarchyConfig) mapping Per-proposal prediction market state
28 autoFutarchyParam uint256 10 Automatic futarchy earmark; 1–10000 is basis points of basis supply, above 10000 is an absolute amount
29 autoFutarchyCap uint256 5000000000000000000 Per-proposal ceiling on the automatic earmark (5e18)
30 rewardToken address 0x00000000...000000 Governance-pinned futarchy reward token. Zero leaves the choice to the first funder in fundFutarchy, but resolves to address(1007) — newly minted loot — in the openProposal auto-earmark
31 isOperator mapping(address => mapping(address => bool)) mapping ERC-6909 operator approvals

The three packed slots decode as follows, read directly from the zOrg clone:

slot 2  0x0000000000000000000000000000000000000000000000000de0b6b3a7640000
        proposalThreshold   = 0x0de0b6b3a7640000 = 1e18
        minYesVotesAbsolute = 0

slot 3  0x0000000000000000000151800000000000015180000000000000000000000000
        quorumAbsolute = 0
        proposalTTL    = 0x15180 = 86400
        timelockDelay  = 0x15180 = 86400

slot 4  0x00000000000011c799980827f52d3137b4abd6e6540103e80000000000000000
        config         = 0
        quorumBps      = 0x03e8 = 1000
        ragequittable  = 0x01  = true
        renderer       = 0x000000000011C799980827F52d3137b4abD6E654

Both sampled clones happen to set proposalTTL equal to timelockDelay — 86,400 seconds on zOrg, 43,200 on FWC. Nothing in the implementation ties them together; the consequence of setting them that way is treated in the Contract Analysis.

Shares

Nine declared slots. This is the only satellite that carries voting machinery.

SLOT VARIABLE NAME TYPE CURRENT VALUE PURPOSE
0 transfersLocked bool false When set, blocks transfers unless the DAO is sender or recipient
1 totalSupply uint256 7822066259197685009861991 Share supply, checkpointed on every mint and burn
2 balanceOf mapping(address => uint256) mapping ERC-20 balances
3 allowance mapping(address => mapping(address => uint256)) mapping ERC-20 allowances
4 DAO address payable 0x5E58BA0e...74053E (etherscan) The owning Moloch clone; set once in init and never mutable afterwards
5 _delegates mapping(address => address) mapping Primary delegate per holder; zero is interpreted as self
6 _checkpoints mapping(address => Checkpoint[]) mapping Per-delegate vote history, binary-searched by getPastVotes
7 _totalSupplyCheckpoints Checkpoint[] array Supply history, the source for getPastTotalSupply
8 _splits mapping(address => Split[]) mapping Split delegation configuration, at most four entries per holder

DAO guards every privileged entry point on this contract and is written exactly once, in init, behind a require(DAO == address(0)). There is no setter and no transfer path, so the binding between a Shares clone and its Moloch clone is permanent.

Loot

Five declared slots, identical in shape to the first five of Shares and carrying none of the voting machinery. Loot confers economic rights only.

SLOT VARIABLE NAME TYPE CURRENT VALUE PURPOSE
0 transfersLocked bool false Transfer lock, same semantics as Shares
1 totalSupply uint256 2026458778534528890 Loot supply; counts toward ragequit but never toward votes
2 balanceOf mapping(address => uint256) mapping ERC-20 balances
3 allowance mapping(address => mapping(address => uint256)) mapping ERC-20 allowances
4 DAO address payable 0x5E58BA0e...74053E (etherscan) Owning Moloch clone, written once in init

Loot cannot be delegated, cannot be snapshotted, and contributes nothing to getPastTotalSupply, so issuing loot dilutes treasury claims without diluting voting power.

Badges

Eight declared entries occupying 262 slots, because seats is a fixed 256-element array of packed structs.

SLOT VARIABLE NAME TYPE CURRENT VALUE PURPOSE
0 DAO address payable 0x5E58BA0e...74053E (etherscan) Owning Moloch clone, written once in init
1 _ownerOf mapping(uint256 => address) mapping Seat id (1–256) to holder
2 seatOf mapping(address => uint256) mapping Holder to seat id; 0 means unseated
3 balanceOf mapping(address => uint256) mapping ERC-721 balance, structurally capped at 1 per address
4 occupied uint256 0xffff...ffff (256 of 256 set) Bitmap of taken seats, one bit per slot
5–260 seats Seat[256] array Cached holder and balance per seat, packed as address + uint96
261 (offset 0) minSlot uint16 120 Index of the current cutline seat
261 (offset 2) minBal uint96 16693532759286299628 Share balance at the cutline (≈16.6935 ZORG)

The zOrg board is full: occupied reads as all 256 bits set, and the cutline sits at roughly 16.69 shares held by the occupant of seat index 120. A newcomer joins only by strictly exceeding that balance, which evicts the cutline holder. The FWC board is partly filled, and its occupied word has a cleared bit where a seat was released when its holder's balance reached zero. That seat will be refilled by the next holder to acquire any non-zero balance, regardless of size, because free seats are granted without comparison — the two boards therefore demonstrate both allocation regimes at once.


Diagrams

graph TB
    subgraph Immutable["Immutables — bytecode, not storage"]
        I0["SUMMONER — 0x00000000...eE9138"]
        I1["sharesImpl / lootImpl / badgesImpl"]
    end

    subgraph Config["Governance Config — Slots 2-4 packed"]
        S2["Slot 2: proposalThreshold 1e18 | minYesVotesAbsolute 0"]
        S3["Slot 3: quorumAbsolute 0 | proposalTTL 86400 | timelockDelay 86400"]
        S4["Slot 4: config 0 | quorumBps 1000 | ragequittable true | renderer"]
    end

    subgraph Satellites["Satellite Clones — Slots 5-7"]
        S5["Slot 5: shares"]
        S6["Slot 6: badges"]
        S7["Slot 7: loot"]
    end

    subgraph Proposals["Proposal State — Slots 8-17"]
        S8["Slot 8: executed latch"]
        S9["Slots 9-12: createdAt, snapshotBlock, supplySnapshot, queuedAt"]
        S13["Slots 13-17: tallies, proposalIds, proposerOf, hasVoted, voteWeight"]
    end

    subgraph Modules["Module State — Slots 18-31"]
        S18["Slots 18-20: permits, allowances, sales"]
        S21["Slots 21-22: chat log, org URI"]
        S23["Slots 23-27: ERC-6909 receipts and futarchy"]
        S28["Slots 28-31: futarchy config, operators"]
    end

    Immutable --> Config --> Satellites --> Proposals --> Modules

    style S3 fill:#ffe1e1
    style S4 fill:#ffe1e1
    style S8 fill:#fff4e1
graph LR
    subgraph Moloch["Moloch clone — governance state"]
        M["38 vars / 32 slots"]
    end

    subgraph Shares["Shares clone — 9 slots"]
        SH["totalSupply + checkpoints + splits"]
    end

    subgraph Loot["Loot clone — 5 slots"]
        LO["totalSupply only, no checkpoints"]
    end

    subgraph Badges["Badges clone — 262 slots"]
        BA["seats[256] + occupied bitmap + cutline"]
    end

    Moloch -->|"DAO immutable binding"| Shares
    Moloch --> Loot
    Moloch --> Badges
    Shares -->|"onSharesChanged"| Moloch
    Moloch -->|"onSharesChanged"| Badges

    style BA fill:#e1f0ff