Skip to content

Feat twap oracle storage 1176 - #1195

Open
somotochukwu-dev wants to merge 12 commits into
accesslayerorg:mainfrom
somotochukwu-dev:feat-twap-oracle-storage-1176
Open

somotochukwu-dev wants to merge 12 commits into
accesslayerorg:mainfrom
somotochukwu-dev:feat-twap-oracle-storage-1176

Conversation

@somotochukwu-dev

Copy link
Copy Markdown
Contributor

Summary

This PR adds a Time-Weighted Average Price (TWAP) oracle to the bonding curve contract by recording price snapshots on every trade and maintaining a bounded historical record for efficient on-chain price averaging. The implementation introduces cumulative price tracking, configurable snapshot retention through a ring buffer, and a public get_twap query that returns the average price over a requested time window while gracefully handling limited historical data.

The TWAP oracle provides a more manipulation-resistant price reference than relying on a single spot price by weighting each recorded price according to the amount of time it remained active before the next snapshot.

Problem

The bonding curve currently exposes only instantaneous trade prices, which can fluctuate significantly between transactions. Consumers that require a more stable price reference—such as analytics, integrations, or future protocol components—have no native way to retrieve an average price over time.

Without historical price accumulation:

  • Only spot prices are available.
  • Short-term price swings can disproportionately affect downstream consumers.
  • Historical price behavior must be reconstructed externally.
  • The contract lacks an efficient on-chain TWAP oracle.

Solution

This implementation introduces an internal TWAP mechanism that continuously accumulates price history as trades occur.

Price snapshot storage

  • Records a snapshot on every trade.
  • Stores:
    • Current price
    • Timestamp
  • Maintains snapshots in a fixed-size ring buffer.
  • Ring buffer capacity is configurable during initialization.
  • Uses a default capacity of 100 snapshots when no custom size is provided.

Ring buffer behavior

  • Preserves a bounded storage footprint.
  • Automatically wraps when full.
  • Evicts the oldest snapshot while retaining the newest history.
  • Keeps insertion and overwrite operations efficient.

Time-weighted accumulation

Each interval contributes to the average according to how long that price remained active.

The TWAP is computed as:

Where:

  • price_i is the recorded price.
  • Δt_i is the elapsed time until the next snapshot.
  • total window time is the effective averaging period.

TWAP query

Adds:

  • get_twap(window_seconds)

Behavior:

  • Computes the TWAP over the requested window.
  • Clamps the requested window to available history.
  • Returns the average over the entire stored range if the requested window exceeds historical coverage.
  • Works correctly even when fewer than the maximum number of snapshots exist.

Events

Emits a PriceSnapshot event on every trade containing:

  • Current price
  • Cumulative value

This enables off-chain consumers to track oracle updates without reconstructing state manually.

Implementation Details

  • Added persistent snapshot storage.
  • Added configurable ring buffer initialization.
  • Implemented circular overwrite logic when capacity is reached.
  • Added cumulative time-weighted price accounting.
  • Implemented window-clamped TWAP calculation.
  • Added public get_twap(window_seconds) interface.
  • Added PriceSnapshot event emission during trade execution.

Edge Cases Covered

  • Requested window shorter than stored history.
  • Requested window longer than stored history.
  • Ring buffer wraparound after reaching capacity.
  • Correct weighting across irregular time gaps between trades.
  • Accurate behavior during early contract lifetime with partial history.

Testing

Tests validate:

  • Correct TWAP calculation across varying time intervals.
  • Proper weighting of prices by elapsed time.
  • Ring buffer overwrite behavior after reaching capacity.
  • Preservation of newest snapshots after wraparound.
  • Accurate results for arbitrary valid windows.
  • Graceful fallback when the requested window exceeds available history.
  • PriceSnapshot event emission with expected values on every trade.

Acceptance Criteria Checklist

  • TWAP computed correctly across varying time deltas between snapshots
  • Ring buffer wraps correctly and evicts the oldest snapshot when full
  • get_twap returns accurate results for any window within available history
  • Windows exceeding available history return TWAP over the full stored range
  • PriceSnapshot event emitted correctly on every trade

Closes #1176

@drips-wave

drips-wave Bot commented Oct 21, 2026

Copy link
Copy Markdown

@somotochukwu-dev Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@somotochukwu-dev
somotochukwu-dev force-pushed the feat-twap-oracle-storage-1176 branch from 34faf60 to 7e9a8bd Compare October 26, 2026 23:51
@somotochukwu-dev
somotochukwu-dev force-pushed the feat-twap-oracle-storage-1176 branch from dbc017d to 0c51c7a Compare October 27, 2026 11:05
@Chucks1093

Copy link
Copy Markdown
Member

Please add creator-keys/test_snapshots/ to .gitignore and remove all snapshot files from this PR — they are auto-generated artifacts and should not be committed. Only the source code changes (events.rs, lib.rs) should be included.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add TWAP oracle accumulation and price snapshot storage to bonding curve

3 participants