creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/ERC314a.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\n// Website: https://relief.fi\n// Twitter: https://twitter.com/relief_erc314a\n// Telegram: https://t.me/relief_erc314a\n\n/**\n * @title ERC314a\n * @dev Implementation of the ERC314a 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 * ERC413a is an improved version of ERC314, with the of a MEV Protection and other features.\n */\n\ninterface IERC314a {\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    );\n}\n\ncontract ERC314a is IERC314a {\n    mapping(address account => 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    address public taxWallet;\n    address public factoryWallet;\n\n    uint public buyTax;\n    uint public sellTax;\n\n    uint256 presaleAmount;\n\n    bool public presaleEnable = false;\n\n    mapping(address account => uint32) private lastTransaction;\n\n    modifier onlyOwner() {\n        require(msg.sender == owner, \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    modifier onlyLiquidityProvider() {\n        require(\n            msg.sender == liquidityProvider,\n            \"You are not the liquidity provider\"\n        );\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(\n        string memory name_,\n        string memory symbol_,\n        uint256 totalSupply_,\n        uint256 tokensToLiq_,\n        uint256 tokensToPresale_,\n        uint256 maxWallet_,\n        uint256 buyTax_,\n        uint256 sellTax_,\n        address taxWallet_,\n        address factoryWallet_\n    ) {\n        _name = name_;\n        _symbol = symbol_;\n        _totalSupply = totalSupply_;\n        _maxWallet = maxWallet_;\n        owner = tx.origin;\n        tradingEnable = false;\n        maxWalletEnable = true;\n        presaleAmount = tokensToPresale_;\n        _balances[address(this)] = tokensToLiq_;\n        _balances[tx.origin] = totalSupply_ - tokensToLiq_ - tokensToPresale_;\n        liquidityAdded = false;\n        taxWallet = taxWallet_;\n        factoryWallet = factoryWallet_;\n        buyTax = buyTax_;\n        sellTax = sellTax_;\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     * @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, 0);\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(\n        address from,\n        address to,\n        uint256 value\n    ) internal virtual {\n        require(\n            lastTransaction[msg.sender] != block.number,\n            \"You can't make two transactions in the same block\"\n        );\n\n        lastTransaction[msg.sender] = uint32(block.number);\n\n        require(\n            _balances[from] >= value,\n            \"ERC20: transfer amount exceeds balance\"\n        );\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    function setTax(uint buyTax_, uint sellTax_) public onlyOwner{\n        buyTax = buyTax_;\n        sellTax = sellTax_;\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(\n        uint32 _blockToUnlockLiquidity\n    ) public payable onlyOwner {\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        liquidityProvider = msg.sender;\n\n        emit AddLiquidity(_blockToUnlockLiquidity, msg.value);\n    }\n\n    function extendLock(uint32 _newBlockToUnlock) public onlyOwner{\n        require(_newBlockToUnlock > blockToUnlockLiquidity, \"Dev would never do that, nice try kid\");\n        blockToUnlockLiquidity = _newBlockToUnlock;\n    }\n\n    /**\n     * @dev Removes liquidity from the contract.\n     * onlyLiquidityProvider modifier\n     */\n    function removeLiquidity() public onlyLiquidityProvider {\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     * @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(\n        uint32 _blockToUnlockLiquidity\n    ) public onlyLiquidityProvider {\n        require(\n            blockToUnlockLiquidity < _blockToUnlockLiquidity,\n            \"You can't shorten duration\"\n        );\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(\n        uint256 value,\n        bool _buy\n    ) public view returns (uint256) {\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(uint256 _minAmount) public payable {\n        require(tradingEnable, \"Trading not enable\");\n\n        uint256 token_amount = getAmountOut(msg.value, true);\n\n        if (maxWalletEnable) {\n            require(\n                token_amount + _balances[msg.sender] <= _maxWallet,\n                \"Max wallet exceeded\"\n            );\n        }\n        uint factoryFee = token_amount * 4 / 1000;\n        _transfer(address(this), factoryWallet, factoryFee);\n        \n        if (buyTax > 0){\n            uint fee = token_amount * buyTax / 100;\n            _transfer(address(this), taxWallet, fee);\n            token_amount = token_amount - fee - factoryFee;\n        } else {\n            token_amount = token_amount - factoryFee;\n        }\n\n        _transfer(address(this), msg.sender, token_amount);\n\n        require(token_amount >= _minAmount, \"Slippage too high\");\n\n        emit Swap(msg.sender, msg.value, 0, 0, token_amount);\n    }\n\n    /**\n     * @dev Sells tokens for ETH.\n     * internal function\n     */\n    function sell(uint256 _sellAmount, uint256 _minReceived) public payable {\n        require(tradingEnable, \"Trading not enable\");\n\n        uint256 ethAmount = getAmountOut(_sellAmount, false);\n\n        require(ethAmount > 0, \"Sell amount too low\");\n        require(\n            address(this).balance >= ethAmount,\n            \"Insufficient ETH in reserves\"\n        );\n        uint factoryFee = ethAmount * 4 / 1000;\n        payable(factoryWallet).transfer(factoryFee);\n\n        if (sellTax > 0){\n            uint fee = ethAmount * sellTax / 100;\n            payable(taxWallet).transfer(fee);\n            ethAmount = ethAmount - fee - factoryFee;\n        } else {\n            ethAmount = ethAmount - factoryFee;\n        }\n\n        _transfer(msg.sender, address(this), _sellAmount);\n        require(ethAmount >= _minReceived, \"Slippage too high\");\n        payable(msg.sender).transfer(ethAmount);\n\n        emit Swap(msg.sender, 0, _sellAmount, ethAmount, 0);\n    }\n\n    receive() external payable {\n        buy(0);\n    }\n}\n"
      },
      "contracts/Factory.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\nimport './ERC314a.sol';\n\ncontract Factory {\n\n    address public factoryWallet;\n    address public owner;\n    uint public deployFees;\n\n    modifier onlyOwner() {\n        require(msg.sender == owner, \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    constructor(address factoryWallet_, uint deployFees_) {\n        factoryWallet = factoryWallet_;\n        owner = msg.sender;\n        deployFees = deployFees_;\n    }\n\n    uint public totalDeployed = 0;\n    mapping(uint => address) public tokens;\n    \n    event NewERC314A(address indexed token, address indexed deployer);\n\n    function setFactoryWallet(address newWallet) public onlyOwner{\n        factoryWallet = newWallet;\n    }\n\n    function setDeployFees(uint newFees) public onlyOwner{\n        deployFees = newFees;\n    }\n    \n    function deploy314a(string memory name, string memory symbol, uint256 totalSupply, uint256 tokensToLiq, uint256 tokensToPresale, uint256 buyTax, uint256 sellTax, uint256 maxWallet) public payable{\n        require(msg.value >= deployFees, \"Ether amount is insufficient\");\n        payable(factoryWallet).transfer(msg.value);\n        ERC314a erc314a = new ERC314a(name, symbol, totalSupply, tokensToLiq, tokensToPresale, maxWallet, buyTax, sellTax, msg.sender, factoryWallet);\n        tokens[totalDeployed] = address(erc314a);\n        totalDeployed++;\n        emit NewERC314A(address(erc314a), msg.sender);\n    }\n}"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "evmVersion": "paris",
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}