Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Algorand xGov Beta

This document describes the architecture of the xGov process (Beta).

Specifically, the architecture aims to solve the following main requirement:

The xGov process is a trustless voting system to manage grant proposals funding and polls for the Algorand ecosystem.

The design takes a step towards this end goal, which is a fully decentralized application relying uniquely on a front-end and the Algorand Virtual Machine (AVM).

The current design minimizes the trust model and the off-chain footprint to a few operations, carried out by a back-end controlled by the Algorand Foundation, which could be pushed on the AVM in future iterations.

It is worth noting that the residual trusted off-chain operations are fully accountable on the Algorand public Ledger.

Motivation

The old xGov process (Alpha) has shown some weaknesses concerning the incentive alignment, the gamification risks of the voting system, and low-quality proposals.

Moreover, the old grant proposal submission and funding mechanism were based on a per-quarter schedule, making the whole process slow and inflexible.

Therefore, a more robust process with a continuous stream of grant proposals, votes, and funding is desirable.

Finally, given the shift of the Algorand protocol towards consensus incentivization, the xGov (Beta) voting power will be based on active consensus participation instead of ALGO locking periods (Alpha).

Architecture Overview

The xGov Architecture consists of the following components:

COMPONENTIMPLEMENTATION
xGov PortalFront-End
xGov RegistryAlgorand Application (Factory)
xGov TreasuryAlgorand Application Account
xGov ManagerAlgorand Address
xGov Committee ManagerAlgorand Address
xGov DaemonAlgorand Address, Back-End + DB
xGov CouncilAlgorand Address
xGov PayorAlgorand Address
xGov SubscriberAlgorand Address
xGovAlgorand Address + Box
Managed SubscriberAlgorand Address
xGov (Un)Subscription RequestBox
xGov CommitteeJSON (ARC-86)
ProposerAlgorand Address + Box
KYC ProviderAlgorand Address
ProposalAlgorand Application (Child)
Proposal MetadataBox
Proposal EscrowAlgorand Application Account
Proposal VotersBoxes

xGov Architecture

The on-chain components are used for:

  1. On/off-boarding xGovs;
  2. Whitelisting Proposers (KYC required);
  3. Creating and submitting Proposals;
  4. Binding xGov Committees to Proposals;
  5. Voting on Proposals;
  6. Managing the xGov Treasury and funding approved Proposals.

The off-chain components are used for:

  1. Selecting xGov Committees periodically and verifiably, according to ARC-86;
  2. Intermediate Proposers’ KYC;
  3. Intermediate on/off-boarding of xGovs that cannot execute a self-subscription or self-unsubscription.

Reading Guidelines

The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document, are to be interpreted as described in RFC 2119.

The data types (like uint64, byte[], etc.) in this document are to be interpreted as specified in ARC-4.

📝 NOTE

Notes like this are non-normative

📎 EXAMPLE

Sections like this are examples aiming to clarify the specifications.

Sections like this are either pseudo-code or data structures.

Math Symbols

For a correct rendering of mathematical symbols and formulas, it is recommended to right-click on the symbol below, and select Math Settings -> Math Renderer -> Common HTML from the drop-down menu.

$$ \mathcal{C} $$

Once MathJax rendering is correctly set, you should see a calligraphic “C”.

xGov Registry

The xGov Registry is the orchestrator of the xGov process. It is used to:

The xGov Registry is implemented as an Application, deployed by the original xGov Manager.

Roles

xGov Manager

The xGov Manager is an Algorand Address controlled by the Algorand Foundation.

It represents the root of trust for the xGov process.

RBAC

The xGov Manager MAY rotate itself.

The xGov Manager MUST provide and MAY update the xGov Committee Manager Address.

The xGov Manager MUST provide and MAY update the xGov Daemon Address.

The xGov Manager MUST provide and MAY update the xGov Council Address.

The xGov Manager MUST provide and MAY update the xGov Payor.

The xGov Manager MUST provide and MAY update the xGov Subscriber Address.

The xGov Manager MUST provide and MAY update the KYC Provider Address.

Configuration and Updates

The xGov Manager MAY pause the xGov Registry.

The xGov Manager MAY pause the creation of new Proposals.

The xGov Manager MAY update the xGov Registry anytime.

The xGov Manager MAY reconfigure the parameters of the xGov Registry.

Treasury Management

The xGov Manager MAY execute withdrawals of outstanding funds from the xGov Treasury.

xGov Committee Manager

The xGov Committee Manager is an Algorand Address controlled by the Algorand Foundation.

The xGov Committee Manager SHALL declare the xGov Committee currently in charge on the xGov Registry.

xGov Daemon

The xGov Daemon is an Algorand Address controlled by the Algorand Foundation (back-end).

The xGov Daemon SHALL assign the xGov Committee currently in charge (voters and their voting power) to open Proposals.

The xGov Daemon SHOULD delete absentees (voters) after Proposals scrutiny.

xGov Council

The xGov Council is an Algorand Address representing a group of elected Councilors.

The xGov Council MUST have an odd number of Councilors.

The xGov Council MUST review approved Proposals (see Proposal review section).

The xGov Council MAY apply a veto against approved Proposals according to the terms and conditions of the xGov process.

The xGov Council majority vote is REQUIRED to apply a veto against approved proposals.

xGov Payor

The xGov Payor is an Algorand Address controlled by the Algorand Foundation.

The xGov Payor MAY disburse the requested funds for approved and reviewed Proposals if there are enough funds in the xGov Treasury.

xGov Subscriber

The xGov Subscriber is an Algorand Address controlled by the Algorand Foundation.

The xGov Subscriber MAY onboard or offboard xGovs who cannot execute a self-subscription or self-unsubscription (e.g., due to contract immutability or other restrictions).

