Replaceable DAOs
Sophia contracts are immutable once deployed, and Superhero's contracts have no proxy, no
admin key and no migration hook. A community that wants different governance rules cannot
patch DAO.aes. What it can do is deploy a different DAO contract and vote to hand over
control. ReplaceableDAO.aes defines the interface that makes that possible, and ChangeDAO
is the vote that performs it.
What survives a migration: the AEX-9 token keeps its address, its supply and its holders; the bonding curve keeps its reserve and its price; the community keeps its name and its posts. Only the contract that owns the sale and holds the treasury is replaced.
The interface
A contract that implements all three entrypoints can be the target of a ChangeDAO vote:
| Entrypoint | Signature | Purpose |
|---|---|---|
is_dao | () : bool | Must return true. Blocks transfers to non-DAO addresses. |
get_community_management | () : option(CommunityManagement) | The linked community management contract, or None. |
record_sale_transaction | (address, int) : unit, stateful, payable | Receive sale proceeds with the buyer and buy price as arguments. |
The stock DAO.aes implements all three, so a community's DAO can be replaced by another
instance of the same implementation as well as by a custom one.
record_sale_transaction
stateful payable entrypoint record_sale_transaction(buyer: address, buy_price: int) : unitThe AE arrives with the call; the buyer and the buy price arrive as arguments. A
replacement DAO can therefore act on income the moment it lands: split it between a treasury
and a rewards pool, credit it per buyer, forward a share to a partner contract. The token sale
calls it with protected = true, so an aborting DAO does not block a trade, and calls it with
zero value as a probe on set_beneficiary, so the entrypoint must accept zero-value calls.
is_dao
ChangeDAO transfers ownership of the token sale, the beneficiary rights to all future
proceeds, and the accumulated treasury, in one call. is_dao() returning true is a type
check that the target is at least a DAO-shaped contract: an account address, the token
address or an unrelated contract does not answer the call. It is not a trust check, since any
contract can implement is_dao() = true.
Build a replacement DAO
- Write the contract in Sophia. Implement
is_dao,get_community_managementandrecord_sale_transactionwith exactly the signatures above. Sophia type-checks the interface, so a mismatched arity or a missingpayablefails at the call site. - Decide what it does with authority. The replacement becomes the owner and beneficiary
of the existing
AffiliationBondingCurveTokenSale, and the owner of the existingCommunityManagement. If it does not expose equivalents ofadd_voteandapply_vote_subject, the community loses the ability to appoint moderators or change its write threshold, because those actions can only be reached by the sale's owner. - Point it at the existing
CommunityManagement.apply_vote_subjectassertsget_community_management() == new_dao.get_community_management()and aborts the whole migration withNEW_DAO_HAS_TO_REFERENCE_SAME_COMMUNITY_MANAGEMENTif they differ. The stock DAO derives it by asking its factory (factory.get_community_management(token_sale)), so a replacement built the same way needs the factory address and the sale address at deployment. - Deploy it to the same network, and check that
is_dao()answerstruefrom an external call before proposing anything. - Fund nothing. The treasury transfers with the migration; the target should start empty.
- Publish the source and the bytecode hash so voters can verify that the deployed contract at the proposed address is the code they are being asked to approve.
The migration
A ChangeDAO proposal is an ordinary DAO vote:
- A holder at or above the community threshold calls
DAO.add_vote(metadata)withsubject = ChangeDAO(ct_new_dao...), paying 555 AE. - The vote is open for two weeks.
- It needs at least 55% of the voted stake in favour and at least 10% of total supply participating.
- Within roughly two days of closing, somebody calls
DAO.apply_vote_subject(vote_seq_id). - The old DAO verifies
is_dao()on the target, then transfers the treasury, the sale's beneficiary and owner, and ownership ofCommunityManagement. On the way it checks that the target references the same community management contract.
If nobody applies it inside the window, the vote expires and nothing moves. The 555 AE is spent and the proposal has to be reopened.
What the migration transfers
| Thing | Transferred? | How |
|---|---|---|
| The AE treasury | Yes, in full | Chain.spend(new_dao_address, Contract.balance) |
| Token sale beneficiary | Yes | get_token_sale().set_beneficiary(new_dao_address) |
| Token sale ownership | Yes | get_token_sale().set_owner(new_dao_address) |
CommunityManagement ownership | Yes | community_management.set_owner(new_dao_address) |
| The moderator roster, mute list, threshold and metadata | Untouched | They live in CommunityManagement, which is not redeployed |
| The AEX-9 token, its supply and its holders | Untouched | Not owned by the DAO |
| The bonding curve and its reserve | Untouched | Held by the sale contract, which is not replaced |
| The vote history | Not transferred | DAO.votes stays on the old contract, which keeps answering votes() |
Because CommunityManagement.set_owner is called in the same transaction, the
AddModerator, DeleteModerator, ChangeMinimumTokenThreshold and ChangeMetaInfo
subjects keep working after a migration, provided the replacement DAO implements equivalents
of add_vote and apply_vote_subject to reach them.
A community's governance history after a migration is split across two contracts, and the new DAO's vote ids restart at zero.
What a ChangeDAO vote commits to
- It is irreversible by the old DAO. Reversing a migration requires the new DAO to offer
a
ChangeDAOequivalent. is_dao()proves nothing about intent. Any contract can pass the check.- The vote approves an address. Unless the source is published and the deployed bytecode matches it, holders are approving the proposer's word.
- Governance is whatever the replacement implements, and that could be a single owner key.
- The treasury moves in the same transaction. There is no staged handover, trial period or clawback.
Before voting, check that the source is published, that the bytecode at the proposed address matches it, that the replacement implements proposals and voting, and who controls it.
Related
- Proposals and Vote Subjects:
ChangeDAOalongside the other six subjects. - The Treasury: what
record_sale_transactiondoes in the stock DAO. - How DAOs Work: the vote and execution steps a migration passes through.
- Quorum and Thresholds: why a replacement DAO can use different constants.
- DAO contract reference: the stock implementation a replacement stands in for.
- Moderators and Write Thresholds: the
CommunityManagementcontract whose ownership the migration moves. - Sophia and FATE: the language and VM a replacement DAO is written for.