The Republic: A Flexible, Optional Governance Proposal with Self-Governed Portals

Assumes the existance of an Aztec Token (AZT).


The Republic is a two-part idea I have been working on that presents a new spin on governance.

It’s all about giving the user more control of her risk-profile, whether she desires to delegate the responsibility to some governance or accept it herself.

The first part of ‘The Republic’ is about self-governed portals. We’re dividing them into three main types: rollup-governed, portal-governed, and ungovernable. Each one with different levels of control and flexibility, so you can pick what works best for you.

The second part is about creating a more streamlined process for those who want to follow forks without the hassle of migrations. We’re proposing the idea of a ‘Senate’ to embody this decision making system. The Senate is a smaller group, whose members are elected by the Citizens through token-governance.

But don’t worry if you’re not into that - portals can reject governance, and the system is flexible enough to replace the Senate with something else if desirable.

What makes this proposal interesting is how it integrates the self-governed portals with the Senate. It creates a flexible structure that lets portals choose whether to accept or reject forks individually. This makes governance an opt-in process, giving you the freedom to choose.

Lastly, we’ve got some ideas for tackling the issue of ‘pending messages’ - those messages that are sent but not consumed before an upgrade. We’ve also got a plan for mass migrations for ‘ungovernable’ portals. We think these ideas could be useful for other proposals too.

Looking forward to hearing your thoughts and feedback!


Currently no other proposals exits, however, consult “Closing Thoughts” to see it marked on the spectrum.

Generic Background

This section is generic background that also ended up being adopted for the RFP proposal itself. Added here for self-containment.

In the land of blockchain, it is sometimes useful to perform network upgrades to fix bugs or include new functionality, be it new opcodes, precompiles or changing the fee structure.

The “problem” of an upgrade can be split into two sub-problems:

  1. Deciding that we want to upgrade and what we want to upgrade to
  2. How we enforce the upgrade

In the following sections, we will be looking at how these sub-problems can be solved at a very high level for different types of systems; L1 blockchains and L2 (with bridged assets).

Difference on migrations and upgrading

We make a distinction between a “technical upgrade” and “technical migration”. A migration is a separate deployment, where users must take action to migrate their positions from A to B. An upgrade instead requires no interaction for the individual user.
Example of migration: Uniswap: With the launch of V3, people would migrate funds from V2 to V3 to supply liquidity.
Example of upgrade: Aave: The pool contract is using a proxy and the implementation have been updated on occasion.

Before diving into the specifics, we have some notation to get out the way. Namely that we will differentiate between the words upgrade and migrate in a technical manner.

namely what is the technical difference between an upgrade and a migration. While the end goal for those are similar, “provide users access to a new version of the software”, it have some major differences it how this is acheived, and what kind of actions is required by the users of the software.

A migration is a separate version of the software, where foreign state must be “moved” from the old to the new version.


In the domain of Ethereum, the first part is often a mix of discussion by the community proposing EIP’s and client developers that work on implementing the proposed EIP’s. When a decision is made to include XYZ into a network upgrade, a time of upgrade is decided. Throughout this process any community member can raise issues with the proposed changes and you might see fractions in the community that disagree whether to support or reject the change.

When the time of the upgrade arrives any node in the network can decide if they want to run the new node software (including the change) or continue running the existing software. If there is a significant divide between the nodes this can spawn long-lived forks of the network with different rules. The value of the fork (and its claim to be the real Ethereum) comes down to social consensus. A famous example of such a split spawned Ethereum Classic after the Dao Hack. Social consensus decided that classic was not the real Ethereum, but both versions live on and users are able to decide for themselves what they think is the real Ethereum.

Rollups with bridged assets

As Jon Charbonneau nicely conveyed in his essays Rollups Are L1s (& L2s) a.k.a. How Rollups *Actually Actually Actually* Work and The Rollup Multiverse a rollup can use the same structure as Ethereum to figure out when to fork and what to fork to but there is one very large difference from a fully separate blockchain - the bridged assets (foreign state).

If there is a proposed upgrade and community want to “fork off” they can deploy the rollup state transition contract, and start it from the current state. The assets can be used inside the fork as if they always were there, but the collateral for any bridged assets will still be in the same contract (not forked by this).

The bridge must decide which of the forks is the “real” one, and only allow it to withdraw funds from the bridge. Only one of the forks can be seen as the “real” one as it might be possible to double-spend otherwise. As an example, assume that you have 10 eth and the fork happens. On both of the forks you now have 10 eth, so you can from the L2 point of view exit those to L1. If L1 accepts messages from both forks you would be able to exit with 2*10 eth and practically have stolen someone else funds (double-spending your deposit).

