Expand description

§Phragmén Election Module.

An election module based on sequential phragmen.

§Term and Round

The election happens in rounds: every N blocks, all previous members are retired and a new set is elected (which may or may not have an intersection with the previous set). Each round lasts for some number of blocks defined by Config::TermDuration. The words term and round can be used interchangeably in this context.

Config::TermDuration might change during a round. This can shorten or extend the length of the round. The next election round’s block number is never stored but rather always checked on the fly. Based on the current block number and Config::TermDuration, the condition BlockNumber % TermDuration == 0 being satisfied will always trigger a new election round.

§Bonds and Deposits

Both voting and being a candidate requires deposits to be taken, in exchange for the data that needs to be kept on-chain. The terms bond and deposit can be used interchangeably in this context.

Bonds will be unreserved only upon adhering to the protocol laws. Failing to do so will cause in the bond to slashed.


Voters can vote for a limited number of the candidates by providing a list of account ids, bounded by Config::MaxVotesPerVoter. Invalid votes (voting for non-candidates) and duplicate votes are ignored during election. Yet, a voter might vote for a future candidate. Voters reserve a bond as they vote. Each vote defines a value. This amount is locked from the account of the voter and indicates the weight of the vote. Voters can update their votes at any time by calling vote() again. This can update the vote targets (which might update the deposit) or update the vote’s stake (Voter::stake). After a round, votes are kept and might still be valid for further rounds. A voter is responsible for calling remove_voter once they are done to have their bond back and remove the lock.

See Call::vote, Call::remove_voter.

§Defunct Voter

A voter is defunct once all of the candidates that they have voted for are not a valid candidate (as seen further below, members and runners-up are also always candidates). Defunct voters can be removed via a root call (Call::clean_defunct_voters). Upon being removed, their bond is returned. This is an administrative operation and can be called only by the root origin in the case of state bloat.

§Candidacy and Members

Candidates also reserve a bond as they submit candidacy. A candidate can end up in one of the below situations:

  • Members: A winner is kept as a member. They must still have a bond in reserve and they are automatically counted as a candidate for the next election. The number of desired members is set by Config::DesiredMembers.
  • Runner-up: Runners-up are the best candidates immediately after the winners. The number of runners up to keep is set by Config::DesiredRunnersUp. Runners-up are used, in the same order as they are elected, as replacements when a candidate is kicked by Call::remove_member, or when an active member renounces their candidacy. Runners are automatically counted as a candidate for the next election.
  • Loser: Any of the candidate who are not member/runner-up are left as losers. A loser might be an outgoing member or runner-up, meaning that they are an active member who failed to keep their spot. An outgoing candidate/member/runner-up will always lose their bond.
§Renouncing candidacy.

All candidates, elected or not, can renounce their candidacy. A call to Call::renounce_candidacy will always cause the candidacy bond to be refunded.

Note that with the members being the default candidates for the next round and votes persisting in storage, the election system is entirely stable given no further input. This means that if the system has a particular set of candidates C and voters V that lead to a set of members M being elected, as long as V and C don’t remove their candidacy and votes, M will keep being re-elected at the end of each round.

§Module Information



  • All migrations. All migrations of this pallet.
  • The pallet module in each FRAME pallet hosts the most important items needed to construct this pallet.
  • Autogenerated weights for pallet_elections_phragmen


  • A holder of a seat as either a member or a runner-up.
  • An active voter.


  • An indication that the renouncing account currently has which of the below roles.