diff --git a/src/components/swap-form.tsx b/src/components/swap-form.tsx
index 62c538c..62c6242 100644
--- a/src/components/swap-form.tsx
+++ b/src/components/swap-form.tsx
@@ -370,6 +370,18 @@ export function SwapForm() {
)}
+ {/* High slippage warning - show if calculated slippage exceeds max slippage OR 5% */}
+ {swapAmounts && swapAmounts.length > 0 && swapAmounts[0].calculatedSlippage !== undefined && (
+ Math.abs(swapAmounts[0].calculatedSlippage) > Math.max(currentSlippage, 5)
+ ) && (
+
+
⚠️ High Slippage Warning
+
+ The estimated slippage for this swap is {Math.abs(swapAmounts[0].calculatedSlippage).toFixed(2)}%. You may lose money due to low liquidity in this pool.
+
+
+ )}
+
{/* Gas Estimate, Slippage, and Fees */}
{isConnected && fromAmount && toAmount && (
diff --git a/src/hooks/usePartyPool.ts b/src/hooks/usePartyPool.ts
index f494731..1781fe0 100644
--- a/src/hooks/usePartyPool.ts
+++ b/src/hooks/usePartyPool.ts
@@ -2,9 +2,10 @@
import { useState, useEffect, useCallback } from 'react';
import { usePublicClient, useWalletClient } from 'wagmi';
-import { decodeEventLog } from 'viem';
+import { decodeEventLog, parseUnits } from 'viem';
import IPartyPoolABI from '@/contracts/IPartyPoolABI';
-import chainInfo from '../../../lmsr-amm/liqp-deployments.json';
+import chainInfo from '../contracts/liqp-deployments.json';
+import IPartyInfoABI from '@/contracts/IPartyInfoABI';
import type { AvailableToken } from './usePartyPlanner';
// Q96 constant for price calculations
@@ -20,6 +21,7 @@ export interface SwapAmountResult {
kappa: bigint;
inputTokenIndex: number;
outputTokenIndex: number;
+ calculatedSlippage?: number; // Percentage, e.g. 5.5 means 5.5%
}
/**
@@ -95,8 +97,7 @@ export function useSwapAmounts(
try {
setLoading(true);
- const amountInWei = BigInt(Math.floor(parseFloat(fromAmount) * Math.pow(10, fromTokenDecimals)));
-
+ const amountInTokenUnits = parseUnits(fromAmount, fromTokenDecimals);
// Calculate limit price based on slippage tolerance
// limitPrice in Q96 format = Q96 * (100 + slippage%) / 100
// This represents the maximum acceptable price ratio (1 + slippage%)
@@ -111,6 +112,8 @@ export function useSwapAmounts(
});
const results: SwapAmountResult[] = [];
+ const chainId = await publicClient.getChainId();
+ const partyInfoAddress = (chainInfo as any)[chainId]?.v1?.PartyInfo as `0x${string}` | undefined;
// Calculate swap amounts for ALL routes of each token
for (const token of availableTokens) {
@@ -129,7 +132,7 @@ export function useSwapAmounts(
args: [
BigInt(route.inputTokenIndex),
BigInt(route.outputTokenIndex),
- amountInWei,
+ amountInTokenUnits,
limitPrice,
],
}) as readonly [bigint, bigint, bigint];
@@ -143,6 +146,45 @@ export function useSwapAmounts(
functionName: 'kappa',
}) as bigint;
+ // Calculate slippage for this route
+ let calculatedSlippage: number | undefined;
+ if (partyInfoAddress) {
+ try {
+ // Get swap amounts with NO LIMIT (0 means no price limit)
+ const [swapInputAmount, swapOutputAmount, inFee] = await publicClient.readContract({
+ address: route.poolAddress,
+ abi: IPartyPoolABI,
+ functionName: 'swapAmounts',
+ args: [
+ BigInt(route.inputTokenIndex),
+ BigInt(route.outputTokenIndex),
+ amountInTokenUnits,
+ 0n, // NO LIMIT
+ ],
+ }) as readonly [bigint, bigint, bigint];
+
+ // Get the current market price from PoolInfo
+ const priceInt128 = await publicClient.readContract({
+ address: partyInfoAddress,
+ abi: IPartyInfoABI,
+ functionName: 'price',
+ args: [route.poolAddress, BigInt(route.inputTokenIndex), BigInt(route.outputTokenIndex)],
+ }) as bigint;
+
+ // Convert Q64 format to decimal (price = priceValue / 2^64)
+ const price = Number(priceInt128) / 2 ** 64;
+
+ // Calculate actual swap price with decimal correction
+ const swapPrice = Number(swapOutputAmount) / ((Number(swapInputAmount)) - Number(inFee));
+ // Calculate slippage: 1 - (actualPrice / marketPrice)
+ const slippage = 1 - (swapPrice / price);
+ calculatedSlippage = slippage * 100; // Convert to percentage
+ console.log('calculatedSlippage', calculatedSlippage)
+ } catch (slippageErr) {
+ console.error(`Error calculating slippage for ${token.symbol}:`, slippageErr);
+ }
+ }
+
routeResults.push({
tokenAddress: token.address,
tokenSymbol: token.symbol,
@@ -153,6 +195,7 @@ export function useSwapAmounts(
kappa,
inputTokenIndex: route.inputTokenIndex,
outputTokenIndex: route.outputTokenIndex,
+ calculatedSlippage,
});
} catch (err) {
console.error(`Error calculating swap for ${token.symbol} via ${route.poolAddress}:`, err);