Request for Comments: Aztec Governance

Preamble

This RFC outlines how the proposed Aztec governance enables stakeholders to make decisions related to upgrading the functionality of the network. Community members are invited to give feedback and discuss the proposed Aztec Governance system.

Section 0: Preliminaries

  1. Portals

Portals are contracts which facilitate communications between Ethereum Layer 1 and the Aztec network. They will usually be pairs of contracts, one on each chain, which interact in prescribed ways through the Rollup contractā€™s Inbox/Outbox.

To fulfill this responsibility, Portals may elect to have their own internal governance mechanisms to independently decide which Rollup contract instance to recognize as the canonical Aztec network. This allows Portals to reject upgrades that they deem unsafe or not in the best interest of their users.

In other words, portals do not have to conform to any one form of governance, including that of the rollup. For more readings on Portal governance, please see this post.

  1. Deployment

Any specific deployment of the Aztec Rollup (ā€œan instantiationā€) will contain several L1 contracts described in the Governance Contracts section.

An ā€œinstanceā€ refers to a specific Rollup smart contract. If at t_0 there is one Rollup smart contract, called 0xa, and at time t_b governance vote deploys and activates Rollup smart contract 0xb, then we have two rollup instances with 0xb being the canonical rollup.

  1. Canonical Rollup

Some governance proposals result in a new Rollup smart contract being deployed to L1. From the perspective of the Aztec Governance, that new contract becomes the ā€œtrueā€ Rollup once the governance vote is concluded.

Section 1: Summary

Sequencers put forward, or ā€œnominateā€, proposals for voting by the Aztec citizens. To do this, sequencers interact with the Governance Proposer smart contract. Nominations are ā€œsignalsā€ by sequencers that they wish to put up for vote the execution of certain code by the Governance smart contract.

If the Governance Proposer smart contract records a certain number of nominations/signals from sequencers, then the Governance Proposer smart contract initiates a voting process where holders of any Hypothetical Assets (as defined below) can participate. Holders of such Hypothetical Assets are called Aztec citizens.

All signalling and voting happen on the L1.

Who puts forward proposals for voting by governance?

Sequencers of the current canonical rollup (as indicated by the Registry smart contract) can propose changes to the Aztec community for voting. In order for a proposal to proceed through the governance process, N sequencers must nominate the proposal in any given round. A round is defined as a sequence of contiguous M L2 blocks.

Sequencers can only nominate a proposal during an L2 slot for which theyā€™ve been assigned proposer duties. This minimizes timing games and provides a lower bound on the time required to successfully bring about a vote by governance.

This however would lead to an inability to nominate proposals for voting in the event that the sequencer rotation mechanism goes down. To mitigate this risk, a mechanism is proposed whereby any digital asset (ETH or any other relevant ERC-20 asset)(ā€œHypothetical AssetĖ®) holder (ā€œHolderĖ®) can burn a large quantity of Hypothetical Asset to trigger a vote on a proposal, without having the sequencers nominating the proposal. Note that Hypothetical Asset holders would still need to vote on this proposal i.e. this proposed procedure is only a nomination.

To nominate a proposal, a validator of the current canonical rollup would deploy two sets of contracts:

  1. The upgraded contracts they wish to upgrade to i.e. a new Rollup smart contract.
  2. A smart contract containing code which can be executed by governance to upgrade to the contracts deployed in (1).

Then when it is their turn as the proposer, sequencers call vote(address _proposal) on the Governance Proposer contract, where _proposal is the address of the code payload.

Note
This implies that only sequencers, who have staked the minimum amount of Hypothetical Assets, can nominate proposals.

How does a proposal get tabled for voting?

Once the upgrade code is deployed to address _proposal , sequencers call the vote(address _proposal) function on the Governance Proposer contract specifying the same address.

Nominations (or ā€œsignalsĖ® for proposals) occur in ā€œroundsĖ® of M = 1,000 blocks. Round 0 is the interval from L2 slot 0 - L2 slot 999 and so on. The Governance Proposer smart contract keeps count of the sequencers who signalled for a proposal during any given round. A proposal must receive N = 667 signals in any single round to move forward to the second ratification stage by governance.

Note
These values of N and M are for illustrative purposes only. It is expected that N and M will be immutable, chosen at the time of the Rollup smart contract deployment.

To move a proposal that has received N signals in a single round of M blocks to the voting phase, anyone can call the pushProposal(uint256_roundNumber) on the Governance Proposer contract which will in turn call GOVERNANCE.propose(_proposal) on the Governance contract and start the voting process.

Who can vote on proposals?

Holders have the ability to vote on proposals as long as they lock any Hypothetical Assets within the Governance contract. The act of locking the funds can be thought of as ā€œactivatingĖ® the voting power of Hypothetical Asset. Locked Hypothetical Assets used to vote on a proposal must wait a delay before being withdrawn to prevent malicious governance attacks.

Hypothetical Assets locked in the Governance contract are simply locked and not ā€œat stakeĖ® i.e. there are no slashing conditions.

Since sequencers may be able to stake Hypothetical Assets with the the rollup instances in order to join the validator set, the rollup instance could in turn lock those Hypothetical Assets in the Governance contract and vote on behalf of the sequencers. This is expected behaviour.

Section 2: Governance Contracts

An Aztec deployment is a set of the following contracts:

