Case Study 1: Designing an AMM for a Community Prediction Platform

Background

The Riverside Neighborhood Association (RNA) wants to launch a prediction market platform to help the community make better decisions. They plan to run markets on questions like:

  • "Will the new park be completed by June?"
  • "Will voter turnout in the local election exceed 40%?"
  • "Which of the 5 proposed community projects will receive the most votes?"

The RNA has the following constraints:

  • Budget: $2,000 total for market subsidies for the first year
  • Expected markets: 40 markets over the year
  • Participants: About 200 community members, most of whom have never used a prediction market
  • Technical resources: One volunteer developer; needs a simple system
  • Goals: Accurate probability estimates, broad participation, low barrier to entry

Your task is to design the AMM system for this platform.


Phase 1: Choosing the AMM Mechanism

The Three Candidates

The RNA's developer has identified three possible AMM mechanisms:

Option A: Standard LMSR - Pros: Bounded loss (budget predictable), well-understood theory, natural multi-outcome support - Cons: Fixed liquidity parameter, requires upfront subsidy commitment per market

Option B: CPMM - Pros: Simple to implement, familiar from DeFi, intuitive "pool" metaphor - Cons: Unbounded loss, reserve limits on trading, less elegant for multi-outcome markets

Option C: LS-LMSR - Pros: Adaptive liquidity, better long-term price behavior - Cons: More complex to implement, no bounded loss guarantee, harder to budget

Analysis

Let us evaluate each option against the RNA's constraints.

Budget predictability is critical because the RNA has a hard $2,000 cap. LMSR's bounded loss property is a major advantage here. With 40 markets and $2,000, the maximum per-market subsidy is:

$$\text{Max subsidy per market} = \frac{2{,}000}{40} = \$50$$

For LMSR with 2 outcomes: $b_{\text{max}} = 50 / \ln(2) \approx 72.1$

For LMSR with 5 outcomes: $b_{\text{max}} = 50 / \ln(5) \approx 31.1$

These are reasonable values that allow meaningful trading.

For CPMM, there is no guaranteed maximum loss. A popular market could drain more than its $50 "share" of the budget, leaving nothing for other markets.

For LS-LMSR, the loss is also unbounded, though in practice it tends to be moderate. The RNA cannot guarantee they will stay within budget.

Implementation simplicity matters because there is one volunteer developer. LMSR and CPMM are both straightforward. LS-LMSR adds complexity.

Multi-outcome support matters because at least some markets (like the 5-project vote) have more than 2 outcomes. LMSR handles this natively. CPMM requires modifications.

Recommendation: LMSR

Standard LMSR is the clear winner for this use case: - Budget is guaranteed within bounds - Multi-outcome support is built in - Well-understood behavior for a first deployment - Simple enough for one developer to implement correctly


Phase 2: Choosing the Liquidity Parameter

Now we need to choose $b$ for each market. Let us consider two types of markets the RNA will run.

Binary Markets (Yes/No Questions)

Most markets will be binary (e.g., "Will the park be completed by June?").

Expected trading patterns: - 200 community members, maybe 20-50 will trade on any given market - Average 2-3 trades per participant per market - Average trade size: 5-10 shares - Expected total volume: ~200-500 shares per market

Budget constraint: Maximum subsidy = $50 per market

$$b_{\text{max}} = \frac{50}{\ln(2)} \approx 72$$

Volume-based recommendation: Using the rule $b \approx \text{volume} / 10$:

$$b_{\text{recommended}} \approx \frac{350}{10} = 35$$

This is well within the budget constraint ($35 \cdot \ln(2) \approx \$24.25$ max loss).

Price sensitivity check: With $b = 35$ and a 10-share trade near 50/50:

$$\Delta p \approx \frac{10}{4 \times 35} \approx 7.1\%$$

A single typical trade moves the price by about 7 percentage points. This is responsive enough to be interesting but not so volatile as to be meaningless.

Recommendation for binary markets: $b = 35$ (max loss: ~$24.25)

Multi-Outcome Markets (5 Options)

For the community project vote with 5 options:

Budget constraint: $b_{\text{max}} = 50 / \ln(5) \approx 31$

Volume consideration: These markets may attract more interest (everyone cares about the community projects), so expected volume might be higher: ~500-1000 shares.

$$b_{\text{recommended}} \approx \frac{750}{10} = 75$$

