|
|
@@ -0,0 +1,172 @@
|
|
|
+-- # DAO::mint()
|
|
|
+--
|
|
|
+-- First one person will create the DAO
|
|
|
+--
|
|
|
+-- $ drk dao create_dao \
|
|
|
+-- PROPOSER_LIMIT \
|
|
|
+-- QUORUM \
|
|
|
+-- APPROVAL_RATIO_BASE \
|
|
|
+-- APPROVAL_RATIO_QUOTIENT \
|
|
|
+-- GOV_TOKEN_ID > dao.dat
|
|
|
+--
|
|
|
+-- dat.dat contains:
|
|
|
+--
|
|
|
+-- * DAO parameters as listed above
|
|
|
+-- * secret key for the DAO
|
|
|
+-- * bulla blind
|
|
|
+--
|
|
|
+-- We can view the data like so:
|
|
|
+--
|
|
|
+-- $ drk dao view_dao < dao.dat
|
|
|
+--
|
|
|
+-- Now everyone inside the DAO exchanges dao.dat out of band will import
|
|
|
+-- it into their wallets.
|
|
|
+--
|
|
|
+-- $ drk dao import_dao DAO_NAME < dao.dat
|
|
|
+-- Imported DAO ccb8XXX8af6
|
|
|
+--
|
|
|
+-- Where ccb8XXX8af6 is the DAO's bulla.
|
|
|
+--
|
|
|
+-- Next one person will mint it on chain
|
|
|
+--
|
|
|
+-- $ drk dao mint DAO_NAME
|
|
|
+-- Broadcasted DAO ccb8XXX8af6
|
|
|
+--
|
|
|
+-- And then the others will receive confirmation that the DAO they imported
|
|
|
+-- into their wallet has also been accepted on chain.
|
|
|
+
|
|
|
+-- # Minting and Receiving Coin
|
|
|
+--
|
|
|
+-- Assume that the governance tokens have been created and distributed
|
|
|
+-- appropriately among DAO members. We will skip that part here.
|
|
|
+--
|
|
|
+-- Now the DAO can receive coins into its treasury. These coins simply
|
|
|
+-- have both the coin's spend_hook and user_data fields set correctly
|
|
|
+-- otherwise they are rejected as invalid/malformed.
|
|
|
+
|
|
|
+-- # DAO::propose()
|
|
|
+--
|
|
|
+-- Create a proposal for the DAO
|
|
|
+--
|
|
|
+-- $ drk dao propose \
|
|
|
+-- DAO_NAME \
|
|
|
+-- RECV_PUBKEY \
|
|
|
+-- AMOUNT \
|
|
|
+-- SERIAL \
|
|
|
+-- SENDCOIN_TOKEN_ID
|
|
|
+--
|
|
|
+-- If we don't have enough tokens to meet the proposer_limit threshold
|
|
|
+-- then this call will simply fail with an error message. Nothing will
|
|
|
+-- be added to the database or sent to the network.
|
|
|
+--
|
|
|
+-- The other participants should automatically receive the proposal
|
|
|
+-- ready to vote on it.
|
|
|
+
|
|
|
+-- # DAO::vote()
|
|
|
+--
|
|
|
+-- You have received a proposal which is active. You can now vote on it.
|
|
|
+--
|
|
|
+-- $ drk dao proposals DAO_NAME
|
|
|
+-- [0] f6cae63ced53d02b372206a8d3ed5ac03fde18da306a520285fd56e8d031f6cf
|
|
|
+-- [1] 1372622f4a38be6eb1c90fa67864474c6603d9f8d4228106e20e2d0d04f2395e
|
|
|
+-- [2] 88b18cbc38dbd3af8d25237af3903e985f70ea06d1e25966bf98e3f08e23c992
|
|
|
+--
|
|
|
+-- $ drk dao show_proposal 1
|
|
|
+-- Proposal: 1372622f4a38be6eb1c90fa67864474c6603d9f8d4228106e20e2d0d04f2395e
|
|
|
+-- destination: ...
|
|
|
+-- amount: ...
|
|
|
+-- token_id: ...
|
|
|
+-- dao_name: DAO_NAME
|
|
|
+-- dao_bulla: ...
|
|
|
+-- Current yes votes: X
|
|
|
+-- Current no votes: Y
|
|
|
+-- Total votes: X + Y
|
|
|
+-- [================ ] 45.56%
|
|
|
+-- DAO quorum threshold: Z
|
|
|
+-- DAO approval ratio: 60%
|
|
|
+--
|
|
|
+-- $ drk dao vote 1 yes
|
|
|
+
|
|
|
+-- # DAO::exec()
|
|
|
+--
|
|
|
+-- Once there are enough yes votes to satisfy the quorum and approval ratio,
|
|
|
+-- then any DAO member can execute the payment out of the treasury.
|
|
|
+--
|
|
|
+-- $ drk dao exec 1
|
|
|
+--
|
|
|
+-- FUTURE NOTE: We have to assume that 2 people could try to exec at once.
|
|
|
+-- So if our exec fails, then the tx fee we pay should be returned
|
|
|
+-- to our wallet.
|
|
|
+-- We should design our tables for exec accordingly.
|
|
|
+-- For now I didn't put anything, but we should keep this minor
|
|
|
+-- point in mind and ruminate on it for later.
|
|
|
+
|
|
|
+CREATE TABLE IF NOT EXISTS dao_daos (
|
|
|
+ dao_id INTEGER PRIMARY KEY NOT NULL,
|
|
|
+ name VARCHAR UNIQUE NOT NULL,
|
|
|
+ proposer_limit INTEGER NOT NULL,
|
|
|
+ -- minimum threshold for total number of votes for proposal to pass.
|
|
|
+ -- If there's too little activity then it cannot pass.
|
|
|
+ quorum INTEGER NOT NULL,
|
|
|
+ -- Needed ratio of yes/total for proposal to pass.
|
|
|
+ -- approval_ratio = approval_ratio_quot / approval_ratio_base
|
|
|
+ approval_ratio_base INTEGER NOT NULL,
|
|
|
+ approval_ratio_quot INTEGER NOT NULL,
|
|
|
+ gov_token_id BLOB NOT NULL,
|
|
|
+ secret BLOB NOT NULL,
|
|
|
+ bulla_blind BLOB NOT NULL,
|
|
|
+ -- these values are NULL until the DAO is minted on chain and received
|
|
|
+ leaf_position BLOB,
|
|
|
+ tx_hash BLOB,
|
|
|
+ call_index INTEGER
|
|
|
+);
|
|
|
+
|
|
|
+-- The merkle tree containing DAO bullas
|
|
|
+CREATE TABLE IF NOT EXISTS dao_trees (
|
|
|
+ daos_tree BLOB NOT NULL
|
|
|
+ proposals_tree BLOB NOT NULL
|
|
|
+);
|
|
|
+
|
|
|
+-- NOTE: we should rename coin as coin_id in the money_coins table
|
|
|
+-- and also keep track of the tx hash, call index, output of the coin.
|
|
|
+-- There should also be a spends table which tracks
|
|
|
+-- tx_hash:call_index:input
|
|
|
+
|
|
|
+-- This table maps received coins to its DAO owner and vice versa.
|
|
|
+CREATE TABLE IF NOT EXISTS dao_coins (
|
|
|
+ coin_id INTEGER PRIMARY KEY NOT NULL,
|
|
|
+ dao_id INTEGER UNIQUE NOT NULL
|
|
|
+);
|
|
|
+
|
|
|
+CREATE TABLE IF NOT EXISTS dao_proposals (
|
|
|
+ proposal_id INTEGER PRIMARY KEY NOT NULL,
|
|
|
+ dao_id INTEGER NOT NULL,
|
|
|
+ -- Public key of person that would receive the funds
|
|
|
+ recv_public BLOB NOT NULL,
|
|
|
+ -- Amount of funds that would be sent
|
|
|
+ amount INTEGER NOT NULL,
|
|
|
+ serial BLOB NOT NULL,
|
|
|
+ -- Token ID we propose to send
|
|
|
+ sendcoin_token_id BLOB NOT NULL,
|
|
|
+ bulla_blind BLOB NOT NULL,
|
|
|
+ -- these values are NULL until the proposal is minted on chain
|
|
|
+ -- and received by the DAO
|
|
|
+ leaf_position BLOB,
|
|
|
+ tx_hash BLOB,
|
|
|
+ call_index INTEGER
|
|
|
+ -- this is NULL until we have voted on this proposal
|
|
|
+ our_vote_id INTEGER UNIQUE,
|
|
|
+);
|
|
|
+
|
|
|
+CREATE TABLE IF NOT EXISTS dao_votes (
|
|
|
+ vote_id INTEGER PRIMARY KEY NOT NULL,
|
|
|
+ proposal_id INTEGER NOT NULL,
|
|
|
+ vote_option INTEGER NOT NULL
|
|
|
+ -- these values are NULL until the vote is minted on chain
|
|
|
+ -- and received by the DAO
|
|
|
+ tx_hash BLOB,
|
|
|
+ call_index INTEGER
|
|
|
+ -- My code has votes merkle tree and position for votes, but
|
|
|
+ -- that might be a mistake...
|
|
|
+);
|
|
|
+
|