Skip to content

Contract Analysis

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

Analysis Date: 2026-10-27


Metadata

Primary Contract

PROPERTY VALUE
Contract Address 0x00000000...4e6f2a (etherscan)
Network Ethereum Mainnet
Contract Type Standalone, stateless. A configuration wrapper around the Majeur Summoner (the Moloch-derived Decentralized Autonomous Organization (DAO) factory), plus a public CREATE2 deployer
Deployment Date 2026-03-13 16:35:59 UTC
Deployment Block 24,649,778
Contract Creator 0x1C0Aa8cC...855A20 (etherscan)
Creation TX 0x028bd2b5...f05cfc (tx)
Compiler Version Solidity v0.8.30, optimizer on (245 runs), via-IR, EVM target cancun
Total Functions 16 external/public (9 state-changing, 7 view/pure)
External Contract Dependencies 6 hardcoded; up to 6 more supplied per call
Upgrade Mechanism ◇ None. No owner and no storage
Verification Status ☑ Verified on Etherscan
Audit Status △ No audit report for this contract located. Source comments cite numbered findings ("KF#") from a review of the Majeur framework; the analysis below reads the code, not the comments
TYPE ADDRESS NOTES
Summoner (SUMMONER) 0x00000000...eE9138 (etherscan) Majeur factory. Every summon path ends in SUMMONER.summon. 30 of its 59 DAOs were summoned through SafeSummoner
Moloch implementation (MOLOCH_IMPL) 0x643A45B5...0673C1 (etherscan) Never called. Used only to compute the predicted DAO address. See the Majeur analysis
Shares implementation (SHARES_IMPL) 0x71E9b38d...Acf600 (etherscan) Used only to predict each DAO's Shares token address
Loot implementation (LOOT_IMPL) 0x6f1f2aF7...7bc6A5 (etherscan) Used only to predict each DAO's Loot token address
ShareBurner (SHARE_BURNER) 0x00000000...c3Aa9f (etherscan) Default target of the burn-unsold permit. Verified, stateless
Renderer (RENDERER) 0x00000000...D6E654 (etherscan) Hardcoded into every preset. safeSummon and safeSummonDAICO take the renderer as an argument instead
ShareSale module 0x00000000...EA60f9 (etherscan) Not referenced in source. The sale singleton passed by all seven Decentralized Autonomous Initial Coin Offering (DAICO) summons that used a sale module. Itself deployed through SafeSummoner
TapVest module 0x00000000...7bF56D (etherscan) Not referenced in source. The tap singleton passed by four DAICO summons. Itself deployed through SafeSummoner
Deployment factory 0x00000000...3C15AA (etherscan) VanityMarket, a CREATE3 vanity-address market. SafeSummoner's address is independent of its bytecode
Heaviest create2Deploy caller 0xAcFBA7Ce...DE4082 (etherscan) Externally Owned Account (EOA). 55 of the 91 create2Deploy calls, including TokenList and ZorgConviction

Executive Summary

SafeSummoner sits between a user and the Majeur Summoner. A Majeur DAO is summoned with a list of initial holders, their share amounts, and an array of raw initialization calls that the new DAO executes against itself before anyone can vote. The Summoner checks none of the governance values those calls set. SafeSummoner takes a typed configuration struct instead, rejects combinations that the framework permits but that leave a DAO open to griefing or misconfiguration, encodes the struct into the init calls, and forwards everything to Summoner.summon in the same transaction.

It also offers five preset entry points (Standard, Fast, Founder, and DAICO variants of the first two) that fill the struct with fixed timings, and a "modular" DAICO path that wires three external singleton contracts — a share sale, a vesting tap, and a liquidity seeder — into the DAO through allowances.

Every call is permissionless and every value the contract uses is either a compile-time constant or a call argument. It adds a validation pass and an encoder, neither of which binds the resulting DAO.

By transaction count, create2Deploy is the primary use: it deploys arbitrary bytecode at a deterministic address, and 91 of the contract's 121 transactions call it. Ninety contracts came out of it, among them TokenList, ZorgConviction, the Majeur DAICO modules, several zSwap and zQuoter versions, and the Precision pool family. The TokenList analysis lists this address as the registry's "CREATE2 vanity factory" without naming it.

As of block 26,284,732 the 30 DAOs summoned through it hold a combined ~0.0101 ETH, and one of them has opened a proposal. The contract itself holds no ETH and no tokens.


Architecture

graph TB
    subgraph Callers
        U["Summoner caller<br/>(25 distinct EOAs)"]
        DEP["Deployer EOAs<br/>(3 distinct)"]
    end

    subgraph SS["SafeSummoner — 0x00000000...4e6f2a"]
        V["_validate / _validateModules<br/>pure checks"]
        P["_predictDAO / _predictShares / _predictLoot<br/>address arithmetic"]
        B["_buildCalls / _buildModuleCalls / _buildLootMints<br/>init-call encoder"]
        C2["create2Deploy<br/>arbitrary bytecode"]
        MC["multicall<br/>delegatecall to self"]
    end

    subgraph Majeur["Majeur framework"]
        SUM["Summoner<br/>0x00000000...eE9138"]
        DAO["New Moloch clone<br/>runs init calls as itself"]
        SH["Shares clone"]
        LT["Loot clone"]
    end

    subgraph Singletons["Peripheral singletons (caller-chosen)"]
        SB["ShareBurner<br/>0x00000000...c3Aa9f (default)"]
        SALE["ShareSale"]
        TAP["TapVest"]
        SEED["LPSeedSwapHook"]
        RG["RollbackGuardian"]
    end

    U -->|"safeSummon / presets / DAICO"| V
    V --> P --> B
    B -->|"summon(..., initCalls)"| SUM
    SUM -->|"CREATE2 + init"| DAO
    DAO --> SH
    DAO --> LT
    DAO -.->|"setPermit / setAllowance / configure"| Singletons
    DEP -->|"create2Deploy"| C2
    C2 -->|"90 contracts"| OUT["zFi contracts<br/>TokenList, ZorgConviction, zSwap, ..."]
    U -.-> MC
    MC -.->|"delegatecall"| SS

    style V fill:#e1f0ff
    style C2 fill:#ffe1e1
    style DAO fill:#fff4d6

System Overview

A summon through SafeSummoner runs in four steps, all inside one transaction:

  • Validate. _validate checks the typed SafeConfig against the rules in Validation Rules; _validateModules adds the DAICO-specific checks. All of them are pure.
  • Predict. The DAO's address is derivable before it exists, because Summoner deploys each clone with CREATE2 using keccak256(abi.encode(initHolders, initShares, salt)) as the salt. The Shares and Loot clone addresses follow from the DAO address. SafeSummoner recomputes all three locally.
  • Encode. The predicted addresses are written into the init calls: setPermit targets, setAllowance tokens, mintFromMoloch calls on the Loot clone, and configure calls on module singletons.
  • Forward. SUMMONER.summon{value: msg.value}(...) deploys the clone and has it execute the calls in order. If the prediction were wrong, the calls would target empty addresses and the summon would either revert or silently configure nothing. All 30 DAOs hold the proposal threshold and time-to-live (TTL) that their init calls wrote to the predicted address, so the prediction held each time.

SafeSummoner adds:

  • Reject zero proposal thresholds, zero proposal lifetimes, out-of-range basis-point Quorum, Futarchy without a cap or without any quorum, and minting sales that rely on percentage quorum alone.
  • Mint initial Loot to holders, since Summoner only accepts initial shares.
  • Grant one-shot permits to a ShareBurner (burn unsold sale inventory after a deadline) and to a RollbackGuardian (bump the DAO's config or disable auto-futarchy). The RollbackGuardian is caller-supplied; no deployed instance was identified and no summon has configured one.

SafeSummoner does not:

  • Constrain extraCalls, the holder list, or the share amounts.
  • Record anything. There is no registry of DAOs it summoned and no event of its own. Summoner's NewDAO event names SafeSummoner, not the human caller, as the summoner.
  • Hold or route funds beyond passing msg.value straight through.

Design Patterns Used

  • Counterfactual addressing: every dependency on the not-yet-deployed DAO, its Shares and its Loot is resolved by recomputing the CREATE2 address formula. This removes the need for a two-transaction setup, at the cost of tying correctness to the Summoner's salt scheme and the three hardcoded implementation addresses.
  • Typed builder over raw calls: SafeConfig, SaleModule, TapModule and SeedModule structs replace hand-assembled Calldata. Zero means "skip" for every optional field.
  • Sentinel addresses: the module structs use address(1) and address(2) to mean "this DAO's shares" and "this DAO's loot" before those addresses exist; sale allowances use Moloch's own sentinels, address(dao) (mint shares) and address(1007) (mint loot).
  • One-shot permits as delegated authority: the ShareBurner and RollbackGuardian integrations are expressed as Majeur permits — an ERC-6909 balance of 1 on an intent hash — so a third-party contract can perform exactly one pre-approved action as the DAO.
  • Self-Delegatecall multicall: multicall replays each entry against SafeSummoner itself, preserving msg.sender and msg.value across the batch.
  • Minimal Proxy prediction: the 54-byte (45-byte runtime) 602d5f8160095f39f35f5f365f5f37365f73 <impl> 5af43d5f5f3e6029573d5ffd5b3d5ff3 sequence is the same ERC-1167-style clone creation code Summoner and Moloch use internally.

Validation Rules

All revert with a custom error; none touches state. summonFounder skips _validate, since its hardcoded values satisfy every rule. The Summoner and Moloch.init perform none of these checks — init writes quorumBps without the <= 10_000 bound that setQuorumBps enforces later.

RULE REVERTS WHEN ERROR APPLIES TO
Holders present initHolders.length == 0 NoInitialHolders All except summonFounder
Proposal threshold set proposalThreshold == 0 ProposalThresholdRequired All except summonFounder
Proposal TTL set proposalTTL == 0 ProposalTTLRequired All except summonFounder
Basis-point quorum in range quorumBps > 10_000 QuorumBpsOutOfRange All except summonFounder
Timelock shorter than TTL timelockDelay > 0 && proposalTTL <= timelockDelay TimelockExceedsTTL All except summonFounder
Futarchy needs a quorum autoFutarchyParam > 0 && quorumBps == 0 && quorumAbsolute == 0 QuorumRequiredForFutarchy All except summonFounder
Futarchy needs a cap autoFutarchyParam > 0 && autoFutarchyCap == 0 FutarchyCapRequired All except summonFounder
Minting sale needs absolute quorum saleActive && saleMinting && quorumBps > 0 && quorumAbsolute == 0 MintingSaleWithDynamicQuorum All except summonFounder
Sale price set saleActive && salePricePerShare == 0 SalePriceRequired All except summonFounder
Guardian needs a singleton rollbackGuardian != 0 && rollbackSingleton == 0 RollbackSingletonRequired All except summonFounder
Loot array aligned initLoot.length != 0 && initLoot.length != initHolders.length InitLootLengthMismatch safeSummon, safeSummonDAICO
One sale mechanism config.saleActive && sale.singleton != 0 ModuleSaleConflict safeSummonDAICO
Module sale price set sale.singleton != 0 && sale.price == 0 SalePriceRequired DAICO paths
Module minting sale needs absolute quorum sale.singleton != 0 && sale.minting && quorumBps > 0 && quorumAbsolute == 0 MintingSaleWithDynamicQuorum DAICO paths
Seed gate needs a sale seed.singleton != 0 && seed.gateBySale && sale.singleton == 0 SeedGateWithoutSale DAICO paths

Several rules check that a value is present rather than that it is adequate.


Presets

PRESET TTL TIMELOCK QUORUM BPS THRESHOLD HOLDERS RENDERER
summonStandard / summonStandardDAICO 7 days 2 days 1000 (10%) 1% of initial shares, floor 1 Caller-supplied RENDERER
summonFast / summonFastDAICO 3 days 1 day 500 (5%) 1% of initial shares, floor 1 Caller-supplied RENDERER
summonFounder 1 day None 1000 (10%) 100,000 shares msg.sender alone, 10,000,000 shares RENDERER

All presets set ragequittable = true, enabling Ragequit. summonStandard and summonFast expose a lockShares flag; summonFounder exposes nothing beyond name, symbol, URI and salt.

summonFounder produces a single-key DAO.

On-chain, the stored settings of the 30 summoned DAOs match the paths that created them: 15 carry the Standard preset values, 3 the Fast values and 3 the Founder values. The 9 safeSummonDAICO summons supplied their own SafeConfig and all chose Standard timings with a threshold of one whole share.


Access Control

Roles & Permissions

ROLE ASSIGNED BY REVOKABLE CALL COUNT
Anyone N/A N/A Unlimited

There is no owner or allowlist. The contract has no storage in which a role could be recorded.

Permission Matrix

FUNCTION ANYONE
safeSummon ☑
safeSummonDAICO ☑
summonStandard / summonFast / summonFounder ☑
summonStandardDAICO / summonFastDAICO ☑
create2Deploy ☑
multicall ☑
All view/pure helpers ☑

Time Locks & Delays

ACTION TIME LOCK CAN CANCEL PURPOSE
Summon a DAO None N/A ◇ Immediate. Timelocks belong to the DAO being created, not to the wrapper
Deploy via create2Deploy None N/A ◇ Immediate

Authority over each summoned DAO passes entirely to that DAO's own governance at the end of the summon transaction. SafeSummoner retains nothing; no call it builds names it as a holder or a spender.


Economic Model

SafeSummoner does not hold funds. Every summon path and create2Deploy forwards msg.value in full; multicall forwards nothing itself:

  • Summon paths pass it to Summoner.summon, which passes it to the CREATE2 that deploys the clone, so the ETH lands in the new DAO's treasury.
  • create2Deploy passes it to the CREATE2 of the deployed contract.
  • multicall does not forward anything itself; each delegated sub-call sees the same msg.value and forwards it again.

The contract has no receive or fallback function, so a plain ETH transfer to it reverts. Its balance at block 26,284,732 is 0.

Modular DAICO

The DAICO path composes three separately deployed singletons, configured from inside the DAO's init calls. SafeSummoner only encodes the wiring; the economic logic lives in the singletons, which are not analyzed here. ShareSale and TapVest addresses are in Related Addresses; no LPSeedSwapHook deployment was identified, and no summon has used one.

flowchart LR
    DAO["New DAO<br/>(executing init calls)"]
    SALE["ShareSale"]
    TAP["TapVest"]
    SEED["LPSeedSwapHook"]
    BUY["Buyers"]
    BEN["Tap beneficiary"]
    POOL["ZAMM pool"]

    DAO -->|"setAllowance(sale, token, cap)<br/>configure(token, payToken, price, deadline)"| SALE
    DAO -->|"setAllowance(tap, token, budget)<br/>configure(token, beneficiary, ratePerSec)"| TAP
    DAO -->|"mintFromMoloch (sentinels)<br/>setAllowance x2<br/>configure(...)"| SEED
    BUY -->|"pay"| SALE
    SALE -->|"spendAllowance: mint or transfer"| BUY
    TAP -->|"spendAllowance over time"| BEN
    SEED -->|"spendAllowance x2"| POOL
MODULE ALLOWANCE TOKEN WHAT THE DAO GRANTS
ShareSale address(dao) if minting shares, address(1007) if minting loot, else the predicted Shares/Loot ERC20 Up to cap units minted or transferred to buyers through spendAllowance
TapVest tap.token (address(0) = ETH) Up to budget streamed to one beneficiary at ratePerSec
LPSeedSwapHook tokenA and tokenB, sentinels resolved to predicted Shares/Loot amountA and amountB, with sentinel amounts minted to the DAO first

Of the nine DAICO summons, seven configured a ShareSale — all seven as minting sales, one with an unlimited cap — and four a TapVest. The remaining two, DemosWork 0x54f67E0c...B57220 (etherscan) and VangeCoin 0xb0553fD4...834e4b (etherscan), set up a minting sale through a different contract, ShareOffering 0x000000A4...Ae57e1 (etherscan), using raw extraCalls instead of a module. None used the Liquidity Provider (LP) seed module, and no summon of any kind configured a rollback guardian.


Deployment Activity

ACTIVITY COUNT NOTES
Transactions to the contract 121 2026-03-13 to 2026-09-22
create2Deploy calls 91 90 succeeded, 1 reverted. Contract nonce is 91
Contracts deployed 90 79 verified on Etherscan, 11 unverified. Full list
create2Deploy callers 3 0xAcFBA7Ce...DE4082 (etherscan) 55, 0x1C0Aa8cC...855A20 (etherscan) 30, 0x68575B07...6267C7 (etherscan) 6
DAOs summoned 30 15 Standard, 9 DAICO, 3 Fast, 3 Founder. 30 of the Summoner's 59. Full list
Distinct summoning addresses 25 Most summons are clustered in 2026-05-07 to 2026-05-12
Summoned DAOs with any proposal 1 CELL, 0xD5dcE9BE...ceB8bE (etherscan)

Summary of Observations

SafeSummoner is a configuration linter and Calldata encoder for Majeur DAOs that a frontend can call in one step. The Summoner and Moloch.init accept a zero proposal threshold, a zero TTL, an unbounded basis-point quorum and uncapped futarchy; SafeSummoner rejects each. Its address prediction held for every DAO it has produced, and the stored settings of each match its preset.

The checks run once, at summon time, before any extraCalls the caller appends, and nothing about the result is recorded. The only two summons that used extraCalls added a sale the module validation never saw. A third party evaluating a Majeur DAO learns nothing from the fact that SafeSummoner was involved; they have to read the DAO's current parameters, which governance may have changed since. Several checks also test for the presence of a value rather than its adequacy.

Inherited from the Summoner: the DAO's address depends only on holders, shares and salt, so a pending summon can be pre-empted by anyone who replays those three values with different init calls. Within SafeSummoner itself, multicall lets each sub-call spend msg.value again, which would let anyone drain ETH the contract held — it holds none, and can receive ETH only through its own payable functions or a forced transfer.

This analysis was performed for educational purposes. It is not a security audit and not financial advice.


References

RESOURCE NOTES
Etherscan — SafeSummoner source Verified source, Application Binary Interface (ABI), compiler settings
Etherscan — Summoner Salt derivation and init-call execution
Etherscan — ShareBurner source Behaviour of the burn-unsold permit target
Etherscan — VanityMarket The CREATE3 factory that deployed SafeSummoner
Majeur contract analysis Moloch, Shares, Loot and Summoner behaviour this wrapper configures
Majeur governance companion Proposal ids, permits, and the init-call model in operating terms
github.com/z0r0z/majeur Upstream repository for the framework
EIP-1014: CREATE2 Address derivation used for every prediction

Change Log

DATE AUTHOR NOTES
2026-10-27 Artificial. Generated by robots. Gas: 1 mtok
2026-10-29 Denizen. Reviewed, edited, and curated by humans.