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.
- Early exec quorum specifies the absolute minimum number of tokens required for before a proposal can be considered as strongly accepted.
- The approval ratio is a tuple that specifies the minimum theshold of affirmative yes votes for a proposal to become accepted.
- Notes public key controls who can view encrypted notes.
- Proposer public key controls who can mint proposals.
- Proposals public key controls who can view the proposals.
- Votes public key controls who can view votes.
- Executor public key controls who can execute proposals.
- Early executor public key controls who can execute proposals that are strongly accepted.
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,
/// Minimal threshold of participating total tokens needed for a proposal to
/// be considered as strongly supported, enabling early execution.
/// Must be greater or equal to normal quorum.
pub early_exec_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,
/// DAO notes decryption public key
pub notes_public_key: PublicKey,
/// DAO proposals creator public key
pub proposer_public_key: PublicKey,
/// DAO proposals viewer public key
pub proposals_public_key: PublicKey,
/// DAO votes viewer public key
pub votes_public_key: PublicKey,
/// DAO proposals executor public key
pub exec_public_key: PublicKey,
/// DAO strongly supported proposals executor public key
pub early_exec_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;
// Precalculating the const for better performance
// WINDOW_TIME = WINDOW_TIME_HR * SECS_IN_HOUR
const WINDOW_TIME: u64 = 14400;
/// 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 as u64) * (target as u64);
timestamp_secs / WINDOW_TIME
}
which can be used like this
let current_blockwindow =
blockwindow(wasm::util::get_verifying_block_height()?, wasm::util::get_block_target()?);