Let be defined as in the section Bulla Commitments.

Let be defined as in the section Pallas and Vesta.


The DAO contains the main parameters that define DAO operation:

  • The proposer limit is the minimum number of governance tokens of type required to create a valid proposal on chain. Note this minimum can come from multiple token holders.
  • Quorum specifies the absolute minimum number of tokens required for before a proposal can be accepted.
  • The approval ratio is a tuple that specifies the minimum theshold of affirmative yes votes for a proposal to become accepted.
  • The public key serves a dual role for both encrypted notes, and as a key to authorize accepted proposals to be executed. This key may be shared widely with all DAO members or within a privileged group.

Define the DAO params where the approval ratio defines the equivalence class of fractions defined by .

/// DAOs are represented on chain as a commitment to this object
pub struct Dao {
    pub proposer_limit: u64,
    pub quorum: u64,
    pub approval_ratio_quot: u64,
    pub approval_ratio_base: u64,
    pub gov_token_id: TokenId,
    pub public_key: PublicKey,
    pub bulla_blind: BaseBlind,


Auth Calls

Let be defined as in Function IDs.

Let be defined as in BLAKE2b Hash Function.

Define . Each authorization call represents a child call made by the DAO. The auth data field is used by the child invoked contract to enforce additional invariants.

pub struct DaoAuthCall {
    pub contract_id: ContractId,
    pub function_code: u8,
    pub auth_data: Vec<u8>,

Define by which commits to a Vec<DaoAuthCall>.


Define the proposal params

pub struct DaoProposal {
    pub auth_calls: Vec<DaoAuthCall>,
    pub creation_day: u64,
    pub duration_days: u64,
    /// Arbitrary data provided by the user. We don't use this.
    pub user_data: pallas::Base,
    pub dao_bulla: DaoBulla,
    pub blind: BaseBlind,

Vote Nullifiers

Additionally for proposals, we keep track of nullifiers for each token weighted vote for or against a proposal.

Let be defined as in the section PoseidonHash Function.

Let be the coin params, and be the coin commitment as defined in Money Contract.

Let be a proposal bulla as in the section Proposal.

Define as follows:


Time limits on proposals are expressed in 4 hour windows. Since proofs cannot guarantee which block they get into, we therefore must modulo the block height a certain number which we use in the proofs.

const BLOCK_TIME: u64 = 90;
const SECS_IN_HOUR: u64 = 60 * 60;
const WINDOW_TIME_HR: u64 = 4;

/// Blockwindow from blockheight. Used for time limit on DAO proposals.
pub fn blockwindow(height: u64) -> u64 {
    let timestamp_secs = height * BLOCK_TIME;
    timestamp_secs / (WINDOW_TIME_HR * SECS_IN_HOUR)

which can be used like this

    let current_day = blockwindow(get_verifying_block_height());