creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "/contracts/Squirrel.sol": {
        "content": "\n// SPDX-License-Identifier: MIT\n\n\npragma solidity ^0.8.20;\n\n\n/**\n * @title ERC314\n * @dev Implementation of the ERC314 interface.\n * ERC314 is a derivative of ERC20 which aims to integrate a liquidity pool on the token in order to enable native swaps, notably to reduce gas consumption. \n */\n\n// Events interface for ERC314\ninterface IEERC314 {\n    event Transfer(address indexed from, address indexed to, uint256 value);\n    event AddLiquidity(uint32 _blockToUnlockLiquidity, uint256 value);\n    event RemoveLiquidity(uint256 value);\n    event Swap(\n        address indexed sender,\n        uint amount0In,\n        uint amount1In,\n        uint amount0Out,\n        uint amount1Out,\n        uint timestamp\n    );\n}\n\n\nabstract contract ERC314 is IEERC314{\n\n    mapping(address => uint256) private _balances;\n\n    uint256 private _totalSupply;\n    uint256 public _maxWallet;\n    uint32 public blockToUnlockLiquidity;\n\n    string private _name;\n    string private _symbol;\n\n    address public owner;\n    address public liquidityProvider;\n\n    bool public tradingEnable;\n    bool public liquidityAdded;\n    bool public maxWalletEnable;\n\n    uint256 presaleAmount;\n\n    bool public presaleEnable = false;\n\n    mapping(address => uint32) private lastTransaction;\n    \n\n    modifier onlyOwner() {\n        require(msg.sender == owner, \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    modifier onlyLiquidityProvider() {\n        require(msg.sender == liquidityProvider, \"You are not the liquidity provider\");\n        _;\n    }\n\n    /**\n     * @dev Sets the values for {name}, {symbol} and {totalSupply}. \n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name_, string memory symbol_, uint256 totalSupply_) {\n        _name = name_;\n        _symbol = symbol_;\n        _totalSupply = totalSupply_;\n        _maxWallet = totalSupply_ / 200;\n        owner = msg.sender;\n        tradingEnable = false;\n        maxWalletEnable = true;\n        _balances[msg.sender] = totalSupply_/10;\n        presaleAmount = (totalSupply_ - _balances[msg.sender]) / 2;\n        uint256 liquidityAmount = totalSupply_ - presaleAmount - _balances[msg.sender];\n        _balances[address(this)] = liquidityAmount;\n        liquidityAdded = false;\n\n    }\n\n    /**\n     * @dev Sends the presale amount to the investors\n     */\n    function presale(address[] memory _investors) public onlyOwner {\n        require(presaleEnable == false, \"Presale already enabled\");\n        uint256 _amount = presaleAmount / _investors.length;\n        for (uint256 i = 0; i < _investors.length; i++) {\n            _balances[_investors[i]] += _amount;\n        }\n        presaleEnable = true;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual returns (string memory) {\n        return _symbol;\n    }\n\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     */\n\n    function decimals() public view virtual returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - the caller must have a balance of at least `value`.\n     * - if the receiver is the contract, the caller must send the amount of tokens to sell\n     */\n    function transfer(address to, uint256 value) public virtual returns (bool) {\n        // sell or transfer\n        if (to == address(this)) {\n            sell(value);\n        }\n        else{\n            _transfer(msg.sender, to, value);\n        }\n        return true;\n    }\n\n    /**\n     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively burns if `to` is the zero address.\n     * All customizations to transfers and burns should be done by overriding this function.\n     * This function includes MEV protection, which prevents the same address from making two transactions in the same block.(lastTransaction)\n     * Emits a {Transfer} event.\n     */\n    function _transfer(address from, address to, uint256 value) internal virtual {\n        \n        require(lastTransaction[msg.sender] != block.number, \"You can't make two transactions in the same block\");\n\n        lastTransaction[msg.sender] = uint32(block.number);\n\n        require (_balances[from] >= value, \"ERC20: transfer amount exceeds balance\");\n\n        unchecked {\n            _balances[from] = _balances[from] - value;\n        }\n\n        if (to == address(0)) {\n            unchecked {\n                _totalSupply -= value;\n            }\n        } else {\n            unchecked {\n                _balances[to] += value;\n            }\n        }\n\n        emit Transfer(from, to, value);\n    }\n\n    /**\n    * @dev Returns the amount of ETH and tokens in the contract, used for trading.\n    */\n    function getReserves() public view returns (uint256, uint256) {\n        return (address(this).balance, _balances[address(this)]);\n    }\n\n    /**\n    * @dev Enables or disables trading.\n    * @param _tradingEnable: true to enable trading, false to disable trading.\n    * onlyOwner modifier\n    */\n    function enableTrading(bool _tradingEnable) external onlyOwner {\n        tradingEnable = _tradingEnable;\n    }\n\n    /**\n    * @dev Enables or disables the max wallet.\n    * @param _maxWalletEnable: true to enable max wallet, false to disable max wallet.\n    * onlyOwner modifier\n    */\n    function enableMaxWallet(bool _maxWalletEnable) external onlyOwner {\n        maxWalletEnable = _maxWalletEnable;\n    }\n\n    /**\n    * @dev Sets the max wallet.\n    * @param _maxWallet_: the new max wallet.\n    * onlyOwner modifier\n    */\n    function setMaxWallet(uint256 _maxWallet_) external onlyOwner {\n        _maxWallet = _maxWallet_;\n    }\n\n    /**\n    * @dev Transfers the ownership of the contract to zero address\n    * onlyOwner modifier\n    */\n    function renounceOwnership() external onlyOwner {\n        owner = address(0);\n    }\n\n    /**\n    * @dev Adds liquidity to the contract.\n    * @param _blockToUnlockLiquidity: the block number to unlock the liquidity.\n    * value: the amount of ETH to add to the liquidity.\n    * onlyOwner modifier\n    */\n    function addLiquidity(uint32 _blockToUnlockLiquidity) public onlyOwner payable {\n\n        require(liquidityAdded == false, \"Liquidity already added\");\n\n        liquidityAdded = true;\n\n        require(msg.value > 0, \"No ETH sent\");\n        require(block.number < _blockToUnlockLiquidity, \"Block number too low\");\n        \n        blockToUnlockLiquidity = _blockToUnlockLiquidity;\n        tradingEnable = true;\n        liquidityProvider = msg.sender;\n        \n        emit AddLiquidity(_blockToUnlockLiquidity, msg.value);\n    }\n\n    /**\n    * @dev Removes liquidity from the contract.\n    * onlyLiquidityProvider modifier\n    */\n    function removeLiquidity() public onlyLiquidityProvider {\n\n        require(block.number > blockToUnlockLiquidity, \"Liquidity locked\");\n\n        tradingEnable = false;\n\n        payable(msg.sender).transfer(address(this).balance);\n\n        emit RemoveLiquidity(address(this).balance);\n\n    }\n\n    /**\n    * @dev Extends the liquidity lock, only if the new block number is higher than the current one.\n    * @param _blockToUnlockLiquidity: the new block number to unlock the liquidity.\n    * onlyLiquidityProvider modifier\n    */\n    function extendLiquidityLock(uint32 _blockToUnlockLiquidity) public onlyLiquidityProvider {\n\n        require(blockToUnlockLiquidity < _blockToUnlockLiquidity, \"You can't shorten duration\");\n\n        blockToUnlockLiquidity = _blockToUnlockLiquidity;\n    }\n\n    /**\n    * @dev Estimates the amount of tokens or ETH to receive when buying or selling.\n    * @param value: the amount of ETH or tokens to swap.\n    * @param _buy: true if buying, false if selling.\n    */\n    function getAmountOut(uint256 value, bool _buy) public view returns(uint256) {\n\n        (uint256 reserveETH, uint256 reserveToken) = getReserves();\n\n        if (_buy) {\n            return (value * reserveToken) / (reserveETH + value);\n        } else {\n            return (value * reserveETH) / (reserveToken + value);\n        }\n    }\n\n    /**\n    * @dev Buys tokens with ETH.\n    * internal function\n    */\n    function buy() internal {\n        \n        require(tradingEnable, \"Trading not enable\");\n\n        uint256 token_amount = (msg.value * _balances[address(this)]) / (address(this).balance);\n\n        if (maxWalletEnable) {\n            require(token_amount + _balances[msg.sender] <= _maxWallet, \"Max wallet exceeded\");\n        }\n\n        _transfer(address(this), msg.sender, token_amount);\n\n        emit Swap(msg.sender, msg.value,0,0,token_amount, block.timestamp);\n    }\n\n    /**\n    * @dev Sells tokens for ETH.\n    * internal function\n    */\n    function sell(uint256 sell_amount) internal {\n\n        require(tradingEnable, \"Trading not enable\");\n\n        uint256 ethAmount = (sell_amount * address(this).balance) / (_balances[address(this)] + sell_amount);\n\n        require(ethAmount > 0, \"Sell amount too low\");\n        require(address(this).balance >= ethAmount, \"Insufficient ETH in reserves\");\n\n        _transfer(msg.sender, address(this), sell_amount);\n        payable(msg.sender).transfer(ethAmount);\n\n        emit Swap(msg.sender, 0,sell_amount,ethAmount,0, block.timestamp);\n    }\n\n    /**\n    * @dev Fallback function to buy tokens with ETH.\n    */\n    receive() external payable {\n        buy();\n    }\n}\n\n\ncontract Squirrel is ERC314 {\n    uint256 private _totalSupply = 100_000_000 * 10 ** 18;\n\n    constructor() ERC314(\"Squirrel\", \"SIEL\", _totalSupply) {\n    }\n}"
      }
    },
    "settings": {
      "remappings": [],
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "evmVersion": "shanghai",
      "libraries": {},
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      }
    }
  }}