If the bridge contract with the collateral is controlled by some governance that decided what it seen at the real fork it can impact what is seen as the “real” fork by anyone. In the case where a rollup has a canonical bridge which holds custody of a large part of the non-native assets, this bridge can practically decide what is seen as the real fork (or at least which of the forks that will have backed assets)

Above is a diagram showing how such a setup could look. We are showing message boxes as the means of communicating between L1 and L2.

Governance Spectrum


If the contracts seen in the above diagram are all immutable without admin control or keys, the act of upgrading from one version to another requires that users are exiting funds from the rollup to enter in another system. This is sometimes referred to as a migration as users need to migrate the state from one system to another to employ the benefits of the new.

It is a “upgrade” mechanism that have been used in multiple projects in DeFi mostly prominent is probably Uniswap V3, which required liquidity providers to exit V2 and put their funds into V3.


Alternatively, contracts can be controlled by some governance organ which are able to decide what is seen as the “real” fork.

The exact mechanism for how this decision is enforced varies between different platforms, but can be done by having a proxy in front of every contract such that the implementations can be changed by govenrance if the decision is made. Graphically this would look like what we saw earlier, just with an extra party the “governance” that can update the implementations.

Upgrade delay and rage-quitting
To ensure that it is possible to rage-quit the system in case an undesired upgrade, it must be possible for the user to perform a forced-exit before the upgrade is executed. Otherwise malicious governance can trivially steal all bridged funds.
See Forcing a Transaction.


To outline some of the tradeoffs in a digestable manner, the below table shows what is required by the user to ACCEPT or REJECT upgrades and outlining what the user trust beyond correct implementation.

To summarise:

  • Governed systems use delegates (direct or indirect) to perform decision making, making the workload smaller for users and thereby more convenient. While users and delegates are in agreement this method runs smoothly. However in case of disagreements, users need to act actively in order not to be forced to use the new upgrade.
  • Imutable systems once again proves to be a double edge sword that protects users from automatically following upgrades - good or bad. Upgrades becomes an active choice for each individual, thereby avoiding coercion but also requires more work and research by users.

Details: Proposal Part A - How to upgrade

Going to address it in opposite order.
First will outline how we can enforce upgrades,
Second outline how we decide on doing an upgrade

Design Goals

  • Safety: It MUST be possible for an resourceful user to REJECT rollup upgrades and rage-quit with his funds.
  • Safety: It MUST be possible for a prepared user to REJECT rollup upgrades without having to interact with the chain.
  • Safe: It MUST be possible for a user to send messages L1<->L2 that can only be consumed by the specified version, even if an upgrade was performed
  • UX: It MUST be possible for a user to ACCEPT upgrades without needing to migrate his state
  • UX: It SHOULD be possible for a user to send messages L1<->L2 that can be consumed by the newest version, even if upgraded after message was sent

Social consensus light: By supporting the Safety goals, it is possibly for us to emulate a light version of social consensus, where users can REJECT updates if they desire and there is nothing a malicious upgrade can do to take their funds.


  • There is no canonical bridge.
  • Portals are individually governed!
  • Rollup governance is opt-in.
  • Pending messages can be made to follow upgrade (opt-in)


Let \mathcal{R}_i be the i'th state transition contract. Let c be the “current” index and \mathcal{R}_c be the “current” rollup. Current being the one that is seen as “real” from the governance point of view.

Let N_i denote indexed constant values, such thah N_1, N_2, \dots, N_n are all constant values.

No Canonical Bridge - But self-governed portals

The Aztec Rollup will not have a canonical rollup bridge that hold assets, but entirely rely on external developers using the message boxes to build asset containers (or bridges). This deviates from what most other platforms are doing at first glance, but is practially similar to a rollup where majority of collateral is held by bridges that are not controlled by the rollup governance.

We believe it is useful to seperate rollup-governance and bridge-governance (in order to combat centralization)

Since the bridges are contracts that are permissionlessly developed and deployed by anyone with the desire to do so, it is impossible for an “Aztec” governance to force its view upon the individual bridges. It might incentivise them, but cannot force it.

A portal can be fully immutable, or have its own governance mechanism that it used to decide which fork is real or it might fit somewhere between these options. Practically we could say that every bridge is self-governed.

Portal Variants

Since the Aztec portal contracts are the holders of collateral the governance strictly don’t have full control of the assets that have been bridged into the rollup. Their power is restricted by the implementation of the individual bridges.

