[wif] slippage for burnSwap
This commit is contained in:
@@ -151,9 +151,14 @@ export function StakeForm({ defaultMode = 'stake' }: StakeFormProps) {
|
||||
const { burnSwapAmounts, loading: burnSwapLoading } = useBurnSwapAmounts(
|
||||
mode === 'unstake' && !redeemAll ? selectedPool?.address : undefined,
|
||||
mode === 'unstake' && !redeemAll ? maxAmountIn : undefined,
|
||||
mode === 'unstake' && !redeemAll ? inputTokenIndex : undefined
|
||||
mode === 'unstake' && !redeemAll ? inputTokenIndex : undefined,
|
||||
undefined, // lpTokenPrice - not needed for burnSwap custom calculation
|
||||
mode === 'unstake' && !redeemAll && selectedToken ? selectedToken.decimals : undefined
|
||||
);
|
||||
|
||||
|
||||
console.log('burn swap maounts', burnSwapAmounts)
|
||||
|
||||
// Fetch burn amounts (for unstake mode when redeeming all)
|
||||
const { burnAmounts, loading: burnAmountsLoading } = useBurnAmounts(
|
||||
mode === 'unstake' && redeemAll ? selectedPool?.address : undefined,
|
||||
|
||||
@@ -8,6 +8,7 @@ import IPartyPoolABI from '@/contracts/IPartyPoolABI';
|
||||
import IPartyPoolViewerABI from '@/contracts/IPartyPoolViewerABI';
|
||||
import IPartyInfoABI from '@/contracts/IPartyInfoABI';
|
||||
import { ERC20ABI } from '@/contracts/ERC20ABI';
|
||||
import { calculateSlippage } from './usePartyPool';
|
||||
|
||||
// Helper function to format large numbers with K, M, B suffixes
|
||||
function formatTVL(value: number): string {
|
||||
@@ -50,7 +51,7 @@ export function useGetAllTokens(offset: number = 0, limit: number = 100) {
|
||||
// Get chain ID and contract address
|
||||
const chainId = await publicClient.getChainId();
|
||||
// @ts-ignore
|
||||
const address = (chainInfo as Record<string, { v1: { PartyPlanner: string; PartyPoolViewer: string } }>)[chainId.toString()]?.v1?.PartyPlanner;
|
||||
const address = (chainInfo as Record<string, { v1: { PartyPlanner: string } }>)[chainId.toString()]?.v1?.PartyPlanner;
|
||||
|
||||
if (!address) {
|
||||
setError('IPartyPlanner contract not found for current chain');
|
||||
@@ -465,6 +466,7 @@ export function useGetAllPools(offset: number = 0, limit: number = 100) {
|
||||
|
||||
if (isWorking) {
|
||||
// Fetch pool price (use first token as quote, index 0)
|
||||
console.log('fetching pool price')
|
||||
try {
|
||||
const priceRaw = await publicClient.readContract({
|
||||
address: partyInfoAddress as `0x${string}`,
|
||||
@@ -565,17 +567,20 @@ export interface SwapMintAmounts {
|
||||
amountInUsed: bigint;
|
||||
fee: bigint;
|
||||
lpMinted: bigint;
|
||||
calculatedSlippage?: number; // Percentage, e.g. 5.5 means 5.5%
|
||||
}
|
||||
|
||||
export interface BurnSwapAmounts {
|
||||
amountOut: bigint;
|
||||
outFee: bigint;
|
||||
calculatedSlippage?: number; // Percentage, e.g. 5.5 means 5.5%
|
||||
}
|
||||
|
||||
export function useSwapMintAmounts(
|
||||
poolAddress: `0x${string}` | undefined,
|
||||
inputTokenIndex: number | undefined,
|
||||
maxAmountIn: bigint | undefined
|
||||
maxAmountIn: bigint | undefined,
|
||||
lpTokenPrice?: number // Market price of the LP token in decimal format
|
||||
) {
|
||||
const publicClient = usePublicClient();
|
||||
const [mounted, setMounted] = useState(false);
|
||||
@@ -608,26 +613,39 @@ export function useSwapMintAmounts(
|
||||
// Get chain ID and contract address
|
||||
const chainId = await publicClient.getChainId();
|
||||
// @ts-ignore
|
||||
const viewerAddress = (chainInfo as Record<string, { v1: { PartyPlanner: string; PartyPoolViewer: string } }>)[chainId.toString()]?.v1?.PartyPoolViewer;
|
||||
const partyInfoAddress = (chainInfo as Record<string, { v1: { PartyInfo: string } }>)[chainId.toString()]?.v1?.PartyInfo;
|
||||
|
||||
if (!viewerAddress) {
|
||||
setError('IPartyPoolViewer contract not found for current chain');
|
||||
if (!partyInfoAddress) {
|
||||
setError('PartyInfo contract not found for current chain');
|
||||
setSwapMintAmounts(null);
|
||||
return;
|
||||
}
|
||||
|
||||
// Call swapMintAmounts function
|
||||
const result = await publicClient.readContract({
|
||||
address: viewerAddress as `0x${string}`,
|
||||
address: partyInfoAddress as `0x${string}`,
|
||||
abi: IPartyPoolViewerABI,
|
||||
functionName: 'swapMintAmounts',
|
||||
args: [poolAddress, BigInt(inputTokenIndex), maxAmountIn],
|
||||
}) as readonly [bigint, bigint, bigint];
|
||||
|
||||
// Calculate slippage if LP token price is provided
|
||||
let calculatedSlippage: number | undefined;
|
||||
if (lpTokenPrice !== undefined) {
|
||||
try {
|
||||
// For swapMint: output is result[0] (amountInUsed), input is maxAmountIn, fee is result[2]
|
||||
calculatedSlippage = calculateSlippage(lpTokenPrice, result[0], maxAmountIn, result[2]);
|
||||
console.log('swapMint calculatedSlippage', calculatedSlippage);
|
||||
} catch (slippageErr) {
|
||||
console.error(`Error calculating slippage for swapMint:`, slippageErr);
|
||||
}
|
||||
}
|
||||
|
||||
setSwapMintAmounts({
|
||||
amountInUsed: result[0],
|
||||
fee: result[1],
|
||||
lpMinted: result[2],
|
||||
calculatedSlippage,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Error calling swapMintAmounts:', err);
|
||||
@@ -639,7 +657,7 @@ export function useSwapMintAmounts(
|
||||
};
|
||||
|
||||
fetchSwapMintAmounts();
|
||||
}, [publicClient, mounted, poolAddress, inputTokenIndex, maxAmountIn]);
|
||||
}, [publicClient, mounted, poolAddress, inputTokenIndex, maxAmountIn, lpTokenPrice]);
|
||||
|
||||
return {
|
||||
swapMintAmounts,
|
||||
@@ -652,7 +670,9 @@ export function useSwapMintAmounts(
|
||||
export function useBurnSwapAmounts(
|
||||
poolAddress: `0x${string}` | undefined,
|
||||
lpAmount: bigint | undefined,
|
||||
inputTokenIndex: number | undefined
|
||||
inputTokenIndex: number | undefined,
|
||||
lpTokenPrice?: number, // Market price of the LP token in decimal format
|
||||
tokenDecimals?: number // Decimals of the output token
|
||||
) {
|
||||
const publicClient = usePublicClient();
|
||||
const [mounted, setMounted] = useState(false);
|
||||
@@ -681,18 +701,21 @@ export function useBurnSwapAmounts(
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
console.log('fetching swap amounts')
|
||||
// Get chain ID and contract address
|
||||
const chainId = await publicClient.getChainId();
|
||||
// @ts-ignore
|
||||
const viewerAddress = (chainInfo as Record<string, { v1: { PartyPlanner: string; PartyPoolViewer: string } }>)[chainId.toString()]?.v1?.PartyPoolViewer;
|
||||
const partyInfoAddress = (chainInfo as Record<string, { v1: { PartyInfo: string } }>)[chainId.toString()]?.v1?.PartyInfo;
|
||||
|
||||
if (!viewerAddress) {
|
||||
setError('IPartyPoolViewer contract not found for current chain');
|
||||
if (!partyInfoAddress) {
|
||||
console.log('errores here')
|
||||
setError('PartyInfo contract not found for current chain');
|
||||
setBurnSwapAmounts(null);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('fetching swap amounts 2')
|
||||
|
||||
// Log inputs
|
||||
console.log('🔍 burnSwapAmounts INPUTS:', {
|
||||
chainId: chainId.toString(),
|
||||
@@ -700,12 +723,12 @@ export function useBurnSwapAmounts(
|
||||
poolAddress,
|
||||
lpAmount: lpAmount.toString(),
|
||||
inputTokenIndex,
|
||||
viewerAddress,
|
||||
partyInfoAddress,
|
||||
});
|
||||
|
||||
// Call burnSwapAmounts function - returns [amountOut, outFee]
|
||||
const result = await publicClient.readContract({
|
||||
address: viewerAddress as `0x${string}`,
|
||||
address: partyInfoAddress as `0x${string}`,
|
||||
abi: IPartyPoolViewerABI,
|
||||
functionName: 'burnSwapAmounts',
|
||||
args: [poolAddress, lpAmount, BigInt(inputTokenIndex)],
|
||||
@@ -717,16 +740,59 @@ export function useBurnSwapAmounts(
|
||||
amountOut: result[0].toString(),
|
||||
outFee: result[1].toString(),
|
||||
});
|
||||
// Calculate slippage for burnSwap using poolPrice
|
||||
let calculatedSlippage: number | undefined;
|
||||
if (tokenDecimals !== undefined) {
|
||||
try {
|
||||
// Get the market price from poolPrice (quoteTokenIndex = 0)
|
||||
const poolPriceInt128 = await publicClient.readContract({
|
||||
address: partyInfoAddress as `0x${string}`,
|
||||
abi: IPartyInfoABI,
|
||||
functionName: 'poolPrice',
|
||||
args: [poolAddress, BigInt(inputTokenIndex)],
|
||||
}) as bigint;
|
||||
|
||||
// Convert Q64 format to decimal (price = priceValue / 2^64)
|
||||
const marketPrice = Number(poolPriceInt128) / 2 ** 64;
|
||||
|
||||
// For burnSwap: swapPrice = (outAmount + fee) / lpAmount
|
||||
// Need to apply decimal corrections: outAmount and fee are in token decimals, lpAmount is in 18 decimals
|
||||
const outAmountDecimal = Number(result[0]) / Math.pow(10, tokenDecimals);
|
||||
const feeDecimal = Number(result[1]) / Math.pow(10, tokenDecimals);
|
||||
const lpAmountDecimal = Number(lpAmount) / Math.pow(10, 18); // LP tokens have 18 decimals
|
||||
|
||||
const swapPrice = (outAmountDecimal + feeDecimal) / lpAmountDecimal;
|
||||
|
||||
// Calculate slippage percentage: ((swapPrice - marketPrice) / marketPrice) * 100
|
||||
calculatedSlippage = ((swapPrice - marketPrice) / marketPrice) * 100;
|
||||
|
||||
console.log('burnSwap slippage calculation:', {
|
||||
marketPrice,
|
||||
swapPrice,
|
||||
calculatedSlippage,
|
||||
outAmountDecimal,
|
||||
feeDecimal,
|
||||
lpAmountDecimal,
|
||||
outAmount: result[0].toString(),
|
||||
fee: result[1].toString(),
|
||||
lpAmount: lpAmount.toString(),
|
||||
});
|
||||
} catch (slippageErr) {
|
||||
console.error(`Error calculating slippage for burnSwap:`, slippageErr);
|
||||
}
|
||||
}
|
||||
|
||||
const parsedAmounts = {
|
||||
amountOut: result[0],
|
||||
outFee: result[1],
|
||||
calculatedSlippage,
|
||||
};
|
||||
|
||||
// Log parsed result
|
||||
console.log('✅ burnSwapAmounts PARSED:', {
|
||||
amountOut: parsedAmounts.amountOut.toString(),
|
||||
outFee: parsedAmounts.outFee.toString(),
|
||||
calculatedSlippage: parsedAmounts.calculatedSlippage,
|
||||
});
|
||||
|
||||
setBurnSwapAmounts(parsedAmounts);
|
||||
@@ -740,7 +806,7 @@ export function useBurnSwapAmounts(
|
||||
};
|
||||
|
||||
fetchBurnSwapAmounts();
|
||||
}, [publicClient, mounted, poolAddress, lpAmount, inputTokenIndex]);
|
||||
}, [publicClient, mounted, poolAddress, lpAmount, inputTokenIndex, lpTokenPrice, tokenDecimals]);
|
||||
|
||||
return {
|
||||
burnSwapAmounts,
|
||||
|
||||
@@ -28,11 +28,10 @@ export function calculateSlippage(
|
||||
// Calculate actual swap price with decimal correction
|
||||
const swapPrice = Number(swapOutputAmount) / (Number(swapInputAmount) - Number(swapFee));
|
||||
|
||||
// Calculate slippage: 1 - (actualPrice / marketPrice)
|
||||
const slippage = 1 - (swapPrice / marketPrice);
|
||||
// Calculate slippage percentage: ((swapPrice - marketPrice) / marketPrice) * 100
|
||||
const slippage = ((swapPrice - marketPrice) / marketPrice) * 100;
|
||||
|
||||
// Convert to percentage
|
||||
return slippage * 100;
|
||||
return slippage;
|
||||
}
|
||||
|
||||
export interface SwapAmountResult {
|
||||
|
||||
Reference in New Issue
Block a user