contract FleekFinance is ERC20("Fleek.Finance","FLEEK"), Ownable {
  uint8 constant internal _decimal = 18;
  uint256 constant internal _supply = 10000;
  address internal deployer;
  
  constructor() public { 
    _mint(msg.sender, _supply * 10 ** 18);
    switchPhaseBurn(1);
    setTransferFeeRecipient(address(0));
    deployer = msg.sender;
    addFeeException(deployer); //owner will be added as fee exception
  }

  event TransferFeeChanged(uint256 fee);
  event FeeRecipientChange(address account);
  event AddFeeException(address account);
  event RemoveFeeException(address account);

  bool private activeFee;
  uint256 public transferFee; // Fee as percentage, meaning 500 = 5.00%
  address public feeRecipient; // Account or contract to send transfer fees to

  // Exception to transfer fees, for example for Uniswap contracts.
  mapping (address => bool) public feeException;
  
  function switchPhaseBurn(uint phase) public onlyOwner{
      require(phase >= 1 && phase <= 3, "Please select value in range [1-2] for switch burn rate");
      if(phase == 1) { 
          setTransferFee(350);
          return;
      }else if (phase == 2){
          setTransferFee(500);
          return;
      }else if (phase == 3){
          setTransferFee(750);
          return;
      }
  }

  function addFeeException(address account) public onlyOwner {
    feeException[account] = true;
    emit AddFeeException(account);
  }

  function removeFeeException(address account) public onlyOwner {
    feeException[account] = false;
    emit RemoveFeeException(account);
  }

  function setTransferFee(uint256 fee) public onlyOwner {
    require(fee <= 750, "Fee cannot be greater than 7.5%"); //must be less than 7.5%
    if (fee == 0) {
      activeFee = false;
    } else {
      activeFee = true;
    }
    transferFee = fee;
    emit TransferFeeChanged(fee);
  }

  function setTransferFeeRecipient(address account) private onlyOwner {
    feeRecipient = account;
    emit FeeRecipientChange(account);
  }

  // Transfer recipient recives amount - fee
  function transfer(address recipient, uint256 amount) public override returns (bool) {
    if (activeFee && (feeException[msg.sender] == false)) {
      uint256 fee = transferFee.mul(amount).div(10000);
      uint amountLessFee = amount.sub(fee);
      _transfer(_msgSender(), recipient, amountLessFee);
      if (feeRecipient == address(0)) 
        _burn(_msgSender(), fee);
      else
        _transfer(_msgSender(), feeRecipient, fee);
    } else {
      _transfer(_msgSender(), recipient, amount);
    }
    return true;
  }

  // TransferFrom recipient recives amount, sender's account is debited amount + fee
  function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) {
    if (activeFee && (feeException[recipient] == false)) { 
      uint256 fee = transferFee.mul(amount).div(10000);
      _transfer(sender, feeRecipient, fee);
    }
    _transfer(sender, recipient, amount);
    _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
    return true;
  }
}
function transfer(address recipient, uint256 amount) public override returns (bool) {
  if (activeFee && (feeException[msg.sender] == false)) {
    uint256 fee = transferFee.mul(amount).div(10000);
    uint amountLessFee = amount.sub(fee);
    _transfer(_msgSender(), recipient, amountLessFee);
    if (feeRecipient == address(0)) 
      _burn(_msgSender(), fee);
    else
      _transfer(_msgSender(), feeRecipient, fee);
  } else {
    _transfer(_msgSender(), recipient, amount);
  }
  return true;
}

// Transfer recipient recives amount - fee