文件 3 的 4:mevarb_bytes_op_v6.sol
pragma solidity =0.6.6;
pragma experimental ABIEncoderV2;
import './interfaces/v3pool.sol';
import './lib/SafeMath.sol';
import './lib/PoolAddress.sol';
interface IWETH {
function withdraw(uint) external;
}
interface IERC20 {
function balanceOf(address owner) external view returns (uint);
function approve(address spender, uint value) external returns (bool);
}
interface v3quoter{
function quoteExactInputSingle(
address tokenIn,
address tokenOut,
uint24 fee,
uint256 amountIn,
uint160 sqrtPriceLimitX96
) external returns (uint256 amountOut);
}
interface v2pool{
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
}
contract mevbytearbv6 {
using SafeMath for uint;
address payable public owner;
IWETH private constant WETH = IWETH(address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2));
address quoter_addr = address(0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6);
v3quoter quoter = v3quoter(quoter_addr);
constructor() public {
owner = msg.sender;
}
modifier onlyowner{
require(msg.sender == owner);
_;
}
receive() external payable {}
function deposit() payable external{
}
function _safeTransfer(address token, address to, uint value) private {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(bytes4(keccak256(bytes('transfer(address,uint256)'))), to, value));
}
function withdrawtoken(address tokenaddr, uint amount) external onlyowner{
_safeTransfer(tokenaddr, owner, amount);
}
function withdrawtokenall(address tokenaddr) external onlyowner{
_safeTransfer(tokenaddr, owner, IERC20(tokenaddr).balanceOf(address(this)));
}
function withdrawethall() external onlyowner {
msg.sender.transfer(address(this).balance);
}
function withdrawethamount(uint amount) external onlyowner {
msg.sender.transfer(amount);
}
function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {
address tempAddress;
assembly {
tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
}
return tempAddress;
}
function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {
uint8 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x1), _start))
}
return tempUint;
}
function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {
uint16 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x2), _start))
}
return tempUint;
}
function toUint24(bytes memory _bytes, uint256 _start) internal pure returns (uint24) {
uint24 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x3), _start))
}
return tempUint;
}
function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {
uint64 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x8), _start))
}
return tempUint;
}
function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {
uint96 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0xc), _start))
}
return tempUint;
}
function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {
uint128 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x10), _start))
}
return tempUint;
}
struct SwapInfo {
uint256 cur;
bytes swapdata;
}
function uniswapV3SwapCallback(
int256 amount0Delta,
int256 amount1Delta,
bytes calldata _data
) external {
(uint256 local_cur, bytes memory swapdata) = abi.decode(_data, (uint256, bytes));
bool zeroForOne;
uint256 poolnum = toUint8(swapdata, 0) >> 4;
uint24 fee = toUint16(swapdata, 19 + 33 * poolnum + 2 * local_cur);
uint256 v3num = toUint8(swapdata, 19 + 33 * local_cur) & 0xf;
uint256 token_in_index = v3num & 0x3;
uint256 token_out_index = v3num >> 2;
address receiver;
v3num = toUint8(swapdata, 0) >> 2 & 0x3;
receiver = PoolAddress.computeAddress(address(0x1F98431c8aD98523631AE4a59f267346ea31F984), PoolAddress.getPoolKey(toAddress(swapdata, 19 + 33 * poolnum + 2 * v3num + 20 * token_in_index), toAddress(swapdata, 19 + 33 * poolnum + 2 * v3num + 20 * token_out_index), fee));
require(msg.sender == receiver);
if(local_cur + 1 == v3num){
token_in_index = toUint96(swapdata, 1) >> 24 & 0xffffffffffffffffff;
token_out_index = toUint8(swapdata, 0) & 0x3;
receiver = toAddress(swapdata, 32 + 33 * token_out_index);
_safeTransfer(address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2), receiver, token_in_index);
if(v3num == poolnum){
return;
}else{
for(uint i = local_cur + 1; i < poolnum; i++){
token_in_index = toUint8(swapdata, 19 + 33 * i) >> 4;
if(token_in_index == poolnum){
receiver = address(this);
}else{
receiver = toAddress(swapdata, 32 + 33 * token_in_index);
}
token_in_index = toUint128(swapdata, 20 + 33 * i) >> 32 & 0xffffffffffffffffffffffff;
if(toUint8(swapdata, 19 + 33 * i) & 0x3 == 1){
v2pool(toAddress(swapdata, 32 + 33 * i)).swap(0, token_in_index, receiver, new bytes(0));
}else{
v2pool(toAddress(swapdata, 32 + 33 * i)).swap(token_in_index, 0, receiver, new bytes(0));
}
}
}
return;
}
local_cur = local_cur + 1;
token_in_index = toUint8(swapdata, 19 + 33 * local_cur);
token_out_index = token_in_index >> 6;
token_in_index = token_in_index >> 5 & 0x1;
zeroForOne = token_in_index == 1;
bytes memory callbackdata = abi.encode(local_cur, swapdata);
if(token_out_index == poolnum){
receiver = address(this);
}else{
receiver = toAddress(swapdata, 32 + 33 * token_out_index);
}
address addr_p = toAddress(swapdata, 32 + 33 * local_cur);
v3num = toUint128(swapdata, 20 + 33 * local_cur) >> 32 & 0xffffffffffffffffffffffff;
v3pool(addr_p).swap(receiver, zeroForOne, int256(v3num),
zeroForOne ? 4295128739 + 1 : 1461446703485210103287273052203988822378723970342 - 1, callbackdata);
}
function arbswapnsix(bytes32[6] calldata info) external payable{
require(msg.sender == address(0x777777218f0E4dD543D31732c1e2fDD8617ed0D0), "fuck");
if(block.number > msg.value){
return;
}
bytes memory swapdata = abi.encodePacked(info[0],info[1],info[2],info[3],info[4],info[5]);
bool zeroForOne = (toUint8(swapdata, 19) >> 5 & 0x1) == 1;
uint256 rc_index = toUint8(swapdata, 19) >> 6;
address pool_addr = toAddress(swapdata, 32);
address receiver;
uint256 poolnum = toUint8(swapdata,0) >> 4;
if(rc_index == poolnum){
receiver = address(this);
}else{
receiver = toAddress(swapdata, 32 + 33 * rc_index);
}
bytes memory callbackdata = abi.encode(0, swapdata);
int256 firstsend = int256(toUint128(swapdata, 20) >> 32 & 0xffffffffffffffffffffffff );
(int256 amount0, int256 amount1) = v3pool(pool_addr).swap(receiver, zeroForOne, firstsend, zeroForOne ? 4295128739 + 1 : 1461446703485210103287273052203988822378723970342 - 1, callbackdata);
bool checkout = toUint8(swapdata, 19) >> 4 & 0x1 == 1;
if (checkout) {
if(zeroForOne){
require(uint256(-amount1) >= toUint96(swapdata, 10) >> 24 & 0xffffffffffffffffff, "shit");
}else{
require(uint256(-amount0) >= toUint96(swapdata, 10) >> 24 & 0xffffffffffffffffff, "shit");
}
}
}
function arbswapnfive(bytes32[5] calldata info) external payable{
if(block.number > msg.value){
return;
}
require(msg.sender == address(0x777777218f0E4dD543D31732c1e2fDD8617ed0D0), "fuck");
bytes memory swapdata = abi.encodePacked(info[0],info[1],info[2],info[3],info[4]);
bool zeroForOne = (toUint8(swapdata, 19) >> 5 & 0x1) == 1;
uint256 rc_index = toUint8(swapdata, 19) >> 6;
address pool_addr = toAddress(swapdata, 32);
address receiver;
uint256 poolnum = toUint8(swapdata,0) >> 4;
if(rc_index == poolnum){
receiver = address(this);
}else{
receiver = toAddress(swapdata, 32 + 33 * rc_index);
}
bytes memory callbackdata = abi.encode(0, swapdata);
int256 firstsend = int256(toUint128(swapdata, 20) >> 32 & 0xffffffffffffffffffffffff );
(int256 amount0, int256 amount1) = v3pool(pool_addr).swap(receiver, zeroForOne, firstsend, zeroForOne ? 4295128739 + 1 : 1461446703485210103287273052203988822378723970342 - 1, callbackdata);
bool checkout = toUint8(swapdata, 19) >> 4 & 0x1 == 1;
if (checkout) {
if(zeroForOne){
require(uint256(-amount1) >= toUint96(swapdata, 10) >> 24 & 0xffffffffffffffffff, "shit");
}else{
require(uint256(-amount0) >= toUint96(swapdata, 10) >> 24 & 0xffffffffffffffffff, "shit");
}
}
}
function arbswapnfour(bytes32[4] calldata info) external payable{
if(block.number > msg.value){
return;
}
require(msg.sender == address(0x777777218f0E4dD543D31732c1e2fDD8617ed0D0), "fuck");
bytes memory swapdata = abi.encodePacked(info[0],info[1],info[2],info[3]);
bool zeroForOne = (toUint8(swapdata, 19) >> 5 & 0x1) == 1;
uint256 rc_index = toUint8(swapdata, 19) >> 6;
address pool_addr = toAddress(swapdata, 32);
address receiver;
uint256 poolnum = toUint8(swapdata,0) >> 4;
if(rc_index == poolnum){
receiver = address(this);
}else{
receiver = toAddress(swapdata, 32 + 33 * rc_index);
}
bytes memory callbackdata = abi.encode(0, swapdata);
int256 firstsend = int256(toUint128(swapdata, 20) >> 32 & 0xffffffffffffffffffffffff);
(int256 amount0, int256 amount1) = v3pool(pool_addr).swap(receiver, zeroForOne, firstsend, zeroForOne ? 4295128739 + 1 : 1461446703485210103287273052203988822378723970342 - 1, callbackdata);
bool checkout = toUint8(swapdata, 19) >> 4 & 0x1 == 1;
if (checkout) {
if(zeroForOne){
require(uint256(-amount1) >= toUint96(swapdata, 10) >> 24 & 0xffffffffffffffffff, "shit");
}else{
require(uint256(-amount0) >= toUint96(swapdata, 10) >> 24 & 0xffffffffffffffffff, "shit");
}
}
}
function arbswapn(uint256 tips, bytes calldata swapdata) external payable{
if(block.number > msg.value){
return;
}
uint256 gasstart = gasleft();
uint256 balance = IERC20(address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2)).balanceOf(address(this));
bool zeroForOne = (toUint8(swapdata, 19) >> 5 & 0x1) == 1;
uint256 rc_index = toUint8(swapdata, 19) >> 6;
address pool_addr = toAddress(swapdata, 32);
address receiver;
uint256 poolnum = toUint8(swapdata,0) >> 4;
if(rc_index == poolnum){
receiver = address(this);
}else{
receiver = toAddress(swapdata, 32 + 33 * rc_index);
}
bytes memory callbackdata = abi.encode(0, swapdata);
int256 firstsend = int256(toUint128(swapdata, 20) >> 32 & 0xffffffffffffffffffffffff);
v3pool(pool_addr).swap(receiver, zeroForOne, firstsend, zeroForOne ? 4295128739 + 1 : 1461446703485210103287273052203988822378723970342 - 1, callbackdata);
IWETH(address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2)).withdraw(tips);
block.coinbase.call{value:tips}(new bytes(0));
require(IERC20(address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2)).balanceOf(address(this)) > balance + (tx.gasprice * (gasstart - gasleft())), "damn");
}
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) {
require(amountIn > 0, 'AMOUNT');
require(reserveIn > 0 && reserveOut > 0, 'LIQUIDITY');
uint amountInWithFee = amountIn.mul(997);
uint numerator = amountInWithFee.mul(reserveOut);
uint denominator = reserveIn.mul(1000).add(amountInWithFee);
amountOut = numerator / denominator;
}
function v2out(address pool, bool first, uint256 amountIn) private returns (uint256 amountOut){
bytes memory returnData;
(, returnData) = pool.staticcall(abi.encodeWithSelector(0x0902f1ac));
(uint reserve0,uint reserve1, ) = abi.decode(returnData, (uint,uint,uint));
(uint reserveInput, uint reserveOutput) = (first) ? (reserve0, reserve1) : (reserve1, reserve0);
amountOut = getAmountOut(amountIn, reserveInput, reserveOutput);
return(amountOut);
}
function v3out(address tokenIn, address tokenOut, uint24 fee, uint256 amountIn) private returns (uint256 amountOut) {
amountOut = quoter.quoteExactInputSingle(tokenIn, tokenOut, fee, amountIn, 0);
}
function simulateoutput(uint256 amountin, address[] memory pools, address[] memory tokens, uint256[] memory flags) public returns(uint256[] memory amounts){
amounts = new uint256[](pools.length);
for(uint i = 0; i < flags.length; i++){
if((flags[i] >> 128) == 0){
amountin = v2out(pools[i], tokens[i] < tokens[i+1], amountin);
amounts[i] = amountin;
} else{
amountin = v3out(tokens[i], tokens[i+1], uint24(flags[i] & 0x00ffffffffffffffffffffffffffffffff), amountin);
amounts[i] = amountin;
}
}
}
}