账户
0xaf...6014
0xaf...6014

0xaf...6014

$500
此合同的源代码已经过验证!
合同元数据
编译器
0.6.6+commit.6c089d02
语言
Solidity
合同源代码
文件 1 的 4:PoolAddress.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;

/// @title Provides functions for deriving a pool address from the factory, tokens, and the fee
library PoolAddress {
    bytes32 internal constant POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;

    /// @notice The identifying key of the pool
    struct PoolKey {
        address token0;
        address token1;
        uint24 fee;
    }

    /// @notice Returns PoolKey: the ordered tokens with the matched fee levels
    /// @param tokenA The first token of a pool, unsorted
    /// @param tokenB The second token of a pool, unsorted
    /// @param fee The fee level of the pool
    /// @return Poolkey The pool details with ordered token0 and token1 assignments
    function getPoolKey(
        address tokenA,
        address tokenB,
        uint24 fee
    ) internal pure returns (PoolKey memory) {
        if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA);
        return PoolKey({token0: tokenA, token1: tokenB, fee: fee});
    }

    /// @notice Deterministically computes the pool address given the factory and PoolKey
    /// @param factory The Uniswap V3 factory contract address
    /// @param key The PoolKey
    /// @return pool The contract address of the V3 pool
    function computeAddress(address factory, PoolKey memory key) internal pure returns (address pool) {
        //require(key.token0 < key.token1);
        pool = address(
            uint256(
                keccak256(
                    abi.encodePacked(
                        hex'ff',
                        factory,
                        keccak256(abi.encode(key.token0, key.token1, key.fee)),
                        bytes32(0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54)
                    )
                )
            )
        );
    }
}
合同源代码
文件 2 的 4:SafeMath.sol
pragma solidity =0.6.6;

library SafeMath {

  /**
  * @dev Multiplies two numbers, throws on overflow.
  */
  function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
    if (a == 0) {
      return 0;
    }
    c = a * b;
    assert(c / a == b);
    return c;
  }

  /**
  * @dev Adds two numbers, throws on overflow.
  */
  function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
    c = a + b;
    assert(c >= a);
    return c;
  }
  
  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    assert(b <= a);
    return a - b;
  }  
  
}
合同源代码
文件 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';
// import './lib/CusByteslib.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;
    
    // uint160 internal constant MIN_SQRT_RATIO = 4295128739;
    // uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;
    // bytes4 private constant SELECTOR = bytes4(keccak256(bytes('transfer(address,uint256)')));
    
    // ropsten
    /*
    address wethaddr = address(0xc778417E063141139Fce010982780140Aa0cD5Ab);
    IWETH private constant WETH = IWETH(address(0xc778417E063141139Fce010982780140Aa0cD5Ab));
    */
    
    // goerli
    
    /*
    address wethaddr = address(0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6);
    IWETH private constant WETH = IWETH(address(0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6));
    */
    
    // main net
    
    // address wethaddr = address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
    IWETH private constant WETH = IWETH(address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2));
    
    
    // address factory = address(0x1F98431c8aD98523631AE4a59f267346ea31F984);
    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);
    }


    // util functions to operate on bytes
    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; // point to the current swap pool, plus one after every swap
        bytes swapdata;
    }


    function uniswapV3SwapCallback(
        int256 amount0Delta,
        int256 amount1Delta,
        bytes calldata _data
    ) external {
        /// require(amount0Delta > 0 || amount1Delta > 0); // swaps entirely within 0-liquidity regions are not supported
        (uint256 local_cur, bytes memory swapdata) = abi.decode(_data, (uint256, bytes));
        
        bool zeroForOne;
        // uint256 local_cur = data.cur;
        // bytes memory swapdata = data.swapdata;
        uint256 poolnum = toUint8(swapdata, 0) >> 4;
        // uint256 v3num = swapdata.toUint8(3) & 0xf;
        uint24 fee = toUint16(swapdata, 19 + 33 * poolnum + 2 * local_cur);

        
        // reuse v3num to store the token index
        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;
        
        
        // verify caller to make it safe
        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 last v3 swap, send weth to the first pool
        // and do all the v2 swaps
        if(local_cur + 1 == v3num){
            // reuse the token_in_index to store the amountin
            token_in_index = toUint96(swapdata, 1) >> 24 & 0xffffffffffffffffff;
            // reuse token_out_index to store the first pool's rc index
            token_out_index = toUint8(swapdata, 0) & 0x3;
            // use receiver to store the first pool addr
            receiver = toAddress(swapdata, 32 + 33 * token_out_index);
            
            _safeTransfer(address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2), receiver, token_in_index);
            
            // do the v2 swaps
            if(v3num == poolnum){
                return;
            }else{
                // the pools after data.cur is all v2 pools
                for(uint i = local_cur + 1; i < poolnum; i++){
                    // reuse the token_in_index to store the rc index of v2 pool info
                    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);
                    }                 
            
                    // reuse the token_in_index to store the amountout
                    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;

        }
        
        // not the last v3 swap, so swap v3 again
        local_cur = local_cur + 1;
        // data.cur = local_cur;
        // reuse token_in_index to store the rc index + zeroForOne
        token_in_index = toUint8(swapdata, 19 + 33 * local_cur);
        token_out_index = token_in_index >> 6; // this is the rc index
        token_in_index = token_in_index >> 5 & 0x1; // this is zeroForOne
        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);
        
        // reuse v3 num to store the amountin
        v3num = toUint128(swapdata, 20 + 33 * local_cur) >> 32 & 0xffffffffffffffffffffffff;
        
        // this one can't be the one with weth out
        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");
        
        // check the blknum to avoid the uncle blk pack
        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);
        // amountin occupys 12 bytes
        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);

        // reuse zeroForOne to check whether we need to check the amoutout
        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{

        // check the blknum to avoid the uncle blk pack
        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);
        // amountin occupys 12 bytes
        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);


        // reuse zeroForOne to check whether we need to check the amoutout
        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{

        // check the blknum to avoid the uncle blk pack
        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);
        // amountin occupys 12 bytes
        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);

        // reuse zeroForOne to check whether we need to check the amoutout
        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");
            }
        }

    }


    // use withdraw to pay the bribe
    function arbswapn(uint256 tips, bytes calldata swapdata) external payable{
        
        // check the blknum to avoid the uncle blk pack
        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);
        // amountin occupys 12 bytes
        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;
    } 


    // the first flag indicts whether the token transferred to the pool is the token0
    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)); // getreserve
        
        (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);
    }
    
    // simulate a swap and returns the exact output amount through trace_call
    function simulateoutput(uint256 amountin,  address[] memory pools, address[] memory tokens, uint256[] memory flags) public returns(uint256[] memory amounts){
 
        amounts = new uint256[](pools.length);
        // loop all the pools and do the swap
        for(uint i = 0; i < flags.length; i++){
            // the pool going to swap is v2 pool
            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;
            } 
   
        }
        
        
    }


    

}
合同源代码
文件 4 的 4:v3pool.sol
pragma solidity =0.6.6;
pragma experimental ABIEncoderV2;

interface v3pool {
  function swap(address recipient,
        bool zeroForOne,
        int256 amountSpecified,
        uint160 sqrtPriceLimitX96,
        bytes calldata data) external payable returns (int256 amount0, int256 amount1);

    function token0() external view returns (address);

    function token1() external view returns (address);
    
    function fee() external view returns (uint24);

}
设置
{
  "compilationTarget": {
    "contracts/mevarb_bytes_op_v6.sol": "mevbytearbv6"
  },
  "evmVersion": "istanbul",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": []
}
ABI
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"tips","type":"uint256"},{"internalType":"bytes","name":"swapdata","type":"bytes"}],"name":"arbswapn","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32[5]","name":"info","type":"bytes32[5]"}],"name":"arbswapnfive","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32[4]","name":"info","type":"bytes32[4]"}],"name":"arbswapnfour","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32[6]","name":"info","type":"bytes32[6]"}],"name":"arbswapnsix","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountin","type":"uint256"},{"internalType":"address[]","name":"pools","type":"address[]"},{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"flags","type":"uint256[]"}],"name":"simulateoutput","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int256","name":"amount0Delta","type":"int256"},{"internalType":"int256","name":"amount1Delta","type":"int256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"uniswapV3SwapCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawethall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawethamount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenaddr","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawtoken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenaddr","type":"address"}],"name":"withdrawtokenall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]