Smart Contract Immutability
Hypothetical Asset Immutable
Issuer Contract Immutable
Registry Contract Immutable
Reward Distribution Contract Mutable
Governance Proposer Contract Mutable
Governance Contract Immutable
Rollup Contract Immutable

Hypothetical Asset Contract

Hypothetical Asset would live on Ethereum L1. It may have a minter which would be the only actor capable of calling the mint function on the Hypothetical Asset contract.

This is brought up to the community for discussion purposes only to illustrate how proposed governance mechanisms could work with a Hypothetical Asset.

Validators must stake the Hypothetical Asset with the Rollup smart contract to join that instanceŹ¼s validator set, while holders must lock the Hypothetical Asset with the Governance contract to be able to vote on proposals.

Provers must deposit Hypothetical Asset in the escrow contract in order to bid for the right to create a proof for an epoch.

Issuer Contract

This contract will be the sole minter of Hypothetical Asset. It will itself have an owner which is the only actor capable of calling the mint function on the Hypothetical Asset ERC20 contract.

The mint function will limit the amount of Hypothetical Assets that could be minted in a given time period. The reasoning behind this limit is that it makes supply expansions more predictable since ā€œinfinite mintsĖ® cannot be made.

contract Issuer is Ownable {
    ERC20 immutable public ASSET; // Hypothetical Asset
    uint256 immutable public RATE;
    uint256 public timeOfLastMint;

    constructor(ERC20 _asset, uint256 _rate, address _owner) Ownable(_owner) {
        ASSET = _asset;
        RATE = _rate;
        timeOfLastMint = block.timestamp;
    }

    function mint(address _to, uint256 _amount) external onlyOwner {
        uint256 maxMint = RATE * (block.timestamp - timeOfLastMint);
        require(_amount <= maxMint, 'Insufficient mint available');
        timeOfLastMint = block.timestamp;
        ASSET.mint(_to, _amount);
    }
}

Registry Contract

The governance of Aztec will be community driven - the Aztec community will be able to decide whether to upgrade or migrate to a new rollup instance. Portals / apps donŹ¼t need to follow along with the Aztec governance and can specify the specific instance (i.e. ā€œversionĖ®) of the rollup that they view as canonical.

Therefore it will be necessary to keep track onchain of what versions of the rollup have existed as well as what version the Aztec Governance views as the current canonical rollup. Only the current canonical rollup from the perspective of the Aztec Governance will be eligible to claim any further Hypothetical Asset rewards.

In practice, the Registry is an append-only array of rollup instances. The array can only be appended by the RegistryŹ¼s owner - the Governance contract.

contract Registry is IRegistry, Ownable {
    struct Instance {
        address rollup;
        uint96 blockNumber;
    }
    
    Instance[] public instances;
    
    constructor(address _gov) Ownable(_gov) {
        instances.push(
            Instance({address: address(0), blockNumber: block.number})  
        );
    }
    
    function addInstance(address _rollup) external onlyOwner {
        instances.push(
            Instance({address: _rollup, blockNumber: block.number})  
        );
    }
    
    function getRollup() external view returns(address) {
        return instances[instances.length - 1].rollup;
    }
    
    function getInstancesLength() external view returns(uint256) {
        return instances.length;
    }
}

Reward Distribution Contract

This contract distributes ERC20 rewards only to the instance the Registry contract says is canonical. This is separated from the Registry and the Issuer so that the distribution logic can be changed without replacing the Registry.

In practice, the flow is expected to be such that infrequently, the Aztec Governance votes that the Issuer smart contract mints a quantity of Hypothetical Asset and sends them to the Reward Distribution contract.

When a new epoch has been proven, the rollup smart contract will call the claim(_to) on the Distribution contract which checks that the calling Rollup is the current canonical Rollup before releasing a Hypothetical Asset to the rollup.

The Rollup smart contract implements custom logic for how to split BLOCK_REWARDS amongst the sequencers/committee/provers who provide real work in the form of electricity and hardware intensive computational resources to the network.

contract RewardDistribution is Ownable {
    uint256 public constant BLOCK_REWARD = xxx;
    
    IERC20 public immutable ASSET; 
    IRegistry public registry;
    
    // constructor etc
    
    function claim(address _to) external returns(uint256) {
        address canonical = registry.getRollup();
        require(msg.sender == canonical);
        ASSET.safeTransfer(_to, BLOCK_REWARD);
        return BLOCK_REWARD
    }
    
    function updateRegistry(IRegistry _registry) external onlyOwner {}
    // ...
}

If the Rollup smart contract is no longer the canonical instance, then any calls to claim() would revert. Therefore it is important that Rollup smart contract implementations not fail in this case to make sure sequencers can still service the instance after it is no longer canonical.

The protocol inflation rate is capped in the Issuer smart contract as the constant RATE. It is not possible to change this cap once the Issuer smart contract has been deployed.

The Aztec Governance will choose how often to call mint on the Issuer smart contract which will send any Hypothetical Assets to the Reward Distribution smart contract. The Reward Distribution smart contract defines a BLOCK_REWARD immutable value. Every epoch, the Rollup contract can call the Distribution smart contract to claim BLOCK_REWARD of Hypothetical Assets from the Distribution contract.

The BLOCK_REWARD is the actual inflation rate and cannot exceed RATE. Both RATE and BLOCK_REWARD will be set upon deployment of the Aztec Rollup by the Aztec Governance. Aztec Governance may vote to deploy a new RewardDistribution smart contract that defines a different BLOCK_REWARD as long as it is less than RATE

