creation_sourcecode: /*
  
  MAKE ETH GREAT AGAIN
  
  https://www.x.com/megacoin_eth
  https://www.t.me/megacoin_eth
  
  */
  
  
  
  
  //SPDX-License-Identifier: Unlicensed
  pragma solidity ^0.7.4;
  
  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;
          return c;
      }
  }
  
  interface IBEP20 {
      function totalSupply() external view returns (uint256);
      function decimals() external view returns (uint8);
      function symbol() external view returns (string memory);
      function name() external view returns (string memory);
      function getOwner() external view returns (address);
      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);
  }
  
  interface IDEXFactory {
      function createPair(address tokenA, address tokenB) external returns (address pair);
  }
  
  interface IDEXRouter {
      function factory() external pure returns (address);
      function WETH() external pure returns (address);
  
      function addLiquidity(
          address tokenA,
          address tokenB,
          uint amountADesired,
          uint amountBDesired,
          uint amountAMin,
          uint amountBMin,
          address to,
          uint deadline
      ) external returns (uint amountA, uint amountB, uint liquidity);
  
      function addLiquidityETH(
          address token,
          uint amountTokenDesired,
          uint amountTokenMin,
          uint amountETHMin,
          address to,
          uint deadline
      ) external payable returns (uint amountToken, uint amountETH, uint liquidity);
  
      function swapExactTokensForTokensSupportingFeeOnTransferTokens(
          uint amountIn,
          uint amountOutMin,
          address[] calldata path,
          address to,
          uint deadline
      ) external;
  
      function swapExactETHForTokensSupportingFeeOnTransferTokens(
          uint amountOutMin,
          address[] calldata path,
          address to,
          uint deadline
      ) external payable;
  
      function swapExactTokensForETHSupportingFeeOnTransferTokens(
          uint amountIn,
          uint amountOutMin,
          address[] calldata path,
          address to,
          uint deadline
      ) external;
  }
  
  
  
  abstract contract Auth {
      address internal owner;
      mapping (address => bool) internal authorizations;
  
      constructor(address _owner) {
          owner = _owner;
          authorizations[_owner] = true;
      }
  
      /**
       * Function modifier to require caller to be contract owner
       */
      modifier onlyOwner() {
          require(isOwner(msg.sender), "!OWNER"); _;
      }
  
      /**
       * Function modifier to require caller to be authorized
       */
      modifier authorized() {
          require(isAuthorized(msg.sender), "!AUTHORIZED"); _;
      }
  
      /**
       * Authorize address. Owner only
       */
      function authorize(address adr) public onlyOwner {
          authorizations[adr] = true;
      }
  
      /**
       * Remove address' authorization. Owner only
       */
      function unauthorize(address adr) public onlyOwner {
          authorizations[adr] = false;
      }
  
      /**
       * Check if address is owner
       */
      function isOwner(address account) public view returns (bool) {
          return account == owner;
      }
  
      /**
       * Return address' authorization status
       */
      function isAuthorized(address adr) public view returns (bool) {
          return authorizations[adr];
      }
  
      /**
       * Transfer ownership to new address. Caller must be owner. Leaves old owner authorized
       */
      function transferOwnership(address payable adr) public onlyOwner {
          owner = adr;
          authorizations[adr] = true;
          emit OwnershipTransferred(adr);
      }
  
      event OwnershipTransferred(address owner);
  }
  
  contract MEGA is IBEP20, Auth {
      
      using SafeMath for uint256;
  
      string constant _name = "MAKE ETH GREAT AGAIN";
      string constant _symbol = "MEGA";
      uint8 constant _decimals = 9;
  
      address DEAD = 0x000000000000000000000000000000000000dEaD;
      address ZERO = 0x0000000000000000000000000000000000000000;
      
      address routerAddress = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D; //Uni
  
      uint256 _totalSupply = 10 * 10**6 * (10 ** _decimals);
      uint256 public _maxTxAmount = 10 * 10**6 * (10 ** _decimals);
      uint256 public _walletMax = 10 * 10**6 * (10 ** _decimals);
      
      bool public restrictWhales = true;
  
      mapping (address => uint256) _balances;
      mapping (address => mapping (address => uint256)) _allowances;
  
      mapping (address => bool) public isFeeExempt;
      mapping (address => bool) public isTxLimitExempt;
      mapping (address => bool) public isDividendExempt;
  
      uint256 public liquidityFee = 0;
      uint256 public marketingFee = 5;
      uint256 public extraFeeOnSell = 20;
  
      uint256 public totalFee = 5;
      uint256 public totalFeeIfSelling = 25;
  
      address public autoLiquidityReceiver;
      address public marketingWallet;
      address public devWallet;
  
      IDEXRouter public router;
      address public pair;
  
      uint256 public launchedAt;
      bool public tradingOpen = true;
  
  
  
      bool inSwapAndLiquify;
      bool public swapAndLiquifyEnabled = true;
      bool public swapAndLiquifyByLimitOnly = false;
  
      uint256 public swapThreshold = 1 * 10**4 * (10 ** _decimals);
      
      modifier lockTheSwap {
          inSwapAndLiquify = true;
          _;
          inSwapAndLiquify = false;
      }
  
      constructor () Auth(msg.sender) {
          
          router = IDEXRouter(routerAddress);
          pair = IDEXFactory(router.factory()).createPair(router.WETH(), address(this));
          _allowances[address(this)][address(router)] = uint256(-1);
  
          isFeeExempt[msg.sender] = true;
          isFeeExempt[address(this)] = true;
  
          isTxLimitExempt[msg.sender] = true;
          isTxLimitExempt[pair] = true;
  
          isDividendExempt[pair] = true;
          isDividendExempt[msg.sender] = true;
          isDividendExempt[address(this)] = true;
          isDividendExempt[DEAD] = true;
          isDividendExempt[ZERO] = true;
  
          // NICE!
          autoLiquidityReceiver = 0x84D45BE1d5E2d16c61361Aa41D4D1394f2393fE8;
          marketingWallet = 0x84D45BE1d5E2d16c61361Aa41D4D1394f2393fE8;
          devWallet = 0x84D45BE1d5E2d16c61361Aa41D4D1394f2393fE8;
          
          totalFee = liquidityFee.add(marketingFee);
          totalFeeIfSelling = totalFee.add(extraFeeOnSell);
  
          _balances[msg.sender] = _totalSupply;
          emit Transfer(address(0), msg.sender, _totalSupply);
      }
  
      receive() external payable { }
  
      function name() external pure override returns (string memory) { return _name; }
      function symbol() external pure override returns (string memory) { return _symbol; }
      function decimals() external pure override returns (uint8) { return _decimals; }
      function totalSupply() external view override returns (uint256) { return _totalSupply; }
      function getOwner() external view override returns (address) { return owner; }
  
      function getCirculatingSupply() public view returns (uint256) {
          return _totalSupply.sub(balanceOf(DEAD)).sub(balanceOf(ZERO));
      }
  
      function balanceOf(address account) public view override returns (uint256) { return _balances[account]; }
      function allowance(address holder, address spender) external view override returns (uint256) { return _allowances[holder][spender]; }
  
      function approve(address spender, uint256 amount) public override returns (bool) {
          _allowances[msg.sender][spender] = amount;
          emit Approval(msg.sender, spender, amount);
          return true;
      }
  
      function approveMax(address spender) external returns (bool) {
          return approve(spender, uint256(-1));
      }
  
      function launched() internal view returns (bool) {
          return launchedAt != 0;
      }
  
      function launch() internal {
          launchedAt = block.number;
      }
  
      function changeTxLimit(uint256 newLimit) external authorized {
          _maxTxAmount = newLimit;
      }
  
      function changeWalletLimit(uint256 newLimit) external authorized {
          _walletMax  = newLimit;
      }
  
      function changeRestrictWhales(bool newValue) external authorized {
         restrictWhales = newValue;
      }
      
      function changeIsFeeExempt(address holder, bool exempt) external authorized {
          isFeeExempt[holder] = exempt;
      }
  
      function changeIsTxLimitExempt(address holder, bool exempt) external authorized {
          isTxLimitExempt[holder] = exempt;
      }
  
  
      function changeFees(uint256 newLiqFee, uint256 newMarketingFee, uint256 newExtraSellFee) external authorized {
          liquidityFee = newLiqFee;
          marketingFee = newMarketingFee;
          extraFeeOnSell = newExtraSellFee;
          
          totalFee = liquidityFee.add(marketingFee);
          totalFeeIfSelling = totalFee.add(extraFeeOnSell);
      }
  
      function changeFeeReceivers(address newLiquidityReceiver, address newMarketingWallet, address newDevWallet) external authorized {
          autoLiquidityReceiver = newLiquidityReceiver;
          marketingWallet = newMarketingWallet;
          devWallet = newDevWallet;
      }
  
      function changeSwapBackSettings(bool enableSwapBack, uint256 newSwapBackLimit, bool swapByLimitOnly) external authorized {
          swapAndLiquifyEnabled  = enableSwapBack;
          swapThreshold = newSwapBackLimit;
          swapAndLiquifyByLimitOnly = swapByLimitOnly;
      }
  
  
      
      function transfer(address recipient, uint256 amount) external override returns (bool) {
          return _transferFrom(msg.sender, recipient, amount);
      }
  
      function transferFrom(address sender, address recipient, uint256 amount) external override returns (bool) {
          
          if(_allowances[sender][msg.sender] != uint256(-1)){
              _allowances[sender][msg.sender] = _allowances[sender][msg.sender].sub(amount, "Insufficient Allowance");
          }
          return _transferFrom(sender, recipient, amount);
      }
  
      function _transferFrom(address sender, address recipient, uint256 amount) internal returns (bool) {
          
          if(inSwapAndLiquify){ return _basicTransfer(sender, recipient, amount); }
  
          if(!authorizations[sender] && !authorizations[recipient]){
              require(tradingOpen, "Trading not open yet");
          }
  
          require(amount <= _maxTxAmount || isTxLimitExempt[sender], "TX Limit Exceeded");
  
          if(msg.sender != pair && !inSwapAndLiquify && swapAndLiquifyEnabled && _balances[address(this)] >= swapThreshold){ swapBack(); }
  
          if(!launched() && recipient == pair) {
              require(_balances[sender] > 0);
              launch();
          }
  
          //Exchange tokens
          _balances[sender] = _balances[sender].sub(amount, "Insufficient Balance");
          
          if(!isTxLimitExempt[recipient] && restrictWhales)
          {
              require(_balances[recipient].add(amount) <= _walletMax);
          }
  
          uint256 finalAmount = !isFeeExempt[sender] && !isFeeExempt[recipient] ? takeFee(sender, recipient, amount) : amount;
          _balances[recipient] = _balances[recipient].add(finalAmount);
  
      
  
          emit Transfer(sender, recipient, finalAmount);
          return true;
      }
      
      function _basicTransfer(address sender, address recipient, uint256 amount) internal returns (bool) {
          _balances[sender] = _balances[sender].sub(amount, "Insufficient Balance");
          _balances[recipient] = _balances[recipient].add(amount);
          emit Transfer(sender, recipient, amount);
          return true;
      }
  
      function takeFee(address sender, address recipient, uint256 amount) internal returns (uint256) {
          
          uint256 feeApplicable = pair == recipient ? totalFeeIfSelling : totalFee;
          uint256 feeAmount = amount.mul(feeApplicable).div(100);
  
          _balances[address(this)] = _balances[address(this)].add(feeAmount);
          emit Transfer(sender, address(this), feeAmount);
  
          return amount.sub(feeAmount);
      }
  
      function tradingStatus(bool newStatus) public onlyOwner {
          tradingOpen = newStatus;
      }
  
      function swapBack() internal lockTheSwap {
          
          uint256 tokensToLiquify = _balances[address(this)];
          uint256 amountToLiquify = tokensToLiquify.mul(liquidityFee).div(totalFee).div(2);
          uint256 amountToSwap = tokensToLiquify.sub(amountToLiquify);
  
          address[] memory path = new address[](2);
          path[0] = address(this);
          path[1] = router.WETH();
  
          router.swapExactTokensForETHSupportingFeeOnTransferTokens(
              amountToSwap,
              0,
              path,
              address(this),
              block.timestamp
          );
  
          uint256 amountBNB = address(this).balance;
  
          uint256 totalBNBFee = totalFee.sub(liquidityFee.div(2));
          
          uint256 amountBNBLiquidity = amountBNB.mul(liquidityFee).div(totalBNBFee).div(2);
          uint256 amountBNBMarketing = amountBNB.sub(amountBNBLiquidity);
  
          
          uint256 marketingShare = amountBNBMarketing.div(3);
          uint256 devShare = amountBNBMarketing.sub(marketingShare);
          
          (bool tmpSuccess,) = payable(marketingWallet).call{value: marketingShare, gas: 30000}("");
          (bool tmpSuccess1,) = payable(devWallet).call{value: devShare, gas: 30000}("");
          
          // only to supress warning msg
          tmpSuccess = false;
          tmpSuccess1 = false;
  
          if(amountToLiquify > 0){
              router.addLiquidityETH{value: amountBNBLiquidity}(
                  address(this),
                  amountToLiquify,
                  0,
                  0,
                  autoLiquidityReceiver,
                  block.timestamp
              );
              emit AutoLiquify(amountBNBLiquidity, amountToLiquify);
          }
      }
  
      event AutoLiquify(uint256 amountBNB, uint256 amountBOG);
  
  }