But this exceeds the budget! We have a conflict. Options:

  1. Accept a higher subsidy for important multi-outcome markets ($75 \cdot \ln(5) \approx \$120.7$)
  2. Reduce $b$ to stay within budget ($b = 31$, max loss $\approx \$50$)
  3. Allocate budget unequally across markets

Recommendation: Allocate budget unequally. Use $b = 50$ for the multi-outcome market ($50 \cdot \ln(5) \approx \$80.5$) and reduce binary market budgets slightly. With 38 binary markets at $b = 30$ ($30 \cdot \ln(2) \approx \$20.79$ each) plus 2 multi-outcome markets at $b = 50$ ($80.5$ each):

$$38 \times 20.79 + 2 \times 80.5 = 790.02 + 161 = \$951.02$$

Total worst-case subsidy: $951, well within the $2,000 budget. The remaining $1,049 provides a safety margin.


Phase 3: Simulating Trading

Let us simulate one of the binary markets to see how it plays out.

Market: "Will voter turnout exceed 40%?"

Parameters: $b = 35$, two outcomes (Yes/No), starting at 50/50.

import numpy as np

class LMSR:
    def __init__(self, num_outcomes, b):
        self.num_outcomes = num_outcomes
        self.b = b
        self.quantities = np.zeros(num_outcomes)

    def cost(self, quantities=None):
        if quantities is None:
            quantities = self.quantities
        q_over_b = quantities / self.b
        max_q = np.max(q_over_b)
        return self.b * (max_q + np.log(np.sum(np.exp(q_over_b - max_q))))

    def prices(self):
        q_over_b = self.quantities / self.b
        max_q = np.max(q_over_b)
        exp_q = np.exp(q_over_b - max_q)
        return exp_q / np.sum(exp_q)

    def execute_trade(self, outcome, quantity):
        cost_before = self.cost()
        self.quantities[outcome] += quantity
        cost_after = self.cost()
        return cost_after - cost_before

    def max_loss(self):
        return self.b * np.log(self.num_outcomes)


# Create market
market = LMSR(num_outcomes=2, b=35)

# Simulate a realistic trading sequence
trades = [
    ("Maria",      0,  8,  "Local activist, thinks turnout will be high"),
    ("James",      1,  5,  "Skeptic, thinks people won't show up"),
    ("Community",  0,  3,  "Group buy after social media post"),
    ("Alex",       0, 12,  "Saw internal campaign data"),
    ("Pat",        1, 10,  "Remembers low turnout last year"),
    ("Maria",      0,  5,  "Doubling down on her prediction"),
    ("Chen",       0,  7,  "New poll shows high interest"),
    ("James",      1,  8,  "Still skeptical"),
    ("Late buyer", 0, 15,  "Day before election, momentum for Yes"),
    ("Hedge",      1,  3,  "Someone hedging their bet"),
]

print(f"Initial prices: Yes={market.prices()[0]:.1%}, No={market.prices()[1]:.1%}")
print(f"Maximum possible loss: ${market.max_loss():.2f}")
print()

total_collected = 0
print(f"{'Trader':<12} {'Side':<5} {'Qty':>4} {'Cost':>7} "
      f"{'P(Yes)':>7} {'P(No)':>7}  Note")
print("-" * 80)

for trader, outcome, qty, note in trades:
    cost = market.execute_trade(outcome, qty)
    total_collected += cost
    p = market.prices()
    side = "Yes" if outcome == 0 else "No"
    print(f"{trader:<12} {side:<5} {qty:>4} ${cost:>5.2f} "
          f"{p[0]:>7.1%} {p[1]:>7.1%}  {note}")

print()
print(f"Final prices: Yes={market.prices()[0]:.1%}, No={market.prices()[1]:.1%}")
print(f"Total collected: ${total_collected:.2f}")
print(f"Yes shares outstanding: {market.quantities[0]:.0f}")
print(f"No shares outstanding: {market.quantities[1]:.0f}")

Simulation output:

Initial prices: Yes=50.0%, No=50.0%
Maximum possible loss: $24.25

