mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-08 22:28:12 -05:00
dao: all documentation updated
This commit is contained in:
@@ -5,29 +5,29 @@
|
|||||||
-- $ drk dao create_dao \
|
-- $ drk dao create_dao \
|
||||||
-- PROPOSER_LIMIT \
|
-- PROPOSER_LIMIT \
|
||||||
-- QUORUM \
|
-- QUORUM \
|
||||||
-- APPROVAL_RATIO_BASE \
|
-- EARLY_EXEC_QUORUM \
|
||||||
-- APPROVAL_RATIO_QUOTIENT \
|
-- APPROVAL_RATIO \
|
||||||
-- GOV_TOKEN_ID > dao.dat
|
-- GOV_TOKEN_ID > dao.toml
|
||||||
--
|
--
|
||||||
-- dat.dat contains:
|
-- dat.toml contains:
|
||||||
--
|
--
|
||||||
-- * DAO parameters as listed above
|
-- * DAO parameters as listed above
|
||||||
-- * secret key for the DAO
|
-- * Secret keys for the DAO
|
||||||
-- * bulla blind
|
-- * Bulla blind
|
||||||
--
|
--
|
||||||
-- We can view the data like so:
|
-- We can view the data like so:
|
||||||
--
|
--
|
||||||
-- $ drk dao view < dao.dat
|
-- $ drk dao view < dao.toml
|
||||||
--
|
--
|
||||||
-- Now everyone inside the DAO exchanges dao.dat out of band will import
|
-- Now everyone inside the DAO exchanges dao.toml out of band,
|
||||||
-- it into their wallets.
|
-- will import it into their wallets.
|
||||||
--
|
--
|
||||||
-- $ drk dao import DAO_NAME < dao.dat
|
-- $ drk dao import DAO_NAME < dao.toml
|
||||||
-- Imported DAO ccb8XXX8af6
|
-- Imported DAO ccb8XXX8af6
|
||||||
--
|
--
|
||||||
-- Where ccb8XXX8af6 is the DAO's name.
|
-- Where ccb8XXX8af6 is the DAO's name.
|
||||||
--
|
--
|
||||||
-- Next one person will mint it on chain
|
-- Next someone that holds all the keys will mint it on chain
|
||||||
--
|
--
|
||||||
-- $ drk dao mint DAO_NAME > dao_mint_tx
|
-- $ drk dao mint DAO_NAME > dao_mint_tx
|
||||||
-- $ drk broadcast < dao_mint_tx
|
-- $ drk broadcast < dao_mint_tx
|
||||||
@@ -56,8 +56,9 @@
|
|||||||
-- RECV_PUBKEY
|
-- RECV_PUBKEY
|
||||||
--
|
--
|
||||||
-- If we don't have enough tokens to meet the proposer_limit threshold
|
-- 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
|
-- or don't hold the proposer key, then this call will simply fail with
|
||||||
-- be added to the database or sent to the network.
|
-- an error message. Nothing will be added to the database or sent to the
|
||||||
|
-- network.
|
||||||
--
|
--
|
||||||
-- Once a proposal has been generated, it can be exported and shared
|
-- Once a proposal has been generated, it can be exported and shared
|
||||||
-- to other participants.
|
-- to other participants.
|
||||||
@@ -73,6 +74,7 @@
|
|||||||
-- # DAO::vote()
|
-- # DAO::vote()
|
||||||
--
|
--
|
||||||
-- You have received a proposal which is active. You can now vote on it.
|
-- You have received a proposal which is active. You can now vote on it.
|
||||||
|
-- You will see other votes only if you hold the DAO votes view key.
|
||||||
--
|
--
|
||||||
-- $ drk dao proposals DAO_NAME
|
-- $ drk dao proposals DAO_NAME
|
||||||
-- 0. f6cae63ced53d02b372206a8d3ed5ac03fde18da306a520285fd56e8d031f6cf
|
-- 0. f6cae63ced53d02b372206a8d3ed5ac03fde18da306a520285fd56e8d031f6cf
|
||||||
|
|||||||
@@ -2758,11 +2758,6 @@ impl Drk {
|
|||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check we know the plaintext data
|
|
||||||
if proposal.data.is_none() {
|
|
||||||
return Err(Error::Custom("[dao_vote] Proposal plainext data is empty".to_string()))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch DAO and check its deployed
|
// Fetch DAO and check its deployed
|
||||||
let Ok(dao) = self.get_dao_by_bulla(&proposal.proposal.dao_bulla).await else {
|
let Ok(dao) = self.get_dao_by_bulla(&proposal.proposal.dao_bulla).await else {
|
||||||
return Err(Error::Custom(format!(
|
return Err(Error::Custom(format!(
|
||||||
|
|||||||
@@ -35,45 +35,46 @@ testnet user guide.
|
|||||||
Note: List is not exhaustive. Missing functionalities that are not part
|
Note: List is not exhaustive. Missing functionalities that are not part
|
||||||
of the guide can be added for future regressions.
|
of the guide can be added for future regressions.
|
||||||
|
|
||||||
| # | Description | Command | Status |
|
| # | Description | Command | Status |
|
||||||
|----|---------------------------|----------------------------------------------------------|--------------------|
|
|----|------------------------------|-----------------------------------------------------------------|--------|
|
||||||
| 0 | Initialization | wallet --initialize | Pass |
|
| 0 | Initialization | wallet --initialize | Pass |
|
||||||
| 1 | Key generation | wallet --keygen | Pass |
|
| 1 | Key generation | wallet --keygen | Pass |
|
||||||
| 2 | Set default wallet | wallet --default-address {ADDR_ID} | Pass |
|
| 2 | Set default wallet | wallet --default-address {ADDR_ID} | Pass |
|
||||||
| 3 | Default address retrieval | wallet --address | Pass |
|
| 3 | Default address retrieval | wallet --address | Pass |
|
||||||
| 4 | Block scanning | scan | Pass |
|
| 4 | Block scanning | scan | Pass |
|
||||||
| 5 | Block subscribing | subscribe | Pass |
|
| 5 | Block subscribing | subscribe | Pass |
|
||||||
| 6 | Balance retrieval | wallet --balance | Pass |
|
| 6 | Balance retrieval | wallet --balance | Pass |
|
||||||
| 7 | Aliases retrieval | alias show | Pass |
|
| 7 | Aliases retrieval | alias show | Pass |
|
||||||
| 8 | Mint auth generation | token generate-mint | Pass |
|
| 8 | Mint auth generation | token generate-mint | Pass |
|
||||||
| 9 | Mint auths retrieval | token list | Pass |
|
| 9 | Mint auths retrieval | token list | Pass |
|
||||||
| 10 | Alias add | alias add {ALIAS} {TOKEN} | Pass |
|
| 10 | Alias add | alias add {ALIAS} {TOKEN} | Pass |
|
||||||
| 11 | Aliases retrieval | alias show | Pass |
|
| 11 | Aliases retrieval | alias show | Pass |
|
||||||
| 12 | Mint generation | token mint {ALIAS} {AMOUNT} {ADDR} | Pass |
|
| 12 | Mint generation | token mint {ALIAS} {AMOUNT} {ADDR} | Pass |
|
||||||
| 13 | Token freeze | token freeze {ALIAS} | Pass |
|
| 13 | Token freeze | token freeze {ALIAS} | Pass |
|
||||||
| 14 | Transfer | transfer {AMOUNT} {ALIAS} {ADDR} | Pass |
|
| 14 | Transfer | transfer {AMOUNT} {ALIAS} {ADDR} | Pass |
|
||||||
| 15 | Coins retrieval | wallet --coins | Pass |
|
| 15 | Coins retrieval | wallet --coins | Pass |
|
||||||
| 16 | OTC initialization | otc init -v {AMOUNT}:{AMOUNT} -t {ALIAS}:{ALIAS} | Pass |
|
| 16 | OTC initialization | otc init -v {AMOUNT}:{AMOUNT} -t {ALIAS}:{ALIAS} | Pass |
|
||||||
| 17 | OTC join | otc join | Pass |
|
| 17 | OTC join | otc join | Pass |
|
||||||
| 18 | OTC sign | otc sign | Pass |
|
| 18 | OTC sign | otc sign | Pass |
|
||||||
| 19 | DAO create | dao create {LIMIT} {QUORUM} {RATIO} {TOKEN} | Pass |
|
| 19 | DAO create | dao create {LIMIT} {QUORUM} {EARLY_EXEC_QUORUM} {RATIO} {TOKEN} | Pass |
|
||||||
| 20 | DAO view | dao view | Pass |
|
| 20 | DAO view | dao view | Pass |
|
||||||
| 21 | DAO import | dao import | Pass |
|
| 21 | DAO import | dao import | Pass |
|
||||||
| 22 | DAO list | dao list | Pass |
|
| 22 | DAO update keys | dao update-keys | Pass |
|
||||||
| 23 | DAO mint | dao mint {DAO} | Pass |
|
| 23 | DAO list | dao list | Pass |
|
||||||
| 24 | DAO balance | dao balance {DAO} | Pass |
|
| 24 | DAO mint | dao mint {DAO} | Pass |
|
||||||
| 25 | DAO proposals retrieval | dao proposals {DAO} | Pass |
|
| 25 | DAO balance | dao balance {DAO} | Pass |
|
||||||
| 26 | DAO propose a transfer | dao propose-transfer {DAO} {DUR} {AMOUNT} {TOKEN} {ADDR} | Pass |
|
| 26 | DAO proposals retrieval | dao proposals {DAO} | Pass |
|
||||||
| 27 | DAO proposals retrieval | dao proposals {DAO} | Pass |
|
| 27 | DAO propose a transfer | dao propose-transfer {DAO} {DUR} {AMOUNT} {TOKEN} {ADDR} | Pass |
|
||||||
| 28 | DAO proposal retrieval | dao proposal {PROPOSAL_BULLA} | Pass |
|
| 28 | DAO propose generic | dao propose-generic {DAO} {DUR} {AMOUNT} {TOKEN} {ADDR} | Pass |
|
||||||
| 29 | DAO proposal export | dao proposal {PROPOSAL_BULLA} --export | Pass |
|
| 29 | DAO proposal retrieval | dao proposal {PROPOSAL_BULLA} | Pass |
|
||||||
| 30 | DAO proposal import | dao proposal-import | Pass |
|
| 30 | DAO proposal export | dao proposal {PROPOSAL_BULLA} --export | Pass |
|
||||||
| 31 | DAO proposal mint | dao proposal {PROPOSAL_BULLA} --mint-proposal | Pass |
|
| 31 | DAO proposal import | dao proposal-import | Pass |
|
||||||
| 32 | DAO vote | dao vote {PROPOSAL_BULLA} {VOTE} {WEIGHT} | Pass |
|
| 32 | DAO proposal mint | dao proposal {PROPOSAL_BULLA} --mint-proposal | Pass |
|
||||||
| 33 | DAO proposal execution | dao exec {PROPOSAL_BULLA} | Pass |
|
| 33 | DAO vote | dao vote {PROPOSAL_BULLA} {VOTE} {WEIGHT} | Pass |
|
||||||
| 34 | Coins unspend | unspend {COIN} | Pass |
|
| 34 | DAO proposal execution | dao exec {PROPOSAL_BULLA} | Pass |
|
||||||
| 35 | Transaction inspect | inspect | Pass |
|
| 35 | DAO proposal early execution | dao exec --early {PROPOSAL_BULLA} | Pass |
|
||||||
| 36 | Transaction simulate | explorer simulate-tx | Pass |
|
| 36 | Coins unspend | unspend {COIN} | Pass |
|
||||||
| 37 | Transaction broadcast | broadcast | Pass |
|
| 37 | Transaction inspect | inspect | Pass |
|
||||||
| 38 | Transaction attach fee | attach-fee | Pass |
|
| 38 | Transaction simulate | explorer simulate-tx | Pass |
|
||||||
|
| 39 | Transaction broadcast | broadcast | Pass |
|
||||||
|
| 40 | Transaction attach fee | attach-fee | Pass |
|
||||||
|
|||||||
@@ -5,12 +5,14 @@ set -x
|
|||||||
# Path to `drk` binary
|
# Path to `drk` binary
|
||||||
DRK="../../../drk -c drk.toml"
|
DRK="../../../drk -c drk.toml"
|
||||||
|
|
||||||
# First run the consensus node and the faucet:
|
# First run the darkfid node and the miner:
|
||||||
#
|
#
|
||||||
# ./clean.sh
|
# ./clean.sh
|
||||||
|
# ./init-wallet.sh
|
||||||
# ./tmux_sessions.sh -vv
|
# ./tmux_sessions.sh -vv
|
||||||
#
|
#
|
||||||
# In another term run the wallet syncing:
|
# In another term run the wallet syncing,
|
||||||
|
# and wait until some blocks are mined:
|
||||||
#
|
#
|
||||||
# ./sync-wallet.sh
|
# ./sync-wallet.sh
|
||||||
#
|
#
|
||||||
@@ -61,8 +63,8 @@ wait_tokens() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mint_dao() {
|
mint_dao() {
|
||||||
$DRK dao create 20 10 0.67 MLDY > /tmp/dao.dat
|
$DRK dao create 20 10 10 0.67 MLDY > /tmp/dao.toml
|
||||||
$DRK dao import MiladyMakerDAO < /tmp/dao.dat
|
$DRK dao import MiladyMakerDAO < /tmp/dao.toml
|
||||||
$DRK dao list
|
$DRK dao list
|
||||||
$DRK dao list MiladyMakerDAO
|
$DRK dao list MiladyMakerDAO
|
||||||
|
|
||||||
@@ -70,19 +72,20 @@ mint_dao() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
wait_dao_mint() {
|
wait_dao_mint() {
|
||||||
while [ "$($DRK dao list MiladyMakerDAO | grep '^Tx hash: ' | awk '{print $3}')" = None ]; do
|
while [ "$($DRK dao list MiladyMakerDAO | grep '^Transaction hash: ' | awk '{print $3}')" = None ]; do
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
fill_treasury() {
|
fill_treasury() {
|
||||||
PUBKEY="$($DRK dao list 1 | grep '^Public key: ' | cut -d ' ' -f3)"
|
PUBKEY="$($DRK dao list MiladyMakerDAO | grep '^Notes Public key: ' | cut -d ' ' -f4)"
|
||||||
BULLA="$($DRK dao list 1 | grep '^Bulla: ' | cut -d' ' -f2)"
|
SPEND_HOOK="$($DRK dao spend-hook)"
|
||||||
$DRK transfer 20 WCKD "$PUBKEY" --dao "$BULLA" | tee /tmp/xfer.tx | $DRK broadcast
|
BULLA="$($DRK dao list MiladyMakerDAO | grep '^Bulla: ' | cut -d' ' -f2)"
|
||||||
|
$DRK transfer 20 WCKD "$PUBKEY" "$SPEND_HOOK" "$BULLA" | tee /tmp/xfer.tx | $DRK broadcast
|
||||||
}
|
}
|
||||||
|
|
||||||
dao_balance() {
|
dao_balance() {
|
||||||
BALANCE=$($DRK dao balance 1 2>/dev/null)
|
BALANCE=$($DRK dao balance MiladyMakerDAO 2>/dev/null)
|
||||||
# No tokens received at all yet
|
# No tokens received at all yet
|
||||||
if echo "$BALANCE" | grep -q "No unspent balances found"; then
|
if echo "$BALANCE" | grep -q "No unspent balances found"; then
|
||||||
echo 0
|
echo 0
|
||||||
@@ -108,51 +111,44 @@ wait_dao_treasury() {
|
|||||||
|
|
||||||
propose() {
|
propose() {
|
||||||
MY_ADDR=$($DRK wallet --address)
|
MY_ADDR=$($DRK wallet --address)
|
||||||
$DRK dao balance MiladyMakerDAO
|
PROPOSAL="$($DRK dao propose-transfer MiladyMakerDAO 1 5 WCKD "$MY_ADDR" | cut -d' ' -f3)"
|
||||||
$DRK dao propose MiladyMakerDAO "$MY_ADDR" 0.1 WCKD > /tmp/propose.tx
|
$DRK dao proposal "$PROPOSAL" --mint-proposal > /tmp/propose.tx
|
||||||
$DRK broadcast < /tmp/propose.tx
|
$DRK broadcast < /tmp/propose.tx
|
||||||
}
|
}
|
||||||
|
|
||||||
proposal_status() {
|
|
||||||
PROPOSALS_LEN=$($DRK dao proposals MiladyMakerDAO | wc -l)
|
|
||||||
if [ "$PROPOSALS_LEN" = 0 ]; then
|
|
||||||
echo 0
|
|
||||||
else
|
|
||||||
echo 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
wait_proposal() {
|
wait_proposal() {
|
||||||
while [ "$(proposal_status)" = 0 ]; do
|
PROPOSAL="$($DRK dao proposals MiladyMakerDAO | cut -d' ' -f2)"
|
||||||
|
while [ "$($DRK dao proposal $PROPOSAL | grep '^Proposal transaction hash: ' | awk '{print $4}')" = None ]; do
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
vote() {
|
vote() {
|
||||||
PROPOSAL_ID=1
|
PROPOSAL="$($DRK dao proposals MiladyMakerDAO | cut -d' ' -f2)"
|
||||||
$DRK dao vote MiladyMakerDAO "$PROPOSAL_ID" 1 20 > /tmp/dao-vote.tx
|
$DRK dao vote "$PROPOSAL" 1 > /tmp/dao-vote.tx
|
||||||
$DRK broadcast < /tmp/dao-vote.tx
|
$DRK broadcast < /tmp/dao-vote.tx
|
||||||
}
|
}
|
||||||
|
|
||||||
vote_status() {
|
|
||||||
PROPOSAL_ID=1
|
|
||||||
$DRK dao proposal MiladyMakerDAO "$PROPOSAL_ID" | grep -q yes
|
|
||||||
echo $?
|
|
||||||
}
|
|
||||||
|
|
||||||
wait_vote() {
|
wait_vote() {
|
||||||
while [ "$(vote_status)" != 0 ]; do
|
PROPOSAL="$($DRK dao proposals MiladyMakerDAO | cut -d' ' -f2)"
|
||||||
|
while [ "$($DRK dao proposal $PROPOSAL | grep '^Current proposal outcome: ' | awk '{print $4}')" != "Approved" ]; do
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
do_exec() {
|
do_exec() {
|
||||||
PROPOSAL_ID=1
|
PROPOSAL="$($DRK dao proposals MiladyMakerDAO | cut -d' ' -f2)"
|
||||||
$DRK dao exec MiladyMakerDAO "$PROPOSAL_ID" > /tmp/dao-exec.tx
|
$DRK dao exec --early $PROPOSAL > /tmp/dao-exec.tx
|
||||||
$DRK broadcast < /tmp/dao-exec.tx
|
$DRK broadcast < /tmp/dao-exec.tx
|
||||||
}
|
}
|
||||||
|
|
||||||
$DRK wallet --keygen
|
wait_exec() {
|
||||||
|
PROPOSAL="$($DRK dao proposals MiladyMakerDAO | cut -d' ' -f2)"
|
||||||
|
while [ "$($DRK dao proposal $PROPOSAL | grep '^Proposal was executed on transaction: ' | awk '{print $6}')" = None ]; do
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
mint_tokens
|
mint_tokens
|
||||||
wait_tokens
|
wait_tokens
|
||||||
mint_dao
|
mint_dao
|
||||||
@@ -164,3 +160,4 @@ wait_proposal
|
|||||||
vote
|
vote
|
||||||
wait_vote
|
wait_vote
|
||||||
do_exec
|
do_exec
|
||||||
|
wait_exec
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ set -e
|
|||||||
set -x
|
set -x
|
||||||
|
|
||||||
# Path to `drk` binary
|
# Path to `drk` binary
|
||||||
DRK="../../../drk -vv -c drk.toml"
|
DRK="../../../drk -c drk.toml"
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
if $DRK ping 2> /dev/null; then
|
if $DRK ping 2> /dev/null; then
|
||||||
|
|||||||
@@ -14,49 +14,70 @@ these bullas.
|
|||||||
|
|
||||||
## `DAO::mint()`: Establishing the DAO
|
## `DAO::mint()`: Establishing the DAO
|
||||||
|
|
||||||
From `darkfi/src/contract/dao/proof/dao-mint.zk`:
|
From `darkfi/src/contract/dao/proof/mint.zk`:
|
||||||
```zkas
|
```zkas
|
||||||
bulla = poseidon_hash(
|
bulla = poseidon_hash(
|
||||||
dao_proposer_limit,
|
proposer_limit,
|
||||||
dao_quorum,
|
quorum,
|
||||||
dao_approval_ratio_quot,
|
early_exec_quorum,
|
||||||
dao_approval_ratio_base,
|
approval_ratio_quot,
|
||||||
|
approval_ratio_base,
|
||||||
gov_token_id,
|
gov_token_id,
|
||||||
dao_public_x,
|
notes_public_x,
|
||||||
dao_public_y,
|
notes_public_y,
|
||||||
dao_bulla_blind,
|
proposer_public_x,
|
||||||
);
|
proposer_public_y,
|
||||||
|
proposals_public_x,
|
||||||
|
proposals_public_y,
|
||||||
|
votes_public_x,
|
||||||
|
votes_public_y,
|
||||||
|
exec_public_x,
|
||||||
|
exec_public_y,
|
||||||
|
early_exec_public_x,
|
||||||
|
early_exec_public_y,
|
||||||
|
bulla_blind,
|
||||||
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
Brief description of the DAO bulla params:
|
Brief description of the DAO bulla params:
|
||||||
|
|
||||||
* **proposer_limit**: minimum deposit required for proposals to become valid.
|
* **proposer_limit**: the minimum amount of governance tokens needed to open a proposal.
|
||||||
TODO: rename to `min_deposit`.
|
* **quorum**: minimal threshold of participating total tokens needed for a proposal to pass.
|
||||||
* **quorum**: minimum threshold of votes before it's allowed to pass.
|
|
||||||
Normally this is implemented as min % of voting power, but we do this in
|
Normally this is implemented as min % of voting power, but we do this in
|
||||||
absolute value
|
absolute value
|
||||||
* **approval_ratio**: proportion of winners to losers for a proposal to pass.
|
* **early_exec_quorum**: minimal threshold of participating total tokens needed for a proposal
|
||||||
|
to be considered as strongly supported, enabling early execution. Must be greater or equal
|
||||||
|
to normal quorum.
|
||||||
|
* **approval_ratio**: the ratio of winning/total votes needed for a proposal to pass.
|
||||||
|
* **gov_token_id**: DAO's governance token ID.
|
||||||
|
* **notes_public_key**: notes(coins) decryption public key
|
||||||
|
* **proposer_public_key**: proposals creator public key
|
||||||
|
* **proposals_public_key**: proposals viewer public key
|
||||||
|
* **votes_public_key**: votes viewer public key
|
||||||
|
* **exec_public_key**: proposals executor public key
|
||||||
|
* **early_exec_public_key**: strongly supported proposals executor public key
|
||||||
|
* **bulla_blind**: bulla blind
|
||||||
|
|
||||||
Currently there is no notion of veto although it could be trivially added
|
DAO creators/founders have full control on how they want to configure and share
|
||||||
if desired.
|
the actions keys, giving them the ability to veto if needed.
|
||||||
|
|
||||||
## `DAO::propose()`: Propose the Vote
|
## `DAO::propose()`: Propose the Vote
|
||||||
|
|
||||||
From `darkfi/src/contract/dao/proof/dao-propose-main.zk`:
|
From `darkfi/src/contract/dao/proof/propose-main.zk`:
|
||||||
```zkas
|
```zkas
|
||||||
proposal_bulla = poseidon_hash(
|
proposal_bulla = poseidon_hash(
|
||||||
proposal_dest_x,
|
proposal_auth_calls_commit,
|
||||||
proposal_dest_y,
|
proposal_creation_blockwindow,
|
||||||
proposal_amount,
|
proposal_duration_blockwindows,
|
||||||
proposal_token_id,
|
proposal_user_data,
|
||||||
dao_bulla,
|
dao_bulla,
|
||||||
proposal_blind,
|
proposal_blind,
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
We create a proposal which will send tokens to the dest provided.
|
Proposals are committed to a specific calls set, therefore they
|
||||||
This will soon be changed to be generic. Proposals will commit to
|
are generic and we can attach various calls to it. We will use a
|
||||||
calling params or code instead.
|
money transfer as the example for rest sections.
|
||||||
|
|
||||||
## `DAO::vote()`: Vote on a Proposal
|
## `DAO::vote()`: Vote on a Proposal
|
||||||
|
|
||||||
@@ -366,37 +387,52 @@ be executed early. We should add this option to DarkFi DAO params.
|
|||||||
|
|
||||||
## Suggested Changes
|
## Suggested Changes
|
||||||
|
|
||||||
DAO params:
|
~~DAO params:~~
|
||||||
|
|
||||||
* Voting period (currently called duration) should be moved from proposals to
|
* ~~Voting period (currently called duration) should be moved from proposals to
|
||||||
DAO params.
|
DAO params.~~
|
||||||
* upgrayedd: we should just have minimum allowed period in the DAO, but keep
|
* ~~upgrayedd: we should just have minimum allowed period in the DAO, but keep
|
||||||
this param in the proposal.
|
this param in the proposal.~~
|
||||||
* Window (currently set at 4 hours of blocks) should be customizable. We need a
|
* ~~Window (currently set at 4 hours of blocks) should be customizable. We need a
|
||||||
terminology for the unit of time. Maybe `time_units`.
|
terminology for the unit of time. Maybe `time_units`.~~
|
||||||
* This should be switched from block index to using timestamps.
|
* ~~This should be switched from block index to using timestamps.
|
||||||
See the quoted paragraph in the OpenZeppelin section above for the
|
See the quoted paragraph in the OpenZeppelin section above for the
|
||||||
reasoning.
|
reasoning.~~
|
||||||
* upgrayedd: stick with block index.
|
* ~~upgrayedd: stick with block index.~~
|
||||||
* Early execution bool flag. If true, then passed proposals can be `exec()`uted
|
* ~~Early execution bool flag. If true, then passed proposals can be `exec()`uted
|
||||||
asap, otherwise the entire voting period must pass.
|
asap, otherwise the entire voting period must pass.~~
|
||||||
|
|
||||||
No changes to proposals, except moving duration to DAO params.
|
~~No changes to proposals, except moving duration to DAO params.~~
|
||||||
|
|
||||||
Currently the DAO public key is used for:
|
> Resolution:
|
||||||
|
> The full voting period must pass in order to be able to execute a proposal.
|
||||||
|
> A new configuration parameter was introduced, called early exec quorum,
|
||||||
|
> where we can define the quorum for a proposal to be considered as strongly
|
||||||
|
> supported/voted on, which should always be greater or equal to normal quorum.
|
||||||
|
> With this addition, we can execute proposals before the voting period has
|
||||||
|
> passed, if they were accepted.
|
||||||
|
|
||||||
* Encrypting votes.
|
~~Currently the DAO public key is used for:~~
|
||||||
* Calling exec.
|
|
||||||
|
|
||||||
We should introduce a new key:
|
* ~~Encrypting votes.~~
|
||||||
|
* ~~Calling exec.~~
|
||||||
|
|
||||||
* Proposer role, which is needed to make proposals. This can be shared openly
|
~~We should introduce a new key:~~
|
||||||
|
|
||||||
|
* ~~Proposer role, which is needed to make proposals. This can be shared openly
|
||||||
amongst DAO members if they wish to remove the restriction on who can make
|
amongst DAO members if they wish to remove the restriction on who can make
|
||||||
proposals.
|
proposals.~~
|
||||||
* OZ does this with a canceller role that has the ability to cancel
|
* ~~OZ does this with a canceller role that has the ability to cancel
|
||||||
proposals.
|
proposals.~~
|
||||||
* In the future allow multiple keys for this so you can see who makes
|
* ~~In the future allow multiple keys for this so you can see who makes
|
||||||
proposals.
|
proposals.~~
|
||||||
|
|
||||||
|
> Resolution:
|
||||||
|
> DAO public key was split into six other keys, providing maximum control over
|
||||||
|
> each DAO action. Now the DAO creator can define who can view the coin notes,
|
||||||
|
> create proposals, view proposals, view votes, execute proposals and early
|
||||||
|
> execute proposals. They can configure the keys however they like like reusing
|
||||||
|
> keys if they want some actions to have same key.
|
||||||
|
|
||||||
Optional: many DAOs these days implement Abstain, which increases the quorum
|
Optional: many DAOs these days implement Abstain, which increases the quorum
|
||||||
without voting yes. This is for when you want to weak support a measure,
|
without voting yes. This is for when you want to weak support a measure,
|
||||||
|
|||||||
@@ -7,12 +7,16 @@ The governance process is divided in a few steps that are outlined below:
|
|||||||
* **Exec:** if the proposal passes within the time limit then the proposal is
|
* **Exec:** if the proposal passes within the time limit then the proposal is
|
||||||
executed.
|
executed.
|
||||||
|
|
||||||
|
> Note:
|
||||||
|
> There is a special case where a proposal can be executed before voting period
|
||||||
|
> passes, if its strongly supported, based on the configured early execution quorum.
|
||||||
|
|
||||||
## Propose
|
## Propose
|
||||||
|
|
||||||
To prevent spam, proposals must be submitted by holders with a certain number
|
To prevent spam, proposals must be submitted by holders with a certain number
|
||||||
of governance tokens. Several members of the DAO can add inputs separately to
|
of governance tokens and the DAO proposers key. Several members of the DAO can
|
||||||
a proposal before it is posted on chain so that their combined inputs meet the
|
add inputs separately to a proposal before it is posted on chain so that their
|
||||||
proposal governance token limit.
|
combined inputs meet the proposal governance token limit.
|
||||||
|
|
||||||
Once proposals are posted on chain, they are immediately active.
|
Once proposals are posted on chain, they are immediately active.
|
||||||
|
|
||||||
@@ -46,8 +50,14 @@ no longer vote on the proposal, and it is considered *expired*.
|
|||||||
|
|
||||||
### Quorum
|
### Quorum
|
||||||
|
|
||||||
Quorum is defined as the minimum absolute number of governance tokens voting
|
Quorum is defined as the minimal threshold of participating total governance tokens need for
|
||||||
yes required for a proposal to become accepted.
|
a proposal to pass. Normally this is implemented as min % of voting power, but we do this in
|
||||||
|
absolute value.
|
||||||
|
|
||||||
|
### Early Execution Quorum
|
||||||
|
Early execytuib quorum is defined as the minimal threshold of participating total tokens needed
|
||||||
|
for a proposal to be considered as strongly supported, enabling early execution. Must be greater
|
||||||
|
or equal to normal quorum.
|
||||||
|
|
||||||
### Approval Ratio
|
### Approval Ratio
|
||||||
|
|
||||||
|
|||||||
@@ -13,20 +13,31 @@ The DAO contains the main parameters that define DAO operation:
|
|||||||
come from multiple token holders.
|
come from multiple token holders.
|
||||||
* Quorum $Q$ specifies the absolute minimum number of tokens required for
|
* Quorum $Q$ specifies the absolute minimum number of tokens required for
|
||||||
before a proposal can be accepted.
|
before a proposal can be accepted.
|
||||||
|
* Early exec quorum $EEQ$ specifies the absolute minimum number of tokens
|
||||||
|
required for before a proposal can be considered as strongly accepted.
|
||||||
* The approval ratio $A^\%$ is a tuple that specifies the minimum theshold
|
* The approval ratio $A^\%$ is a tuple that specifies the minimum theshold
|
||||||
of affirmative yes votes for a proposal to become accepted.
|
of affirmative yes votes for a proposal to become accepted.
|
||||||
* The public key $PK$ serves a dual role for both encrypted notes, and as
|
* Notes public key $NPK$ controls who can view encrypted notes.
|
||||||
a key to authorize accepted proposals to be executed.
|
* Proposer public key $pPK$ controls who can mint proposals.
|
||||||
This key may be shared widely with all DAO members or within a privileged
|
* Proposals public key $PPK$ controls who can view the proposals.
|
||||||
group.
|
* Votes public key $VPK$ controls who can view votes.
|
||||||
|
* Executor public key $EPK$ controls who can execute proposals.
|
||||||
|
* Early executor public key $EEPK$ controls who can execute proposals that
|
||||||
|
are strongly accepted.
|
||||||
|
|
||||||
Define the DAO params
|
Define the DAO params
|
||||||
$$ \begin{aligned}
|
$$ \begin{aligned}
|
||||||
\t{Params}_\t{DAO}.L &∈ ℕ₆₄ \\
|
\t{Params}_\t{DAO}.L &∈ ℕ₆₄ \\
|
||||||
\t{Params}_\t{DAO}.Q &∈ ℕ₆₄ \\
|
\t{Params}_\t{DAO}.Q &∈ ℕ₆₄ \\
|
||||||
|
\t{Params}_\t{DAO}.EEQ &∈ ℕ₆₄ \\
|
||||||
\t{Params}_\t{DAO}.A^\% &∈ ℕ₆₄ × ℕ₆₄ \\
|
\t{Params}_\t{DAO}.A^\% &∈ ℕ₆₄ × ℕ₆₄ \\
|
||||||
\t{Params}_\t{DAO}.τ &∈ 𝔽ₚ \\
|
\t{Params}_\t{DAO}.τ &∈ 𝔽ₚ \\
|
||||||
\t{Params}_\t{DAO}.\t{PK} &∈ ℙₚ
|
\t{Params}_\t{DAO}.\t{NPK} &∈ ℙₚ \\
|
||||||
|
\t{Params}_\t{DAO}.\t{pPK} &∈ ℙₚ \\
|
||||||
|
\t{Params}_\t{DAO}.\t{PPK} &∈ ℙₚ \\
|
||||||
|
\t{Params}_\t{DAO}.\t{VPK} &∈ ℙₚ \\
|
||||||
|
\t{Params}_\t{DAO}.\t{EPK} &∈ ℙₚ \\
|
||||||
|
\t{Params}_\t{DAO}.\t{EEPK} &∈ ℙₚ
|
||||||
\end{aligned} $$
|
\end{aligned} $$
|
||||||
where the approval ratio $\t{Approval}^\% = (q, d)$ defines the equivalence
|
where the approval ratio $\t{Approval}^\% = (q, d)$ defines the equivalence
|
||||||
class $[\frac{q}{d}]$ of fractions defined by $q₁d₂ = q₂d₁ ⟺ [\frac{q₁}{d₁}] \~ [\frac{q₂}{d₂}]$.
|
class $[\frac{q}{d}]$ of fractions defined by $q₁d₂ = q₂d₁ ⟺ [\frac{q₁}{d₁}] \~ [\frac{q₂}{d₂}]$.
|
||||||
@@ -36,7 +47,22 @@ class $[\frac{q}{d}]$ of fractions defined by $q₁d₂ = q₂d₁ ⟺ [\frac{q
|
|||||||
```
|
```
|
||||||
|
|
||||||
$$ \t{Bulla}_\t{DAO} : \t{Params}_\t{DAO} × 𝔽ₚ → 𝔽ₚ $$
|
$$ \t{Bulla}_\t{DAO} : \t{Params}_\t{DAO} × 𝔽ₚ → 𝔽ₚ $$
|
||||||
$$ \t{Bulla}_\t{DAO}(p, b_\t{DAO}) = \t{Bulla}(ℕ₆₄2𝔽ₚ(p.L), ℕ₆₄2𝔽ₚ(p.Q), ℕ₆₄2𝔽ₚ(p.A^\%), p.τ, \mathcal{X}(p.\t{PK}), \mathcal{Y}(p.\t{PK}), b_\t{DAO}) $$
|
$$ \begin{aligned}
|
||||||
|
\t{Bulla}_\t{DAO}(p, b_\t{DAO}) = \t{Bulla}( \\
|
||||||
|
ℕ₆₄2𝔽ₚ(p.L), \\
|
||||||
|
ℕ₆₄2𝔽ₚ(p.Q), \\
|
||||||
|
ℕ₆₄2𝔽ₚ(p.EEQ), \\
|
||||||
|
ℕ₆₄2𝔽ₚ(p.A^\%), \\
|
||||||
|
p.τ, \\
|
||||||
|
\mathcal{X}(p.\t{NPK}), \mathcal{Y}(p.\t{NPK}), \\
|
||||||
|
\mathcal{X}(p.\t{pPK}), \mathcal{Y}(p.\t{pPK}), \\
|
||||||
|
\mathcal{X}(p.\t{PPK}), \mathcal{Y}(p.\t{PPK}), \\
|
||||||
|
\mathcal{X}(p.\t{VPK}), \mathcal{Y}(p.\t{VPK}), \\
|
||||||
|
\mathcal{X}(p.\t{EPK}), \mathcal{Y}(p.\t{EPK}), \\
|
||||||
|
\mathcal{X}(p.\t{EEPK}), \mathcal{Y}(p.\t{EEPK}), \\
|
||||||
|
b_\t{DAO} \\
|
||||||
|
)
|
||||||
|
\end{aligned} $$
|
||||||
|
|
||||||
## Proposals
|
## Proposals
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ the DAO params and then add the bulla to the set.
|
|||||||
|
|
||||||
* Wallet builder: `src/contract/dao/src/client/mint.rs`
|
* Wallet builder: `src/contract/dao/src/client/mint.rs`
|
||||||
* WASM VM code: `src/contract/dao/src/entrypoint/mint.rs`
|
* WASM VM code: `src/contract/dao/src/entrypoint/mint.rs`
|
||||||
* ZK proof: `src/contract/dao/proof/dao-mint.zk`
|
* ZK proof: `src/contract/dao/proof/mint.zk`
|
||||||
|
|
||||||
### Function Params
|
### Function Params
|
||||||
|
|
||||||
@@ -45,22 +45,41 @@ Let there be a prover auxiliary witness inputs:
|
|||||||
$$ \begin{aligned}
|
$$ \begin{aligned}
|
||||||
L &∈ ℕ₆₄ \\
|
L &∈ ℕ₆₄ \\
|
||||||
Q &∈ ℕ₆₄ \\
|
Q &∈ ℕ₆₄ \\
|
||||||
|
EEQ &∈ ℕ₆₄ \\
|
||||||
A^\% &∈ ℕ₆₄ × ℕ₆₄ \\
|
A^\% &∈ ℕ₆₄ × ℕ₆₄ \\
|
||||||
τ &∈ 𝔽ₚ \\
|
τ &∈ 𝔽ₚ \\
|
||||||
x &∈ 𝔽ₚ \\
|
Nx &∈ 𝔽ₚ \\
|
||||||
|
px &∈ 𝔽ₚ \\
|
||||||
|
Px &∈ 𝔽ₚ \\
|
||||||
|
Vx &∈ 𝔽ₚ \\
|
||||||
|
Ex &∈ 𝔽ₚ \\
|
||||||
|
EEx &∈ 𝔽ₚ \\
|
||||||
b_\t{DAO} &∈ 𝔽ₚ
|
b_\t{DAO} &∈ 𝔽ₚ
|
||||||
\end{aligned} $$
|
\end{aligned} $$
|
||||||
|
|
||||||
Attach a proof $π$ such that the following relations hold:
|
Attach a proof $π$ such that the following relations hold:
|
||||||
|
|
||||||
**Proof of public key ownership**   $\t{PK} = \t{DerivePubKey}(x)$.
|
**Proof of notes public key ownership**   $\t{NPK} = \t{DerivePubKey}(Nx)$.
|
||||||
|
|
||||||
**DAO bulla integrity**   $ℬ = \t{Bulla}_\t{DAO}((L, Q, A^\%, τ, \t{PK}), b_\t{DAO})$
|
**Proof of proposer public key ownership**   $\t{pPK} = \t{DerivePubKey}(px)$.
|
||||||
|
|
||||||
|
**Proof of proposals public key ownership**   $\t{PPK} = \t{DerivePubKey}(Px)$.
|
||||||
|
|
||||||
|
**Proof of votes public key ownership**   $\t{VPK} = \t{DerivePubKey}(Vx)$.
|
||||||
|
|
||||||
|
**Proof of executor public key ownership**   $\t{EPK} = \t{DerivePubKey}(Ex)$.
|
||||||
|
|
||||||
|
**Proof of early executor public key ownership**   $\t{EEPK} = \t{DerivePubKey}(EEx)$.
|
||||||
|
|
||||||
|
**Proof that early execution quorum is greater than normal quorum**   $Q <= EEQ1$.
|
||||||
|
|
||||||
|
**DAO bulla integrity**   $ℬ = \t{Bulla}_\t{DAO}((L, Q, EEQ, A^\%, τ,
|
||||||
|
\t{NPK}, \t{pPK}, \t{PPK}, \t{VPK}, \t{EPK}, \t{EEPK}), b_\t{DAO})$
|
||||||
|
|
||||||
### Signatures
|
### Signatures
|
||||||
|
|
||||||
There should be a single signature attached, which uses
|
There should be a single signature attached, which uses
|
||||||
$\t{PK}$ as the signature public key.
|
$\t{NPK}$ as the signature public key.
|
||||||
|
|
||||||
## Propose
|
## Propose
|
||||||
|
|
||||||
@@ -89,8 +108,8 @@ A proposal contains a list of auth calls as specified in [Auth Calls](model.md#a
|
|||||||
* Wallet builder: `src/contract/dao/src/client/propose.rs`
|
* Wallet builder: `src/contract/dao/src/client/propose.rs`
|
||||||
* WASM VM code: `src/contract/dao/src/entrypoint/propose.rs`
|
* WASM VM code: `src/contract/dao/src/entrypoint/propose.rs`
|
||||||
* ZK proofs:
|
* ZK proofs:
|
||||||
* `src/contract/dao/proof/dao-propose-main.zk`
|
* `src/contract/dao/proof/propose-main.zk`
|
||||||
* `src/contract/dao/proof/dao-propose-input.zk`
|
* `src/contract/dao/proof/propose-input.zk`
|
||||||
|
|
||||||
### Function Params
|
### Function Params
|
||||||
|
|
||||||
@@ -146,6 +165,8 @@ Attach a proof $π_𝒫 $ such that the following relations hold:
|
|||||||
**Governance token commit**   export the DAO token ID as an encrypted pedersen
|
**Governance token commit**   export the DAO token ID as an encrypted pedersen
|
||||||
commit $T = \t{PedersenCommit}(d.τ, b_τ)$ where $T = ∑_{i ∈ 𝐢} Tᵢ$.
|
commit $T = \t{PedersenCommit}(d.τ, b_τ)$ where $T = ∑_{i ∈ 𝐢} Tᵢ$.
|
||||||
|
|
||||||
|
**Proof of proposer public key ownership**   $\t{pPK} = \t{DerivePubKey}(px)$.
|
||||||
|
|
||||||
**DAO bulla integrity**   $𝒟 = \t{Bulla}_\t{DAO}(d, b_d)$
|
**DAO bulla integrity**   $𝒟 = \t{Bulla}_\t{DAO}(d, b_d)$
|
||||||
|
|
||||||
**DAO existence**   $R_\t{DAO} = \t{MerkleRoot}(ψ, Π, 𝒟 )$
|
**DAO existence**   $R_\t{DAO} = \t{MerkleRoot}(ψ, Π, 𝒟 )$
|
||||||
@@ -200,8 +221,8 @@ public key $i.\t{PK}_σ$.
|
|||||||
After `DAO::propose()` is called, DAO members can then call this contract
|
After `DAO::propose()` is called, DAO members can then call this contract
|
||||||
function. Using a similar method as before, they attach inputs proving ownership
|
function. Using a similar method as before, they attach inputs proving ownership
|
||||||
of a certain value of governance tokens. This is how we achieve token weighted
|
of a certain value of governance tokens. This is how we achieve token weighted
|
||||||
voting. The result of the vote is communicated to other DAO members through the
|
voting. The result of the vote is communicated to DAO members that can view votes
|
||||||
encrypted note $\t{note}$.
|
through the encrypted note $\t{note}$.
|
||||||
|
|
||||||
Each nullifier $𝒩 $ is stored uniquely per proposal. Additionally as before,
|
Each nullifier $𝒩 $ is stored uniquely per proposal. Additionally as before,
|
||||||
there is a leakage here connecting the coins when spent. However prodigious
|
there is a leakage here connecting the coins when spent. However prodigious
|
||||||
@@ -220,8 +241,8 @@ and the yes votes by $V_\t{yes}$.
|
|||||||
* Wallet builder: `src/contract/dao/src/client/vote.rs`
|
* Wallet builder: `src/contract/dao/src/client/vote.rs`
|
||||||
* WASM VM code: `src/contract/dao/src/entrypoint/vote.rs`
|
* WASM VM code: `src/contract/dao/src/entrypoint/vote.rs`
|
||||||
* ZK proofs:
|
* ZK proofs:
|
||||||
* `src/contract/dao/proof/dao-vote-main.zk`
|
* `src/contract/dao/proof/vote-main.zk`
|
||||||
* `src/contract/dao/proof/dao-vote-input.zk`
|
* `src/contract/dao/proof/vote-input.zk`
|
||||||
|
|
||||||
### Function Params
|
### Function Params
|
||||||
|
|
||||||
@@ -247,8 +268,9 @@ selected such that their sum is a valid field element in $𝔽ₚ$ so the blind
|
|||||||
for $∑ V$ can be verifiably encrypted. Likewise we do the same for the blind
|
for $∑ V$ can be verifiably encrypted. Likewise we do the same for the blind
|
||||||
used to calculate $V_\t{yes}$.
|
used to calculate $V_\t{yes}$.
|
||||||
|
|
||||||
This allows DAO members to securely receive all secrets for votes on a proposal.
|
This allows DAO members that hold the votes key to securely receive all secrets
|
||||||
This is then used in the Exec phase when we work on the sum of DAO votes.
|
for votes on a proposal. This is then used in the Exec phase when we work on the
|
||||||
|
sum of DAO votes.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
{{#include ../../../../../src/contract/dao/src/model.rs:dao-vote-params}}
|
{{#include ../../../../../src/contract/dao/src/model.rs:dao-vote-params}}
|
||||||
@@ -300,7 +322,7 @@ and then check $t_\t{now} < t_\t{end}$.
|
|||||||
|
|
||||||
**Verifiable encryption of vote commit secrets**  
|
**Verifiable encryption of vote commit secrets**  
|
||||||
let $𝐧 = (o, b_y, v, bᵥ)$, and verify
|
let $𝐧 = (o, b_y, v, bᵥ)$, and verify
|
||||||
$\t{enc\_vote} = \t{ElGamal}.\t{Encrypt}(𝐧, \t{esk}, d.\t{PK})$.
|
$\t{enc\_vote} = \t{ElGamal}.\t{Encrypt}(𝐧, \t{esk}, d.\t{VPK})$.
|
||||||
|
|
||||||
For each input $i ∈ 𝐢$, perform the following checks:
|
For each input $i ∈ 𝐢$, perform the following checks:
|
||||||
|
|
||||||
@@ -343,8 +365,8 @@ public key $i.\t{PK}_σ$.
|
|||||||
|
|
||||||
Exec is the final stage after voting is [Accepted](concepts.md#proposal-states).
|
Exec is the final stage after voting is [Accepted](concepts.md#proposal-states).
|
||||||
|
|
||||||
It checks the correct voting conditions have been met in accordance with the
|
It checks that voting has passed, and correct conditions have been met, in accordance
|
||||||
[DAO params](model.md#dao) such as quorum and approval ratio.
|
with the [DAO params](model.md#dao) such as quorum and approval ratio.
|
||||||
$V_\t{yes}$ and $V_\t{all}$ are pedersen commits to $v_\t{yes}$ and $v_\t{all}$ respectively.
|
$V_\t{yes}$ and $V_\t{all}$ are pedersen commits to $v_\t{yes}$ and $v_\t{all}$ respectively.
|
||||||
|
|
||||||
It also checks that child calls have been attached in accordance with the auth
|
It also checks that child calls have been attached in accordance with the auth
|
||||||
@@ -354,7 +376,9 @@ function. Currently the DAO provides a single preset for executing
|
|||||||
|
|
||||||
* Wallet builder: `src/contract/dao/src/client/exec.rs`
|
* Wallet builder: `src/contract/dao/src/client/exec.rs`
|
||||||
* WASM VM code: `src/contract/dao/src/entrypoint/exec.rs`
|
* WASM VM code: `src/contract/dao/src/entrypoint/exec.rs`
|
||||||
* ZK proof: `src/contract/dao/proof/dao-exec.zk`
|
* ZK proofs:
|
||||||
|
* `src/contract/dao/proof/exec.zk`
|
||||||
|
* `src/contract/dao/proof/early-exec.zk`
|
||||||
|
|
||||||
### Function Params
|
### Function Params
|
||||||
|
|
||||||
@@ -402,11 +426,16 @@ $$ \begin{aligned}
|
|||||||
\end{aligned} $$
|
\end{aligned} $$
|
||||||
Attach a proof $π$ such that the following relations hold:
|
Attach a proof $π$ such that the following relations hold:
|
||||||
|
|
||||||
|
**Proof of executor public key ownership**   $\t{EPK} = \t{DerivePubKey}(Ex)$.
|
||||||
|
|
||||||
**DAO bulla integrity**   $𝒟 = \t{Bulla}_\t{DAO}(d, b_d)$
|
**DAO bulla integrity**   $𝒟 = \t{Bulla}_\t{DAO}(d, b_d)$
|
||||||
|
|
||||||
**Proposal bulla integrity**   $𝒫 = \t{Bulla}_\t{Proposal}(p, b_p)$
|
**Proposal bulla integrity**   $𝒫 = \t{Bulla}_\t{Proposal}(p, b_p)$
|
||||||
where $p.𝒜 = 𝒜 $.
|
where $p.𝒜 = 𝒜 $.
|
||||||
|
|
||||||
|
**Proposal has expired**   let $t_\t{end} = ℕ₆₄2𝔽ₚ(p.t₀) + ℕ₆₄2𝔽ₚ(p.D)$,
|
||||||
|
and then check $t_\t{end} <= t_\t{now}$.
|
||||||
|
|
||||||
**Yes vote commit**   $V_\t{yes} = \t{PedersenCommit}(v_y, b_y)$
|
**Yes vote commit**   $V_\t{yes} = \t{PedersenCommit}(v_y, b_y)$
|
||||||
|
|
||||||
**All vote commit**   $V_\t{all} = \t{PedersenCommit}(v_a, b_a)$
|
**All vote commit**   $V_\t{all} = \t{PedersenCommit}(v_a, b_a)$
|
||||||
@@ -417,6 +446,46 @@ where $p.𝒜 = 𝒜 $.
|
|||||||
$\frac{A^\%_q}{A^\%_b} ≤ \frac{v_y}{v_a}$. Instead we perform the
|
$\frac{A^\%_q}{A^\%_b} ≤ \frac{v_y}{v_a}$. Instead we perform the
|
||||||
equivalent check that $v_a A^\%_q ≤ v_y A^\%_b$.
|
equivalent check that $v_a A^\%_q ≤ v_y A^\%_b$.
|
||||||
|
|
||||||
|
### EarlyExec
|
||||||
|
|
||||||
|
This is a special case of Exec for when we want to execute a strongly accepted proposal
|
||||||
|
before voting period has passed. A different proof statement is used in this case.
|
||||||
|
|
||||||
|
Let there be prover auxiliary witness inputs:
|
||||||
|
$$ \begin{aligned}
|
||||||
|
p &∈ \t{Params}_\t{Proposal} \\
|
||||||
|
b_p &∈ 𝔽ₚ \\
|
||||||
|
d &∈ \t{Params}_\t{DAO} \\
|
||||||
|
b_d &∈ 𝔽ₚ \\
|
||||||
|
v_y &∈ 𝔽ₚ \\
|
||||||
|
v_a &∈ 𝔽ₚ \\
|
||||||
|
b_y &∈ 𝔽ᵥ \\
|
||||||
|
b_a &∈ 𝔽ᵥ \\
|
||||||
|
\end{aligned} $$
|
||||||
|
Attach a proof $π$ such that the following relations hold:
|
||||||
|
|
||||||
|
**Proof of executor public key ownership**   $\t{EPK} = \t{DerivePubKey}(Ex)$.
|
||||||
|
|
||||||
|
**Proof of early executor public key ownership**   $\t{EEPK} = \t{DerivePubKey}(EEx)$.
|
||||||
|
|
||||||
|
**DAO bulla integrity**   $𝒟 = \t{Bulla}_\t{DAO}(d, b_d)$
|
||||||
|
|
||||||
|
**Proposal bulla integrity**   $𝒫 = \t{Bulla}_\t{Proposal}(p, b_p)$
|
||||||
|
where $p.𝒜 = 𝒜 $.
|
||||||
|
|
||||||
|
**Proposal has not expired**   let $t_\t{end} = ℕ₆₄2𝔽ₚ(p.t₀) + ℕ₆₄2𝔽ₚ(p.D)$,
|
||||||
|
and then check $t_\t{now} < t_\t{end}$.
|
||||||
|
|
||||||
|
**Yes vote commit**   $V_\t{yes} = \t{PedersenCommit}(v_y, b_y)$
|
||||||
|
|
||||||
|
**All vote commit**   $V_\t{all} = \t{PedersenCommit}(v_a, b_a)$
|
||||||
|
|
||||||
|
**All votes pass early execution quorum**   $EEQ ≤ v_a$
|
||||||
|
|
||||||
|
**Approval ratio satisfied**   we wish to check that
|
||||||
|
$\frac{A^\%_q}{A^\%_b} ≤ \frac{v_y}{v_a}$. Instead we perform the
|
||||||
|
equivalent check that $v_a A^\%_q ≤ v_y A^\%_b$.
|
||||||
|
|
||||||
### Signatures
|
### Signatures
|
||||||
|
|
||||||
No signatures are attached.
|
No signatures are attached.
|
||||||
@@ -437,8 +506,8 @@ DAO treasury but be unspendable.
|
|||||||
* Wallet builder: `src/contract/dao/src/client/auth_xfer.rs`
|
* Wallet builder: `src/contract/dao/src/client/auth_xfer.rs`
|
||||||
* WASM VM code: `src/contract/dao/src/entrypoint/auth_xfer.rs`
|
* WASM VM code: `src/contract/dao/src/entrypoint/auth_xfer.rs`
|
||||||
* ZK proofs:
|
* ZK proofs:
|
||||||
* `src/contract/dao/proof/dao-auth-money-transfer.zk`
|
* `src/contract/dao/proof/auth-money-transfer.zk`
|
||||||
* `src/contract/dao/proof/dao-auth-money-transfer-enc-coin.zk`
|
* `src/contract/dao/proof/auth-money-transfer-enc-coin.zk`
|
||||||
|
|
||||||
### Function Params
|
### Function Params
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ Let's create a DAO with the following parameters:
|
|||||||
|
|
||||||
* Proposer limit: `20`
|
* Proposer limit: `20`
|
||||||
* Quorum: `10`
|
* Quorum: `10`
|
||||||
|
* Early execution quorum: `10`
|
||||||
* Approval ratio: `0.67`
|
* Approval ratio: `0.67`
|
||||||
* Governance token: `MLDY`
|
* Governance token: `MLDY`
|
||||||
|
|
||||||
@@ -20,17 +21,21 @@ $ ./drk help dao create
|
|||||||
Let's create our DAO.
|
Let's create our DAO.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ ./drk dao create 20 10 0.67 MLDY > dao_mldy.dat
|
$ ./drk dao create 20 10 10 0.67 MLDY > dao_mldy.toml
|
||||||
$ ./drk dao view < dao_mldy.dat
|
$ ./drk dao view < dao_mldy.toml
|
||||||
```
|
```
|
||||||
|
|
||||||
Now this file can be shared amongst all dao members, so they
|
Since its a normal `toml` file, you may open it with you favourite
|
||||||
hold the generated DAO information and keys. The view command
|
editor, modify they keys configuration and/or keep different versions
|
||||||
will show us the parameters. If everything looks fine, we can
|
for different members. By default all keys are different, so its up
|
||||||
now import it into our wallet:
|
to the DAO founders to chose what configuration they are going to use.
|
||||||
|
After configuring the file(s) properly, it can be shared amonst the
|
||||||
|
dao members, so they hold the generated DAO information and keys.
|
||||||
|
The view command will show us the parameters. If everything looks fine,
|
||||||
|
we can now import it into our wallet:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ ./drk dao import MiladyMakerDAO < dao_mldy.dat
|
$ ./drk dao import MiladyMakerDAO < dao_mldy.toml
|
||||||
$ ./drk dao list
|
$ ./drk dao list
|
||||||
$ ./drk dao list MiladyMakerDAO
|
$ ./drk dao list MiladyMakerDAO
|
||||||
```
|
```
|
||||||
@@ -39,7 +44,8 @@ $ ./drk dao list MiladyMakerDAO
|
|||||||
|
|
||||||
If parameters are shown, this means the DAO was successfully imported
|
If parameters are shown, this means the DAO was successfully imported
|
||||||
into our wallet. We use the DAO name to reference it. Now we can create
|
into our wallet. We use the DAO name to reference it. Now we can create
|
||||||
a transaction that will mint the DAO on-chain, and broadcast it:
|
a transaction that will mint the DAO on-chain, if we hold all its keys,
|
||||||
|
and broadcast it:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ ./drk dao mint MiladyMakerDAO > dao_mldy_mint_tx
|
$ ./drk dao mint MiladyMakerDAO > dao_mldy_mint_tx
|
||||||
@@ -55,19 +61,19 @@ should see a leaf position and a transaction hash when running
|
|||||||
|
|
||||||
Let's send some tokens to the DAO's treasury so we're able to make
|
Let's send some tokens to the DAO's treasury so we're able to make
|
||||||
a proposal to send those somewhere. First, find the DAO bulla, the
|
a proposal to send those somewhere. First, find the DAO bulla, the
|
||||||
dao contract spend hook and the DAO public key a d then create a
|
dao contract spend hook and the DAO notes public key and then create
|
||||||
transfer transaction:
|
a transfer transaction:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ ./drk dao spend-hook
|
$ ./drk dao spend-hook
|
||||||
$ ./drk dao list MiladyMakerDAO
|
$ ./drk dao list MiladyMakerDAO
|
||||||
$ ./drk transfer 10 WCKD {DAO_PUBLIC_KEY} \
|
$ ./drk transfer 10 WCKD {DAO_NOTES_PUBLIC_KEY} \
|
||||||
{DAO_CONTRACT_SPEND_HOOK} {DAO_BULLA} > dao_mldy_transfer_tx
|
{DAO_CONTRACT_SPEND_HOOK} {DAO_BULLA} > dao_mldy_transfer_tx
|
||||||
$ ./drk broadcast < dao_mldy_transfer_tx
|
$ ./drk broadcast < dao_mldy_transfer_tx
|
||||||
```
|
```
|
||||||
|
|
||||||
Wait for it to confirm, and if subscribed, you should see the DAO
|
Wait for it to confirm, and if subscribed, you should see the DAO
|
||||||
receive the funds:
|
receive the funds, if you hold the DAO notes key:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ ./drk dao balance MiladyMakerDAO
|
$ ./drk dao balance MiladyMakerDAO
|
||||||
@@ -77,23 +83,24 @@ $ ./drk dao balance MiladyMakerDAO
|
|||||||
|
|
||||||
Now that the DAO has something in its treasury, we can generate a
|
Now that the DAO has something in its treasury, we can generate a
|
||||||
transfer proposal to send it somewhere, that will be up to vote
|
transfer proposal to send it somewhere, that will be up to vote
|
||||||
for 1 block period. Let's propose to send 5 of the 10 tokens to
|
for 1 block period, if we hold the DAO proposer key. Let's propose
|
||||||
our address (we can find that with `drk wallet --address`):
|
to send 5 of the 10 tokens to our address (we can find that with
|
||||||
|
`drk wallet --address`):
|
||||||
|
|
||||||
```
|
```
|
||||||
$ ./drk dao propose-transfer MiladyMakerDAO 1 5 WCKD {YOUR_ADDRESS}
|
$ ./drk dao propose-transfer MiladyMakerDAO 1 5 WCKD {YOUR_ADDRESS}
|
||||||
```
|
```
|
||||||
|
|
||||||
After command was executed, it will output the generated proposal
|
After command was executed, it will output the generated proposal
|
||||||
bulla, which we will use to full the proposal information:
|
bulla, which we will use to view the proposal full information:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ ./drk dao proposal {PROPOSAL_BULLA}
|
$ ./drk dao proposal {PROPOSAL_BULLA}
|
||||||
```
|
```
|
||||||
|
|
||||||
We can export this proposal, to share with rest DAO members.
|
We can export this proposal, to share with rest DAO members.
|
||||||
The exported file will be encrypted using the DAO keys, so only
|
The exported file will be encrypted using the DAO proposals view key,
|
||||||
its members can decrypt and import it.
|
so only its members can decrypt and import it.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ ./drk dao proposal {PROPOSAL_BULLA} --export > dao_mldy_transfer_proposal.dat
|
$ ./drk dao proposal {PROPOSAL_BULLA} --export > dao_mldy_transfer_proposal.dat
|
||||||
@@ -142,32 +149,74 @@ $ ./drk broadcast < dao_mldy_transfer_proposal_vote_tx
|
|||||||
```
|
```
|
||||||
|
|
||||||
Once confirmed and scanned, you should see votes information and
|
Once confirmed and scanned, you should see votes information and
|
||||||
current status when running `dao proposal {PROPOSAL_BULLA}`.
|
current status when running `dao proposal {PROPOSAL_BULLA}`,
|
||||||
|
assuming you hold the votes view key.
|
||||||
|
|
||||||
## Executing the proposal
|
## Executing the proposal
|
||||||
|
|
||||||
Once the block period has passed and enough votes have been cast that
|
Once the block period has passed(~4h) and enough votes have been cast that
|
||||||
meet the required minimum (quorum), and assuming the yes:no votes ratio
|
meet the required minimum (quorum), and assuming the yes:no votes ratio
|
||||||
ratio is bigger than the approval ratio, then we are ready to confirm
|
ratio is bigger than the approval ratio, then we are ready to confirm
|
||||||
the vote. Any DAO member can perform this action.
|
the vote. Only DAO members with the executor key can perform this action.
|
||||||
|
|
||||||
Since in our tutorial the `MLDY` governance tokens we used surpass the
|
|
||||||
quorum, we can execute the proposal right away:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
$ ./drk dao exec {PROPOSAL_BULLA} > dao_mldy_transfer_proposal_exec_tx
|
$ ./drk dao exec {PROPOSAL_BULLA} > dao_mldy_transfer_proposal_exec_tx
|
||||||
$ ./drk broadcast < dao_mldy_transfer_proposal_exec_tx
|
$ ./drk broadcast < dao_mldy_transfer_proposal_exec_tx
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Since in our tutorial the `MLDY` governance tokens we used surpass the
|
||||||
|
early execution quorum, we can execute the proposal right away, if we hold
|
||||||
|
both the DAO executor and early executor keys:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./drk dao exec --early {PROPOSAL_BULLA} > dao_mldy_transfer_proposal_exec_tx
|
||||||
|
$ ./drk broadcast < dao_mldy_transfer_proposal_exec_tx
|
||||||
|
```
|
||||||
|
|
||||||
After the proposal has been executed on chain, we will see that
|
After the proposal has been executed on chain, we will see that
|
||||||
the DAO balance has been reduced by 5 `WCKD`, while our own balance
|
the DAO balance has been reduced by 5 `WCKD`, if we hold the DAO notes key,
|
||||||
has been increased by the same amount:
|
while our own balance has been increased by the same amount:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ ./drk dao balance MiladyMakerDAO
|
$ ./drk dao balance MiladyMakerDAO
|
||||||
$ ./drk wallet --balance
|
$ ./drk wallet --balance
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Generic proposal
|
||||||
|
|
||||||
|
DAOs can vote on off-chain operations by creating what is known as generic
|
||||||
|
proposals, meaning that no on-chain action is tied to it:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./drk dao propose-generic MiladyMakerDAO 1
|
||||||
|
$ ./drk dao proposal {PROPOSAL_BULLA} --mint-proposal > dao_mldy_generic_proposal_mint_tx
|
||||||
|
$ ./drk broadcast < dao_mldy_generic_proposal_mint_tx
|
||||||
|
```
|
||||||
|
|
||||||
|
Vote on the proposal:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./drk dao vote {PROPOSAL_BULLA} 1 > dao_mldy_generic_proposal_vote_tx
|
||||||
|
$ ./drk broadcast < dao_mldy_generic_proposal_vote_tx
|
||||||
|
```
|
||||||
|
|
||||||
|
And execute it, after the vote period(1 block period) has passed:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./drk dao exec {PROPOSAL_BULLA} > dao_mldy_generic_proposal_exec_tx
|
||||||
|
$ ./drk broadcast < dao_mldy_generic_proposal_exec_tx
|
||||||
|
```
|
||||||
|
|
||||||
|
Or right away, since the early execution quorum has been reached:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./drk dao exec --early {PROPOSAL_BULLA} > dao_mldy_generic_proposal_exec_tx
|
||||||
|
$ ./drk broadcast < dao_mldy_generic_proposal_exec_tx
|
||||||
|
```
|
||||||
|
|
||||||
|
Executing the proposal will just confirm it on-chain, without any
|
||||||
|
other actions taken.
|
||||||
|
|
||||||
## DAO->DAO
|
## DAO->DAO
|
||||||
|
|
||||||
Let's now try some more exotic operations!
|
Let's now try some more exotic operations!
|
||||||
@@ -192,8 +241,8 @@ $ ./drk dao balance MiladyMakerDAO
|
|||||||
Now we will create a second dao:
|
Now we will create a second dao:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ ./drk dao create 20 10 0.67 WCKD > dao_wckd.dat
|
$ ./drk dao create 20 10 10 0.67 WCKD > dao_wckd.toml
|
||||||
$ ./drk dao import WickedDAO < dao_wckd.dat
|
$ ./drk dao import WickedDAO < dao_wckd.toml
|
||||||
$ ./drk dao mint WickedDAO > dao_wckd_mint_tx
|
$ ./drk dao mint WickedDAO > dao_wckd_mint_tx
|
||||||
$ ./drk broadcast < dao_wckd_mint_tx
|
$ ./drk broadcast < dao_wckd_mint_tx
|
||||||
```
|
```
|
||||||
@@ -223,6 +272,13 @@ $ ./drk dao exec {PROPOSAL_BULLA} > dao_mldy_transfer_proposal_wckd_exec_tx
|
|||||||
$ ./drk broadcast < dao_mldy_transfer_proposal_wckd_exec_tx
|
$ ./drk broadcast < dao_mldy_transfer_proposal_wckd_exec_tx
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Or right away, since the early execution quorum has been reached:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./drk dao exec --early {PROPOSAL_BULLA} > dao_mldy_transfer_proposal_wckd_exec_tx
|
||||||
|
$ ./drk broadcast < dao_mldy_transfer_proposal_wckd_exec_tx
|
||||||
|
```
|
||||||
|
|
||||||
After the proposal has been executed on chain, we will see that
|
After the proposal has been executed on chain, we will see that
|
||||||
the DAO governance token balance has been reduced by 6.9 `MLDY`,
|
the DAO governance token balance has been reduced by 6.9 `MLDY`,
|
||||||
while the new DAO balance has been increased by the same amount:
|
while the new DAO balance has been increased by the same amount:
|
||||||
|
|||||||
Reference in New Issue
Block a user