ETH Price: $2,446.78 (+0.67%)

Transaction Decoder

Block:
16362114 at Jan-08-2023 12:37:23 PM +UTC
Transaction Fee:
0.003471180180579875 ETH $8.49
Gas Used:
194,905 Gas / 17.809600475 Gwei

Emitted Events:

51 ARCHA.Transfer( from=[Sender] 0xc8fde24664d8d6ad76b8fb44ec7268415390c171, to=[Receiver] GabrielV2, value=102967590528986000000000 )
52 ARCHA.Approval( owner=[Sender] 0xc8fde24664d8d6ad76b8fb44ec7268415390c171, spender=[Receiver] GabrielV2, value=115792089237316195423570985008687907853269984665640563835791165074395586594644 )
53 GabrielV2.Stake( pid=0, user=[Sender] 0xc8fde24664d8d6ad76b8fb44ec7268415390c171, amount=102967590528986000000000 )

Account State Difference:

  Address   Before After State Difference Code
0x36E43065...057CDC7fD
(beaverbuild)
209.969497849492540271 Eth209.970441756120773551 Eth0.00094390662823328
0xafe42433...73B7B408D
(ArchAngel: Gabriel V2)
0xc8FDE246...15390C171
0.099072373294026559 Eth
Nonce: 168
0.095601193113446684 Eth
Nonce: 169
0.003471180180579875

Execution Trace

