Swapping
Execute swaps against Rapiddex v3 pools directly from your smart contracts using the SwapRouter.
This guide explains how to integrate token swaps on Rapiddex v3 into your smart contracts. It covers
interacting with the ISwapRouter contract for single-hop swaps using both exact input (known
amount of input tokens) and exact output (known amount of desired output tokens).
The Swap Router
The SwapRouter contract executes token swaps on Rapiddex v3. It acts as the periphery wrapper around pools, ensuring safe execution, transfer of tokens, and slippage verification. Smart contracts call the router by passing parameters packed into structs.
Exact Input Single Hop
An exact input swap trades a fixed amount of tokenIn for the maximum possible amount of
tokenOut. A single-hop swap routes trades through a single pool identified by its fee tier.
Exact Output Single Hop
An exact output swap trades a minimum possible amount of tokenIn for a fixed target amount of
tokenOut. If the trade requires fewer tokens than the maximum allowed, the unused input tokens
must be refunded to the caller.
Solidity Implementation Examples
The following Solidity contract shows how to set up token approvals, transfer tokens from the user, and execute single-hop swaps via the SwapRouter:
solidity// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@rapiddex/v3-periphery/contracts/interfaces/ISwapRouter.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract SwapExamples {
ISwapRouter public immutable swapRouter;
// The SwapRouter is deployed at a fixed address on each chain (see Deployments)
constructor(ISwapRouter _swapRouter) {
swapRouter = _swapRouter;
}
/// @notice Swap a fixed amount of tokenIn for tokenOut
function swapExactInputSingle(
address tokenIn,
address tokenOut,
uint24 fee,
uint256 amountIn,
uint256 amountOutMinimum
) external returns (uint256 amountOut) {
// Pull tokenIn from the sender to this contract
IERC20(tokenIn).transferFrom(msg.sender, address(this), amountIn);
// Approve the SwapRouter to spend tokenIn from this contract
IERC20(tokenIn).approve(address(swapRouter), amountIn);
ISwapRouter.ExactInputSingleParams memory params =
ISwapRouter.ExactInputSingleParams({
tokenIn: tokenIn,
tokenOut: tokenOut,
fee: fee,
recipient: msg.sender,
deadline: block.timestamp,
amountIn: amountIn,
amountOutMinimum: amountOutMinimum,
sqrtPriceLimitX96: 0
});
// Execute the swap
amountOut = swapRouter.exactInputSingle(params);
}
/// @notice Swap tokenIn for a fixed amount of tokenOut
function swapExactOutputSingle(
address tokenIn,
address tokenOut,
uint24 fee,
uint256 amountOut,
uint256 amountInMaximum
) external returns (uint256 amountIn) {
// Transfer max possible tokenIn from the sender
IERC20(tokenIn).transferFrom(msg.sender, address(this), amountInMaximum);
// Approve the router to spend tokenIn
IERC20(tokenIn).approve(address(swapRouter), amountInMaximum);
ISwapRouter.ExactOutputSingleParams memory params =
ISwapRouter.ExactOutputSingleParams({
tokenIn: tokenIn,
tokenOut: tokenOut,
fee: fee,
recipient: msg.sender,
deadline: block.timestamp,
amountOut: amountOut,
amountInMaximum: amountInMaximum,
sqrtPriceLimitX96: 0
});
// Execute the swap
amountIn = swapRouter.exactOutputSingle(params);
// Refund any leftover tokenIn to the caller
if (amountIn < amountInMaximum) {
IERC20(tokenIn).approve(address(swapRouter), 0);
IERC20(tokenIn).transfer(msg.sender, amountInMaximum - amountIn);
}
}
}
Parameters and Outputs Reference
1. exactInputSingle
Executes a swap to trade a fixed input amount of one token for as many output tokens as possible.
| Struct Field (ExactInputSingleParams) | Type | Description |
|---|---|---|
tokenIn |
address | The contract address of the input token (token to spend). |
tokenOut |
address | The contract address of the output token (token to receive). |
fee |
uint24 | The fee tier of the pool (500 for 0.05%, 3000 for 0.30%, 10000 for 1.00%). |
recipient |
address | The destination address that will receive the output tokens. |
deadline |
uint256 | The Unix timestamp after which the transaction will revert if not processed. |
amountIn |
uint256 | The exact amount of input tokens to send for the swap. |
amountOutMinimum |
uint256 | The minimum amount of output tokens expected. Reverts if slippage exceeds this bounds. |
sqrtPriceLimitX96 |
uint160 | The square root price limit. Set to 0 to bypass price limiting. |
Output: amountOut (uint256) - The actual amount of output tokens sent to the
recipient.
2. exactOutputSingle
Executes a swap to trade as few input tokens as possible for an exact target amount of output tokens.
| Struct Field (ExactOutputSingleParams) | Type | Description |
|---|---|---|
tokenIn |
address | The contract address of the input token (token to spend). |
tokenOut |
address | The contract address of the output token (token to receive). |
fee |
uint24 | The fee tier of the pool (500 for 0.05%, 3000 for 0.30%, 10000 for 1.00%). |
recipient |
address | The destination address that will receive the output tokens. |
deadline |
uint256 | The Unix timestamp after which the transaction will revert if not processed. |
amountOut |
uint256 | The exact amount of output tokens to receive. |
amountInMaximum |
uint256 | The maximum amount of input tokens allowed to be spent. Reverts if swap costs more. |
sqrtPriceLimitX96 |
uint160 | The square root price limit. Set to 0 to bypass price limiting. |
Output: amountIn (uint256) - The actual amount of input tokens spent in the
swap.
