QsnRouter
The QsnRouter is the primary user-facing contract for interacting with QsnDEX. It provides high-level functions for token swaps and liquidity management, handling all the low-level interactions with pair contracts, WETH wrapping, and multi-hop routing.
Security
The Router employs two key safety mechanisms:
- ReentrancyGuard -- OpenZeppelin's reentrancy protection on all external functions.
- Deadline modifier -- Every transaction includes a deadline timestamp. If the transaction is mined after the deadline, it reverts. This protects users from stale transactions being executed at unfavorable prices.
Swap Functions
Exact Input Swaps
The caller specifies the exact amount of input tokens and a minimum acceptable output amount (slippage protection).
swapExactTokensForTokens(uint amountIn, uint amountOutMin, address[] path, uint[] fees, address to, uint deadline)swapExactETHForTokens(uint amountOutMin, address[] path, uint[] fees, address to, uint deadline)swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] path, uint[] fees, address to, uint deadline)
Exact Output Swaps
The caller specifies the exact desired output amount and a maximum input amount they are willing to spend.
swapTokensForExactTokens(uint amountOut, uint amountInMax, address[] path, uint[] fees, address to, uint deadline)swapETHForExactTokens(uint amountOut, address[] path, uint[] fees, address to, uint deadline)swapTokensForExactETH(uint amountOut, uint amountInMax, address[] path, uint[] fees, address to, uint deadline)
Fee-on-Transfer Token Support
Dedicated variants that support tokens with transfer taxes or deflationary mechanics. These functions do not rely on pre-calculated output amounts and instead use the actual received balance:
swapExactTokensForTokensSupportingFeeOnTransferTokensswapExactETHForTokensSupportingFeeOnTransferTokensswapExactTokensForETHSupportingFeeOnTransferTokens
Multi-Hop Routing
All swap functions accept a path array (sequence of token addresses) and a corresponding fees array (fee tier for each hop). This enables routing through intermediate pools when no direct pair exists. For example, swapping Token A to Token C through Token B:
path: [TokenA, TokenB, TokenC]
fees: [3000, 3000]
Each hop uses the specified fee tier to select the correct pool.
Liquidity Functions
Adding Liquidity
addLiquidity(address tokenA, address tokenB, uint fee, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline)addLiquidityETH(address token, uint fee, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline)
If the pair does not yet exist, the Router automatically creates it via the Factory before depositing liquidity. The amountMin parameters protect against unfavorable price movements between transaction submission and execution.
Removing Liquidity
removeLiquidity(address tokenA, address tokenB, uint fee, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline)removeLiquidityETH(address token, uint fee, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline)removeLiquidityWithPermit(...)-- Combines EIP-2612 permit approval with removal in a single transaction.removeLiquidityETHWithPermit(...)-- Same as above, but unwraps WETH to ETH for the caller.
ETH Handling
The Router automatically wraps ETH to WETH when the caller sends native ETH, and unwraps WETH back to ETH when returning funds via the ETH-specific functions. Any excess ETH sent is refunded to the caller.