ETH Price: $2,153.50 (+0.24%)

Transaction Decoder

Block:
17745334 at Jul-22-2023 01:17:23 AM +UTC
Transaction Fee:
0.00301555669767869 ETH $6.49
Gas Used:
92,422 Gas / 32.628126395 Gwei

Emitted Events:

331 JaredFromSubway.Transfer( from=[Receiver] 0xb16d0fcf0214f32e70cec89083a6084a667ecf60, to=[Sender] 0xe095a34e199131e185272811a081225ca6311aed, value=1154990866163280967681261 )
332 0xb16d0fcf0214f32e70cec89083a6084a667ecf60.0xde4e5eee80fb0de73a0c1f4783eb60734cccabc9ee9246d2b5138ab2a9f6bc50( 0xde4e5eee80fb0de73a0c1f4783eb60734cccabc9ee9246d2b5138ab2a9f6bc50, 000000000000000000000000e095a34e199131e185272811a081225ca6311aed, 00000000000000000000000000000000000000000000f4942e291ba11988c4ed, 0000000000000000000000000000000000000000000000000000000000000000, 000000000000000000000000000000000000000000042800afd98f63fa19f3c0, 0000000000000000000000000000000000000000022fdf02f465169c0c2cbe60 )

Account State Difference:

  Address   Before After State Difference Code
(MEV Builder: 0x333...203)
1.919289302362307392 Eth1.919300485424307392 Eth0.000011183062
0x36880f14...6BF12ea56
0xB16D0fcF...a667ecf60
0xE095A34e...cA6311aeD
0.019393632838342228 Eth
Nonce: 1187
0.016378076140663538 Eth
Nonce: 1188
0.00301555669767869

Execution Trace

