Skip to content

fix(bids): enforce deterministic ranking, winner selection, and cursored pagination - #2553

Open
Madukanino wants to merge 2 commits into
QuickLendX:mainfrom
Madukanino:fix/deterministic-bid-ranking-and-pagination
Open

fix(bids): enforce deterministic ranking, winner selection, and cursored pagination#2553
Madukanino wants to merge 2 commits into
QuickLendX:mainfrom
Madukanino:fix/deterministic-bid-ranking-and-pagination

Conversation

@Madukanino

Copy link
Copy Markdown
Contributor

Closes #2446

fix(bids): deterministic bid ranking, winner selection, and cursored pagination semantics

Description

This PR provides production-grade guarantees for bid acceptance, ranking, expiry, winner selection, and cursored query pagination. It guarantees deterministic evaluation and mathematical total ordering across all validators while eliminating stale or adversarial inputs across normal, invalid, repeated, concurrent, and failure conditions.


Technical Highlights & Invariants

  1. Deterministic Multi-Key Ranking & Tiebreaking (BidStorage::compare_bids):

    • Implements a strict total order comparator evaluated across all validators:
      1. Clamped Profit: expected_return.saturating_sub(bid_amount).max(0) (descending)
      2. Expected Return: expected_return (descending)
      3. Bid Amount: bid_amount (descending)
      4. Timestamp: timestamp (descending, newer bids first)
      5. Bid ID: bid_id.to_array() (lexicographical tiebreaker)
    • Guarantees strict anti-symmetry, reflexivity, and transitivity, ensuring identical ranking and winner selection irrespective of storage insertion or transaction arrival order.
    • Enforces invariant: get_best_bid(...) == rank_bids(...).get(0).
  2. Stale & Adversarial Input Elimination:

    • load_accept_bid_context and accept_bid_impl validate bid status and expiration, returning QuickLendXError::BidStale for non-Placed or expired bids.
    • Active ranking queries (rank_bids, get_best_bid, rank_bids_paged) filter expired bids in real time prior to lazy compaction.
    • Failed, rejected, or stale operations leave zero residual escrow, partial funding, or mutated state.
  3. Safe Bounded Cursored Pagination (pagination.rs):

    • Bounded queries enforce MAX_QUERY_LIMIT = 50, safe slice bounding, and string-encoded cursors ("{generation}_{offset}").
    • require_stable_cursor detects and halts iteration with QuickLendXError::UnstableCursor upon mid-pagination state mutation.
    • Exposed paged contract endpoints:
      • get_ranked_bids_paged(invoice_id, offset, limit) -> PaginatedBids
      • get_bid_history_paged(invoice_id, status_filter, offset, limit) -> PaginatedBids
      • get_investor_bids_paged(investor, status_filter, offset, limit) -> PaginatedBids
  4. Resource Footprint & Storage Isolation:

    • Migrated audit trail storage to persistent storage with TTL extensions, preventing instance storage budget overflow.
    • Optimized get_active_bid_count to use indexed counts directly without redundant O(N) deserializations.

Validation Performed

  • Unit & Integration Suite: cargo test --lib (98 passed, 0 failed, 3 ignored legacy specs).
  • Determinism & Pagination Suite: Passed all 18 test cases in quicklendx-contracts/src/test_bid_ranking_determinism.rs covering mathematical ordering, tiebreakers, empty slices, pagination boundaries, and cursor stability.
  • Concurrency Suite: Passed all 12 test cases in quicklendx-contracts/src/test_bid_concurrency.rs validating concurrent placement, race safety, retry after conflict, and capacity limits.
  • WASM Compliance: cargo check --target wasm32v1-none completed with 0 errors.
  • Code Style: cargo fmt --all --check passed cleanly.

@drips-wave

drips-wave Bot commented Aug 30, 2026

Copy link
Copy Markdown

@Madukanino 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

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.

[Quality][Medium] bid submission and auction selection: pagination and cursor semantics — QE-2026-08

1 participant