Summary
Investors have no way to see how a large buy or sell will move the bonding curve price before committing. This issue implements a client-side bonding curve simulation engine that runs the full curve formula in the browser, renders an interactive price impact preview as the user drags a quantity slider, and highlights the slippage percentage relative to the current spot price — all without a server round-trip.
Scope
1. Curve engine (pure TypeScript)
- Implement
computeBuyCost(currentSupply: bigint, amount: bigint, feeBps: bigint): { grossCost: bigint, fee: bigint, netCost: bigint, newPrice: bigint } using bigint arithmetic only (no floating point)
- Implement
computeSellPayout(currentSupply: bigint, amount: bigint, feeBps: bigint): { grossPayout: bigint, fee: bigint, netPayout: bigint, newPrice: bigint }
- Both functions must produce results identical to the Soroban contract for any input — add a cross-validation test suite comparing client outputs against a reference table derived from the contract
2. Interactive price impact slider
- Replace the static quantity input in the buy and sell modals with a dual-control: a numeric input and a slider ranging from 1 to
min(availableSupply, 500)
- As the slider moves, re-run the curve engine synchronously (no debounce — must be instant) and update: gross cost / payout, protocol fee, creator fee, net cost / payout, new price after trade, and slippage % =
(newPrice - currentPrice) / currentPrice * 100
- Colour-code the slippage badge: green < 1%, yellow 1–5%, red > 5%
3. Price impact chart overlay
- Render a small sparkline chart below the slider showing the marginal cost per key across the range
[currentSupply, currentSupply + sliderMax]
- The chart updates in real time as the slider moves, with a vertical cursor line at the current slider position
- The chart must render within a single animation frame of the slider move — use
requestAnimationFrame and a canvas renderer (not SVG) for performance
4. Worst-case XLM display
- Display the worst-case XLM cost (at
max_price = computed cost + 0.5% buffer) alongside the expected cost so the user understands the slippage tolerance that will be submitted to the contract
- The
max_price buffer percentage should be configurable in app config
5. Unit and performance tests
- Unit tests:
computeBuyCost matches reference table for supplies 0, 1, 10, 100, 1000
- Unit tests:
computeSellPayout matches reference table
- Performance test: 1000 consecutive slider moves (quantity 1 → 500 → 1) complete in under 16ms total on a mid-range device (use
performance.now() assertions in tests)
Acceptance Criteria
ETA: 24 hours
Coordinate on Telegram
Summary
Investors have no way to see how a large buy or sell will move the bonding curve price before committing. This issue implements a client-side bonding curve simulation engine that runs the full curve formula in the browser, renders an interactive price impact preview as the user drags a quantity slider, and highlights the slippage percentage relative to the current spot price — all without a server round-trip.
Scope
1. Curve engine (pure TypeScript)
computeBuyCost(currentSupply: bigint, amount: bigint, feeBps: bigint): { grossCost: bigint, fee: bigint, netCost: bigint, newPrice: bigint }using bigint arithmetic only (no floating point)computeSellPayout(currentSupply: bigint, amount: bigint, feeBps: bigint): { grossPayout: bigint, fee: bigint, netPayout: bigint, newPrice: bigint }2. Interactive price impact slider
min(availableSupply, 500)(newPrice - currentPrice) / currentPrice * 1003. Price impact chart overlay
[currentSupply, currentSupply + sliderMax]requestAnimationFrameand a canvas renderer (not SVG) for performance4. Worst-case XLM display
max_price= computed cost + 0.5% buffer) alongside the expected cost so the user understands the slippage tolerance that will be submitted to the contractmax_pricebuffer percentage should be configurable in app config5. Unit and performance tests
computeBuyCostmatches reference table for supplies 0, 1, 10, 100, 1000computeSellPayoutmatches reference tableperformance.now()assertions in tests)Acceptance Criteria
requestAnimationFrameof slider moveETA: 24 hours
Coordinate on Telegram