contract InfernoFinance is ERC20, Ownable 
{
	// Token Details
	string constant tokenName = "Inferno Finance";
	string constant tokenSymbol = "INFNO";
	uint8  constant tokenDecimals = 18;
    uint256 private _totalSupply = 1000 * (10 ** 18);
	uint256 public basePercent = 100;

	constructor() public ERC20(tokenName, tokenSymbol) 
	{
		_mint(msg.sender, _totalSupply);
	}

	// Transfer Fee
	event TransferFeeChanged(uint256 newFee);
	event FeeRecipientChange(address account);
	event AddFeeException(address account);
	event RemoveFeeException(address account);

	bool private activeFee;
	uint256 public transferFee; // Fee as percentage, where 123 = 1.23%
	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 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 
	{
		// Maximum Possible Fee is 35%
		require(fee <= 3500, "Fee cannot be greater than 35%");
		if (fee == 0) 
		{
			activeFee = false;
		} 
		
		else 
		{
			activeFee = true;
		}
		
		transferFee = fee;
		emit TransferFeeChanged(fee);
	}

	function setTransferFeeRecipient(address account) public onlyOwner 
	{
		feeRecipient = account;
		emit FeeRecipientChange(account);
	}
	
	// Get 2%
	function percentSupply(uint256 value) public view returns (uint256)  
	{
		uint256 roundValue = value.ceil(basePercent);
		uint256 onePercent = roundValue.mul(basePercent).div(5000);
		return onePercent;
	}

	// Transfer recipient recives amount - fee
	function transfer(address recipient, uint256 amount) public override returns (bool) 
	{
		if (activeFee && feeException[_msgSender()] == false) 
		{
			uint256 twoPercent = percentSupply(_totalSupply);
		
			// Max transactable amount of 2% of total supply
			require (amount <= twoPercent);
		
			uint256 fee = transferFee.mul(amount).div(10000);
			uint amountLessFee = amount.sub(fee);
			_transfer(_msgSender(), recipient, amountLessFee);
			_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 twoPercent = percentSupply(_totalSupply);
		
			// Max transactable amount of 2% of total supply
			require (amount <= twoPercent);
		    
			_transfer(sender, recipient, amount);
			_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
		}
	    
	     _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
	
		return true;
	}
}
function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) 
{
	if (activeFee && feeException[recipient] == false)
	{ 
	    uint256 twoPercent = percentSupply(_totalSupply);
		
		// Max transactable amount of 2% of total supply
		require (amount <= twoPercent);
		    
		_transfer(sender, recipient, amount);
		_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
	}
	    
     _transfer(sender, recipient, amount);
       _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
	
	return true;
}

// TransferFrom recipient recives amount, sender's account is debited amount + fee