Files
darkfi/bin/dao/daod/proof/dao-exec.zk

169 lines
4.7 KiB
Plaintext

constant "DaoExec" {
EcFixedPointShort VALUE_COMMIT_VALUE,
EcFixedPoint VALUE_COMMIT_RANDOM,
}
contract "DaoExec" {
# proposal params
Base proposal_dest_x,
Base proposal_dest_y,
Base proposal_amount,
Base proposal_serial,
Base proposal_token_id,
Base proposal_blind,
# DAO params
Base dao_proposer_limit,
Base dao_quorum,
Base dao_approval_ratio_quot,
Base dao_approval_ratio_base,
Base gov_token_id,
Base dao_public_x,
Base dao_public_y,
Base dao_bulla_blind,
# votes
Base yes_votes_value,
Base all_votes_value,
Scalar yes_votes_blind,
Scalar all_votes_blind,
# outputs + inputs
Base user_serial,
Base user_coin_blind,
Base dao_serial,
Base dao_coin_blind,
Base input_value,
Scalar input_value_blind,
# misc
Base dao_spend_hook,
Base user_spend_hook,
Base user_data,
}
circuit "DaoExec" {
dao_bulla = poseidon_hash(
dao_proposer_limit,
dao_quorum,
dao_approval_ratio_quot,
dao_approval_ratio_base,
gov_token_id,
dao_public_x,
dao_public_y,
dao_bulla_blind,
);
# Proposal bulla is valid means DAO bulla is also valid
# because of dao-propose-main.zk, already checks that when
# we first create the proposal. So it is redundant here.
proposal_bulla = poseidon_hash(
proposal_dest_x,
proposal_dest_y,
proposal_amount,
proposal_serial,
proposal_token_id,
dao_bulla,
proposal_blind,
# @tmp-workaround
proposal_blind,
);
constrain_instance(proposal_bulla);
coin_0 = poseidon_hash(
proposal_dest_x,
proposal_dest_y,
proposal_amount,
proposal_token_id,
proposal_serial,
user_spend_hook,
user_data,
proposal_blind,
);
constrain_instance(coin_0);
change = base_sub(input_value, proposal_amount);
coin_1 = poseidon_hash(
dao_public_x,
dao_public_y,
change,
proposal_token_id,
dao_serial,
dao_spend_hook,
dao_bulla,
dao_coin_blind,
);
constrain_instance(coin_1);
# Create pedersen commits for win_votes, and total_votes
# and make public
yes_votes_value_c = ec_mul_short(yes_votes_value, VALUE_COMMIT_VALUE);
yes_votes_blind_c = ec_mul(yes_votes_blind, VALUE_COMMIT_RANDOM);
yes_votes_commit = ec_add(yes_votes_value_c, yes_votes_blind_c);
# get curve points and constrain
yes_votes_commit_x = ec_get_x(yes_votes_commit);
yes_votes_commit_y = ec_get_y(yes_votes_commit);
constrain_instance(yes_votes_commit_x);
constrain_instance(yes_votes_commit_y);
all_votes_c = ec_mul_short(all_votes_value, VALUE_COMMIT_VALUE);
all_votes_blind_c = ec_mul(all_votes_blind, VALUE_COMMIT_RANDOM);
all_votes_commit = ec_add(all_votes_c, all_votes_blind_c);
# get curve points and constrain
all_votes_commit_x = ec_get_x(all_votes_commit);
all_votes_commit_y = ec_get_y(all_votes_commit);
constrain_instance(all_votes_commit_x);
constrain_instance(all_votes_commit_y);
# Create pedersen commit for input_value and make public
input_value_v = ec_mul_short(input_value, VALUE_COMMIT_VALUE);
input_value_r = ec_mul(input_value_blind, VALUE_COMMIT_RANDOM);
input_value_commit = ec_add(input_value_v, input_value_r);
# get curve points and constrain
input_value_x = ec_get_x(input_value_commit);
input_value_y = ec_get_y(input_value_commit);
constrain_instance(input_value_x);
constrain_instance(input_value_y);
constrain_instance(dao_spend_hook);
constrain_instance(user_spend_hook);
constrain_instance(user_data);
# Check that dao_quorum is less than or equal to all_votes_value
one = witness_base(1);
all_votes_value_1 = base_add(all_votes_value, one);
less_than(dao_quorum, all_votes_value_1);
# approval_ratio_quot / approval_ratio_base <= yes_votes / all_votes
#
# The above is also equivalent to this:
#
# all_votes * approval_ratio_quot <= yes_votes * approval_ratio_base
rhs = base_mul(all_votes_value, dao_approval_ratio_quot);
lhs = base_mul(yes_votes_value, dao_approval_ratio_base);
lhs_1 = base_add(lhs, one);
less_than(rhs, lhs_1);
####
# Create coin 0
# Create coin 1
# Check values of coin 0 + coin 1 == input value
# Check value of coin 0 == proposal_amount
# Check public key matches too
# Create the input value commit
# Create the value commits
# NOTE: there is a vulnerability here where someone can create the exec
# transaction with a bad note so it cannot be decrypted by the receiver
# TODO: research verifiable encryption inside ZK
}