mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-07 22:04:03 -05:00
dao: all documentation updated
This commit is contained in:
@@ -5,29 +5,29 @@
|
||||
-- $ drk dao create_dao \
|
||||
-- PROPOSER_LIMIT \
|
||||
-- QUORUM \
|
||||
-- APPROVAL_RATIO_BASE \
|
||||
-- APPROVAL_RATIO_QUOTIENT \
|
||||
-- GOV_TOKEN_ID > dao.dat
|
||||
-- EARLY_EXEC_QUORUM \
|
||||
-- APPROVAL_RATIO \
|
||||
-- GOV_TOKEN_ID > dao.toml
|
||||
--
|
||||
-- dat.dat contains:
|
||||
-- dat.toml contains:
|
||||
--
|
||||
-- * DAO parameters as listed above
|
||||
-- * secret key for the DAO
|
||||
-- * bulla blind
|
||||
-- * Secret keys for the DAO
|
||||
-- * Bulla blind
|
||||
--
|
||||
-- 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
|
||||
-- it into their wallets.
|
||||
-- Now everyone inside the DAO exchanges dao.toml out of band,
|
||||
-- will import it into their wallets.
|
||||
--
|
||||
-- $ drk dao import DAO_NAME < dao.dat
|
||||
-- $ drk dao import DAO_NAME < dao.toml
|
||||
-- Imported DAO ccb8XXX8af6
|
||||
--
|
||||
-- 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 broadcast < dao_mint_tx
|
||||
@@ -56,8 +56,9 @@
|
||||
-- RECV_PUBKEY
|
||||
--
|
||||
-- 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.
|
||||
-- or don't hold the proposer key, then this call will simply fail with
|
||||
-- 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
|
||||
-- to other participants.
|
||||
@@ -73,6 +74,7 @@
|
||||
-- # DAO::vote()
|
||||
--
|
||||
-- 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
|
||||
-- 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
|
||||
let Ok(dao) = self.get_dao_by_bulla(&proposal.proposal.dao_bulla).await else {
|
||||
return Err(Error::Custom(format!(
|
||||
|
||||
@@ -35,45 +35,46 @@ testnet user guide.
|
||||
Note: List is not exhaustive. Missing functionalities that are not part
|
||||
of the guide can be added for future regressions.
|
||||
|
||||
| # | Description | Command | Status |
|
||||
|----|---------------------------|----------------------------------------------------------|--------------------|
|
||||
| 0 | Initialization | wallet --initialize | Pass |
|
||||
| 1 | Key generation | wallet --keygen | Pass |
|
||||
| 2 | Set default wallet | wallet --default-address {ADDR_ID} | Pass |
|
||||
| 3 | Default address retrieval | wallet --address | Pass |
|
||||
| 4 | Block scanning | scan | Pass |
|
||||
| 5 | Block subscribing | subscribe | Pass |
|
||||
| 6 | Balance retrieval | wallet --balance | Pass |
|
||||
| 7 | Aliases retrieval | alias show | Pass |
|
||||
| 8 | Mint auth generation | token generate-mint | Pass |
|
||||
| 9 | Mint auths retrieval | token list | Pass |
|
||||
| 10 | Alias add | alias add {ALIAS} {TOKEN} | Pass |
|
||||
| 11 | Aliases retrieval | alias show | Pass |
|
||||
| 12 | Mint generation | token mint {ALIAS} {AMOUNT} {ADDR} | Pass |
|
||||
| 13 | Token freeze | token freeze {ALIAS} | Pass |
|
||||
| 14 | Transfer | transfer {AMOUNT} {ALIAS} {ADDR} | Pass |
|
||||
| 15 | Coins retrieval | wallet --coins | Pass |
|
||||
| 16 | OTC initialization | otc init -v {AMOUNT}:{AMOUNT} -t {ALIAS}:{ALIAS} | Pass |
|
||||
| 17 | OTC join | otc join | Pass |
|
||||
| 18 | OTC sign | otc sign | Pass |
|
||||
| 19 | DAO create | dao create {LIMIT} {QUORUM} {RATIO} {TOKEN} | Pass |
|
||||
| 20 | DAO view | dao view | Pass |
|
||||
| 21 | DAO import | dao import | Pass |
|
||||
| 22 | DAO list | dao list | Pass |
|
||||
| 23 | DAO mint | dao mint {DAO} | Pass |
|
||||
| 24 | DAO balance | dao balance {DAO} | Pass |
|
||||
| 25 | DAO proposals retrieval | dao proposals {DAO} | Pass |
|
||||
| 26 | DAO propose a transfer | dao propose-transfer {DAO} {DUR} {AMOUNT} {TOKEN} {ADDR} | Pass |
|
||||
| 27 | DAO proposals retrieval | dao proposals {DAO} | Pass |
|
||||
| 28 | DAO proposal retrieval | dao proposal {PROPOSAL_BULLA} | Pass |
|
||||
| 29 | DAO proposal export | dao proposal {PROPOSAL_BULLA} --export | Pass |
|
||||
| 30 | DAO proposal import | dao proposal-import | Pass |
|
||||
| 31 | DAO proposal mint | dao proposal {PROPOSAL_BULLA} --mint-proposal | Pass |
|
||||
| 32 | DAO vote | dao vote {PROPOSAL_BULLA} {VOTE} {WEIGHT} | Pass |
|
||||
| 33 | DAO proposal execution | dao exec {PROPOSAL_BULLA} | Pass |
|
||||
| 34 | Coins unspend | unspend {COIN} | Pass |
|
||||
| 35 | Transaction inspect | inspect | Pass |
|
||||
| 36 | Transaction simulate | explorer simulate-tx | Pass |
|
||||
| 37 | Transaction broadcast | broadcast | Pass |
|
||||
| 38 | Transaction attach fee | attach-fee | Pass |
|
||||
|
||||
| # | Description | Command | Status |
|
||||
|----|------------------------------|-----------------------------------------------------------------|--------|
|
||||
| 0 | Initialization | wallet --initialize | Pass |
|
||||
| 1 | Key generation | wallet --keygen | Pass |
|
||||
| 2 | Set default wallet | wallet --default-address {ADDR_ID} | Pass |
|
||||
| 3 | Default address retrieval | wallet --address | Pass |
|
||||
| 4 | Block scanning | scan | Pass |
|
||||
| 5 | Block subscribing | subscribe | Pass |
|
||||
| 6 | Balance retrieval | wallet --balance | Pass |
|
||||
| 7 | Aliases retrieval | alias show | Pass |
|
||||
| 8 | Mint auth generation | token generate-mint | Pass |
|
||||
| 9 | Mint auths retrieval | token list | Pass |
|
||||
| 10 | Alias add | alias add {ALIAS} {TOKEN} | Pass |
|
||||
| 11 | Aliases retrieval | alias show | Pass |
|
||||
| 12 | Mint generation | token mint {ALIAS} {AMOUNT} {ADDR} | Pass |
|
||||
| 13 | Token freeze | token freeze {ALIAS} | Pass |
|
||||
| 14 | Transfer | transfer {AMOUNT} {ALIAS} {ADDR} | Pass |
|
||||
| 15 | Coins retrieval | wallet --coins | Pass |
|
||||
| 16 | OTC initialization | otc init -v {AMOUNT}:{AMOUNT} -t {ALIAS}:{ALIAS} | Pass |
|
||||
| 17 | OTC join | otc join | Pass |
|
||||
| 18 | OTC sign | otc sign | Pass |
|
||||
| 19 | DAO create | dao create {LIMIT} {QUORUM} {EARLY_EXEC_QUORUM} {RATIO} {TOKEN} | Pass |
|
||||
| 20 | DAO view | dao view | Pass |
|
||||
| 21 | DAO import | dao import | Pass |
|
||||
| 22 | DAO update keys | dao update-keys | Pass |
|
||||
| 23 | DAO list | dao list | Pass |
|
||||
| 24 | DAO mint | dao mint {DAO} | Pass |
|
||||
| 25 | DAO balance | dao balance {DAO} | Pass |
|
||||
| 26 | DAO proposals retrieval | dao proposals {DAO} | Pass |
|
||||
| 27 | DAO propose a transfer | dao propose-transfer {DAO} {DUR} {AMOUNT} {TOKEN} {ADDR} | Pass |
|
||||
| 28 | DAO propose generic | dao propose-generic {DAO} {DUR} {AMOUNT} {TOKEN} {ADDR} | Pass |
|
||||
| 29 | DAO proposal retrieval | dao proposal {PROPOSAL_BULLA} | Pass |
|
||||
| 30 | DAO proposal export | dao proposal {PROPOSAL_BULLA} --export | Pass |
|
||||
| 31 | DAO proposal import | dao proposal-import | Pass |
|
||||
| 32 | DAO proposal mint | dao proposal {PROPOSAL_BULLA} --mint-proposal | Pass |
|
||||
| 33 | DAO vote | dao vote {PROPOSAL_BULLA} {VOTE} {WEIGHT} | Pass |
|
||||
| 34 | DAO proposal execution | dao exec {PROPOSAL_BULLA} | Pass |
|
||||
| 35 | DAO proposal early execution | dao exec --early {PROPOSAL_BULLA} | Pass |
|
||||
| 36 | Coins unspend | unspend {COIN} | Pass |
|
||||
| 37 | Transaction inspect | inspect | 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
|
||||
DRK="../../../drk -c drk.toml"
|
||||
|
||||
# First run the consensus node and the faucet:
|
||||
# First run the darkfid node and the miner:
|
||||
#
|
||||
# ./clean.sh
|
||||
# ./init-wallet.sh
|
||||
# ./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
|
||||
#
|
||||
@@ -61,8 +63,8 @@ wait_tokens() {
|
||||
}
|
||||
|
||||
mint_dao() {
|
||||
$DRK dao create 20 10 0.67 MLDY > /tmp/dao.dat
|
||||
$DRK dao import MiladyMakerDAO < /tmp/dao.dat
|
||||
$DRK dao create 20 10 10 0.67 MLDY > /tmp/dao.toml
|
||||
$DRK dao import MiladyMakerDAO < /tmp/dao.toml
|
||||
$DRK dao list
|
||||
$DRK dao list MiladyMakerDAO
|
||||
|
||||
@@ -70,19 +72,20 @@ mint_dao() {
|
||||
}
|
||||
|
||||
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
|
||||
done
|
||||
}
|
||||
|
||||
fill_treasury() {
|
||||
PUBKEY="$($DRK dao list 1 | grep '^Public key: ' | cut -d ' ' -f3)"
|
||||
BULLA="$($DRK dao list 1 | grep '^Bulla: ' | cut -d' ' -f2)"
|
||||
$DRK transfer 20 WCKD "$PUBKEY" --dao "$BULLA" | tee /tmp/xfer.tx | $DRK broadcast
|
||||
PUBKEY="$($DRK dao list MiladyMakerDAO | grep '^Notes Public key: ' | cut -d ' ' -f4)"
|
||||
SPEND_HOOK="$($DRK dao spend-hook)"
|
||||
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() {
|
||||
BALANCE=$($DRK dao balance 1 2>/dev/null)
|
||||
BALANCE=$($DRK dao balance MiladyMakerDAO 2>/dev/null)
|
||||
# No tokens received at all yet
|
||||
if echo "$BALANCE" | grep -q "No unspent balances found"; then
|
||||
echo 0
|
||||
@@ -108,51 +111,44 @@ wait_dao_treasury() {
|
||||
|
||||
propose() {
|
||||
MY_ADDR=$($DRK wallet --address)
|
||||
$DRK dao balance MiladyMakerDAO
|
||||
$DRK dao propose MiladyMakerDAO "$MY_ADDR" 0.1 WCKD > /tmp/propose.tx
|
||||
PROPOSAL="$($DRK dao propose-transfer MiladyMakerDAO 1 5 WCKD "$MY_ADDR" | cut -d' ' -f3)"
|
||||
$DRK dao proposal "$PROPOSAL" --mint-proposal > /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() {
|
||||
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
|
||||
done
|
||||
}
|
||||
|
||||
vote() {
|
||||
PROPOSAL_ID=1
|
||||
$DRK dao vote MiladyMakerDAO "$PROPOSAL_ID" 1 20 > /tmp/dao-vote.tx
|
||||
PROPOSAL="$($DRK dao proposals MiladyMakerDAO | cut -d' ' -f2)"
|
||||
$DRK dao vote "$PROPOSAL" 1 > /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() {
|
||||
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
|
||||
done
|
||||
}
|
||||
|
||||
do_exec() {
|
||||
PROPOSAL_ID=1
|
||||
$DRK dao exec MiladyMakerDAO "$PROPOSAL_ID" > /tmp/dao-exec.tx
|
||||
PROPOSAL="$($DRK dao proposals MiladyMakerDAO | cut -d' ' -f2)"
|
||||
$DRK dao exec --early $PROPOSAL > /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
|
||||
wait_tokens
|
||||
mint_dao
|
||||
@@ -164,3 +160,4 @@ wait_proposal
|
||||
vote
|
||||
wait_vote
|
||||
do_exec
|
||||
wait_exec
|
||||
|
||||
@@ -3,7 +3,7 @@ set -e
|
||||
set -x
|
||||
|
||||
# Path to `drk` binary
|
||||
DRK="../../../drk -vv -c drk.toml"
|
||||
DRK="../../../drk -c drk.toml"
|
||||
|
||||
while true; do
|
||||
if $DRK ping 2> /dev/null; then
|
||||
|
||||
@@ -14,49 +14,70 @@ these bullas.
|
||||
|
||||
## `DAO::mint()`: Establishing the DAO
|
||||
|
||||
From `darkfi/src/contract/dao/proof/dao-mint.zk`:
|
||||
From `darkfi/src/contract/dao/proof/mint.zk`:
|
||||
```zkas
|
||||
bulla = poseidon_hash(
|
||||
dao_proposer_limit,
|
||||
dao_quorum,
|
||||
dao_approval_ratio_quot,
|
||||
dao_approval_ratio_base,
|
||||
proposer_limit,
|
||||
quorum,
|
||||
early_exec_quorum,
|
||||
approval_ratio_quot,
|
||||
approval_ratio_base,
|
||||
gov_token_id,
|
||||
dao_public_x,
|
||||
dao_public_y,
|
||||
dao_bulla_blind,
|
||||
);
|
||||
notes_public_x,
|
||||
notes_public_y,
|
||||
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:
|
||||
|
||||
* **proposer_limit**: minimum deposit required for proposals to become valid.
|
||||
TODO: rename to `min_deposit`.
|
||||
* **quorum**: minimum threshold of votes before it's allowed to pass.
|
||||
* **proposer_limit**: the minimum amount of governance tokens needed to open a proposal.
|
||||
* **quorum**: minimal threshold of participating total tokens needed for a proposal to pass.
|
||||
Normally this is implemented as min % of voting power, but we do this in
|
||||
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
|
||||
if desired.
|
||||
DAO creators/founders have full control on how they want to configure and share
|
||||
the actions keys, giving them the ability to veto if needed.
|
||||
|
||||
## `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
|
||||
proposal_bulla = poseidon_hash(
|
||||
proposal_dest_x,
|
||||
proposal_dest_y,
|
||||
proposal_amount,
|
||||
proposal_token_id,
|
||||
proposal_auth_calls_commit,
|
||||
proposal_creation_blockwindow,
|
||||
proposal_duration_blockwindows,
|
||||
proposal_user_data,
|
||||
dao_bulla,
|
||||
proposal_blind,
|
||||
);
|
||||
```
|
||||
|
||||
We create a proposal which will send tokens to the dest provided.
|
||||
This will soon be changed to be generic. Proposals will commit to
|
||||
calling params or code instead.
|
||||
Proposals are committed to a specific calls set, therefore they
|
||||
are generic and we can attach various calls to it. We will use a
|
||||
money transfer as the example for rest sections.
|
||||
|
||||
## `DAO::vote()`: Vote on a Proposal
|
||||
|
||||
@@ -366,37 +387,52 @@ be executed early. We should add this option to DarkFi DAO params.
|
||||
|
||||
## Suggested Changes
|
||||
|
||||
DAO params:
|
||||
~~DAO params:~~
|
||||
|
||||
* Voting period (currently called duration) should be moved from proposals to
|
||||
DAO params.
|
||||
* upgrayedd: we should just have minimum allowed period in the DAO, but keep
|
||||
this param in the proposal.
|
||||
* Window (currently set at 4 hours of blocks) should be customizable. We need a
|
||||
terminology for the unit of time. Maybe `time_units`.
|
||||
* This should be switched from block index to using timestamps.
|
||||
* ~~Voting period (currently called duration) should be moved from proposals to
|
||||
DAO params.~~
|
||||
* ~~upgrayedd: we should just have minimum allowed period in the DAO, but keep
|
||||
this param in the proposal.~~
|
||||
* ~~Window (currently set at 4 hours of blocks) should be customizable. We need a
|
||||
terminology for the unit of time. Maybe `time_units`.~~
|
||||
* ~~This should be switched from block index to using timestamps.
|
||||
See the quoted paragraph in the OpenZeppelin section above for the
|
||||
reasoning.
|
||||
* upgrayedd: stick with block index.
|
||||
* Early execution bool flag. If true, then passed proposals can be `exec()`uted
|
||||
asap, otherwise the entire voting period must pass.
|
||||
reasoning.~~
|
||||
* ~~upgrayedd: stick with block index.~~
|
||||
* ~~Early execution bool flag. If true, then passed proposals can be `exec()`uted
|
||||
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.
|
||||
* Calling exec.
|
||||
~~Currently the DAO public key is used for:~~
|
||||
|
||||
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
|
||||
proposals.
|
||||
* OZ does this with a canceller role that has the ability to cancel
|
||||
proposals.
|
||||
* In the future allow multiple keys for this so you can see who makes
|
||||
proposals.
|
||||
proposals.~~
|
||||
* ~~OZ does this with a canceller role that has the ability to cancel
|
||||
proposals.~~
|
||||
* ~~In the future allow multiple keys for this so you can see who makes
|
||||
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
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
a proposal before it is posted on chain so that their combined inputs meet the
|
||||
proposal governance token limit.
|
||||
of governance tokens and the DAO proposers key. Several members of the DAO can
|
||||
add inputs separately to a proposal before it is posted on chain so that their
|
||||
combined inputs meet the proposal governance token limit.
|
||||
|
||||
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 is defined as the minimum absolute number of governance tokens voting
|
||||
yes required for a proposal to become accepted.
|
||||
Quorum is defined as the minimal threshold of participating total governance tokens need for
|
||||
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
|
||||
|
||||
|
||||
@@ -13,20 +13,31 @@ The DAO contains the main parameters that define DAO operation:
|
||||
come from multiple token holders.
|
||||
* Quorum $Q$ specifies the absolute minimum number of tokens required for
|
||||
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
|
||||
of affirmative yes votes for a proposal to become accepted.
|
||||
* The public key $PK$ serves a dual role for both encrypted notes, and as
|
||||
a key to authorize accepted proposals to be executed.
|
||||
This key may be shared widely with all DAO members or within a privileged
|
||||
group.
|
||||
* Notes public key $NPK$ controls who can view encrypted notes.
|
||||
* Proposer public key $pPK$ controls who can mint proposals.
|
||||
* Proposals public key $PPK$ controls who can view the proposals.
|
||||
* 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
|
||||
$$ \begin{aligned}
|
||||
\t{Params}_\t{DAO}.L &∈ ℕ₆₄ \\
|
||||
\t{Params}_\t{DAO}.Q &∈ ℕ₆₄ \\
|
||||
\t{Params}_\t{DAO}.EEQ &∈ ℕ₆₄ \\
|
||||
\t{Params}_\t{DAO}.A^\% &∈ ℕ₆₄ × ℕ₆₄ \\
|
||||
\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} $$
|
||||
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₂}]$.
|
||||
@@ -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}(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
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ the DAO params and then add the bulla to the set.
|
||||
|
||||
* Wallet builder: `src/contract/dao/src/client/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
|
||||
|
||||
@@ -45,22 +45,41 @@ Let there be a prover auxiliary witness inputs:
|
||||
$$ \begin{aligned}
|
||||
L &∈ ℕ₆₄ \\
|
||||
Q &∈ ℕ₆₄ \\
|
||||
EEQ &∈ ℕ₆₄ \\
|
||||
A^\% &∈ ℕ₆₄ × ℕ₆₄ \\
|
||||
τ &∈ 𝔽ₚ \\
|
||||
x &∈ 𝔽ₚ \\
|
||||
Nx &∈ 𝔽ₚ \\
|
||||
px &∈ 𝔽ₚ \\
|
||||
Px &∈ 𝔽ₚ \\
|
||||
Vx &∈ 𝔽ₚ \\
|
||||
Ex &∈ 𝔽ₚ \\
|
||||
EEx &∈ 𝔽ₚ \\
|
||||
b_\t{DAO} &∈ 𝔽ₚ
|
||||
\end{aligned} $$
|
||||
|
||||
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
|
||||
|
||||
There should be a single signature attached, which uses
|
||||
$\t{PK}$ as the signature public key.
|
||||
$\t{NPK}$ as the signature public key.
|
||||
|
||||
## 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`
|
||||
* WASM VM code: `src/contract/dao/src/entrypoint/propose.rs`
|
||||
* ZK proofs:
|
||||
* `src/contract/dao/proof/dao-propose-main.zk`
|
||||
* `src/contract/dao/proof/dao-propose-input.zk`
|
||||
* `src/contract/dao/proof/propose-main.zk`
|
||||
* `src/contract/dao/proof/propose-input.zk`
|
||||
|
||||
### 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
|
||||
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 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
|
||||
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
|
||||
voting. The result of the vote is communicated to other DAO members through the
|
||||
encrypted note $\t{note}$.
|
||||
voting. The result of the vote is communicated to DAO members that can view votes
|
||||
through the encrypted note $\t{note}$.
|
||||
|
||||
Each nullifier $𝒩 $ is stored uniquely per proposal. Additionally as before,
|
||||
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`
|
||||
* WASM VM code: `src/contract/dao/src/entrypoint/vote.rs`
|
||||
* ZK proofs:
|
||||
* `src/contract/dao/proof/dao-vote-main.zk`
|
||||
* `src/contract/dao/proof/dao-vote-input.zk`
|
||||
* `src/contract/dao/proof/vote-main.zk`
|
||||
* `src/contract/dao/proof/vote-input.zk`
|
||||
|
||||
### 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
|
||||
used to calculate $V_\t{yes}$.
|
||||
|
||||
This allows DAO members to securely receive all secrets for votes on a proposal.
|
||||
This is then used in the Exec phase when we work on the sum of DAO votes.
|
||||
This allows DAO members that hold the votes key to securely receive all secrets
|
||||
for votes on a proposal. This is then used in the Exec phase when we work on the
|
||||
sum of DAO votes.
|
||||
|
||||
```rust
|
||||
{{#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**  
|
||||
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:
|
||||
|
||||
@@ -343,8 +365,8 @@ public key $i.\t{PK}_σ$.
|
||||
|
||||
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
|
||||
[DAO params](model.md#dao) such as quorum and approval ratio.
|
||||
It checks that voting has passed, and correct conditions have been met, in accordance
|
||||
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.
|
||||
|
||||
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`
|
||||
* 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
|
||||
|
||||
@@ -402,11 +426,16 @@ $$ \begin{aligned}
|
||||
\end{aligned} $$
|
||||
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)$
|
||||
|
||||
**Proposal bulla integrity**   $𝒫 = \t{Bulla}_\t{Proposal}(p, b_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)$
|
||||
|
||||
**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
|
||||
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
|
||||
|
||||
No signatures are attached.
|
||||
@@ -437,8 +506,8 @@ DAO treasury but be unspendable.
|
||||
* Wallet builder: `src/contract/dao/src/client/auth_xfer.rs`
|
||||
* WASM VM code: `src/contract/dao/src/entrypoint/auth_xfer.rs`
|
||||
* ZK proofs:
|
||||
* `src/contract/dao/proof/dao-auth-money-transfer.zk`
|
||||
* `src/contract/dao/proof/dao-auth-money-transfer-enc-coin.zk`
|
||||
* `src/contract/dao/proof/auth-money-transfer.zk`
|
||||
* `src/contract/dao/proof/auth-money-transfer-enc-coin.zk`
|
||||
|
||||
### Function Params
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ Let's create a DAO with the following parameters:
|
||||
|
||||
* Proposer limit: `20`
|
||||
* Quorum: `10`
|
||||
* Early execution quorum: `10`
|
||||
* Approval ratio: `0.67`
|
||||
* Governance token: `MLDY`
|
||||
|
||||
@@ -20,17 +21,21 @@ $ ./drk help dao create
|
||||
Let's create our DAO.
|
||||
|
||||
```
|
||||
$ ./drk dao create 20 10 0.67 MLDY > dao_mldy.dat
|
||||
$ ./drk dao view < dao_mldy.dat
|
||||
$ ./drk dao create 20 10 10 0.67 MLDY > dao_mldy.toml
|
||||
$ ./drk dao view < dao_mldy.toml
|
||||
```
|
||||
|
||||
Now this file can be shared amongst all 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:
|
||||
Since its a normal `toml` file, you may open it with you favourite
|
||||
editor, modify they keys configuration and/or keep different versions
|
||||
for different members. By default all keys are different, so its up
|
||||
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 MiladyMakerDAO
|
||||
```
|
||||
@@ -39,7 +44,8 @@ $ ./drk dao list MiladyMakerDAO
|
||||
|
||||
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
|
||||
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
|
||||
@@ -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
|
||||
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
|
||||
transfer transaction:
|
||||
dao contract spend hook and the DAO notes public key and then create
|
||||
a transfer transaction:
|
||||
|
||||
```
|
||||
$ ./drk dao spend-hook
|
||||
$ ./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
|
||||
$ ./drk broadcast < dao_mldy_transfer_tx
|
||||
```
|
||||
|
||||
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
|
||||
@@ -77,23 +83,24 @@ $ ./drk dao balance MiladyMakerDAO
|
||||
|
||||
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
|
||||
for 1 block period. Let's propose to send 5 of the 10 tokens to
|
||||
our address (we can find that with `drk wallet --address`):
|
||||
for 1 block period, if we hold the DAO proposer key. Let's propose
|
||||
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}
|
||||
```
|
||||
|
||||
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}
|
||||
```
|
||||
|
||||
We can export this proposal, to share with rest DAO members.
|
||||
The exported file will be encrypted using the DAO keys, so only
|
||||
its members can decrypt and import it.
|
||||
The exported file will be encrypted using the DAO proposals view key,
|
||||
so only its members can decrypt and import it.
|
||||
|
||||
```
|
||||
$ ./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
|
||||
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
|
||||
|
||||
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
|
||||
ratio is bigger than the approval ratio, then we are ready to confirm
|
||||
the vote. Any DAO member can perform this action.
|
||||
|
||||
Since in our tutorial the `MLDY` governance tokens we used surpass the
|
||||
quorum, we can execute the proposal right away:
|
||||
the vote. Only DAO members with the executor key can perform this action.
|
||||
|
||||
```
|
||||
$ ./drk dao exec {PROPOSAL_BULLA} > 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
|
||||
the DAO balance has been reduced by 5 `WCKD`, while our own balance
|
||||
has been increased by the same amount:
|
||||
the DAO balance has been reduced by 5 `WCKD`, if we hold the DAO notes key,
|
||||
while our own balance has been increased by the same amount:
|
||||
|
||||
```
|
||||
$ ./drk dao balance MiladyMakerDAO
|
||||
$ ./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
|
||||
|
||||
Let's now try some more exotic operations!
|
||||
@@ -192,8 +241,8 @@ $ ./drk dao balance MiladyMakerDAO
|
||||
Now we will create a second dao:
|
||||
|
||||
```
|
||||
$ ./drk dao create 20 10 0.67 WCKD > dao_wckd.dat
|
||||
$ ./drk dao import WickedDAO < dao_wckd.dat
|
||||
$ ./drk dao create 20 10 10 0.67 WCKD > dao_wckd.toml
|
||||
$ ./drk dao import WickedDAO < dao_wckd.toml
|
||||
$ ./drk dao mint WickedDAO > 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
|
||||
```
|
||||
|
||||
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
|
||||
the DAO governance token balance has been reduced by 6.9 `MLDY`,
|
||||
while the new DAO balance has been increased by the same amount:
|
||||
|
||||
Reference in New Issue
Block a user