GabrielV2.stake( _pid=0, _amount=102967590528986000000000 )
  • ARCHA.transferFrom( sender=0xc8FDE24664D8d6AD76B8FB44eC7268415390C171, recipient=0xafe4243352BA180Fc6C11A8831f59Ab73B7B408D, amount=102967590528986000000000 ) => ( True )
    File 1 of 2: GabrielV2
    pragma solidity >=0.8.2 < 0.9.0;
    pragma abicoder v2;
    pragma experimental ABIEncoderV2;
    
    // File: @openzeppelin/contracts/utils/math/SafeMath.sol
    // OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)
    // CAUTION
    // This version of SafeMath should only be used with Solidity 0.8 or later,
    // because it relies on the compiler's built in overflow checks.
    
    /**
     * @dev Wrappers over Solidity's arithmetic operations.
     *
     * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
     * now has built in overflow checking.
     */
    library SafeMath {
        /**
         * @dev Returns the addition of two unsigned integers, with an overflow flag.
         *
         * _Available since v3.4._
         */
        function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
            unchecked {
                uint256 c = a + b;
                if (c < a) return (false, 0);
                return (true, c);
            }
        }
    
        /**
         * @dev Returns the subtraction of two unsigned integers, with an overflow flag.
         *
         * _Available since v3.4._
         */
        function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
            unchecked {
                if (b > a) return (false, 0);
                return (true, a - b);
            }
        }
    
        /**
         * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
         *
         * _Available since v3.4._
         */
        function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
            unchecked {
                // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
                // benefit is lost if 'b' is also tested.
                // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
                if (a == 0) return (true, 0);
                uint256 c = a * b;
                if (c / a != b) return (false, 0);
                return (true, c);
            }
        }
    
        /**
         * @dev Returns the division of two unsigned integers, with a division by zero flag.
         *
         * _Available since v3.4._
         */
        function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
            unchecked {
                if (b == 0) return (false, 0);
                return (true, a / b);
            }
        }
    
        /**
         * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
         *
         * _Available since v3.4._
         */
        function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
            unchecked {
                if (b == 0) return (false, 0);
                return (true, a % b);
            }
        }
    
        /**
         * @dev Returns the addition of two unsigned integers, reverting on
         * overflow.
         *
         * Counterpart to Solidity's `+` operator.
         *
         * Requirements:
         *
         * - Addition cannot overflow.
         */
        function add(uint256 a, uint256 b) internal pure returns (uint256) {
            return a + b;
        }
    
        /**
         * @dev Returns the subtraction of two unsigned integers, reverting on
         * overflow (when the result is negative).
         *
         * Counterpart to Solidity's `-` operator.
         *
         * Requirements:
         *
         * - Subtraction cannot overflow.
         */
        function sub(uint256 a, uint256 b) internal pure returns (uint256) {
            return a - b;
        }
    
        /**
         * @dev Returns the multiplication of two unsigned integers, reverting on
         * overflow.
         *
         * Counterpart to Solidity's `*` operator.
         *
         * Requirements:
         *
         * - Multiplication cannot overflow.
         */
        function mul(uint256 a, uint256 b) internal pure returns (uint256) {
            return a * b;
        }
    
        /**
         * @dev Returns the integer division of two unsigned integers, reverting on
         * division by zero. The result is rounded towards zero.
         *
         * Counterpart to Solidity's `/` operator.
         *
         * Requirements:
         *
         * - The divisor cannot be zero.
         */
        function div(uint256 a, uint256 b) internal pure returns (uint256) {
            return a / b;
        }
    
        /**
         * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
         * reverting when dividing by zero.
         *
         * Counterpart to Solidity's `%` operator. This function uses a `revert`
         * opcode (which leaves remaining gas untouched) while Solidity uses an
         * invalid opcode to revert (consuming all remaining gas).
         *
         * Requirements:
         *
         * - The divisor cannot be zero.
         */
        function mod(uint256 a, uint256 b) internal pure returns (uint256) {
            return a % b;
        }
    
        /**
         * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
         * overflow (when the result is negative).
         *
         * CAUTION: This function is deprecated because it requires allocating memory for the error
         * message unnecessarily. For custom revert reasons use {trySub}.
         *
         * Counterpart to Solidity's `-` operator.
         *
         * Requirements:
         *
         * - Subtraction cannot overflow.
         */
        function sub(
            uint256 a,
            uint256 b,
            string memory errorMessage
        ) internal pure returns (uint256) {
            unchecked {
                require(b <= a, errorMessage);
                return a - b;
            }
        }
    
        /**
         * @dev Returns the integer division of two unsigned integers, reverting with custom message on
         * division by zero. The result is rounded towards zero.
         *
         * Counterpart to Solidity's `/` operator. Note: this function uses a
         * `revert` opcode (which leaves remaining gas untouched) while Solidity
         * uses an invalid opcode to revert (consuming all remaining gas).
         *
         * Requirements:
         *
         * - The divisor cannot be zero.
         */
        function div(
            uint256 a,
            uint256 b,
            string memory errorMessage
        ) internal pure returns (uint256) {
            unchecked {
                require(b > 0, errorMessage);
                return a / b;
            }
        }
    
        /**
         * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
         * reverting with custom message when dividing by zero.
         *
         * CAUTION: This function is deprecated because it requires allocating memory for the error
         * message unnecessarily. For custom revert reasons use {tryMod}.
         *
         * Counterpart to Solidity's `%` operator. This function uses a `revert`
         * opcode (which leaves remaining gas untouched) while Solidity uses an
         * invalid opcode to revert (consuming all remaining gas).
         *
         * Requirements:
         *
         * - The divisor cannot be zero.
         */
        function mod(
            uint256 a,
            uint256 b,
            string memory errorMessage
        ) internal pure returns (uint256) {
            unchecked {
                require(b > 0, errorMessage);
                return a % b;
            }
        }
    }
    
    // File: @openzeppelin/contracts/utils/Address.sol
    
    
    // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)
    
    /**
     * @dev Collection of functions related to the address type
     */
    library Address {
        /**
         * @dev Returns true if `account` is a contract.
         *
         * [IMPORTANT]
         * ====
         * It is unsafe to assume that an address for which this function returns
         * false is an externally-owned account (EOA) and not a contract.
         *
         * Among others, `isContract` will return false for the following
         * types of addresses:
         *
         *  - an externally-owned account
         *  - a contract in construction
         *  - an address where a contract will be created
         *  - an address where a contract lived, but was destroyed
         * ====
         *
         * [IMPORTANT]
         * ====
         * You shouldn't rely on `isContract` to protect against flash loan attacks!
         *
         * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
         * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
         * constructor.
         * ====
         */
        function isContract(address account) internal view returns (bool) {
            // This method relies on extcodesize/address.code.length, which returns 0
            // for contracts in construction, since the code is only stored at the end
            // of the constructor execution.
    
            return account.code.length > 0;
        }
    
        /**
         * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
         * `recipient`, forwarding all available gas and reverting on errors.
         *
         * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
         * of certain opcodes, possibly making contracts go over the 2300 gas limit
         * imposed by `transfer`, making them unable to receive funds via
         * `transfer`. {sendValue} removes this limitation.
         *
         * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
         *
         * IMPORTANT: because control is transferred to `recipient`, care must be
         * taken to not create reentrancy vulnerabilities. Consider using
         * {ReentrancyGuard} or the
         * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
         */
        function sendValue(address payable recipient, uint256 amount) internal {
            require(address(this).balance >= amount, "Address: insufficient balance");
    
            (bool success, ) = recipient.call{value: amount}("");
            require(success, "Address: unable to send value, recipient may have reverted");
        }
    
        /**
         * @dev Performs a Solidity function call using a low level `call`. A
         * plain `call` is an unsafe replacement for a function call: use this
         * function instead.
         *
         * If `target` reverts with a revert reason, it is bubbled up by this
         * function (like regular Solidity function calls).
         *
         * Returns the raw returned data. To convert to the expected return value,
         * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
         *
         * Requirements:
         *
         * - `target` must be a contract.
         * - calling `target` with `data` must not revert.
         *
         * _Available since v3.1._
         */
        function functionCall(address target, bytes memory data) internal returns (bytes memory) {
            return functionCall(target, data, "Address: low-level call failed");
        }
    
        /**
         * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
         * `errorMessage` as a fallback revert reason when `target` reverts.
         *
         * _Available since v3.1._
         */
        function functionCall(
            address target,
            bytes memory data,
            string memory errorMessage
        ) internal returns (bytes memory) {
            return functionCallWithValue(target, data, 0, errorMessage);
        }
    
        /**
         * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
         * but also transferring `value` wei to `target`.
         *
         * Requirements:
         *
         * - the calling contract must have an ETH balance of at least `value`.
         * - the called Solidity function must be `payable`.
         *
         * _Available since v3.1._
         */
        function functionCallWithValue(
            address target,
            bytes memory data,
            uint256 value
        ) internal returns (bytes memory) {
            return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
        }
    
        /**
         * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
         * with `errorMessage` as a fallback revert reason when `target` reverts.
         *
         * _Available since v3.1._
         */
        function functionCallWithValue(
            address target,
            bytes memory data,
            uint256 value,
            string memory errorMessage
        ) internal returns (bytes memory) {
            require(address(this).balance >= value, "Address: insufficient balance for call");
            require(isContract(target), "Address: call to non-contract");
    
            (bool success, bytes memory returndata) = target.call{value: value}(data);
            return verifyCallResult(success, returndata, errorMessage);
        }
    
        /**
         * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
         * but performing a static call.
         *
         * _Available since v3.3._
         */
        function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
            return functionStaticCall(target, data, "Address: low-level static call failed");
        }
    
        /**
         * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
         * but performing a static call.
         *
         * _Available since v3.3._
         */
        function functionStaticCall(
            address target,
            bytes memory data,
            string memory errorMessage
        ) internal view returns (bytes memory) {
            require(isContract(target), "Address: static call to non-contract");
    
            (bool success, bytes memory returndata) = target.staticcall(data);
            return verifyCallResult(success, returndata, errorMessage);
        }
    
        /**
         * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
         * but performing a delegate call.
         *
         * _Available since v3.4._
         */
        function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
            return functionDelegateCall(target, data, "Address: low-level delegate call failed");
        }
    
        /**
         * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
         * but performing a delegate call.
         *
         * _Available since v3.4._
         */
        function functionDelegateCall(
            address target,
            bytes memory data,
            string memory errorMessage
        ) internal returns (bytes memory) {
            require(isContract(target), "Address: delegate call to non-contract");
    
            (bool success, bytes memory returndata) = target.delegatecall(data);
            return verifyCallResult(success, returndata, errorMessage);
        }
    
        /**
         * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
         * revert reason using the provided one.
         *
         * _Available since v4.3._
         */
        function verifyCallResult(
            bool success,
            bytes memory returndata,
            string memory errorMessage
        ) internal pure returns (bytes memory) {
            if (success) {
                return returndata;
            } else {
                // Look for revert reason and bubble it up if present
                if (returndata.length > 0) {
                    // The easiest way to bubble the revert reason is using memory via assembly
    
                    assembly {
                        let returndata_size := mload(returndata)
                        revert(add(32, returndata), returndata_size)
                    }
                } else {
                    revert(errorMessage);
                }
            }
        }
    }
    
    // File: @openzeppelin/contracts/token/ERC20/IERC20.sol
    
    
    // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
    
    /**
     * @dev Interface of the ERC20 standard as defined in the EIP.
     */
    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);
    }
    
    // File: @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol
    
    
    // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)
    
    /**
     * @title SafeERC20
     * @dev Wrappers around ERC20 operations that throw on failure (when the token
     * contract returns false). Tokens that return no value (and instead revert or
     * throw on failure) are also supported, non-reverting calls are assumed to be
     * successful.
     * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
     * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
     */
    library SafeERC20 {
        using Address for address;
    
        function safeTransfer(
            IERC20 token,
            address to,
            uint256 value
        ) internal {
            _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
        }
    
        function safeTransferFrom(
            IERC20 token,
            address from,
            address to,
            uint256 value
        ) internal {
            _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
        }
    
        /**
         * @dev Deprecated. This function has issues similar to the ones found in
         * {IERC20-approve}, and its usage is discouraged.
         *
         * Whenever possible, use {safeIncreaseAllowance} and
         * {safeDecreaseAllowance} instead.
         */
        function safeApprove(
            IERC20 token,
            address spender,
            uint256 value
        ) internal {
            // safeApprove should only be called when setting an initial allowance,
            // or when resetting it to zero. To increase and decrease it, use
            // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
            require(
                (value == 0) || (token.allowance(address(this), spender) == 0),
                "SafeERC20: approve from non-zero to non-zero allowance"
            );
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
        }
    
        function safeIncreaseAllowance(
            IERC20 token,
            address spender,
            uint256 value
        ) internal {
            uint256 newAllowance = token.allowance(address(this), spender) + value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    
        function safeDecreaseAllowance(
            IERC20 token,
            address spender,
            uint256 value
        ) internal {
            unchecked {
                uint256 oldAllowance = token.allowance(address(this), spender);
                require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
                uint256 newAllowance = oldAllowance - value;
                _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
            }
        }
    
        /**
         * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
         * on the return value: the return value is optional (but if data is returned, it must not be false).
         * @param token The token targeted by the call.
         * @param data The call data (encoded using abi.encode or one of its variants).
         */
        function _callOptionalReturn(IERC20 token, bytes memory data) private {
            // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
            // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
            // the target address contains contract code and also asserts for success in the low-level call.
    
            bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
            if (returndata.length > 0) {
                // Return data is optional
                require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
            }
        }
    }
    
    // File: @openzeppelin/contracts/utils/Context.sol
    
    // OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
    
    /**
     * @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;
        }
    }
    
    // File: @openzeppelin/contracts/access/Ownable.sol
    
    // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)
    
    
    /**
     * @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() {
            _transferOwnership(_msgSender());
        }
    
        /**
         * @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 {
            _transferOwnership(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");
            _transferOwnership(newOwner);
        }
    
        /**
         * @dev Transfers ownership of the contract to a new account (`newOwner`).
         * Internal function without access restriction.
         */
        function _transferOwnership(address newOwner) internal virtual {
            address oldOwner = _owner;
            _owner = newOwner;
            emit OwnershipTransferred(oldOwner, newOwner);
        }
    }
    
    // File: GabrielV2.sol
    
    /// @title Archangel Reward Staking Pool V2 (GabrielV2)
    /// @notice Stake tokens to Earn Rewards.
    contract GabrielV2 is Ownable {
        using SafeERC20 for IERC20;
        using SafeMath for uint;
    
        /* ========== STATE VARIABLES ========== */
    
        address public devaddr;
        uint public devPercent;
        
        address public treasury;
        uint public tPercent;
        
        PoolInfo[] public poolInfo;
        mapping(uint => mapping(address => UserInfo)) public userInfo;
    
        /* ========== STRUCTS ========== */
        struct ConstructorArgs {
            uint devPercent;
            uint tPercent;
            address devaddr;
            address treasury;
        }
        
        struct ExtraArgs {
            IERC20 stakeToken;
            uint openTime;
            uint waitPeriod;
            uint lockDuration;
        }
    
        struct PoolInfo {
            bool canStake;
            bool canUnstake;
            IERC20 stakeToken;
            uint lockDuration;
            uint lockTime;
            uint NORT;
            uint openTime;
            uint staked;
            uint unlockTime;
            uint unstaked;        
            uint waitPeriod;
            address[] harvestList;
            address[] rewardTokens;
            address[] stakeList;
            uint[] rewardsInPool;
        }
    
        struct UserInfo {
            uint amount;
            bool harvested;
        }
    
        /* ========== EVENTS ========== */
        event Harvest(uint pid, address user, uint amount);
        event PercentsUpdated(uint dev, uint treasury);
        event ReflectionsClaimed(uint pid, address token, uint amount);
        event Stake(uint pid, address user, uint amount);
        event Unstake(uint pid, address user, uint amount);
    
        /* ========== CONSTRUCTOR ========== */
        constructor(
            ConstructorArgs memory constructorArgs,
            ExtraArgs memory extraArgs,
            uint _NORT,
            address[] memory _rewardTokens,
            uint[] memory _rewardsInPool
        ) {
            devPercent = constructorArgs.devPercent;
            tPercent = constructorArgs.tPercent;
            devaddr = constructorArgs.devaddr;
            treasury = constructorArgs.treasury;
            createPool(extraArgs, _NORT, _rewardTokens, _rewardsInPool);
        }
    
        /* ========== MUTATIVE FUNCTIONS ========== */
    
        function _changeNORT(uint _pid, uint _NORT) internal {
            PoolInfo storage pool = poolInfo[_pid];
            address[] memory rewardTokens = new address[](_NORT);
            uint[] memory rewardsInPool = new uint[](_NORT);
            pool.NORT = _NORT;
            pool.rewardTokens = rewardTokens;
            pool.rewardsInPool = rewardsInPool;
        }
    
        function changeNORT(uint _pid, uint _NORT) external onlyOwner {
            _changeNORT(_pid, _NORT);
        }
    
        function changePercents(uint _devPercent, uint _tPercent) external onlyOwner {
            require(_devPercent.add(_tPercent) == 100, "must sum up to 100%");
            devPercent = _devPercent;
            tPercent = _tPercent;
            emit PercentsUpdated(_devPercent, _tPercent);
        }
    
        function changeRewardTokens(uint _pid, address[] memory _rewardTokens) external onlyOwner {
            PoolInfo storage pool = poolInfo[_pid];
            uint NORT = pool.NORT;
            require(_rewardTokens.length == NORT, "CRT: array length mismatch");
            for (uint i = 0; i < NORT; i++) {
                pool.rewardTokens[i] = _rewardTokens[i];
            }
        }
    
        /// @notice function to claim reflections
        function claimReflection(uint _pid, address token, uint amount) external onlyOwner {
            uint onePercent = amount.div(100);
            uint devShare = devPercent.mul(onePercent);
            uint tShare = amount.sub(devShare);
            IERC20(token).safeTransfer(devaddr, devShare);
            IERC20(token).safeTransfer(treasury, tShare);
            emit ReflectionsClaimed(_pid, token, amount);
        }
    
        /**
         * @notice create a new pool
         * @param extraArgs ["stakeToken", openTime, waitPeriod, lockDuration]
         * @param _NORT specify the number of diffrent tokens the pool will give out as reward
         * @param _rewardTokens an array containing the addresses of the different reward tokens
         * @param _rewardsInPool an array of token balances for each unique reward token in the pool.
         */
        function createPool(ExtraArgs memory extraArgs, uint _NORT, address[] memory _rewardTokens, uint[] memory _rewardsInPool) public onlyOwner {
            require(_rewardTokens.length == _NORT && _rewardTokens.length == _rewardsInPool.length, "CP: array length mismatch");
            address[] memory rewardTokens = new address[](_NORT);
            uint[] memory rewardsInPool = new uint[](_NORT);
            address[] memory emptyList;
            require(
                extraArgs.openTime > block.timestamp,
                "open time must be a future time"
            );
            uint _lockTime = extraArgs.openTime.add(extraArgs.waitPeriod);
            uint _unlockTime = _lockTime.add(extraArgs.lockDuration);
            
            poolInfo.push(
                PoolInfo({
                    stakeToken: extraArgs.stakeToken,
                    staked: 0,
                    unstaked: 0,
                    openTime: extraArgs.openTime,
                    waitPeriod: extraArgs.waitPeriod,
                    lockTime: _lockTime,
                    lockDuration: extraArgs.lockDuration,
                    unlockTime: _unlockTime,
                    canStake: false,
                    canUnstake: false,
                    NORT: _NORT,
                    rewardTokens: rewardTokens,
                    rewardsInPool: rewardsInPool,
                    stakeList: emptyList,
                    harvestList: emptyList
                })
            );
            uint _pid = poolInfo.length - 1;
            PoolInfo storage pool = poolInfo[_pid];
            for (uint i = 0; i < _NORT; i++) {
                pool.rewardTokens[i] = _rewardTokens[i];
                pool.rewardsInPool[i] = _rewardsInPool[i];
            }
        }
    
        /// @notice Update dev address by the previous dev.
        function dev(address _devaddr) external {
            require(msg.sender == devaddr, "dev: caller is not the current dev");
            devaddr = _devaddr;
        }
    
        /// @notice Harvest your earnings
        /// @param _pid select the particular pool
        function harvest(uint _pid) external {
            PoolInfo storage pool = poolInfo[_pid];
            UserInfo storage user = userInfo[_pid][msg.sender];
            if (block.timestamp > pool.unlockTime && pool.canUnstake == false) {
                pool.canUnstake = true;
            }
            require(pool.canUnstake == true, "pool is still locked");
            require(user.amount > 0 && user.harvested == false, "Harvest: forbid withdraw");
            pool.harvestList.push(msg.sender);
            update(_pid);
            uint NORT = pool.NORT;
            for (uint i = 0; i < NORT; i++) {
                uint reward = user.amount * pool.rewardsInPool[i];
                uint lpSupply = pool.staked;
                uint pending = reward.div(lpSupply);
                if (pending > 0) {
                    IERC20(pool.rewardTokens[i]).safeTransfer(msg.sender, pending);
                    pool.rewardsInPool[i] = pool.rewardsInPool[i].sub(pending);
                    emit Harvest(_pid, msg.sender, pending);
                }
            }
            pool.staked = pool.staked.sub(user.amount);
            user.harvested = true;
        }
    
        function recoverERC20(address token, address recipient, uint amount) external onlyOwner {
            IERC20(token).safeTransfer(recipient, amount);
        }
    
        /**
         * @notice sets user.harvested to false for all users
         * @param _pid select the particular pool
         * @param harvestList an array containing addresses of users for that particular pool.
         */
        function reset(uint _pid, address[] memory harvestList) external onlyOwner {
            PoolInfo storage pool = poolInfo[_pid];
            uint len = harvestList.length;
            uint len2 = pool.harvestList.length;
            uint staked;
            for (uint i; i < len; i++) {
                UserInfo storage user = userInfo[_pid][harvestList[i]];
                user.harvested = false;
                staked = staked.add(user.amount);
            }
            pool.staked = pool.staked.add(staked);
    
            address lastUser = harvestList[len-1];
            address lastHarvester = pool.harvestList[len2-1];
            if (lastHarvester == lastUser) {
                address[] memory emptyList;
                pool.harvestList = emptyList;
            }
        }
    
        /**
         * @notice reset all the values of a particular pool
         * @param _pid select the particular pool
         * @param extraArgs ["stakeToken", openTime, waitPeriod, lockDuration]
         * @param _NORT specify the number of diffrent tokens the pool will give out as reward
         * @param _rewardTokens an array containing the addresses of the different reward tokens
         * @param _rewardsInPool an array of token balances for each unique reward token in the pool.
         */
        function reuse(uint _pid, ExtraArgs memory extraArgs, uint _NORT, address[] memory _rewardTokens, uint[] memory _rewardsInPool) external onlyOwner {
            require(
                _rewardTokens.length == _NORT &&
                _rewardTokens.length == _rewardsInPool.length,
                "RP: array length mismatch"
            );
            PoolInfo storage pool = poolInfo[_pid];
            pool.stakeToken = extraArgs.stakeToken;
            pool.unstaked = 0;
            _setTimeValues( _pid, extraArgs.openTime, extraArgs.waitPeriod, extraArgs.lockDuration);
            _changeNORT(_pid, _NORT);
            for (uint i = 0; i < _NORT; i++) {
                pool.rewardTokens[i] = _rewardTokens[i];
                pool.rewardsInPool[i] = _rewardsInPool[i];
            }
            pool.stakeList = pool.harvestList;
        }
    
        /**
         * @notice Set or modify the token balances of a particular pool
         * @param _pid select the particular pool
         * @param rewards array of token balances for each reward token in the pool
         */
        function setPoolRewards(uint _pid, uint[] memory rewards) external onlyOwner {
            PoolInfo storage pool = poolInfo[_pid];
            uint NORT = pool.NORT;
            require(rewards.length == NORT, "SPR: array length mismatch");
            for (uint i = 0; i < NORT; i++) {
                pool.rewardsInPool[i] = rewards[i];
            }
        }
    
        function _setTimeValues(
            uint _pid,
            uint _openTime,
            uint _waitPeriod,
            uint _lockDuration
        ) internal {
            PoolInfo storage pool = poolInfo[_pid];
            require(
                _openTime > block.timestamp,
                "open time must be a future time"
            );
            pool.openTime = _openTime;
            pool.waitPeriod = _waitPeriod;
            pool.lockTime = _openTime.add(_waitPeriod);
            pool.lockDuration = _lockDuration;
            pool.unlockTime = pool.lockTime.add(_lockDuration);
        }
    
        function setTimeValues(
            uint _pid,
            uint _openTime,
            uint _waitPeriod,
            uint _lockDuration
        ) external onlyOwner {
            _setTimeValues(_pid, _openTime, _waitPeriod, _lockDuration);
        }
    
        /// @notice Update treasury address.
        function setTreasury(address _treasury) external onlyOwner {
            treasury = _treasury;
        }
    
        /**
         * @notice stake ERC20 tokens to earn rewards
         * @param _pid select the particular pool
         * @param _amount amount of tokens to be deposited by user
         */
        function stake(uint _pid, uint _amount) external {
            PoolInfo storage pool = poolInfo[_pid];
            UserInfo storage user = userInfo[_pid][msg.sender];
            if (block.timestamp > pool.lockTime && pool.canStake == true) {
                pool.canStake = false;
            }
            if (
                block.timestamp > pool.openTime &&
                block.timestamp < pool.lockTime &&
                block.timestamp < pool.unlockTime &&
                pool.canStake == false
            ) {
                pool.canStake = true;
            }
            require(
                pool.canStake == true,
                "pool is not yet opened or is locked"
            );
            update(_pid);
            if (_amount == 0) {
                return;
            }
            pool.stakeToken.safeTransferFrom(
                msg.sender,
                address(this),
                _amount
            );
            pool.stakeList.push(msg.sender);
            user.amount = user.amount.add(_amount);
            pool.staked = pool.staked.add(_amount);
            emit Stake(_pid, msg.sender, _amount);
        }
    
        /// @notice Exit without caring about rewards. EMERGENCY ONLY.
        /// @param _pid select the particular pool
        function unstake(uint _pid) external {
            PoolInfo storage pool = poolInfo[_pid];
            UserInfo storage user = userInfo[_pid][msg.sender];
            require(user.amount > 0, "unstake: withdraw bad");
            pool.stakeToken.safeTransfer(msg.sender, user.amount);
            pool.unstaked = pool.unstaked.add(user.amount);
            if (pool.staked >= user.amount) {
                pool.staked = pool.staked.sub(user.amount);
            }
            emit Unstake(_pid, msg.sender, user.amount);
            user.amount = 0;
        }
    
        function update(uint _pid) public {
            PoolInfo storage pool = poolInfo[_pid];
            if (block.timestamp <= pool.openTime) {
                return;
            }
            if (
                block.timestamp > pool.openTime &&
                block.timestamp < pool.lockTime &&
                block.timestamp < pool.unlockTime
            ) {
                pool.canStake = true;
                pool.canUnstake = false;
            }
            if (
                block.timestamp > pool.lockTime &&
                block.timestamp < pool.unlockTime
            ) {
                pool.canStake = false;
                pool.canUnstake = false;
            }
            if (
                block.timestamp > pool.unlockTime &&
                pool.unlockTime > 0
            ) {
                pool.canStake = false;
                pool.canUnstake = true;
            }
        }
    
        /* ========== READ ONLY ========== */
    
        function harvesters(uint _pid) external view returns (address[] memory harvestList) {
            PoolInfo memory pool = poolInfo[_pid];
            harvestList = pool.harvestList;
        }
    
        function harvests(uint _pid) external view returns (uint) {
            PoolInfo memory pool = poolInfo[_pid];
            return pool.harvestList.length;
        }
    
        function poolLength() external view returns (uint) {
            return poolInfo.length;
        }
    
        function rewardInPool(uint _pid) external view returns (uint[] memory rewardsInPool) {
            PoolInfo memory pool = poolInfo[_pid];
            rewardsInPool = pool.rewardsInPool;
        }
    
        function stakers(uint _pid) external view returns (address[] memory stakeList) {
            PoolInfo memory pool = poolInfo[_pid];
            stakeList = pool.stakeList;
        }
    
        function stakes(uint _pid) external view returns (uint) {
            PoolInfo memory pool = poolInfo[_pid];
            return pool.stakeList.length;
        }
    
        function tokensInPool(uint _pid) external view returns (address[] memory rewardTokens) {
            PoolInfo memory pool = poolInfo[_pid];
            rewardTokens = pool.rewardTokens;
        }
    
        function unclaimedRewards(uint _pid, address _user)
            external
            view
            returns (uint[] memory unclaimedReward)
        {
            PoolInfo memory pool = poolInfo[_pid];
            UserInfo memory user = userInfo[_pid][_user];
            uint NORT = pool.NORT;
            if (block.timestamp > pool.lockTime && block.timestamp < pool.unlockTime && pool.staked != 0) {
                uint[] memory array = new uint[](NORT);
                for (uint i = 0; i < NORT; i++) {
                    uint blocks = block.timestamp.sub(pool.lockTime);
                    uint reward = blocks * user.amount * pool.rewardsInPool[i];
                    uint lpSupply = pool.staked * pool.lockDuration;
                    uint pending = reward.div(lpSupply);
                    array[i] = pending;
                }
                return array;
            } else if (block.timestamp > pool.unlockTime && user.harvested == false && pool.staked != 0) {
                uint[] memory array = new uint[](NORT);
                for (uint i = 0; i < NORT; i++) {                
                    uint reward = user.amount * pool.rewardsInPool[i];
                    uint lpSupply = pool.staked;
                    uint pending = reward.div(lpSupply);
                    array[i] = pending;
                }
                return array;
            } else {
                uint[] memory array = new uint[](NORT);
                for (uint i = 0; i < NORT; i++) {                
                    array[i] = 0;
                }
                return array;
            }        
        }
    }

    File 2 of 2: ARCHA
    {"ARCHA.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.2;\n\nimport \"./Context.sol\";\nimport \"./Pausable.sol\";\nimport \"./Ownable.sol\";\nimport \"./IERC20.sol\";\n\n// (Uni|Pancake)Swap libs are interchangeable\nimport \"./IUniswapV2Factory.sol\";\nimport \"./IUniswapV2Pair.sol\";\nimport \"./IUniswapV2Router01.sol\";\nimport \"./IUniswapV2Router02.sol\";\n\n/*\n    For lines that are marked ERC20 Token Standard, learn more at https://eips.ethereum.org/EIPS/eip-20. \n*/\ncontract ExtendedReflections is IERC20, Ownable, Pausable {\n\n    // Keeps track of balances for address that are included in receiving reward.\n    mapping (address =\u003e uint256) private _reflectionBalances;\n\n    // Keeps track of balances for address that are excluded from receiving reward.\n    mapping (address =\u003e uint256) private _tokenBalances;\n\n    // Keeps track of which address are excluded from fee.\n    mapping (address =\u003e bool) private _isExcludedFromFee;\n\n    // Keeps track of which address are excluded from reward.\n    mapping (address =\u003e bool) private _isExcludedFromReward;\n    \n    // An array of addresses that are excluded from reward.\n    address[] private _excludedFromReward;\n\n    // ERC20 Token Standard\n    mapping (address =\u003e mapping (address =\u003e uint256)) private _allowances;\n\n    // Liquidity pool provider router\n    IUniswapV2Router02 internal _uniswapV2Router;\n\n    // This Token and WETH pair contract.\n    IUniswapV2Pair internal _uniswapV2Pair;\n\n    // Where burnt tokens are sent to. This is an address that no one can have accesses to.\n    address private constant burnAccount = 0x000000000000000000000000000000000000dEaD;\n\n    address public marketingAddress;\n    \n    /*\n        Tax rate = (_taxXXX / 10**_tax_XXXDecimals) percent.\n        For example: if _taxBurn is 1 and _taxBurnDecimals is 2.\n        Tax rate = 0.01%\n\n        If you want tax rate for burn to be 5% for example,\n        set _taxBurn to 5 and _taxBurnDecimals to 0.\n        5 * (10 ** 0) = 5\n    */\n\n    // Decimals of taxBurn. Used for have tax less than 1%.\n    uint8 private _taxBurnDecimals;\n\n    // Decimals of taxReward. Used for have tax less than 1%.\n    uint8 private _taxRewardDecimals;\n\n    // Decimals of taxLiquify. Used for have tax less than 1%.\n    uint8 private _taxLiquifyDecimals;\n\n    // Decimals of taxMarketing. Used for have tax less than 1%.\n    uint8 private _taxMarketingDecimals;\n\n    // This percent of a transaction will be burnt.\n    uint8 private _taxBurn;\n\n    // This percent of a transaction will be redistribute to all holders.\n    uint8 private _taxReward;\n\n    // This percent of a transaction will be added to the liquidity pool. More details at https://github.com/Sheldenshi/ERC20Deflationary.\n    uint8 private _taxLiquify;\n\n    // This percent of a transaction will be transferred to Marketing wallet.\n    uint8 private _taxMarketing; \n\n    // ERC20 Token Standard\n    uint8 private _decimals;\n\n    // ERC20 Token Standard\n    uint256 private _totalSupply;\n\n    // Current supply:= total supply - burnt tokens\n    uint256 private _currentSupply;\n\n    // A number that helps distributing fees to all holders respectively.\n    uint256 private _reflectionTotal;\n\n    // Total amount of tokens rewarded / distributing. \n    uint256 private _totalRewarded;\n\n    // Total amount of tokens burnt.\n    uint256 private _totalBurnt;\n\n    // Total amount of tokens locked in the LP (this token and WETH pair).\n    uint256 private _totalTokensLockedInLiquidity;\n\n    // Total amount of ETH locked in the LP (this token and WETH pair).\n    uint256 private _totalETHLockedInLiquidity;\n\n    // A threshold for swap and liquify.\n    uint256 private _minTokensBeforeSwap;\n\n    uint256 private _marketingTokensToSwap;\n\n    // ERC20 Token Standard\n    string private _name;\n    // ERC20 Token Standard\n    string private _symbol;\n\n    // Whether a previous call of SwapAndLiquify process is still in process.\n    bool private _inSwapAndLiquify;\n\n    bool private _autoSwapAndLiquifyEnabled;\n    bool private _autoBurnEnabled;\n    bool private _rewardEnabled;\n    bool private _marketingRewardEnabled;\n    \n    // Prevent reentrancy.\n    modifier lockTheSwap {\n        require(!_inSwapAndLiquify, \"Currently in swap and liquify.\");\n        _inSwapAndLiquify = true;\n        _;\n        _inSwapAndLiquify = false;\n    }\n\n    // Return values of _getValues function.\n    struct ValuesFromAmount {\n        // Amount of tokens for to transfer.\n        uint256 amount;\n        // Amount tokens charged for burning.\n        uint256 tBurnFee;\n        // Amount tokens charged to reward.\n        uint256 tRewardFee;\n        // Amount tokens charged to add to liquidity.\n        uint256 tLiquifyFee;\n\n        uint256 tMarketingFee;\n        // Amount tokens after fees.\n        uint256 tTransferAmount;\n        // Reflection of amount.\n        uint256 rAmount;\n        // Reflection of burn fee.\n        uint256 rBurnFee;\n        // Reflection of reward fee.\n        uint256 rRewardFee;\n        // Reflection of liquify fee.\n        uint256 rLiquifyFee;\n\n        uint256 rMarketingFee;\n        // Reflection of transfer amount.\n        uint256 rTransferAmount;\n    }\n\n    /*\n        Events\n    */\n    event Burn(address from, uint256 amount);\n    event TaxBurnUpdate(uint8 previousTax, uint8 previousDecimals, uint8 currentTax, uint8 currentDecimal);\n    event TaxRewardUpdate(uint8 previousTax, uint8 previousDecimals, uint8 currentTax, uint8 currentDecimal);\n    event TaxLiquifyUpdate(uint8 previousTax, uint8 previousDecimals, uint8 currentTax, uint8 currentDecimal);\n    event TaxMarketingUpdate(uint8 previousTax, uint8 previousDecimals, uint8 currentTax, uint8 currentDecimal);\n    event MinTokensBeforeSwapUpdated(uint256 previous, uint256 current);\n    event MarketingAddressUpdated(address previous, address current);\n    event AMMPairUpdated(address pair, bool value);\n    event SwapAndLiquify(\n        uint256 tokensSwapped,\n        uint256 ethReceived,\n        uint256 tokensAddedToLiquidity\n    );\n    event ExcludeAccountFromReward(address account);\n    event IncludeAccountInReward(address account);\n    event ExcludeAccountFromFee(address account);\n    event IncludeAccountInFee(address account);\n    event EnabledAutoBurn();\n    event EnabledReward();\n    event EnabledAutoSwapAndLiquify();\n    event EnabledMarketingReward();\n    event DisabledAutoBurn();\n    event DisabledReward();\n    event DisabledAutoSwapAndLiquify();\n    event DisabledMarketingReward();\n    event Airdrop(uint256 amount);\n    \n    constructor (string memory name_, string memory symbol_, uint8 decimals_, uint256 tokenSupply_) {\n        // Sets the values for `name`, `symbol`, `totalSupply`, `currentSupply`, and `rTotal`.\n        _name = name_;\n        _symbol = symbol_;\n        _decimals = decimals_;\n        _totalSupply = tokenSupply_ * (10 ** decimals_);\n        _currentSupply = _totalSupply;\n        _reflectionTotal = (~uint256(0) - (~uint256(0) % _totalSupply));\n\n        // Mint\n        _reflectionBalances[_msgSender()] = _reflectionTotal;\n\n        // exclude owner and this contract from fee.\n        excludeAccountFromFee(owner());\n        excludeAccountFromFee(address(this));\n\n        // exclude owner, burnAccount, and this contract from receiving rewards.\n        excludeAccountFromReward(owner());\n        excludeAccountFromReward(burnAccount);\n        excludeAccountFromReward(address(this));\n        \n        emit Transfer(address(0), _msgSender(), _totalSupply);\n    }\n\n    // allow the contract to receive ETH\n    receive() external payable {}\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual returns (uint8) {\n        return _decimals;\n    }\n\n    /**\n     * @dev Returns the address of this token and WETH pair.\n     */\n    function uniswapV2Pair() public view virtual returns (address) {\n        return address(_uniswapV2Pair);\n    }\n\n    /**\n     * @dev Returns the current burn tax.\n     */\n    function taxBurn() public view virtual returns (uint8) {\n        return _taxBurn;\n    }\n\n    /**\n     * @dev Returns the current reward tax.\n     */\n    function taxReward() public view virtual returns (uint8) {\n        return _taxReward;\n    }\n\n    /**\n     * @dev Returns the current liquify tax.\n     */\n    function taxLiquify() public view virtual returns (uint8) {\n        return _taxLiquify;\n    }\n\n    function taxMarketing() public view virtual returns (uint8) {\n        return _taxMarketing;\n    }\n\n    /**\n     * @dev Returns the current burn tax decimals.\n     */\n    function taxBurnDecimals() public view virtual returns (uint8) {\n        return _taxBurnDecimals;\n    }\n\n    /**\n     * @dev Returns the current reward tax decimals.\n     */\n    function taxRewardDecimals() public view virtual returns (uint8) {\n        return _taxRewardDecimals;\n    }\n\n    /**\n     * @dev Returns the current liquify tax decimals.\n     */\n    function taxLiquifyDecimals() public view virtual returns (uint8) {\n        return _taxLiquifyDecimals;\n    }\n\n    function taxMarketingDecimals() public view virtual returns (uint8) {\n        return _taxMarketingDecimals;\n    }\n\n     /**\n     * @dev Returns true if auto burn feature is enabled.\n     */\n    function autoBurnEnabled() public view virtual returns (bool) {\n        return _autoBurnEnabled;\n    }\n\n    /**\n     * @dev Returns true if reward feature is enabled.\n     */\n    function rewardEnabled() public view virtual returns (bool) {\n        return _rewardEnabled;\n    }\n\n    /**\n     * @dev Returns true if auto swap and liquify feature is enabled.\n     */\n    function autoSwapAndLiquifyEnabled() public view virtual returns (bool) {\n        return _autoSwapAndLiquifyEnabled;\n    }\n\n\n    function marketingRewardEnabled() public view virtual returns (bool) {\n        return _marketingRewardEnabled;\n    }\n\n    /**\n     * @dev Returns the threshold before swap and liquify.\n     */\n    function minTokensBeforeSwap() external view virtual returns (uint256) {\n        return _minTokensBeforeSwap;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() external view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev Returns current supply of the token. \n     * (currentSupply := totalSupply - totalBurnt)\n     */\n    function currentSupply() external view virtual returns (uint256) {\n        return _currentSupply;\n    }\n\n    /**\n     * @dev Returns the total number of tokens burnt. \n     */\n    function totalBurnt() external view virtual returns (uint256) {\n        return _totalBurnt;\n    }\n\n    /**\n     * @dev Returns the total number of tokens locked in the LP.\n     */\n    function totalTokensLockedInLiquidity() external view virtual returns (uint256) {\n        return _totalTokensLockedInLiquidity;\n    }\n\n    /**\n     * @dev Returns the total number of ETH locked in the LP.\n     */\n    function totalETHLockedInLiquidity() external view virtual returns (uint256) {\n        return _totalETHLockedInLiquidity;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        if (_isExcludedFromReward[account]) return _tokenBalances[account];\n        return tokenFromReflection(_reflectionBalances[account]);\n    }\n\n    /**\n     * @dev Returns whether an account is excluded from reward. \n     */\n    function isExcludedFromReward(address account) external view returns (bool) {\n        return _isExcludedFromReward[account];\n    }\n\n    /**\n     * @dev Returns whether an account is excluded from fee. \n     */\n    function isExcludedFromFee(address account) external view returns (bool) {\n        return _isExcludedFromFee[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `recipient` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n        _transfer(_msgSender(), recipient, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        _approve(_msgSender(), spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * Requirements:\n     *\n     * - `sender` and `recipient` cannot be the zero address.\n     * - `sender` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``sender``\u0027s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n        _transfer(sender, recipient, amount);\n        require(_allowances[sender][_msgSender()] \u003e= amount, \"ERC20: transfer amount exceeds allowance\");\n        _approve(sender, _msgSender(), _allowances[sender][_msgSender()] - amount);\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        uint256 currentAllowance = _allowances[_msgSender()][spender];\n        require(currentAllowance \u003e= subtractedValue, \"ERC20: decreased allowance below zero\");\n        _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n        return true;\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Burn} event indicating the amount burnt.\n     * Emits a {Transfer} event with `to` set to the burn address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual whenNotPaused {\n        require(account != burnAccount, \"ERC20: burn from the burn address\");\n        require(!isBlacklisted[account], \"Blacklisted address\");\n\n        uint256 accountBalance = balanceOf(account);\n        require(accountBalance \u003e= amount, \"ERC20: burn amount exceeds balance\");\n\n        uint256 rAmount = _getRAmount(amount);\n\n        // Transfer from account to the burnAccount\n        if (_isExcludedFromReward[account]) {\n            _tokenBalances[account] -= amount;\n        } \n        _reflectionBalances[account] -= rAmount;\n\n        _tokenBalances[burnAccount] += amount;\n        _reflectionBalances[burnAccount] += rAmount;\n\n        _currentSupply -= amount;\n\n        _totalBurnt += amount;\n\n        emit Burn(account, amount);\n        emit Transfer(account, burnAccount, amount);\n    }\n    \n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.\n     *\n     * This is internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Moves tokens `amount` from `sender` to `recipient`.\n     *\n     * This is internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `sender` cannot be the zero address.\n     * - `recipient` cannot be the zero address.\n     * - `sender` must have a balance of at least `amount`.\n     */\n    function _transfer(address sender, address recipient, uint256 amount) internal virtual whenNotPaused {\n        require(sender != address(0), \"ERC20: transfer from the zero address\");\n        require(recipient != address(0), \"ERC20: transfer to the zero address\");\n        require(!isBlacklisted[sender] \u0026\u0026 !isBlacklisted[recipient], \"Blacklisted address\");\n\n        if (sender != owner() \u0026\u0026 recipient != owner())\n            _beforeTokenTransfer(sender);\n\n        bool buying = false;\n\n        if( // BUY\n            AMMPairs[sender] \u0026\u0026\n            recipient != address(_uniswapV2Router) //pair -\u003e router is changing liquidity\n        ) {\n            buying = true;\n        }\n\n        bool selling = false;\n\n        if ( // SELL\n            AMMPairs[recipient] \u0026\u0026\n            !_isExcludedFromFee[sender]\n        ) {\n            require(amount \u003c= getReservePercent(maxSellAmountPercent), \"Sell transfer amount exceeds max limit\");\n\n            selling = true;\n        }\n\n        ValuesFromAmount memory values = _getValues(\n            amount,\n            !(!_isExcludedFromFee[sender] || (buying \u0026\u0026 !_isExcludedFromFee[recipient])),\n            selling, \n            buying\n        );\n\n        if (_isExcludedFromReward[sender] \u0026\u0026 !_isExcludedFromReward[recipient]) {\n            _transferFromExcluded(sender, recipient, values);\n        } else if (!_isExcludedFromReward[sender] \u0026\u0026 _isExcludedFromReward[recipient]) {\n            _transferToExcluded(sender, recipient, values);\n        } else if (!_isExcludedFromReward[sender] \u0026\u0026 !_isExcludedFromReward[recipient]) {\n            _transferStandard(sender, recipient, values);\n        } else if (_isExcludedFromReward[sender] \u0026\u0026 _isExcludedFromReward[recipient]) {\n            _transferBothExcluded(sender, recipient, values);\n        } else {\n            _transferStandard(sender, recipient, values);\n        }\n\n        emit Transfer(sender, recipient, values.tTransferAmount);\n\n        if (!_isExcludedFromFee[sender] || (buying \u0026\u0026 !_isExcludedFromFee[recipient])) {\n            _afterTokenTransfer(values, selling, buying);\n        }\n    }\n\n    function _beforeTokenTransfer(address sender) internal virtual {\n        if (_marketingRewardEnabled \u0026\u0026 \n            !_inSwapAndLiquify \u0026\u0026\n            !AMMPairs[sender]\n            ) {\n            sendFeeInEthToAddress(marketingAddress, _marketingTokensToSwap);\n            _marketingTokensToSwap = 0;\n        }\n\n        if (_autoSwapAndLiquifyEnabled) {\n            uint256 contractBalance = _tokenBalances[address(this)];\n\n            // whether the current contract balances makes the threshold to swap and liquify.\n            bool overMinTokensBeforeSwap = contractBalance \u003e= _minTokensBeforeSwap;\n\n            if (overMinTokensBeforeSwap \u0026\u0026\n                !_inSwapAndLiquify \u0026\u0026\n                !AMMPairs[sender]\n                ) {\n                swapAndLiquify(contractBalance);\n            }\n        }\n    }\n\n    /**\n      * @dev Performs all the functionalities that are enabled.\n      */\n    function _afterTokenTransfer(ValuesFromAmount memory values, bool selling, bool buying) internal virtual {\n        \n        if (buying || selling) {\n            if (_autoBurnEnabled) {\n                _tokenBalances[address(this)] += values.tBurnFee;\n                _reflectionBalances[address(this)] += values.rBurnFee;\n                _approve(address(this), _msgSender(), values.tBurnFee);\n                burnFrom(address(this), values.tBurnFee);\n            }\n\n            if (_marketingRewardEnabled) {\n                _tokenBalances[address(this)] += values.tMarketingFee;\n                _reflectionBalances[address(this)] += values.rMarketingFee;\n\n                _marketingTokensToSwap += values.tMarketingFee;\n            }\n\n            if (_rewardEnabled) {\n                _distributeFee(values.rRewardFee, values.tRewardFee);\n            }\n        }\n\n        if (!buying \u0026\u0026 selling \u0026\u0026 values.amount \u003e= getReservePercent(maxSellAmountNormalTax) \u0026\u0026 values.amount \u003c getReservePercent(maxSellAmountPercent)) {\n            if (_autoSwapAndLiquifyEnabled) {\n                // add liquidity fee to this contract.\n                _tokenBalances[address(this)] += values.tLiquifyFee;\n                _reflectionBalances[address(this)] += values.rLiquifyFee;\n            }\n        }\n    }\n\n    /**\n     * @dev Performs transfer between two accounts that are both included in receiving reward.\n     */\n    function _transferStandard(address sender, address recipient, ValuesFromAmount memory values) private {\n        \n    \n        _reflectionBalances[sender] = _reflectionBalances[sender] - values.rAmount;\n        _reflectionBalances[recipient] = _reflectionBalances[recipient] + values.rTransferAmount;   \n\n        \n    }\n\n    /**\n     * @dev Performs transfer from an included account to an excluded account.\n     * (included and excluded from receiving reward.)\n     */\n    function _transferToExcluded(address sender, address recipient, ValuesFromAmount memory values) private {\n        \n        _reflectionBalances[sender] = _reflectionBalances[sender] - values.rAmount;\n        _tokenBalances[recipient] = _tokenBalances[recipient] + values.tTransferAmount;\n        _reflectionBalances[recipient] = _reflectionBalances[recipient] + values.rTransferAmount;    \n\n    }\n\n    /**\n     * @dev Performs transfer from an excluded account to an included account.\n     * (included and excluded from receiving reward.)\n     */\n    function _transferFromExcluded(address sender, address recipient, ValuesFromAmount memory values) private {\n        \n        _tokenBalances[sender] = _tokenBalances[sender] - values.amount;\n        _reflectionBalances[sender] = _reflectionBalances[sender] - values.rAmount;\n        _reflectionBalances[recipient] = _reflectionBalances[recipient] + values.rTransferAmount;   \n\n    }\n\n    /**\n     * @dev Performs transfer between two accounts that are both excluded in receiving reward.\n     */\n    function _transferBothExcluded(address sender, address recipient, ValuesFromAmount memory values) private {\n\n        _tokenBalances[sender] = _tokenBalances[sender] - values.amount;\n        _reflectionBalances[sender] = _reflectionBalances[sender] - values.rAmount;\n        _tokenBalances[recipient] = _tokenBalances[recipient] + values.tTransferAmount;\n        _reflectionBalances[recipient] = _reflectionBalances[recipient] + values.rTransferAmount;        \n\n    }\n    \n    /**\n     * @dev Destroys `amount` tokens from the caller.\n     *\n     */\n    function burn(uint256 amount) public virtual {\n        _burn(_msgSender(), amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, deducting from the caller\u0027s\n     * allowance.\n     *\n     * See {ERC20-_burn} and {ERC20-allowance}.\n     *\n     * Requirements:\n     *\n     * - the caller must have allowance for ``accounts``\u0027s tokens of at least\n     * `amount`.\n     */\n    function burnFrom(address account, uint256 amount) public virtual {\n        uint256 currentAllowance = allowance(account, _msgSender());\n        require(currentAllowance \u003e= amount, \"ERC20: burn amount exceeds allowance\");\n        _approve(account, _msgSender(), currentAllowance - amount);\n        _burn(account, amount);\n    }\n\n    /**\n      * @dev Excludes an account from receiving reward.\n      *\n      * Emits a {ExcludeAccountFromReward} event.\n      *\n      * Requirements:\n      *\n      * - `account` is included in receiving reward.\n      */\n    function excludeAccountFromReward(address account) public onlyOwner {\n        if(_reflectionBalances[account] \u003e 0) {\n            _tokenBalances[account] = tokenFromReflection(_reflectionBalances[account]);\n        }\n        _isExcludedFromReward[account] = true;\n        _excludedFromReward.push(account);\n        \n        emit ExcludeAccountFromReward(account);\n    }\n\n    /**\n      * @dev Includes an account from receiving reward.\n      *\n      * Emits a {IncludeAccountInReward} event.\n      *\n      * Requirements:\n      *\n      * - `account` is excluded in receiving reward.\n      */\n    function includeAccountInReward(address account) public onlyOwner {\n        require(_isExcludedFromReward[account], \"Account is already included.\");\n\n        for (uint256 i = 0; i \u003c _excludedFromReward.length; i++) {\n            if (_excludedFromReward[i] == account) {\n                _excludedFromReward[i] = _excludedFromReward[_excludedFromReward.length - 1];\n                _tokenBalances[account] = 0;\n                _isExcludedFromReward[account] = false;\n                _excludedFromReward.pop();\n                break;\n            }\n        }\n\n        emit IncludeAccountInReward(account);\n    }\n\n     /**\n      * @dev Excludes an account from fee.\n      *\n      * Emits a {ExcludeAccountFromFee} event.\n      *\n      * Requirements:\n      *\n      * - `account` is included in fee.\n      */\n    function excludeAccountFromFee(address account) public onlyOwner {\n        _isExcludedFromFee[account] = true;\n\n        emit ExcludeAccountFromFee(account);\n    }\n\n    /**\n      * @dev Includes an account from fee.\n      *\n      * Emits a {IncludeAccountFromFee} event.\n      *\n      * Requirements:\n      *\n      * - `account` is excluded in fee.\n      */\n    function includeAccountInFee(address account) public onlyOwner {\n        require(_isExcludedFromFee[account], \"Account is already included.\");\n\n        _isExcludedFromFee[account] = false;\n        \n        emit IncludeAccountInFee(account);\n    }\n\n    /**\n     * @dev Airdrop tokens to all holders that are included from reward. \n     *  Requirements:\n     * - the caller must have a balance of at least `amount`.\n     */\n    function airdrop(uint256 amount) public whenNotPaused {\n        address sender = _msgSender();\n        //require(!_isExcludedFromReward[sender], \"Excluded addresses cannot call this function\");\n        require(!isBlacklisted[_msgSender()], \"Blacklisted address\");\n        require(balanceOf(sender) \u003e= amount, \"The caller must have balance \u003e= amount.\");\n\n        ValuesFromAmount memory values = _getValues(amount, false, false, false);\n        if (_isExcludedFromReward[sender]) {\n            _tokenBalances[sender] -= values.amount;\n        }\n        _reflectionBalances[sender] -= values.rAmount;\n        \n        _reflectionTotal = _reflectionTotal - values.rAmount;\n        _totalRewarded += amount;\n        emit Airdrop(amount);\n    }\n\n    /**\n     * @dev Returns the reflected amount of a token.\n     *  Requirements:\n     * - `amount` must be less than total supply.\n     */\n    function reflectionFromToken(uint256 amount, bool deductTransferFee, bool selling, bool buying) internal view returns(uint256) {\n        require(amount \u003c= _totalSupply, \"Amount must be less than supply\");\n        ValuesFromAmount memory values = _getValues(amount, deductTransferFee, selling, buying);\n        return values.rTransferAmount;\n    }\n\n    /**\n     * @dev Used to figure out the balance after reflection.\n     * Requirements:\n     * - `rAmount` must be less than reflectTotal.\n     */\n    function tokenFromReflection(uint256 rAmount) internal view returns(uint256) {\n        require(rAmount \u003c= _reflectionTotal, \"Amount must be less than total reflections\");\n        uint256 currentRate =  _getRate();\n        return rAmount / currentRate;\n    }\n\n    /**\n     * @dev Swap half of contract\u0027s token balance for ETH,\n     * and pair it up with the other half to add to the\n     * liquidity pool.\n     *\n     * Emits {SwapAndLiquify} event indicating the amount of tokens swapped to eth,\n     * the amount of ETH added to the LP, and the amount of tokens added to the LP.\n     */\n    function swapAndLiquify(uint256 contractBalance) private lockTheSwap {\n        // Split the contract balance into two halves.\n        uint256 tokensToSwap = contractBalance / 2;\n        uint256 tokensAddToLiquidity = contractBalance - tokensToSwap;\n\n        // Contract\u0027s current ETH balance.\n        uint256 initialBalance = address(this).balance;\n\n        // Swap half of the tokens to ETH.\n        swapTokensForEth(tokensToSwap, address(this));\n\n        // Figure out the exact amount of tokens received from swapping.\n        uint256 ethAddToLiquify = address(this).balance - initialBalance;\n\n        // Add to the LP of this token and WETH pair (half ETH and half this token).\n        addLiquidity(ethAddToLiquify, tokensAddToLiquidity);\n\n        _totalETHLockedInLiquidity += address(this).balance - initialBalance;\n        _totalTokensLockedInLiquidity += contractBalance - balanceOf(address(this));\n\n        emit SwapAndLiquify(tokensToSwap, ethAddToLiquify, tokensAddToLiquidity);\n    }\n\n\n    /**\n     * @dev Swap `amount` tokens for ETH and send to `to`\n     *\n     * Emits {Transfer} event. From this contract to the token and WETH Pair.\n     */\n    function swapTokensForEth(uint256 amount, address to) private {\n        // Generate the uniswap pair path of token -\u003e weth\n        address[] memory path = new address[](2);\n        path[0] = address(this);\n        path[1] = _uniswapV2Router.WETH();\n\n        _approve(address(this), address(_uniswapV2Router), amount);\n\n\n        // Swap tokens to ETH\n        _uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(\n            amount, \n            0, \n            path, \n            to,\n            block.timestamp + 60 * 1000\n            );\n    }\n    \n    /**\n     * @dev Add `ethAmount` of ETH and `tokenAmount` of tokens to the LP.\n     * Depends on the current rate for the pair between this token and WETH,\n     * `ethAmount` and `tokenAmount` might not match perfectly. \n     * Dust(leftover) ETH or token will be refunded to this contract\n     * (usually very small quantity).\n     *\n     * Emits {Transfer} event. From this contract to the token and WETH Pai.\n     */\n    function addLiquidity(uint256 ethAmount, uint256 tokenAmount) private {\n        _approve(address(this), address(_uniswapV2Router), tokenAmount);\n\n        // Add the ETH and token to LP.\n        // The LP tokens will be sent to burnAccount.\n        // No one will have access to them, so the liquidity will be locked forever.\n        _uniswapV2Router.addLiquidityETH{value: ethAmount}(\n            address(this), \n            tokenAmount, \n            0, // slippage is unavoidable\n            0, // slippage is unavoidable\n            burnAccount, // the LP is sent to burnAccount. \n            block.timestamp + 60 * 1000\n        );\n    }\n\n    /**\n     * @dev Distribute the `tRewardFee` tokens to all holders that are included in receiving reward.\n     * amount received is based on how many token one owns.  \n     */\n    function _distributeFee(uint256 rRewardFee, uint256 tRewardFee) private {\n        // This would decrease rate, thus increase amount reward receive based on one\u0027s balance.\n        _reflectionTotal = _reflectionTotal - rRewardFee;\n        _totalRewarded += tRewardFee;\n    }\n    \n    /**\n     * @dev Returns fees and transfer amount in both tokens and reflections.\n     * tXXXX stands for tokenXXXX\n     * rXXXX stands for reflectionXXXX\n     * More details can be found at comments for ValuesForAmount Struct.\n     */\n    function _getValues(uint256 amount, bool deductTransferFee, bool selling, bool buying) private view returns (ValuesFromAmount memory) {\n        ValuesFromAmount memory values;\n        values.amount = amount;\n        _getTValues(values, deductTransferFee, selling, buying);\n        _getRValues(values, deductTransferFee, selling, buying);\n        return values;\n    }\n\n    /**\n     * @dev Adds fees and transfer amount in tokens to `values`.\n     * tXXXX stands for tokenXXXX\n     * More details can be found at comments for ValuesForAmount Struct.\n     */\n    function _getTValues(ValuesFromAmount memory values, bool deductTransferFee, bool selling, bool buying) view private {\n        \n        if (deductTransferFee) {\n            values.tTransferAmount = values.amount;\n        } else {\n            // calculate fee\n            if (buying || selling) {\n                values.tBurnFee = _calculateTax(values.amount, _taxBurn, _taxBurnDecimals);\n                values.tMarketingFee = _calculateTax(values.amount, _taxMarketing, _taxMarketingDecimals);\n                values.tRewardFee = _calculateTax(values.amount, _taxReward, _taxRewardDecimals);\n            }\n\n            if (!buying \u0026\u0026 selling \u0026\u0026 values.amount \u003e= getReservePercent(maxSellAmountNormalTax) \u0026\u0026 values.amount \u003c getReservePercent(maxSellAmountPercent)) {\n                values.tLiquifyFee = _calculateTax(values.amount, _taxLiquify, _taxLiquifyDecimals);\n            }\n            \n            // amount after fee\n            values.tTransferAmount = values.amount - values.tBurnFee - values.tRewardFee - values.tLiquifyFee - values.tMarketingFee;\n        }\n        \n    }\n\n    /**\n     * @dev Adds fees and transfer amount in reflection to `values`.\n     * rXXXX stands for reflectionXXXX\n     * More details can be found at comments for ValuesForAmount Struct.\n     */\n    function _getRValues(ValuesFromAmount memory values, bool deductTransferFee, bool selling, bool buying) view private {\n        uint256 currentRate = _getRate();\n\n        values.rAmount = values.amount * currentRate;\n\n        if (deductTransferFee) {\n            values.rTransferAmount = values.rAmount;\n        } else {\n            values.rAmount = values.amount * currentRate;\n\n            if (buying || selling) {\n                values.rBurnFee = values.tBurnFee * currentRate;\n                values.rMarketingFee = values.tMarketingFee * currentRate;\n                values.rRewardFee = values.tRewardFee * currentRate;\n            }\n\n            if (!buying \u0026\u0026 selling \u0026\u0026 values.amount \u003e= getReservePercent(maxSellAmountNormalTax) \u0026\u0026 values.amount \u003c getReservePercent(maxSellAmountPercent)) {\n                values.rLiquifyFee = values.tLiquifyFee * currentRate;\n            }\n\n            values.rTransferAmount = values.rAmount - values.rBurnFee - values.rRewardFee - values.rLiquifyFee - values.rMarketingFee;\n        }\n        \n    }\n\n    /**\n     * @dev Returns `amount` in reflection.\n     */\n    function _getRAmount(uint256 amount) private view returns (uint256) {\n        uint256 currentRate = _getRate();\n        return amount * currentRate;\n    }\n\n    /**\n     * @dev Returns the current reflection rate.\n     */\n    function _getRate() private view returns(uint256) {\n        (uint256 rSupply, uint256 tSupply) = _getCurrentSupply();\n        return rSupply / tSupply;\n    }\n\n    /**\n     * @dev Returns the current reflection supply and token supply.\n     */\n    function _getCurrentSupply() private view returns(uint256, uint256) {\n        uint256 rSupply = _reflectionTotal;\n        uint256 tSupply = _totalSupply;      \n        for (uint256 i = 0; i \u003c _excludedFromReward.length; i++) {\n            if (_reflectionBalances[_excludedFromReward[i]] \u003e rSupply || _tokenBalances[_excludedFromReward[i]] \u003e tSupply) return (_reflectionTotal, _totalSupply);\n            rSupply = rSupply - _reflectionBalances[_excludedFromReward[i]];\n            tSupply = tSupply - _tokenBalances[_excludedFromReward[i]];\n        }\n        if (rSupply \u003c _reflectionTotal / _totalSupply) return (_reflectionTotal, _totalSupply);\n        return (rSupply, tSupply);\n    }\n\n    /**\n     * @dev Returns fee based on `amount` and `taxRate`\n     */\n    function _calculateTax(uint256 amount, uint8 tax, uint8 taxDecimals_) private pure returns (uint256) {\n        return amount * tax / (10 ** taxDecimals_) / (10 ** 2);\n    }\n\n    /*\n        Owner functions\n    */\n\n    /**\n     * @dev Enables the auto burn feature.\n     * Burn transaction amount * `taxBurn_` amount of tokens each transaction when enabled.\n     *\n     * Emits a {EnabledAutoBurn} event.\n     *\n     * Requirements:\n     *\n     * - auto burn feature mush be disabled.\n     * - tax must be greater than 0.\n     * - tax decimals + 2 must be less than token decimals. \n     * (because tax rate is in percentage)\n     */\n    function enableAutoBurn(uint8 taxBurn_, uint8 taxBurnDecimals_) public onlyOwner {\n        require(!_autoBurnEnabled, \"Auto burn feature is already enabled.\");\n        require(taxBurn_ \u003e 0, \"Tax must be greater than 0.\");\n        require(taxBurnDecimals_ + 2  \u003c= decimals(), \"Tax decimals must be less than token decimals - 2\");\n        \n        _autoBurnEnabled = true;\n        setTaxBurn(taxBurn_, taxBurnDecimals_);\n        \n        emit EnabledAutoBurn();\n    }\n\n    /**\n     * @dev Enables the reward feature.\n     * Distribute transaction amount * `taxReward_` amount of tokens each transaction when enabled.\n     *\n     * Emits a {EnabledReward} event.\n     *\n     * Requirements:\n     *\n     * - reward feature mush be disabled.\n     * - tax must be greater than 0.\n     * - tax decimals + 2 must be less than token decimals. \n     * (because tax rate is in percentage)\n    */\n    function enableReward(uint8 taxReward_, uint8 taxRewardDecimals_) public onlyOwner {\n        require(!_rewardEnabled, \"Reward feature is already enabled.\");\n        require(taxReward_ \u003e 0, \"Tax must be greater than 0.\");\n        require(taxRewardDecimals_ + 2  \u003c= decimals(), \"Tax decimals must be less than token decimals - 2\");\n\n        _rewardEnabled = true;\n        setTaxReward(taxReward_, taxRewardDecimals_);\n\n        emit EnabledReward();\n    }\n\n    function initSwap(address routerAddress) public onlyOwner {\n        // init Router\n        IUniswapV2Router02 uniswapV2Router = IUniswapV2Router02(routerAddress);\n\n        address uniswapV2Pair_ = IUniswapV2Factory(uniswapV2Router.factory()).getPair(address(this), uniswapV2Router.WETH());\n\n        if (uniswapV2Pair_ == address(0)) {\n            uniswapV2Pair_ = IUniswapV2Factory(uniswapV2Router.factory())\n                .createPair(address(this), uniswapV2Router.WETH());\n        }\n        \n        _uniswapV2Router = uniswapV2Router;\n        _uniswapV2Pair = IUniswapV2Pair(uniswapV2Pair_);\n\n        _setAMMPair(uniswapV2Pair_, true);\n\n        // exclude uniswapV2Router from receiving reward.\n        excludeAccountFromReward(address(uniswapV2Router));\n\n        // exclude WETH and this Token Pair from receiving reward.\n        // excludeAccountFromReward(uniswapV2Pair_);\n        // Account already exluded in _setAMMPair\n\n        // exclude uniswapV2Router from paying fees.\n        excludeAccountFromFee(address(uniswapV2Router));\n        // exclude WETH and this Token Pair from paying fees.\n        // excludeAccountFromFee(uniswapV2Pair_);\n        // Account already exluded in _setAMMPair\n    }\n\n    /**\n      * @dev Enables the auto swap and liquify feature.\n      * Swaps half of transaction amount * `taxLiquify_` amount of tokens \n      * to ETH and pair with the other half of tokens to the LP each transaction when enabled.\n      *\n      * Emits a {EnabledAutoSwapAndLiquify} event.\n      *\n      * Requirements:\n      *\n      * - auto swap and liquify feature mush be disabled.\n      * - tax must be greater than 0.\n      * - tax decimals + 2 must be less than token decimals. \n      * (because tax rate is in percentage)\n      */\n    function enableAutoSwapAndLiquify(uint8 taxLiquify_, uint8 taxLiquifyDecimals_, address routerAddress, uint256 minTokensBeforeSwap_) public onlyOwner {\n        require(!_autoSwapAndLiquifyEnabled, \"Auto swap and liquify feature is already enabled.\");\n        require(taxLiquify_ \u003e 0, \"Tax must be greater than 0.\");\n        require(taxLiquifyDecimals_ + 2  \u003c= decimals(), \"Tax decimals must be less than token decimals - 2\");\n\n        _minTokensBeforeSwap = minTokensBeforeSwap_;\n\n        initSwap(routerAddress);\n\n        // enable\n        _autoSwapAndLiquifyEnabled = true;\n        setTaxLiquify(taxLiquify_, taxLiquifyDecimals_);\n        \n        emit EnabledAutoSwapAndLiquify();\n    }\n\n    function enableMarketingTax(uint8 taxMarketing_, uint8 taxMarketingDecimals_, address marketingAddress_) public onlyOwner {\n        require(!_marketingRewardEnabled, \"Marketing tax feature is already enabled.\");\n        require(taxMarketing_ \u003e 0, \"Tax must be greater than 0.\");\n        require(taxMarketingDecimals_ + 2  \u003c= decimals(), \"Tax decimals must be less than token decimals - 2\");\n\n        _marketingRewardEnabled = true;\n        setMarketingTax(taxMarketing_, taxMarketingDecimals_);\n        setMarketingAddress(marketingAddress_);\n\n        emit EnabledMarketingReward();\n    }\n\n    /**\n     * @dev Disables the auto burn feature.\n     *\n     * Emits a {DisabledAutoBurn} event.\n     *\n     * Requirements:\n     *\n     * - auto burn feature mush be enabled.\n     */\n    function disableAutoBurn() public onlyOwner {\n        require(_autoBurnEnabled, \"Auto burn feature is already disabled.\");\n\n        setTaxBurn(0, 0);\n        _autoBurnEnabled = false;\n        \n        emit DisabledAutoBurn();\n    }\n\n    /**\n      * @dev Disables the reward feature.\n      *\n      * Emits a {DisabledReward} event.\n      *\n      * Requirements:\n      *\n      * - reward feature mush be enabled.\n      */\n    function disableReward() public onlyOwner {\n        require(_rewardEnabled, \"Reward feature is already disabled.\");\n\n        setTaxReward(0, 0);\n        _rewardEnabled = false;\n        \n        emit DisabledReward();\n    }\n\n    /**\n      * @dev Disables the auto swap and liquify feature.\n      *\n      * Emits a {DisabledAutoSwapAndLiquify} event.\n      *\n      * Requirements:\n      *\n      * - auto swap and liquify feature mush be enabled.\n      */\n    function disableAutoSwapAndLiquify() public onlyOwner {\n        require(_autoSwapAndLiquifyEnabled, \"Auto swap and liquify feature is already disabled.\");\n\n        setTaxLiquify(0, 0);\n        _autoSwapAndLiquifyEnabled = false;\n         \n        emit DisabledAutoSwapAndLiquify();\n    }\n\n\n    function disableMarketingTax() public onlyOwner {\n        require(_marketingRewardEnabled, \"Marketing reward feature is already disabled.\");\n\n        setMarketingTax(0, 0);\n        setMarketingAddress(address(0x0));\n        _marketingRewardEnabled = false;\n        \n        emit DisabledMarketingReward();\n    }\n\n     /**\n      * @dev Updates `_minTokensBeforeSwap`\n      *\n      * Emits a {MinTokensBeforeSwap} event.\n      *\n      * Requirements:\n      *\n      * - `minTokensBeforeSwap_` must be less than _currentSupply.\n      */\n    function setMinTokensBeforeSwap(uint256 minTokensBeforeSwap_) public onlyOwner {\n        require(minTokensBeforeSwap_ \u003c _currentSupply, \"minTokensBeforeSwap must be lower than current supply.\");\n\n        uint256 previous = _minTokensBeforeSwap;\n        _minTokensBeforeSwap = minTokensBeforeSwap_;\n\n        emit MinTokensBeforeSwapUpdated(previous, _minTokensBeforeSwap);\n    }\n\n    /**\n      * @dev Updates taxBurn\n      *\n      * Emits a {TaxBurnUpdate} event.\n      *\n      * Requirements:\n      *\n      * - auto burn feature must be enabled.\n      * - total tax rate must be less than 100%.\n      */\n    function setTaxBurn(uint8 taxBurn_, uint8 taxBurnDecimals_) public onlyOwner {\n        require(_autoBurnEnabled, \"Auto burn feature must be enabled. Try the EnableAutoBurn function.\");\n\n        uint8 previousTax = _taxBurn;\n        uint8 previousDecimals = _taxBurnDecimals;\n        _taxBurn = taxBurn_;\n        _taxBurnDecimals = taxBurnDecimals_;\n\n        emit TaxBurnUpdate(previousTax, previousDecimals, taxBurn_, taxBurnDecimals_);\n    }\n\n    /**\n      * @dev Updates taxReward\n      *\n      * Emits a {TaxRewardUpdate} event.\n      *\n      * Requirements:\n      *\n      * - reward feature must be enabled.\n      * - total tax rate must be less than 100%.\n      */\n    function setTaxReward(uint8 taxReward_, uint8 taxRewardDecimals_) public onlyOwner {\n        require(_rewardEnabled, \"Reward feature must be enabled. Try the EnableReward function.\");\n\n        uint8 previousTax = _taxReward;\n        uint8 previousDecimals = _taxRewardDecimals;\n        _taxReward = taxReward_;\n        _taxRewardDecimals = taxRewardDecimals_;\n\n        emit TaxRewardUpdate(previousTax, previousDecimals, taxReward_, taxRewardDecimals_);\n    }\n\n    /**\n      * @dev Updates taxLiquify\n      *\n      * Emits a {TaxLiquifyUpdate} event.\n      *\n      * Requirements:\n      *\n      * - auto swap and liquify feature must be enabled.\n      * - total tax rate must be less than 100%.\n      */\n    function setTaxLiquify(uint8 taxLiquify_, uint8 taxLiquifyDecimals_) public onlyOwner {\n        require(_autoSwapAndLiquifyEnabled, \"Auto swap and liquify feature must be enabled. Try the EnableAutoSwapAndLiquify function.\");\n\n        uint8 previousTax = _taxLiquify;\n        uint8 previousDecimals = _taxLiquifyDecimals;\n        _taxLiquify = taxLiquify_;\n        _taxLiquifyDecimals = taxLiquifyDecimals_;\n\n        emit TaxLiquifyUpdate(previousTax, previousDecimals, taxLiquify_, taxLiquifyDecimals_);\n    }\n\n    function setMarketingTax(uint8 taxMarketing_, uint8 taxMarketingDecimals_) public onlyOwner {\n        require(_marketingRewardEnabled, \"Marketing reward feature must be enabled. Try the enableMarketingTax function.\");\n\n        uint8 previousTax = _taxMarketing;\n        uint8 previousDecimals = _taxMarketingDecimals;\n        _taxMarketing = taxMarketing_;\n        _taxMarketingDecimals = taxMarketingDecimals_;\n\n        emit TaxMarketingUpdate(previousTax, previousDecimals, taxMarketing_, taxMarketingDecimals_);\n    }\n\n    function setMarketingAddress(address marketingAddress_) public onlyOwner {\n        require(marketingAddress != marketingAddress_, \"New marketing address must be different than old one.\");\n\n        address previous = marketingAddress;\n        marketingAddress = marketingAddress_;\n\n        emit MarketingAddressUpdated(previous, marketingAddress_);\n    }\n\n    // function sendFeeToAddress(address addr, uint256 rAmount, uint256 tAmount) private {\n    //     if (_isExcludedFromReward[addr])\n    //         _tokenBalances[addr] += tAmount;\n\n    //     _reflectionBalances[addr] += rAmount;\n    // }\n\n    function sendFeeInEthToAddress(address addr, uint256 tAmount) private lockTheSwap {\n        if (tAmount\u003e0)\n            swapTokensForEth(tAmount, addr);\n    }\n\n    // ##############\n    // Features added\n    // ##############\n\n    uint8 public maxSellAmountPercent;\n    uint8 public maxSellAmountNormalTax;\n\n    mapping (address =\u003e bool) public AMMPairs;\n\n    mapping(address =\u003e bool) public isBlacklisted;\n\n    function setAMMPair(address pair, bool value) public onlyOwner {\n        require(pair != uniswapV2Pair(), \"The main pair cannot be removed from AMMPairs.\");\n\n        _setAMMPair(pair, value);\n    }\n\n    function _setAMMPair(address pair, bool value) private {\n        AMMPairs[pair] = value;\n\n        if(value) {\n            excludeAccountFromReward(pair);\n            excludeAccountFromFee(pair);\n        }\n\n        emit AMMPairUpdated(pair, value);\n    }\n\n    function changeMaxSellAmountPercent(uint8 amount) public onlyOwner {\n        maxSellAmountPercent = amount;\n    }\n\n    function changeMaxSellAmountNormalTax(uint8 amount) public onlyOwner {\n        maxSellAmountNormalTax = amount;\n    }\n\n    function getReservePercent(uint8 percent) public view returns (uint256) {\n        uint112 reserve;\n        if (_uniswapV2Pair.token0() == address(this))\n            (reserve,,) = _uniswapV2Pair.getReserves();\n        else\n            (,reserve,) = _uniswapV2Pair.getReserves();\n\n        return _calculateTax(uint256(reserve), percent, 0);\n    }\n\n    function blacklistAddress(address addr, bool value) external onlyOwner {\n        isBlacklisted[addr] = value;\n    }\n\n    function pause() public onlyOwner {\n        _pause();\n    }\n\n    function unpause() public onlyOwner {\n        _unpause();\n    }\n\n    /**\n     * @dev Remember that only owner can call so be careful when use on contracts generated from other contracts.\n     * @param tokenAddress The token contract address\n     * @param tokenAmount Number of tokens to be sent\n     */\n    function recoverERC20(address tokenAddress, uint256 tokenAmount) public virtual onlyOwner {\n        require(tokenAddress != address(this), \"Cannot withdraw this token\");\n        IERC20(tokenAddress).transfer(owner(), tokenAmount);\n    }\n\n    function recoverETH(uint256 ethAmount) public virtual onlyOwner returns (bool success) {\n        (success,) = owner().call{value: ethAmount}(\"\");\n    }\n}\n\ncontract ARCHA is ExtendedReflections {\n\n    uint256 private _tokenSupply = 100000000000000000; // 100Q\n\n    uint8 private _taxBurn = 2;\n    uint8 private _taxReward = 2;\n    uint8 private _taxMarketing = 2;\n    uint8 private _taxLiquifyCustom = 25;\n\n    uint8 private _taxDecimals = 0;\n    uint8 private _decimals = 9;\n\n    uint8 private _maxSellAmount = 3; // 3% of total liquidity tokens\n    uint8 private _maxSellAmountNormalTax = 2; // 2% of total liquidity tokens\n    uint256 private _minTokensBeforeSwap = 1; // Cannot be zero\n\n    /**\n     * @dev Choose proper router address according to your network:\n     * Ethereum: 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D (Uniswap)\n     * BSC mainnet: 0x10ED43C718714eb63d5aA57B78B54704E256024E (PancakeSwap)\n     * BSC testnet: 0x9Ac64Cc6e4415144C455BD8E4837Fea55603e5c3\n     */\n    address private _routerAddress = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;\n\n    address private _marketingAddress = _msgSender();\n\n    constructor () ExtendedReflections(\"archangel\", \"ARCHA\", _decimals, _tokenSupply) {\n        enableAutoBurn(_taxBurn, _taxDecimals);\n        enableReward(_taxReward, _taxDecimals);\n        enableMarketingTax(_taxMarketing, _taxDecimals, _marketingAddress);\n\n        changeMaxSellAmountPercent(_maxSellAmount);\n        changeMaxSellAmountNormalTax(_maxSellAmountNormalTax);\n\n        enableAutoSwapAndLiquify(_taxLiquifyCustom, _taxDecimals, _routerAddress, _minTokensBeforeSwap);\n    }\n}\n"},"Context.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.0 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n"},"IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.0 (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller\u0027s account to `recipient`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller\u0027s tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender\u0027s allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `sender` to `recipient` using the\n     * allowance mechanism. `amount` is then deducted from the caller\u0027s\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) external returns (bool);\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"},"IUniswapV2Factory.sol":{"content":"pragma solidity \u003e=0.5.0;\n\ninterface IUniswapV2Factory {\n    event PairCreated(address indexed token0, address indexed token1, address pair, uint);\n\n    function feeTo() external view returns (address);\n    function feeToSetter() external view returns (address);\n\n    function getPair(address tokenA, address tokenB) external view returns (address pair);\n    function allPairs(uint) external view returns (address pair);\n    function allPairsLength() external view returns (uint);\n\n    function createPair(address tokenA, address tokenB) external returns (address pair);\n\n    function setFeeTo(address) external;\n    function setFeeToSetter(address) external;\n}\n"},"IUniswapV2Pair.sol":{"content":"pragma solidity \u003e=0.5.0;\n\ninterface IUniswapV2Pair {\n    event Approval(address indexed owner, address indexed spender, uint value);\n    event Transfer(address indexed from, address indexed to, uint value);\n\n    function name() external pure returns (string memory);\n    function symbol() external pure returns (string memory);\n    function decimals() external pure returns (uint8);\n    function totalSupply() external view returns (uint);\n    function balanceOf(address owner) external view returns (uint);\n    function allowance(address owner, address spender) external view returns (uint);\n\n    function approve(address spender, uint value) external returns (bool);\n    function transfer(address to, uint value) external returns (bool);\n    function transferFrom(address from, address to, uint value) external returns (bool);\n\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n    function PERMIT_TYPEHASH() external pure returns (bytes32);\n    function nonces(address owner) external view returns (uint);\n\n    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n    event Mint(address indexed sender, uint amount0, uint amount1);\n    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);\n    event Swap(\n        address indexed sender,\n        uint amount0In,\n        uint amount1In,\n        uint amount0Out,\n        uint amount1Out,\n        address indexed to\n    );\n    event Sync(uint112 reserve0, uint112 reserve1);\n\n    function MINIMUM_LIQUIDITY() external pure returns (uint);\n    function factory() external view returns (address);\n    function token0() external view returns (address);\n    function token1() external view returns (address);\n    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n    function price0CumulativeLast() external view returns (uint);\n    function price1CumulativeLast() external view returns (uint);\n    function kLast() external view returns (uint);\n\n    function mint(address to) external returns (uint liquidity);\n    function burn(address to) external returns (uint amount0, uint amount1);\n    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;\n    function skim(address to) external;\n    function sync() external;\n\n    function initialize(address, address) external;\n}\n"},"IUniswapV2Router01.sol":{"content":"pragma solidity \u003e=0.6.2;\n\ninterface IUniswapV2Router01 {\n    function factory() external pure returns (address);\n    function WETH() external pure returns (address);\n\n    function addLiquidity(\n        address tokenA,\n        address tokenB,\n        uint amountADesired,\n        uint amountBDesired,\n        uint amountAMin,\n        uint amountBMin,\n        address to,\n        uint deadline\n    ) external returns (uint amountA, uint amountB, uint liquidity);\n    function addLiquidityETH(\n        address token,\n        uint amountTokenDesired,\n        uint amountTokenMin,\n        uint amountETHMin,\n        address to,\n        uint deadline\n    ) external payable returns (uint amountToken, uint amountETH, uint liquidity);\n    function removeLiquidity(\n        address tokenA,\n        address tokenB,\n        uint liquidity,\n        uint amountAMin,\n        uint amountBMin,\n        address to,\n        uint deadline\n    ) external returns (uint amountA, uint amountB);\n    function removeLiquidityETH(\n        address token,\n        uint liquidity,\n        uint amountTokenMin,\n        uint amountETHMin,\n        address to,\n        uint deadline\n    ) external returns (uint amountToken, uint amountETH);\n    function removeLiquidityWithPermit(\n        address tokenA,\n        address tokenB,\n        uint liquidity,\n        uint amountAMin,\n        uint amountBMin,\n        address to,\n        uint deadline,\n        bool approveMax, uint8 v, bytes32 r, bytes32 s\n    ) external returns (uint amountA, uint amountB);\n    function removeLiquidityETHWithPermit(\n        address token,\n        uint liquidity,\n        uint amountTokenMin,\n        uint amountETHMin,\n        address to,\n        uint deadline,\n        bool approveMax, uint8 v, bytes32 r, bytes32 s\n    ) external returns (uint amountToken, uint amountETH);\n    function swapExactTokensForTokens(\n        uint amountIn,\n        uint amountOutMin,\n        address[] calldata path,\n        address to,\n        uint deadline\n    ) external returns (uint[] memory amounts);\n    function swapTokensForExactTokens(\n        uint amountOut,\n        uint amountInMax,\n        address[] calldata path,\n        address to,\n        uint deadline\n    ) external returns (uint[] memory amounts);\n    function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)\n        external\n        payable\n        returns (uint[] memory amounts);\n    function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)\n        external\n        returns (uint[] memory amounts);\n    function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)\n        external\n        returns (uint[] memory amounts);\n    function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)\n        external\n        payable\n        returns (uint[] memory amounts);\n\n    function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);\n    function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);\n    function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);\n    function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);\n    function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);\n}\n"},"IUniswapV2Router02.sol":{"content":"pragma solidity \u003e=0.6.2;\n\nimport \u0027./IUniswapV2Router01.sol\u0027;\n\ninterface IUniswapV2Router02 is IUniswapV2Router01 {\n    function removeLiquidityETHSupportingFeeOnTransferTokens(\n        address token,\n        uint liquidity,\n        uint amountTokenMin,\n        uint amountETHMin,\n        address to,\n        uint deadline\n    ) external returns (uint amountETH);\n    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(\n        address token,\n        uint liquidity,\n        uint amountTokenMin,\n        uint amountETHMin,\n        address to,\n        uint deadline,\n        bool approveMax, uint8 v, bytes32 r, bytes32 s\n    ) external returns (uint amountETH);\n\n    function swapExactTokensForTokensSupportingFeeOnTransferTokens(\n        uint amountIn,\n        uint amountOutMin,\n        address[] calldata path,\n        address to,\n        uint deadline\n    ) external;\n    function swapExactETHForTokensSupportingFeeOnTransferTokens(\n        uint amountOutMin,\n        address[] calldata path,\n        address to,\n        uint deadline\n    ) external payable;\n    function swapExactTokensForETHSupportingFeeOnTransferTokens(\n        uint amountIn,\n        uint amountOutMin,\n        address[] calldata path,\n        address to,\n        uint deadline\n    ) external;\n}\n"},"Ownable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.0 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor() {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"},"Pausable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.0 (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context {\n    /**\n     * @dev Emitted when the pause is triggered by `account`.\n     */\n    event Paused(address account);\n\n    /**\n     * @dev Emitted when the pause is lifted by `account`.\n     */\n    event Unpaused(address account);\n\n    bool private _paused;\n\n    /**\n     * @dev Initializes the contract in unpaused state.\n     */\n    constructor() {\n        _paused = false;\n    }\n\n    /**\n     * @dev Returns true if the contract is paused, and false otherwise.\n     */\n    function paused() public view virtual returns (bool) {\n        return _paused;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is not paused.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    modifier whenNotPaused() {\n        require(!paused(), \"Pausable: paused\");\n        _;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is paused.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    modifier whenPaused() {\n        require(paused(), \"Pausable: not paused\");\n        _;\n    }\n\n    /**\n     * @dev Triggers stopped state.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    function _pause() internal virtual whenNotPaused {\n        _paused = true;\n        emit Paused(_msgSender());\n    }\n\n    /**\n     * @dev Returns to normal state.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    function _unpause() internal virtual whenPaused {\n        _paused = false;\n        emit Unpaused(_msgSender());\n    }\n}\n"}}