k = 13;
field = "pallas";

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

witness "DaoExec" {
    # Proposal parameters
    Base proposal_auth_calls_commit,
    Base proposal_current_day,
    Base proposal_duration_days,
    Base proposal_user_data,
    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,

    # Votes
    Base yes_vote_value,
    Base all_vote_value,
    Scalar yes_vote_blind,
    Scalar all_vote_blind,
}

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 being valid means DAO bulla is also valid because
    # dao-propose-main.zk already checks that when we first create the
    # proposal - so it is redundant to check DAO bulla exists here.
    proposal_bulla = poseidon_hash(
        proposal_auth_calls_commit,
        proposal_current_day,
        proposal_duration_days,
        proposal_user_data,
        dao_bulla,
        proposal_blind,
    );
    constrain_instance(proposal_bulla);
    constrain_instance(proposal_auth_calls_commit);

    # Create Pedersen commitments for win_votes and total_votes, and
    # constrain the commitments' coordinates.
    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));

    all_vote_value_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_value_c, all_vote_blind_c);
    constrain_instance(ec_get_x(all_vote_commit));
    constrain_instance(ec_get_y(all_vote_commit));

    # Check that dao_quorum is less than or equal to all_vote_value
    one = witness_base(1);
    all_vote_value_1 = base_add(all_vote_value, one);
    less_than_strict(dao_quorum, all_vote_value_1);

    # approval_ratio_quot / approval_ratio_base <= yes_vote / all_vote
    #
    # The above is also equivalent to this:
    #
    # all_vote * approval_ratio_quot <= yes_vote * approval_ratio_base
    lhs = base_mul(all_vote_value, dao_approval_ratio_quot);
    rhs = base_mul(yes_vote_value, dao_approval_ratio_base);
    rhs_1 = base_add(rhs, one);
    less_than_strict(lhs, rhs_1);
}