Treasury

The xGov Treasury is an Algorand Address controlled by the xGov Registry.

Treasury Inflows

FLOWFROMTOAMOUNTMETHODCONDITION
Deposit Governance FundsAnyonexGov TreasuryAnydeposit_funds
xGov SubscriptionAnyonexGov TreasuryxGov Feesubscribe_xgov
xGov Subscription RequestAnyonexGov TreasuryxGov Feerequest_subscribe_xgov
xGov Unsubscription RequestAnyonexGov TreasuryxGov Feerequest_unsubscribe_xgov
Proposer SubscriptionAnyonexGov TreasuryProposer Feesubscribe_proposer
Open ProposalAnyonexGov TreasuryOpen Proposal Feeopen_proposal
Slash Proposal CommitmentProposal EscrowxGov TreasuryProposal Locked Depositreview (on Proposal)Veto is applied (block=True)

Treasury Outflows

FLOWFROMTOAMOUNTMETHODCONDITION
Open ProposalxGov TreasuryProposal EscrowPartial Proposal Feeopen_proposal
Pay ProposalxGov TreasuryProposerRequested Amountpay_grant_proposalProposal is approved
Withdraw Governance FundsxGov TreasuryxGov ManagerUp to available Governance Fundswithdraw_funds
Withdraw Outstanding BalancexGov TreasuryxGov ManagerOutstanding balance, excluding MBR and Governance Fundswithdraw_balance

📝 NOTE

Partial Open Proposal Fees are equal to the Open Proposal Fee discounted by the Proposal Application MBR.

Treasury MBRs

  • Treasury Application Account;

  • xGov Boxes;

  • Proposer Boxes;

  • Created Proposal Applications.

xGovs

An xGov MUST have an Algorand Address (\( a \)).

An xGov MUST provide a Voting Address.

It is RECOMMENDED to provide a Voting Address different from the xGov Address, to facilitate voting operation on behalf of the xGov Address (supposed to be secure and less accessible).

The xGov Address and the current Voting Address MAY update the Voting Address.

The xGov Address MUST subscribe on (acknowledge) the xGov Registry, to acquire the xGov status.

The xGov status is defined as the pair \( (a, h) \), where:

  • \( a \) is the xGov Address;
  • \( h \) is the block at which the xGov Address subscribed.

The xGov Address MAY unsubscribe from the xGov Registry, losing the xGov status.

📝 NOTE

xGov Address can be associated with any Account type. This ensures the compatibility and inclusivity of xGov participation (direct or delegated).

Subscription

The xGov Registry provides two xGov (un)subscription procedures:

  • Self-Subscription: the xGov Address MUST call the xGov Registry.

  • Managed-Subscription: the ownership of the xGov App Address is verified off-chain, by the Algorand Foundation, according to a pre-defined trust model. The Managed-Onboarding/Offboarding is executed in two steps:

    1. Users issue a (Un)Subscription Request to (un)subscribe, declaring the xGov App Address, the Application Owner Address, and a Relation Type (enumerative that identifies a pre-defined trust model).

    2. The Algorand Foundation verifies the declared and accountable xGov/Owner Addresses relationship off-chain (based on the Relation Type) and eventually approves it.

📝 NOTE

For further details about existing and new Relation Types, refer to the Relation Types section.

An xGov Fee MUST be paid to the xGov Treasury for the subscription or subscription request or unsubscription request.

📝 NOTE

The xGov Manager MAY update the xGov Fee.

The xGov Fee has the following scope:

  1. Minimal deterrent for Sybil attacks;

  2. Covering the xGov Box MBR (see below).

xGov Box

An xGov is associated with a Box on the xGov Registry, called xGov Box.

xGov Box ID is equal to: [X||<xgov address>], where X is a domain separation prefix and || denotes concatenation.

An xGov Box has the following ABI schema:

{
    "voting_addr": "address",
    "voted_proposals": "uint64",
    "last_vote_timestamp": "uint64",
    "subscription_round": "uint64"
}

The xGov Fee MUST NOT be lower than the xGov Box MBR.

xGov Self-Subscription

The xGov Fee MUST be paid to the xGov Treasury upon xGov Box creation.

The xGov Fee MAY NOT be paid by the xGov Address.

The Voting Address declared on subscription MUST BE assigned to the xGov Box.

xGov Managed-Subscription

An xGov (Un)Subscription Request is associated with a Box on the xGov Registry, called xGov (Un)Subscription Request Box.

The xGov Fee MUST be paid to the xGov Treasury upon xGov (Un)Subscription Request Box creation.

The xGov Fee MAY NOT be paid by the xGov Address.

xGov (Un)Subscription Request Box ID is equal to: [<d>||<counter>], where <d> is a domain separation prefix which is either r for subscription requests or ru for unsubscription request, <counter> is a global counter for pending requests, and || denotes concatenation.

An xGov (Un)Subscription Request Box has the following ABI schema:

{
    "xgov_addr": "address",
    "owner_addr": "address",
    "relation_type": "uint64"
}

The xGov (Un)Subscription Request MUST be performed by the Owner Address.

The xGov Fee MUST NOT be lower than the xGov (Un)Subscribe Request Box MBR.

If the Algorand Foundation approves the subscription request:

  1. The xGov Subscription Request Box MUST be destroyed;

  2. An xGov Box MUST be created using the xGov Address declared on the subscription request.

  3. The Owner Address declared on the subscription request MUST be assigned to the Voting Address in the created xGov Box.

  4. The subscription round MUST be set to the current round number in the created xGov Box.

If the Algorand Foundation approves the unsubscription request:

  1. The xGov Unsubscription Request Box MUST be destroyed;

  2. The xGov Box of the xGov address MUST be destroyed.

Relation Types