Governance Proposer Contract

This is the only smart contract that is able to submit proposals to the Governance contract.

The Governance Proposer Contract will accept proposals only from sequencers of the current canonical instance, as indicated by the Registry.

contract GovernanceProposer is IGovernanceProposer {
    
    // ... imports
    
    IGovernance public immutable GOVERNANCE;
    IRegistry public immutable REGISTRY;
    uint256 public immutable N;
    uint256 public immutable M;
    
    constructor(IGovernance _governance, IRegistry _registry, uint256 _n, uint256 _m) {
        // ...
        
        require(N > M / 2);
        require(N <= M);
    }
    
    function vote(address _proposal) external override(IGovernanceProposer) returns (bool) {
// this code check has been removed to allow utilizing the same logic to vote on slashing proposals. 
        // require(_proposal.code.length > 0); 
        // ... 
        Rollup instance = Rollup(REGISTRY.getRollup());
        address proposer = instance.getCurrentProposer();
        require(msg.sender == proposer);
    }
    // ...
}

To vote to table a proposal, anyone may deploy to L1 the contracts being proposed to upgrade to as well as the upgrade logic i.e. the code that Governance contract will execute. The current L2 slotā€™s sequencer then call GovernanceProposer.vote(_code). This is referred to as a ā€œsignalā€.

The Governance Proposer contract will then count signals specifying that same _code . For a proposal to be nominated for voting, it must garner at least N signals in a single round, where a round is defined as a M consecutive L2 slots.

Note
A sequencerā€™s ability to signal is not affected by the rollupŹ¼s availability since voting happens on the L1.

If the signalling quorum has been reached, anyone can call a pushProposal(uint256 _roundNumber) on the Governance Proposer smart contract to send the proposal to the Governance smart contract for voting. Only one successful proposal per round can be sent to the Governance contract for voting.

Governance Contract

This contract is the ā€œassembly of Aztec citizensĖ® that is the final arbiter of whether to enact the proposals from the Governance Proposer Contract or not.

This contract decides what is the canonical instance which gets BLOCK_REWARDS.

The Governance Proposer contract tables proposals for voting, Aztec network participants who lock their Hypothetical Assets with the Governance contract may vote once for each Hypothetical Asset locked. They can vote either Yea or Nea.

Once a proposal garners the minimum number of votes, and the Yea votes exceed Nea by at least the quorum% , the proposal can be executed by the Governance contract.

contract Governance is IGovernance {
// ... imports
    
    IERC20 public immutable ASSET;
    address public proposalsContract;
    
    // ...
    constructor(IERC20 _asset, address _proposalsContract, uint256 _votingDelay, uint256 _votingDuration,
                   uint256 _gracePeriod, uint256 _quorum, uint256 _voteDifferential, uint256 _minimumVotes) {
// ... 
        configuration = DataStructures.Configuration({
            votingDelay: Timestamp.wrap(_votingDelay), // Min time between proposal creation and when voting starts
            votingDuration: Timestamp.wrap(_votingDuration), // Max duration of voting period
            executionDelay: Timestamp.wrap(_executionDelay), // Min time between voting passing and proposal execution
            gracePeriod: Timestamp.wrap(_gracePeriod), // max time between proposal creation and proposal execution. 
            quorum: _quorum, // % of deposited Assets that must participate in a vote (could be Yes or No)
            votingDifferential: _voteDifferential, // Yea must outweigh Nay by this % to pass vote  
           minimumVotes: _minimumVotes, // users with this much cummulative deposited Assets must participate in the vote
        })
    }
    
    // ...
    function deposit(address _onBehalfOf, uint256 _amount) external override(IGovernance) {
        // deposits are allowed on behalf of other addresses. This is useful to enable sequencers to vote.
        users[_onBehalfOf].add(_amount);
        // ...
    }
    
    function initiateWithdraw(address _to, uint256 _amount) external override(IGovernance) returns(uint256) {
        // ...
        // No one can withdraw on behalf of someone else
        users[msg.sender].sub(amount);
        // ...
    }
    
    function propose(address _payload) external override(IGovernance) returns(bool) {
        require(msg.sender == proposalsContract);
        // ...
    }
    
    function vote(_proposalId, uint256 _amount, bool _support) external override(IGovernance) returns(bool) {}
    
    function execute(uint256 _proposalId) exte rnal override(IGovernance) returns(bool) {
        // execute proposal via `call()`
    }
}

Section 3: PoS

A PoS system is proposed to protect against sybil attacks on the validator set. The major features of the proposed PoS system are:

Separation of attester and proposer keys
Each node operator who wishes to join the validator set must specify a pair of identifiers - a proposer address for proposing blocks and an attester key for attesting on block proposals. Duplicate proposer addresses are allowed whereas duplicate attesters keys are not. Together the set of the proposer address and the attester key make up what is called an Operator.

It is possible to specify a smart contract address as the proposer as this will allow for advanced setups and will make building LSTs easier.

Withdrawer keys
Every Operator is enriched with a withdrawer address. The withdrawer is able to initialize a removal of the Operator from the set - without the help of the proposer or attester. The withdrawer can initiate a withdrawal of the stake to some recipient address.

Validators can also vote for Governance proposals:
Sequencers stake Hypothetical Assets with the Rollup smart contract. However, it is expected that the Rollup smart contract may in turn lock Hypothetical Assets with the Governance contract and vote on behalf of staked sequencers.

Entering the validator set

