Skip to content

feat: track liquidity providers orders#1274

Merged
MicBun merged 1 commit intomainfrom
LpTracking
Dec 5, 2025
Merged

feat: track liquidity providers orders#1274
MicBun merged 1 commit intomainfrom
LpTracking

Conversation

@MicBun
Copy link
Member

@MicBun MicBun commented Dec 5, 2025

resolves: https://github.com/truflation/website/issues/2923

It is part of the bigger tasks. More PR will be needed for this issue

Summary by CodeRabbit

  • New Features
    • Implemented liquidity provider eligibility tracking and qualification system
    • Liquidity providers are now tracked across markets with order volume and pricing data
    • Added ability to query liquidity provider statistics by market
    • Qualification criteria based on order spread and minimum order size requirements

✏️ Tip: You can customize this high-level summary in your review settings.

@MicBun MicBun self-assigned this Dec 5, 2025
@MicBun MicBun added the type: feat New feature or request label Dec 5, 2025
@coderabbitai
Copy link

coderabbitai bot commented Dec 5, 2025

Walkthrough

Adds liquidity provider eligibility tracking by enhancing place_split_limit_order with snapshot-based qualification logic that validates market parameters, computes price distances, evaluates qualification criteria, and records qualified LPs. Includes a new tracking table, index, query view, and comprehensive test suite.

Changes

Cohort / File(s) Summary
LP Eligibility Logic
internal/migrations/032-order-book-actions.sql
Implements LP qualification workflow in place_split_limit_order: fetches market parameters (max_spread, min_order_size), validates retrieval, computes price distances from 50-cent midpoint for YES/NO sides, evaluates qualification via two-sided spread and minimum order size checks, and upserts qualified LPs to tracking table with metadata (prices, timestamps, order count).
LP Tracking Schema & View
internal/migrations/034-lp-tracking.sql
Introduces ob_liquidity_providers table (query_id, participant_id as composite key) with per-LP aggregation columns; creates idx_ob_lp_by_query index for market-wide LP lookups; adds public get_lp_stats(query_id) view to retrieve LP details joined with participant wallet addresses, ordered by split_order_amount descending.
LP Tracking Tests
tests/streams/order_book/lp_tracking_test.go
Comprehensive test suite covering LP qualification (spread boundaries, minimum order size), volume accumulation across multiple orders, per-market tracking isolation, and LP stats query functionality with zero/one/multiple LPs; includes test utilities (createTestMarket, getLPStats, callPlaceSplitLimitOrder).

Sequence Diagram

sequenceDiagram
    participant Client
    participant place_split_limit_order as place_split_limit_order<br/>(Order Action)
    participant ob_queries as ob_queries<br/>(Market Params)
    participant ob_liquidity_providers as ob_liquidity_providers<br/>(LP Table)
    participant get_lp_stats as get_lp_stats<br/>(Query View)

    Client->>place_split_limit_order: Place split limit order<br/>(participant, split_amount, prices)
    activate place_split_limit_order
    
    place_split_limit_order->>ob_queries: Fetch market parameters<br/>(max_spread, min_order_size)
    activate ob_queries
    ob_queries-->>place_split_limit_order: Return parameters or NULL
    deactivate ob_queries
    
    alt Parameters Retrieved
        place_split_limit_order->>place_split_limit_order: Compute price distances<br/>from 50¢ midpoint<br/>(YES & NO sides)
        
        place_split_limit_order->>place_split_limit_order: Evaluate qualification:<br/>buy_distance ≤ max_spread AND<br/>sell_distance ≤ max_spread AND<br/>amount ≥ min_order_size
        
        alt Qualified
            place_split_limit_order->>ob_liquidity_providers: Upsert LP record<br/>(snapshot metadata)
            activate ob_liquidity_providers
            ob_liquidity_providers-->>place_split_limit_order: Record stored/updated
            deactivate ob_liquidity_providers
            rect rgba(76, 175, 80, 0.2)
                note over place_split_limit_order: LP tracked for<br/>fee distribution
            end
        else Not Qualified
            rect rgba(244, 67, 54, 0.2)
                note over place_split_limit_order: LP not tracked
            end
        end
    else Parameters Missing
        rect rgba(244, 67, 54, 0.2)
            note over place_split_limit_order: Error: Missing params
        end
    end
    deactivate place_split_limit_order
    
    Client->>get_lp_stats: Query LP statistics<br/>for market (query_id)
    activate get_lp_stats
    get_lp_stats->>ob_liquidity_providers: SELECT LP records<br/>joined with participants
    activate ob_liquidity_providers
    ob_liquidity_providers-->>get_lp_stats: Return LP details
    deactivate ob_liquidity_providers
    get_lp_stats-->>Client: Return sorted LP stats<br/>(by split_order_amount DESC)
    deactivate get_lp_stats
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • 032-order-book-actions.sql: Review snapshot-based LP qualification logic, price distance computations, two-sided spread validation, and upsert conditions to ensure correctness of eligibility criteria.
  • 034-lp-tracking.sql: Verify table schema design (composite key, foreign keys, cascading deletes), index coverage for query efficiency, and the public view's join logic and ordering.
  • lp_tracking_test.go: Validate test case coverage (boundary conditions for spread, minimum order size validation, per-market isolation, volume accumulation, stats query sorting), test setup/teardown patterns, and assertion completeness.

Possibly related PRs

  • PR #1267: Updates comments in internal/migrations/032-order-book-actions.sql to clarify that LP qualification requires both buy and sell distances within max_spread; this PR implements that two-sided snapshot-based tracking.
  • PR #1266: Introduces place_split_limit_order flow; this PR extends it with LP eligibility checks and tracking.
  • PR #1262: Modifies order-book actions schema; this PR adds LP eligibility section to the same actions file.

