Skip to content

feat(trading): implement slippage-protected multi-buy function (#717) - #759

Merged
Chucks1093 merged 1 commit into
accesslayerorg:mainfrom
Alaka-ibr:feat/multi-buy-717
Aug 24, 2026
Merged

feat(trading): implement slippage-protected multi-buy function (#717)#759
Chucks1093 merged 1 commit into
accesslayerorg:mainfrom
Alaka-ibr:feat/multi-buy-717

Conversation

@Alaka-ibr

Copy link
Copy Markdown
Contributor

feat(trading): implement slippage-protected multi-buy function (#717)

Summary

Closes #717

Investors seeking to diversify across multiple creators previously had to submit one transaction per creator, exposing them to price movements between submissions. This PR implements a multi-buy function that accepts a vector of (creator, amount, max_price) legs and executes purchases atomically with all-or-nothing semantics and per-leg slippage protection.

Changes

1. Endpoint & Schema (src/modules/trading/multi-buy.schemas.ts)

  • Added POST /api/v1/trading/multi-buy endpoint.
  • Validates request payload:
    • legs: 1–10 entries (rejects legs_empty if empty, too_many_legs if > 10).
    • amount and max_price: positive integers.
    • global_deadline_ledger: positive integer sequence number.

2. Service Logic (src/modules/trading/multi-buy.service.ts)

  • Pre-flight Validation:
    • duplicate_creator: panics if any creator appears more than once.
    • deadline_passed: compares current ledger against global_deadline_ledger.
    • insufficient_funds: verifies buyer XLM balance covers worst-case total cost ($\sum \text{amount} \times \text{max_price}$).
  • Atomic Leg Execution:
    • Computes bonding curve cost per leg via computeBuyCost.
    • Panics with slippage_exceeded if leg cost exceeds max_price * amount, rolling back all purchases.
    • Emits a key_purchased debug log per leg and a multi_buy_completed summary log upon completion.

3. Controller & Routing (src/modules/trading/multi-buy.controllers.ts, src/modules/trading/multi-buy.routes.ts)

  • Mounted at /api/v1/trading/multi-buy in src/modules/index.ts.

Test Coverage

Unit tests in src/modules/trading/multi-buy.service.test.ts (6 passed):

  • Executes 3 legs all within max_price and returns correct supplies and costs.
  • Rolls back all legs when the second leg exceeds max_price (slippage_exceeded).
  • Rejects duplicate creator in legs (duplicate_creator).
  • Rejects legs vector exceeding 10 entries (too_many_legs).
  • Rejects when global_deadline_ledger is in the past (deadline_passed).
  • Rejects when buyer balance is less than worst-case total cost (insufficient_funds).

…slayerorg#717)

Add a multi-buy endpoint that accepts a vector of purchase legs and
executes them atomically with per-leg slippage protection.

- POST /api/v1/trading/multi-buy endpoint
- Pre-flight validation: empty legs, max 10 legs, duplicate creator,
  deadline check against current ledger, buyer balance vs worst-case cost
- Per-leg bonding curve cost computed via computeBuyCost and compared
  against max_price * amount
- Structured debug logs: KeyPurchased per leg, MultiBuyCompleted summary
- Provider interfaces for ledger, balance, and supply to support testing
- 6 unit tests covering all acceptance criteria
@Chucks1093

Copy link
Copy Markdown
Member

The all-or-nothing rollback on slippage is exactly the right call here. One thing worth thinking about as usage grows is what happens when a partial failure lands near the deadline ledger and the buyer has to retry the whole bundle from scratch at new prices. A structured error response that tells the caller which leg triggered the slippage and what the actual cost was would make client side recovery a lot smoother without changing the core atomicity guarantee.

@Chucks1093
Chucks1093 merged commit 5a9e6e3 into accesslayerorg:main Aug 24, 2026
1 check passed
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 integration test for the wallet authentication challenge endpoint returning a valid Stellar transaction

2 participants