SIP-207: V3GM Election Module

ProposalLoading status...

Simple Summary

This SIP introduces one of the first components of the V3 Governance Module - called the Election Module. The Election Module is proposed to replace the existing Snapshot election process carried out by the Synthetix DAOs whilst also providing a standard module which other protocols can use for their governance system.


If this meta-governance proposal is approved, the Election Module will replace the off-chain elections carried out on Snapshot (i.e example election space) - by deploying, on Optimism, a modular on-chain solution which will be configured to the existing governance election standards of Synthetix.


Since the introduction of SIP-93 - Delegated Council Governance which mainly introduced the Spartan Council the Synthetix Governance has evolved.

In the Synthetix Governance System - there are currently 5 official bodies

  • Spartan Council
  • Ambassador Council
  • Grants Council
  • Treasury Council
  • Core Contributor Committee

In the journey to this current stage - the Synthetix Governance system has relied heavily on using apps that are still constantly improving (i.e Snapshot, Synthetix Staking dApp).

As the protocol governance grew, the protocol started out-growing existing processes, identifying the need to start building a system surrounding the current and future plans of Synthetix Governance - leading to the catalyst behind the V3GM (V3 Governance Module) product squad within the Core Contributors.

One of the first things that the protocol needed to solve was removing the centralized aspect of the governing body elections - the Election Module was built to replicate most of the election process that happens on snapshot into a modular and customizable on-chain solution.

More specifically - the election module addresses:

  • Centralization of election strategy updating (both on snapshot team and synthetix cc’s)
  • Dependency on Core Contributors collecting nominations on Discord
  • Dependency on Core Contributor/pDAO in transferring the Council/Committee NFTs on the conclusion of an election
  • Standardize elections within the Web 3.0 space so other projects can replicate delegated governance

The Core Contributor Commmittee is excluded from the governance election module described in this SIP and will continue to be voted on via snapshot voting, with their responsibilities outlined in SIP-232.



The Election Module is a factory set of smart contracts that given parameters relating to the delegated group it represents (i.e seat number, epoch length) will enable the necessary election processes to occur on-chain in a modular and decentralized way.


In the process of the V3GM - Election Module R&D phase, the following design decisions were considered

  • On-Chain Implementation
  • Ethereum L1 vs Optimism L2
  • NFT Membership Issuance
  • Implementation of Voting Strategies
  • Transparency and Verification
  • Scheduling
  • Pagination to Prevent Gas Limit Reverts
  • Ties Exceeding Seats Count
  • Module Initialization (epoch 0)
  • L1 and L2 Debt Synthesis
  • Council Members Dismissals
  • Election Metadata
  • Staking dApp Frontend Enhancement - No need to Vote to Claim on the first release
  • Staking dApp Frontend Enhancement - Fast Election Widget

On-Chain Implementation

The existing election process happens off-chain on Snapshot - one of the main problems that arose due to this was the amount of discretion and centralization that was present in one of the most important meta-governance processes.

When an election was concluded - the community had to trust the protocolDAO in replicating the results of the elections on-chain via the transferring of NFTs which granted the council members their ability to vote on proposals*

With the election module being on-chain all of this can be automated based on-chain actions and data.

*Proposals in this early revision are to still be carried out on snapshot until the introduction of the Governor Module, this is further explained in the Council Dismissal section

Ethereum L1 vs Optimism L2

With the increased usage of Ethereum L1, the cost of conducting elections on Ethereum L1 contracts would not be viable for the general community and would limit participation of voters and nominees. To find the balance between conducting the election on-chain while keeping cost low, the Optimism L2 network was selected.

NFT Membership Issuance

To reduce the complexity and confusion involved in rearranging the NFTs via transfer after a election is resolved, the previous council member NFTs are burned and a new set is minted for the new council members.

Implementation of Voting Strategies

There are many different voting methods and alternatives to choose from when implementing an election system. In order to meet the needs and demands of different bodies or organizations the system was designed to be flexible to support a wide range of Election configurations:

  • Ballot Configuration: Which defines how the voter is allowed to vote for an election.
    • Examples are: single choice, multiple choice, ranked multiple choice
  • Votes: A vote is broken down into two components;
    • Voting Power - Defines how many units a vote contains. It can depend on one or several variables (token balance, debt share, etc.). The strategy could contain any arbitrary code that performs any arbitrary DeFi calculation, and returns the number of voting units a particular address has.
    • Voting Weight - Defines how each unit is scaled. It takes the Voting Power and performs some sort of arbitrary mathematics to return the scaled result (i.e linear, quadratic)
  • Vote Counting: Which defines how the votes are counted to identify the winner(s)
    • Examples are: plurality, STV, Condorcet winner, Borda’s winner