Suggested reviewers

  • pr-time-tracker

Poem

🐰 Hop along, the LPs now have their place,
Snapshot qualification, two-sided grace!
Orders placed with vigor, tracked with care,
Fee distribution coming—if fair and square!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: track liquidity providers orders' accurately describes the main change, which is implementing LP eligibility tracking and order recording functionality across migrations and tests.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch LpTracking

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@holdex
Copy link

holdex bot commented Dec 5, 2025

Time Submission Status

Member Status Time Action Last Update
MicBun ✅ Submitted 4h Update time Dec 5, 2025, 12:12 PM

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (7)
internal/migrations/034-lp-tracking.sql (1)

94-130: Verify the view action handles non-existent query_id gracefully.

The get_lp_stats action returns an empty result set when no LPs exist for a market, which is correct behavior. However, consider whether it should also validate that the market exists (query_id is valid) and provide a more descriptive response if the market doesn't exist at all.

Currently, querying a non-existent market returns the same empty result as a market with no LPs - this may be acceptable but could mask issues.

internal/migrations/032-order-book-actions.sql (3)

1452-1454: Fix duplicate section numbering.

This section is labeled "SECTION 8: LP ELIGIBILITY TRACKING" but there's already a "SECTION 8: TRIGGER MATCHING ENGINE" at line 1438. This should be "SECTION 9" for consistency.

     -- ==========================================================================
-    -- SECTION 8: LP ELIGIBILITY TRACKING (ISSUE 9A)
+    -- SECTION 9: LP ELIGIBILITY TRACKING (ISSUE 9A)
     -- ==========================================================================

1480-1490: Distance calculations are equivalent when prices sum to 100.

Since $false_price = 100 - $true_price, both abs(50 - $true_price) and abs(50 - $false_price) yield the same value. For example:

  • true_price = 52, false_price = 48abs(50-52) = 2, abs(50-48) = 2
  • true_price = 60, false_price = 40abs(50-60) = 10, abs(50-40) = 10

The code is correct but could be simplified to check only one distance. The current implementation is fine for clarity and documentation purposes.


1466-1478: Consider combining market queries for efficiency.

The market parameters (max_spread, min_order_size) are fetched in a separate query (lines 1470-1473), while settled was already queried from ob_queries in Section 1.3 (lines 1323-1326). For minor efficiency gains, consider fetching all needed fields in a single query earlier in the action.

This is a low-priority optimization since the database hit is minimal.

tests/streams/order_book/lp_tracking_test.go (3)

474-484: Consider adding nil checks for type assertions.

The type assertions (e.g., row.Values[0].(int64)) will panic if any value is nil. While the database schema defines all columns as NOT NULL, adding defensive nil checks would make the test helper more robust:

if row.Values[0] == nil {
    return fmt.Errorf("unexpected nil value for participant_id")
}

This is optional since the schema constraints should prevent nil values.


52-54: Consider extracting test state reset to a helper function.

The pattern of resetting balancePointCounter and lastBalancePoint is repeated at the start of every test function. Consider extracting this to a helper:

func resetTestState() {
    balancePointCounter = 100
    lastBalancePoint = nil
}

Then call resetTestState() at the start of each test. This reduces duplication and makes the intent clearer.

Also applies to: 93-94, 125-127, 159-160, 198-200, 260-262, 312-314, 341-343, 382-384


447-456: Consider using int32 for price fields to match SQL INT type more precisely.

The LastOrderTruePrice and LastOrderFalsePrice fields are defined as int16, but prices in the SQL schema are INT (typically 32-bit). While the value range (1-99) easily fits in int16, using int32 would be more consistent with the database type.

This is a minor nit and the current implementation works correctly.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b989495 and 170a7bb.

📒 Files selected for processing (3)
  • internal/migrations/032-order-book-actions.sql (1 hunks)
  • internal/migrations/034-lp-tracking.sql (1 hunks)
  • tests/streams/order_book/lp_tracking_test.go (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: acceptance-test
  • GitHub Check: lint
🔇 Additional comments (3)
internal/migrations/034-lp-tracking.sql (1)

41-53: LGTM! Well-designed LP tracking schema.

The table design correctly uses a composite primary key for one-record-per-LP-per-market semantics. The ON DELETE CASCADE for query_id ensures cleanup when markets are deleted, while the absence of cascade on participant_id prevents orphan LP records if participants are somehow removed.

internal/migrations/032-order-book-actions.sql (1)

1494-1520: LGTM! Correct UPSERT pattern for LP tracking.

The UPSERT correctly:

  • Inserts new LP records with initial values
  • Accumulates split_order_amount on conflict
  • Preserves first_qualified_at (not updated on conflict)
  • Updates last_qualified_at and last_order_*_price to latest values
  • Increments total_qualified_orders counter
tests/streams/order_book/lp_tracking_test.go (1)

21-42: LGTM! Comprehensive test coverage for LP tracking.

The test suite covers all critical scenarios:

  • Qualification within spread (Category A)
  • Rejection when spread too wide or amount too small
  • Boundary conditions (exact max_spread)
  • Volume accumulation across orders (Category B)
  • Per-market isolation
  • Empty, single, and multiple LP stats queries (Category C)

@MicBun MicBun merged commit d3d0936 into main Dec 5, 2025
6 checks passed
@MicBun MicBun deleted the LpTracking branch December 5, 2025 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: feat New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant