Created
February 3, 2025 10:33
-
-
Save beauwilliams/14cd70a07d753a697911a64e1138a37d to your computer and use it in GitHub Desktop.
SimpleSwapV2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.0; | |
// Minimal interface for the Uniswap V2 Router. | |
interface IUniswapV2Router { | |
function swapExactTokensForTokens( | |
uint amountIn, // amount of input tokens to send. | |
uint amountOutMin, // minimum amount of output tokens that must be received for the transaction not to revert. | |
address[] calldata path,// an array of token addresses. path.length must be >= 2. Pools for each consecutive pair must exist. | |
address to, // recipient of the output tokens. | |
uint deadline // Unix timestamp after which the transaction will revert. | |
) external returns (uint[] memory amounts); | |
// Added function to fetch expected output amounts for a given input. | |
function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); | |
} | |
// Minimal ERC20 interface needed for token transfers and approvals. | |
interface IERC20 { | |
function transferFrom( | |
address sender, | |
address recipient, | |
uint256 amount | |
) external returns (bool); | |
function approve( | |
address spender, | |
uint256 amount | |
) external returns (bool); | |
} | |
contract SimpleSwap { | |
// Instance of the Uniswap V2 Router. | |
IUniswapV2Router public immutable uniswapRouter; | |
// Set the router address upon deployment. | |
constructor(address _router) { | |
uniswapRouter = IUniswapV2Router(_router); | |
} | |
/** | |
* @notice Swap a given amount of tokenIn for tokenOut using Uniswap. | |
* Slippage is hardcoded to 10% and the deadline is set to 15 minutes from now. | |
* @param tokenIn The address of the ERC20 token to swap from. | |
* @param tokenOut The address of the ERC20 token to swap to. | |
* @param amountIn The exact amount of tokenIn to swap. | |
*/ | |
function swapTokens( | |
address tokenIn, | |
address tokenOut, | |
uint amountIn | |
) external { | |
// 1. Transfer tokenIn from the caller to this contract. | |
// The user must have approved this contract to spend tokenIn. | |
require( | |
IERC20(tokenIn).transferFrom(msg.sender, address(this), amountIn), | |
"Transfer of tokenIn failed" | |
); | |
// 2. Approve the Uniswap router to spend the tokenIn held by this contract. | |
require( | |
IERC20(tokenIn).approve(address(uniswapRouter), amountIn), | |
"Approval failed" | |
); | |
// 3. Define the swap path: from tokenIn directly to tokenOut. | |
address[] memory path = new address[](2); | |
path[0] = tokenIn; | |
path[1] = tokenOut; | |
// 4. Get the expected output amount using Uniswap's pricing. | |
uint[] memory amountsOut = uniswapRouter.getAmountsOut(amountIn, path); | |
uint expectedOut = amountsOut[amountsOut.length - 1]; | |
// 5. Calculate the minimum acceptable output accounting for a 10% slippage tolerance. | |
// For example, if expectedOut is 100 tokens, minAmountOut will be 90 tokens. | |
uint minAmountOut = (expectedOut * 90) / 100; | |
// 6. Set deadline as 15 minutes from the current block timestamp. | |
uint deadline = block.timestamp + 15 minutes; | |
// 7. Perform the swap on Uniswap. | |
// The output tokens will be sent directly to the caller. | |
uniswapRouter.swapExactTokensForTokens( | |
amountIn, | |
minAmountOut, | |
path, | |
msg.sender, | |
deadline | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment