constant "DaoVoteMain" {
	EcFixedPointShort VALUE_COMMIT_VALUE,
	EcFixedPoint VALUE_COMMIT_RANDOM,
}

contract "DaoVoteMain" {
    # 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,

    # Is the vote yes or no
    Base vote_option,
    Scalar yes_vote_blind,

    # Total amount of capital allocated to vote
    Base all_votes_value,
    Scalar all_votes_blind,

    # Check the inputs and this proof are for the same token
    Base gov_token_blind,
}

circuit "DaoVoteMain" {
    token_commit = poseidon_hash(gov_token_id, gov_token_blind);
	constrain_instance(token_commit);

    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);
    # TODO: we need to check the proposal isn't invalidated
    # that is expired or already executed.

    # normally we call this yes vote
	# Pedersen commitment for vote option
    yes_votes_value = base_mul(vote_option, all_votes_value);
	yes_votes_value_c = ec_mul_short(yes_votes_value, VALUE_COMMIT_VALUE);
	yes_votes_blind_c = ec_mul(yes_vote_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);

	# Pedersen commitment for vote value
	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);

    # Vote option should be 0 or 1
    bool_check(vote_option);
}


