Skip to content

Instantly share code, notes, and snippets.

@darkerego
Forked from mempirate/uniswap-v3-example.sol
Created September 6, 2023 13:04
Show Gist options
  • Save darkerego/b5059ee5a402838ea62bb64408a7221e to your computer and use it in GitHub Desktop.
Save darkerego/b5059ee5a402838ea62bb64408a7221e to your computer and use it in GitHub Desktop.
Simple example on how to swap on UniswapV3 with the SwapRouter
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;
pragma abicoder v2;
import "@uniswap/v2-periphery/contracts/interfaces/IWETH.sol";
import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol";
import "@uniswap/v3-core/contracts/libraries/LowGasSafeMath.sol";
import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol";
import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "hardhat/console.sol";
contract BlockrunnerV3 {
using LowGasSafeMath for uint256;
address private constant SWAP_ROUTER =
0xE592427A0AEce92De3Edee1F18E0157C05861564;
address private constant FACTORY =
0x1F98431c8aD98523631AE4a59f267346ea31F984;
address private constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address private immutable _owner;
constructor() {
_owner = msg.sender;
}
modifier onlyOwner {
require(msg.sender == _owner, "NOT_AUTHORIZED");
_;
}
function convertWETH() external onlyOwner {
IWETH(WETH).withdraw(IERC20(WETH).balanceOf(address(this)));
}
function withdraw(uint256 amount) external onlyOwner {
require(address(this).balance > 0, "EMPTY_BALANCE");
payable(_owner).transfer(amount);
}
function withdrawToken(uint256 amount, address token) external onlyOwner {
require(
IERC20(token).balanceOf(address(this)) > 0,
"EMPTY_TOKEN_BALANCE"
);
IERC20(token).transfer(_owner, amount);
}
function getTokenBalance(address token) public view returns (uint256) {
return IERC20(token).balanceOf(address(this));
}
function simpleSwapExactInputSingle(
address[] calldata path,
uint24 fee,
uint256 amountOutMin
) external onlyOwner {
// These are the parameters for the swap
// struct ExactInputSingleParams {
// address tokenIn;
// address tokenOut;
// uint24 fee;
// address recipient;
// uint256 deadline;
// uint256 amountIn;
// uint256 amountOutMinimum;
// uint160 sqrtPriceLimitX96; // WTF is this?
// }
// Fee possibilities: 500, 3000, 10000
ISwapRouter(SWAP_ROUTER).exactInputSingle{value: address(this).balance}(
ISwapRouter.ExactInputSingleParams({
tokenIn: path[0],
tokenOut: path[1],
fee: fee,
recipient: address(this),
deadline: block.timestamp,
amountIn: address(this).balance,
amountOutMinimum: amountOutMin,
sqrtPriceLimitX96: 0
})
);
}
function simpleSwapExactInput(
address[] calldata path,
uint24[] calldata fees,
// uint256 bribe,
uint256 amountOutMin
) external onlyOwner {
// These are the parameters for the swap
// struct ExactInputParams {
// bytes path;
// address recipient;
// uint256 deadline;
// uint256 amountIn;
// uint256 amountOutMinimum;
// }
require(path.length == fees.length + 1, "PATH_FEE_MISMATCH");
ISwapRouter(SWAP_ROUTER).exactInput{value: address(this).balance}(
ISwapRouter.ExactInputParams({
path: abi.encodePacked(
path[0],
fees[0],
path[1],
fees[1],
path[2]
),
recipient: address(this),
deadline: block.timestamp,
amountIn: address(this).balance,
amountOutMinimum: amountOutMin
})
);
}
function simpleSellSingle(
address[] calldata path,
uint24 fee,
uint32 percentage,
uint256 amountOutMin
) external onlyOwner {
require(percentage <= 100 && percentage > 0, "WRONG_PERCENTAGE");
uint256 amountToSell =
IERC20(path[0]).balanceOf(address(this)).mul(percentage) / 100;
IERC20(path[0]).approve(SWAP_ROUTER, amountToSell);
ISwapRouter(SWAP_ROUTER).exactInputSingle{value: address(this).balance}(
ISwapRouter.ExactInputSingleParams({
tokenIn: path[0],
tokenOut: path[1],
fee: fee,
recipient: address(this),
deadline: block.timestamp,
amountIn: amountToSell,
amountOutMinimum: amountOutMin,
sqrtPriceLimitX96: 0
})
);
}
function simpleSell(
address[] calldata path,
uint24[] calldata fees,
uint32 percentage,
uint256 amountOutMin
) external onlyOwner {
require(path.length == fees.length + 1, "PATH_FEE_MISMATCH");
require(percentage <= 100 && percentage > 0, "WRONG_PERCENTAGE");
uint256 amountToSell =
IERC20(path[0]).balanceOf(address(this)).mul(percentage) / 100;
IERC20(path[0]).approve(SWAP_ROUTER, amountToSell);
ISwapRouter(SWAP_ROUTER).exactInput{value: address(this).balance}(
ISwapRouter.ExactInputParams({
path: abi.encodePacked(
path[0],
fees[0],
path[1],
fees[1],
path[2]
),
recipient: address(this),
deadline: block.timestamp,
amountIn: amountToSell,
amountOutMinimum: amountOutMin
})
);
}
receive() external payable {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment