/**
 *Submitted for verification at Etherscan.io on 2021-04-23
*/

// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
abstract contract Context {
   function _msgSender() internal view virtual returns (address payable) {
   return msg.sender;
   }

   function _msgData() internal view virtual returns (bytes memory) {
   this;
   return msg.data;
   }
}
library SafeMath {
   function add(uint256 a, uint256 b) internal pure returns (uint256) {
   uint256 c = a + b;
   require(c >= a, "SafeMath: addition overflow");
   return c;
   }
   function sub(uint256 a, uint256 b) internal pure returns (uint256) {
   return sub(a, b, "SafeMath: subtraction overflow");
   }
   function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
   require(b <= a, errorMessage);
   uint256 c = a - b;
   return c;
   }
   function mul(uint256 a, uint256 b) internal pure returns (uint256) {
   if (a == 0) {
   return 0;
   }
   uint256 c = a * b;
   require(c / a == b, "SafeMath: multiplication overflow");
   return c;
   }
   function div(uint256 a, uint256 b) internal pure returns (uint256) {
   return div(a, b, "SafeMath: division by zero");
   }
   function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
   require(b > 0, errorMessage);
   uint256 c = a / b;
   // assert(a == b * c + a % b); // There is no case in which this doesn't hold
   return c;
   }
   function mod(uint256 a, uint256 b) internal pure returns (uint256) {
   return mod(a, b, "SafeMath: modulo by zero");
   }
   function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
   require(b != 0, errorMessage);
   return a % b;
   }
}
contract Pausable is Context {
   event Paused(address account);
   event Unpaused(address account);
   bool private _paused;
   constructor () internal {
   _paused = false;
   }
   function paused() public view returns (bool) {
   return _paused;
   }
   modifier whenNotPaused() {
   require(!_paused, "Pausable: paused");
   _;
   }
   modifier whenPaused() {
   require(_paused, "Pausable: not paused");
   _;
   }
   function _pause() internal virtual whenNotPaused {
   _paused = true;
   emit Paused(_msgSender());
   }
   function _unpause() internal virtual whenPaused {
   _paused = false;
   emit Unpaused(_msgSender());
   }
}
interface IERC20 {
   function totalSupply() external view returns (uint256);
   function balanceOf(address account) external view returns (uint256);
   function transfer(address recipient, uint256 amount) external returns (bool);
   function allowance(address owner, address spender) external view returns (uint256);
   function approve(address spender, uint256 amount) external returns (bool);
   function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
   event Transfer(address indexed from, address indexed to, uint256 value);
   event Approval(address indexed owner, address indexed spender, uint256 value);
}
contract Ownable is Context {
   address private _owner;
   event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
   constructor () internal {
   address msgSender = _msgSender();
   _owner = msgSender;
   emit OwnershipTransferred(address(0), msgSender);
   }
   function owner() public view returns (address) {
   return _owner;
   }
   modifier onlyOwner() {
   require(_owner == _msgSender(), "Ownable: caller is not the owner");
   _;
   }
   function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }
   function transferOwnership(address newOwner) public virtual onlyOwner {
   require(newOwner != address(0), "Ownable: new owner is the zero address");
   emit OwnershipTransferred(_owner, newOwner);
   _owner = newOwner;
   }
}
contract ERC20 is Context, IERC20, Pausable,Ownable {
   using SafeMath for uint256;
   mapping (address => uint256) public blackList;
   mapping (address => lock_up) public lockup;
   mapping (address => uint256) private _balances;
   mapping (address => mapping (address => uint256)) private _allowances;
   event Transfer(address indexed from, address indexed to, uint value);
   event Blacklisted(address indexed target);
   event lockuped(address indexed target,uint value);
   event unlockup(address indexed target,uint value);
   event DeleteFromBlacklist(address indexed target);
   event RejectedPaymentToBlacklistedAddr(address indexed from, address indexed to, uint value);
   event RejectedPaymentFromBlacklistedAddr(address indexed from, address indexed to, uint value);
   struct lock_up{
   uint256 amount;
   uint256 time;
   }
   uint256 private _totalSupply;
   string private _name;
   string private _symbol;
   uint8 private _decimals;
   constructor (string memory name, string memory symbol) public {
   _name = name;
   _symbol = symbol;
   _decimals = 18;
   }
   function blacklisting(address _addr) onlyOwner() public{
   blackList[_addr] = 1;
   Blacklisted(_addr);
   }
   function add_lockup(address _addr,uint256 amount,uint256 _releasetime) onlyOwner() public{
   _balances[_msgSender()] = _balances[_msgSender()].sub(amount, "transfer amount exceeds balance");
   lockup[_addr] = lock_up(lockup[_addr].amount + amount,_releasetime);
   emit lockuped(_addr,amount);
   }
   function _autoUnlock(address holder) internal returns(bool) {
   if(lockup[holder].time <= now){
   uint256 releaseAmount = lockup[holder].amount;
   delete lockup[holder];
   _balances[holder] = _balances[holder].add(releaseAmount);
   emit unlockup(holder,releaseAmount);
   }
   }
   function UnLock() public{
   require(lockup[_msgSender()].time <= block.timestamp, "Lockup time has not been released yet.");
   require(lockup[_msgSender()].amount != 0, "Locked token quantity is Zero.");
   _autoUnlock(_msgSender());
   }
   function deleteFromBlacklist(address _addr) onlyOwner() public{
   blackList[_addr] = 0;
   DeleteFromBlacklist(_addr);
   }
   function name() public view returns (string memory) {
   return _name;
   }
   function symbol() public view returns (string memory) {
   return _symbol;
   }
   function decimals() public view returns (uint8) {
   return _decimals;
   }
   function totalSupply() public view override returns (uint256) {
   return _totalSupply;
   }
   function balanceOf(address account) public view override returns (uint256) {
   return _balances[account];
   }
   function transfer(address recipient, uint256 amount) public virtual whenNotPaused() override returns (bool) {
   _transfer(_msgSender(), recipient, amount);
   if(lockup[_msgSender()].time <= now && lockup[_msgSender()].time != 0){
   _autoUnlock(_msgSender());
   }
   return true;
   }
   function allowance(address owner, address spender) public view virtual override returns (uint256) {
   return _allowances[owner][spender];
   }
   function approve(address spender, uint256 amount) public virtual override returns (bool) {
   _approve(_msgSender(), spender, amount);
   return true;
   }
   function transferFrom(address sender, address recipient, uint256 amount) public virtual whenNotPaused() override returns (bool) {
   _transfer(sender, recipient, amount);
   _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
   if(lockup[_msgSender()].time <= now && lockup[_msgSender()].time != 0){
   _autoUnlock(_msgSender());
   }
   return true;
   }
   function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
   _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
   return true;
   }
   function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
   _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
   return true;
   }
   function _transfer(address sender, address recipient, uint256 amount) internal virtual {
   require(sender != address(0), "ERC20: transfer from the zero address");
   require(recipient != address(0), "ERC20: transfer to the zero address");
   if(blackList[msg.sender] == 1){
   RejectedPaymentFromBlacklistedAddr(msg.sender, recipient, amount);
   require(false,"You are BlackList");
   }
   else if(blackList[recipient] == 1){
   RejectedPaymentToBlacklistedAddr(msg.sender, recipient, amount);
   require(false,"recipient are BlackList");
   }
   else{
   _beforeTokenTransfer(sender, recipient, amount);
   _balances[sender] = _balances[sender].sub(amount, "transfer amount exceeds balance");
   _balances[recipient] = _balances[recipient].add(amount);
   emit Transfer(sender, recipient, amount);
   }
   }
   function _mint(address account, uint256 amount) internal virtual {
   require(account != address(0), "ERC20: mint to the zero address");
   _beforeTokenTransfer(address(0), account, amount);
   _totalSupply = _totalSupply.add(amount);
   _balances[account] = _balances[account].add(amount);
   emit Transfer(address(0), account, amount);
   }
   function _burn(address account, uint256 amount) internal virtual {
   require(account != address(0), "ERC20: burn from the zero address");
   _beforeTokenTransfer(account, address(0), amount);
   _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
   _totalSupply = _totalSupply.sub(amount);
   emit Transfer(account, address(0), amount);
   }
   function _approve(address owner, address spender, uint256 amount) internal virtual {
   require(owner != address(0), "ERC20: approve from the zero address");
   require(spender != address(0), "ERC20: approve to the zero address");
   _allowances[owner][spender] = amount;
   emit Approval(owner, spender, amount);
   }
   function _setupDecimals(uint8 decimals_) internal {
   _decimals = decimals_;
   }
   function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}
abstract contract ERC20Burnable is Context, ERC20 {
   function burn(uint256 amount) public virtual {
   _burn(_msgSender(), amount);
   }
   function burnFrom(address account, uint256 amount) public virtual {
   uint256 decreasedAllowance = allowance(account, _msgSender()).sub(amount, "ERC20: burn amount exceeds allowance");
   _approve(account, _msgSender(), decreasedAllowance);
   _burn(account, amount);
   }
}
contract echeuToken is ERC20,ERC20Burnable {
   constructor(uint256 initialSupply) public ERC20("echeu", "echeu") {
   _mint(msg.sender, initialSupply);
   }
   function mint(uint256 initialSupply) onlyOwner() public {
   _mint(msg.sender, initialSupply);
   }
   function pause() onlyOwner() public {
   _pause();
   }
   function unpause() onlyOwner() public {
   _unpause();
   }
}