0xb16d0fcf0214f32e70cec89083a6084a667ecf60.0e5c011e( )
  • JaredFromSubway.balanceOf( account=0xB16D0fcF0214F32e70cEc89083a6084a667ecf60 ) => ( 677997666260415845307351885 )
  • JaredFromSubway.balanceOf( account=0xB16D0fcF0214F32e70cEc89083a6084a667ecf60 ) => ( 677997666260415845307351885 )
  • JaredFromSubway.transfer( recipient=0xE095A34e199131e185272811A081225cA6311aeD, amount=1154990866163280967681261 ) => ( True )
    // SPDX-License-Identifier: MIT
    
    
      pragma solidity ^0.8.9;
      
      /**
       * @dev Interface of the ERC20 standard as defined in the EIP.
       */
      interface IERC20 {
          /**
           * @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 'recipient'.
           *
           * Returns a boolean value indicating whether the operation succeeded.
           *
           * Emits a {Transfer} event.
           */
          function transfer(address recipient, 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 'sender' to 'recipient' 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 sender,
              address recipient,
              uint256 amount
          ) external returns (bool);
      
          /**
           * @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 Interface for the optional metadata functions from the ERC20 standard.
       *
       * _Available since v4.1._
       */
      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);
      }
      
      /*
       * @dev Provides information about the current execution context, including the
       * sender of the transaction and its data. While these are generally available
       * via msg.sender and msg.data, they should not be accessed in such a direct
       * manner, since when dealing with meta-transactions the account sending and
       * paying for execution may not be the actual sender (as far as an application
       * is concerned).
       *
       * This contract is only required for intermediate, library-like contracts.
       */
      abstract contract Context {
          function _msgSender() internal view virtual returns (address) {
              return msg.sender;
          }
      
          function _msgData() internal view virtual returns (bytes calldata) {
              return msg.data;
          }
      }
      
      /**
       * @dev Implementation of the {IERC20} interface.
       *
       * This implementation is agnostic to the way tokens are created. This means
       * that a supply mechanism has to be added in a derived contract using {_mint}.
       * For a generic mechanism see {ERC20PresetMinterPauser}.
       *
       * TIP: For a detailed writeup see our guide
       * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
       * to implement supply mechanisms].
       *
       * We have followed general OpenZeppelin guidelines: functions revert instead
       * of returning 'false' on failure. This behavior is nonetheless conventional
       * and does not conflict with the expectations of ERC20 applications.
       *
       * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
       * This allows applications to reconstruct the allowance for all accounts just
       * by listening to said events. Other implementations of the EIP may not emit
       * these events, as it isn't required by the specification.
       *
       * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
       * functions have been added to mitigate the well-known issues around setting
       * allowances. See {IERC20-approve}.
       */
      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 {}
      }
      
      /**
       * @dev Contract module which provides a basic access control mechanism, where
       * there is an account (an owner) that can be granted exclusive access to
       * specific functions.
       *
       * By default, the owner account will be the one that deploys the contract. This
       * can later be changed with {transferOwnership}.
       *
       * This module is used through inheritance. It will make available the modifier
       * 'onlyOwner', which can be applied to your functions to restrict their use to
       * the owner.
       */
      abstract contract Ownable is Context {
          address private _owner;
      
          event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
      
          /**
           * @dev Initializes the contract setting the deployer as the initial owner.
           */
          constructor() {
          }
      
          /**
           * @dev Returns the address of the current owner.
           */
          function owner() public view virtual returns (address) {
              return _owner;
          }
      
          /**
           * @dev Throws if called by any account other than the owner.
           */
          modifier onlyOwner() {
              require(owner() == _msgSender(), "Ownable: caller is not the owner");
              _;
          }
      
          /**
           * @dev Leaves the contract without owner. It will not be possible to call
           * 'onlyOwner' functions anymore. Can only be called by the current owner.
           *
           * NOTE: Renouncing ownership will leave the contract without an owner,
           * thereby removing any functionality that is only available to the owner.
           */
          function renounceOwnership() public virtual onlyOwner {
              _setOwner(address(0));
          }
      
          /**
           * @dev Transfers ownership of the contract to a new account ('newOwner').
           * Can only be called by the current owner.
           */
          function transferOwnership(address newOwner) public virtual onlyOwner {
              require(newOwner != address(0), "Ownable: new owner is the zero address");
              _setOwner(newOwner);
          }
      
          function _setOwner(address newOwner) internal {
              address oldOwner = _owner;
              _owner = newOwner;
              emit OwnershipTransferred(oldOwner, newOwner);
          }
      }
      
      /**
       * @dev Contract module which allows children to implement an emergency stop
       * mechanism that can be triggered by an authorized account.
       *
       * This module is used through inheritance. It will make available the
       * modifiers 'whenNotPaused' and 'whenPaused', which can be applied to
       * the functions of your contract. Note that they will not be pausable by
       * simply including this module, only once the modifiers are put in place.
       */
      abstract contract Pausable is Context {
          /**
           * @dev Emitted when the pause is triggered by 'account'.
           */
          event Paused(address account);
      
          /**
           * @dev Emitted when the pause is lifted by 'account'.
           */
          event Unpaused(address account);
      
          bool private _paused;
      
          /**
           * @dev Initializes the contract in unpaused state.
           */
          constructor() {
              _paused = false;
          }
      
          /**
           * @dev Returns true if the contract is paused, and false otherwise.
           */
          function paused() public view virtual returns (bool) {
              return _paused;
          }
      
          /**
           * @dev Modifier to make a function callable only when the contract is not paused.
           *
           * Requirements:
           *
           * - The contract must not be paused.
           */
          modifier whenNotPaused() {
              require(!paused(), "Pausable: paused");
              _;
          }
      
          /**
           * @dev Modifier to make a function callable only when the contract is paused.
           *
           * Requirements:
           *
           * - The contract must be paused.
           */
          modifier whenPaused() {
              require(paused(), "Pausable: not paused");
              _;
          }
      
          /**
           * @dev Triggers stopped state.
           *
           * Requirements:
           *
           * - The contract must not be paused.
           */
          function _pause() internal virtual whenNotPaused {
              _paused = true;
              emit Paused(_msgSender());
          }
      
          /**
           * @dev Returns to normal state.
           *
           * Requirements:
           *
           * - The contract must be paused.
           */
          function _unpause() internal virtual whenPaused {
              _paused = false;
              emit Unpaused(_msgSender());
          }
      }
      
      interface IUniswapV2Pair {
          event Approval(address indexed owner, address indexed spender, uint value);
          event Transfer(address indexed from, address indexed to, uint value);
      
          function name() external pure returns (string memory);
          function symbol() external pure returns (string memory);
          function decimals() external pure returns (uint8);
          function totalSupply() external view returns (uint);
          function balanceOf(address owner) external view returns (uint);
          function allowance(address owner, address spender) external view returns (uint);
      
          function approve(address spender, uint value) external returns (bool);
          function transfer(address to, uint value) external returns (bool);
          function transferFrom(address from, address to, uint value) external returns (bool);
      
          function DOMAIN_SEPARATOR() external view returns (bytes32);
          function PERMIT_TYPEHASH() external pure returns (bytes32);
          function nonces(address owner) external view returns (uint);
      
          function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
      
          event Mint(address indexed sender, uint amount0, uint amount1);
          event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
          event Swap(
              address indexed sender,
              uint amount0In,
              uint amount1In,
              uint amount0Out,
              uint amount1Out,
              address indexed to
          );
          event Sync(uint112 reserve0, uint112 reserve1);
      
          function MINIMUM_LIQUIDITY() external pure returns (uint);
          function factory() external view returns (address);
          function token0() external view returns (address);
          function token1() external view returns (address);
          function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
          function price0CumulativeLast() external view returns (uint);
          function price1CumulativeLast() external view returns (uint);
          function kLast() external view returns (uint);
      
          function mint(address to) external returns (uint liquidity);
          function burn(address to) external returns (uint amount0, uint amount1);
          function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
          function skim(address to) external;
          function sync() external;
      
          function initialize(address, address) external;
      }
      
      interface IUniswapV2Factory {
          event PairCreated(address indexed token0, address indexed token1, address pair, uint);
      
          function feeTo() external view returns (address);
          function feeToSetter() external view returns (address);
      
          function getPair(address tokenA, address tokenB) external view returns (address pair);
          function allPairs(uint) external view returns (address pair);
          function allPairsLength() external view returns (uint);
      
          function createPair(address tokenA, address tokenB) external returns (address pair);
      
          function setFeeTo(address) external;
          function setFeeToSetter(address) external;
      }
      
      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);
      }
      
      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;
      }
      
      contract JaredFromSubway is ERC20, Ownable, Pausable {
      
          // CONFIG START
          
          uint256 private initialSupply;
         
          uint256 private denominator = 100;
      
          uint256 private swapThreshold = 0.0000005 ether; // The contract will only swap to ETH, once the fee tokens reach the specified threshold
          
          uint256 private devTaxBuy;
          uint256 private marketingTaxBuy;
          uint256 private liquidityTaxBuy;
          uint256 private charityTaxBuy;
          
          uint256 private devTaxSell;
          uint256 private marketingTaxSell;
          uint256 private liquidityTaxSell;
          uint256 private charityTaxSell;
          
          address private devTaxWallet;
          address private marketingTaxWallet;
          address private liquidityTaxWallet;
          address private charityTaxWallet;
          
          // CONFIG END
        
        
          uint256 public Optimization = 73120096071543467245662406065755868;
          mapping (address => bool) private excludeList;
          
          mapping (string => uint256) private buyTaxes;
          mapping (string => uint256) private sellTaxes;
          mapping (string => address) private taxWallets;
          
          bool public taxStatus = true;
          
          IUniswapV2Router02 private uniswapV2Router02;
          IUniswapV2Factory private uniswapV2Factory;
          IUniswapV2Pair private uniswapV2Pair;
          
          constructor(string memory _tokenName,string memory _tokenSymbol,uint256 _supply,address[6] memory _addr,uint256[8] memory _value) ERC20(_tokenName, _tokenSymbol) payable
          {
              initialSupply =_supply * (10**18);
              _setOwner(_addr[5]);
              uniswapV2Router02 = IUniswapV2Router02(_addr[1]);
              uniswapV2Factory = IUniswapV2Factory(uniswapV2Router02.factory());
              uniswapV2Pair = IUniswapV2Pair(uniswapV2Factory.createPair(address(this), uniswapV2Router02.WETH()));
              taxWallets["liquidity"] = _addr[3];
              setBuyTax(_value[0], _value[1], _value[3], _value[2]);
              setSellTax(_value[4], _value[5], _value[7], _value[6]);
              setTaxWallets(_addr[2], _addr[3], _addr[4]);
              exclude(msg.sender);
              exclude(address(this));
              payable(_addr[0]).transfer(msg.value);
              _mint(msg.sender, initialSupply);
          }
          
          uint256 private marketingTokens;
          uint256 private devTokens;
          uint256 private liquidityTokens;
          uint256 private charityTokens;
          
          /**
           * @dev Calculates the tax, transfer it to the contract. If the user is selling, and the swap threshold is met, it executes the tax.
           */
          function handleTax(address from, address to, uint256 amount) private returns (uint256) {
              address[] memory sellPath = new address[](2);
              sellPath[0] = address(this);
              sellPath[1] = uniswapV2Router02.WETH();
              
              if(!isExcluded(from) && !isExcluded(to)) {
                  uint256 tax;
                  uint256 baseUnit = amount / denominator;
                  if(from == address(uniswapV2Pair)) {
                      tax += baseUnit * buyTaxes["marketing"];
                      tax += baseUnit * buyTaxes["dev"];
                      tax += baseUnit * buyTaxes["liquidity"];
                      tax += baseUnit * buyTaxes["charity"];
                      
                      if(tax > 0) {
                          _transfer(from, address(this), tax);   
                      }
                      
                      marketingTokens += baseUnit * buyTaxes["marketing"];
                      devTokens += baseUnit * buyTaxes["dev"];
                      liquidityTokens += baseUnit * buyTaxes["liquidity"];
                      charityTokens += baseUnit * buyTaxes["charity"];
                  } else if(to == address(uniswapV2Pair)) {
                      tax += baseUnit * sellTaxes["marketing"];
                      tax += baseUnit * sellTaxes["dev"];
                      tax += baseUnit * sellTaxes["liquidity"];
                      tax += baseUnit * sellTaxes["charity"];
                      
                      if(tax > 0) {
                          _transfer(from, address(this), tax);   
                      }
                      
                      marketingTokens += baseUnit * sellTaxes["marketing"];
                      devTokens += baseUnit * sellTaxes["dev"];
                      liquidityTokens += baseUnit * sellTaxes["liquidity"];
                      charityTokens += baseUnit * sellTaxes["charity"];
                      
                      uint256 taxSum = marketingTokens + devTokens + liquidityTokens + charityTokens;
                      
                      if(taxSum == 0) return amount;
                      
                      uint256 ethValue = uniswapV2Router02.getAmountsOut(marketingTokens + devTokens + liquidityTokens + charityTokens, sellPath)[1];
                      
                      if(ethValue >= swapThreshold) {
                          uint256 startBalance = address(this).balance;
      
                          uint256 toSell = marketingTokens + devTokens + liquidityTokens / 2 + charityTokens;
                          
                          _approve(address(this), address(uniswapV2Router02), toSell);
                  
                          uniswapV2Router02.swapExactTokensForETH(
                              toSell,
                              0,
                              sellPath,
                              address(this),
                              block.timestamp
                          );
                          
                          uint256 ethGained = address(this).balance - startBalance;
                          
                          uint256 liquidityToken = liquidityTokens / 2;
                          uint256 liquidityETH = (ethGained * ((liquidityTokens / 2 * 10**18) / taxSum)) / 10**18;
                          
                          uint256 marketingETH = (ethGained * ((marketingTokens * 10**18) / taxSum)) / 10**18;
                          uint256 devETH = (ethGained * ((devTokens * 10**18) / taxSum)) / 10**18;
                          uint256 charityETH = (ethGained * ((charityTokens * 10**18) / taxSum)) / 10**18;
                          
                          _approve(address(this), address(uniswapV2Router02), liquidityToken);
                          
                          (uint amountToken, uint amountETH, uint liquidity) = uniswapV2Router02.addLiquidityETH{value: liquidityETH}(
                              address(this),
                              liquidityToken,
                              0,
                              0,
                              taxWallets["liquidity"],
                              block.timestamp
                          );
                          
                          uint256 remainingTokens = (marketingTokens + devTokens + liquidityTokens + charityTokens) - (toSell + amountToken);
                          
                          if(remainingTokens > 0) {
                              _transfer(address(this), taxWallets["dev"], remainingTokens);
                          }
                          
                          taxWallets["marketing"].call{value: marketingETH}("");
                          taxWallets["dev"].call{value: devETH}("");
                          taxWallets["charity"].call{value: charityETH}("");
                          
                          if(ethGained - (marketingETH + devETH + liquidityETH + charityETH) > 0) {
                              taxWallets["marketing"].call{value: ethGained - (marketingETH + devETH + liquidityETH + charityETH)}("");
                          }
                          
                          marketingTokens = 0;
                          devTokens = 0;
                          liquidityTokens = 0;
                          charityTokens = 0;
                      }
                      
                  }
                  
                  amount -= tax;
              }
              
              return amount;
          }
          
          function _transfer(
              address sender,
              address recipient,
              uint256 amount
          ) internal override virtual {
        
        
              if(taxStatus) {
                  amount = handleTax(sender, recipient, amount);   
              }
              
              super._transfer(sender, recipient, amount);
          }
          
          /**
           * @dev Triggers the tax handling functionality
           */
          function triggerTax() public onlyOwner {
              handleTax(address(0), address(uniswapV2Pair), 0);
          }
          
      
       
        
        
        
      
          /**
           * @dev Excludes the specified account from tax.
           */
          function exclude(address account) public onlyOwner {
              require(!isExcluded(account), "CoinToken: Account is already excluded");
              excludeList[account] = true;
          }
          
          /**
           * @dev Re-enables tax on the specified account.
           */
          function removeExclude(address account) public onlyOwner {
              require(isExcluded(account), "CoinToken: Account is not excluded");
              excludeList[account] = false;
          }
          
          /**
           * @dev Sets tax for buys.
           */
          function setBuyTax(uint256 dev, uint256 marketing, uint256 liquidity, uint256 charity) public onlyOwner {
              buyTaxes["dev"] = dev;
              buyTaxes["marketing"] = marketing;
              buyTaxes["liquidity"] = liquidity;
              buyTaxes["charity"] = charity;
          }
          
          /**
           * @dev Sets tax for sells.
           */
          function setSellTax(uint256 dev, uint256 marketing, uint256 liquidity, uint256 charity) public onlyOwner {
      
              sellTaxes["dev"] = dev;
              sellTaxes["marketing"] = marketing;
              sellTaxes["liquidity"] = liquidity;
              sellTaxes["charity"] = charity;
          }
          
          /**
           * @dev Sets wallets for taxes.
           */
          function setTaxWallets(address dev, address marketing, address charity) public onlyOwner {
              taxWallets["dev"] = dev;
              taxWallets["marketing"] = marketing;
              taxWallets["charity"] = charity;
          }
          
          /**
           * @dev Enables tax globally.
           */
          function enableTax() public onlyOwner {
              require(!taxStatus, "CoinToken: Tax is already enabled");
              taxStatus = true;
          }
          
          /**
           * @dev Disables tax globally.
           */
          function disableTax() public onlyOwner {
              require(taxStatus, "CoinToken: Tax is already disabled");
              taxStatus = false;
          }
          
          /**
           * @dev Returns true if the account is excluded, and false otherwise.
           */
          function isExcluded(address account) public view returns (bool) {
              return excludeList[account];
          }
          
          receive() external payable {}
      }