As alluded to earlier, portals might be ungovernable or governed, but additional types exist. We distinguish between 3 primary types of implementations from the point of view of governance models, namely:

  1. Rollup Governance: This type of portal follows the whim of the Rollups governance. It relies on Rollup governance for safety.
  2. Internal Governance: This type of portal uses its own governance mechanism to decide which rollup to honor (what rollup is real). It can default to follow the Rollup Governance, but use its own governance to reject upgrades if desired. This portal has a lot of flexibility, but relies on 2 (possibly distinct) governance mechanism for safety.
  3. Ungovernable: This type of portal is immutable with fixed values for the current rollup. Assets in this type of portal must actively be migrated from \mathcal{R}_i to \mathcal{R}_{i+1} by the users, see Appendix for initial idea on how this can be done. The design is trust-minimized and unfetched by the actions of the governance, but massively inconvenient for users that want to follow the upgrade as interaction (transactions on minimum L2) is required.

When thinking about upgrades by governance, one needs to consider that the portals individually decide what they believe to be the “real” fork. In the table below, we have the 2 extremes, but also middle cases, that have an internal governance and might rely on it for either all decision or only emergencies.

Migration simply means that is requires action, but not necessarily individual exit and new deposit from every user. See the mass-migration. The case of exit and deposit is practically a simple migration.

That portals can employ any combination of these 4 makes upgrades a bit different from the norm. Also, it adds some constraint on us when we want to decide the upgrades as it makes handling “pending” messages a bit different.

What are we going to do?

To support our goals, most of the contracts that make up the Aztec Rollups L1 presence will be immutable without admin keys. This includes the state transitioner and message boxes.

These contracts must be immutable, because an immutable portal can be tricked by cheating message boxes or state transitioner. By making them immutable governance cannot upgrade it to cheat these portals.

Note, that with state transitioner being immutable and not reading from external values, the implementations specify fully which sequencer selection mechanism is used and cannot be changed without a separate deployment of the state transitoner.

To facilitate an upgrade when most contracts are immutable, we propose to introduce a registry which is controlled by the governance with the following tasks:

  • Point to the governance implementation of choice.
  • Point to the “real” implementation from the POV of the governance (state transitioner, message boxes)
  • Store all prior “real” versions as snapshots (blocknumber of upgrade, state transitioner, message boxes) allowing archivers to easily figure out where to pull historic blocks from.
  • Store a merkle root of a tree with the snapshots.

The registry is controlled by the governance, and they can insert a new state transitioners and swap message boxes as follows:

  • Registry will run a migrate(address _newStateTransitioner) function that
    • Reads the rollup state from \mathcal{R}_{c}
    • Deploys new state transition contract (\mathcal{R}_{new}) with the above state to initialise
    • Adds \mathcal{R}_{new} as the last “snapshot” of rollups (along with message boxes, which can be unchanged)
    • Updates the current rollup in registry \mathcal{R}_c = \mathcal{R}_{new}
    • Update a snapshot root computed on chain (merkle tree of snapshots)

The registry can only receive updates after long time-locks. The timelock ensures that users with assets in Governance Controlled Portals have sufficent time to performed a forced exit, see Forcing a Transaction.

Furthermore, the upgrade should not be possible to execute if there are pending forced transactions whose inclusion time is before the upgrade is at the earliest executable. This ensure that sequencers just halt halt block production until the upgrade can be executed to avoid escapes.

Hence the state transitioners are all immutable and without any access control, the old “rollups” \mathcal{R}_{i \neq c} cannot be killed or paused. This allows users that have rejected the upgrade to continue using the previous implementation, assuming that there will still be someone to sequence it.

Due to the many-portal design, we can get a really interesting dynamic if assuming that the majority of portals are not simply following rollup governance. Namely, that rollup governance need buy-in from portal-governances and users in order to successfully “migrate” the collateral to the new rollup. If they cannot get this, due to contentious upgrade, users might decide that the “old” rollup is the real one and governance could be pushed into reverting their change and add the old rollup as the current one again. This might complicate expected state for users a bit as the upgraded state is practically discarded - The fork is pruned.

Note on sequencers
Only the “real” fork specified by the registry is able to mint a block reward, so sequencer selection implementations MUST be able to function without providing a minted token reward, as governance is otherwise able to “kill” existing implementations when the upgrade is happening. This can be supported by making the minting optimistic, and not revert if failing.

Sequencer selection implementations should not be constrained to only sequence for one instance.

There might be little incentives for sequencer to keep processing “old versions” if fees do not cover the cost as not additional AZT reward can be supplied.

It should be possible for “anyone” to act as the sequencer if the sequencer selection mechanism have been inactive for sufficiently long. Mainly applies to leader election proposals where leaders could be absent, and not B52 where anyone might propose the blocks.

The diagram below gives an intuition of how the registry is attached to the system outlined in earlier in generic background.