Any address with the required Hypothetical Assets could stake with the Rollup smart contract, specifying 3 identifiers in the process.

function deposit(address _attester, address _proposer, address _withdrawer, uint256 _amount)
    public
  {
    require(_amount >= MINIMUM_STAKE)
    HYPOTHETICAL_ASSET.transferFrom(msg.sender, address(this), _amount);

The two requirements are:

  1. attester must be unique and not already registered in the set.
  2. msg.sender has the necessary Hypothetical Assets.

Note
The attester value may be implemented as a BLS key instead of an address.

Exiting the validator set

Exiting the validator set happens in two steps. A preliminary withdrawal must be initiated by the withdrawer address.

function initiateWithdraw(address _attester, address _recipient)
    public
  {
   // The validator is identified by the unique attester key. 
    ValidatorInfo storage validator = stakingStore.info[_attester];
   // Only the withdrawer address may initiate a withdrawal.
    require(msg.sender == validator.withdrawer)

A few things are checked here:

  1. Each Operator has a status of either VALIDATING, LIVING or EXITING. An initial withdrawal triggers a status change from VALIDATING or LIVING to EXITING.
  2. Only the withdrawer address can call the initiateWithdraw function.
  3. The withdrawer address specifies a recipient address to which any Hypothetical Assets will be sent.
  4. No amount is specified as only full exits are supported.

Once the checks pass, the status of the attester Operator becomes EXITING and they are removed from the validator set. Any Hypothetical Assets may not be withdrawn until after EXIT_DELAY time has passed.

After the exit delay has passed, any address can call a finalizeWithdraw() function to trigger a transfer of the entire balance of Hypothetical Assets to the recipient address specified in the initiateWithdraw() call.

The EXIT_DELAY serves as a buffer period to allow for slashing. Once EXIT_DELAY time has passed, the validator cannot be slashed by the Aztec Governance. In other words, if it is possible to successfully call finalizeWithdraw() then the balance of a validatorā€™s Hypothetical Assets cannot be slashed.

Section 4: Slashing

Background
We need to make sure that the chain is always (eventually) finalizing new blocks. The conditions required for the chain to finalize new blocks:

  • Sequencers are including txs in blocks and making block proposals.
  • More than 2/3 of the committee are making attestations.
  • Validators are gossiping client side proofs and TxObject data to committee members and to the provers via the p2p layer for example.
  • Provers are producing proofs.

In the event that a significant portion of the validator set goes offline (i.e. geopolitical emergency) and proposers are unable to get enough attestations on block proposals, the Aztec Rollup will be unable to finalize new blocks. This will require the community to engage to fix the issue and make sure new blocks are being finalized.

In current block production designs, if Aztec Rollup is not finalizing new blocks for a prolonged period of time, it may enter Based Fallback mode. The conditions that lead to Based Fallback mode are expected to be well defined by the community of sequencers, provers, client teams and all other Aztec Rollup stakeholders and participants.

During Based Fallback mode, anyone can propose blocks if they supply proofs for these blocks alongside them. This is in contrast to the usual condition that only the sequencer assigned to a particular slot can propose blocks during that slot. This means that the inactive validator set is bypassed and anyone can advance the chain in the event of an inactive / non-participating validator set.

But terminally inactive validators must be removed from the validator set or otherwise we end up in Based Fallback too often. Slashing is a method whereby the validator set votes to ā€œslashā€ the stake of inactive validators down to a point where they are kicked off the validator set. For example, if Aztec Governance sets MINIMUM_STAKING_BALANCE=50% then as soon as 50% or more of a validatorā€™s balance is slashed, they will be kicked out of the set.

Example of Slashable Offences

  1. Committee is withholding data from the provers

Provers need the transaction data (i.e. TxObjects ) plus the client-side generated proofs to produce the final rollup proof, none of which are posted onchain. Client side proofs + transaction data are gossiped on the p2p instead so that committee members can re-execute block proposals and verify that the proposed state root is correct.

Recall from the RFC on block production that the committee is a subset of validators, randomly sampled from the entire validator set. Block proposers are sampled from this committee. ā…” + 1 of this committee must attest to L2 block proposals before they are posted to the L1 by the block proposer.

A malicious committee may not gossip the transaction data or proofs to the rest of the validator set, nor to the provers. As a result, no prover can produce the proof and the epoch in question will reorg by design. Also recall from the RFC on block production that if no proof for epoch N is submitted to L1 by the end of epoch N+1, then epoch N + any blocks built in epoch N+1 are reorged.

  1. A committee proposed an invalid state root

Committee members who receive a block proposal from a proposer, must execute the blockā€™s transaction to compare the resulting state root with that contained in the proposal. A committee member should only attest to a block proposalā€™s validity after checking for the correctness of the state root.

A committee member could skip re-executing block proposals, for a number of reasons including saving compute, faulty client software or maliciousness. This opens up the possibility of a malicious proposer posting an invalid state transition to L1 by gathering signatures from non-executing committee members. Or a malicious entity that bribes ā…” + 1 of the committee can obtain the required signatures to post an invalid state transition.

The epoch will not be proven and will be re-orged.

  1. L1 congestion has made it impossible for provers to land proofs on time

An honest prover who has funds at stake (i.e. posted a bond to produce the epoch proof), could be unable to post the proof on L1 due to congestion, an L1 reorg or just an inactivity of the L1 proposers (i.e. inactivity leak).

Therefore prover bonds should not be slashed automatically. They are kept in escrow for a suitable amount of time (i.e. 30 days) to allow sequencers to vote to slash the bond if they deem the prover to be acting maliciously.

Slashing Mechanism

In all the previous cases, it is very hard to verify and automatically slash for these events onchain. This is mainly due to the fact that neither TxObjects nor client side proofs are posted onchain. Committee members also gossip attestations on the p2p and do not post them directly on chain.

Therefore an offchain ā€œsocial slashingā€ or ā€œProof of Governance Slashingā€ mechanism is proposed whereby the validator set votes to slash dishonest, staked network participants such as other validators and provers, based on evidence that is collected onchain + offchain, and discussed and analyzed offchain (i.e. on a community forum).

The mechanism for slashing proposals is expected to be very similar to how sequencers signal proposals to the Governance Proposer smart contract. In other words, to vote on a particular slashing vote, it is expected that node operators will change an environment var to call a function on the L1.

If enough such slashing votes are recorded, then the actor(s) are slashed. The Aztec Governance will set the proportion of the validator set votes required to pass a slashing vote. To decrease coordination costs of slashing bad actors, client teams could consider equipping the node software with the functionality to auto-vote on slashing proposals based on p2p and onchain evidence.

Section 5: FAQ

Can Governance change RATE?
An earlier version of this RFC claimed the Aztec Governance could change RATE by deploying a new Issuer contract. This is not true since the Issuer contract is the owner of any Hypothetical Asset ERC20 contract. For all practical purposes, RATE is fixed forever and it is the inflation ceiling.

Why require proposal nominations on L1 instead of within L2 blocks?
ā†’ The main concern is that validators that disagree with proposals could choose to censor blocks that contain nominations of proposals they disagree with i.e. refuse to attest to such blocks.

Do users vote on the L1?
ā†’ Yes currently users are also expected to vote on L1, directly on the Governance contract.

Do validators migrate stake when a new Rollup smart contract is deployed?
ā†’ Sequencers and provers are free to choose which version/instance of the Aztec rollup they wish to provide services to. They are not bound to what Aztec Governance deems as the canonical version.

In the event of a new Rollup smart contract, for sequencers who wish to migrate to the new rollup, the proposed system requires them to first exit stake from the previous rollup and then stake in the new Rollup smart contract. This affords some protection to sequencers against upgrades they disagree with.

However recall from the section on Staking that exits require waiting an EXIT_DELAY to allow for slashing.

In order to minimize the amount of time it takes to move stake, an auxiliary and optional Deposit contract could be utilized that accepts deposits on behalf of Rollup smart contracts. Some sequencers may elect to auto-move in response to a governance upgrade that deploys a new Rollup smart contract.

This reduces the time required for validators to switch to provide services to new instances of the rollup without moving any Hypothetical Assets. This is fine as long as validators remain ā€œliableā€ to be staked for any actions they may have done on the old rollup.

Since utilizing such a Deposit contract is optional and up to the specific instance to implement or not, implementation details are not proposed in this RFC.

Reference Links

  1. RFC on Block Production
  2. The Republic: A Flexible, Optional Governance Proposal with Self-Governed Portals
  3. Upgrade Proposal - The Empire Stakes Back

Disclaimer

The published proposed processes and mechanisms were explicitly published as discussion points to invite community feedback in the community forums. Robust design and developer discussion is the best way for the community to collectively secure and govern the network. Any ultimate governance design will be a result of the analysis and feedback of the community. The information set out herein is for discussion purposes only and does not represent any binding indication or commitment by Aztec Labs or its employees or affiliates to take any action whatsoever, including relating to the structure and/or any potential operation of the Aztec protocol or the protocol roadmap. In particular: (i) nothing in this post (and any response to this post) is intended to create any contractual or other form of legal, investment, financial or advisory relationship between Aztec Labs or third parties, who engage with such posts (including, without limitation, by submitting comments, a proposal, and/or responding to posts including any medium such as X, Discord, etc.), (ii) by engaging with any post, the relevant persons are consenting to Aztec LabsŹ¼ use and publication of such engagement and related information on an open-source basis (and agree that Aztec Labs will not treat such engagement and related information as confidential), and (iii) Aztec Labs is not under any duty to consider any or all engagements, and that consideration of such engagements and any decision to award grants or other rewards for any such engagement is entirely at Aztec LabsŹ¼ sole discretion. Please do not rely on any information on this forum for any purpose - the development, release, and timing of any products, features or functionality remains subject to change and is currently entirely hypothetical. Nothing on this forum post should be treated as an offer to sell any security or any other asset by Aztec Labs or its affiliates, and you should not rely on any forum posts or content for advice of any kind, including legal, investment, financial, tax or other professional advice.

12 Likes

love Aztecā€™s ongoing commitment to finding the right ā€˜governanceā€™ system without just slapping on a multisig. kudos to the team :slight_smile:

a few questions:

  • does voting on L1 mean that userā€™s votes will be public, like current token-voting DAOs?
  • in the ā€˜Who puts forward proposalsā€¦ā€™ section, you mention a Hypothetical Asset holder ā€˜can burn a large quantity of Hypothetical Asset to trigger a voteā€™. Is there an amount in mind? I recognize that itā€™d be hard to set an objective amount today that wonā€™t change in the future, but maybe thereā€™s something simple that can be done on L1 (e.g., amount must be bigger than 32 eth in any asset, or amount must be bigger than whatever the current amount to enter the validator queue is, etc)
  • for the reward distribution mechanism, what happens to unclaimed rewards if a rollup instance becomes non-canonical mid-epoch? Are they burned, redistributed, handled in some other way? It seems to me like this could happen semi-frequently but thereā€™s a lot of moving parts here so I might be misunderstanding how often that could occur :sweat_smile:
9 Likes

Reading this preamble gave me a good understanding of how governance will work, but Iā€™d like to ask a question regarding the burn to push a proposal.

Normally, sequencers, in their turn as proposers, nominate proposals, or ā€œsignalā€ them by calling vote(address _proposal), and the rest of the process continues with the Governance Proposer Contract, but in case of sequencer rotation mechanism going down, any Holder can burn an X amount of Hypothetical Asset to have the proposal pushed to be voted on by Citizens in the Governance Contract.

If I understand this correctly, would the burn method then fully bypass Governance Proposer Contract, and also how will the X amount of the Hypothetical Asset be determined, will it be an immutable value chosen at the time of the Rollup smart contract deployment like N and M?

3 Likes

does voting on L1 mean that userā€™s votes will be public

Yes, user votes will be public on Ethereum.

Is there an amount in mind?

The primary reason this mechanism exists is to sidestep the sequencer set. For example in the case where a large % of sequencers go offline and cannot ā€œsignalā€ anymore.

I think the burn amount should be commensurate with the odds of sequencers not being to initiate desirable governance proposals. Since this is a parameter set by Governance, it would ideally start off low and then gradually increased as the sequencer set de-risks its ability to coordinate and pass desirable governance upgrades.

what happens to unclaimed rewards if a rollup instance becomes non-canonical mid-epoch?

Every epoch the rollup ā€œclaimsā€ some rewards from the distributor contract. But it doesnā€™t have to distribute all of them to sequencers/provers. The rollup may choose to accumulate rewards in order to pay for services in the event it becomes non-canonical.

As for unclaimed rewards in the Distributor contract, they become claimable by the next Rollup smart contract. Suppose at time t=0 the canonical rollup 0xa can claim rewards from Distributor contract. At time t=1 a new Rollup contract is deployed 0xb - then 0xb can now claim rewards from the same Distributor contract.

In the case where a new Distributor contract is deployed, you have to deploy a new Rollup contract also. The new ā€œcanonicalā€ rollup would not be able to claim rewards still contained in the previous Distributor contract.

If I understand this correctly, would the burn method then fully bypass Governance Proposer Contract,

Yes your understanding is correct. The proposed governance process is a two phase process. Sequencers signal and then holders of any Hypothetical Assets (HA) vote.

The burn method will bypass the Governance Proposer contract entirely i.e. will bypass Phase 1, but Phase 2 will not be bypassed. Holders of any HA still need to vote to pass the proposal.

Aztec Governance will need to determine what is the burn amount. See my comment above regarding how I think about determining it.

1 Like

Reassuringly ambitious and novel in terms of pushing the boundaries on decentralisation!

Lots to think about but a couple of discussion points coming to mind immediately:

  1. Proposal timing - how often on average would we expect a validator to be capable of nominating a proposal via a proposer slot? The number of stars that need to align to hit the target number of sequencers in a round is probably an ambitious ask, at least from my personal experience of how coordination tends to play out (often itā€™s like pulling teeth). Are we thinking about how to incentivise sequencers to be active governance participants? This is often left as an afterthought, but with target proposal numbers required within a round, sequencers absolutely need to be engaged with governance if the process is to be effective. I might even go so far as to say that lack of participation should be punished.

  2. Is governance deadlock possible? Just an open question really. Like if there was a split in opinion between portal deployers and sequencers.

3 Likes

Ossify RATE (e.g. incrementally over 1-5yr) to prevent future malicious governance from collapsing the token.

As validators leave non-reward-rollups, the rollup becomes increasingly vulnerable to censorship attacks. I suggest either defaulting to based-sequencing, or triggering permanent based-sequencing based on L1 forced-inclusion usage (for non-reward-rollups).

I suggest a delay period after a vote has passed during which it can be aborted by a re-vote.

Is this just to prevent double-voting? Liquid derivative contracts otherwise obviate delay protections.

Refund the burn if the vote succeeds. To fund future protocol development an additional UPGRADE_REWARD could be paid out if successful (only for burn-upgrades) (like a dominant-assurance contract).

Provers are sophisticated actors and can purchase L1 congestion insurance out-of-band.

All vote-to-slash mechanisms are vulnerable to collusion. e.g. an L1 contract which pays out if targeted validators are slashed or if a prover is not slashed.

My largest concern is governance incompetence leading to a security vulnerability in the rollup.

Iā€™d like to see:

  • First class community support for non-reward-rollups
  • Economically incentivized security information
    • A reward-subsidized security prediction market (perhaps with trustless settlement via an impossible-to-call function)
    • SECURITY_AUDIT_REWARD, assigned to N addresses at proposal time, requiring majority sign-off
  • Eventual ossification of all contracts
4 Likes

RATE is fixed per deployment - itā€™s not possible for Governance to change RATE without passing a vote to deploy a new set of contracts. If governance itself goes rogue and is able to pass arbitrary proposals, thereā€™s no way to prevent governance from changing RATE, or any other parameter for that matter.

Good suggestion - are you aware of a time where this happened in live decentralized governance setting?

It should not be cheap to just buy a lot of Assets, vote maliciously and then exit immediately. Do you see any threat vectors with the way the delays are described? or with the use of liquid derivative contracts?

Thank you for the suggestion and I agree. Currently the ā€œburnā€ is implemented as a permanent lock up, so easy to make this change.

Just to be clear - who should receive this and under what conditions? IIUC in a dominant assurance contract, the UPGRADE_REWARD should be paid out to Yes voters IFF the proposal does not pass to encourage participation. Where did I misunderstand?

What could be done to at-least decrease odds of successful collusion? So far our thoughts are 1) require high participation i.e. >50% of entire stake and 2) do not refund cost of slashing (signature verification etc).

