ETH Price: $2,512.03 (+1.43%)

Transaction Decoder

Block:
18105775 at Sep-10-2023 11:48:23 AM +UTC
Transaction Fee:
0.000580890893100168 ETH $1.46
Gas Used:
54,334 Gas / 10.691112252 Gwei

Emitted Events:

179 0x93314ee69bf8f943504654f9a8eced0071526439.0xee503bee2bb6a87e57bc57db795f98137327401a0e7b7ce42e37926cc1a9ca4d( 0xee503bee2bb6a87e57bc57db795f98137327401a0e7b7ce42e37926cc1a9ca4d, 0000000000000000000000003d9d1e210bcc15902d06131246e91025bd67abc0, 000000000000000000000000000000000000000000000000001e91c4cab28d70 )

Account State Difference:

  Address   Before After State Difference Code
0x3d9d1e21...5BD67aBc0
0.04733517377242989 Eth
Nonce: 720
0.055358806580966186 Eth
Nonce: 721
0.008023632808536296
(builder0x69)
2.850997828117168143 Eth2.851003261517168143 Eth0.0000054334
0x93314Ee6...071526439 101.928989554558526696 Eth101.920385030856890232 Eth0.008604523701636464

Execution Trace

AimBot.CALL( )
  • 0x93314ee69bf8f943504654f9a8eced0071526439.1e83409a( )
    • ETH 0.008604523701636464 0x3d9d1e210bcc15902d06131246e91025bd67abc0.CALL( )
      // https://aim-bot.app/
      // https://t.me/Aimbotportal
      // https://twitter.com/aimbot_coin
      // SPDX-License-Identifier: MIT
      import "./AimBotDividends.sol";
      import "./Ownable.sol";
      import "./Context.sol";
      import "./ERC20.sol";
      import "./IERC20.sol";
      import "./IERC20Metadata.sol";
      import "./IUniswapV2Factory.sol";
      import "./IUniswapV2Router.sol";
      pragma solidity ^0.8.19;
      contract AimBot is Ownable, ERC20 {
          uint256 public maxWallet;
          address public uniswapV2Pair;
          IUniswapV2Router02 immutable router = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
          AimBotDividends public dividends;
          uint256 SUPPLY = 1000000 * 10**18;
          uint256 snipeFee = 30; 
          uint256 totalFee = 5; 
          uint256 botFee = 3; 
          bool private inSwap = false;
          address public marketingWallet;
          address public devWallet;
          address public botWallet;
          uint256 public openTradingBlock;
          mapping (address => uint256) public receiveBlock;
          uint256 public swapAt = SUPPLY / 1000; //0.1%
          constructor() ERC20("AimBot", "AIMBOT") payable {
              _mint(msg.sender, SUPPLY * 23 / 1000);
              _mint(address(this), SUPPLY * 977 / 1000);
              maxWallet = SUPPLY;
              marketingWallet = 0x3be53c7D961F3595515E9905E7507b33A5DC7c5A;
              devWallet = 0x092A071a3322166A840B06Ace845761f98FbBAa0;
              botWallet = 0x88054E4FF95395d43286b52D97451C71a974D8c9;
              dividends = new AimBotDividends();
              dividends.excludeFromDividends(address(dividends));
              dividends.excludeFromDividends(address(this));
              dividends.excludeFromDividends(owner());
          }
          receive() external payable {}
          function isContract(address account) private view returns (bool) {
              uint256 size;
              assembly {
                  size := extcodesize(account)
              }
              return size > 0;
          }
          function updateBotWallet(address _botWallet) external onlyOwner {
              botWallet = _botWallet;
          }
          function updateDividends(address _dividends) external onlyOwner {
              dividends = AimBotDividends(payable(_dividends));
              dividends.excludeFromDividends(address(dividends));
              dividends.excludeFromDividends(address(this));
              dividends.excludeFromDividends(owner());
              dividends.excludeFromDividends(uniswapV2Pair);
              dividends.excludeFromDividends(address(router));
          }
          function updateFee(uint256 _totalFee, uint256 _botFee) external onlyOwner {
              require(_totalFee <= 5 && _botFee <= _totalFee);
              totalFee = _totalFee;
              botFee = _botFee;
          }
          function updateMaxHoldingPercent(uint256 percent) public onlyOwner {
              require(percent >= 1 && percent <= 100, "invalid percent");
              maxWallet = SUPPLY * percent / 100;
          }
          function updateSwapAt(uint256 value) external onlyOwner() {
              require(value <= SUPPLY / 50);
              swapAt = value;
          }
          function stats(address account) external view returns (uint256 withdrawableDividends, uint256 totalDividends) {
              (,withdrawableDividends,totalDividends) = dividends.getAccount(account);
          }
          function claim() external {
      \t\tdividends.claim(msg.sender);
          }
          function openTrading() external onlyOwner {
              address pair = IUniswapV2Factory(router.factory()).createPair(address(this), router.WETH());
              _approve(address(this), address(router), balanceOf(address(this)));
              router.addLiquidityETH{
                  value: address(this).balance
              } (
                  address(this),
                  balanceOf(address(this)),
                  0,
                  0,
                  owner(),
                  block.timestamp
              );
              uniswapV2Pair = pair;
              openTradingBlock = block.number;
              dividends.excludeFromDividends(address(router));
              dividends.excludeFromDividends(pair);
              updateMaxHoldingPercent(1);
          }
          function _transfer(address from, address to, uint256 amount) internal override {
              if(uniswapV2Pair == address(0)) {
                  require(from == address(this) || from == address(0) || from == owner() || to == owner(), "Not started");
                  super._transfer(from, to, amount);
                  return;
              }
              if(from == uniswapV2Pair && to != address(this) && to != owner() && to != address(router)) {
                  require(super.balanceOf(to) + amount <= maxWallet, "max wallet");
              }
              uint256 swapAmount = balanceOf(address(this));
              if(swapAmount > swapAt) {
                  swapAmount = swapAt;
              }
              if(
                  swapAt > 0 &&
                  swapAmount == swapAt &&
                  !inSwap &&
                  from != uniswapV2Pair) {
                  inSwap = true;
                  swapTokensForEth(swapAmount);
                  uint256 balance = address(this).balance;
                  if(balance > 0) {
                      withdraw(balance);
                  }
                  inSwap = false;
              }
              uint256 fee;
              if(block.number <= openTradingBlock + 4 && from == uniswapV2Pair) {
                  require(!isContract(to));
                  fee = snipeFee;
              }
              else if(totalFee > 0) {
                  fee = totalFee;
              }
                  
              if(
                  fee > 0 &&
                  from != address(this) &&
                  from != owner() &&
                  from != address(router)
              ) {
                  uint256 feeTokens = amount * fee / 100;
                  amount -= feeTokens;
                  super._transfer(from, address(this), feeTokens);
              }
              super._transfer(from, to, amount);
              dividends.updateBalance(payable(from));
              dividends.updateBalance(payable(to));
          }
          function swapTokensForEth(uint256 tokenAmount) private {
              address[] memory path = new address[](2);
              path[0] = address(this);
              path[1] = router.WETH();
              _approve(address(this), address(router), tokenAmount);
              router.swapExactTokensForETHSupportingFeeOnTransferTokens(
                  tokenAmount,
                  0,
                  path,
                  address(this),
                  block.timestamp
              );
          }
          function sendFunds(address user, uint256 value) private {
              if(value > 0) {
                  (bool success,) = user.call{value: value}("");
                  success;
              }
          }
          function withdraw(uint256 amount) private {
              uint256 botShare = totalFee > 0 ? botFee * 10000 / totalFee : 0;
              uint256 toBot = amount * botShare / 10000;
              uint256 toMarketing = (amount - toBot) / 2;
              uint256 toDev = toMarketing;
              sendFunds(marketingWallet, toMarketing);
              sendFunds(devWallet, toDev);
              sendFunds(botWallet, toBot);
          }
      }// 
      //
      //
      // SPDX-License-Identifier: MIT
      import "./Ownable.sol";
      import "./ERC20.sol";
      import "./IERC20.sol";
      import "./SafeMath.sol";
      pragma solidity ^0.8.19;
      contract DividendPayingToken is ERC20 {
        using SafeMath for uint256;
        using SafeMathUint for uint256;
        using SafeMathInt for int256;
        // With `magnitude`, we can properly distribute dividends even if the amount of received ether is small.
        // For more discussion about choosing the value of `magnitude`,
        //  see https://github.com/ethereum/EIPs/issues/1726#issuecomment-472352728
        uint256 constant internal magnitude = 2**128;
        uint256 internal magnifiedDividendPerShare;
        // About dividendCorrection:
        // If the token balance of a `_user` is never changed, the dividend of `_user` can be computed with:
        //   `dividendOf(_user) = dividendPerShare * balanceOf(_user)`.
        // When `balanceOf(_user)` is changed (via minting/burning/transferring tokens),
        //   `dividendOf(_user)` should not be changed,
        //   but the computed value of `dividendPerShare * balanceOf(_user)` is changed.
        // To keep the `dividendOf(_user)` unchanged, we add a correction term:
        //   `dividendOf(_user) = dividendPerShare * balanceOf(_user) + dividendCorrectionOf(_user)`,
        //   where `dividendCorrectionOf(_user)` is updated whenever `balanceOf(_user)` is changed:
        //   `dividendCorrectionOf(_user) = dividendPerShare * (old balanceOf(_user)) - (new balanceOf(_user))`.
        // So now `dividendOf(_user)` returns the same value before and after `balanceOf(_user)` is changed.
        mapping(address => int256) internal magnifiedDividendCorrections;
        mapping(address => uint256) internal withdrawnDividends;
        uint256 public totalDividendsDistributed;
        event DividendsDistributed(address user, uint256 amount);
        event DividendWithdrawn(address user, uint256 amount);
        constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) {
        }
        /// @dev Distributes dividends whenever ether is paid to this contract.
        receive() external payable {
          distributeDividends();
        }
        /// @notice Distributes ether to token holders as dividends.
        /// @dev It reverts if the total supply of tokens is 0.
        /// It emits the `DividendsDistributed` event if the amount of received ether is greater than 0.
        /// About undistributed ether:
        ///   In each distribution, there is a small amount of ether not distributed,
        ///     the magnified amount of which is
        ///     `(msg.value * magnitude) % totalSupply()`.
        ///   With a well-chosen `magnitude`, the amount of undistributed ether
        ///     (de-magnified) in a distribution can be less than 1 wei.
        ///   We can actually keep track of the undistributed ether in a distribution
        ///     and try to distribute it in the next distribution,
        ///     but keeping track of such data on-chain costs much more than
        ///     the saved ether, so we don't do that.
        function distributeDividends() public virtual payable {
          require(totalSupply() > 0);
          if (msg.value > 0) {
            magnifiedDividendPerShare = magnifiedDividendPerShare.add(
              (msg.value).mul(magnitude) / totalSupply()
            );
            emit DividendsDistributed(msg.sender, msg.value);
            totalDividendsDistributed = totalDividendsDistributed.add(msg.value);
          }
        }
        /// @notice Withdraws the ether distributed to the sender.
        /// @dev It emits a `DividendWithdrawn` event if the amount of withdrawn ether is greater than 0.
        function withdrawDividend() public virtual {
          _withdrawDividendOfUser(payable(msg.sender));
        }
        /// @notice Withdraws the ether distributed to the sender.
        /// @dev It emits a `DividendWithdrawn` event if the amount of withdrawn ether is greater than 0.
        function _withdrawDividendOfUser(address payable user) internal returns (uint256) {
          uint256 _withdrawableDividend = withdrawableDividendOf(user);
          if (_withdrawableDividend > 0) {
            withdrawnDividends[user] = withdrawnDividends[user].add(_withdrawableDividend);
            emit DividendWithdrawn(user, _withdrawableDividend);
            (bool success,) = user.call{value: _withdrawableDividend, gas: 3000}("");
            if(!success) {
              withdrawnDividends[user] = withdrawnDividends[user].sub(_withdrawableDividend);
              return 0;
            }
            return _withdrawableDividend;
          }
          return 0;
        }
        /// @notice View the amount of dividend in wei that an address can withdraw.
        /// @param _owner The address of a token holder.
        /// @return The amount of dividend in wei that `_owner` can withdraw.
        function dividendOf(address _owner) public view returns(uint256) {
          return withdrawableDividendOf(_owner);
        }
        /// @notice View the amount of dividend in wei that an address can withdraw.
        /// @param _owner The address of a token holder.
        /// @return The amount of dividend in wei that `_owner` can withdraw.
        function withdrawableDividendOf(address _owner) public view returns(uint256) {
          return accumulativeDividendOf(_owner).sub(withdrawnDividends[_owner]);
        }
        /// @notice View the amount of dividend in wei that an address has withdrawn.
        /// @param _owner The address of a token holder.
        /// @return The amount of dividend in wei that `_owner` has withdrawn.
        function withdrawnDividendOf(address _owner) public view returns(uint256) {
          return withdrawnDividends[_owner];
        }
        /// @notice View the amount of dividend in wei that an address has earned in total.
        /// @dev accumulativeDividendOf(_owner) = withdrawableDividendOf(_owner) + withdrawnDividendOf(_owner)
        /// = (magnifiedDividendPerShare * balanceOf(_owner) + magnifiedDividendCorrections[_owner]) / magnitude
        /// @param _owner The address of a token holder.
        /// @return The amount of dividend in wei that `_owner` has earned in total.
        function accumulativeDividendOf(address _owner) public view returns(uint256) {
          return magnifiedDividendPerShare.mul(balanceOf(_owner)).toInt256Safe()
            .add(magnifiedDividendCorrections[_owner]).toUint256Safe() / magnitude;
        }
        /// @dev Internal function that transfer tokens from one address to another.
        /// Update magnifiedDividendCorrections to keep dividends unchanged.
        /// @param from The address to transfer from.
        /// @param to The address to transfer to.
        /// @param value The amount to be transferred.
        function _transfer(address from, address to, uint256 value) internal virtual override {
          require(false);
          int256 _magCorrection = magnifiedDividendPerShare.mul(value).toInt256Safe();
          magnifiedDividendCorrections[from] = magnifiedDividendCorrections[from].add(_magCorrection);
          magnifiedDividendCorrections[to] = magnifiedDividendCorrections[to].sub(_magCorrection);
        }
        /// @dev Internal function that mints tokens to an account.
        /// Update magnifiedDividendCorrections to keep dividends unchanged.
        /// @param account The account that will receive the created tokens.
        /// @param value The amount that will be created.
        function _mint(address account, uint256 value) internal override {
          super._mint(account, value);
          magnifiedDividendCorrections[account] = magnifiedDividendCorrections[account]
            .sub( (magnifiedDividendPerShare.mul(value)).toInt256Safe() );
        }
        /// @dev Internal function that burns an amount of the token of a given account.
        /// Update magnifiedDividendCorrections to keep dividends unchanged.
        /// @param account The account whose tokens will be burnt.
        /// @param value The amount that will be burnt.
        function _burn(address account, uint256 value) internal override {
          super._burn(account, value);
          magnifiedDividendCorrections[account] = magnifiedDividendCorrections[account]
            .add( (magnifiedDividendPerShare.mul(value)).toInt256Safe() );
        }
        function _setBalance(address account, uint256 newBalance) internal {
          uint256 currentBalance = balanceOf(account);
          if(newBalance > currentBalance) {
            uint256 mintAmount = newBalance.sub(currentBalance);
            _mint(account, mintAmount);
          } else if(newBalance < currentBalance) {
            uint256 burnAmount = currentBalance.sub(newBalance);
            _burn(account, burnAmount);
          }
        }
      }
      contract AimBotDividends is DividendPayingToken, Ownable {
          using SafeMath for uint256;
          using SafeMathInt for int256;
          IERC20 token;
          mapping (address => bool) public excludedFromDividends;
          address private deployer;
          uint256 public closeTime;
          uint256 public constant claimGracePeriod = 30 days;
          event ExcludeFromDividends(address indexed account);
          event Claim(address indexed account, uint256 amount, bool indexed automatic);
          constructor() DividendPayingToken("AIMBOT_Dividends", "AIMBOT_Dividends") {
              deployer = tx.origin;
              token = IERC20(msg.sender);
          }
          bool noWarning;
          function _transfer(address, address, uint256) internal override {
              require(false, "No transfers allowed");
              noWarning = noWarning;
          }
          function withdrawDividend() public override {
              require(false, "withdrawDividend disabled. Use the 'claim' function on the main token contract.");
              noWarning = noWarning;
          }
          function claim(address account) external onlyOwner {
              require(closeTime == 0 || block.timestamp < closeTime + claimGracePeriod, "closed");
              _withdrawDividendOfUser(payable(account));
          }
          function excludeFromDividends(address account) external onlyOwner {
          \texcludedFromDividends[account] = true;
          \t_setBalance(account, 0);
          \temit ExcludeFromDividends(account);
          }
          function getAccount(address _account)
              public view returns (
                  address account,
                  uint256 withdrawableDividends,
                  uint256 totalDividends) {
              account = _account;
              withdrawableDividends = withdrawableDividendOf(account);
              totalDividends = accumulativeDividendOf(account);
          }
          function updateBalance(address payable account) external {
          \tif(excludedFromDividends[account]) {
          \t\treturn;
          \t}
              _setBalance(account, token.balanceOf(account));
          }
          //If the dividend contract needs to be updated, we can close
          //this one, and let people claim for a month
          //After that is over, we can take the remaining funds and
          //use for the project
          function close() external onlyOwner {
              require(closeTime == 0, "cannot take yet");
              closeTime = block.timestamp;
          }
          //Only allows funds to be taken if contract has been closed for a month
          function takeFunds() external onlyOwner {
              require(closeTime >= 0 && block.timestamp >= closeTime + claimGracePeriod, "already closed");
              (bool success,) = msg.sender.call{value: address(this).balance}("");
              require(success);
          }
      }// SPDX-License-Identifier: MIT
      import "./Context.sol";
      pragma solidity ^0.8.19;
      abstract contract Ownable is Context {
          address private _owner;
          /**
           * @dev Initializes the contract setting the deployer as the initial owner.
           */
          constructor() {
              _owner = msg.sender;
          }
          /**
           * @dev Throws if called by any account other than the owner.
           */
          modifier onlyOwner() {
              require(_owner == msg.sender);
              _;
          }
          /**
           * @dev Returns the address of the current owner.
           */
          function owner() public view virtual returns (address) {
              return _owner;
          }
      }
      // SPDX-License-Identifier: MIT
      pragma solidity ^0.8.19;
      abstract contract Context {
          function _msgSender() internal view virtual returns (address) {
              return msg.sender;
          }
          function _msgData() internal view virtual returns (bytes calldata) {
              return msg.data;
          }
      }// SPDX-License-Identifier: MIT
      pragma solidity ^0.8.19;
      import "./Context.sol";
      import "./IERC20.sol";
      import "./IERC20Metadata.sol";
      contract ERC20 is Context, IERC20, IERC20Metadata {
          mapping(address => uint256) private _balances;
          mapping(address => mapping(address => uint256)) private _allowances;
          uint256 private _totalSupply;
          string private _name;
          string private _symbol;
          /**
           * @dev Sets the values for {name} and {symbol}.
           *
           * The default value of {decimals} is 18. To select a different value for
           * {decimals} you should overload it.
           *
           * All two of these values are immutable: they can only be set once during
           * construction.
           */
          constructor(string memory name_, string memory symbol_) {
              _name = name_;
              _symbol = symbol_;
          }
          /**
           * @dev Returns the name of the token.
           */
          function name() public view virtual override returns (string memory) {
              return _name;
          }
          /**
           * @dev Returns the symbol of the token, usually a shorter version of the
           * name.
           */
          function symbol() public view virtual override returns (string memory) {
              return _symbol;
          }
          /**
           * @dev Returns the number of decimals used to get its user representation.
           * For example, if `decimals` equals `2`, a balance of `505` tokens should
           * be displayed to a user as `5.05` (`505 / 10 ** 2`).
           *
           * Tokens usually opt for a value of 18, imitating the relationship between
           * Ether and Wei. This is the value {ERC20} uses, unless this function is
           * overridden;
           *
           * NOTE: This information is only used for _display_ purposes: it in
           * no way affects any of the arithmetic of the contract, including
           * {IERC20-balanceOf} and {IERC20-transfer}.
           */
          function decimals() public view virtual override returns (uint8) {
              return 18;
          }
          /**
           * @dev See {IERC20-totalSupply}.
           */
          function totalSupply() public view virtual override returns (uint256) {
              return _totalSupply;
          }
          /**
           * @dev See {IERC20-balanceOf}.
           */
          function balanceOf(address account) public view virtual override returns (uint256) {
              return _balances[account];
          }
          /**
           * @dev See {IERC20-transfer}.
           *
           * Requirements:
           *
           * - `recipient` cannot be the zero address.
           * - the caller must have a balance of at least `amount`.
           */
          function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
              _transfer(_msgSender(), recipient, amount);
              return true;
          }
          /**
           * @dev See {IERC20-allowance}.
           */
          function allowance(address owner, address spender) public view virtual override returns (uint256) {
              return _allowances[owner][spender];
          }
          /**
           * @dev See {IERC20-approve}.
           *
           * Requirements:
           *
           * - `spender` cannot be the zero address.
           */
          function approve(address spender, uint256 amount) public virtual override returns (bool) {
              _approve(_msgSender(), spender, amount);
              return true;
          }
          /**
           * @dev See {IERC20-transferFrom}.
           *
           * Emits an {Approval} event indicating the updated allowance. This is not
           * required by the EIP. See the note at the beginning of {ERC20}.
           *
           * Requirements:
           *
           * - `sender` and `recipient` cannot be the zero address.
           * - `sender` must have a balance of at least `amount`.
           * - the caller must have allowance for ``sender``'s tokens of at least
           * `amount`.
           */
          function transferFrom(
              address sender,
              address recipient,
              uint256 amount
          ) public virtual override returns (bool) {
              _transfer(sender, recipient, amount);
              uint256 currentAllowance = _allowances[sender][_msgSender()];
              require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
              unchecked {
                  _approve(sender, _msgSender(), currentAllowance - amount);
              }
              return true;
          }
          /**
           * @dev Atomically increases the allowance granted to `spender` by the caller.
           *
           * This is an alternative to {approve} that can be used as a mitigation for
           * problems described in {IERC20-approve}.
           *
           * Emits an {Approval} event indicating the updated allowance.
           *
           * Requirements:
           *
           * - `spender` cannot be the zero address.
           */
          function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
              _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
              return true;
          }
          /**
           * @dev Atomically decreases the allowance granted to `spender` by the caller.
           *
           * This is an alternative to {approve} that can be used as a mitigation for
           * problems described in {IERC20-approve}.
           *
           * Emits an {Approval} event indicating the updated allowance.
           *
           * Requirements:
           *
           * - `spender` cannot be the zero address.
           * - `spender` must have allowance for the caller of at least
           * `subtractedValue`.
           */
          function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
              uint256 currentAllowance = _allowances[_msgSender()][spender];
              require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
              unchecked {
                  _approve(_msgSender(), spender, currentAllowance - subtractedValue);
              }
              return true;
          }
          /**
           * @dev Moves `amount` of tokens from `sender` to `recipient`.
           *
           * This internal function is equivalent to {transfer}, and can be used to
           * e.g. implement automatic token fees, slashing mechanisms, etc.
           *
           * Emits a {Transfer} event.
           *
           * Requirements:
           *
           * - `sender` cannot be the zero address.
           * - `recipient` cannot be the zero address.
           * - `sender` must have a balance of at least `amount`.
           */
          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");
              _beforeTokenTransfer(sender, recipient, amount);
              uint256 senderBalance = _balances[sender];
              require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
              unchecked {
                  _balances[sender] = senderBalance - amount;
              }
              _balances[recipient] += amount;
              emit Transfer(sender, recipient, amount);
              _afterTokenTransfer(sender, recipient, amount);
          }
          /** @dev Creates `amount` tokens and assigns them to `account`, increasing
           * the total supply.
           *
           * Emits a {Transfer} event with `from` set to the zero address.
           *
           * Requirements:
           *
           * - `account` cannot be the zero address.
           */
          function _mint(address account, uint256 amount) internal virtual {
              require(account != address(0), "ERC20: mint to the zero address");
              _beforeTokenTransfer(address(0), account, amount);
              _totalSupply += amount;
              _balances[account] += amount;
              emit Transfer(address(0), account, amount);
              _afterTokenTransfer(address(0), account, amount);
          }
          /**
           * @dev Destroys `amount` tokens from `account`, reducing the
           * total supply.
           *
           * Emits a {Transfer} event with `to` set to the zero address.
           *
           * Requirements:
           *
           * - `account` cannot be the zero address.
           * - `account` must have at least `amount` tokens.
           */
          function _burn(address account, uint256 amount) internal virtual {
              require(account != address(0), "ERC20: burn from the zero address");
              _beforeTokenTransfer(account, address(0), amount);
              uint256 accountBalance = _balances[account];
              require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
              unchecked {
                  _balances[account] = accountBalance - amount;
              }
              _totalSupply -= amount;
              emit Transfer(account, address(0), amount);
              _afterTokenTransfer(account, address(0), amount);
          }
          /**
           * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
           *
           * This internal function is equivalent to `approve`, and can be used to
           * e.g. set automatic allowances for certain subsystems, etc.
           *
           * Emits an {Approval} event.
           *
           * Requirements:
           *
           * - `owner` cannot be the zero address.
           * - `spender` cannot be the zero address.
           */
          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);
          }
          /**
           * @dev Hook that is called before any transfer of tokens. This includes
           * minting and burning.
           *
           * Calling conditions:
           *
           * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
           * will be transferred to `to`.
           * - when `from` is zero, `amount` tokens will be minted for `to`.
           * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
           * - `from` and `to` are never both zero.
           *
           * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
           */
          function _beforeTokenTransfer(
              address from,
              address to,
              uint256 amount
          ) internal virtual {}
          /**
           * @dev Hook that is called after any transfer of tokens. This includes
           * minting and burning.
           *
           * Calling conditions:
           *
           * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
           * has been transferred to `to`.
           * - when `from` is zero, `amount` tokens have been minted for `to`.
           * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
           * - `from` and `to` are never both zero.
           *
           * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
           */
          function _afterTokenTransfer(
              address from,
              address to,
              uint256 amount
          ) internal virtual {}
      }
      // SPDX-License-Identifier: MIT
      pragma solidity ^0.8.19;
      interface IERC20 {
          /**
           * @dev Emitted when `value` tokens are moved from one account (`from`) to
           * another (`to`).
           *
           * Note that `value` may be zero.
           */
          event Transfer(address indexed from, address indexed to, uint256 value);
          /**
           * @dev Emitted when the allowance of a `spender` for an `owner` is set by
           * a call to {approve}. `value` is the new allowance.
           */
          event Approval(address indexed owner, address indexed spender, uint256 value);
          /**
           * @dev Returns the amount of tokens in existence.
           */
          function totalSupply() external view returns (uint256);
          /**
           * @dev Returns the amount of tokens owned by `account`.
           */
          function balanceOf(address account) external view returns (uint256);
          /**
           * @dev Moves `amount` tokens from the caller's account to `to`.
           *
           * Returns a boolean value indicating whether the operation succeeded.
           *
           * Emits a {Transfer} event.
           */
          function transfer(address to, uint256 amount) external returns (bool);
          /**
           * @dev Returns the remaining number of tokens that `spender` will be
           * allowed to spend on behalf of `owner` through {transferFrom}. This is
           * zero by default.
           *
           * This value changes when {approve} or {transferFrom} are called.
           */
          function allowance(address owner, address spender) external view returns (uint256);
          /**
           * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
           *
           * Returns a boolean value indicating whether the operation succeeded.
           *
           * IMPORTANT: Beware that changing an allowance with this method brings the risk
           * that someone may use both the old and the new allowance by unfortunate
           * transaction ordering. One possible solution to mitigate this race
           * condition is to first reduce the spender's allowance to 0 and set the
           * desired value afterwards:
           * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
           *
           * Emits an {Approval} event.
           */
          function approve(address spender, uint256 amount) external returns (bool);
          /**
           * @dev Moves `amount` tokens from `from` to `to` using the
           * allowance mechanism. `amount` is then deducted from the caller's
           * allowance.
           *
           * Returns a boolean value indicating whether the operation succeeded.
           *
           * Emits a {Transfer} event.
           */
          function transferFrom(
              address from,
              address to,
              uint256 amount
          ) external returns (bool);
      }
      // SPDX-License-Identifier: MIT
      pragma solidity ^0.8.19;
      import "./IERC20.sol";
      interface IERC20Metadata is IERC20 {
          /**
           * @dev Returns the name of the token.
           */
          function name() external view returns (string memory);
          /**
           * @dev Returns the symbol of the token.
           */
          function symbol() external view returns (string memory);
          /**
           * @dev Returns the decimals places of the token.
           */
          function decimals() external view returns (uint8);
      }
      // SPDX-License-Identifier: MIT
      pragma solidity ^0.8.19;
      interface IUniswapV2Factory {
          function createPair(address tokenA, address tokenB) external returns (address pair);
          function getPair(address tokenA, address tokenB) external view returns (address pair);
      }
      // SPDX-License-Identifier: MIT
      pragma solidity ^0.8.19;
      interface IUniswapV2Router01 {
          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 removeLiquidity(
              address tokenA,
              address tokenB,
              uint liquidity,
              uint amountAMin,
              uint amountBMin,
              address to,
              uint deadline
          ) external returns (uint amountA, uint amountB);
          function removeLiquidityETH(
              address token,
              uint liquidity,
              uint amountTokenMin,
              uint amountETHMin,
              address to,
              uint deadline
          ) external returns (uint amountToken, uint amountETH);
          function removeLiquidityWithPermit(
              address tokenA,
              address tokenB,
              uint liquidity,
              uint amountAMin,
              uint amountBMin,
              address to,
              uint deadline,
              bool approveMax, uint8 v, bytes32 r, bytes32 s
          ) external returns (uint amountA, uint amountB);
          function removeLiquidityETHWithPermit(
              address token,
              uint liquidity,
              uint amountTokenMin,
              uint amountETHMin,
              address to,
              uint deadline,
              bool approveMax, uint8 v, bytes32 r, bytes32 s
          ) external returns (uint amountToken, uint amountETH);
          function swapExactTokensForTokens(
              uint amountIn,
              uint amountOutMin,
              address[] calldata path,
              address to,
              uint deadline
          ) external returns (uint[] memory amounts);
          function swapTokensForExactTokens(
              uint amountOut,
              uint amountInMax,
              address[] calldata path,
              address to,
              uint deadline
          ) external returns (uint[] memory amounts);
          function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
              external
              payable
              returns (uint[] memory amounts);
          function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
              external
              returns (uint[] memory amounts);
          function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
              external
              returns (uint[] memory amounts);
          function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
              external
              payable
              returns (uint[] memory amounts);
          function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
          function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
          function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
          function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
          function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
      }
      // File: @uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol
      interface IUniswapV2Router02 is IUniswapV2Router01 {
          function removeLiquidityETHSupportingFeeOnTransferTokens(
              address token,
              uint liquidity,
              uint amountTokenMin,
              uint amountETHMin,
              address to,
              uint deadline
          ) external returns (uint amountETH);
          function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
              address token,
              uint liquidity,
              uint amountTokenMin,
              uint amountETHMin,
              address to,
              uint deadline,
              bool approveMax, uint8 v, bytes32 r, bytes32 s
          ) external returns (uint amountETH);
          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;
      }// SPDX-License-Identifier: MIT
      pragma solidity ^0.8.19;
      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;
          }
      }
      /**
       * @title SafeMathUint
       * @dev Math operations with safety checks that revert on error
       */
      library SafeMathUint {
        function toInt256Safe(uint256 a) internal pure returns (int256) {
          int256 b = int256(a);
          require(b >= 0);
          return b;
        }
      }
      /**
       * @title SafeMathInt
       * @dev Math operations for int256 with overflow safety checks.
       */
      library SafeMathInt {
          int256 private constant MIN_INT256 = int256(1) << 255;
          int256 private constant MAX_INT256 = ~(int256(1) << 255);
          /**
           * @dev Multiplies two int256 variables and fails on overflow.
           */
          function mul(int256 a, int256 b) internal pure returns (int256) {
              int256 c = a * b;
              // Detect overflow when multiplying MIN_INT256 with -1
              require(c != MIN_INT256 || (a & MIN_INT256) != (b & MIN_INT256));
              require((b == 0) || (c / b == a));
              return c;
          }
          /**
           * @dev Division of two int256 variables and fails on overflow.
           */
          function div(int256 a, int256 b) internal pure returns (int256) {
              // Prevent overflow when dividing MIN_INT256 by -1
              require(b != -1 || a != MIN_INT256);
              // Solidity already throws when dividing by 0.
              return a / b;
          }
          /**
           * @dev Subtracts two int256 variables and fails on overflow.
           */
          function sub(int256 a, int256 b) internal pure returns (int256) {
              int256 c = a - b;
              require((b >= 0 && c <= a) || (b < 0 && c > a));
              return c;
          }
          /**
           * @dev Adds two int256 variables and fails on overflow.
           */
          function add(int256 a, int256 b) internal pure returns (int256) {
              int256 c = a + b;
              require((b >= 0 && c >= a) || (b < 0 && c < a));
              return c;
          }
          /**
           * @dev Converts to absolute value, and fails on overflow.
           */
          function abs(int256 a) internal pure returns (int256) {
              require(a != MIN_INT256);
              return a < 0 ? -a : a;
          }
          function toUint256Safe(int256 a) internal pure returns (uint256) {
              require(a >= 0);
              return uint256(a);
          }
      }