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

witness "DaoProposeMain" {
	# Proposers total number of governance tokens
	Base total_funds,
	Scalar total_funds_blind,

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

	# Proposal parameters
	Base proposal_dest_x,
	Base proposal_dest_y,
	Base proposal_amount,
	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,

	Uint32 dao_leaf_pos,
	MerklePath dao_path,
}

circuit "DaoProposeMain" {
	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,
	);

	dao_root = merkle_root(dao_leaf_pos, dao_path, dao_bulla);
	constrain_instance(dao_root);
	# Proves this DAO is valid

	proposal_bulla = poseidon_hash(
		proposal_dest_x,
		proposal_dest_y,
		proposal_amount,
		proposal_token_id,
		dao_bulla,
		proposal_blind,
	);
	constrain_instance(proposal_bulla);

	# Rangeproof check for proposal amount
	zero = witness_base(0);
	less_than_strict(zero, proposal_amount);

	# This is the main check
	# We check that dao_proposer_limit <= total_funds
	one = witness_base(1);
	total_funds_1 = base_add(total_funds, one);
	less_than_strict(dao_proposer_limit, total_funds_1);

	# Pedersen commitment for coin's value
	vcv = ec_mul_short(total_funds, VALUE_COMMIT_VALUE);
	vcr = ec_mul(total_funds_blind, VALUE_COMMIT_RANDOM);
	total_funds_commit = ec_add(vcv, vcr);
	constrain_instance(ec_get_x(total_funds_commit));
	constrain_instance(ec_get_y(total_funds_commit));
}