Can you elaborate how SECURITY_AUDIT_REWARD would work?

The signal is a payload to L1. As long as more and more of the sequencers start to deploy this payload to L1 along with their blocks etc, eventually in some round in the future sequencers will successfully trigger a vote.

The N and M parameters could be set by Governance to be any number of sequencers in an arbitrarily large round. Iā€™d imagine for V1, this would be 10 sequencers in a round of 100 L2 blocks and increased later as the validator set grows in size.

Anon proposed a dominant assurance contract which I presume acts to incentivize participation. Iā€™m waiting on clarification but so far we have not put much thought into incentivizing participation. Any thoughts on how this could be done?

The proposed slashing mechanism will likely require a lot of the sequencers to agree to want to punish some subset of sequencers who consistently donā€™t participate in governance.

Yes for example an asset issuer (and a portal operator) may choose to not support an upgrade. In that case any assets bridged into the Aztec L2 through that portal become unbacked. In the case where some % portals donā€™t upgrade but other portals do, both the new and old rollups are now unbacked.

This is the price paid for providing guarantees to portals that a malicious governance upgrade can be rejected.

Make Hypothetical Asset an OssifyingRateERC20 that restricts mint(). Really, RATE should be fixed from day 1 (or only decrease).
Has there been consideration to issuing on a curve based on percentage of staked tokens?

