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, Base gov_token_id, Base dao_public_x, Base dao_public_y, Base dao_bulla_blind, # votes Base yes_vote_values, Base all_vote_values, Scalar all_vote_blinds, Scalar all_vote_value_blinds, # 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, gov_token_id, dao_public_x, dao_public_y, dao_bulla_blind, # @tmp-workaround 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, proposal_bulla, dao_coin_blind, ); constrain_instance(coin_1); # Create pedersen commits for win_votes, and total_votes # and make public yes_vote_values_c = ec_mul_short(yes_vote_values, VALUE_COMMIT_VALUE); all_vote_blinds_c = ec_mul(all_vote_blinds, VALUE_COMMIT_RANDOM); weighted_votes_commit = ec_add(yes_vote_values_c, all_vote_blinds_c); # get curve points and constrain weighted_votes_commit_x = ec_get_x(weighted_votes_commit); weighted_votes_commit_y = ec_get_y(weighted_votes_commit); constrain_instance(weighted_votes_commit_x); constrain_instance(weighted_votes_commit_y); all_vote_values_c = ec_mul_short(all_vote_values, VALUE_COMMIT_VALUE); all_vote_value_blinds_c = ec_mul(all_vote_value_blinds, VALUE_COMMIT_RANDOM); all_vote_values_commit = ec_add(all_vote_values_c, all_vote_value_blinds_c); # get curve points and constrain all_vote_values_commit_x = ec_get_x(all_vote_values_commit); all_vote_values_commit_y = ec_get_y(all_vote_values_commit); constrain_instance(all_vote_values_commit_x); constrain_instance(all_vote_values_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); # total_votes >= dao_quorum # TODO: waiting on this opcode in zkas # # greater_than_or_equal(total_votes, dao_quorum) # # win_votes / total_votes >= approval_ratio_quot / approval_ratio_base # # The above is also equivalent to this: # # win_votes * approval_ratio_base >= total_votes * approval_ratio_quot # # TODO: waiting on this opcode in zkas # # lhs = base_mul(win_votes, approval_ratio_base); # rhs = base_mul(total_votes, approval_ratio_quot); # greater_than_or_equal(lhs, rhs); # #### # 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 }