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, proposal_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 }