Finalizing Proposals (TWAPs)
Time-Weighted Average Prices (TWAPs) are the mechanism that converts market activity into governance decisions. Instead of using a single snapshot price — which could be easily manipulated — NovaDAO computes a weighted average over the entire trading period. This page explains how TWAPs work, why they resist manipulation, and how they determine proposal outcomes.
TWAPs Decide Pass or Fail
When a proposal's trading period ends, the DAO contract computes two TWAPs:
- Pass TWAP: The time-weighted average price of pNOVA (the pass token) over the trading period.
- Fail TWAP: The time-weighted average price of fNOVA (the fail token) over the trading period.
The decision rule is straightforward: if the Pass TWAP exceeds the Fail TWAP (adjusted for any applicable threshold), the proposal passes. Otherwise, it fails.
Lagged Price Observations
NovaDAO's TWAP implementation uses lagged observations to further increase manipulation resistance. Here is how it works:
Periodic Sampling
The AMM contract records the current pool price at regular intervals (every slot or on every trade, whichever comes first). Each observation is stored on-chain with its timestamp.
Cumulative Price Tracking
Rather than storing individual price snapshots, the contract maintains a cumulative price sum. The TWAP for any time window is computed as:TWAP = (cumulative_price_end - cumulative_price_start) / (time_end - time_start)
This approach is gas-efficient and resistant to single-block manipulation.
Lag Window
Observations are lagged — the price recorded at time T reflects the pool state from a previous checkpoint, not the current instant. This means an attacker cannot manipulate the price and have it immediately affect the TWAP. By the time the manipulated price enters the average, arbitrageurs have had time to correct it.
The 24-Hour Grace Period
After the main trading period ends, a 24-hour grace period begins before the TWAP is finalized. This grace period serves several purposes:
- Final corrections: If late-breaking information emerges (e.g., a technical flaw is discovered in the proposal), traders have 24 hours to adjust prices before the decision is locked in.
- Manipulation detection: If someone attempted to manipulate the price at the end of the trading period, the grace period gives the market time to identify and correct the distortion.
- Time zone fairness: A 24-hour window ensures that participants in all time zones have an opportunity to react to the final state of the market before the outcome is determined.
Pass Thresholds
The pass/fail decision is not always a simple comparison. NovaDAO applies different thresholds depending on the proposer:
| Proposer Type | Pass Condition | Example |
|---|---|---|
| Non-team member | Pass TWAP > Fail TWAP | If Pass TWAP = $1.05 and Fail TWAP = $1.03, the proposal passes because $1.05 > $1.03. |
| Team member | Pass TWAP > Fail TWAP + 5% | If Pass TWAP = $1.05 and Fail TWAP = $1.03, the adjusted threshold is $1.03 * 1.05 = $1.0815. Since $1.05 < $1.0815, the proposal fails despite the pass market being higher. The market must demonstrate stronger conviction for team-originated proposals. |
This mechanism protects against insider self-dealing. A team member proposing their own compensation increase must demonstrate that the market strongly believes the proposal is net positive — not just marginally so.
Complete Proposal Timeline
Here is the full timeline for a typical proposal, from submission to final resolution:
| Phase | Duration | What Happens |
|---|---|---|
| Pending | Variable | Proposal is submitted. Proposer and supporters stake NOVA toward the 200,000 NOVA activation threshold. No markets are open. |
| Activation | Instant | Threshold is met. The Conditional Vault is initialized and the AMM creates pass/fail trading pools. Markets open for trading. |
| Trading Period | 7 days (default) | Traders buy and sell pNOVA and fNOVA. The AMM records price observations for the TWAP calculation. This is the primary price discovery window. |
| Grace Period | 24 hours | Trading continues. Final opportunity for price corrections and manipulation detection. TWAP observations continue to accumulate. |
| Finalization | Instant | Anyone can call the finalize function. The DAO contract computes final TWAPs, applies the pass threshold, and marks the proposal as Passed or Failed. If passed, the on-chain action is executed atomically. |
| Redemption | Open-ended | Holders of the winning conditional token redeem 1:1 for NOVA. Staked tokens are returned to proposer and supporters. There is no deadline for redemption. |
Technical Implementation on Stellar
NovaDAO's TWAP oracle is implemented directly in the Futarchy AMM Soroban contract. Here are the key technical details:
On-Chain Price Accumulator
The AMM maintains a cumulative price variable that is updated on every trade. The accumulator stores the sum of price * time_elapsed since the market opened. To compute the TWAP over any interval, the contract simply divides the difference in accumulator values by the time elapsed:
// Pseudo-code for TWAP calculation
let twap = (accumulator_at_end - accumulator_at_start)
/ (timestamp_end - timestamp_start);Observation Storage
Price observations are stored in contract storage as a series of checkpoints. Each checkpoint records the cumulative price and timestamp. The contract uses Soroban's persistent storage to ensure observations survive across ledger boundaries and cannot be tampered with.
Finalization Call
Finalization is permissionless — any account can call the finalize function after the grace period ends. The function:
- Verifies the grace period has elapsed
- Computes the Pass TWAP and Fail TWAP from stored observations
- Applies the appropriate pass threshold based on proposer type
- Updates the proposal state to Passed or Failed
- If passed, executes the proposal's on-chain action
- Unlocks staked tokens for return to their owners
Back to: Governance Overview | Trading Proposals | Creating Proposals