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

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

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

	# Total amount of capital allocated to vote
	Base all_vote_value,
	Scalar all_vote_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 = poseidon_hash(
		proposal_dest_x,
		proposal_dest_y,
		proposal_amount,
		proposal_token_id,
		dao_bulla,
		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_vote_value = base_mul(vote_option, all_vote_value);
	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));

	# Pedersen commitment for vote value
	all_vote_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_c, all_vote_blind_c);
	constrain_instance(ec_get_x(all_vote_commit));
	constrain_instance(ec_get_y(all_vote_commit));

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