To support our goals for pending L1 and L2 messages, we have added changes in the appendix that allow us to both specify directly which state transitioner can consume the message from the Inbox, but also allows a user to send messages that can be consumed by upgrades through governance. The Latter being opt-in for safety reasons.

To fork or not to fork?

As we walked through above, upgrades are practically done through forking and convincing portal governance that they should use the new version, or for immutable portals that they should migrate to the new version.

This means that it is possible to reject upgrades by governance, WITHOUT foregoing the collateral on L1.

However, from earlier we have already seen the actions required for accepting or rejecting an upgrade proposed by the Governance under portal variations, so we will not dvelve too much in it here.

Nevertheless, governance is not the only that can play this game (even if they have the AZT incentives on their side). It is possible for anyone to fork the rollup by deploying their own variation. The main difference being that, no-one will by default be following the anon fork, they need to actively migrate to it. Note that this would fall into the “upgrade by governance” catagory if governance decide to follow the fork.

The specifics of migrations again depends on the type of fork, so lets draw a new version of our diagram, one showing how different portals handles upgrades to NON-governance appointed forks. Note that we do not have the REJECT option, as the action to REJECT a random contract deployment is no action.

With this at hand, we should have a decent idea around the portals and indirectly its users ability to control what version of the rollup is the “real” rollup.

Note that if rollup governed portals hold all but a negligable amount of collateral, the bargening power of other portals might insignificant, and you are back to the “standard” rollup case where the Rollup governance effectively controls the correct version of the rollup. Unless of course we have the special case where collateral on L1 is negligable as a whole, then we can socially decide what is the real rollup is!

Did we reach our goals?

  • Safety: It MUST be possible for an resourceful user to REJECT rollup upgrades and rage-quit with his funds.
    • Since we must forced transactions and upgrades can only be executed when timely exists have happened, it is possible for a user that follows the news to reject the upgrade and rage-quit with his funds.
  • Safety: It MUST be possible for a prepared user to REJECT rollup upgrades without having to interact with the chain.
    • A prepared user can use ungovernable portals instead of rollup governed which will require no action to reject the upgrade. Alternatively, a user with trust in “internal governed” portals can rely on a non-rollup governance to keep him safe.
  • Safe: It MUST be possible for a user to send messages L1<->L2 that can only be consumed by the specified version, even if an upgrade was performed
    • Through the use of addresses as the version (see Appendix), it is possible for the user to make his message consumable only by a specific instance of the rollup.
  • UX: It MUST be possible for a user to ACCEPT upgrades without needing to migrate his state
    • A user that has funds in a governed portal will follow what the governance decides. If he choose the rollup governance or an aligned internal governance, he will follow along without any further interaction from his side.
  • UX: It SHOULD be possible for a user to send messages L1<->L2 that can be consumed by the newest version, even if upgraded after message was sent
    • Through the special case of using type(uint160).max as the version number the messages can be made to follow governance, supporting pending messages to move along with the upgrades.

Details: Proposal Part B - How To Decide

This decision can practically happen without impacting Part A much, and might even be changed through the upgrade process itself if the desire is so.

Who decides on upgrades

Token voting on every proposal scales horrible and users are often ill prepared for making decisions guarding the platforms.

As Part A introduced a way to govern the protocol without allowing governance to steal the funds of users that cannot fight back we believe that it can be beneficial to use a smaller Senate that strives to enforce the will of the people.

The Senate is used such that it is not required to have a full token vote for every upgrade where voters might be ill-equipped for taking a decision which in the end will centralise power anyway. We outline it explicitly hence it will often arrise anyways, and have the voting be in discrete chunks (elections) instead of continious delegation.

The Senate consist of members (senators) which are chosen by the Aztec token holders and it has the power to decide what “Rollup governance” believes to be the real Rollup.


Actor-groups (a single actor might fit in multiple groups, e.g., holder and technical council):

  • Token Holders (referred to as Aztecs or Citizens)
    • Decide who the members of the senate should be
    • Can force a re-election of the Senate
    • Can declare “state of emergency” and “pause” the power of the Senate by doing a significant burn of Azt. Inspired by Makerdao Emergency Shutdown.
  • Senators
    • Voted in by the Aztecs (token holders) for a period
    • Votes on AZIPs that upgrade contracts
  • Technical Council
    • Voted in by the Aztecs (token holders)
    • To analyse feasibility of AZIPs and their impact on existing portals/contracts
    • To analyse AZIPs from a security point of view and its impact on privacy of both new and existing users
    • To publish their findings in the public domain as part of the review phase of the AZIP.

Upgrade Process from governance point of view