Note that some strategies will condition the options for the rest of the areas.

Strategy Implemented For V3GM

In order to have a limited scope, this SIP will allow for different strategies while only implementing a direct replacement of V2 voting strategy. This means, the following considerations are taken for the Voting Strategy:

  • Ballot Configuration: The implementation supports one candidate per vote, applying the voting power to it. Voters can change the candidate voted.
  • Voting Power: A user's debt share balance (acquired from the Synthetix Debt Shares contract) is snapshotted at the beginning of an epoch.
  • Voting Weight: Quadratic. 1 debt unit = sqrt(1) vote.
  • Vote Counting: The strategy to implement is Plurality. The Voting Power received from voters is added to the voted candidate(s). The most voted candidates are elected to be the new members.

Transparency and Verification

The election data must be accessible to audit and challenge the results. All election related actions should emit events. Candidates, Ballots, Voters and Results will be publicly available and verifiable.


The scheduling indicates when the different periods start and end. The system is designed in a way that the length of the periods are preserved from one epoch to the other with the beginning of the epoch as a time reference when the previous epoch is closed (i.e success call to resolve()).

An example of an epoch and how scheduling works follows:


  1. Epoch Number = 5
  2. Epoch Length = 3 Months
  3. Epoch Start Date = 1st January
  4. Nominations Starts = 18th March
  5. Voting Starts = 25th March
  6. Voting Ends = 1st April

After the voting closes, the election can be evaluated (evaluate()) and later resolved ( resolve()). The new epoch is automatically started with the epoch length.

It is important to note that drifting may occur due to the evaluation and resolution stages being kept. To help maintain human-friendly dates, the epoch scheduling can be adjusted in two ways:

  1. Via a fine tuning mechanism, where the epoch scheduling can be adjusted up to a predefined tolerance
  2. Via a protected tuning mechanism, where the epoch scheduling can be adjusted without restrictions - this will be considered a metagovernance change and will require a SCCP.

Note: The two mechanisms of adjusting the scheduling, for the scope of this SIP, are restricted to onlyOwner (pDAO). Eventually it will be managed by the GovernorModule and both methods can have different requirements to be executed.

The epoch periods defined are:

  • Administration Period: The period in which the current members of a council operate, before the next nominations have begun. This is the only period where durations can be tweaked.
  • Nomination Period: During this stage the only available action for the election of the next council is nominations. Addresses can self nominate (or withdraw their self-nomination). The result of this period is a fixed list of candidates.
  • Voting Period: during this stage the only available action for the election of the next council is cast. Addresses (voters) cast votes for the ordered list of candidates. It is possible to re-cast a vote to change the candidates voted, the latest casted vote is the only one that takes effect. The result of this period is a set of ballots and the accumulated votes for each.
  • Evaluation Period: This period is fixed so that the election can be evaluated (votes counted) and resolved (new council is formed). The election is evaluated by batches (a small election may fit in only one batch) using one tx per batch to prevent gas exhaustion, once the election is evaluated, the election is resolved in a separate tx.

Pagination to Prevent Gas Limit Reverts

Given the number of candidates and votes is not limited, processing or accessing them can lead to large arrays processing which can cause out-of-gas execution errors. To prevent this, all functions that need to iterate over such arrays need to implement pagination.

Public/protected functions that need to process data looping over the candidates or ballots need to implement an iteration process. The following piece of code shows an example of how the UI or script runs the evaluate process.

The process uses a boolean flag that can be retrieved with `isElectionEvaluated()`, it shows if all the ballots were processed or there are still pending ballots to check. To process a new batch of ballots the `evaluate()` function that will use an internal property to identify the latest item processed. In this case, the batch size is set as the parameter of the evaluate() function or if set to 0 it will use a default value that can be updated using the setter `setDefaultBallotEvaluationBatchSize()`.
    let finished = await ElectionModule.isElectionEvaluated();
    while (!finished) {
      await (await ElectionModule.evaluate(0)).wait();
      finished = await ElectionModule.isElectionEvaluated();

Ties Exceeding Seats Count

An election can result in a tie for a set of candidates that are potential winners of the election. If there are seats available for all of them, they will form the new council. If there are not enough seats for the tied candidates there should be a mechanism to define which of them are going to be part of the council (identify as winners).

For that edge case, the solution proposed in the SIP is to let the contract pick the candidate based on how the counting strategy finds the matches (first candidate found will fill a seat).

If later (after exposing the ElectionModule to real world elections) there’s a need to get another kind of solution, the analysis of the alternatives and implementation of another strategy will be considered in another SIP.

Module Initialization (Epoch 0)

When the ElectionModule is first initialized, the first council members and dates can be set.

The ElectionModule initialization function receives:

  • a list of addresses that will be granted the Council Token NFT,
  • Nomination period start date (nominationPeriodStartDate),
  • Voting period start date (votingPeriodStartDate), and
  • Epoch end date (epochEndDate).

With those parameters the first epoch can be arbitrarily set as the first real action council, or a temporary one until the first election is done.

L1 and L2 debt synthesis

While all the election steps are conducted on L2, there is still a large pool of voters’ that have a voting weight on L1, to include these voters, a intermediary solution will be used which involves using a merkle tree snapshot of L1 debt holders that is uploaded into the L2 instance.

In the near future, this solution will optimally be replaced by the debt migration work within the V2.X Synthetix scope.

Council Members Dismissals

In the event of one or several council members acting out of line with the expectation of the token holders, token holders will be able to create a snapshot proposal for the council to execute akin to the current SIP/SCCP process. To achieve parity with the existing V2.X governance, the protocolDAO will be the only user who is able to dismiss council member(s) according to the proposal outcome. The proposal outcome is considered to be positive (i.e. dismissal should be implemented) if the meta-governance vote passes with a quorum of n-1. Although this SIP touches on the topic of dismissal, the GovernanceModule will flesh out more details on the specificity of the cases pertaining to dismissal and veto, while SIP-207 sets out the guidelines on the election module mostly.

The Election Module was designed to not handle dismissals internally as it is too specific to the implementation of Synthetix and instead assumes that implementation of dismissals will be handled by the GovernorModule via an on-chain proposal.

If the number of council members goes below the minimum accepted number to work as a council (minimumActiveMembers), initially set to 1, the whole council is demoted and a new election is expedited. During this special expedited election, the Election Module will operate under a headless state, in the first instances of the Election Module implementation this means that the owner will be the only “council” but in future iterations the GovernorModule will control the Election Module which means that the temporarily governing of the system will fallback to the token holders or delegated to an external fallback council (i.e DeFi Union). After the election is resolved, a new epoch is started and the newly elected council will act as a valid council. If the dates for the next nomination and election phases are not according to the calendar, the council can fix the dates as explained in scheduling. In future SIPs the minimumActiveMembers will be revised to any configurable bounded number, as updates to the election module allow for configuration based on different council bodies, for now it is just an on-chain placeholder updateable by pdao, should a meta-governance vote pass.

*Everything under this section was added in a newer revision of this SIP (12/04/22)

Election Metadata

While developing the Election Module dApp, the V3GM contributors have discovered the need for a solution to host the metadata of nominees and voters. In this first release of the V3GM we will be using Boardroom's SDK to fetch and push profile data so that nominees and voters can contextual their decisions.

The Boardroom SDK uses a centralized database in combination with Sign-In With Ethereum and Arweave to store, fetch and organise wallet specific data. The Boardroom team will add the Election Module into their framework so the V3GM Contributors will be able to leverage it in the dApps.

Staking dApp Frontend Enhancement

While an election is going on, the staking dApp will not require that L1 and L2 stakers vote in order to claim their weekly SNX rewards. The staking dApp will also be modified to read the Election Module states so that it will show contextual information on the status of Elections. In addition, the UI will incorporate a restriction on 1 council nomination per address, althought, no restriction is incorporated into the contracts.

Staking dApp Frontend Enhancement - Fast Election Widget

As the staking dApp is still heavily used, the Election Module will be integrated into the Staking dApp so that users can quickly vote during an Election if they do not prefer to visit the dedicated Governance dApp which the Election Module will be housed in.

Configurable Values (Via SCCP)

  • minimumActiveMembers : Minimum number of members left on the council before we are in a headless state situation.
  • nextEpochSeatCount: Number of members in the next epoch
  • minEpochDuration: Duration of an epoch during which members serve and their votes are valid
  • minNominationPeriodDuration: Minimum nomination period duration
  • minVotingPeriodDuration: Minimum voting period duration when adjusting schedules
  • maxDateAdjustmentTolerance: Maximum size for tweaking epoch schedules (see tweakEpochSchedule)
  • defaultBallotEvaluationBatchSize: Default batch size when calling evaluate()

Note that minEpochDuration and nextEpochSeatCount can be changed during the Administration period only.

Copyright and related rights waived via CC0.