From ea9e3cdf58bd30fa627c2c41b3f350d65669cc42 Mon Sep 17 00:00:00 2001 From: x Date: Sun, 8 Jan 2023 09:56:31 +0100 Subject: [PATCH] add DAO wallet.sql --- src/contract/dao/tests/integration.rs | 3 - src/contract/dao/wallet.sql | 172 ++++++++++++++++++++++++++ 2 files changed, 172 insertions(+), 3 deletions(-) create mode 100644 src/contract/dao/wallet.sql diff --git a/src/contract/dao/tests/integration.rs b/src/contract/dao/tests/integration.rs index 924a22456..431d07648 100644 --- a/src/contract/dao/tests/integration.rs +++ b/src/contract/dao/tests/integration.rs @@ -539,7 +539,6 @@ async fn integration_test() -> Result<()> { // TODO: look into verifiable encryption for notes // TODO: look into timelock puzzle as a possibility let vote_note_1 = { - // TODO: EncryptedNote should be accessible by wasm and put in the structs directly let enc_note = note::EncryptedNote2 { ciphertext: params.ciphertext, ephem_public: params.ephem_public, @@ -607,7 +606,6 @@ async fn integration_test() -> Result<()> { dao_th.alice_state.read().await.verify_transactions(&[tx.clone()], true).await?; let vote_note_2 = { - // TODO: EncryptedNote should be accessible by wasm and put in the structs directly let enc_note = note::EncryptedNote2 { ciphertext: params.ciphertext, ephem_public: params.ephem_public, @@ -678,7 +676,6 @@ async fn integration_test() -> Result<()> { // TODO: look into verifiable encryption for notes // TODO: look into timelock puzzle as a possibility let vote_note_3 = { - // TODO: EncryptedNote should be accessible by wasm and put in the structs directly let enc_note = note::EncryptedNote2 { ciphertext: params.ciphertext, ephem_public: params.ephem_public, diff --git a/src/contract/dao/wallet.sql b/src/contract/dao/wallet.sql new file mode 100644 index 000000000..1373f68fe --- /dev/null +++ b/src/contract/dao/wallet.sql @@ -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... +); +