dao-exec.zk 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. constant "DaoExec" {
  2. EcFixedPointShort VALUE_COMMIT_VALUE,
  3. EcFixedPoint VALUE_COMMIT_RANDOM,
  4. }
  5. contract "DaoExec" {
  6. # proposal params
  7. Base proposal_dest_x,
  8. Base proposal_dest_y,
  9. Base proposal_amount,
  10. Base proposal_serial,
  11. Base proposal_token_id,
  12. Base proposal_blind,
  13. # DAO params
  14. Base dao_proposer_limit,
  15. Base dao_quorum,
  16. Base dao_approval_ratio,
  17. Base gov_token_id,
  18. Base dao_public_x,
  19. Base dao_public_y,
  20. Base dao_bulla_blind,
  21. # votes
  22. Base yes_vote_values,
  23. Base all_vote_values,
  24. Scalar all_vote_blinds,
  25. Scalar all_vote_value_blinds,
  26. # outputs + inputs
  27. Base user_serial,
  28. Base user_coin_blind,
  29. Base dao_serial,
  30. Base dao_coin_blind,
  31. Base input_value,
  32. Scalar input_value_blind,
  33. # misc
  34. Base dao_spend_hook,
  35. Base user_spend_hook,
  36. Base user_data,
  37. }
  38. circuit "DaoExec" {
  39. dao_bulla = poseidon_hash(
  40. dao_proposer_limit,
  41. dao_quorum,
  42. dao_approval_ratio,
  43. gov_token_id,
  44. dao_public_x,
  45. dao_public_y,
  46. dao_bulla_blind,
  47. # @tmp-workaround
  48. dao_bulla_blind,
  49. );
  50. # Proposal bulla is valid means DAO bulla is also valid
  51. # because of dao-propose-main.zk, already checks that when
  52. # we first create the proposal. So it is redundant here.
  53. proposal_bulla = poseidon_hash(
  54. proposal_dest_x,
  55. proposal_dest_y,
  56. proposal_amount,
  57. proposal_serial,
  58. proposal_token_id,
  59. dao_bulla,
  60. proposal_blind,
  61. # @tmp-workaround
  62. proposal_blind,
  63. );
  64. constrain_instance(proposal_bulla);
  65. coin_0 = poseidon_hash(
  66. proposal_dest_x,
  67. proposal_dest_y,
  68. proposal_amount,
  69. proposal_token_id,
  70. proposal_serial,
  71. user_spend_hook,
  72. user_data,
  73. proposal_blind,
  74. );
  75. constrain_instance(coin_0);
  76. change = base_sub(input_value, proposal_amount);
  77. coin_1 = poseidon_hash(
  78. dao_public_x,
  79. dao_public_y,
  80. change,
  81. proposal_token_id,
  82. dao_serial,
  83. dao_spend_hook,
  84. proposal_bulla,
  85. dao_coin_blind,
  86. );
  87. constrain_instance(coin_1);
  88. # Create pedersen commits for win_votes, and total_votes
  89. # and make public
  90. yes_vote_values_c = ec_mul_short(yes_vote_values, VALUE_COMMIT_VALUE);
  91. all_vote_blinds_c = ec_mul(all_vote_blinds, VALUE_COMMIT_RANDOM);
  92. weighted_votes_commit = ec_add(yes_vote_values_c, all_vote_blinds_c);
  93. # get curve points and constrain
  94. weighted_votes_commit_x = ec_get_x(weighted_votes_commit);
  95. weighted_votes_commit_y = ec_get_y(weighted_votes_commit);
  96. constrain_instance(weighted_votes_commit_x);
  97. constrain_instance(weighted_votes_commit_y);
  98. all_vote_values_c = ec_mul_short(all_vote_values, VALUE_COMMIT_VALUE);
  99. all_vote_value_blinds_c = ec_mul(all_vote_value_blinds, VALUE_COMMIT_RANDOM);
  100. all_vote_values_commit = ec_add(all_vote_values_c, all_vote_value_blinds_c);
  101. # get curve points and constrain
  102. all_vote_values_commit_x = ec_get_x(all_vote_values_commit);
  103. all_vote_values_commit_y = ec_get_y(all_vote_values_commit);
  104. constrain_instance(all_vote_values_commit_x);
  105. constrain_instance(all_vote_values_commit_y);
  106. # Create pedersen commit for input_value and make public
  107. input_value_v = ec_mul_short(input_value, VALUE_COMMIT_VALUE);
  108. input_value_r = ec_mul(input_value_blind, VALUE_COMMIT_RANDOM);
  109. input_value_commit = ec_add(input_value_v, input_value_r);
  110. # get curve points and constrain
  111. input_value_x = ec_get_x(input_value_commit);
  112. input_value_y = ec_get_y(input_value_commit);
  113. constrain_instance(input_value_x);
  114. constrain_instance(input_value_y);
  115. constrain_instance(dao_spend_hook);
  116. constrain_instance(user_spend_hook);
  117. constrain_instance(user_data);
  118. # total_votes >= dao_quorum
  119. # TODO: waiting on this opcode in zkas
  120. #
  121. # greater_than_or_equal(total_votes, dao_quorum)
  122. #
  123. # win_votes / total_votes >= approval_ratio_quot / approval_ratio_base
  124. #
  125. # The above is also equivalent to this:
  126. #
  127. # win_votes * approval_ratio_base >= total_votes * approval_ratio_quot
  128. #
  129. # TODO: waiting on this opcode in zkas
  130. #
  131. # lhs = base_mul(win_votes, approval_ratio_base);
  132. # rhs = base_mul(total_votes, approval_ratio_quot);
  133. # greater_than_or_equal(lhs, rhs);
  134. #
  135. ####
  136. # Create coin 0
  137. # Create coin 1
  138. # Check values of coin 0 + coin 1 == input value
  139. # Check value of coin 0 == proposal_amount
  140. # Check public key matches too
  141. # Create the input value commit
  142. # Create the value commits
  143. # NOTE: there is a vulnerability here where someone can create the exec
  144. # transaction with a bad note so it cannot be decrypted by the receiver
  145. # TODO: research verifiable encryption inside ZK
  146. }