Model

Let be defined as in the section Bulla Commitments.

Let be defined as in the section Pallas and Vesta.

DAO

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 {
    /// The minimum amount of governance tokens needed to open a proposal
    pub proposer_limit: u64,
    /// Minimal threshold of participating total tokens needed for a proposal to pass
    pub quorum: u64,
    /// The ratio of winning/total votes needed for a proposal to pass
    pub approval_ratio_quot: u64,
    pub approval_ratio_base: u64,
    /// DAO's governance token ID
    pub gov_token_id: TokenId,
    /// Public key of the DAO
    pub public_key: PublicKey,
    /// DAO bulla blind
    pub bulla_blind: BaseBlind,
}

Proposals

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>.

Proposal

Define the proposal params

pub struct DaoProposal {
    pub auth_calls: Vec<DaoAuthCall>,
    pub creation_blockwindow: u64,
    pub duration_blockwindows: 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:

Blockwindow

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 SECS_IN_HOUR: u64 = 60 * 60;
const WINDOW_TIME_HR: u64 = 4;

/// Blockwindow from block height and target time. Used for time limit on DAO proposals.
pub fn blockwindow(height: u32, target: u32) -> u64 {
    let timestamp_secs = (height * target) as u64;
    timestamp_secs / (WINDOW_TIME_HR * SECS_IN_HOUR)
}

which can be used like this

    let current_blockwindow =
        blockwindow(wasm::util::get_verifying_block_height()?, wasm::util::get_block_target()?);