creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "Simulatetax.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity >=0.8.0;\r\n\r\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\r\n\r\n\r\ninterface IWETH {\r\n    function deposit() external payable;\r\n    function transfer(address to, uint value) external returns (bool);\r\n    function withdraw(uint) external;\r\n}\r\n\r\ninterface IPancakePair {\r\n    event Approval(address indexed owner, address indexed spender, uint value);\r\n    event Transfer(address indexed from, address indexed to, uint value);\r\n\r\n    function name() external pure returns (string memory);\r\n    function symbol() external pure returns (string memory);\r\n    function decimals() external pure returns (uint8);\r\n    function totalSupply() external view returns (uint);\r\n    function balanceOf(address owner) external view returns (uint);\r\n    function allowance(address owner, address spender) external view returns (uint);\r\n\r\n    function approve(address spender, uint value) external returns (bool);\r\n    function transfer(address to, uint value) external returns (bool);\r\n    function transferFrom(address from, address to, uint value) external returns (bool);\r\n\r\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\r\n    function PERMIT_TYPEHASH() external pure returns (bytes32);\r\n    function nonces(address owner) external view returns (uint);\r\n\r\n    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;\r\n\r\n    event Mint(address indexed sender, uint amount0, uint amount1);\r\n    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);\r\n    event Swap(\r\n        address indexed sender,\r\n        uint amount0In,\r\n        uint amount1In,\r\n        uint amount0Out,\r\n        uint amount1Out,\r\n        address indexed to\r\n    );\r\n    event Sync(uint112 reserve0, uint112 reserve1);\r\n\r\n    function MINIMUM_LIQUIDITY() external pure returns (uint);\r\n    function factory() external view returns (address);\r\n    function token0() external view returns (address);\r\n    function token1() external view returns (address);\r\n    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\r\n    function price0CumulativeLast() external view returns (uint);\r\n    function price1CumulativeLast() external view returns (uint);\r\n    function kLast() external view returns (uint);\r\n\r\n    function mint(address to) external returns (uint liquidity);\r\n    function burn(address to) external returns (uint amount0, uint amount1);\r\n    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\r\n    function skim(address to) external;\r\n    function sync() external;\r\n\r\n    function initialize(address, address) external;\r\n}\r\n\r\ncontract AlphaXBotsSimulateTax {\r\n    function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut, uint256 feeDeduct) internal pure returns (uint amountOut) {\r\n        require(amountIn > 0, 'PancakeLibrary: INSUFFICIENT_INPUT_AMOUNT');\r\n        require(reserveIn > 0 && reserveOut > 0, 'PancakeLibrary: INSUFFICIENT_LIQUIDITY');\r\n        uint amountInWithFee = amountIn * (10000 - feeDeduct);\r\n        uint numerator = amountInWithFee * reserveOut;\r\n        uint denominator = reserveIn * 10000 + amountInWithFee;\r\n        amountOut = numerator / denominator;\r\n    }\r\n\r\n    function pairSwap(address currentPair, address currentToken, address _to, uint256 feeDeduct) internal returns (uint256) {\r\n        IPancakePair pair = IPancakePair(currentPair);\r\n        uint amountInput;\r\n        uint amountOutput;\r\n        { // scope to avoid stack too deep errors\r\n            (uint reserve0, uint reserve1,) = pair.getReserves();\r\n            (uint reserveInput, uint reserveOutput) = pair.token0() == currentToken ? (reserve0, reserve1) : (reserve1, reserve0);\r\n            amountInput = IERC20(currentToken).balanceOf(address(pair)) - reserveInput;\r\n            amountOutput = getAmountOut(amountInput, reserveInput, reserveOutput, feeDeduct);\r\n        }\r\n        (uint amount0Out, uint amount1Out) = pair.token0() == currentToken ? (uint(0), amountOutput) : (amountOutput, uint(0));\r\n        pair.swap(amount0Out, amount1Out, _to, new bytes(0));\r\n\r\n        return amount0Out > 0? amount0Out: amount1Out;\r\n    }\r\n\r\n    function testTax(address token, address weth, address[] calldata pairChain, uint256 feeDeduct) external payable returns (\r\n        uint256 totalBuyAmount,\r\n        uint256 boughtAmount,\r\n        uint256 totalSellAmount,\r\n        uint256 soldAmount\r\n    ) {\r\n        IERC20 tokenContract = IERC20(token);\r\n        require(pairChain.length > 0, \"Null pair chain\");\r\n        require(IPancakePair(pairChain[0]).token0() == weth || IPancakePair(pairChain[0]).token1() == weth, \"WETH is not set\");\r\n\r\n        {\r\n            uint amountIn = msg.value;\r\n            IWETH(weth).deposit{value: amountIn}();\r\n            assert(IWETH(weth).transfer(pairChain[0], amountIn));\r\n        }\r\n\r\n        address[] memory tokenChain = new address[](pairChain.length + 1);\r\n        {\r\n            tokenChain[0] = weth;\r\n            uint256 i;\r\n            for (i = 1; i < tokenChain.length; i ++) {\r\n                if (IPancakePair(pairChain[i - 1]).token0() == tokenChain[i - 1]) tokenChain[i] = IPancakePair(pairChain[i - 1]).token1();\r\n                else if (IPancakePair(pairChain[i - 1]).token1() == tokenChain[i - 1]) tokenChain[i] = IPancakePair(pairChain[i - 1]).token0();\r\n                else revert(\"Not valid pair chain\");\r\n            }\r\n\r\n            require(token == tokenChain[tokenChain.length - 1], \"Token not set\");\r\n        }\r\n\r\n        {\r\n            // buy chain processing\r\n            address to = address(this);\r\n            uint256 oldBalance = tokenContract.balanceOf(to);\r\n\r\n            //_swapSupportingFeeOnTransferTokens(path, to)\r\n            for (uint256 i = 0; i < tokenChain.length - 1; i++) {\r\n                uint256 outAmount = pairSwap(pairChain[i], tokenChain[i], i < tokenChain.length - 2 ? pairChain[i + 1]: to, feeDeduct);\r\n\r\n                if (i >= tokenChain.length - 2) {\r\n                    totalBuyAmount = outAmount;\r\n                }\r\n            }\r\n\r\n            boughtAmount = tokenContract.balanceOf(to) - oldBalance;\r\n        }\r\n        {\r\n            // sell chain processing\r\n            // address to = address(this);\r\n            IPancakePair pair;\r\n            bool bFirstToken;\r\n            {\r\n                address tokenPair = pairChain[pairChain.length - 1];\r\n                pair = IPancakePair(tokenPair);\r\n                bFirstToken = pair.token0() == token;\r\n\r\n                // (uint oldReserve0, uint oldReserve1,) = pair.getReserves();\r\n                // (uint oldReserveInput, uint oldReserveOutput) = bFirstToken ? (oldReserve0, oldReserve1) : (oldReserve1, oldReserve0);\r\n\r\n                tokenContract.transfer(tokenPair, boughtAmount);\r\n                \r\n                (uint newReserve0, uint newReserve1,) = pair.getReserves();\r\n                (uint newReserveInput, ) = bFirstToken ? (newReserve0, newReserve1) : (newReserve1, newReserve0);\r\n\r\n                soldAmount = tokenContract.balanceOf(tokenPair) - newReserveInput;\r\n                // if (newReserveInput > oldReserveInput) { // contract sell\r\n                // } else if (newReserveInput < oldReserveInput) { // contract buy\r\n                // }\r\n            }\r\n\r\n            totalSellAmount = boughtAmount;\r\n            // uint256 outAmount = pairSwap(address(pair), token, to);\r\n        }\r\n    }\r\n\r\n    receive() external payable {\r\n    }\r\n}\r\n"
      },
      "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      }
    }
  }}