Skip to content

feat: add liquidity depth oracle for batch trade pre-validation (#1035) - #1046

Open
meem08 wants to merge 6 commits into
accesslayerorg:mainfrom
meem08:feat/issue-1035-liquidity-depth-oracle
Open

meem08 wants to merge 6 commits into
accesslayerorg:mainfrom
meem08:feat/issue-1035-liquidity-depth-oracle

Conversation

@meem08

@meem08 meem08 commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements the key-pair liquidity depth oracle requested in #1035: two new read-only views on the creator-keys bonding curve contract that return the maximum buyable / sellable amount of keys within a given price-impact tolerance, together with the current price and the price expected after full execution. Intended for per-order pre-validation on the batch trade endpoint.

Closes #1035

New API

get_max_buy(env, key_id: Address, max_impact_bps: u32) -> Result<LiquidityDepthQuote, ContractError>
get_max_sell(env, key_id: Address, min_impact_bps: u32) -> Result<LiquidityDepthQuote, ContractError>
pub struct LiquidityDepthQuote {
    pub max_amount: u32,        // keys buyable/sellable within the tolerance
    pub current_price: i128,    // curve price per key at current supply
    pub expected_price: i128,   // curve price per key after executing max_amount
}

Semantics

  • Impact measurement (raw bonding-curve price, before fees): (price_after - price_now).abs() * 10_000 / price_now <= tolerance_bps. For buys the curve walks supply -> supply + max_amount; for sells it walks supply -> supply - max_amount and never below zero supply.
  • Exactness: the curve price is monotonically non-decreasing in supply for every configurable shape (flat / linear / quadratic / exponent override / graduated milestones all use non-negative slopes), so the maximal in-tolerance amount is found by exact binary search over the depth range - ~20 curve evaluations regardless of depth.
  • Depth bound: sells are bounded by current supply; buys are bounded by the remaining supply cap when one is configured, and by MAX_DEPTH_SCAN_LIMIT (1 000 000) when uncapped (this only binds when the price never leaves the tolerance, e.g. a flat preset, where the entire scan depth is correctly reported as buyable at any tolerance).
  • Zero-liquidity handling: get_max_sell at zero supply returns max_amount = 0 with the current/expected price reported gracefully; a non-positive curve price likewise yields an empty depth instead of a division by zero.
  • Read-only: both views only read storage (KEY_PRICE, creator profile, supply cap, curve config) and never mutate state - asserted by a dedicated test.
  • Validation: tolerances above 10 000 bps revert with the new ContractError::InvalidImpactTolerance (= 105, appended); unregistered keys revert NotRegistered; missing key price reverts KeyPriceNotSet (same ordering as the existing quote views).

Changes

  • creator-keys/src/lib.rs (+242, purely additive):
    • LiquidityDepthQuote result struct
    • ContractError::InvalidImpactTolerance = 105
    • helpers depth_post_trade_price, depth_within_impact_limit, find_max_depth, MAX_DEPTH_SCAN_LIMIT next to the existing curve math
    • get_max_buy / get_max_sell views next to get_sell_quote
  • creator-keys/src/test_issue_1035.rs (new, 17 tests):
    • linear-curve amounts for multiple tolerances incl. exact boundary impact and zero tolerance
    • quadratic-curve math, flat-curve full-depth behaviour, supply-cap bounding
    • expected_price verified against get_price_at_supply at supply +/- max_amount, and maximality (one more key must exceed the tolerance) verified independently
    • oracle-then-execute consistency (buy the quoted amount, curve price matches expected_price)
    • read-only assertion: supply, balances, slope, bid/ask price and buy quote unchanged after repeated calls; repeated results stable
    • zero-liquidity sell (empty depth, no revert), unregistered key, >100 % tolerance, missing key price

Testing

  • cargo test -p creator-keys --lib - 489 passed, 0 failed (includes the 17 new tests)
  • cargo clippy -p creator-keys --all-targets -- -D warnings - clean
  • cargo fmt -p creator-keys -- --check - clean

Notes for reviewers

  • Impact is measured on the raw curve price (before fees and before the configurable bid-ask spread) so the depth figure is stable across fee-config changes and matches query_price / get_bid_ask_price's buy side; callers can layer fees/spread on top during pre-validation.
  • The scan uses binary search rather than a linear walk so worst-case cost stays bounded (~20 curve price evaluations) even at the 1 M depth ceiling.

@drips-wave

drips-wave Bot commented Oct 17, 2026

Copy link
Copy Markdown

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

… merge

Merging main brought in CapCannotIncrease (105) and CapTooLow (106) from the
holder-cap work, colliding with InvalidImpactTolerance (105) and tripping
E0081 so every target failed to compile. Keep main's published codes and
renumber the new liquidity-depth error to 107.
@Chucks1093

Copy link
Copy Markdown
Member

Conflict

meem08 and others added 3 commits October 17, 2026 08:56
…merge

The main merge brought in the price-alert errors WalletAlertLimitReached
(107), KeyAlertLimitReached (108) and AlertNotFound (109), colliding with
InvalidImpactTolerance (107) and tripping E0081. Keep main's published
codes and append the liquidity-depth error as 110.
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 key pair liquidity depth oracle for batch trade pre-validation

2 participants