账户
0x59...d6f6
0x59...d6F6

0x59...d6F6

$500
此合同的源代码已经过验证!
合同元数据
编译器
0.8.1+commit.df193b15
语言
Solidity
合同源代码
文件 1 的 1:sav2.sol
pragma solidity ^0.8.0;
// SPDX-License-Identifier: UNLICENSED

interface IWETH {
    /*
    function deposit() external payable;
    function transfer(address to, uint value) external returns (bool);
    */
    function withdraw(uint) external;
}

interface IPAIR {
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
}

interface IERC20 {
    /*
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view returns (uint8);
    function totalSupply() external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);
    */
    function balanceOf(address owner) external view returns (uint);
    //function approve(address spender, uint value) external returns (bool);
}

// https://gastoken.io/
interface Gastoken {
    function free(uint256 value) external returns (bool success);
    // function freeUpTo(uint256 value) public returns (uint256 freed);
    // function freeFrom(address from, uint256 value) public returns (bool success);
    // function freeFromUpTo(address from, uint256 value) public returns (uint256 freed);
}

contract Sandwich {
    // 用来看版本号
    string public constant name = "0x33-v2.0";

    // 固定owner,不然就要从storage中读取,浪费gas
    address private constant OWNER = 0x3376EBC8DCE3453a045A145Ab7b1e728b2ED581e;

    // WETH
    address private constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;

    // GST2
    address private constant GST2 = 0x0000000000b3F879cb30FE243b4Dfee438691c04;

    //
    bytes4 private constant SELECTOR = bytes4(keccak256(bytes('transfer(address,uint256)')));

    address private constant EMPT = 0x0000000000000000000000000000000000000000;

    // 构造函数,空的
    constructor() {
    }    

    // receive ETH,空的
    receive() external payable {}

    // OWNER
    modifier onlyOwner() {
        require(msg.sender == OWNER, "SaV2: sender not owner");
        _;
    }

    //万一有token,提现
    // 这些都是偶尔调用,因此应该不会在正常使用的时候浪费gas的
    // token是ERC20 token address
    function withdrawToken(address token) external onlyOwner returns (uint balance) {
        balance = IERC20(token).balanceOf(address(this));
        if(balance > 0) {
            _safeTransfer(token, msg.sender, balance);
        }
    }

    function withdrawTokenWithAmount(address token, uint amount) external onlyOwner returns (uint balance) {
        balance = IERC20(token).balanceOf(address(this));
        require(balance >= amount);
        _safeTransfer(token, msg.sender, amount);
    }

    function withdrawETH() external onlyOwner returns (uint balance) {
        balance = address(this).balance;
        if(balance > 0) {
            _safeTransferETH(msg.sender, balance);
        }
    }

    function _safeTransferETH(address to, uint256 value) private {
        (bool success, ) = to.call{value: value}(new bytes(0));
        require(success, 'SaV2: ETH transfer failed');
    }

    function _safeTransfer(address token, address to, uint value) private {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'SaV2: TRANSFER_FAILED');
    }

    // 下面是正式的函数

    // buy: 用ETH buy token
    function buy(
        uint gst2_to_use, 
        address pair_addr, 
        uint token_pos, 
        uint eth_amount_in, 
        uint token_amount_out,
        bytes32 parent_hash
    ) external onlyOwner {
        bytes32 real_parent_hash = blockhash(block.number - 1);
        require(parent_hash == real_parent_hash, 'SaV2: invalid parent_hash');

        if(gst2_to_use > 0) {
            require(Gastoken(GST2).free(gst2_to_use));
        }

        _safeTransfer(WETH, pair_addr, eth_amount_in);

        bytes memory data = new bytes(0);

        if(token_pos == 0) {
            IPAIR(pair_addr).swap(token_amount_out, 0, address(this), data);
        } else {
            IPAIR(pair_addr).swap(0, token_amount_out, address(this), data);
        }

        // done
    }

    // sell: 
    function sell(
        uint gst2_to_use, 
        address pair_addr, 
        address token_addr, 
        uint token_pos, 
        uint token_amount_in, 
        uint eth_amout_out, 
        uint amount_to_coinbase,
        address coinbase_addr,
        bytes32 parent_hash
        ) external onlyOwner {

        bytes32 real_parent_hash = blockhash(block.number - 1);
        require(parent_hash == real_parent_hash, 'SaV2: invalid parent_hash' );

        if(gst2_to_use > 0) {
            require(Gastoken(GST2).free(gst2_to_use));
        }

        _safeTransfer(token_addr, pair_addr, token_amount_in);

        bytes memory data = new bytes(0);

        if(token_pos == 0) {
            IPAIR(pair_addr).swap(0, eth_amout_out, address(this), data);
        } else {
            IPAIR(pair_addr).swap(eth_amout_out, 0, address(this), data);
        }

        if(amount_to_coinbase > 0) {
            IWETH(WETH).withdraw(amount_to_coinbase);

            if(coinbase_addr == EMPT) {
                block.coinbase.transfer(amount_to_coinbase);
            } else {
                _safeTransferETH(coinbase_addr, amount_to_coinbase);
            }
        }
    }
}
设置
{
  "compilationTarget": {
    "sav2.sol": "Sandwich"
  },
  "evmVersion": "istanbul",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "remappings": []
}
ABI
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"gst2_to_use","type":"uint256"},{"internalType":"address","name":"pair_addr","type":"address"},{"internalType":"uint256","name":"token_pos","type":"uint256"},{"internalType":"uint256","name":"eth_amount_in","type":"uint256"},{"internalType":"uint256","name":"token_amount_out","type":"uint256"},{"internalType":"bytes32","name":"parent_hash","type":"bytes32"}],"name":"buy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"gst2_to_use","type":"uint256"},{"internalType":"address","name":"pair_addr","type":"address"},{"internalType":"address","name":"token_addr","type":"address"},{"internalType":"uint256","name":"token_pos","type":"uint256"},{"internalType":"uint256","name":"token_amount_in","type":"uint256"},{"internalType":"uint256","name":"eth_amout_out","type":"uint256"},{"internalType":"uint256","name":"amount_to_coinbase","type":"uint256"},{"internalType":"address","name":"coinbase_addr","type":"address"},{"internalType":"bytes32","name":"parent_hash","type":"bytes32"}],"name":"sell","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawETH","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"withdrawToken","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawTokenWithAmount","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]