Token YW 35 (WINGS-USDC)

Overview CRC20

Price
$0.00 @ 0.000000 CRO
Fully Diluted Market Cap
Total Supply:
0.000115 YW35

Holders:
11 addresses
Contract:
0xbf4afce817865291b8d0e21997926371021b1c5c0xBF4afcE817865291b8D0e21997926371021b1c5c

Decimals:
18

Social Profiles:
Not Available, Update ?

Balance
0 YW35

Value
$0.00
0xf462978892606ebbdb43a577cacfe57e4f6932c0
Loading
[ Download CSV Export  ] 
Loading
[ Download CSV Export  ] 
Loading

Click here to update the token ICO / general information
# Exchange Pair Price  24H Volume % Volume

Similar Match Source Code
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0x31D0079E592f6169fB863373aC7a0D10D97e7869

Contract Name:
ACMasterChefLP

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 17 : ACMasterChefLP.sol
// SPDX-License-Identifier: MIT

//// _____.___.__       .__       ._____      __      .__   _____  ////
//// \__  |   |__| ____ |  |    __| _/  \    /  \____ |  |_/ ____\ ////
////  /   |   |  |/ __ \|  |   / __ |\   \/\/   /  _ \|  |\   __\  ////
////  \____   |  \  ___/|  |__/ /_/ | \        (  <_> )  |_|  |    ////
////  / ______|__|\___  >____/\____ |  \__/\  / \____/|____/__|    ////
////  \/              \/           \/       \/                     ////

pragma solidity 0.8.9;

import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol';
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol';
import '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';

import './AutoCompoundVault.sol';

interface IFarm {
    function deposit(uint256 _pid, uint256 _amount) external;

    function withdraw(uint256 _pid, uint256 _amount) external;

    function userInfo(uint256 _pid, address _user) external view returns (uint256, uint256);

    function emergencyWithdraw(uint256 _pid) external;
}

/**
 * @title AutoCompound MasterChef
 * @notice vault for auto-compounding LPs on pools using a standard MasterChef contract
 * @author YieldWolf
 */
contract ACMasterChefLP is AutoCompoundVault {
    IUniswapV2Router02 public immutable liquidityRouter; // router used for adding liquidity to the LP token
    IERC20 public immutable token0; // first token of the lp
    IERC20 public immutable token1; // second token of the lp

    constructor(
        string memory _name,
        string memory _symbol,
        uint256 _pid,
        address[6] memory _addresses,
        IUniswapV2Router02 _liquidityRouter
    ) ERC20(_name, _symbol) AutoCompoundVault(_pid, _addresses) {
        token0 = IERC20(IUniswapV2Pair(_addresses[1]).token0());
        token1 = IERC20(IUniswapV2Pair(_addresses[1]).token1());
        liquidityRouter = _liquidityRouter;
        token0.approve(address(liquidityRouter), type(uint256).max);
        token1.approve(address(liquidityRouter), type(uint256).max);
    }

    function _earnToStake(uint256 _earnAmount) internal override {
        uint256 halfEarnAmount = _earnAmount / 2;
        if (earnToken != token0) {
            _safeSwap(halfEarnAmount, address(earnToken), address(token0));
        }
        if (earnToken != token1) {
            _safeSwap(_earnAmount - halfEarnAmount, address(earnToken), address(token1));
        }
        uint256 token0Amt = token0.balanceOf(address(this));
        uint256 token1Amt = token1.balanceOf(address(this));
        liquidityRouter.addLiquidity(
            address(token0),
            address(token1),
            token0Amt,
            token1Amt,
            1,
            1,
            address(this),
            block.timestamp
        );
    }

    function _farmDeposit(uint256 amount) internal override {
        IFarm(masterChef).deposit(pid, amount);
    }

    function _farmWithdraw(uint256 amount) internal override {
        IFarm(masterChef).withdraw(pid, amount);
    }

    function _farmEmergencyWithdraw() internal override {
        IFarm(masterChef).emergencyWithdraw(pid);
    }

    function _totalStaked() internal view override returns (uint256 amount) {
        (amount, ) = IFarm(masterChef).userInfo(pid, address(this));
    }

    function _addAllawences() internal override {
        IERC20(stakeToken).approve(masterChef, type(uint256).max);
        token0.approve(address(liquidityRouter), type(uint256).max);
        token1.approve(address(liquidityRouter), type(uint256).max);
    }

    function _removeAllawences() internal override {
        IERC20(stakeToken).approve(masterChef, 0);
        token0.approve(address(liquidityRouter), 0);
        token1.approve(address(liquidityRouter), 0);
    }
}