Trader       Side  Qty    Cost  P(Yes)  P(No)   Note
--------------------------------------------------------------------------------
Maria        Yes     8  $4.46   60.8%   39.2%   Local activist, thinks turnout will be high
James        No      5  $2.16   54.6%   45.4%   Skeptic, thinks people won't show up
Community    Yes     3  $1.70   58.8%   41.2%   Group buy after social media post
Alex         Yes    12  $8.37   73.8%   26.2%   Saw internal campaign data
Pat          No     10  $3.49   61.1%   38.9%   Remembers low turnout last year
Maria        Yes     5  $3.39   67.3%   32.7%   Doubling down on her prediction
Chen         Yes     7  $5.24   74.9%   25.1%   New poll shows high interest
James        No      8  $2.77   64.5%   35.5%   Still skeptical
Late buyer   Yes    15 $11.87   79.6%   20.4%   Day before election, momentum for Yes
Hedge        No      3  $0.71   77.3%   22.7%   Someone hedging their bet

Final prices: Yes=77.3%, No=22.7%
Total collected: $44.16
Yes shares outstanding: 50
No shares outstanding: 26

Analyzing the Simulation

Market behavior: The market started at 50/50 and settled at about 77/23, reflecting net "Yes" sentiment. The price path shows a coherent narrative: initial bullishness (Maria, Alex), some pushback (James, Pat), and a final surge (Late buyer).

Subsidy analysis: - Total collected: $44.16 - If "Yes" wins: Payout = $50 (50 Yes shares), Loss = $50 - $44.16 = $5.84 - If "No" wins: Payout = $26 (26 No shares), Profit = $44.16 - $26 = $18.16 - Maximum possible loss was $24.25; actual worst case is $5.84 --- well within budget

Price sensitivity: Individual trades moved the price by 4-15 percentage points, which feels appropriate for a community market. Trades are meaningful but no single trade dominates.


Phase 4: Computing Subsidy Costs Across All Markets

Let us estimate the total subsidy cost for the RNA's first year.

Worst-Case Analysis

  • 38 binary markets at $b = 30$: $38 \times 30 \times \ln(2) = \$790$
  • 2 multi-outcome markets (5 outcomes) at $b = 50$: $2 \times 50 \times \ln(5) = \$161$
  • Total worst case: $951

Expected-Case Analysis

Based on empirical studies, actual losses typically run 30-60% of maximum. Using 50%:

  • Expected total cost: ~$475

This leaves the RNA with ample budget reserves for: - Increasing $b$ on popular markets - Adding more markets than originally planned - Creating special high-liquidity markets for important questions

Cost Per Probability Estimate

The RNA gets 40 probability estimates for about $475 in expected subsidy:

$$\text{Cost per estimate} \approx \frac{\$475}{40} \approx \$12$$

Compare to alternatives: - Expert consultant for one question: $200-1,000 - Survey for one question: $500-5,000 - The AMM approach is extraordinarily cost-effective


Phase 5: Final Recommendation

System Design

  1. Mechanism: Standard LMSR
  2. Binary market parameter: $b = 30$ (max loss ~$20.79 each)
  3. Multi-outcome market parameter: $b = 50$ (max loss ~$80.47 for 5 outcomes)
  4. Initial prices: Uniform (50/50 for binary, 20% each for 5-outcome)
  5. Total budget allocation: $951 worst-case out of $2,000 available

Implementation Priorities

  1. Start with binary markets only (simpler, lower risk)
  2. Add multi-outcome markets once the system is proven
  3. Track actual losses vs. maximum to refine $b$ choices over time
  4. Consider migrating to LS-LMSR after year one if trading patterns justify it

Risk Mitigation

  • Set aside 50% of budget as reserve for year one
  • Monitor each market's actual loss vs. theoretical maximum
  • If any market shows unusually high activity, do not increase $b$ mid-market (this would change the rules); instead, take notes for future parameter selection
  • Provide clear documentation to community members explaining that prices represent probabilities

Success Metrics

After year one, evaluate: - Calibration: Did markets priced at 70% resolve "Yes" about 70% of the time? - Participation: Did at least 50 of the 200 members trade at least once? - Cost efficiency: What was the actual total subsidy vs. the $2,000 budget? - Price informativeness: Were there cases where the market price was notably better (or worse) than individual forecasts?


Discussion Questions

  1. Would CPMM have been a viable choice for the RNA? Under what circumstances might you recommend it instead?

  2. The RNA chose uniform initial prices (50/50 for binary markets). Would it ever make sense to start at different prices? What are the trade-offs?

  3. If the RNA wanted to allow community members to fund liquidity (adding to $b$ in exchange for a share of any AMM profits), how would you structure this?

  4. How would your recommendation change if the RNA had 10x the budget ($20,000) but expected the same 40 markets and 200 participants?

  5. The simulation showed one trader ("Alex") with apparent insider information moving the price significantly. Is this a feature or a bug of the system?