A Relation Type identifies the trust model and the off-chain verification process of the xGov App Address ownership for a Managed-Subscription.

New Relation Type Request

A request for a new Relation Type SHALL be submitted by the Application Creator opening a new Relation Type Request issue.

A Relation Type MUST be approved by the Algorand Foundation.

Available Relation Type

The following enumerative relation_type (uint64) are currently available:

RELATION TYPEENUM
Réti Pooling1
Compx LST2

Relation Type 1: Réti Pooling

Réti Validators are created by an immutable factory contract.

A Validator is uniquely owned by an immutable Owner Address.

Each Validator may control several Staking Pools, which participate in Algorand consensus.

To request a Managed Subscription for a Réti Staking Pool:

  • The relation_type MUST be set to 1;
  • The owner_addr MUST be set to the Validator Owner Address;
  • The xgov_addr MUST be set to the Staking Pool Address.

Relation Type 2: Compx LST

TBD

$$ \newcommand {\abs}[1] {\lvert #1 \rvert} \newcommand \A {\mathcal{A}} \newcommand \N {\mathbb{N}} \newcommand \Comm {\mathsf{Comm}} \newcommand \Addr {\mathrm{Addr}} \newcommand \Members {\mathrm{Members}} \newcommand \Votes {\mathrm{Votes}} $$

xGov Committee

xGov Committees are responsible for voting on Proposals.

The formalization of xGov Committees and their voting power, as defined by ARC-0086, is provided below.

Preliminaries

Let

  • \( \A \) be the (finite) set of Algorand addresses;
  • \( \N \) be the set of non–negative integers;
  • \( g \) be the network Genesis Hash;
  • \( R \in \N \) be the Application ID of the xGov Registry;
  • \( B_c \in \N \) be the block at which the xGov Registry was created.

Governance Period

A governance period is a pair \( (B_i, B_f) \in \N^2 \) such that

$$ \begin{align} B_i &\equiv 0 \pmod{10^6}, \\ B_f &\equiv 0 \pmod{10^6}, \\ B_f &> B_c, \\ B_f &> B_i. \end{align} $$

And is intended as a range of blocks \( [B_i; B_f) \) (\( B_i \) included, \( B_f \) excluded).

\( B_i < B_c \) is valid and denotes a period across the xGov Registry creation.

xGovs and Voting Power

An xGov is an address \( a \in \A \) that has acknowledged the xGov Registry on block \( h \) and is therefore eligible to acquire voting power.

The xGov acknowledgement is defined by the pair \( (a, h) \) (represented on the xGov Registry as an xGov Box).

If xGovs unsubscribe, the xGov acknowledgement of their address \( a \) is lost and the pair \( (a, h) \) is removed from the xGov Registry state.

For a governance period \( (B_i, B_f) \), an address \( a \) is an eligible xGov in \( [B_c; B_f) \) if and only if there exists a block height \( k \) with \( B_c ≤ k < B_f \) such that the xGov Registry state at height \( k \) contains \( (a, h) \) for some \( h ≤ k \).

Once the xGov Registry has recorded an acknowledgement \( (a, h) \) with \( h ≥ B_c \), the address \( a \) is considered an eligible xGov for every governance period \( (B_i, B_f) \) such that \( h \in [B_c; B_f) \); in particular, it is not necessary to re-acknowledge the xGov Registry for subsequent governance periods.

For a fixed governance period \( (B_i, B_f) \), the voting power of an eligible xGov \( (a, h) \) in that governance period is the integer

$$ w((a, h); B_i, B_f) \in \N, $$

defined as the number of blocks proposed by an eligible address \( a \) in the governance period \( [B_i; B_f) \)1.

If an xGov a has acknowledged the xGov Registry at some \( h \in [B_c; B_f) \) and has proposed one or more blocks in \( [B_i; B_f) \), then all such proposals in \( [B_i; B_f) \) contributes to its voting power, including those that occurred before \( h \).

Definition of xGov Committee

Fix an xGov Registry \( (g, R, B_c) \) and a governance period \( (B_i, B_f) \) as above.

An xGov Committee for \( (g, R, B_c, B_i, B_f) \) is a finite set

$$ C \subseteq \A \times \N_{>0}, $$

of address–weight pairs \( (a, v) \) such that:

$$ \begin{align} &\textbf{eligibility} && \forall (a, v) \in C, a \text{ is an eligible xGov in } [B_c; B_f), \\ &\textbf{voting power} && \forall (a, v) \in C, v = w(a; B_i, B_f), \\ &\textbf{uniqueness} && (a_1, v_1), (a_2, v_2) \in C \text{ and } a_1 = a_2 \Rightarrow v_1 = v_2. \end{align} $$

The corresponding xGov Committee object is the tuple

$$ \Comm := (g, R, B_c, B_i, B_f, C). $$

For convenience, we write

$$ \Addr(C) := \{ a \in \A \mid \exists v>0, (a, v) \in C \} $$

for the set of xGov Committee members (addresses) induced by \( C \).

xGov Committee Members

The number of xGov Committee members (or cardinality of the xGov Committee) is defined as

$$ \Members(\Comm) := \abs{\Addr(C)} = \abs{C}. $$

This value corresponds to the totalMembers field in the ARC-86 canonical JSON representation of the xGov Committee.

xGov Committee Voting Power

The voting power function of the xGov Committee is the map

$$ v_C : \Addr(C) \to \N_{>0}, \qquad v_C(a) := v \text{ such that } (a, v) \in C. $$

The total committee voting power is

$$ \Votes(\Comm) := \sum_{(a, v) \in C} v = \sum_{a \in \Addr(C)} v_C(a). $$

This value corresponds to the totalVotes field in the ARC-86 canonical JSON representation of the xGov Committee.

Optionally, the relative vote of a member \( a \in \Addr(C) \) is

$$ \mathrm{share}_C(a) := \frac{v_C(a)}{\Votes(\Comm)}, $$

whenever \( \Votes(\Comm) > 0 \).

xGov Committee ID

An xGov Committee is identified by the Committee ID, as defined in ARC-86 canonical JSON representation.

Selection

The xGov Committee selection and the assignment of their voting power is performed by the Algorand Foundation.

Declaration

The xGov Committee Manager SHALL declare on the xGov Registry:

  • The current Committee ID;

  • The current xGov Committee Members;

  • The current xGov Committee Voting Power.

Assignment to Proposal

The xGov Daemon SHALL assign the current xGov Committee to Proposals upon creation (see Proposal Creation section).



  1. If \( a \) is not eligible as an xGov in \( [B_c; B_f) \), its voting power is implicitly taken to be zero, and it is not included in the xGov Committee.

Proposers

A Proposer MUST have an Algorand Address.

KYC

A Proposer MUST have a valid or invalid KYC status, defined by a KYC process.

The Proposer KYC status MUST have an expiration date.

The KYC Provider SHALL update the Proposer KYC status after the KYC process.

The KYC Provider MAY update the Proposer KYC during its validity.

The Proposer KYC status MUST be valid and not expired to receive Proposal funding.

Subscription

A Proposer Fee MUST be paid to the xGov Treasury for the subscription.

📝 NOTE

The xGov Manager MAY modify the Proposer Fee.

The Proposer Fee has the following scope:

  1. Covering the KYC process costs;

  2. Covering the Proposer Box MBR (see below).

Proposer Box

A Proposer is associated with a Box on the xGov Registry, called Proposer Box.

The Proposer Fee MUST be paid to the xGov Treasury upon creating the Proposer Box.

The Proposer SHOULD pay the Proposer Fee.

Proposer Box ID is equal to [P||<proposer address>], where P is a domain separation prefix and || denotes concatenation.

A Proposer Box has the following ABI schema:

{
    "active_proposal": "bool",
    "kyc_status": "bool",
    "kyc_expiring": "uint64"
}

The Proposer Fee MUST NOT be lower than the Proposer Box MBR.

Proposal

A Proposal is a funding request from the xGov Treasury, which is approved or rejected by the xGov Committee vote and reviewed by the xGov Council.

A Proposal consists of:

  • Proposal Application, with REQUIRED data;

  • Proposal metadata.

The Proposal Application is created and funded by the xGov Registry App (see Creation section) through the Open Proposal Fee.

Lifecycle

The Proposal life cycle has four phases:

  1. Creation;

  2. Discussion & Submission;

  3. Vote & Review;

  4. Finalization.

Funding Types

The Proposals have two different funding types:

  1. Retroactive

    • Claim: “I have done X, which has benefited the Algorand ecosystem because of Y metrics, I would like to receive Z as compensation for the work”.

    • Positive outcome: funding is immediately disbursed if the Proposal is approved by the xGov Committee vote, and the xGov Council does not apply a veto according to the terms and conditions.

  2. Proactive (NOT AVAILABLE YET)

    • Claim: “I want to do X, it has the potential Y for the Algorand ecosystem, I would like to receive Z staggered behind these milestones”.

    • Positive outcome: funding will be disbursed if the Proposal is approved by the xGov Committee vote, after milestone reviews from the xGov Council, and if the xGov Council does not apply a veto according to terms and conditions.

Requested Amount

The Proposal’s requested amount (\( A \)) MUST be bounded as follows:

SmallMediumLarge
Requested Amount\( A_\min ≤ A < A_{S,\max} \)\( A_{S,\max} ≤ A < A_{M,\max} \)\( A_{M,\max} ≤ A ≤ A_{L,\max} \)

Funding Sizes

Proposals have different funding sizes based on the requested amount of funds.

The funding size defines the timing of the Proposal lifecycle.

SmallMediumLarge
Discussion time\( D_S \)\( D_M \)\( D_L \)
Voting time (after discussion)\( V_S \)\( V_M \)\( V_L \)

📝 NOTE

Refer to the Proposal implementation configuration for the Proposal lifecycle timing values.

Quorum Thresholds

$$ \newcommand \Comm {\mathsf{Comm}} \newcommand \Members {\mathrm{Members}} \newcommand \Votes {\mathrm{Votes}} $$

Proposals have two quorum thresholds based on the requested amount of funds.

The quorum thresholds define the minimum number of (regular and weighted) votes required to approve a Proposal:

  • \( T(A) \), Democratic Quorum Threshold (1 xGov, 1 Vote);

  • \( T_w(A) \), Weighted Quorum Threshold (1 xGov, w Votes).

Given the xGov Committee assigned to the Proposal, with its members and voting power (see the xGov Committee definition), the quorum thresholds are defined as follows:

  • \( T(A) = \Members(\Comm) \times Q(A) \), with

$$ Q(A) = Q_\min + \frac{\Delta Q}{\Delta A} \times (A - A_\min) $$

  • \( T_w(A) = \Votes(\Comm) \times Q_w(A) \), with

$$ Q_w(A) = Q_{w,\min} + \frac{\Delta Q_w}{\Delta A} \times (A - A_\min) $$

Where:

  • \( Q_\min = Q(A_\min) \)
  • \( Q_\max = Q(A_{L,\max}) \)
  • \( Q_{w,\min} = Q_w(A_\min) \)
  • \( Q_{w,\max} = Q_w(A_{L,\max}) \)
  • \( \Delta Q = Q_\max - Q_\min \)
  • \( \Delta Q_w = Q_{w,\max} - Q_{w,\min} \)
  • \( \Delta A = A_{L,\max} - A_\min \)

Proposal Quorum

📝 NOTE

Refer to the Proposal implementation configuration for the minimum and maximum quorum values.

Metadata

The Proposal Metadata byte length MUST NOT exceed 30 kB.

The Proposal Metadata is stored in a Box on the Proposal Application, called Metadata Box.

The Proposal Metadata Box ID is equal to metadata.

The Proposal Metadata Box body has no ABI schema (raw bytes).

Finite-State Machine

A Proposal SHALL be in one of the following enumerated statuses:

StatusEnumDescription
EMPTY0The xGov Registry creates an empty proposal, the Proposer SHOULD open a draft (or it SHOULD be finalized for staleness)
DRAFT10The Proposer MAY submit (with updated metadata) or drop the draft (or it SHOULD be finalized for staleness)
SUBMITTED20The xGov Daemon SHALL assign the xGov Committee to the submitted proposal, which is then opened to vote
VOTING25The xGov Committee MAY vote the proposal until the voting session expires
APPROVED30The outcome of the vote scrutiny (quorum and majority) approved the proposal, the absentees SHALL be deleted, the xGov Council SHALL review it
REJECTED40The outcome of the vote scrutiny (quorum and majority) rejected the proposal, the absentees SHALL be deleted, it SHOULD be finalized
REVIEWED45The xGov Council positively reviewed the approved proposal (T&C, etc.), the locked amount MUST be returned to the Proposer, the xGov Payor MAY disburse the requested amount
BLOCKED60The xGov Council blocked the approved proposal with veto, it SHOULD be finalized, the locked amount MUST be slashed, the requested amount MUST NOT be paid
FUNDED50The xGov Payor paid the requested amount, it SHOULD be finalized
FINALIZEDboolThe proposal life cycle is terminated and MAY be deleted

📝 NOTE

The FINALIZED boolean flag is not an enumerated state, since it can be superposed to several states (i.e., EMPTY, DRAFT, REJECTED, BLOCKED, and FUNDED). Example: a Proposal can be FUNDED and FINALIZED.

Proposal Finite-State Machine

Escrow

The Proposal Escrow is an Address controlled by the Proposal Application.

Escrow Inflows

FLOWFROMTOAMOUNTMETHODCONDITION
Open ProposalxGov TreasuryProposal EscrowPartial Proposal Feeopen_proposal (on xGov Registry)
Deposit Proposal CommitmentProposerProposal EscrowProposal Locked Depositopen

Escrow Outflows

FLOWFROMTOAMOUNTMETHODCONDITION
Operations FundingProposal EscrowxGov Daemon% of Open Proposal Feesubmit
Return Proposal CommitmentProposal EscrowProposerProposal Locked Depositdrop
Return Proposal CommitmentProposal EscrowProposerProposal Locked DepositscrutinyProposal is rejected
Return Proposal CommitmentProposal EscrowProposerProposal Locked DepositfinalizeProposal is dropped for staleness
Return Proposal CommitmentProposal EscrowProposerProposal Locked DepositreviewVeto is not applied (block=False)
Slash Proposal CommitmentProposal EscrowxGov TreasuryProposal Locked DepositreviewVeto is applied (block=True)
Claim Voters MBRProposal EscrowxGov TreasuryVoters Box MBRfinalize
Close Out ProposalProposal EscrowxGov TreasuryMetadata Box MBR + App Accountdelete

Escrow MBRs

  • Proposal Application Account

  • Metadata Box

  • xGov Committee Voters Boxes

Creation

Proposers can create a Proposal at any time.

The Proposer MUST provide the following REQUIRED data to open a Proposal:

  • Title: a short name for the Proposal;

  • Focus: an enumerative focus area (e.g., Wallets, SDKs, etc.);

  • Funding Type: enumerative for Retroactive or Proactive (currently just Retroactive);

  • Requested Amount (in 𝜇ALGO).

A Proposer MUST NOT have more than one active proposal at any time.

The Proposer creates a Proposal Application from the xGov Registry.

Upon Proposal creation, an Open Proposal Fee MUST be paid to the xGov Treasury.

The Open Proposal Fee MUST NOT be lower than the sum of:

  • Proposal Application MBR;

  • Proposal Escrow Account MBR;

  • Full Metadata Box MBR;

  • Daemon Operations Funding.

The Proposal Application MBR is deducted from the Open Proposal Fee; the remainder MUST be entirely transferred to the Proposal Escrow.

📝 NOTE

The xGov Manager MAY update the Proposal Fee.

The remainder of the Open Proposal Fee MUST cover the MBR of all the Boxes required by the xGov Committee assigned to the Proposal upon opening.

📎 EXAMPLE

Given a Proposer Voter Box size, the Open Proposal Fee amount SHOULD be proportional to the xGov Committee size. The Voter Box MBR is roughly \( 0.02 \) ALGO. Example: an xGov Committee of \( 500 \) voters requires roughly \( 10 \) ALGO of MBR to the Proposal Application.

The Proposer SHOULD pay the Open Proposal Fee.

The Open Proposal Fee has the following scope:

  1. Anti-spam measure;

  2. Covering Proposal Escrow Account MBR;

  3. Covering Proposal Metadata Box MBR;

  4. Covering xGov Committee Boxes MBR (introduced later).

  5. Covering xGov Daemon operation fees for the Proposal.

Upon opening the Proposal Draft, the Proposer MUST lock in the Proposal Escrow a percentage of the requested funding amount as a commitment.

📝 NOTE

The xGov Manager MAY update the percentage of the requested funding amount to commit.

The locked amount SHALL be either:

  • Returned to the Proposer when the Proposal is:

    • Reviewed and not blocked by veto by the xGov Council or Rejected by voting;
    • Dropped by the Proposer before submission.
  • Slashed if the Proposal is blocked with a veto by the xGov Council.

Upon proposal opening, the xGov Committee ID, total members, and total voting power MUST be fetched from the xGov Registry and assigned to the Proposal.

The xGov Daemon MAY finalize the Empty Proposal if it becomes stale (the Proposer does not open a Draft).

Discussion

The Proposer MAY update the Proposal Metadata during the discussion phase.

The Proposer SHALL NOT change the Proposal REQUIRED data (e.g., the requested amount) during the discussion phase.

To change the Proposal REQUIRED data, the Proposer MUST drop the Proposal Draft and open a new one.

Submission

The Proposer SHALL submit the Draft Proposal after the minimum discussion period (depending on the Proposal funding size).

The xGov Daemon MAY finalize the Draft Proposal if it becomes stale (the Proposer does not submit the Draft).

The Proposal Metadata SHOULD be submitted from the xGov Portal (front-end).

The Proposal MUST NOT be submitted without Metadata.

Upon proposal submission, a percentage of the Open Proposal Fee SHALL be transferred from the Proposal Escrow to the xGov Daemon to cover the operation fees.

📝 NOTE

The xGov Manager MAY update the percentage of the Open Proposal Fee transferred to the xGov Daemon.

Vote Distribution

$$ \newcommand \Comm {\mathsf{Comm}} \newcommand \Members {\mathrm{Members}} \newcommand \Votes {\mathrm{Votes}} $$

The xGov Daemon SHALL distribute the votes to the xGov Committee (\( \Comm \)) assigned to the Proposal.

The distributed votes MUST be equal to the xGov Committee Voting Power (\( \Votes(\Comm) \)) (see xGov Committee section).

The number of voters who received votes MUST be equal to the xGov Committee Members (\( \Members(\Comm) \)) (see xGov Committee section).

The Proposal status MUST be set to Voting once the xGov Committee is completely assigned.

Voters

The xGov Committee Voters are represented by a set of Boxes on the Proposal Application (one box per xGov Committee Member), called the Voter Box.

The xGov Daemon SHALL create all the Voter Boxes once the Proposal is Submitted.

Voter Box MBR MUST be covered by the Partial Open Proposal Fee.

Voter Box ID is equal to [V||<xgov address>], where V is a domain separation prefix, <xgov address> is the same as used by the xGov upon subscription, and || denotes concatenation.

A Voter Box has the following ABI schema:

{
    "votes": "unit32"
}

Vote Opening

The Submitted Proposal MUST be promoted to Voting once the xGov Committee has been completely assigned.

The duration of the voting session depends on the Proposal funding sizes.

The Voting Proposal MUST stay open until either:

  • All the xGov Committee members have voted, or

  • The voting duration expires.

Votes

xGovs vote MUST BE either “Approve”, “Reject”, or “Null”.

xGovs MAY abstain from voting.

xGovs SHALL vote once per Proposal: the allocation of “Approve”, “Reject”, and “Null” votes MUST be simultaneous.

Vote usage MAY be partial. Unused votes are default “Null”.

The sum of “Approve”, “Reject”, and “Null” votes of each xGov MUST equal to the xGov voting power.

Vote SHALL NOT be modified.

📎 EXAMPLE

Pooled Vote Example: Let’s have an xGov Staking Pool with N votes. The Pool SHOULD collect poolers’ opinions before expressing the Pool vote accordingly. Once the Pool is ready to vote, the allocation of N votes among “Approve”, “Reject”, or “Null” is simultaneous and can no longer be modified.

Scrutiny

A Submitted Proposal is Approved if and only if all the following conditions hold:

  • A democratic quorum of all xGov Committee (one xGov, one vote) is reached. “Null” votes affect this quorum.

  • A weighted quorum of all xGov Committee voting power is reached. “Null” votes affect this quorum.

  • The relative majority of “Approve” over “Reject” votes is reached. “Null” votes do not affect the relative majority.

And it is Rejected otherwise.

The Commitment Lock MUST be returned to the Proposer if the Proposal is Rejected.

The xGov Daemon SHALL delete Voter Boxes of absentees xGovs.

Review

All Voter Box MUST be deleted before reviewing the Proposal.

The xGov Council MUST review Approved Proposals.

The xGov Council MAY apply a veto to an Approved Proposal.

An Approved Proposal is considered either:

  • Blocked, if the veto is applied;

  • Reviewed, if the veto is not applied.

In case of a Blocked Proposal:

  • The requested amount MUST NOT be paid.

  • The Commitment Lock MUST be transferred (slashed) from the Proposal Escrow to the xGov Treasury.

In case of a Reviewed Proposal:

  • The Commitment Lock MUST be returned from the Proposal Escrow to the Proposer.

Finalization

Payment

The xGov Payor MAY pay a Reviewed Proposal and promote it to Funded.

If the Proposal is Funded:

  • The requested amount MUST BE transferred from the xGov Treasury to its Proposer.

Finalize

The xGov Daemon SHOULD finalize:

  • Empty and Draft Proposals, after a stale period,

  • Funded, Rejected, or Blocked Proposals.

If a Draft Proposal is finalized, the Commitment Lock MUST be returned to the Proposer.

Outstanding balance of the Proposal Escrow MUST be returned to the xGov Treasury.

Delete

The xGov Manager MAY delete Finalized Proposals.

The Proposal Metadata MUST be deleted before deletion (Empty Proposals are an exception).

Proposal Escrow MUST be closed to the xGov Treasury before deletion.

Events

The xGov Architecture provides the following classes of ARC-28 events:

Clients can subscribe to these ARC-28 events using the AlgoKit Subscriber Library.

xGov Registry Events

XGovSubscribed

An xGov subscribed (either through self-onboarding or managed onboarding).

ARGUMENTTYPEDESCRIPTION
xGovaddressThe address of the subscribed xGov
DelegateaddressThe address of the delegated voter

XGovUnsubscribed

An xGov unsubscribed (either through self-onboarding or managed onboarding).

ARGUMENTTYPEDESCRIPTION
xGovaddressThe address of the unsubscribed xGov

ProposerSubscribed

A Proposer subscribed.

ARGUMENTTYPEDESCRIPTION
ProposeraddressThe address of the subscribed Proposer

ProposerKYC

A Proposer KYC status update.

ARGUMENTTYPEDESCRIPTION
ProposeraddressThe address of the unsubscribed Proposer
Valid KYCboolThe Proposer KYC is valid

NewCommittee

A new xGov Committee has been elected.

ARGUMENTTYPEDESCRIPTION
Committee IDbyte[32]ARC-86 Committee ID
Sizeuint32Committee members
Votesuint32Committee votes

NewProposal

A new Proposal has been opened.

ARGUMENTTYPEDESCRIPTION
Proposal IDuint64Proposal Application ID
ProposeraddressProposer address

Proposal Events

Opened

The Proposal has been opened.

ARGUMENTTYPEDESCRIPTION
Funding Typeuint8Enum: Retroactive (10), Proactive (20)
Requested Amountuint64Requested Amount (microALGO)
Categoryuint8Small (10), Medium (20), Large (30)

Submitted

The Proposal has been submitted for voting.

ARGUMENTTYPEDESCRIPTION
Vote Openinguint64Vote Opening UNIX timestamp
Vote Closinguint64Vote Closing UNIX timestamp
Quorum Votersuint32Democratic Quorum (voters) required to pass
Weighted Quorum Votesuint32Weighted Quorum (votes) required to pass

Vote

A vote has been cast on the Proposal.

ARGUMENTTYPEDESCRIPTION
xGovaddressxGov address that expressed the vote
Total Votersuint32Voters so far
Total Approvalsuint32Approval votes so far
Total Rejectionsuint32Rejections votes so far
Total Nullsuint32Null votes so far

Scrutiny

The vote has been scrutinized.

ARGUMENTTYPEDESCRIPTION
ApprovedboolThe Proposal has been approved (both quorums reached and majority approved)
PlebisciteboolAll Committee members voted

Review

The xGov Council has reviewed the Proposal.

ARGUMENTTYPEDESCRIPTION
VetoboolThe proposal has been blocked with a veto

Numeric Precisions

Percentages

All the percentages MUST have a precision of two decimals and be expressed as basis-points (bps) scaled as Algorand Virtual Machine (AVM) uint64.

📎 EXAMPLE

The AVM works with uint64, therefore \( 100.00 \% = 10{,}000 \mathrm{bps} \). So, \( 12.5 \% \) of \( X \) is calculated on the AVM as:

$$ \frac{1{,}250 \mathrm{bps} \times X}{10{,}000 \mathrm{bps}}. $$

Testing

xGov Architecture uses the PyTest framework for unit tests and end-to-end tests.

PyTest fixtures are organized hierarchically in the tests folder: fixtures defined in the conftest.py file at higher levels are available to all the nested-level tests.

Configuration

PARAMETERCLIENT VALUECLIENT UNITAVM VALUEAVM UNIT
xGov Fee\( 10 \)ALGO\( 10 \times 10^6 \)𝜇ALGO
Proposer Fee\( 100 \)ALGO\( 100 \times 10^6 \)𝜇ALGO
Open Proposal Fee\( 100 \)ALGO\( 100 \times 10^6 \)𝜇ALGO
Daemon Operation Funding\( 5 \)% of Open Proposal Fee\( 500 \)bps
Proposal Commitment\( 3 \)% of Requested Amount\( 300 \)bps
Minimum Requested Amount\( 2{,}500 \)ALGO\( 2{,}500 \times 10^6 \)𝜇ALGO
Maximum Requested Amount Small\( 25{,}000 \)ALGO\( 25{,}000 \times 10^6 \)𝜇ALGO
Maximum Requested Amount Medium\( 100{,}000 \)ALGO\( 100{,}000 \times 10^6 \)𝜇ALGO
Maximum Requested Amount Large\( 200{,}000 \)ALGO\( 200{,}000 \times 10^6 \)𝜇ALGO
Discussion duration Small\( 3 \)Week\( 1{,}814{,}400 \)seconds
Discussion duration Medium\( 3 \)Week\( 1{,}814{,}400 \)seconds
Discussion duration Large\( 3 \)Week\( 1{,}814{,}400 \)seconds
Voting duration Small\( 1 \)Week\( 604{,}800 \)seconds
Voting duration Medium\( 1 \)Week\( 604{,}800 \)seconds
Voting duration Large\( 2 \)Week\( 1{,}209{,}600 \)seconds
Quorum Min\( 30 \)%\( 3{,}000 \)bps
Quorum Max\( 70 \)%\( 7{,}000 \)bps
Weighted Quorum Min\( 50 \)%\( 5{,}000 \)bps
Weighted Quorum Max\( 70 \)%\( 7{,}000 \)bps

Deployment

xGov Registry

NetworkxGov Registry
Main Net3147789458
Test Net742949200

xGov Council

NetworkxGov Council
Main NetTBD
Test Net749237467

App Specs

App SpecLink
xGov RegistryAppSpec
ProposalAppSpec
xGov CouncilAppSpec

xGov Architecture Integrations

The xGov Architecture supports integrations with external on-chain Applications, especially those related to vote delegation of xGovs or the vote of the xGov Council.

Third parties and Applications can rely on the xGov Registry ARC-56 App Spec to build:

  • The App Client for direct ABI calls to the xGov Registry, or

  • The App Interface for internal C2C ABI calls to the xGov Registry from their Applications.

To integrate the xGov Registry, you can follow these steps:

  1. Download the xGov Registry ARC-56 App Spec or add the xgov-beta-sc as git submodule to your project.

  2. Use the algokit generate client ... to call the xGov Registry with a direct ABI call using the App Client.

  3. Use the puyapy-clientgen utility to call the xGov Registry with an inner abi_call() using the App Interface.

CI/CD

Branch Management

---
title: Trunk-based with CD
---
%%{init: { 'logLevel': 'debug', 'theme': 'base', 'gitGraph': {'showBranches': true, 'showCommitLabel':true,'mainBranchName': 'main'}} }%%
gitGraph
   commit tag: "0.37.0"

   branch "feat/add-foo-123"
   branch "feat/add-bar-123"

   checkout "feat/add-foo-123"
   commit id: "feat(foo): ..."
   commit id: "doc(foo): ..."
   checkout main
   merge "feat/add-foo-123" tag: "v1.0.0.canary.1"

   branch "feat/add-baz-123"
   commit id: "feat(baz): ..."
   commit id: "doc(baz): ..."
   commit id: "test(baz): ..."

   checkout "feat/add-bar-123"
   commit id: "chore(bar): ..."
   commit id: "feat(bar): ..."
   checkout main
   merge "feat/add-bar-123" tag: "v1.0.0.canary.2"

   checkout main
   branch "version/1.0.0"
   commit id: "bump(v1.0.0): pyproject.toml"

   checkout main
   branch release
   merge "version/1.0.0"
   commit id: "release(v1.0.0): ..." tag: "v1.0.0"

   checkout main
   merge release
   checkout main
   merge "feat/add-baz-123" tag: "v1.1.0.canary.1"

Protected Branches

  • main (default), the trunk
  • release

The trunk is considered stable and MUST:

  • Reject commits not included in a Pull Request
  • Require Docs and TestNet deployments to be healthy to accept commits from release
  • Meet the quality criteria defined in the CI/CD pipeline

The release branch MUST:

  • Be kept in sync with main
  • Be used to generate release tags
  • Reject commits from branches other than main that are:
    • Not included in a Pull Request
    • Have a diff that is not strictly equal to the pyproject.toml version bump.

The CI/CD pipeline ensures that:

  • The main branch contains release-grade code at any time (both for Smart Contracts and Docs)

  • The release branch is synced with main and used only to generate release tags (reflected as pyproject.toml version)

Unprotected Branches

Features, major refactoring, dependency bumps, or bugfixes SHALL be carried out on a dedicated unprotected branch pointing to the trunk (main).

The pyproject.toml release version bumps SHALL be carried out on a dedicated unprotected branch pointing to the release branch.

Draft Pull Requests from unprotected branches, either to main or release, SHOULD skip the CI.

Deployments

The CD makes use of the following deployment environments:

  • github-pages: to host the static documentation (mdBook)

  • contract-testnet: to continuously deploy Smart Contracts to the Algorand TestNet

  • contract-mainnet: to deploy Smart Contracts to the Algorand MainNet on release

Implementation

The CI/CD pipeline is implemented with the following automated workflows:

  • Smart Contracts CI (tests, lint, output stability, mock deployment)

  • Smart Contracts CD (to TestNet)

  • Documentation CI (tests, lint)

  • Documentation CD (to GitHub Pages)

  • Release CI (validate release tag, version, etc.)

  • Release (to MainNet)

And the following manually dispatchable workflows:

  • xGov Registry parameters configuration
  • xGov Registry RBAC management
  • Pause and Resume Proposals
  • Release and Update xGov Council

Contribution Guidelines

The xGov Architecture source code is released on the official GitHub repository.

Issues can be submitted on the GitHub issues page.

External contributions to tests and documentation are welcome. If you would like to contribute, please read these guidelines and consider submitting a Pull Request.

⚠️ Commits must be signed!

Docs Guidelines

By clicking on the “Suggest an edit” icon in the top-right corner, while reading this book, you will be redirected to the relevant documentation source code file to be referenced in an Issue or edited in a Pull Request.

The xGov Architecture Specifications book is built with mdBook.

The book is written in CommonMark.

The CI pipeline enforces Markdown linting, formatting, and style checking with markdownlint.

Numbered Lists

Numbered lists MUST be defined with 1-only style.

📎 EXAMPLE

1. First item
1. Second item
1. Third item

Result:

  1. First item
  2. Second item
  3. Third item

Tables

Table rows MUST use the same column widths.

📎 EXAMPLE

✅ Correct table format

| Month    | Savings |
|----------|---------|
| January  | €250    |
| February | €80     |
| March    | €420    |

❌ Wrong table format

| Month | Savings |
|----------|---------|
| January | €250 |
| February | €80 |
| March | €420 |

Result:

MonthSavings
January€250
February€80
March€420

Consider aligning text in the columns to the left, right, or center by adding a colon : to the left, right, or on both sides of the dashes --- within the header row.

📎 EXAMPLE

| Name   | Quantity | Size |
|:-------|:--------:|-----:|
| Item A |    1     |    S |
| Item B |    5     |    M |
| Item C |    10    |   XL |

Result:

NameQuantitySize
Item A1S
Item B5M
Item C10XL

MathJax

Mathematical formulas are defined with MathJax.

mdBook MathJax documentation.

Block Styles

Block styles are defined in the ./docs/_include/styles.md file using the mdBook include feature.

Block styles (e.g., examples, implementation notes, etc.) are “styled quote” blocks included in the book.

📎 EXAMPLE

This example block has been included with the following syntax:

{{#include ./_include/styles.md:example}}
> This example block has been included with the following syntax:

Bug Bounty

Refer to the GitHub repository security policy.

License

Refer to the GitHub repository license.