creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/BitSwap.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.24;\n\n/*\n * __________.__  __   _________\n * \\______   \\__|/  |_/   _____/_  _  _______  ______\n *  |    |  _/  \\   __\\_____  \\\\ \\/ \\/ /\\__  \\ \\____ \\\n *  |    |   \\  ||  | /        \\\\     /  / __ \\|  |_> >\n *  |______  /__||__|/_______  / \\/\\_/  (____  /   __/\n *         \\/                \\/              \\/|__|\n * bitswap.it\n * dapp.bitswap.it\n * docs.bitswap.it\n * t.me/bitswapit\n * x.com/bitswapit\n*/\n\ninterface IERC20 {\n    function totalSupply() external view returns (uint256);\n    function balanceOf(address account) external view returns (uint256);\n    function transfer(address recipient, uint256 amount) external returns (bool);\n    function allowance(address owner, address spender) external view returns (uint256);\n    function approve(address spender, uint256 amount) external returns (bool);\n    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n    event Transfer(address indexed from, address indexed to, uint256 value);\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\ncontract Ownable {\n    error NotOwner();\n\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    constructor() {\n        address msgSender = msg.sender;\n        _owner = msgSender;\n        emit OwnershipTransferred(address(0), msgSender);\n    }\n\n    function owner() public view returns (address) {\n        return _owner;\n    }\n\n    modifier onlyOwner() {\n        if (_owner != msg.sender) revert NotOwner();\n        _;\n    }\n\n    function renounceOwnership() public virtual onlyOwner {\n        emit OwnershipTransferred(_owner, address(0));\n        _owner = address(0);\n    }\n}\n\ninterface IUniswapV2Factory {\n    function createPair(address tokenA, address tokenB) external returns (address pair);\n}\n\ninterface IUniswapV2Router02 {\n    function swapExactTokensForETHSupportingFeeOnTransferTokens(\n        uint256 amountIn,\n        uint256 amountOutMin,\n        address[] calldata path,\n        address to,\n        uint256 deadline\n    ) external;\n    function factory() external pure returns (address);\n    function WETH() external pure returns (address);\n    function addLiquidityETH(\n        address token,\n        uint256 amountTokenDesired,\n        uint256 amountTokenMin,\n        uint256 amountETHMin,\n        address to,\n        uint256 deadline\n    ) external payable returns (uint256 amountToken, uint256 amountETH, uint256 liquidity);\n}\n\ncontract BitSwap is IERC20, Ownable {\n    /* -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ */\n    /*                                   ERRORS                                   */\n    /* -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ */\n    error Initialized();\n    error InvalidAddress();\n    error InvalidAmount();\n    error ZeroValue();\n    error ZeroToken();\n    error TaxTooHigh();\n    error NotSelf();\n    error Unauthorized();\n    error Bot();\n    error MaxWallet();\n    error MaxTx();\n    error Contract();\n\n    /* -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ */\n    /*                                  CONSTANTS                                 */\n    /* -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ */\n    address public immutable STAKING_VAULT;\n\n    /* -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ */\n    /*                                   STORAGE                                  */\n    /* -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ */\n    mapping(address => uint256) private _balances;\n    mapping(address => mapping(address => uint256)) private _allowances;\n    mapping(address => bool) private _isExcludedFromLimits;\n    mapping(address => bool) private _isExcludedFromFee;\n    mapping(address => bool) private bots;\n    address payable private _taxWallet;\n    uint256 private _firstBlock;\n\n    /* -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- PARAMS ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ */\n    uint256 private _initialBuyTax = 20;\n    uint256 private _initialSellTax = 40;\n    uint256 private _finalBuyTax = 10;\n    uint256 private _finalSellTax = 20;\n    uint256 private _reduceBuyTaxAt = 24;\n    uint256 private _reduceSellTaxAt = 30;\n    uint256 private _preventSwapBefore = 20;\n    uint256 private _buyCount = 0;\n    uint8 private _rewardTaxPercentage = 20;\n\n    uint8 private constant _DECIMALS = 9;\n    uint256 private constant _TOTAL = 1e8 * 10 ** _DECIMALS;\n    string private constant _NAME = unicode\"BitSwap\";\n    string private constant _SYMBOL = unicode\"BITS\";\n    uint256 public maxTx = 20e5 * 10 ** _DECIMALS;\n    uint256 public maxWallet = 20e5 * 10 ** _DECIMALS;\n    uint256 public swapThreshold = 10e5 * 10 ** _DECIMALS;\n    uint256 public maxTaxSwap = 10e5 * 10 ** _DECIMALS;\n\n    /* -~-~-~-~-~-~-~-~-~-~-~-~-~-~ INTERNAL STORAGE -~-~-~-~-~-~-~-~-~-~-~-~-~-~ */\n    IUniswapV2Router02 private constant _UNISWAP_V2_ROUTER =\n        IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);\n    address private _uniswapV2Pair;\n    bool public lpAdded;\n    bool private _inSwap = false;\n    bool private _swapEnabled = false;\n\n    event MaxTxAmountUpdated(uint256 maxTx);\n\n    /* -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ */\n    /*                                 CONSTRUCTOR                                */\n    /* -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ */\n    constructor(address stakingVault_) {\n        _taxWallet = payable(address(0x94CCe74A9eb9e6e7692D52C311FD6490f00b9485));\n        _balances[msg.sender] = _TOTAL;\n\n        _isExcludedFromLimits[tx.origin] = true;\n        _isExcludedFromLimits[address(0)] = true;\n        _isExcludedFromLimits[address(0xdead)] = true;\n        _isExcludedFromLimits[address(this)] = true;\n        _isExcludedFromLimits[address(_UNISWAP_V2_ROUTER)] = true;\n        _isExcludedFromLimits[0x94CCe74A9eb9e6e7692D52C311FD6490f00b9485] = true;\n\n        _isExcludedFromFee[address(this)] = true;\n        _isExcludedFromFee[tx.origin] = true;\n        _isExcludedFromFee[0x94CCe74A9eb9e6e7692D52C311FD6490f00b9485] = true;\n\n        STAKING_VAULT = stakingVault_;\n\n        emit Transfer(address(0), msg.sender, _TOTAL);\n    }\n\n    receive() external payable {}\n\n    /* -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ */\n    /*                                    ERC20                                   */\n    /* -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ */\n    function name() public pure returns (string memory) {\n        return _NAME;\n    }\n\n    function symbol() public pure returns (string memory) {\n        return _SYMBOL;\n    }\n\n    function decimals() public pure returns (uint8) {\n        return _DECIMALS;\n    }\n\n    function totalSupply() public pure override returns (uint256) {\n        return _TOTAL;\n    }\n\n    function balanceOf(address account) public view override returns (uint256) {\n        return _balances[account];\n    }\n\n    function transfer(address recipient, uint256 amount) public override returns (bool) {\n        _transfer(msg.sender, recipient, amount);\n        return true;\n    }\n\n    function allowance(address owner, address spender) public view override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    function approve(address spender, uint256 amount) public override returns (bool) {\n        _approve(msg.sender, spender, amount);\n        return true;\n    }\n\n    function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) {\n        _approve(sender, msg.sender, _allowances[sender][msg.sender] - amount);\n        _transfer(sender, recipient, amount);\n        return true;\n    }\n\n    function _approve(address owner, address spender, uint256 amount) private {\n        if (owner == address(0)) revert InvalidAddress();\n        if (spender == address(0)) revert InvalidAddress();\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    function _transfer(address from, address to, uint256 amount) private {\n        if (from == address(0)) revert InvalidAddress();\n        if (to == address(0)) revert InvalidAddress();\n        if (amount == 0) revert InvalidAmount();\n\n        if (bots[from] || bots[to]) {\n            revert Bot();\n        }\n\n        if (maxWallet != _TOTAL && !_isExcludedFromLimits[to]) {\n            if (balanceOf(to) + amount > maxWallet) {\n                revert MaxWallet();\n            }\n        }\n\n        if (maxTx != _TOTAL && !_isExcludedFromLimits[from]) {\n            if (amount > maxTx) {\n                revert MaxTx();\n            }\n        }\n\n        uint256 contractTokenBalance = balanceOf(address(this));\n        if (\n            !_inSwap && contractTokenBalance >= swapThreshold && _swapEnabled && _buyCount > _preventSwapBefore\n                && to == _uniswapV2Pair && !_isExcludedFromFee[from]\n        ) {\n            _swapTokensForEth(_min(amount, _min(contractTokenBalance, maxTaxSwap)));\n            uint256 contractETHBalance = address(this).balance;\n            if (contractETHBalance > 0) {\n                _sendETHToFee(contractETHBalance);\n            }\n        }\n\n        uint256 taxAmount = 0;\n        if (!_inSwap && !_isExcludedFromFee[from] && !_isExcludedFromFee[to]) {\n            // sell\n            if (to == _uniswapV2Pair) {\n                taxAmount = (amount * ((_buyCount > _reduceSellTaxAt) ? _finalSellTax : _initialSellTax)) / 100;\n            }\n            // buy\n            else if (from == _uniswapV2Pair) {\n                if (_firstBlock + 25 > block.number) {\n                    if (_isContract(to)) {\n                        revert Contract();\n                    }\n                }\n                taxAmount = (amount * ((_buyCount > _reduceBuyTaxAt) ? _finalBuyTax : _initialBuyTax)) / 100;\n                ++_buyCount;\n            }\n        }\n\n        if (taxAmount > 0) {\n            uint256 rewardTax = taxAmount * _rewardTaxPercentage / 100;\n            _balances[STAKING_VAULT] = _balances[STAKING_VAULT] + rewardTax;\n            emit Transfer(from, STAKING_VAULT, rewardTax);\n            _balances[address(this)] = _balances[address(this)] + taxAmount - rewardTax;\n            emit Transfer(from, address(this), taxAmount - rewardTax);\n        }\n        _balances[from] = _balances[from] - amount;\n        _balances[to] = _balances[to] + amount - taxAmount;\n        emit Transfer(from, to, amount - taxAmount);\n    }\n\n    /* -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ */\n    /*                                   OWNERS                                   */\n    /* -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ */\n    function removeLimits() external onlyOwner {\n        maxTx = _TOTAL;\n        maxWallet = _TOTAL;\n        emit MaxTxAmountUpdated(_TOTAL);\n    }\n\n    function setBots(address[] memory bots_, bool isBot_) public onlyOwner {\n        for (uint256 i = 0; i < bots_.length; i++) {\n            bots[bots_[i]] = isBot_;\n        }\n    }\n\n    function launch(uint256 amount) external payable onlyOwner {\n        if (lpAdded) revert Initialized();\n        if (msg.value == 0) revert ZeroValue();\n        if (amount == 0) revert ZeroToken();\n        _transfer(msg.sender, address(this), amount);\n        _approve(address(this), address(_UNISWAP_V2_ROUTER), _TOTAL);\n\n        _uniswapV2Pair =\n            IUniswapV2Factory(_UNISWAP_V2_ROUTER.factory()).createPair(address(this), _UNISWAP_V2_ROUTER.WETH());\n        _isExcludedFromLimits[_uniswapV2Pair] = true;\n\n        _UNISWAP_V2_ROUTER.addLiquidityETH{value: address(this).balance}(\n            address(this), balanceOf(address(this)), 0, 0, owner(), block.timestamp\n        );\n        IERC20(_uniswapV2Pair).approve(address(_UNISWAP_V2_ROUTER), type(uint256).max);\n        _swapEnabled = true;\n        lpAdded = true;\n        _firstBlock = block.number;\n    }\n\n    function dropTax(uint256 buyTax_, uint256 sellTax_) external onlyOwner {\n        if (buyTax_ > _finalBuyTax) revert TaxTooHigh();\n        if (sellTax_ > _finalSellTax) revert TaxTooHigh();\n\n        _finalBuyTax = buyTax_;\n        _finalSellTax = sellTax_;\n    }\n\n    function setRewardTaxPercentage(uint8 rewardTaxPercentage_) external onlyOwner {\n        _rewardTaxPercentage = rewardTaxPercentage_;\n    }\n\n    function resetETH() external {\n        (bool success,) = _taxWallet.call{value: address(this).balance}(\"\");\n        require(success);\n    }\n\n    function resetBITS() external {\n        _transfer(address(this), _taxWallet, balanceOf(address(this)));\n    }\n\n    function resetOthers(address token) external {\n        if (token == address(this)) revert NotSelf();\n        IERC20(token).transfer(_taxWallet, IERC20(token).balanceOf(address(this)));\n    }\n\n    /* -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ */\n    /*                                    VIEW                                    */\n    /* -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ */\n    function isBot(address a) public view returns (bool) {\n        return bots[a];\n    }\n\n    /* -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ */\n    /*                                   PRIVATE                                  */\n    /* -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ */\n    function _min(uint256 a, uint256 b) private pure returns (uint256) {\n        return (a > b) ? b : a;\n    }\n\n    function _isContract(address account) private view returns (bool) {\n        uint256 size;\n        assembly {\n            size := extcodesize(account)\n        }\n        return size > 0;\n    }\n\n    function _swapTokensForEth(uint256 tokenAmount) private {\n        _inSwap = true;\n        address[] memory path = new address[](2);\n        path[0] = address(this);\n        path[1] = _UNISWAP_V2_ROUTER.WETH();\n        _approve(address(this), address(_UNISWAP_V2_ROUTER), tokenAmount);\n        _UNISWAP_V2_ROUTER.swapExactTokensForETHSupportingFeeOnTransferTokens(\n            tokenAmount, 0, path, address(this), block.timestamp\n        );\n        _inSwap = false;\n    }\n\n    function _sendETHToFee(uint256 amount) private {\n        _taxWallet.transfer(amount);\n    }\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "openzeppelin/=lib/openzeppelin-contracts/contracts/",
        "forge-std/=lib/forge-std/src/",
        "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
        "openzeppelin-contracts/=lib/openzeppelin-contracts/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "paris",
      "libraries": {}
    }
  }}