Architecture
A DAO Ships "ship" is not a single contract. It is a small constellation of contracts that
deploy together and play distinct roles: a governance module (DAOShip), two ERC-20 tokens
(SharesERC20 and LootERC20), a treasury (a Quai Vault acting as the avatar), and an
on-chain metadata bus (Poster). A factory — DAOShipAndVaultLauncher — wires them up in a
single transaction. This page explains how the pieces relate.
The canonical deployment lives on Quai mainnet (Cyprus-1), chain ID 9, with a parallel
deployment on the Orchard testnet (Cyprus-1), chain ID 15000. See
Contracts for the per-network address tables.
The components
| Component | Role |
|---|---|
DAOShip | The governance engine — proposals, voting, ragequit, navigator and guild-token management. Holds no funds. |
SharesERC20 | Voting token. Timestamp-checkpointed voting power with auto-delegation. |
LootERC20 | Non-voting economic token. Counts toward a member's ragequit claim. |
| Quai Vault | The treasury (the avatar). Holds all assets. DAOShip is enabled as a module on it. |
DAOShipAndVaultLauncher | Atomic factory: one transaction deploys the vault, DAOShip, and both tokens. |
Poster | EIP-3722 content bus. Emits NewPost(user, content, tag) for off-chain metadata. |
The Zodiac IAvatar pattern
DAOShip follows the Zodiac module pattern. The vault is a
Zodiac-compatible avatar: a smart account that can execute transactions on behalf of enabled
modules. DAOShip is enabled as a module on its vault, so when a proposal passes, DAOShip
spends treasury funds by calling the avatar's execTransactionFromModule:
// 3-param convenience form for plain Call operations
IAvatar(avatar).execTransactionFromModule(to, value, data);
// 4-param form for DelegateCall (e.g. MultiSend batching)
IAvatar(avatar).execTransactionFromModule(to, value, data, Enum.Operation.DelegateCall);This separation is the core safety property: the vault holds the money, DAOShip holds none.
DAOShip has no receive() function — the treasury is always the vault. If governance ever
misbehaves, vault owners retain the emergency power to disable the module.
EIP-1167 clones and atomic deployment
The tokens and the DAOShip instance are EIP-1167 minimal proxy clones of pre-deployed
singletons (logic contracts). Cloning costs roughly 300K gas versus around 4M for deploying
a fresh singleton. The vault is an ERC-1967 proxy created by the Quai Vault factory.
Deployment is atomic and avoids a separate enableModule step. The launcher uses a
predict-then-create flow:
- Predict the
DAOShipclone address deterministically (CREATE2). - Create the vault with
initialModules = [predictedDAOShip]and MultiSendCallOnly whitelisted as a DelegateCall target. - Launch
DAOShipwith the freshly created vault address injected as theavatar. - Assert the predicted address equals the actual deployed address.
Because CREATE2 addresses are deterministic, callers can mine salts off-chain so every clone
lands on the Cyprus-1 0x00 shard prefix. See
Launch from TypeScript for the salt-mining workflow.
Execution flow
┌──────────────────────────────┐
│ DAOShipAndVaultLauncher │
│ (CREATE2 clones + vault proxy)│
└───────────────┬────────────────┘
│ one transaction
┌───────────────────────┼────────────────────────┐
▼ ▼ ▼
┌────────────┐ ┌────────────────┐ ┌──────────────┐
│ SharesERC20│◄────────│ DAOShip │───────►│ LootERC20 │
│ (voting) │ mint/ │ (governance │ mint/ │ (economic) │
└────────────┘ burn │ module) │ burn └──────────────┘
└───────┬─────────┘
execTransactionFromModule │
▼
┌──────────────────┐
│ Quai Vault │
│ (avatar/treasury) │
└──────────────────┘
Poster (EIP-3722) ──NewPost(user, content, tag)──► off-chain indexers / frontendsNavigators
Navigators are immutable extension contracts that add behavior to a ship — onboarding, polls,
vesting, recurring payouts — without changing the DAOShip core. Architecturally they fall into
three classes, distinguished by where their authority attaches:
| Class | Attaches to | Example |
|---|---|---|
| Permissioned | DAOShip, via an additive bitmask (ADMIN = 1, MANAGER = 2, GOVERNOR = 4) granted with setNavigators | Onboarder, Timelock, Vesting |
| Read-only | Nothing — it only reads DAOShip state (e.g. getPriorVotes) and is endorsed by a vault Poster post | Signal polls |
| Module | The Quai Vault, enabled as a Zodiac module exactly as DAOShip is — it moves treasury funds and takes no DAOShip permission | Budget |
That last class is the architecturally notable one: a module navigator sits beside DAOShip on
the vault and calls execTransactionFromModule itself, rather than routing through governance per
payment. See Navigators overview for the full catalog and trust model.
Trust model
A MANAGER navigator can mint shares and loot; a vault-module navigator can move funds. They run
with real power, so they must be immutable, reentrancy-guarded, and bounded by caps and expiry. See
Build a Navigator.
Where to go next
- Contracts — real deployed addresses and key functions.
- Launch from TypeScript — deploy a DAO with the quais SDK.
- Indexer — read DAO state from Supabase.
- Build a Navigator — write your own extension.