-
Notifications
You must be signed in to change notification settings - Fork 0
Slippage
When trading on a decentralized exchange (DEX) like PancakeSwap V3, it's important to understand how slippage and minimum output (minimumOut) affect your transactions. This page will explain what slippage is, how it works, and how you can calculate and set a minimum output amount to protect your trades.
Slippage occurs when the final price of a trade is different from the price you expected due to rapid changes in token prices or insufficient liquidity. On PancakeSwap V3, trades are executed based on the best available price at the time, but if the market moves while your trade is being processed, you may receive fewer tokens than anticipated.
For example, if you’re swapping tokens and expect to get 100 tokens, but due to slippage, you might end up receiving only 98 or 99 tokens. Slippage can happen because other users are making trades at the same time, or the market is volatile and moving quickly.
High volatility or low liquidity can result in trades executing at less favorable prices. To protect yourself from slippage, you can specify a minimum amount of tokens you're willing to accept in a swap, known as the amountOutMinimum
.
This ensures that the transaction will only execute if the amount of tokens received is greater than or equal to this minimum. If the market price moves unfavorably and the received amount falls below the amountOutMinimum
, the transaction will fail, preventing you from incurring a greater loss than you anticipated.
The amountOutMinimum
is calculated by applying a slippage tolerance to the quoted amount of tokens you expect to receive from the trade. This gives you a buffer against unfavorable price movements.
Formula to Calculate amountOutMinimum
:
amountOutMinimum = expectedAmount * (1 - slippage)
Where:
-
expectedAmount
- The expected amount of tokens you'll receive based on the current exchange rate (quoted by the DEX) -
slippage
- The acceptable slippage tolerance, expressed as a percentage (e.g., for 1% slippage, use 0.01)
Example:
Suppose you're swapping 1 BNB for MEME tokens on a DEX, and you expect to receive 100 MEME tokens. You want to protect yourself from a 2% price slippage.
-
expectedAmount
- 100 MEME tokens (quoted by the exchange) -
slippage
- 2% or 0.02
amountOutMinimum = 100 * (1 - 0.02) = 100 * 0.98 = 98 MEME tokens
In this case, you'd set amountOutMinimum
to 98 MEME tokens. If the trade executes and results in fewer than 98 MEME tokens, the transaction will revert, ensuring you don’t get a worse deal than you intended.
// Typescript example
import { ethers } from "ethers";
const expectedAmount = ethers.parseUnits("100", 18); // 100 MEME tokens
const slippageTolerance = 0.02; // 2% slippage
// Calculate amountOutMinimum
const amountOutMinimum = expectedAmount.mul(ethers.BigNumber.from(100).sub(ethers.BigNumber.from(slippageTolerance * 100))).div(100);
console.log(`Amount Out Minimum: ${amountOutMinimum.toString()} MEME tokens`);
In the context of the BNBPartyFactory, understanding and implementing slippage management through the amountOutMinimum
is crucial for ensuring that trades executed via the smart contract meet user expectations. Here’s how it works within the joinParty
and leaveParty
functions of the BNBPartyFactory contract:
Here’s how to implement the slippage calculation and call the joinParty
and leaveParty
functions in TypeScript:
import { ethers } from "ethers";
// Function to calculate amountOutMinimum
function calculateAmountOutMinimum(expectedAmount: ethers.BigNumber, slippageTolerance: number): ethers.BigNumber {
const slippageFactor = ethers.BigNumber.from((1 - slippageTolerance).toFixed(2).split('.')[1]);
return expectedAmount.mul(100 - slippageFactor.toNumber()).div(100);
}
async function joinParty(tokenOut: string, amountIn: ethers.BigNumber, slippageTolerance: number) {
const expectedAmount = await getExpectedAmount(tokenOut); // Implement this function to get expected amount
const amountOutMinimum = calculateAmountOutMinimum(expectedAmount, slippageTolerance);
const params = {
tokenOut,
amountOutMinimum: amountOutMinimum.toString(),
};
const tx = await bnbPartyFactoryContract.joinParty(params.tokenOut, params.amountOutMinimum, {
value: amountIn, // BNB sent in the transaction
});
await tx.wait(); // Wait for the transaction to be mined
console.log(`Joined party and received a minimum of ${params.amountOutMinimum} tokens.`);
}
async function leaveParty(tokenIn: string, amountIn: ethers.BigNumber, slippageTolerance: number) {
const expectedAmount = await getExpectedAmountForBNB(tokenIn); // Implement this function to get expected BNB amount
const amountOutMinimum = calculateAmountOutMinimum(expectedAmount, slippageTolerance);
const params = {
tokenIn,
amountIn: amountIn.toString(),
amountOutMinimum: amountOutMinimum.toString(),
};
const tx = await bnbPartyFactoryContract.leaveParty(params.tokenIn, params.amountIn, params.amountOutMinimum);
await tx.wait(); // Wait for the transaction to be mined
console.log(`Left party and received a minimum of ${params.amountOutMinimum} BNB.`);
}
(async () => {
const tokenOutAddress = "0x..."; // Replace with actual token address
const tokenInAddress = "0x..."; // Replace with actual token address
const amountIn = ethers.utils.parseEther("1.0"); // 1 BNB
const slippageTolerance = 0.02; // 2%
await joinParty(tokenOutAddress, amountIn, slippageTolerance);
await leaveParty(tokenInAddress, ethers.utils.parseUnits("100", 18), slippageTolerance); // Assuming leaving 100 tokens
})();
- Ensure you implement the
getExpectedAmount
andgetExpectedAmountForBNB
functions to retrieve the expected amounts from the DEX or contract logic. - Adjust the
ethers
and contract references as needed based on your project's setup. - Handle exceptions and errors in a real application for robustness.