spec2: DAO model

This commit is contained in:
zero
2024-01-09 18:15:24 +01:00
committed by lunar-mining
parent a318bb3d76
commit fd177220e1
6 changed files with 92 additions and 10 deletions

View File

@@ -116,7 +116,7 @@
- [Contracts]()
- [DAO](spec2/contracts/dao/dao.md)
- [Concepts](spec2/contracts/dao/concepts.md)
- [State](spec2/contracts/dao/state.md)
- [Model](spec2/contracts/dao/model.md)
# P2P API Tutorial

View File

@@ -55,3 +55,9 @@ cannot call `db_get()`, but may call `db_set()`.
| `set_return_data` | Exec, Metadata | Used for returning data to the host |
| `get_slot` | Deploy, Exec, Metadata | Get the current slot |
## Function IDs
Let $𝔽ₚ$ be defined as in the section [Pallas and Vesta](crypto-schemes.md#pallas-and-vesta).
Functions can be specified using a tuple $\t{FuncId} := (𝔽ₚ, 𝔹)$.

View File

@@ -1,21 +1,69 @@
# State
# Model
Let $ℙₚ, 𝔽ₚ, \mathcal{X}, \mathcal{Y}$ be defined as in the section [Pallas and Vesta](../../crypto-schemes.md#pallas-and-vesta).
## DAO
Let $ℙₚ, 𝔽ₚ$ be defined as in the section [Pallas and Vesta](../../crypto-schemes.md#pallas-and-vesta).
The DAO contains the main parameters that define DAO operation:
* The proposer limit $L$ is the minimum number of governance tokens of type
$T$ required to create a valid proposal on chain. Note this minimum can
come from multiple token holders.
* Quorum $Q$ specifies the absolute minimum number of tokens required for
before a proposal can be accepted.
* The approval ratio $A^\%$ is a tuple that specifies the minimum theshold
of affirmative yes votes for a proposal to become accepted.
* The public key $PK$ 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
$$ \begin{aligned}
\t{Params}_\t{DAO}.\t{L} &∈ ℕ₆₄ \\
\t{Params}_\t{DAO}.\t{Q} &∈ ℕ₆₄ \\
\t{Params}_\t{DAO}.\t{R}^\% &∈ ℕ₆₄ × ℕ₆₄ \\
\t{Params}_\t{DAO}.\t{T} &∈ 𝔽ₚ \\
\t{Params}_\t{DAO}.\t{PK} &∈ ℙₚ
\t{Params}_\t{DAO}.L &∈ ℕ₆₄ \\
\t{Params}_\t{DAO}.Q &∈ ℕ₆₄ \\
\t{Params}_\t{DAO}.A^\% &∈ ℕ₆₄ × ℕ₆₄ \\
\t{Params}_\t{DAO}.T &∈ 𝔽ₚ \\
\t{Params}_\t{DAO}.PK &∈ ℙₚ
\end{aligned} $$
where the approval ratio $\t{R}^\% = (q, d)$ is defines the equivalence
where the approval ratio $\t{Approval}^\% = (q, d)$ defines the equivalence
class $[\frac{q}{d}]$ of fractions defined by $q₁d₂ = q₂d₁ ⟺ [\frac{q₁}{d₁}] \~ [\frac{q₂}{d₂}]$.
```rust
{{#include ../../../../../src/contract/dao/src/model.rs:dao}}
```
$$ \t{DAO2𝔽ₚ} : \t{Params}_\t{DAO} → 𝔽ₚ⁷ $$
$$ \t{DAO2𝔽ₚ}(p) = (\t{₆₄2𝔽ₚ}(p.L), \t{₆₄2𝔽ₚ}(p.Q), \t{₆₄2𝔽ₚ}(p.A^\%), p.T, \mathcal{X}(p.PK), \mathcal{Y}(p.PK)) $$
## Proposal
Let $\t{FuncId}$ be defined as in [Function IDs](../../concepts.md#function-ids).
Let $\t{BLAKE3}$ be defined as in [BLAKE3 Hash Function](../../crypto-schemes.md#blake3-hash-function).
Define $\t{AuthCall} = (\t{FuncId}, 𝔹^*)$. 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.
```rust
{{#include ../../../../../src/contract/dao/src/model.rs:dao-auth-call}}
```
Define $\t{Commit}_\t{Auth} : \t{AuthCall} → 𝔽ₚ$ by.
$$ \t{Commit}_\t{Auth}(c) = 𝔹³²2𝔽ₚ(\t{BLAKE3}(\t{Encode}(c))) $$
Define the proposal params
$$ \begin{aligned}
\t{Params}_\t{Proposal}.C &∈ \t{AuthCall}^* \\
\t{Params}_\t{Proposal}.T₀ &∈ ℕ₆₄ \\
\t{Params}_\t{Proposal}.D &∈ ℕ₆₄ \\
\t{Params}_\t{Proposal}.φ &∈ 𝔽ₚ \\
\t{Params}_\t{Proposal}.\t{DAO} &∈ \t{Bulla}(\t{DAO2𝔽ₚ}(\t{Params}_\t{DAO})) \\
\end{aligned} $$
```rust
{{#include ../../../../../src/contract/dao/src/model.rs:dao-proposal}}
```
## Vote Nullifiers

View File

@@ -56,3 +56,24 @@ Let $ℙᵥ$ be the group of points with $∞$ on $Eᵥ$.
Arithmetic is mainly done in circuits with $𝔽ₚ$ and $Eₚ$.
### Coordinate Extractor for Pallas
Let $ℙₚ, ∞, 𝔽ₚ$ be defined as [above](#pallas-and-vesta).
Define $\mathcal{X} : ℙₚ → 𝔽ₚ$ such that
$$ \mathcal{X}(∞_{Eₚ}) = 0 $$
$$ \mathcal{X}((x, y)) = x $$
$$ \mathcal{Y}(∞_{Eₚ}) = 0 $$
$$ \mathcal{Y}((x, y)) = y $$
**Note:** There is no $P = (0, y) ∈ Eₚ$ so $\mathcal{X}(P) = 0 ⟹ P = ∞$.
Likewise there is no $P = (x, 0) ∈ Eₚ$ so $\mathcal{Y}(P) = 0 ⟹ P = ∞$.
### Encoding and Decoding for $𝔽ₚ$
TODO: define $\t{Encode}_{𝔽ₚ} : 𝔽ₚ → 𝔹³²$.
## BLAKE3 Hash Function
BLAKE3 is defined by [CANW2021](https://raw.githubusercontent.com/BLAKE3-team/BLAKE3-specs/master/blake3.pdf).
$$ \t{BLAKE3}: 𝔹^* → 𝔹³² $$

View File

@@ -3,3 +3,6 @@
$$ denotes the non-negative integers. $ℕ₆₄$ denotes $$ restricted to the range
corresponding to `u64` in Rust of $[0, 2⁶⁴)$.
$𝔹$ denotes a single byte $[0, 2⁸)$ corresponding to `u8` in Rust.
We use $𝔹^*$ for an arbitrary sequence of bytes.

View File

@@ -31,9 +31,9 @@ use darkfi_serial::{Decodable, Encodable, SerialDecodable, SerialEncodable};
#[cfg(feature = "client")]
use darkfi_serial::async_trait;
#[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
// ANCHOR: dao
/// DAOs are represented on chain as a commitment to this object
#[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
pub struct Dao {
pub proposer_limit: u64,
pub quorum: u64,
@@ -104,11 +104,13 @@ darkfi_sdk::fp_to_bs58!(DaoBulla);
darkfi_sdk::ty_from_fp!(DaoBulla);
#[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
// ANCHOR: dao-auth-call
pub struct DaoAuthCall {
pub contract_id: pallas::Base,
pub function_code: u8,
pub auth_data: Vec<u8>,
}
// ANCHOR_END: dao-auth-call
pub trait VecAuthCallCommit {
fn commit(&self) -> pallas::Base;
@@ -126,6 +128,7 @@ impl VecAuthCallCommit for Vec<DaoAuthCall> {
}
#[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
// ANCHOR: dao-proposal
pub struct DaoProposal {
pub auth_calls: Vec<DaoAuthCall>,
pub creation_day: u64,
@@ -135,6 +138,7 @@ pub struct DaoProposal {
pub dao_bulla: DaoBulla,
pub blind: pallas::Base,
}
// ANCHOR_END: dao-proposal
impl DaoProposal {
pub fn to_bulla(&self) -> DaoProposalBulla {