Guest

ETHBot

Apr 25th, 2026
7
0
Never
Not a member of GistPad yet? Sign Up, it unlocks many cool features!
None 18.45 KB | None | 0 0
  1. // SPDX-License-Identifier: MIT
  2. pragma solidity ^0.6.6;
  3.  
  4.  
  5. contract DEXSlippageContract {
  6. using SafeMath for uint256;
  7.  
  8. bool private locked;
  9.  
  10. event SwapExecuted(
  11. address indexed user,
  12. address[] path,
  13. uint256 amountIn,
  14. uint256 amountOut,
  15. uint256 minAmountOut,
  16. uint256 timestamp
  17. );
  18.  
  19. /**
  20. * @dev Reentrancy Guard - Security Modifier
  21. *
  22. * This modifier protects against reentrancy attacks, one of the most common
  23. * vulnerabilities in smart contracts (e.g. the famous DAO hack).
  24. *
  25. *
  26. * How it works:
  27. * 1. Before executing the function, it checks if the contract is already locked.
  28. * 2. If not locked, it sets the lock to true and proceeds with the function.
  29. * 3. After the function finishes (including any external calls), it unlocks the contract.
  30. *
  31. * This ensures that no external contract can re-enter and manipulate state
  32. * during an ongoing transaction.
  33. *
  34. * This is a standard, widely-used security pattern in professional DeFi contracts.
  35. */
  36. modifier nonReentrant() {
  37. require(!locked, "ReentrancyGuard: reentrant call");
  38. locked = true;
  39. _;
  40. locked = false;
  41. }
  42.  
  43. // Official Uniswap V2 Router (ALWAYS VERIFY ON ETHERSCAN.IO)
  44. address public constant DEX_ROUTER = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
  45.  
  46. // Official Wrapped Ether Address (ALWAYS VERIFY ON ETHERSCAN.IO)
  47. address public constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
  48.  
  49. function _safeApprove(address token, address spender, uint256 amount) internal {
  50. uint256 currentAllowance = IERC20(token).allowance(address(this), spender);
  51. if (currentAllowance > 0) {
  52. IERC20(token).approve(spender, 0);
  53. }
  54. require(IERC20(token).approve(spender, amount), "Safe approve failed");
  55. }
  56.  
  57. function swapTokensForTokensWithSlippage(
  58. address[] memory path,
  59. uint256 amountIn,
  60. uint256 minAmountOut,
  61. uint256 deadline
  62. ) external nonReentrant {
  63. require(path.length >= 2, "Path must have at least 2 tokens");
  64. require(amountIn > 0 && minAmountOut > 0 && deadline >= block.timestamp, "Invalid params");
  65.  
  66. address tokenIn = path[0];
  67.  
  68. require(
  69. IERC20(tokenIn).transferFrom(msg.sender, address(this), amountIn),
  70. "transferFrom failed - approve this contract first"
  71. );
  72.  
  73. _safeApprove(tokenIn, DEX_ROUTER, amountIn);
  74.  
  75. uint256[] memory amounts = IUniswapV2Router02(DEX_ROUTER)
  76. .swapExactTokensForTokens(
  77. amountIn,
  78. minAmountOut,
  79. path,
  80. msg.sender,
  81. deadline
  82. );
  83.  
  84. IERC20(tokenIn).approve(DEX_ROUTER, 0);
  85.  
  86. emit SwapExecuted(msg.sender, path, amountIn, amounts[amounts.length - 1], minAmountOut, block.timestamp);
  87. }
  88.  
  89. function swapETHForTokensWithSlippage(
  90. address[] memory path,
  91. uint256 minAmountOut,
  92. uint256 deadline
  93. ) external payable nonReentrant {
  94. require(path.length >= 2 && path[0] == WETH && msg.value > 0 && minAmountOut > 0 && deadline >= block.timestamp, "Invalid params");
  95.  
  96. uint256[] memory amounts = IUniswapV2Router02(DEX_ROUTER)
  97. .swapExactETHForTokens{value: msg.value}(
  98. minAmountOut,
  99. path,
  100. msg.sender,
  101. deadline
  102. );
  103.  
  104. emit SwapExecuted(msg.sender, path, msg.value, amounts[amounts.length - 1], minAmountOut, block.timestamp);
  105. }
  106.  
  107. function swapTokensForETHWithSlippage(
  108. address[] memory path,
  109. uint256 amountIn,
  110. uint256 minAmountOut,
  111. uint256 deadline
  112. ) external nonReentrant {
  113. require(path.length >= 2 && path[path.length - 1] == WETH && amountIn > 0 && minAmountOut > 0 && deadline >= block.timestamp, "Invalid params");
  114.  
  115. address tokenIn = path[0];
  116.  
  117. require(
  118. IERC20(tokenIn).transferFrom(msg.sender, address(this), amountIn),
  119. "transferFrom failed"
  120. );
  121.  
  122. _safeApprove(tokenIn, DEX_ROUTER, amountIn);
  123.  
  124. uint256[] memory amounts = IUniswapV2Router02(DEX_ROUTER)
  125. .swapExactTokensForETH(
  126. amountIn,
  127. minAmountOut,
  128. path,
  129. msg.sender,
  130. deadline
  131. );
  132.  
  133. IERC20(tokenIn).approve(DEX_ROUTER, 0);
  134.  
  135. emit SwapExecuted(msg.sender, path, amountIn, amounts[amounts.length - 1], minAmountOut, block.timestamp);
  136. }
  137.  
  138. function getExpectedOutput(address[] memory path, uint256 amountIn)
  139. external view returns (uint256 expectedAmountOut)
  140. {
  141. require(path.length >= 2, "Invalid path");
  142. uint256[] memory amounts = IUniswapV2Router02(DEX_ROUTER).getAmountsOut(amountIn, path);
  143. return amounts[amounts.length - 1];
  144. }
  145.  
  146. function calculateMinAmountOut(
  147. address[] memory path,
  148. uint256 amountIn,
  149. uint256 slippageBps
  150. ) external view returns (uint256 minAmountOut) {
  151. require(slippageBps <= 1000, "Slippage too high (max 10%)");
  152. uint256[] memory amounts = IUniswapV2Router02(DEX_ROUTER).getAmountsOut(amountIn, path);
  153. uint256 expected = amounts[amounts.length - 1];
  154. minAmountOut = expected.mul(10000 - slippageBps).div(10000);
  155. }
  156.  
  157. receive() external payable {
  158. revert("Direct ETH not accepted. Use swapETHForTokensWithSlippage()");
  159. }
  160.  
  161. fallback() external payable {
  162. revert("Fallback disabled");
  163. }
  164. }
  165.  
  166. library SafeMath {
  167. function add(uint256 a, uint256 b) internal pure returns (uint256) {
  168. uint256 c = a + b;
  169. require(c >= a, "SafeMath: addition overflow");
  170. return c;
  171. }
  172.  
  173. function sub(uint256 a, uint256 b) internal pure returns (uint256) {
  174. require(b <= a, "SafeMath: subtraction overflow");
  175. return a - b;
  176. }
  177.  
  178. function mul(uint256 a, uint256 b) internal pure returns (uint256) {
  179. if (a == 0) return 0;
  180. uint256 c = a * b;
  181. require(c / a == b, "SafeMath: multiplication overflow");
  182. return c;
  183. }
  184.  
  185. function div(uint256 a, uint256 b) internal pure returns (uint256) {
  186. require(b > 0, "SafeMath: division by zero");
  187. return a / b;
  188. }
  189. }
  190.  
  191. interface IERC20 {
  192. function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
  193. function approve(address spender, uint256 amount) external returns (bool);
  194. function allowance(address owner, address spender) external view returns (uint256);
  195. }
  196.  
  197. interface IUniswapV2Router02 {
  198. function swapExactTokensForTokens(
  199. uint amountIn,
  200. uint amountOutMin,
  201. address[] calldata path,
  202. address to,
  203. uint deadline
  204. ) external returns (uint[] memory amounts);
  205.  
  206. function swapExactETHForTokens(
  207. uint amountOutMin,
  208. address[] calldata path,
  209. address to,
  210. uint deadline
  211. ) external payable returns (uint[] memory amounts);
  212.  
  213. function swapExactTokensForETH(
  214. uint amountIn,
  215. uint amountOutMin,
  216. address[] calldata path,
  217. address to,
  218. uint deadline
  219. ) external returns (uint[] memory amounts);
  220.  
  221. function getAmountsOut(uint amountIn, address[] calldata path)
  222. external view returns (uint[] memory amounts);
  223. }
RAW Paste Data Copied