ZIP 11: Futarchy

This ZIP outlines the design and implementation of zrml-futarchy.

Futarchy in Theory

Futarchy is a mode of governance defined by R. Hanson in [RH03]. An organization (nation, city, corporation, DAO, etc.) governed by futarchy selects its values (how is welfare measured?) using some form of a democratic vote, but uses prediction markets in which informants bet on their beliefs to aggregate information on which policies will improve the organization's welfare and which policies won't.

In futarchy, decisions about policy are delegated to prediction markets. In
these markets, the efficacy of the policies is estimated in terms of a
pre-defined welfare measure, a scalar measure of how well things are going for
the organization. Depending on the measurements made using the prediction
markets, the policy is either adopted or not. By proceeding in this fashion,
organizations governed by futarchy rely on the
Wisdom of the Crowd instead
of the "public relations teams, organized interest groups, news media,
conversation forums, think tanks, universities, journals, elite committees, and
state agencies" (see What is Futarchy? - Trading on The Future - Friederike Ernst #TOA18). Decisions are based purely on merit (improving the welfare
measure) and those who promote bad or corrupt policy are economically punished,
even if they succeed in the short term.

Futarchy also represents an alternative to the typical approaches to on-chain
governance. As on-chain identities do not necessarily correspond one-to-one to
off-chain identities, "One man, one vote" democracy is infeasible in the
blockchain context. Previous endeavours to finding a good replacement
(Polkadot democracy,
token holder votes,
token curated registries)
have mostly led down the same road: token-based voting.[^3] This essentially
puts the decisions into the hands of the powerful few. Futarchy walks a
different path. Once the welfare measure is set, policy decision become matter
of fact and are decided upon not by vote, but by bet.

Examples

It's easiest to illustrate this new concept through the use of an example.
Suppose that a group wants to make large-scale decisions using futarchy. This is
done by first selecting the welfare measure In case of a publicly traded
company, this could be the stock price of the company.

When a yay/nay decision needs to be made (for example: "Should we fire our CEO?"
for a public company), two scalar markets are created:

  • M0
    : What's the stock price next year if the CEO is fired?
  • M1
    : What's the stock price next year if the CEO is not fired?

These markets will run for some time and provide a prediction for which decision
is better: The difference

s0s1 between the results of
M0
and
M1

approximates the effect of firing the CEO on the stock price. If the estimate of
M0
is larger than the estimate of
M1
, then the stock price is expected to
increase. This means that the CEO actually gets fired and the trades of
M1

are cancelled (this is done as we have no way of ever knowing what the stock
price would have been if the CEO had remained in place). If, on the other hand,
the estimate of
M1
is larger than that of
M0
, then the CEO keeps their job
and the trades of
M0
are cancelled.

The traders in favor of firing the CEO can buy exposure to both markers by
acquiring LONG shares of

M0 and SHORT shares of
M1
. Similarly, traders in
favor of keeping the CEO in place can buy SHORT of
M0
and LONG of
M1
.
Therefore, both parties have skin in the game regardless of what decision is
eventually made. If the decision turns out to be good (stock price is as
predicted or higher), then the traders will on average profit from participating
in the market. If the decision turns out to be bad (stock price is lower than
predicted), then most traders will suffer losses.

Other scenarios can be approached using this pattern. If a political party
wishes to select a candidate in order to maximize their change of winning, they
might select their share of the popular vote as the welfare measure and open a
scalar market for each candidate

i:

  • M0i
    : What will our share of the popular vote be if we choose
    i
    as
    candidate?
  • M1i
    : What will our share of the popular vote be if we don't choose
    i
    as
    candidate?

Of course, these are only toy examples of applications of futarchy. The
processes above can be embellished in a multitude of ways. For example, maybe
the motion to fire the CEO should only be put into action if there is a clear
difference between the stock prices

s0 and
s1
(say, 5 percent). We
encourage you to take a look at section IX. A Reference Proposal of
Shall We Vote on Values, But Bet on Beliefs?
for a deeper dive into the topic.

Governance Flow

The futarchy governance flow we will implement is deliberately kept simple:

  • A hard-coded origin (account or abstract) may submit proposals. A proposal consists of the following information:
    • The oracle that decides if the proposal should be enacted or not.
    • The call that is made if the proposal is enacted.
    • A point in time at which the oracle is evaluated.
  • When the blockchain arrives that the specified point in time, the oracle is evaluated.
  • If the oracle evaluates positively, the proposal's call is scheduled to be executed at the specified point in time.

An oracle is an on-chain object which can, at any point in time, be evaluated and returns either true or false.

What we've described so far is just an oracle-based governance system. What makes this actual futarchy is the choice of oracle. In the first iteration of Zeitgeist's futarchy, the oracle is comprised of the following data:

  • A pool ID pointing to a neo-swaps liquidity pool.
  • A positive outcome.
  • A negative outcome.

The oracle evalulates positively on a block

b if the price of the positive outcome at
b
is larger than the price of the negative outcome.

Using this oracle, the standard futarchy design described in the section above can be implemented as follows:

  • Create a binary market which resolves positively if the proposal
    X
    is implemented.
  • Create a scalar market which predicts the value of the welfare measure.
  • Create a combinatorial pool of these two markets.
  • Use
    XLong
    as positive outcome and
    XShort
    as negative outcome.

The proposal will then only be enacted if the market predicts that

X will strictly increase the welfare measure of the organization.

Implementation

The futarchy service is implemented as a substrate pallet and will be used in the Zeitgeist and Battery Station runtimes. Here is a rough outline of the pallet's Config:

  • The pallet will implement a minimum duration for all proposals which ensures that pools are open long enough before the oracle is evaluated.
  • The pallet will schedule calls through substrate's ScheduleAnon trait. In production, pallet-scheduler will be used to implement this trait.
  • The pallet will use an abstract Oracle type to allow testing its functionality against a mock oracle. The Oracle type must implement the FutarchyOracle trait provided by zeitgeist-primitives:
  • The pallet may use an associated benchmark helper type which implements a trait provided by zeitgeist-primitives to aid in the creation of mock oracles when running benchmarks.
pub trait FutarchyOracle {
    /// Evaluates the query at the current block and returns the weight consumed and a `bool`
    /// indicating whether the query evaluated positively.
    fn evaluate(&self) -> (Weight, bool);
}

The oracle type used in production will be implemented using zrml-neo-swaps. Specifically, neo-swaps will provide the DecisionMarketOracle type which implements FutarchyOracle by looking up self.pool_id, and then querying and comparing the prices of the specified outcomes. It will be implemented pessimistically in the sense that if the pool is not found or a calculation errors unexpectedly, then it will evaluate negatively.

The only extrinsic of zrml-futarchy is submit:

/// Submits a `proposal` for evaluation in `duration` blocks.
///
/// If, after `duration` blocks, the oracle `proposal.oracle` is evaluated positively, the
/// proposal is scheduled for execution at `proposal.when`.
pub fn submit_proposal(
    origin: OriginFor<T>,
    duration: BlockNumberFor<T>,
    proposal: Proposal<T>,
) -> DispatchResult;

The proposal type mentioned in the signature of submit_proposal is:

pub struct Proposal<T>
where
    T: Config,
{
    /// The time at which the proposal will be enacted.
    pub when: BlockNumberFor<T>,

    /// The proposed call.
    pub call: BoundedCallOf<T>,

    /// The oracle that evaluates if the proposal should be enacted.
    pub oracle: OracleOf<T>,
}

In production, calls will be bound using pallet-preimage.

Future Work

  • Extensive dogfooding is recommended before continuing its development.
  • Avoid market manipulation by using and averaging process or a candle auction to evaluate the oracle.
  • Take liquidity of the pool into account. Depending on the severity of the proposal's call the pool should have a minimum liquidity when the oracle is evaluated.
  • Lower the bar of entry for submitting futarchy protocols and take a fee instead. It should be fine to create any sort of proposal as long as pools have a certain minimum liquidity.
  • It is recommended to make court compatible with scalar markets before using combinatorial pools involving scalar markets to make governance decisions.

Bibliography

  • H13 R. Hanson, "Shall We Vote on Values, But Bet on Beliefs?," The Journal of Political Philosophy, vol. 21, no. 2, pp. 151-178, 2013.
  • MK24 M. Kliemann, "How to Design Better On-Chain Governance: An Introduction to Futarchy and Combinatorial Prediction Markets," CoinDesk, Mar. 27, 2024. [Online].