The flow of going from idea to new version of the rollup.

  1. The community proposes an AZIP that require code changes to the Ethereum contracts
    • This could be changing the proof system, updating how the sequencer selection mechanism or other tasks that require changes to the core contracts.
  2. The senate gauges sentiment towards the idea, if there is strong sentiment against the proposal, drops the idea, otherwise continues to step 3
  3. The technical council prepares a report/response and post it as part of the review phase of the AZIP
    • The report should look into the feasibility of the proposal and its impact on the security of the system.
  4. Based on the report, sentiment might change, and the senate decides whether the proposal should be implemented
    • The implementation process itself can be performed by external or internal parties. If already provided, this step can be skipped along with 5.
  5. Implementation is done
  6. After the implementation is done an new contract is deployed
  7. Proposal that alters contract values can be put on chain with signates from \frac{1}{N_1} of the Senate (agreeing to put it to the vote).
  8. Proposal can be voted on by Senators for N_2 days
  9. If m \ge \frac{1}{N_3} > \frac{1}{2} Senators have voted for the proposal before N_4 days, it is enqueued, otherwise dropped.
  10. After a delay N_5 > 14 days the proposal can be executed by anyone. After N_5 additional days the proposal is dropped if not executed yet.


  • Long reaction time
  • Lack of sequencers on forks
  • Malicious Governance
    • Governance Centralization
    • Bribeable senate and vote buying
    • Uneducated Citizens
    • Low participation
    • State of emergency abuse

Long reaction time

In the case of a vulnerability in the code, the reaction time for the governance to deploy a fix can be significant both due to the governance process, but also due to the additional delay to ensure that users have the ability to rage-quit. We think that this is a general issue of upgrades, and that any upgradable system that does not enforce rage-quits are insecure.

Lack of block producers on forks

Assuming that one of the proposals using some form of staking in the sequencer selection (block production) is used, the same group of actors that are producing blocks might be the majority of token holders that elected the senators pushing forward the divisive upgrade. This could lead to only few of the possible sequencers producing blocks on the fork.
This could lead to a case where users that intend to stay on “old” version when a upgrade happens might be unable to produce blocks with certain sequencer selection models.

For upgrades that want to fork off, these can specify a different sequencer selection algorithm and instead rely on bootstrapping a separate set similar to how other L1’s are forked.

Malicious Governance

Governance risks apply to both portal governance and rollup governance. For most portals, governance will likely have the full custody of funds, meaning that they are able to steal funds (similar to some DeFi protocols with proxies and governance). Because of this, we will mainly be interested in rollup governance for the remainder of this proposal.

If governance becomes malicious and want to perform an upgrade to a rollup where they are the only that can perform actions and simply take funds, how is the proposal addressing it? This could be because of greed, outside pressure or other reasons as we will look at shortly.

If a malicious upgrade is performed, portals that are blindly following governance (the aztec governed) are not to be saved. Of the internally governed portals, they either have to opt in to lose their funds or they can use the long delay before an upgrade to opt out. For ungovernable, no action have to be taken.

Governance Centralization


If the governance is centralized because of senators acting from greed or pressure, the citizens are able to throw the republic into a state of emergency or remove them from their duties to avoid an upgrade going through. This require coordination between citizens, but they are able to individually escape using the forced exit if necessary.

Token Distribution

If the centralization is due to token centralization where some entity have huge influence of the senate and can practically do whatever it wants the only real option to avoid the upgrade is to fork and rage-quit from the portals that follow governance blindly. In this case, there are no rollup governance with extended rights (special case in the message boxes) and all portal will need to be internally governed or setup a new governance structure and building on that.

Uneducated Citizen Or Senators, Low participation and bribes

Governance participation generally is very low for token holders, and it does not help us when proposals are hard to analyse completely. Some of this is hopefully addressed by only requiring citizens to participate in elections and state of emergency. However, chosing a senator that is unable to understand the effects of proposals (with the report by technical council) could be very detrimental to the system.

Buying votes as part of the election process or bribing senators can lead to similar results as above. The solutions are similar to centralisation due to other means - remove the senators or use portals that are not blindly following rollup governance.

Unable to upgrade due to “state of emergency”

If the value of the token burn required to enter state of emergency is low, of if there is a possibly payday from delaying an upgrade, it might be in the best interest of citizen to delay the upgrade by sacrificing a gift to the aztec gods.

There is no way to bypass the delay, so governance have to take the L and wait.


Limited by the technology of my time, here is the last characters.

Closing thoughts

Due to my separation of governance into rollup and portal governance, I’m extending the spectrum.

I believe this proposal to be fairly flexible, supporting instances (1, 2, 3, 4 and more) spread across this spectrum, however some more likely than others.