File 2 of 17 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `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);

    /**
     * @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);
}

File 3 of 17 : IUniswapV2Factory.sol
pragma solidity >=0.5.0;

interface IUniswapV2Factory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint);

    function feeTo() external view returns (address);
    function feeToSetter() external view returns (address);

    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function allPairs(uint) external view returns (address pair);
    function allPairsLength() external view returns (uint);

    function createPair(address tokenA, address tokenB) external returns (address pair);

    function setFeeTo(address) external;
    function setFeeToSetter(address) external;
}

File 4 of 17 : IUniswapV2Pair.sol
pragma solidity >=0.5.0;

interface IUniswapV2Pair {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;

    event Mint(address indexed sender, uint amount0, uint amount1);
    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() external view returns (uint);

    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;

    function initialize(address, address) external;
}

File 5 of 17 : IUniswapV2Router02.sol
pragma solidity >=0.6.2;

import './IUniswapV2Router01.sol';

interface IUniswapV2Router02 is IUniswapV2Router01 {
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external returns (uint amountETH);
    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountETH);

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;
    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external payable;
    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;
}

File 6 of 17 : AutoCompoundVault.sol
// SPDX-License-Identifier: MIT

//// _____.___.__       .__       ._____      __      .__   _____  ////
//// \__  |   |__| ____ |  |    __| _/  \    /  \____ |  |_/ ____\ ////
////  /   |   |  |/ __ \|  |   / __ |\   \/\/   /  _ \|  |\   __\  ////
////  \____   |  \  ___/|  |__/ /_/ | \        (  <_> )  |_|  |    ////
////  / ______|__|\___  >____/\____ |  \__/\  / \____/|____/__|    ////
////  \/              \/           \/       \/                     ////

pragma solidity 0.8.9;

import '@openzeppelin/contracts/token/ERC20/ERC20.sol';
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';
import '@openzeppelin/contracts/security/ReentrancyGuard.sol';
import '@openzeppelin/contracts/security/Pausable.sol';

import '../interfaces/IWETH.sol';
import '../interfaces/IYieldWolf.sol';
import '../route-oracle/interfaces/IRouteOracle.sol';

/**
 * @title Auto Compound Strategy
 * @notice handles deposits and withdraws on the underlying farm and auto-compound rewards
 * @author YieldWolf
 */
abstract contract AutoCompoundVault is ERC20, ReentrancyGuard, Pausable {
    using SafeERC20 for IERC20;

    IYieldWolf public immutable yieldWolf; // address of the YieldWolf staking contract
    address public immutable masterChef; // address of the farm staking contract
    uint256 public immutable pid; // pid of pool in the farm staking contract
    IERC20 public immutable stakeToken; // token staked on the underlying farm
    IERC20 public immutable earnToken; // reward token paid by the underlying farm
    address[] public extraEarnTokens; // some underlying farms can give rewards in multiple tokens
    mapping(address => bool) tokenRestricted; // these can never be used as an extra earn token or on tokenToEarn
    address immutable WNATIVE; // address of the network's wrapped native currency

    IRouteOracle public immutable routeOracle;

    bool public emergencyWithdrawn;

    uint256 constant PERFORMANCE_FEE = 300;

    event Deposit(address indexed user, uint256 amount);
    event Withdraw(address indexed user, uint256 amount);
    event Earn();
    event Farm();
    event EmergencyWithdraw();
    event TokenToEarn(address token);
    event WrapNative();
    event SetExtraEarnTokens(address[] _extraEarnTokens);
    event SetTokenRestricted(address _address);

    modifier onlyOwner() {
        require(address(yieldWolf) == _msgSender(), 'onlyOwner: not allowed');
        _;
    }

    modifier onlyOperator() {
        require(yieldWolf.operators(msg.sender), 'onlyOperator: not allowed');
        _;
    }

    function _farmDeposit(uint256 depositAmount) internal virtual;

    function _farmWithdraw(uint256 withdrawAmount) internal virtual;

    function _earnToStake(uint256 _earnAmount) internal virtual;

    function _farmEmergencyWithdraw() internal virtual;

    function _totalStaked() internal view virtual returns (uint256);

    receive() external payable {}

    constructor(uint256 _pid, address[6] memory _addresses) {
        yieldWolf = IYieldWolf(_addresses[0]);
        stakeToken = IERC20(_addresses[1]);
        earnToken = IERC20(_addresses[2]);
        masterChef = _addresses[3];
        routeOracle = IRouteOracle(_addresses[4]);
        WNATIVE = _addresses[5];
        pid = _pid;
        IERC20(stakeToken).approve(masterChef, type(uint256).max);
        tokenRestricted[address(this)] = true;
        tokenRestricted[address(earnToken)] = true;
        tokenRestricted[address(stakeToken)] = true;
    }

    /**
     * @notice deposits stake tokens in the underlying farm
     * @dev can only be called by YieldWolf contract which performs the required validations
     * @param _user address
     * @param _depositAmount amount deposited by the user
     */
    function deposit(address _user, uint256 _depositAmount) external virtual onlyOwner whenNotPaused {
        uint256 stakeTokenAmount = stakeToken.balanceOf(address(this));
        uint256 totalStakedBefore = _totalStaked() + stakeTokenAmount - _depositAmount;
        _farmDeposit(stakeTokenAmount);
        uint256 totalStakedAfter = _totalStaked() + stakeToken.balanceOf(address(this));

        // adjust for deposit fees on the underlying farm and token transfer fees
        _depositAmount = totalStakedAfter - totalStakedBefore;

        uint256 sharesAdded = _depositAmount;
        uint256 _totalSupply = totalSupply();
        if (totalStakedBefore > 0 && _totalSupply > 0) {
            sharesAdded = (_depositAmount * _totalSupply) / totalStakedBefore;
        }

        _mint(_user, sharesAdded);
        emit Deposit(_user, _depositAmount);
    }

    /**
     * @notice unstake tokens from the underlying farm and transfers them to the given address
     * @dev can only be called by YieldWolf contract
     * @param _user address that will receive the stake tokens
     * @param _withdrawAmount number of vault tokens to withdraw
     */
    function withdraw(address _user, uint256 _withdrawAmount) external virtual onlyOwner nonReentrant {
        require(_withdrawAmount > 0, 'withdraw: cannot be zero');
        uint256 totalStakedOnFarm = _totalStaked();
        uint256 stakeAmountBefore = stakeToken.balanceOf(address(this));
        uint256 totalStake = totalStakedOnFarm + stakeAmountBefore;
        uint256 sharesTotal = totalSupply();
        uint256 userBalance = balanceOf(_user);

        require(userBalance > 0, 'withdraw: no shares');

        uint256 maxAmount = (userBalance * totalStake) / sharesTotal;
        if (_withdrawAmount > maxAmount) {
            _withdrawAmount = maxAmount;
        }

        // number of shares that the withdraw amount represents (rounded up)
        uint256 sharesRemoved = (_withdrawAmount * sharesTotal - 1) / totalStake + 1;

        if (sharesRemoved > sharesTotal) {
            sharesRemoved = sharesTotal;
        }

        if (totalStakedOnFarm > 0) {
            _farmWithdraw(_withdrawAmount);
            uint256 totalWithdrawn = stakeToken.balanceOf(address(this)) - stakeAmountBefore;
            if (_withdrawAmount > totalWithdrawn) {
                _withdrawAmount = totalWithdrawn;
            }
        }

        uint256 stakeBalance = stakeToken.balanceOf(address(this));
        if (_withdrawAmount > stakeBalance) {
            _withdrawAmount = stakeBalance;
        }

        _burn(_user, sharesRemoved);
        stakeToken.safeTransfer(_user, _withdrawAmount);
        emit Withdraw(_user, _withdrawAmount);
    }

    /**
     * @notice deposits the contract's balance of stake tokens in the underlying farm
     */
    function farm() external virtual nonReentrant whenNotPaused {
        _farm();
        emit Farm();
    }

    /**
     * @notice harvests earn tokens and deposits stake tokens in the underlying farm
     * @param _bountyHunter address that will get paid the bounty reward
     */
    function earn(address _bountyHunter) external virtual nonReentrant returns (uint256 bountyReward) {
        if (paused()) {
            return 0;
        }

        // harvest earn tokens
        uint256 earnAmountBefore = earnToken.balanceOf(address(this));
        _farmHarvest();

        for (uint256 i; i < extraEarnTokens.length; ) {
            address extraEarnToken = extraEarnTokens[i];
            uint256 balanceExtraEarn = IERC20(extraEarnToken).balanceOf(address(this));
            _trySafeSwap(balanceExtraEarn, extraEarnToken, address(earnToken));
            unchecked {
                i++;
            }
        }

        uint256 earnAmountAfter = earnToken.balanceOf(address(this));
        uint256 harvestAmount = earnAmountAfter - earnAmountBefore;

        uint256 platformFee;
        if (harvestAmount > 0) {
            (bountyReward, platformFee) = _distributeFees(harvestAmount, _bountyHunter);
        }
        uint256 earnAmount = earnAmountAfter - platformFee - bountyReward;

        _earnToStake(earnAmount);
        _farm();

        if (_bountyHunter != address(0)) {
            emit Earn();
        }
    }

    /**
     * @notice pauses the vault in case of emergency
     * @dev can only be called by the operator. Only in case of emergency.
     */
    function pause() external virtual onlyOperator {
        _removeAllawences();
        _pause();
    }

    /**
     * @notice unpauses the vault
     * @dev can only be called by the operator
     */
    function unpause() external virtual onlyOperator {
        require(!emergencyWithdrawn, 'unpause: cannot unpause after emergency withdraw');
        _addAllawences();
        _unpause();
    }

    /**
     * @notice updates the list of extra earn tokens
     * @dev can only be called by the operator
     */
    function setExtraEarnTokens(address[] calldata _extraEarnTokens) external virtual onlyOperator {
        require(_extraEarnTokens.length <= 5, 'setExtraEarnTokens: cap exceeded');

        for (uint256 i; i < _extraEarnTokens.length; i++) {
            require(
                !tokenRestricted[_extraEarnTokens[i]] &&
                    _extraEarnTokens[i] != address(earnToken) &&
                    _extraEarnTokens[i] != address(stakeToken),
                'setExtraEarnTokens: not allowed'
            );

            // erc20 sanity check
            IERC20(_extraEarnTokens[i]).balanceOf(address(this));
        }

        extraEarnTokens = _extraEarnTokens;
        emit SetExtraEarnTokens(_extraEarnTokens);
    }

    function setTokenRestricted(address _addr) external onlyOperator {
        tokenRestricted[_addr] = true;
        emit SetTokenRestricted(_addr);
    }

    /**
     * @notice converts any token in the contract into earn tokens
     * @dev can only be called by the operator
     */
    function tokenToEarn(address _token) external virtual nonReentrant whenNotPaused onlyOperator {
        uint256 amount = IERC20(_token).balanceOf(address(this));
        require(!tokenRestricted[_token], 'tokenToEarn: not allowed');
        if (amount > 0) {
            _safeSwap(amount, _token, address(earnToken));
        }
        emit TokenToEarn(_token);
    }

    /**
     * @notice converts NATIVE into WNATIVE (e.g. ETH -> WETH)
     */
    function wrapNative() external virtual {
        uint256 balance = address(this).balance;
        if (balance > 0) {
            IWETH(WNATIVE).deposit{value: balance}();
        }
        emit WrapNative();
    }

    function totalStakeTokens() external view virtual returns (uint256) {
        return _totalStaked() + stakeToken.balanceOf(address(this));
    }

    /**
     * @notice invokes the emergency withdraw function in the underlying farm
     * @dev can only be called by the operator. Only in case of emergency.
     */
    function emergencyWithdraw() external virtual onlyOperator {
        if (!paused()) {
            _pause();
        }
        emergencyWithdrawn = true;
        _farmEmergencyWithdraw();
        emit EmergencyWithdraw();
    }

    function _farm() internal virtual {
        uint256 depositAmount = stakeToken.balanceOf(address(this));
        _farmDeposit(depositAmount);
    }

    function _farmHarvest() internal virtual {
        _farmDeposit(0);
    }

    function _distributeFees(uint256 _amount, address _bountyHunter)
        internal
        virtual
        returns (uint256 bountyReward, uint256 platformFee)
    {
        platformFee = (_amount * PERFORMANCE_FEE) / 10000;
        if (_bountyHunter != address(0)) {
            bountyReward = platformFee / 10;
            unchecked {
                platformFee = platformFee - bountyReward;
            }
            earnToken.safeTransfer(_bountyHunter, bountyReward);
        }
        earnToken.safeTransfer(yieldWolf.feeAddress(), platformFee);
    }

    function _addAllawences() internal virtual {
        IERC20(stakeToken).approve(masterChef, type(uint256).max);
    }

    function _removeAllawences() internal virtual {
        IERC20(stakeToken).approve(masterChef, 0);
        for (uint256 i; i < extraEarnTokens.length; i++) {
            IERC20(extraEarnTokens[i]).approve(masterChef, 0);
        }
    }

    function _safeSwap(
        uint256 _amountIn,
        address _tokenFrom,
        address _tokenTo
    ) internal virtual {
        (address router, address nextToken, bytes memory sig) = routeOracle.resolveSwapExactTokensForTokens(
            _amountIn,
            _tokenFrom,
            _tokenTo,
            address(this)
        );
        require(router != address(this) && router != masterChef, '_safeSwap: invalid router');
        if (router == address(stakeToken)) {
            require(
                !(sig[0] == 0xa9 && sig[1] == 0x05 && sig[2] == 0x9c && sig[3] == 0xbb) &&
                    !(sig[0] == 0x23 && sig[1] == 0xb8 && sig[2] == 0x72 && sig[3] == 0xdd) &&
                    !(sig[0] == 0x09 && sig[1] == 0x5e && sig[2] == 0xa7 && sig[3] == 0xb3),
                '_safeSwap: not allowed'
            );
        }
        if (IERC20(_tokenFrom).allowance(address(this), router) < _amountIn) {
            IERC20(_tokenFrom).approve(router, type(uint256).max);
        }
        uint256 nextTokenBalanceBefore;
        if (nextToken != address(0)) {
            nextTokenBalanceBefore = IERC20(nextToken).balanceOf(address(this));
        }
        (bool success, ) = router.call(sig);
        require(success, '_safeSwap: swap failed');
        if (nextToken != address(0)) {
            uint256 nextTokenAmount = IERC20(nextToken).balanceOf(address(this)) - nextTokenBalanceBefore;
            _safeSwap(nextTokenAmount, nextToken, _tokenTo);
        }
    }

    function _trySafeSwap(
        uint256 _amountIn,
        address _tokenFrom,
        address _tokenTo
    ) internal virtual {
        (address router, address nextToken, bytes memory sig) = routeOracle.resolveSwapExactTokensForTokens(
            _amountIn,
            _tokenFrom,
            _tokenTo,
            address(this)
        );
        require(router != address(this) && router != masterChef, '_trySafeSwap: invalid router');
        if (router == address(stakeToken)) {
            require(
                !(sig[0] == 0xa9 && sig[1] == 0x05 && sig[2] == 0x9c && sig[3] == 0xbb) &&
                    !(sig[0] == 0x23 && sig[1] == 0xb8 && sig[2] == 0x72 && sig[3] == 0xdd) &&
                    !(sig[0] == 0x09 && sig[1] == 0x5e && sig[2] == 0xa7 && sig[3] == 0xb3),
                '_trySafeSwap: not allowed'
            );
        }
        if (IERC20(_tokenFrom).allowance(address(this), router) < _amountIn) {
            IERC20(_tokenFrom).approve(router, type(uint256).max);
        }
        uint256 nextTokenBalanceBefore;
        if (nextToken != address(0)) {
            nextTokenBalanceBefore = IERC20(nextToken).balanceOf(address(this));
        }
        (bool success, ) = router.call(sig);
        if (success && nextToken != address(0)) {
            uint256 nextTokenAmount = IERC20(nextToken).balanceOf(address(this)) - nextTokenBalanceBefore;
            _safeSwap(nextTokenAmount, nextToken, _tokenTo);
        }
    }
}

File 7 of 17 : IUniswapV2Router01.sol
pragma solidity >=0.6.2;

interface IUniswapV2Router01 {
    function factory() external pure returns (address);
    function WETH() external pure returns (address);

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB, uint liquidity);
    function addLiquidityETH(
        address token,
        uint amountTokenDesired,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external payable returns (uint amountToken, uint amountETH, uint liquidity);
    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB);
    function removeLiquidityETH(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external returns (uint amountToken, uint amountETH);
    function removeLiquidityWithPermit(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountA, uint amountB);
    function removeLiquidityETHWithPermit(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountToken, uint amountETH);
    function swapExactTokensForTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
    function swapTokensForExactTokens(
        uint amountOut,
        uint amountInMax,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
    function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        payable
        returns (uint[] memory amounts);
    function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
        external
        returns (uint[] memory amounts);
    function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        returns (uint[] memory amounts);
    function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
        external
        payable
        returns (uint[] memory amounts);

    function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
    function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
    function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
    function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
    function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
}

File 8 of 17 : ERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;

import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, _allowances[owner][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = _allowances[owner][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `sender` to `recipient`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _balances[to] += amount;

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Spend `amount` form the allowance of `owner` toward `spender`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

File 9 of 17 : SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";
import "../../../utils/Address.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 10 of 17 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

File 11 of 17 : Pausable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

File 12 of 17 : IWETH.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

import '@openzeppelin/contracts/token/ERC20/IERC20.sol';

interface IWETH is IERC20 {
    function deposit() external payable;

    function withdraw(uint256 wad) external;
}

File 13 of 17 : IYieldWolf.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

interface IYieldWolf {
    function operators(address addr) external returns (bool);

    function feeAddress() external returns (address);

    function stakedTokens(uint256 pid, address user) external view returns (uint256);
}

File 14 of 17 : IRouteOracle.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

interface IRouteOracle {
    function resolveSwapExactTokensForTokens(
        uint256 amountIn,
        address tokenFrom,
        address tokenTo,
        address recipient
    )
        external
        view
        returns (
            address router,
            address nextToken,
            bytes memory sig
        );
}

File 15 of 17 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

File 16 of 17 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @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 17 of 17 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @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);
            }
        }
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address[6]","name":"_addresses","type":"address[6]"},{"internalType":"contract IUniswapV2Router02","name":"_liquidityRouter","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[],"name":"Earn","type":"event"},{"anonymous":false,"inputs":[],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[],"name":"Farm","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"_extraEarnTokens","type":"address[]"}],"name":"SetExtraEarnTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_address","type":"address"}],"name":"SetTokenRestricted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"}],"name":"TokenToEarn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[],"name":"WrapNative","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_depositAmount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_bountyHunter","type":"address"}],"name":"earn","outputs":[{"internalType":"uint256","name":"bountyReward","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"earnToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencyWithdrawn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"extraEarnTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"farm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"liquidityRouter","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"masterChef","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"routeOracle","outputs":[{"internalType":"contract IRouteOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_extraEarnTokens","type":"address[]"}],"name":"setExtraEarnTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"setTokenRestricted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakeToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token0","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token1","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"tokenToEarn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalStakeTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_withdrawAmount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wrapNative","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"yieldWolf","outputs":[{"internalType":"contract IYieldWolf","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

6101c06040523480156200001257600080fd5b506040516200514f3803806200514f8339810160408190526200003591620005ab565b82828686816003908051906020019062000051929190620003d1565b50805162000067906004906020840190620003d1565b50506001600555506006805460ff1916905580516001600160a01b0390811660809081526020830151821660e08190526040808501518416610100526060850151841660a081815293860151851661014052928501519093166101205260c0859052915163095ea7b360e01b81526004810191909152600019602482015263095ea7b390604401602060405180830381600087803b1580156200010957600080fd5b505af11580156200011e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000144919062000692565b5050306000908152600860205260408082208054600160ff199182168117909255610100516001600160a01b039081168552838520805483168417905560e0511684529190922080549091168217905583915060200201516001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015620001d557600080fd5b505afa158015620001ea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002109190620006bd565b6001600160a01b03166101805281600160200201516001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156200025e57600080fd5b505afa15801562000273573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002999190620006bd565b6001600160a01b039081166101a0528181166101608190526101805160405163095ea7b360e01b8152600481019290925260001960248301529091169063095ea7b390604401602060405180830381600087803b158015620002fa57600080fd5b505af11580156200030f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000335919062000692565b506101a0516101605160405163095ea7b360e01b81526001600160a01b039182166004820152600019602482015291169063095ea7b390604401602060405180830381600087803b1580156200038a57600080fd5b505af11580156200039f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003c5919062000692565b5050505050506200071a565b828054620003df90620006dd565b90600052602060002090601f0160209004810192826200040357600085556200044e565b82601f106200041e57805160ff19168380011785556200044e565b828001600101855582156200044e579182015b828111156200044e57825182559160200191906001019062000431565b506200045c92915062000460565b5090565b5b808211156200045c576000815560010162000461565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715620004b257620004b262000477565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620004e357620004e362000477565b604052919050565b600082601f830112620004fd57600080fd5b81516001600160401b0381111562000519576200051962000477565b60206200052f601f8301601f19168201620004b8565b82815285828487010111156200054457600080fd5b60005b838110156200056457858101830151828201840152820162000547565b83811115620005765760008385840101525b5095945050505050565b6001600160a01b03811681146200059657600080fd5b50565b8051620005a68162000580565b919050565b60008060008060006101408688031215620005c557600080fd5b85516001600160401b0380821115620005dd57600080fd5b620005eb89838a01620004eb565b96506020915081880151818111156200060357600080fd5b620006118a828b01620004eb565b965050506040870151935087607f8801126200062c57600080fd5b620006366200048d565b8061012089018a8111156200064a57600080fd5b60608a015b8181101562000673578051620006658162000580565b84529284019284016200064f565b50819550620006828162000599565b9450505050509295509295909350565b600060208284031215620006a557600080fd5b81518015158114620006b657600080fd5b9392505050565b600060208284031215620006d057600080fd5b8151620006b68162000580565b600181811c90821680620006f257607f821691505b602082108114156200071457634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516147f962000956600039600081816105da015281816124f101528181612a1501528181613cb401528181613d3b01528181613e1c0152613ed40152600081816102cd0152818161242d0152818161295201528181613c1001528181613c8e01528181613d770152613eac015260008181610340015281816123fd015281816124c101528181612923015281816129e60152613f270152600081816104b101528181612ad70152613492015260006110d30152600081816106d701528181610ec1015281816114e401528181611c5401528181611d9101528181611dd801528181613b0a01528181613bd101528181613c3a01528181613c6d01528181613cde0152613d1a01526000818161041101528181610a1f01528181610b6401528181610c2b01528181610f25015281816118a001528181611a3101528181611add01528181611b8401528181612292015281816123690152818161288f01528181612bf701526135b20152600081816106a301528181612610015281816126d5015281816131b7015261324c015260008181610465015281816123390152818161263f015281816127020152818161286001528181612b74015281816131dd01528181613279015261352f015260008181610281015281816108e901528181610aba01528181610d73015281816111870152818161135101528181611562015281816116710152818161178f0152613b3601526147f96000f3fe6080604052600436106102085760003560e01c806367aee00011610118578063d21220a7116100a0578063edfb9b6e1161006f578063edfb9b6e14610671578063f106845414610691578063f1f98e12146106c5578063f3fef3a3146106f9578063fdb5fefc1461071957600080fd5b8063d21220a7146105c8578063db2e21bc146105fc578063dd62ed3e14610611578063e28701ee1461065757600080fd5b806395d89b41116100e757806395d89b4114610533578063a457c2d714610548578063a9059cbb14610568578063ada1a9a914610588578063c7684081146105a857600080fd5b806367aee0001461049f5780636ad481f3146104d357806370a08231146104e85780638456cb591461051e57600080fd5b806336e9332d1161019b57806347e7ef241161016a57806347e7ef24146103df57806351ed6a30146103ff578063559ae48a14610433578063575a86b2146104535780635c975abb1461048757600080fd5b806336e9332d1461037e57806339509351146103955780633f4ba83a146103b557806340a65823146103ca57600080fd5b806318160ddd116101d757806318160ddd146102ef57806323b872dd1461030e578063247029441461032e578063313ce5671461036257600080fd5b806306fdde0314610214578063095ea7b31461023f5780630c8fb80e1461026f5780630dfe1681146102bb57600080fd5b3661020f57005b600080fd5b34801561022057600080fd5b50610229610739565b60405161023691906142a6565b60405180910390f35b34801561024b57600080fd5b5061025f61025a3660046142ee565b6107cb565b6040519015158152602001610236565b34801561027b57600080fd5b506102a37f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610236565b3480156102c757600080fd5b506102a37f000000000000000000000000000000000000000000000000000000000000000081565b3480156102fb57600080fd5b506002545b604051908152602001610236565b34801561031a57600080fd5b5061025f61032936600461431a565b6107e3565b34801561033a57600080fd5b506102a37f000000000000000000000000000000000000000000000000000000000000000081565b34801561036e57600080fd5b5060405160128152602001610236565b34801561038a57600080fd5b50610393610809565b005b3480156103a157600080fd5b5061025f6103b03660046142ee565b610895565b3480156103c157600080fd5b506103936108d4565b3480156103d657600080fd5b50610300610a07565b3480156103eb57600080fd5b506103936103fa3660046142ee565b610ab8565b34801561040b57600080fd5b506102a37f000000000000000000000000000000000000000000000000000000000000000081565b34801561043f57600080fd5b5061039361044e36600461435b565b610d5e565b34801561045f57600080fd5b506102a37f000000000000000000000000000000000000000000000000000000000000000081565b34801561049357600080fd5b5060065460ff1661025f565b3480156104ab57600080fd5b506102a37f000000000000000000000000000000000000000000000000000000000000000081565b3480156104df57600080fd5b506103936110ca565b3480156104f457600080fd5b506103006105033660046143d0565b6001600160a01b031660009081526020819052604090205490565b34801561052a57600080fd5b50610393611172565b34801561053f57600080fd5b50610229611237565b34801561055457600080fd5b5061025f6105633660046142ee565b611246565b34801561057457600080fd5b5061025f6105833660046142ee565b6112e3565b34801561059457600080fd5b506103936105a33660046143d0565b6112f1565b3480156105b457600080fd5b506103936105c33660046143d0565b61154d565b3480156105d457600080fd5b506102a37f000000000000000000000000000000000000000000000000000000000000000081565b34801561060857600080fd5b5061039361165c565b34801561061d57600080fd5b5061030061062c3660046143ed565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b34801561066357600080fd5b5060095461025f9060ff1681565b34801561067d57600080fd5b506102a361068c366004614426565b611763565b34801561069d57600080fd5b506103007f000000000000000000000000000000000000000000000000000000000000000081565b3480156106d157600080fd5b506102a37f000000000000000000000000000000000000000000000000000000000000000081565b34801561070557600080fd5b506103936107143660046142ee565b61178d565b34801561072557600080fd5b506103006107343660046143d0565b611bff565b6060600380546107489061443f565b80601f01602080910402602001604051908101604052809291908181526020018280546107749061443f565b80156107c15780601f10610796576101008083540402835291602001916107c1565b820191906000526020600020905b8154815290600101906020018083116107a457829003601f168201915b5050505050905090565b6000336107d9818585611ef5565b5060019392505050565b6000336107f185828561201a565b6107fc8585856120ac565b60019150505b9392505050565b600260055414156108355760405162461bcd60e51b815260040161082c90614474565b60405180910390fd5b600260055560065460ff161561085d5760405162461bcd60e51b815260040161082c906144ab565b61086561227a565b6040517fc14affbacf095aeb5f706cd9e32fae5ae213b9d1118f26bff45ef8efb26ef4be90600090a16001600555565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091906107d990829086906108cf9087906144eb565b611ef5565b60405163027cf93b60e31b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906313e7c9d890602401602060405180830381600087803b15801561093557600080fd5b505af1158015610949573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096d9190614503565b6109895760405162461bcd60e51b815260040161082c90614525565b60095460ff16156109f55760405162461bcd60e51b815260206004820152603060248201527f756e70617573653a2063616e6e6f7420756e706175736520616674657220656d60448201526f657267656e637920776974686472617760801b606482015260840161082c565b6109fd612322565b610a0561256e565b565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015610a6957600080fd5b505afa158015610a7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa1919061455c565b610aa9612601565b610ab391906144eb565b905090565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163314610b295760405162461bcd60e51b81526020600482015260166024820152751bdb9b1e53dddb995c8e881b9bdd08185b1b1bddd95960521b604482015260640161082c565b60065460ff1615610b4c5760405162461bcd60e51b815260040161082c906144ab565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015610bae57600080fd5b505afa158015610bc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be6919061455c565b905060008282610bf4612601565b610bfe91906144eb565b610c089190614575565b9050610c13826126c6565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015610c7557600080fd5b505afa158015610c89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cad919061455c565b610cb5612601565b610cbf91906144eb565b9050610ccb8282614575565b9350836000610cd960025490565b9050600084118015610ceb5750600081115b15610d085783610cfb828861458c565b610d0591906145ab565b91505b610d12878361276a565b866001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c87604051610d4d91815260200190565b60405180910390a250505050505050565b60405163027cf93b60e31b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906313e7c9d890602401602060405180830381600087803b158015610dbf57600080fd5b505af1158015610dd3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df79190614503565b610e135760405162461bcd60e51b815260040161082c90614525565b6005811115610e645760405162461bcd60e51b815260206004820181905260248201527f73657445787472614561726e546f6b656e733a20636170206578636565646564604482015260640161082c565b60005b8181101561107f5760086000848484818110610e8557610e856145cd565b9050602002016020810190610e9a91906143d0565b6001600160a01b0316815260208101919091526040016000205460ff16158015610f1c57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316838383818110610efb57610efb6145cd565b9050602002016020810190610f1091906143d0565b6001600160a01b031614155b8015610f8057507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316838383818110610f5f57610f5f6145cd565b9050602002016020810190610f7491906143d0565b6001600160a01b031614155b610fcc5760405162461bcd60e51b815260206004820152601f60248201527f73657445787472614561726e546f6b656e733a206e6f7420616c6c6f77656400604482015260640161082c565b828282818110610fde57610fde6145cd565b9050602002016020810190610ff391906143d0565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a082319060240160206040518083038186803b15801561103457600080fd5b505afa158015611048573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106c919061455c565b5080611077816145e3565b915050610e67565b5061108c60078383614202565b507febf5a470e091904c67cf04ce5dedf0e052ed1bef8c69bbad9617e4655bd016c282826040516110be9291906145fe565b60405180910390a15050565b478015611146577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561112c57600080fd5b505af1158015611140573d6000803e3d6000fd5b50505050505b6040517fc41bad047fb7e343ff0242ad2895fd09379af34386f2c70cbc07952a3e2bacdf90600090a150565b60405163027cf93b60e31b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906313e7c9d890602401602060405180830381600087803b1580156111d357600080fd5b505af11580156111e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061120b9190614503565b6112275760405162461bcd60e51b815260040161082c90614525565b61122f612849565b610a05612a44565b6060600480546107489061443f565b3360008181526001602090815260408083206001600160a01b0387168452909152812054909190838110156112cb5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161082c565b6112d88286868403611ef5565b506001949350505050565b6000336107d98185856120ac565b600260055414156113145760405162461bcd60e51b815260040161082c90614474565b600260055560065460ff161561133c5760405162461bcd60e51b815260040161082c906144ab565b60405163027cf93b60e31b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906313e7c9d890602401602060405180830381600087803b15801561139d57600080fd5b505af11580156113b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d59190614503565b6113f15760405162461bcd60e51b815260040161082c90614525565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a082319060240160206040518083038186803b15801561143357600080fd5b505afa158015611447573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061146b919061455c565b6001600160a01b03831660009081526008602052604090205490915060ff16156114d75760405162461bcd60e51b815260206004820152601860248201527f746f6b656e546f4561726e3a206e6f7420616c6c6f7765640000000000000000604482015260640161082c565b80156115085761150881837f0000000000000000000000000000000000000000000000000000000000000000612a9c565b6040516001600160a01b03831681527fe5bc9466ffc0962b4f5d02c904fde9d62a936d1046497e9b764169c526dc07599060200160405180910390a150506001600555565b60405163027cf93b60e31b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906313e7c9d890602401602060405180830381600087803b1580156115ae57600080fd5b505af11580156115c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e69190614503565b6116025760405162461bcd60e51b815260040161082c90614525565b6001600160a01b038116600081815260086020908152604091829020805460ff1916600117905590519182527f9c464392efe1c423e98323fa87ae0d3a5631b9fe33099a17c07c30c205df92d8910160405180910390a150565b60405163027cf93b60e31b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906313e7c9d890602401602060405180830381600087803b1580156116bd57600080fd5b505af11580156116d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f59190614503565b6117115760405162461bcd60e51b815260040161082c90614525565b60065460ff1661172357611723612a44565b6009805460ff191660011790556117386131a8565b6040517fcc6a1a065ab514031862e10458cbf117148ff1f8a168cfacab350e6644c174f090600090a1565b6007818154811061177357600080fd5b6000918252602090912001546001600160a01b0316905081565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633146117fe5760405162461bcd60e51b81526020600482015260166024820152751bdb9b1e53dddb995c8e881b9bdd08185b1b1bddd95960521b604482015260640161082c565b600260055414156118215760405162461bcd60e51b815260040161082c90614474565b6002600555806118735760405162461bcd60e51b815260206004820152601860248201527f77697468647261773a2063616e6e6f74206265207a65726f0000000000000000604482015260640161082c565b600061187d612601565b6040516370a0823160e01b81523060048201529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a082319060240160206040518083038186803b1580156118e257600080fd5b505afa1580156118f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061191a919061455c565b9050600061192882846144eb565b9050600061193560025490565b90506000611958876001600160a01b031660009081526020819052604090205490565b9050600081116119a05760405162461bcd60e51b815260206004820152601360248201527277697468647261773a206e6f2073686172657360681b604482015260640161082c565b6000826119ad858461458c565b6119b791906145ab565b9050808711156119c5578096505b60008460016119d4868b61458c565b6119de9190614575565b6119e891906145ab565b6119f39060016144eb565b905083811115611a005750825b8615611ac557611a0f8861323d565b6040516370a0823160e01b815230600482015260009087906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a082319060240160206040518083038186803b158015611a7357600080fd5b505afa158015611a87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aab919061455c565b611ab59190614575565b905080891115611ac3578098505b505b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015611b2757600080fd5b505afa158015611b3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b5f919061455c565b905080891115611b6d578098505b611b778a836132b0565b611bab6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168b8b6133fb565b896001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a94243648a604051611be691815260200190565b60405180910390a2505060016005555050505050505050565b600060026005541415611c245760405162461bcd60e51b815260040161082c90614474565b600260055560065460ff1615611c3c57506000611eeb565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015611c9e57600080fd5b505afa158015611cb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cd6919061455c565b9050611ce061344d565b60005b600754811015611dbf57600060078281548110611d0257611d026145cd565b60009182526020822001546040516370a0823160e01b81523060048201526001600160a01b03909116925082906370a082319060240160206040518083038186803b158015611d5057600080fd5b505afa158015611d64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d88919061455c565b9050611db581837f0000000000000000000000000000000000000000000000000000000000000000613457565b5050600101611ce3565b506040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015611e2257600080fd5b505afa158015611e36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e5a919061455c565b90506000611e688383614575565b905060008115611e8257611e7c8287613ac0565b90955090505b600085611e8f8386614575565b611e999190614575565b9050611ea481613bff565b611eac61227a565b6001600160a01b03871615611ee5576040517f20469ab8832a9d2c7e1dd6db951dec84658d81648a578eb0ba8b73afe206aca290600090a15b50505050505b6001600555919050565b6001600160a01b038316611f575760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161082c565b6001600160a01b038216611fb85760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161082c565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146120a657818110156120995760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161082c565b6120a68484848403611ef5565b50505050565b6001600160a01b0383166121105760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161082c565b6001600160a01b0382166121725760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161082c565b6001600160a01b038316600090815260208190526040902054818110156121ea5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161082c565b6001600160a01b038085166000908152602081905260408082208585039055918516815290812080548492906122219084906144eb565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161226d91815260200190565b60405180910390a36120a6565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b1580156122dc57600080fd5b505afa1580156122f0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612314919061455c565b905061231f816126c6565b50565b60405163095ea7b360e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015260001960248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b390604401602060405180830381600087803b1580156123ad57600080fd5b505af11580156123c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e59190614503565b5060405163095ea7b360e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015260001960248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b390604401602060405180830381600087803b15801561247157600080fd5b505af1158015612485573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a99190614503565b5060405163095ea7b360e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015260001960248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044015b602060405180830381600087803b15801561253657600080fd5b505af115801561254a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061231f9190614503565b60065460ff166125b75760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161082c565b6006805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6040516393f1a40b60e01b81527f000000000000000000000000000000000000000000000000000000000000000060048201523060248201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906393f1a40b90604401604080518083038186803b15801561268857600080fd5b505afa15801561269c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c0919061464c565b50919050565b604051631c57762b60e31b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e2bbb158906044015b600060405180830381600087803b15801561274f57600080fd5b505af1158015612763573d6000803e3d6000fd5b5050505050565b6001600160a01b0382166127c05760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161082c565b80600260008282546127d291906144eb565b90915550506001600160a01b038216600090815260208190526040812080548392906127ff9084906144eb565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60405163095ea7b360e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152600060248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b390604401602060405180830381600087803b1580156128d357600080fd5b505af11580156128e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290b9190614503565b5060405163095ea7b360e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152600060248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b390604401602060405180830381600087803b15801561299657600080fd5b505af11580156129aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129ce9190614503565b5060405163095ea7b360e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152600060248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b39060440161251c565b60065460ff1615612a675760405162461bcd60e51b815260040161082c906144ab565b6006805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586125e43390565b6040516313e7550d60e01b8152600481018490526001600160a01b0383811660248301528281166044830152306064830152600091829182917f0000000000000000000000000000000000000000000000000000000000000000909116906313e7550d9060840160006040518083038186803b158015612b1b57600080fd5b505afa158015612b2f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612b579190810190614686565b919450925090506001600160a01b0383163014801590612ba957507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614155b612bf55760405162461bcd60e51b815260206004820152601960248201527f5f73616665537761703a20696e76616c696420726f7574657200000000000000604482015260640161082c565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b03161415612ebb5780600081518110612c4257612c426145cd565b6020910101516001600160f81b03191660a960f81b148015612c89575080600181518110612c7257612c726145cd565b6020910101516001600160f81b031916600560f81b145b8015612cba575080600281518110612ca357612ca36145cd565b6020910101516001600160f81b031916602760fa1b145b8015612ceb575080600381518110612cd457612cd46145cd565b6020910101516001600160f81b03191660bb60f81b145b158015612db1575080600081518110612d0657612d066145cd565b6020910101516001600160f81b031916602360f81b148015612d4d575080600181518110612d3657612d366145cd565b6020910101516001600160f81b031916601760fb1b145b8015612d7e575080600281518110612d6757612d676145cd565b6020910101516001600160f81b031916603960f91b145b8015612daf575080600381518110612d9857612d986145cd565b6020910101516001600160f81b03191660dd60f81b145b155b8015612e76575080600081518110612dcb57612dcb6145cd565b6020910101516001600160f81b031916600960f81b148015612e12575080600181518110612dfb57612dfb6145cd565b6020910101516001600160f81b031916602f60f91b145b8015612e43575080600281518110612e2c57612e2c6145cd565b6020910101516001600160f81b03191660a760f81b145b8015612e74575080600381518110612e5d57612e5d6145cd565b6020910101516001600160f81b03191660b360f81b145b155b612ebb5760405162461bcd60e51b815260206004820152601660248201527517dcd8599954ddd85c0e881b9bdd08185b1b1bddd95960521b604482015260640161082c565b604051636eb1769f60e11b81523060048201526001600160a01b03848116602483015287919087169063dd62ed3e9060440160206040518083038186803b158015612f0557600080fd5b505afa158015612f19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f3d919061455c565b1015612fc85760405163095ea7b360e01b81526001600160a01b038481166004830152600019602483015286169063095ea7b390604401602060405180830381600087803b158015612f8e57600080fd5b505af1158015612fa2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fc69190614503565b505b60006001600160a01b03831615613053576040516370a0823160e01b81523060048201526001600160a01b038416906370a082319060240160206040518083038186803b15801561301857600080fd5b505afa15801561302c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613050919061455c565b90505b6000846001600160a01b03168360405161306d919061475c565b6000604051808303816000865af19150503d80600081146130aa576040519150601f19603f3d011682016040523d82523d6000602084013e6130af565b606091505b50509050806130f95760405162461bcd60e51b815260206004820152601660248201527517dcd8599954ddd85c0e881cddd85c0819985a5b195960521b604482015260640161082c565b6001600160a01b0384161561319e576040516370a0823160e01b815230600482015260009083906001600160a01b038716906370a08231906024015b60206040518083038186803b15801561314d57600080fd5b505afa158015613161573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613185919061455c565b61318f9190614575565b905061319c818689612a9c565b505b5050505050505050565b604051632989754760e11b81527f000000000000000000000000000000000000000000000000000000000000000060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635312ea8e90602401600060405180830381600087803b15801561322957600080fd5b505af11580156120a6573d6000803e3d6000fd5b604051630441a3e760e41b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063441a3e7090604401612735565b6001600160a01b0382166133105760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161082c565b6001600160a01b038216600090815260208190526040902054818110156133845760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161082c565b6001600160a01b03831660009081526020819052604081208383039055600280548492906133b3908490614575565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200161200d565b505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526133f6908490613faf565b610a0560006126c6565b6040516313e7550d60e01b8152600481018490526001600160a01b0383811660248301528281166044830152306064830152600091829182917f0000000000000000000000000000000000000000000000000000000000000000909116906313e7550d9060840160006040518083038186803b1580156134d657600080fd5b505afa1580156134ea573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526135129190810190614686565b919450925090506001600160a01b038316301480159061356457507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614155b6135b05760405162461bcd60e51b815260206004820152601c60248201527f5f74727953616665537761703a20696e76616c696420726f7574657200000000604482015260640161082c565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316141561387d57806000815181106135fd576135fd6145cd565b6020910101516001600160f81b03191660a960f81b14801561364457508060018151811061362d5761362d6145cd565b6020910101516001600160f81b031916600560f81b145b801561367557508060028151811061365e5761365e6145cd565b6020910101516001600160f81b031916602760fa1b145b80156136a657508060038151811061368f5761368f6145cd565b6020910101516001600160f81b03191660bb60f81b145b15801561376c5750806000815181106136c1576136c16145cd565b6020910101516001600160f81b031916602360f81b1480156137085750806001815181106136f1576136f16145cd565b6020910101516001600160f81b031916601760fb1b145b8015613739575080600281518110613722576137226145cd565b6020910101516001600160f81b031916603960f91b145b801561376a575080600381518110613753576137536145cd565b6020910101516001600160f81b03191660dd60f81b145b155b8015613831575080600081518110613786576137866145cd565b6020910101516001600160f81b031916600960f81b1480156137cd5750806001815181106137b6576137b66145cd565b6020910101516001600160f81b031916602f60f91b145b80156137fe5750806002815181106137e7576137e76145cd565b6020910101516001600160f81b03191660a760f81b145b801561382f575080600381518110613818576138186145cd565b6020910101516001600160f81b03191660b360f81b145b155b61387d5760405162461bcd60e51b815260206004820152601960248201527f5f74727953616665537761703a206e6f7420616c6c6f77656400000000000000604482015260640161082c565b604051636eb1769f60e11b81523060048201526001600160a01b03848116602483015287919087169063dd62ed3e9060440160206040518083038186803b1580156138c757600080fd5b505afa1580156138db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138ff919061455c565b101561398a5760405163095ea7b360e01b81526001600160a01b038481166004830152600019602483015286169063095ea7b390604401602060405180830381600087803b15801561395057600080fd5b505af1158015613964573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139889190614503565b505b60006001600160a01b03831615613a15576040516370a0823160e01b81523060048201526001600160a01b038416906370a082319060240160206040518083038186803b1580156139da57600080fd5b505afa1580156139ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a12919061455c565b90505b6000846001600160a01b031683604051613a2f919061475c565b6000604051808303816000865af19150503d8060008114613a6c576040519150601f19603f3d011682016040523d82523d6000602084013e613a71565b606091505b50509050808015613a8a57506001600160a01b03841615155b1561319e576040516370a0823160e01b815230600482015260009083906001600160a01b038716906370a0823190602401613135565b600080612710613ad261012c8661458c565b613adc91906145ab565b90506001600160a01b03831615613b3157613af8600a826145ab565b9150819003613b316001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001684846133fb565b613bf87f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663412753586040518163ffffffff1660e01b8152600401602060405180830381600087803b158015613b8f57600080fd5b505af1158015613ba3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bc79190614778565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690836133fb565b9250929050565b6000613c0c6002836145ab565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614613cb257613cb2817f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000612a9c565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614613d5f57613d5f613d188284614575565b7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000612a9c565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015613dc157600080fd5b505afa158015613dd5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613df9919061455c565b6040516370a0823160e01b81523060048201529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a082319060240160206040518083038186803b158015613e5e57600080fd5b505afa158015613e72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e96919061455c565b60405162e8e33760e81b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000081166024830152604482018590526064820183905260016084830181905260a48301523060c48301524260e48301529192507f00000000000000000000000000000000000000000000000000000000000000009091169063e8e337009061010401606060405180830381600087803b158015613f6e57600080fd5b505af1158015613f82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fa69190614795565b50505050505050565b6000614004826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166140819092919063ffffffff16565b8051909150156133f657808060200190518101906140229190614503565b6133f65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161082c565b60606140908484600085614098565b949350505050565b6060824710156140f95760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161082c565b6001600160a01b0385163b6141505760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161082c565b600080866001600160a01b0316858760405161416c919061475c565b60006040518083038185875af1925050503d80600081146141a9576040519150601f19603f3d011682016040523d82523d6000602084013e6141ae565b606091505b50915091506141be8282866141c9565b979650505050505050565b606083156141d8575081610802565b8251156141e85782518084602001fd5b8160405162461bcd60e51b815260040161082c91906142a6565b828054828255906000526020600020908101928215614255579160200282015b828111156142555781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190614222565b50614261929150614265565b5090565b5b808211156142615760008155600101614266565b60005b8381101561429557818101518382015260200161427d565b838111156120a65750506000910152565b60208152600082518060208401526142c581604085016020870161427a565b601f01601f19169190910160400192915050565b6001600160a01b038116811461231f57600080fd5b6000806040838503121561430157600080fd5b823561430c816142d9565b946020939093013593505050565b60008060006060848603121561432f57600080fd5b833561433a816142d9565b9250602084013561434a816142d9565b929592945050506040919091013590565b6000806020838503121561436e57600080fd5b823567ffffffffffffffff8082111561438657600080fd5b818501915085601f83011261439a57600080fd5b8135818111156143a957600080fd5b8660208260051b85010111156143be57600080fd5b60209290920196919550909350505050565b6000602082840312156143e257600080fd5b8135610802816142d9565b6000806040838503121561440057600080fd5b823561440b816142d9565b9150602083013561441b816142d9565b809150509250929050565b60006020828403121561443857600080fd5b5035919050565b600181811c9082168061445357607f821691505b602082108114156126c057634e487b7160e01b600052602260045260246000fd5b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082198211156144fe576144fe6144d5565b500190565b60006020828403121561451557600080fd5b8151801515811461080257600080fd5b60208082526019908201527f6f6e6c794f70657261746f723a206e6f7420616c6c6f77656400000000000000604082015260600190565b60006020828403121561456e57600080fd5b5051919050565b600082821015614587576145876144d5565b500390565b60008160001904831182151516156145a6576145a66144d5565b500290565b6000826145c857634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b60006000198214156145f7576145f76144d5565b5060010190565b60208082528181018390526000908460408401835b86811015614641578235614626816142d9565b6001600160a01b031682529183019190830190600101614613565b509695505050505050565b6000806040838503121561465f57600080fd5b505080516020909101519092909150565b634e487b7160e01b600052604160045260246000fd5b60008060006060848603121561469b57600080fd5b83516146a6816142d9565b60208501519093506146b7816142d9565b604085015190925067ffffffffffffffff808211156146d557600080fd5b818601915086601f8301126146e957600080fd5b8151818111156146fb576146fb614670565b604051601f8201601f19908116603f0116810190838211818310171561472357614723614670565b8160405282815289602084870101111561473c57600080fd5b61474d83602083016020880161427a565b80955050505050509250925092565b6000825161476e81846020870161427a565b9190910192915050565b60006020828403121561478a57600080fd5b8151610802816142d9565b6000806000606084860312156147aa57600080fd5b835192506020840151915060408401519050925092509256fea2646970667358221220bee5716a30ec8c300c84d07ad865f98d70edcccc970d2c7273dcec36e455e63f64736f6c6343000809003300000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000048d72f2f0da29671093913c846a544f64499af9900000000000000000000000059505978dcdb0c820ecf6486afeb9b2baa58ff490000000000000000000000000944d9a8dea16af1170c51e8dd3921c727a06cbd000000000000000000000000565d328630694fb560a427b07c4167eb88de2d4d000000000000000000000000187c3b7f5295733823ce565d3edd44c1d64fa5250000000000000000000000005c7f8a570d578ed84e63fdfa7b1ee72deae1ae23000000000000000000000000145677fc4d9b8f19b5d56d1820c48e0443049a3000000000000000000000000000000000000000000000000000000000000000165957203020285743524f2d4441524b43525953544c290000000000000000000000000000000000000000000000000000000000000000000000000000000000035957300000000000000000000000000000000000000000000000000000000000

Loading