| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- k = 13;
- field = "pallas";
- constant "DaoExec" {
- EcFixedPointShort VALUE_COMMIT_VALUE,
- EcFixedPoint VALUE_COMMIT_RANDOM,
- }
- witness "DaoExec" {
- # Proposal parameters
- Base proposal_dest_x,
- Base proposal_dest_y,
- Base proposal_amount,
- Base proposal_token_id,
- Base proposal_blind,
- # DAO parameters
- 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_vote_value,
- Base all_vote_value,
- Scalar yes_vote_blind,
- Scalar all_vote_blind,
- # Outputs + Inputs
- Base user_serial,
- Base dao_serial,
- Base input_value,
- Scalar input_value_blind,
- # Miscellaneous
- Base dao_spend_hook,
- Base user_spend_hook,
- Base user_data,
- # Check input user_data_enc encodes the same DAO bulla
- Base input_user_data_blind,
- }
- 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 being valid means DAO bulla is also valid because
- # 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_token_id,
- dao_bulla,
- proposal_blind,
- );
- constrain_instance(proposal_bulla);
- coin_0 = poseidon_hash(
- proposal_dest_x,
- proposal_dest_y,
- proposal_amount,
- proposal_token_id,
- user_serial,
- user_spend_hook,
- user_data,
- );
- 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,
- );
- constrain_instance(coin_1);
- # Create Pedersen commitments for win_votes and total_votes, and
- # constrain the commitments' coordinates.
- yes_vote_value_c = ec_mul_short(yes_vote_value, VALUE_COMMIT_VALUE);
- yes_vote_blind_c = ec_mul(yes_vote_blind, VALUE_COMMIT_RANDOM);
- yes_vote_commit = ec_add(yes_vote_value_c, yes_vote_blind_c);
- constrain_instance(ec_get_x(yes_vote_commit));
- constrain_instance(ec_get_y(yes_vote_commit));
- all_vote_value_c = ec_mul_short(all_vote_value, VALUE_COMMIT_VALUE);
- all_vote_blind_c = ec_mul(all_vote_blind, VALUE_COMMIT_RANDOM);
- all_vote_commit = ec_add(all_vote_value_c, all_vote_blind_c);
- constrain_instance(ec_get_x(all_vote_commit));
- constrain_instance(ec_get_y(all_vote_commit));
- # Create Pedersen commitment 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);
- constrain_instance(ec_get_x(input_value_commit));
- constrain_instance(ec_get_y(input_value_commit));
- 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_vote_value
- one = witness_base(1);
- all_vote_value_1 = base_add(all_vote_value, one);
- less_than_strict(dao_quorum, all_vote_value_1);
- # approval_ratio_quot / approval_ratio_base <= yes_vote / all_vote
- #
- # The above is also equivalent to this:
- #
- # all_vote * approval_ratio_quot <= yes_vote * approval_ratio_base
- lhs = base_mul(all_vote_value, dao_approval_ratio_quot);
- rhs = base_mul(yes_vote_value, dao_approval_ratio_base);
- rhs_1 = base_add(rhs, one);
- less_than_strict(lhs, rhs_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
- # The coin we are spending should have the encrypted DAO bulla
- # Make sure it is the same as the DAO we are operating on.
- input_user_data_enc = poseidon_hash(dao_bulla, input_user_data_blind);
- constrain_instance(input_user_data_enc);
- # 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
- }
|