As seen from the diagram multiple options are outlined:

  1. With most portals implemented as immutable contracts the governance is effectively out of power, and behaves as if there were no governance;
  2. Opposite, if most portals are following rollup governance, we are in the same case as a canonical rollup bridge controlled by governance;
  3. If portals are all governed by their own governance implementations (not immutable) the setup is still governed, though not by the same set (assumed) as for 2. This might resemble multi-sig world of today depending on portal governance;
  4. The combination of portal governance that i think is most likely. Many portals wanting simply to work as a canonical bridge, with some using own governance and few completely without governance.

Overall, the proposal strives to support the ability to REJECT upgrades and instead migrate for maximum immutability, but acknowledges that migrating the chain state at every upgrade is impractical. Therefore, portals are able to decide what instance is the real rollup on their own.

Since portals can decide on their own, we introduce a “guide” in the form of the Senate which can be used by portals that don’t wish to be immutable but simply follow what “token-governance” deems the real rollup. Remember that the opinion of the Senate can be discarded.


Appendix Part A

Adapting Messages

As described in the Aztec Docs | L1 ↔ L2 communication message boxes are used to move a message from L1 to L2 and opposite.

Every message have a sender and receipient along with an identifier for the underlying chains. When instructed to consume a message, a series of events happens:

  • For a portal contract, the portal implementation must ensure that the sender matches the expected L2 contract (simple access control on L1) and that the version comes from the rollup that it believe to be real. If these checks are not performed, the portal might be insecure.
  • For a L2 contract, the rollup circuits (not contract specific) ensures that the sender and recipient matches what is stored in the contract-leaf and that the identifiers (chainid and version) matches the rollup in which it is executed (as specified in the state transitioner contract).

Note that these checks are automatically enforced on L2, but must be enforced by the portal implementation on L1.

When we are specifying a precise version in the message we have some undesired properties for messages that are yet to be consumed (“pending” messages). A message can be pending under different circumstances:

  • Bridging funds into L2, funds are locked on L1 while \mathcal{R}_c = \mathcal{R}_1 and:
    • the message is consumed by the state transition contract. But the upgrade happens BEFORE the message is consumed by the user on L2! When the user want to consume it on \mathcal{R}_c there will be issue since \mathcal{R}_c \neq \mathcal{R}_1 so the message and current chain don’t match and it would revert.
    • the upgrade happens before messages is consumed by the state transitioner. The user either gotta hope that i) the developer of the portal supports cancellation or ii) deposit it into an older rollup rollup where \mathcal{R}_c \neq \mathcal{R}_i and then exit from there (which might require him to also run a sequencer if no-one else wants to).
  • L2 → L1:
    • A user wants to exit a rollup, he creates an exit transaction and it is broadcasted to L1. BEFORE this messages is consumed, the upgrade happens, and the portal (following rollup governance) will not let him consume the message, since \mathcal{R}_c \neq \mathcal{R}_1

Supporting Pending Messages

To support consumption of pending messages, we have a couple of tricks up our sleeve.

Supporting pending L1 → L2

Abuse that if a message is moved along in an upgrade it have been inserted before the upgrade happened. Frist, include L1 block-number in the messages when they are inserted on L1. Second, let snapshots be available inside the circuits (add the snapshot tree root in the public inputs). It is then possible to allow consumption of messages that where moved along if it matches an earlier snapshot :sunglasses:. This supports the case where the pending message had left L1 but not yet executed on L2 as it is already in the state that was copied.

To support the second case, we must allow the current rollup to consume message that were not directly intended for it to be consumed by it. However, if it can consume any message, it can really mess up a fork. Also, we need a design that can distinguish between forks without relying on governance. To work around this, we use the address of the state transitioner as the “version” and have the max value, (type(uint160).max) mean that the message should be consumable by the current rollup \mathcal{R}_c (which the circuit can check from the snapshot).

This helps us cover both cases it is up to the user to decide on who can move his message from L1 to L2. The user has the power to decide if her messages can be moved by \mathcal{R}_c or only a specific version.

Supporting pending L2 → L1

To support this case, we can similarly to above include the L1 block number when messages are hitting the outbox. At the portal contract, it is possible to use the “age” of the message to deduce if it was there before or after upgrading. As before, it is still up to the portal to honor this, but it can be made easier with libraries and standards.

The portal contract must in its logic handle check that the sender is as expected, e.g., from the desired contract on the desired rollup. This can be more or less tricky depending on how nicely it want to support pending messages (follow standard or not).

Note that new messages from an older rollup would still NOT be accepted by the portal because the age would show that it was done after upgrade.

New message structure

