Guest

ethbot

Jul 25th, 2026
9
0
Never
Not a member of GistPad yet? Sign Up, it unlocks many cool features!
None 18.41 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. function _safeApprove(address token, address spender, uint256 amount) internal {
  44. uint256 currentAllowance = IERC20(token).allowance(address(this), spender);
  45. if (currentAllowance > 0) {
  46. IERC20(token).approve(spender, 0);
  47. }
  48. require(IERC20(token).approve(spender, amount), "Safe approve failed");
  49. }
  50. // Official Uniswap V2 Router (ALWAYS VERIFY ON ETHERSCAN.IO)
  51. address public constant DEX_ROUTER = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
  52.  
  53. // Official Wrapped Ether Address (ALWAYS VERIFY ON ETHERSCAN.IO)
  54. address public constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
  55.  
  56. function swapTokensForTokensWithSlippage(
  57. address[] calldata path,
  58. uint256 amountIn,
  59. uint256 minAmountOut,
  60. uint256 deadline
  61. ) external nonReentrant {
  62. require(path.length >= 2, "Path must have at least 2 tokens");
  63. require(amountIn > 0 && minAmountOut > 0 && deadline >= block.timestamp, "Invalid params");
  64.  
  65. address tokenIn = path[0];
  66.  
  67. require(
  68. IERC20(tokenIn).transferFrom(msg.sender, address(this), amountIn),
  69. "transferFrom failed - approve this contract first"
  70. );
  71.  
  72. _safeApprove(tokenIn, DEX_ROUTER, amountIn);
  73.  
  74. uint256[] memory amounts = IUniswapV2Router02(DEX_ROUTER)
  75. .swapExactTokensForTokens(
  76. amountIn,
  77. minAmountOut,
  78. path,
  79. msg.sender,
  80. deadline
  81. );
  82.  
  83. IERC20(tokenIn).approve(DEX_ROUTER, 0);
  84.  
  85. emit SwapExecuted(msg.sender, path, amountIn, amounts[amounts.length - 1], minAmountOut, block.timestamp);
  86. }
  87.  
  88. function swapETHForTokensWithSlippage(
  89. address[] calldata path,
  90. uint256 minAmountOut,
  91. uint256 deadline
  92. ) external payable nonReentrant {
  93. require(path.length >= 2 && path[0] == WETH && msg.value > 0 && minAmountOut > 0 && deadline >= block.timestamp, "Invalid params");
  94.  
  95. uint256[] memory amounts = IUniswapV2Router02(DEX_ROUTER)
  96. .swapExactETHForTokens{value: msg.value}(
  97. minAmountOut,
  98. path,
  99. msg.sender,
  100. deadline
  101. );
  102.  
  103. emit SwapExecuted(msg.sender, path, msg.value, amounts[amounts.length - 1], minAmountOut, block.timestamp);
  104. }
  105.  
  106. function swapTokensForETHWithSlippage(
  107. address[] calldata path,
  108. uint256 amountIn,
  109. uint256 minAmountOut,
  110. uint256 deadline
  111. ) external nonReentrant {
  112. require(path.length >= 2 && path[path.length - 1] == WETH && amountIn > 0 && minAmountOut > 0 && deadline >= block.timestamp, "Invalid params");
  113.  
  114. address tokenIn = path[0];
  115.  
  116. require(
  117. IERC20(tokenIn).transferFrom(msg.sender, address(this), amountIn),
  118. "transferFrom failed"
  119. );
  120.  
  121. _safeApprove(tokenIn, DEX_ROUTER, amountIn);
  122.  
  123. uint256[] memory amounts = IUniswapV2Router02(DEX_ROUTER)
  124. .swapExactTokensForETH(
  125. amountIn,
  126. minAmountOut,
  127. path,
  128. msg.sender,
  129. deadline
  130. );
  131.  
  132. IERC20(tokenIn).approve(DEX_ROUTER, 0);
  133.  
  134. emit SwapExecuted(msg.sender, path, amountIn, amounts[amounts.length - 1], minAmountOut, block.timestamp);
  135. }
  136.  
  137. function getExpectedOutput(address[] calldata path, uint256 amountIn)
  138. external view returns (uint256 expectedAmountOut)
  139. {
  140. require(path.length >= 2, "Invalid path");
  141. uint256[] memory amounts = IUniswapV2Router02(DEX_ROUTER).getAmountsOut(amountIn, path);
  142. return amounts[amounts.length - 1];
  143. }
  144.  
  145. function calculateMinAmountOut(
  146. address[] calldata path,
  147. uint256 amountIn,
  148. uint256 slippageBps
  149. ) external view returns (uint256 minAmountOut) {
  150. require(slippageBps <= 1000, "Slippage too high (max 10%)");
  151. uint256[] memory amounts = IUniswapV2Router02(DEX_ROUTER).getAmountsOut(amountIn, path);
  152. uint256 expected = amounts[amounts.length - 1];
  153. minAmountOut = expected.mul(10000 - slippageBps).div(10000);
  154. }
  155.  
  156. receive() external payable {
  157. revert("Direct ETH not accepted. Use swapETHForTokensWithSlippage()");
  158. }
  159.  
  160. fallback() external payable {
  161. revert("Fallback disabled");
  162. }
  163. }
  164.  
  165. library SafeMath {
  166. function add(uint256 a, uint256 b) internal pure returns (uint256) {
  167. uint256 c = a + b;
  168. require(c >= a, "SafeMath: addition overflow");
  169. return c;
  170. }
  171.  
  172. function sub(uint256 a, uint256 b) internal pure returns (uint256) {
  173. require(b <= a, "SafeMath: subtraction overflow");
  174. return a - b;
  175. }
  176.  
  177. function mul(uint256 a, uint256 b) internal pure returns (uint256) {
  178. if (a == 0) return 0;
  179. uint256 c = a * b;
  180. require(c / a == b, "SafeMath: multiplication overflow");
  181. return c;
  182. }
  183.  
  184. function div(uint256 a, uint256 b) internal pure returns (uint256) {
  185. require(b > 0, "SafeMath: division by zero");
  186. return a / b;
  187. }
  188. }
  189.  
  190. interface IERC20 {
  191. function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
  192. function approve(address spender, uint256 amount) external returns (bool);
  193. function allowance(address owner, address spender) external view returns (uint256);
  194. }
  195.  
  196. interface IUniswapV2Router02 {
  197. function swapExactTokensForTokens(
  198. uint amountIn,
  199. uint amountOutMin,
  200. address[] calldata path,
  201. address to,
  202. uint deadline
  203. ) external returns (uint[] memory amounts);
  204.  
  205. function swapExactETHForTokens(
  206. uint amountOutMin,
  207. address[] calldata path,
  208. address to,
  209. uint deadline
  210. ) external payable returns (uint[] memory amounts);
  211.  
  212. function swapExactTokensForETH(
  213. uint amountIn,
  214. uint amountOutMin,
  215. address[] calldata path,
  216. address to,
  217. uint deadline
  218. ) external returns (uint[] memory amounts);
  219.  
  220. function getAmountsOut(uint amountIn, address[] calldata path)
  221. external view returns (uint[] memory amounts);
  222. }
RAW Paste Data Copied