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 |
Related Addresses
| 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.
_validatechecks the typedSafeConfigagainst the rules in Validation Rules;_validateModulesadds the DAICO-specific checks. All of them arepure. - Predict. The DAO's address is derivable before it exists, because
Summonerdeploys each clone withCREATE2usingkeccak256(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:
setPermittargets,setAllowancetokens,mintFromMolochcalls on the Loot clone, andconfigurecalls 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
Summoneronly 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'sNewDAOevent names SafeSummoner, not the human caller, as the summoner. - Hold or route funds beyond passing
msg.valuestraight through.
Design Patterns Used
- Counterfactual addressing: every dependency on the not-yet-deployed DAO, its Shares and its Loot is resolved by recomputing the
CREATE2address formula. This removes the need for a two-transaction setup, at the cost of tying correctness to theSummoner's salt scheme and the three hardcoded implementation addresses. - Typed builder over raw calls:
SafeConfig,SaleModule,TapModuleandSeedModulestructs replace hand-assembled Calldata. Zero means "skip" for every optional field. - Sentinel addresses: the module structs use
address(1)andaddress(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) andaddress(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:
multicallreplays each entry against SafeSummoner itself, preservingmsg.senderandmsg.valueacross the batch. - Minimal Proxy prediction: the 54-byte (45-byte runtime)
602d5f8160095f39f35f5f365f5f37365f73 <impl> 5af43d5f5f3e6029573d5ffd5b3d5ff3sequence is the same ERC-1167-style clone creation codeSummonerandMolochuse 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 theCREATE2that deploys the clone, so the ETH lands in the new DAO's treasury. create2Deploypasses it to theCREATE2of the deployed contract.multicalldoes not forward anything itself; each delegated sub-call sees the samemsg.valueand 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. |