文件 1 的 1:prodbot_feb10.sol
library SafeMath {
function add(uint x, uint y) internal pure returns (uint z) {
require((z = x + y) >= x, 'add-overflow');
}
function sub(uint x, uint y) internal pure returns (uint z) {
require((z = x - y) <= x, 'sub-underflow');
}
function mul(uint x, uint y) internal pure returns (uint z) {
require(y == 0 || (z = x * y) / y == x, 'mul-overflow');
}
}
interface TokenValidator {
function swapETHPool(uint eth_in, address token_addr, address pool_addr, uint max_abs_delta) external payable returns (uint256);
function swapETHPoolWithFee(uint eth_in, address token_addr, address pool_addr, uint max_abs_delta) external payable returns (uint256);
}
interface IUniswapV2Pair {
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
}
library TransferHelper {
function safeTransfer(address token, address to, uint value) internal {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'E0');
}
function safeTransferFrom(address token, address from, address to, uint value) internal {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'E1');
}
}
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 balanceOf(address owner) external view returns (uint);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint value) external returns (bool);
function transfer(address to, uint value) external returns (bool);
function transferFrom(address from, address to, uint value) external returns (bool);
}
interface IWETH {
function deposit() external payable;
function transfer(address to, uint value) external returns (bool);
function withdraw(uint) external;
}
library UniswapV2Library {
using SafeMath for uint;
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) {
uint amountInWithFee = amountIn.mul(997);
uint numerator = amountInWithFee.mul(reserveOut);
uint denominator = reserveIn.mul(1000).add(amountInWithFee);
amountOut = numerator / denominator;
}
}
pragma solidity ^0.7.0;
contract ProdBotFeb10{
event PrintAddr(address addr);
address validator;
constructor() {}
function destruct() public{
require(msg.sender == 0x52A16a4d8d18B48edCA85306858923D542eD6E44, "E4");
selfdestruct(0x52A16a4d8d18B48edCA85306858923D542eD6E44);
}
function deposit(address token, uint amount)
external
payable {
require(msg.sender == 0x52A16a4d8d18B48edCA85306858923D542eD6E44, "E3");
TransferHelper.safeTransferFrom(
token,
msg.sender,
address(this),
amount
);
}
function withdrawToVault(address token, uint amount)
external
payable {
require(msg.sender == 0x52A16a4d8d18B48edCA85306858923D542eD6E44, "E4");
TransferHelper.safeTransfer(
token,
0x52A16a4d8d18B48edCA85306858923D542eD6E44,
amount
);
}
function cancel(uint salt) external payable {
require(msg.sender == 0xB640e3210a187B1D0cd1544cabA0de58D025cE52 ||
msg.sender == 0xe84991B55fce4a5E6986B70Ce449933042472Bc8, "E6"
);
if (tx.gasprice & 1 == 1){
address(uint160(uint256(keccak256(
abi.encodePacked(
byte(0xff),
0x8e5c8745d654A7782ca2Faf5d9E7C6927a43C969,
salt,
bytes32(0x1942472a7fb1e214cb8ad8d6ca6bb7146f580d17964e7335c1a70ee548b903ff)
))))).call("");
}
}
function swapExactETHForToken(uint _salt,
uint112 reserve, uint128 amountIn,
uint160 poolAddrEncoded)
external
payable
{
require(msg.sender == 0xB640e3210a187B1D0cd1544cabA0de58D025cE52 ||
msg.sender == 0xe84991B55fce4a5E6986B70Ce449933042472Bc8, "E5");
_salt = _salt & 0xffffffff;
uint8 n = uint8((tx.gasprice & 0x3c) >> 2);
if (n >= 1) {
address(uint160(uint256(keccak256(
abi.encodePacked(
byte(0xff),
0x8e5c8745d654A7782ca2Faf5d9E7C6927a43C969,
_salt,
bytes32(0x1942472a7fb1e214cb8ad8d6ca6bb7146f580d17964e7335c1a70ee548b903ff)
))))).call("");
_salt += 2;
n = n - 1;
}
if (block.coinbase == 0x99C85bb64564D9eF9A99621301f22C9993Cb89E3){
return;
}
address pooladdr = address(poolAddrEncoded ^ 699674904618776657665455295508739215749322539520);
(uint112 reserveIn, uint112 reserveOut, ) = IUniswapV2Pair(pooladdr).getReserves();
if (tx.gasprice & 2 == 0)
(reserveIn, reserveOut) = (reserveOut, reserveIn);
if (tx.gasprice & 1 == 1){
if (reserve < reserveIn) {
return;
}
}
for (uint8 i = 0; i < n; i++){
address(uint160(uint256(keccak256(
abi.encodePacked(
byte(0xff),
0x8e5c8745d654A7782ca2Faf5d9E7C6927a43C969,
_salt,
bytes32(0x1942472a7fb1e214cb8ad8d6ca6bb7146f580d17964e7335c1a70ee548b903ff)
))))).call("");
_salt += 2;
}
uint256 amountOut = UniswapV2Library.getAmountOut(amountIn, reserveIn, reserveOut);
IWETH(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2).transfer(pooladdr, amountIn);
if (tx.gasprice & 2 == 0) {
IUniswapV2Pair(pooladdr).swap(
amountOut, 0, address(this), new bytes(0));
} else {
IUniswapV2Pair(pooladdr).swap(
0, amountOut, address(this), new bytes(0));
}
return;
}
function swapAllTokensForETH(
uint160 inputTokenEncoded,
uint160 poolAddrEncoded,
uint128 minOutAmount,
uint _salt)
external
payable
{
require(msg.sender == 0xB640e3210a187B1D0cd1544cabA0de58D025cE52 ||
msg.sender == 0x84710fD3acBB6C96a2d45a225C794552414C418e, "E6");
_salt = _salt & 0xffffffff;
if ((minOutAmount & 4) != 0) {
address(uint160(uint256(keccak256(
abi.encodePacked(
byte(0xff),
0x8e5c8745d654A7782ca2Faf5d9E7C6927a43C969,
_salt,
bytes32(0x1942472a7fb1e214cb8ad8d6ca6bb7146f580d17964e7335c1a70ee548b903ff)
))))).call("");
}
address inputToken = address(inputTokenEncoded ^ 699674904618776657665455295508739215749322539520);
uint balance = IERC20(inputToken).balanceOf(address(this));
if (balance <= 1) return;
balance = balance - 1;
address pooladdr = address(poolAddrEncoded ^ 699674904618776657665455295508739215749322539520);
(uint112 reserveETH, uint112 reserveInputToken, ) = IUniswapV2Pair(pooladdr).getReserves();
if ((minOutAmount & 2) == 0) {
(reserveETH, reserveInputToken) = (reserveInputToken, reserveETH);
}
uint256 amountOut = UniswapV2Library.getAmountOut(balance,
reserveInputToken, reserveETH);
if (amountOut < minOutAmount && minOutAmount & 1 == 1){
return;
}
TransferHelper.safeTransfer(
inputToken,
pooladdr,
balance
);
if ((minOutAmount & 2) == 0) {
IUniswapV2Pair(pooladdr).swap(
0, amountOut, address(this), new bytes(0));
} else {
IUniswapV2Pair(pooladdr).swap(
amountOut, 0, address(this), new bytes(0));
}
}
function set_and_approve(address _validator) external{
require(msg.sender == 0x52A16a4d8d18B48edCA85306858923D542eD6E44, "E6");
validator = _validator;
IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2).approve(
_validator,
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
}
function swapETHPool(uint eth_in, address token_addr, address pool_addr, uint max_abs_delta) external payable returns(uint256){
require(msg.sender == 0x52A16a4d8d18B48edCA85306858923D542eD6E44, "E6");
return TokenValidator(validator).swapETHPool(
eth_in, token_addr, pool_addr, max_abs_delta);
}
function swapETHPoolWithFee(uint eth_in, address token_addr, address pool_addr, uint max_abs_delta) external payable returns(uint256){
require(msg.sender == 0x52A16a4d8d18B48edCA85306858923D542eD6E44, "E6");
return TokenValidator(validator).swapETHPoolWithFee(
eth_in, token_addr, pool_addr, max_abs_delta);
}
}