The above changes mean that we get the following message structure, instead of the one defined in Aztec Docs | L1 ↔ L2 communication.

struct L1Actor {
    address: actorAddress,
    uint256: chainid,

struct L2Actor {
    bytes32: actorAddress,
    address: stateTransitioner,

struct L1L2CrossMsg {
    L1Actor: sender,
    L2Actor: recipient,
    bytes32: content,
    bytes32: secretHash,
    uint256: l1BlockNumber,

struct InnerL2L1CrossMsg {
    L2Actor: sender,
    L1Actor: recipient,
    bytes32: content,

struct L2L1CrossMsg {
    InnerL2L1CrossMsg: inner,
    uint256: l1BlockNumber,

If governance changes the messages boxes to use different logic, it might influence the ability to fork after that upgrade! Users must stay vigilant.

Efficient Mass Migrations for Immutable Portals

The goal is simple; support migrations from rollup A to rollup B for ungovernable portals in a way that has little financial overhead for the user.

At a high level, the idea can be though of as generating a merkle-tree of “migration balances” on L2, and then enqueue a transaction that will send the root along with a target and amount to the portal which transfers the funds to the target and updates a root value it in. The root can be ingested to a new L2 contract that allow “claims” of the migrated funds by the original sender.

Let say that we have the portal, \mathcal{P}_1, on L1 ands its matching L2 contract \mathcal{C}_1 that lives on the current rollup \mathcal{R}_1, the process is then as follows:

  1. Someone deploys a new portal \mathcal{P}_2 on L1 and its L2 contract \mathcal{C}_2 on the new rollup \mathcal{R}_2
  2. User initiate “migrate” with an L2 transaction on \mathcal{R}_1 that is inserting into a merkle tree in a public function on \mathcal{C}_1.
  3. At some point, a lot of people have initiated “migrations” and there is “critial” mass (amount of funds to migrate)
  4. Anyone can initiate a L2 → L1 message that sends the tuple (target, amount, merkle_root) to \mathcal{P}_1
  5. Anyone may then consume the message on L1 at \mathcal{P}_1, which sends amount and adds merkle_root into the target \mathcal{P}_2 which then sends a L1 → L2 message with the (amount, merkle_root) to \mathcal{C}_2.
  6. The new message is consumed \mathcal{C}_2 and set as a claim root.
  7. Users can execute a transaction on \mathcal{C}_2 that “claims” their funds on the new rollup

You could use an array of roots to support multiple migrations, or give users X time to do a large single one, depends on the usecase and users really.

Happy path

A new state transitioner is deployed, and a lot of users want to move to it instead of this old deployment. They are following the scheme, and made two L2 transactions to move their funds (1 to deposit from \mathcal{R}_1 and 1 to claim on \mathcal{R}_2). The user needed to be somewhat active to make sure that he performed his migration initiation while there was still plenty of activity such that he could benefit from the shared costs.

Sad path

If the migration is to happen because sequencers are censoring heavily, they might censor all migration tries, which will degrade the UX since it requires the user to use L1 for forced inclusion. The inclusion is still cheaper than solo exiting, as the final migrate transfer is shared, but will have a faily high cost for the user as it is now a L1 transaction and a L2 transcation (L2 tx as we assume the new sequencer are not censoring on the fork).


I like this proposal a lot. The ‘maximizing user optionality’ portion of governance is an interesting approach and highly-differentiated from the routes that we’ve seen most decentralized orgs take in the last few years. This sits at an interesting place in trade-off space between decentralization, friction of burdensome governance, and optionality for ecosystem participants. I appreciate the creativity here too.

My biggest questions are around what token governance for senators will actually look like. For one, it seems like a potentially bad idea for senators and the technical council to both be voted in by the same entity (the set of token holders). This is also relevant around voter apathy – Is there a minimum threshold in which the Senate might need to be elected? If, for example, only 5% of tokenholders vote, only ~2.5% of all token holders could vote to elect a malicious Senate, drastically decreasing the cost of a governance attack (for reference, lots of governance proposals in crypto today get single-digit participation rates).

This is all mitigated somewhat by the ability to pause the power of the senate in a state of emergency, but curious to hear any thoughts on how to improve this part of the proposal. Overall, I’m a big fan of Lasse’s Republic!


It might be trouble-some to have the same entity (token holders) pick both senators and council, but I am not sure how else you would do it, without it becoming token holders through extra steps? The council members don’t yield any extraordinary power compared to basic community members (though some authority from their position), it is more a way to reward participants of the discussion that can provide technical analysis of the proposals (such as auditors etc) without requiring them to take part in decisions itself.

I think all token voting today require some quorum before anything is accepted as a valid proposal. However, the % is often quite low due to voter apathy, some of the idea with the senate is that we might be able to increase the % participating as they need to do it less often, but in the end, would not expect it. The Senates main “benefit” is that it makes governance more explicit instead of hidden behind delegates where only a handful participate anyway.

For example, the last Synthetix spartan council election had 306 votes cast, where some of the latest Aave proposals had <20 votes cast.

Generally, I don’t think token governance is ideal, but if Aztec is to support upgrades without having everyone migrate, I have a hard time seeing us getting beyond it, as it still seems better than a benevolent multisig. Much of the proposal here is me ensuring that if we need token governance, I have a way to ignore the governance if I think they take bad decisions.

I will accept the existance of governance, as long as I am free to ignore them completely.



yeah, i like that intent as a tagline – “I will begrudgingly accept the existence of token voting… as long as I am free to ignore it completely.” :grinning:

thanks for this proposal Lasse, I’m in support


Great proposal, Lasse. Truly appreciate the amount of thought you put into this.

Now that there are other proposals (non-governance) would you mind updating the comparisons section? I think that this comparison specifically would be valuable in highlighting the extent to which optionality trickles down into the rest of the ecosystem. For example, with non-governance, there are some specific questions about token minting and swaps - how is this different within the republic?

1 Like

As I see it, The Republic does two things:

  • It provides us with some “authority” that can yell about what the “real” rollup is
  • It establishes a mechanism, where we are free to ignore this authority if desired

The first point allows us, with a functioning senate to handle the “who can mint rewards” issue from non-governance, the senate (and thereby token holders) decide. Also, it gives us this “nice” upgrade flow when we want to upgrade to what the senate proposes, as it can handle pending messages for this case well.

The second points allows us to always degrade to non-governance if we think the Senate is making wrong decisions. One main difference though, when degraded, it adds a time constraint to the exits that is not part of non-governance, so a malicious senate can be a bigger threat.

If you have a useless senate in the Republic all upgrades will happen through migrating away to things not proposed by the senate, and no other rollup will be able to mint Azt for rewards. You are back to bootstrapping the new rollups.

I see non-governance as a sub-set of the Republic. In their most inefficient form they both require mass migrations and bootstrapping of networks. But with a better than useless senate, the Republic can more easily coordinate, and coordination is more explicit.

The biggest difference I see between the two, is how explicit they define what the “real” rollup is. For non-governance, I think you would see rise of something similar to an implicit senate that have a registrt for the “real” rollup that other portals can follow, this registry might be end up controlled by Circle or the like.
At that point the main difference is then if you want to make it an explicit part of the protocol and use it to make pending messages easier to handle.


A few months late here, but truly impressive the amount of time and thought put into this. Some high-level thoughts:

  • Agree that the ability to have a voted-in “higher-level authority” is important if issues arise about which rollup is real. The main friction point will probably arise if rollup confusion exists around an election time. People could be economically incentivized to run purely for that reason. Staggering who is elected when could be helpful here.

  • Should the technical council just be appointed versus voted in? Often technical experts are not interested in having to participate in any sort of election process, and the best ones can be identified by a larger group and simply appointed?

  • Veto rights / Emergency Shutdown procedures are often powerful enough via the threat alone to prevent adverse action, as long as the token holders have appropriate time and structures in place to actually vote. Activating a veto / emergency shutdown becomes problematic when those participants rarely have to do anything and then are expected to immediately act on a topic, especially for non-retail holders. Curious if there’s thoughts on ways to structure this process? Lido is working on something similar with their dual-governance proposals, there could be some ideas embedded there, although this would be functionally different unless there was a voting vehicle at play, like stETH in Lido.

  • Regarding upgrades and opt-outs. Somewhat similar to the veto structures, time and predictability are important. Can there be a cadence for users to pay attention to, where upgrades can only occur at certain intervals (quarterly, beginning of month, etc.)?

1 Like

Hi @psmith,

If there is rollup confusion, that seems like a decent time to have elections? I would say you can then vote to get around the confusion possibly changing the senate if voters don’t think they are representing them anymore etc.
I think someone will always run purely for economics :man_shrugging:.

I think appointed by a larger group is somewhat similar to voted in? I wanted it to be voted in similarly to the senate to ensure that the senate would not be the ones appointing puppets or similar, could still happen, but seemed a little less likely.

For the veto, I am not sure on the exact way to structure it, I like shutdown through burn as for Makerdao as it can be coordinated fully out of protocol or by a single large sacrificer.

Since the updates are mainly planned way ahead because they already need significant delay, I think it could be an option to only do it in certain internals, but it is not something I have thought a lot about.