Posted By : Suchit
In the fast-paced world of decentralized finance (DeFi), swapping tokens , as a part of cryptocurrency development, is essential for providing liquidity and allowing smooth asset exchanges between different platforms. Uniswap, a top decentralized exchange (DEX), has led the way with its innovative V3 version, offering advanced features and better efficiency. In this blog, we'll explore and develop a smart contract, which makes it easy to swap tokens on Uniswap V3 using the SwapRouter02 interface.
The UniswapV3Swap contract facilitates token swaps on the Uniswap V3 protocol. It allows users to perform single-token and multi-step swaps with exact input and output conditions. This contract integrates with Uniswap's SwapRouter and handles transfers and approvals of ERC20 tokens, specifically WETH, DAI, and USDC.
Check out | How to Develop Programmable Non-Fungible Tokens on Solana
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "https://github.com/Uniswap/swap-router-contracts/blob/main/contracts/interfaces/ISwapRouter02.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract UniswapV3Swap {
address public SWAP_ROUTER_02;
address public WETH;
address public DAI;
address public USDC;
ISwapRouter02 private router = ISwapRouter02(SWAP_ROUTER_02);
IERC20 private weth = IERC20(WETH);
IERC20 private dai = IERC20(DAI);
constructor(
address _swapRouter,
address _weth,
address _dai,
address _usdc
) {
SWAP_ROUTER_02 = _swapRouter;
WETH = _weth;
DAI = _dai;
USDC = _usdc;
}
function swapExactInputSingle(uint256 amountIn, uint256 amountOutMin)
external
{
weth.transferFrom(msg.sender, address(this), amountIn);
weth.approve(address(router), amountIn);
ISwapRouter02.ExactInputSingleParams memory params = IV3SwapRouter
.ExactInputSingleParams({
tokenIn: WETH,
tokenOut: DAI,
fee: 3000,
recipient: msg.sender,
amountIn: amountIn,
amountOutMinimum: amountOutMin,
sqrtPriceLimitX96: 0
});
router.exactInputSingle(params);
}
function swapExactOutputSingle(uint256 amountOut, uint256 amountInMax)
external
{
weth.transferFrom(msg.sender, address(this), amountInMax);
weth.approve(address(router), amountInMax);
ISwapRouter02.ExactOutputSingleParams memory params = IV3SwapRouter
.ExactOutputSingleParams({
tokenIn: WETH,
tokenOut: DAI,
fee: 3000,
recipient: msg.sender,
amountOut: amountOut,
amountInMaximum: amountInMax,
sqrtPriceLimitX96: 0
});
uint256 amountIn = router.exactOutputSingle(params);
if (amountIn < amountInMax) {
weth.approve(address(router), 0);
weth.transfer(msg.sender, amountInMax - amountIn);
}
}
function swapExactInputMultiStep(uint256 amountIn, uint256 amountOutMin)
external
{
weth.transferFrom(msg.sender, address(this), amountIn);
weth.approve(address(router), amountIn);
bytes memory path =
abi.encodePacked(WETH, uint24(3000), USDC, uint24(100), DAI);
ISwapRouter02.ExactInputParams memory params = IV3SwapRouter
.ExactInputParams({
path: path,
recipient: msg.sender,
amountIn: amountIn,
amountOutMinimum: amountOutMin
});
router.exactInput(params);
}
function swapExactOutputMultiStep(uint256 amountOut, uint256 amountInMax)
external
{
weth.transferFrom(msg.sender, address(this), amountInMax);
weth.approve(address(router), amountInMax);
bytes memory path =
abi.encodePacked(DAI, uint24(100), USDC, uint24(3000), WETH);
ISwapRouter02.ExactOutputParams memory params = IV3SwapRouter
.ExactOutputParams({
path: path,
recipient: msg.sender,
amountOut: amountOut,
amountInMaximum: amountInMax
});
uint256 amountIn = router.exactOutput(params);
if (amountIn < amountInMax) {
weth.approve(address(router), 0);
weth.transfer(msg.sender, amountInMax - amountIn);
}
}
}
USDC: The address of the USDC stablecoin ERC20 token.
dai: An instance of the IERC20 interface representing the DAI token.
Swaps an exact amount of WETH for DAI, ensuring at least a minimum amount of DAI is received. It transfers the specified amount of WETH from the sender to the contract, approves the router to spend that amount, sets up the swap parameters, and executes the swap using the router's exactInputSingle method.
Swaps WETH for an exact amount of DAI, ensuring no more than a maximum amount of WETH is spent. It transfers the maximum amount of WETH from the sender to the contract, approves the router to spend that amount, sets up the swap parameters, executes the swap using the router's exactOutputSingle method, and refunds any excess WETH to the sender.
Swaps an exact amount of WETH for DAI through a multi-step path (WETH -> USDC -> DAI). It transfers the specified amount of WETH from the sender to the contract, approves the router to spend that amount, constructs the multi-step path, sets up the swap parameters, and executes the swap using the router's exactInput method.
Swaps WETH for an exact amount of DAI through a multi-step path (DAI -> USDC -> WETH), ensuring no more than a maximum amount of WETH is spent. It transfers the maximum amount of WETH from the sender to the contract, approves the router to spend that amount, constructs the multi-step path, sets up the swap parameters, executes the swap using the router's exactOutput method, and refunds any excess WETH to the sender.
Read Also | How to Create a Token Swap dApp
With the UniswapV3Swap
smart contract, token swaps on Uniswap V3 become straightforward and efficient. By leveraging the SwapRouter02 interface, users can easily perform single-token and multi-step swaps, ensuring optimal outcomes with minimal effort. This contract handles ERC20 token transfers and approvals seamlessly, making it a valuable tool in the DeFi ecosystem. Contact our blockchain developers today!
November 21, 2024 at 11:35 am
Your comment is awaiting moderation.