// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// Uniswap V2 Router interface
interface IUniswapV2Router02 {
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external payable;
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
function getAmountsOut(uint amountIn, address[] memory path) external view returns (uint[] memory amounts);
function WETH() external pure returns (address);
}
interface IERC20 {
function approve(address spender, uint256 amount) external returns (bool);
function balanceOf(address account) external view returns (uint256);
}
contract BundleBuyAndSell {
IUniswapV2Router02 public uniswapRouter;
address public WETH;
constructor(address _uniswapRouter) {
uniswapRouter = IUniswapV2Router02(_uniswapRouter);
WETH = uniswapRouter.WETH(); // Get WETH address from the router
}
/**
* @dev Function to buy and sell a token in a single transaction
* @param tokenAddress The address of the token to buy and then sell.
* @param amountOutMinBuy The minimum amount of tokens to receive when buying.
* @param amountOutMinSell The minimum amount of ETH to receive when selling.
*/
function bundleBuyAndSell(
address tokenAddress,
uint256 amountOutMinBuy,
uint256 amountOutMinSell
) external payable {
require(msg.value > 0, "ETH required to buy tokens");
// Step 1: Buy tokens with ETH
address[] memory buyPath = new address[](2);
buyPath[0] = WETH; // From WETH (ETH)
buyPath[1] = tokenAddress; // To token
uint256 deadline = block.timestamp + 300; // 5 minutes from now
uniswapRouter.swapExactETHForTokensSupportingFeeOnTransferTokens{value: msg.value}(
amountOutMinBuy,
buyPath,
address(this),
deadline
);
// Step 2: Sell the bought tokens for ETH
uint256 tokenBalance = IERC20(tokenAddress).balanceOf(address(this)); // Get the balance of the bought tokens
require(tokenBalance > 0, "No tokens to sell");
// Approve Uniswap to spend tokens
IERC20(tokenAddress).approve(address(uniswapRouter), tokenBalance);
address[] memory sellPath = new address[](2);
sellPath[0] = tokenAddress; // From token
sellPath[1] = WETH; // To WETH (ETH)
uniswapRouter.swapExactTokensForETHSupportingFeeOnTransferTokens(
tokenBalance,
amountOutMinSell,
sellPath,
msg.sender, // Send ETH back to the user
deadline
);
}
// Fallback function to allow the contract to receive ETH
receive() external payable {}
}
{
"compilationTarget": {
"BundleBuyAndSell.sol": "BundleBuyAndSell"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_uniswapRouter","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amountOutMinBuy","type":"uint256"},{"internalType":"uint256","name":"amountOutMinSell","type":"uint256"}],"name":"bundleBuyAndSell","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"uniswapRouter","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]