No.

Asset holders may sell just their voting rights. A delay does seem like it would raise the price of votes though. Votes as buy orders attempts to solve this problem.

The proposer (burner) receives the reward if the vote passes. The burn itself is payment by the proposer for failure (to all holders). Voters are incentivized because the proposal adds value to the network. (I expect most votes to come from stakers where the cost to vote is low/0).

Decrease the value of collusion, by limiting the power of governance (e.g. fixing RATE). If slashing costs anything then the cost to bribe not-to-slash approaches 0.
However, vote-to-slash is not necessary:

The real problem is stalling attacks are too cheap:

Re-Based can be adapted to use Hypothetical Asset by enshrining an AMM, where block-fee is used to buy and distribute the asset to the ILC. Based-rollups pair well with Unified Addresses, no need for token-voting governance.

Extend propose to propose(upgrade_addr, [auditor_addr]). Once tabled, a majority of auditor_addrs must endorse the upgrade. If the vote succeeds, SECURITY_AUDIT_REWARD is split amongst auditor_addrs. Most of the value relies on the social layer endorsing a set of trustworthy auditors.

1 Like

I understand these values would be static, any rationale why static values instead of a dynamic function. Something like 1/x seems natural to me, easy to fork and make changes in the early days but over time less forks allowed as the network stabilises.

Why require proposal nominations on L1 instead of within L2 blocks?
ā†’ The main concern is that validators that disagree with proposals could choose to censor blocks that contain nominations of proposals they disagree with i.e. refuse to attest to such blocks.
Do users vote on the L1?
ā†’ Yes currently users are also expected to vote on L1, directly on the Governance contract.

I agree with the idea of using L1 for bettter CR, but can we make the contract on L1 ALSO accept batched ZK proofs so that users can either use the Aztec rollup or some other offchain batching solutions to amortise gas costs.

1 Like

Thank you for posting this RFC. The proposed system is quite innovative and Iā€™m looking forward to following along with development.

Have you considered leveraging off the shelf governance contracts? It would make the system easier understand and faster to ship. It could also lower smart contract implementation cost, audit costs, integration costs, and risk of bugs and governance attacks.

Specifically, I would recommend considering the following changes to the implementation:

1 Like

Hi everyone! Anthony, CEO of Aragon here. Really excited to see governance conversations opening up at Aztec, thoughtful governance is the cornerstone of successful organizations.

Weā€™ve followed Aztecā€™s governance progress closely, especially after collaborating on a private voting prototype for Nouns and showcasing Aztec Governance on Aragon, The Return of the Jedi here in the forum in 2023, so itā€™s exciting for us to see the evolution toward this current proposal!

Thereā€™s a lot to digest. So iā€™ve provided some thoughts and some questions below.

Some thoughts:

One of the biggest painpoints in onchain governance has been using single onchain governance processes for making all kinds of decisions. Splitting proposal ā€œtypesā€ into distinct ā€œprocessesā€, can help identify which of a projectā€™s stakeholders need to participate, and with what degree of power, depending on the type of decision being made. If understanding the proposal correctly, it seems that all types of actions, whether itā€™s updating the Registry, Issuance, and Distribution all go through the same two stage process:

  1. Sequencer Vote (1 sequencer 1 vote)
  2. Token Vote (1 token 1 vote)

Should sequencers play the same role in issuance as they do in governing the rollup registry? Maybe itā€™s ok for them to, but I wanted to raise this as a potentially helpful way of reframing them as distinct problems that could have their own optimized governance solutions.

Another helpful framing that we have is thinking of processes as having distinct ā€œstagesā€. Within each stage, there is a vote. If not, itā€™s a timelock. In context of this proposal, it could be misleading referring to stakeholders as merely ā€œnominatingā€ proposals. They are infact participating in a governance process, which will be followed up by a secondary stage led by token votes.

As an industry we have started to move away from 1 party governs all permissions in 1 way as it hasnā€™t been working. The great part is, we have now gotten to a point where we can provide more granular governance designs, onchain. This helps with user participation and decision making effectiveness.

Some more concrete feedback and questions:

  • Optimistic governance: Was was optimistic governance considered in order to help drive upgrades more expediently as a first step? Some L2ā€™s we are working with for example have taken this approach, where token holders have full veto power in a second governance stage, but they donā€™t have to vote in the affirmative if they are satisfied with the proposal. This starts to approach the other idea floated in the thread around aborting a proposal by a re-vote. Doing so via token vote, from a voter participation perspective, seems like it could be too much to ask.

  • Indirect voting: Perhaps the idea is that voter participation will be driven more with the expectation is that the largest voter is in fact the rollup itself voting on behalf of the sequencers and their stake. This makes complete sense. However, has there been consideration around the potential aggregation problem and resulting preference meaurement loss when the rollup votes? If the rollup is unable to split its votes across yes and no votes as and EXIT_DELAY is too long for unstaking to vote in a specific proposal, token holders get their votes ā€œpooledā€. This could lead to results where <50% of the Hypothetical Assets owners (the ā€œpopular voteā€) are able to reach a majority on the governing contract (due to the aggregation of sequencer tokens). Think districts and their effect on election outcomes.

  • Quorum definition: Seems also like there could be a small mixup between quorum and votingDifferential here: ā€œOnce a proposal garners the minimum number of votes, and the Yea votes exceed Nea by at least the quorum%"

  • Double voting: There were a couple comments around how to prevent malicious votes with buying, voting, selling, etc. Thereā€™s several solutions for this, either with taking token balance snapshots upon proposal creation, more sophisticated proof-based solutions, or simply locking the token. Since the proposal actually includes locking, this shouldnā€™t be a threat, and Iā€™m not understanding why there is a separately defined waiting period. The vote counting can simply be dependent on it being locked. For example, weā€™ve built an OSx governance plugin that can be configured in either way:

    • Doesnā€™t let voters unlock until a proposal is over, so tokens canā€™t be double counted
    • Letā€™s users unlock during the proposal, and double counting is preventing by subtracting them from the tally upon unlock.

Would love any feedback on any of the above to provide even more extensive feedback and thoughts.

Overall, we are obviously extremely excited about the future of Aztec and Aztec Governance as industry peers in privacy.

Thank you!

2 Likes

I misrepresented what RATE is. Aztec Governance may NOT meaningfully deploy a new Issuer contract with a new rate. This is because the Issuer contract is the owner of any Hypothetical Asset ERC20 contract.

Therefore, the protocol inflation is forever capped by RATE which is expected to never change. The actual inflation rate may be decided by the Aztec Governance and is set in the Rewards Distribution contract as BLOCK_REWARD.

It is possible to have a contract on L2 which accepts votes from L2 users (could be private) and sends them to L1.

What is 1/x?

If 1/x relates to the size of the validator set, then a fixed N and M would be similar. Youā€™d need a smaller proportion of the validator set to signal in order to trigger a vote.

Slashing for example can be seen as a governance process where HA holders are not involved.

Majority of upgrades will deploy a new rollup contract. Two things happen:

  1. Sequencers of the old rollup will not be eligible for any block rewards.
  2. Fee asset on the old rollup will become unbacked as the fee asset portal on L1 follows the Aztec Governance.

It seems to be reasonable to always require buy in from both holders and sequencers in the event of a new rollup contract being deployed.

I donā€™t think weā€™ve considered optimistic governance. One of the design goals was making ā€œrejecting governanceā€ the path of less resistance. In optimistic governance, the path of least resistance - i.e. doing nothing - leads to accepting the will of governance. In the proposed system, the path of least resistance leads to rejecting the will of governance.

The rollup can split votes across Yes and No - IIUC this ā€œdistrict-similarā€ problem no longer applies. Please let me know if I misunderstand.

Yes thanks for pointing that out. I wasnā€™t using consistent parameter names, will update for clarity.

To be eligible to vote, HA holders must deposit and lock tokens with the Governance contract. The Governance contract in turn takes snapshots of a userā€™s voting power upon every deposit. Users can only utilize voting power they owned before the proposal became active. Double votes are thus not possible.

The delay exists to deter governance attacks. See below discussion with Anon on vote buying

Hey Amin,

Thanks for the clarity.

Makes sense.

Although your logic makes sense, this setup is counter to the industries current problems. Rejecting governance has been lacking and a major problem, where DAOs have reached an ā€œauto-yesā€ on everything. All of these yeses occur in the slowest possible format of referendum based voting which is a tax on the highest credible and professional token holders who do not have the time to participate. So you basically get the same outcome but with optimistic governance you are able to move more quickly and more safely. I highly highly recommend revisiting this thinking and am happy to discuss in more details. This could be negated if you designed governance as such where different proposal types have different processes and governing bodies. Thus you could segment and optimize for a specific outcome defending on what is being governed.

Noted on all and very interested votes as buy orders!

1 Like