AVAX Price: $22.79 (+11.28%)
Gas: 1 nAVAX
 

Overview

AVAX Balance

Avalanche C-Chain LogoAvalanche C-Chain LogoAvalanche C-Chain Logo0 AVAX

AVAX Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Approve425898782024-03-07 10:17:02412 days ago1709806622IN
0x123F4921...093c5fF8d
0 AVAX0.0012285626.5
Approve278647952023-03-24 23:10:20760 days ago1679699420IN
0x123F4921...093c5fF8d
0 AVAX0.0012053826
Approve182022422022-08-04 11:32:43993 days ago1659612763IN
0x123F4921...093c5fF8d
0 AVAX0.0012053826
Approve171594742022-07-10 21:14:051017 days ago1657487645IN
0x123F4921...093c5fF8d
0 AVAX0.0012053826
Approve171593652022-07-10 21:10:271017 days ago1657487427IN
0x123F4921...093c5fF8d
0 AVAX0.0012053826
Approve162529242022-06-19 20:08:041038 days ago1655669284IN
0x123F4921...093c5fF8d
0 AVAX0.0012053826
Approve158527382022-06-10 16:12:211047 days ago1654877541IN
0x123F4921...093c5fF8d
0 AVAX0.0012053826
Approve157563912022-06-08 10:24:381050 days ago1654683878IN
0x123F4921...093c5fF8d
0 AVAX0.0012053826
Approve155825692022-06-04 9:04:421054 days ago1654333482IN
0x123F4921...093c5fF8d
0 AVAX0.0006892326
Approve155825142022-06-04 9:02:501054 days ago1654333370IN
0x123F4921...093c5fF8d
0 AVAX0.0006892326
Approve155821022022-06-04 8:49:011054 days ago1654332541IN
0x123F4921...093c5fF8d
0 AVAX0.0012066326
Approve155820812022-06-04 8:48:191054 days ago1654332499IN
0x123F4921...093c5fF8d
0 AVAX0.0012056926
Approve155179332022-06-02 21:01:011055 days ago1654203661IN
0x123F4921...093c5fF8d
0 AVAX0.0012056926
Approve154597192022-06-01 12:36:331056 days ago1654086993IN
0x123F4921...093c5fF8d
0 AVAX0.0012053826
Approve154554882022-06-01 10:14:381057 days ago1654078478IN
0x123F4921...093c5fF8d
0 AVAX0.0012056926
Approve154538862022-06-01 9:20:571057 days ago1654075257IN
0x123F4921...093c5fF8d
0 AVAX0.0012056926
Approve154531932022-06-01 8:57:211057 days ago1654073841IN
0x123F4921...093c5fF8d
0 AVAX0.0006879826
Approve154531772022-06-01 8:56:491057 days ago1654073809IN
0x123F4921...093c5fF8d
0 AVAX0.0012053826
Approve154314192022-05-31 20:49:211057 days ago1654030161IN
0x123F4921...093c5fF8d
0 AVAX0.0006970326
Approve154313482022-05-31 20:46:561057 days ago1654030016IN
0x123F4921...093c5fF8d
0 AVAX0.0012144326
Withdraw146275402022-05-13 4:53:521076 days ago1652417632IN
0x123F4921...093c5fF8d
0 AVAX0.02414367.98010995
Reinvest146248442022-05-13 3:24:021076 days ago1652412242IN
0x123F4921...093c5fF8d
0 AVAX0.0683879445.7486349
Withdraw145992202022-05-12 13:13:581076 days ago1652361238IN
0x123F4921...093c5fF8d
0 AVAX0.11750436108.86595596
Withdraw145626242022-05-11 17:03:261077 days ago1652288606IN
0x123F4921...093c5fF8d
0 AVAX0.12584133142.03054262
Withdraw145576972022-05-11 14:19:061077 days ago1652278746IN
0x123F4921...093c5fF8d
0 AVAX0.23372693216.54435562
View all transactions

Parent Transaction Hash Block From To
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
BlizzStrategyV1

Compiler Version
v0.7.3+commit.9bfce1f6

Optimization Enabled:
Yes with 999 runs

Other Settings:
default evmVersion
File 1 of 15 : BlizzStrategyV1.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;

import "../YakStrategyV2.sol";
import "../interfaces/IBlizzChef.sol";
import "../interfaces/IBlizzMultiFeeDistribution.sol";
import "../interfaces/ILendingPool.sol";
import "../interfaces/IWAVAX.sol";
import "../interfaces/IERC20.sol";
import "../lib/SafeMath.sol";
import "../lib/DexLibrary.sol";
import "../lib/ReentrancyGuard.sol";

/**
 * @title Blizz strategy for ERC20
 */
contract BlizzStrategyV1 is YakStrategyV2 {
    using SafeMath for uint256;

    struct StrategySettings {
        uint256 minTokensToReinvest;
        uint256 adminFeeBips;
        uint256 devFeeBips;
        uint256 reinvestRewardBips;
    }

    struct LeverageSettings {
        uint256 leverageLevel;
        uint256 safetyFactor;
        uint256 leverageBips;
        uint256 minMinting;
    }

    struct SwapPairs {
        address swapPairRewardDeposit;
        address swapPairPoolReward;
    }

    struct Tokens {
        address depositToken;
        address poolRewardToken;
        address avToken;
        address avDebtToken;
    }

    IBlizzMultiFeeDistribution private rewardDistribution;
    IBlizzChef private blizzChef;
    ILendingPool private tokenDelegator;
    IWAVAX private constant WAVAX = IWAVAX(0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7);
    uint256 private leverageLevel;
    uint256 private safetyFactor;
    uint256 private leverageBips;
    uint256 private minMinting;
    address private avToken;
    address private avDebtToken;
    address private poolRewardToken;
    IPair private swapPairPoolReward;
    IPair private swapPairRewardDeposit;

    constructor(
        string memory _name,
        address _rewardDistribution,
        address _blizzChef,
        address _tokenDelegator,
        address _timelock,
        Tokens memory _tokens,
        SwapPairs memory _swapPairs,
        LeverageSettings memory _leverageSettings,
        StrategySettings memory _strategySettings
    ) {
        name = _name;
        rewardDistribution = IBlizzMultiFeeDistribution(_rewardDistribution);
        blizzChef = IBlizzChef(_blizzChef);
        tokenDelegator = ILendingPool(_tokenDelegator);
        depositToken = IERC20(_tokens.depositToken);
        rewardToken = IERC20(address(WAVAX));
        poolRewardToken = _tokens.poolRewardToken;
        swapPairPoolReward = IPair(_swapPairs.swapPairPoolReward);
        _updateLeverage(_leverageSettings);
        devAddr = msg.sender;
        avToken = _tokens.avToken;
        avDebtToken = _tokens.avDebtToken;

        assignSwapPairSafely(_swapPairs.swapPairRewardDeposit);
        setAllowances();
        updateMinTokensToReinvest(_strategySettings.minTokensToReinvest);
        updateAdminFee(_strategySettings.adminFeeBips);
        updateDevFee(_strategySettings.devFeeBips);
        updateReinvestReward(_strategySettings.reinvestRewardBips);
        updateDepositsEnabled(true);
        transferOwnership(_timelock);

        emit Reinvest(0, 0);
    }

    function assignSwapPairSafely(address _swapPairRewardDeposit) private {
        require(_swapPairRewardDeposit > address(0), "Swap pair is necessary but not supplied");
        swapPairRewardDeposit = IPair(_swapPairRewardDeposit);
        require(
            isPairEquals(swapPairRewardDeposit, depositToken, rewardToken) ||
                isPairEquals(swapPairRewardDeposit, rewardToken, depositToken),
            "Swap pair does not match depositToken and rewardToken."
        );
    }

    function isPairEquals(
        IPair pair,
        IERC20 left,
        IERC20 right
    ) private pure returns (bool) {
        return pair.token0() == address(left) && pair.token1() == address(right);
    }

    /// @notice Internal method to get account state
    /// @dev Values provided in 1e18 (WAD) instead of 1e27 (RAY)
    function _getAccountData()
        internal
        view
        returns (
            uint256 balance,
            uint256 borrowed,
            uint256 borrowable
        )
    {
        balance = IERC20(avToken).balanceOf(address(this));
        borrowed = IERC20(avDebtToken).balanceOf(address(this));
        borrowable = 0;
        if (balance.mul(leverageLevel.sub(leverageBips)).div(leverageLevel) > borrowed) {
            borrowable = balance.mul(leverageLevel.sub(leverageBips)).div(leverageLevel).sub(borrowed);
        }
    }

    function totalDeposits() public view override returns (uint256) {
        (uint256 balance, uint256 borrowed, ) = _getAccountData();
        return balance.sub(borrowed);
    }

    function _updateLeverage(LeverageSettings memory _leverageSettings) internal {
        leverageLevel = _leverageSettings.leverageLevel;
        leverageBips = _leverageSettings.leverageBips;
        safetyFactor = _leverageSettings.safetyFactor;
        minMinting = _leverageSettings.minMinting;
    }

    function updateLeverage(
        uint256 _leverageLevel,
        uint256 _safetyFactor,
        uint256 _minMinting,
        uint256 _leverageBips
    ) external onlyDev {
        _updateLeverage(
            LeverageSettings({
                leverageLevel: _leverageLevel,
                safetyFactor: _safetyFactor,
                minMinting: _minMinting,
                leverageBips: _leverageBips
            })
        );
        (uint256 balance, uint256 borrowed, ) = _getAccountData();
        _unrollDebt(balance.sub(borrowed));
        _rollupDebt();
    }

    function setAllowances() public override onlyOwner {
        IERC20(depositToken).approve(address(tokenDelegator), type(uint256).max);
        IERC20(avToken).approve(address(tokenDelegator), type(uint256).max);
    }

    function deposit(uint256 amount) external override {
        _deposit(msg.sender, amount);
    }

    function depositFor(address account, uint256 amount) external override {
        _deposit(account, amount);
    }

    function depositWithPermit(
        uint256 amount,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external override {
        depositToken.permit(msg.sender, address(this), amount, deadline, v, r, s);
        _deposit(msg.sender, amount);
    }

    function _deposit(address account, uint256 amount) private onlyAllowedDeposits {
        require(DEPOSITS_ENABLED == true, "BlizzStrategyV1::_deposit");
        if (MAX_TOKENS_TO_DEPOSIT_WITHOUT_REINVEST > 0) {
            (uint256 poolTokenAmount, uint256 rewardTokenBalance, uint256 estimatedTotalReward) = _checkReward();
            if (estimatedTotalReward > MAX_TOKENS_TO_DEPOSIT_WITHOUT_REINVEST) {
                _reinvest(poolTokenAmount, rewardTokenBalance, estimatedTotalReward);
            }
        }
        require(depositToken.transferFrom(msg.sender, address(this), amount), "BlizzStrategyV1::transfer failed");
        _mint(account, getSharesForDepositTokens(amount));
        _stakeDepositTokens(amount);
        emit Deposit(account, amount);
    }

    function withdraw(uint256 amount) external override {
        uint256 depositTokenAmount = getDepositTokensForShares(amount);
        require(depositTokenAmount > minMinting, "BlizzStrategyV1::below minimum withdraw");
        if (depositTokenAmount > 0) {
            _burn(msg.sender, amount);
            // actual amount withdrawn may change with time.
            uint256 withdrawnAmount = _withdrawDepositTokens(depositTokenAmount);
            _safeTransfer(address(depositToken), msg.sender, withdrawnAmount);
            emit Withdraw(msg.sender, withdrawnAmount);
        }
    }

    function _withdrawDepositTokens(uint256 amount) private returns (uint256) {
        _unrollDebt(amount);
        (uint256 balance, , ) = _getAccountData();
        amount = amount > balance ? type(uint256).max : amount;
        uint256 withdrawn = tokenDelegator.withdraw(address(depositToken), amount, address(this));
        _rollupDebt();
        return withdrawn;
    }

    function _convertPoolTokensIntoReward(uint256 poolTokenAmount) private returns (uint256) {
        return DexLibrary.swap(poolTokenAmount, address(poolRewardToken), address(rewardToken), swapPairPoolReward);
    }

    function reinvest() external override onlyEOA {
        (uint256 poolTokenAmount, uint256 rewardTokenBalance, uint256 estimatedTotalReward) = _checkReward();
        require(estimatedTotalReward >= MIN_TOKENS_TO_REINVEST, "BlizzStrategyV1::reinvest");
        _reinvest(poolTokenAmount, rewardTokenBalance, estimatedTotalReward);
    }

    /**
     * @notice Reinvest rewards from staking contract to deposit tokens
     * @dev Reverts if the expected amount of tokens are not returned from `stakingContract`
     */
    function _reinvest(
        uint256 poolTokenAmount,
        uint256 rewardTokenBalance,
        uint256 estimatedTotalReward
    ) private {
        address[] memory assets = new address[](2);
        assets[0] = avToken;
        assets[1] = avDebtToken;
        blizzChef.claim(address(this), assets);
        rewardDistribution.exit(true);

        _convertPoolTokensIntoReward(poolTokenAmount);

        uint256 devFee = estimatedTotalReward.mul(DEV_FEE_BIPS).div(BIPS_DIVISOR);
        if (devFee > 0) {
            _safeTransfer(address(rewardToken), devAddr, devFee);
        }

        uint256 adminFee = estimatedTotalReward.mul(ADMIN_FEE_BIPS).div(BIPS_DIVISOR);
        if (adminFee > 0) {
            _safeTransfer(address(rewardToken), owner(), adminFee);
        }

        uint256 reinvestFee = estimatedTotalReward.mul(REINVEST_REWARD_BIPS).div(BIPS_DIVISOR);
        if (reinvestFee > 0) {
            _safeTransfer(address(rewardToken), msg.sender, reinvestFee);
        }

        uint256 depositTokenAmount = DexLibrary.swap(
            estimatedTotalReward.sub(devFee).sub(adminFee).sub(reinvestFee),
            address(rewardToken),
            address(depositToken),
            swapPairRewardDeposit
        );
        _stakeDepositTokens(depositTokenAmount);

        emit Reinvest(totalDeposits(), totalSupply);
    }

    function _rollupDebt() internal {
        (uint256 balance, uint256 borrowed, uint256 borrowable) = _getAccountData();
        uint256 lendTarget = balance.sub(borrowed).mul(leverageLevel.sub(safetyFactor)).div(leverageBips);
        while (balance < lendTarget) {
            if (balance.add(borrowable) > lendTarget) {
                borrowable = lendTarget.sub(balance);
            }
            if (borrowable < minMinting) {
                break;
            }
            tokenDelegator.borrow(
                address(depositToken),
                borrowable,
                2, // variable interest model
                0,
                address(this)
            );
            tokenDelegator.deposit(address(depositToken), borrowable, address(this), 0);
            (balance, borrowed, borrowable) = _getAccountData();
        }
    }

    function _unrollDebt(uint256 amountToFreeUp) internal {
        (uint256 balance, uint256 borrowed, uint256 borrowable) = _getAccountData();
        uint256 targetBorrow = balance
            .sub(borrowed)
            .sub(amountToFreeUp)
            .mul(leverageLevel.sub(safetyFactor))
            .div(leverageBips)
            .sub(balance.sub(borrowed).sub(amountToFreeUp));
        uint256 toRepay = borrowed.sub(targetBorrow);

        while (toRepay > 0) {
            uint256 unrollAmount = borrowable;
            if (unrollAmount > borrowed) {
                unrollAmount = borrowed;
            }
            tokenDelegator.withdraw(address(depositToken), unrollAmount, address(this));
            tokenDelegator.repay(address(depositToken), unrollAmount, 2, address(this));
            (balance, borrowed, borrowable) = _getAccountData();
            if (targetBorrow >= borrowed) {
                break;
            }
            toRepay = borrowed.sub(targetBorrow);
        }
    }

    function _stakeDepositTokens(uint256 amount) private {
        require(amount > 0, "BlizzStrategyV1::_stakeDepositTokens");
        tokenDelegator.deposit(address(depositToken), amount, address(this), 0);
        _rollupDebt();
    }

    /**
     * @notice Safely transfer using an anonymosu ERC20 token
     * @dev Requires token to return true on transfer
     * @param token address
     * @param to recipient address
     * @param value amount
     */
    function _safeTransfer(
        address token,
        address to,
        uint256 value
    ) private {
        require(IERC20(token).transfer(to, value), "BlizzStrategyV1::TRANSFER_FROM_FAILED");
    }

    function _updatePool(IBlizzChef.PoolInfo memory pool) internal view returns (IBlizzChef.PoolInfo memory) {
        if (block.timestamp <= pool.lastRewardTime) {
            return pool;
        }
        uint256 lpSupply = pool.totalSupply;
        if (lpSupply == 0) {
            pool.lastRewardTime = block.timestamp;
            return pool;
        }
        uint256 duration = block.timestamp.sub(pool.lastRewardTime);
        uint256 reward = duration.mul(blizzChef.rewardsPerSecond()).mul(pool.allocPoint).div(
            blizzChef.totalAllocPoint()
        );
        pool.accRewardPerShare = pool.accRewardPerShare.add(reward.mul(1e12).div(lpSupply));
        return pool;
    }

    function _checkReward()
        internal
        view
        returns (
            uint256 _poolTokenAmount,
            uint256 _rewardTokenBalance,
            uint256 _estimatedTotalReward
        )
    {
        uint256 poolTokenAmount = blizzChef.userBaseClaimable(address(this));

        address[] memory assets = new address[](2);
        assets[0] = avToken;
        assets[1] = avDebtToken;

        IBlizzChef.PoolInfo memory pool = blizzChef.poolInfo(assets[0]);
        pool = _updatePool(pool);
        IBlizzChef.UserInfo memory user = blizzChef.userInfo(assets[0], address(this));
        uint256 rewardDebt = user.amount.mul(pool.accRewardPerShare).div(1e12);
        poolTokenAmount = poolTokenAmount.add(rewardDebt.sub(user.rewardDebt));

        pool = blizzChef.poolInfo(assets[1]);
        pool = _updatePool(pool);
        user = blizzChef.userInfo(assets[1], address(this));
        rewardDebt = user.amount.mul(pool.accRewardPerShare).div(1e12);
        poolTokenAmount = poolTokenAmount.add(rewardDebt.sub(user.rewardDebt));

        poolTokenAmount = poolTokenAmount.div(2);
        poolTokenAmount = poolTokenAmount.add(IERC20(poolRewardToken).balanceOf(address(this)));
        uint256 pendingRewardTokenAmount = DexLibrary.estimateConversionThroughPair(
            poolTokenAmount,
            poolRewardToken,
            address(rewardToken),
            swapPairPoolReward
        );
        uint256 rewardTokenBalance = rewardToken.balanceOf(address(this));
        uint256 estimatedTotalReward = pendingRewardTokenAmount.add(rewardTokenBalance);
        return (poolTokenAmount, rewardTokenBalance, estimatedTotalReward);
    }

    function checkReward() public view override returns (uint256) {
        (, , uint256 amount) = _checkReward();
        return amount;
    }

    function getActualLeverage() public view returns (uint256) {
        (uint256 balance, uint256 borrowed, ) = _getAccountData();
        return balance.mul(1e18).div(balance.sub(borrowed));
    }

    function estimateDeployedBalance() external view override returns (uint256) {
        return totalDeposits();
    }

    function rescueDeployedFunds(uint256 minReturnAmountAccepted, bool disableDeposits) external override onlyOwner {
        uint256 balanceBefore = depositToken.balanceOf(address(this));
        (uint256 balance, uint256 borrowed, ) = _getAccountData();
        _unrollDebt(balance.sub(borrowed));
        tokenDelegator.withdraw(address(depositToken), type(uint256).max, address(this));
        uint256 balanceAfter = depositToken.balanceOf(address(this));
        require(balanceAfter.sub(balanceBefore) >= minReturnAmountAccepted, "BlizzStrategyV1::rescueDeployedFunds");
        emit Reinvest(totalDeposits(), totalSupply);
        if (DEPOSITS_ENABLED == true && disableDeposits == true) {
            updateDepositsEnabled(false);
        }
    }
}

File 2 of 15 : YakStrategyV2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

import "./lib/SafeMath.sol";
import "./lib/Ownable.sol";
import "./lib/Permissioned.sol";
import "./interfaces/IERC20.sol";
import "./YakERC20.sol";

/**
 * @notice YakStrategy should be inherited by new strategies
 */
abstract contract YakStrategyV2 is YakERC20, Ownable, Permissioned {
    using SafeMath for uint;


    IERC20 public depositToken;
    IERC20 public rewardToken;
    address public devAddr;

    uint public MIN_TOKENS_TO_REINVEST;
    uint public MAX_TOKENS_TO_DEPOSIT_WITHOUT_REINVEST;
    bool public DEPOSITS_ENABLED;

    uint public REINVEST_REWARD_BIPS;
    uint public ADMIN_FEE_BIPS;
    uint public DEV_FEE_BIPS;

    uint constant internal BIPS_DIVISOR = 10000;
    uint constant internal MAX_UINT = uint(-1);

    event Deposit(address indexed account, uint amount);
    event Withdraw(address indexed account, uint amount);
    event Reinvest(uint newTotalDeposits, uint newTotalSupply);
    event Recovered(address token, uint amount);
    event UpdateAdminFee(uint oldValue, uint newValue);
    event UpdateDevFee(uint oldValue, uint newValue);
    event UpdateReinvestReward(uint oldValue, uint newValue);
    event UpdateMinTokensToReinvest(uint oldValue, uint newValue);
    event UpdateMaxTokensToDepositWithoutReinvest(uint oldValue, uint newValue);
    event UpdateDevAddr(address oldValue, address newValue);
    event DepositsEnabled(bool newValue);

    /**
     * @notice Throws if called by smart contract
     */
    modifier onlyEOA() {
        require(tx.origin == msg.sender, "YakStrategy::onlyEOA");
        _;
    }

    /**
     * @notice Only called by dev
     */
    modifier onlyDev() {
        require(msg.sender == devAddr, "YakStrategy::onlyDev");
        _;
    }

    /**
     * @notice Approve tokens for use in Strategy
     * @dev Should use modifier `onlyOwner` to avoid griefing
     */
    function setAllowances() public virtual;

    /**
     * @notice Revoke token allowance
     * @param token address
     * @param spender address
     */
    function revokeAllowance(address token, address spender) external onlyOwner {
        require(IERC20(token).approve(spender, 0));
    }

    /**
     * @notice Deposit and deploy deposits tokens to the strategy
     * @dev Must mint receipt tokens to `msg.sender`
     * @param amount deposit tokens
     */
    function deposit(uint amount) external virtual;

    /**
    * @notice Deposit using Permit
    * @dev Should revert for tokens without Permit
    * @param amount Amount of tokens to deposit
    * @param deadline The time at which to expire the signature
    * @param v The recovery byte of the signature
    * @param r Half of the ECDSA signature pair
    * @param s Half of the ECDSA signature pair
    */
    function depositWithPermit(uint amount, uint deadline, uint8 v, bytes32 r, bytes32 s) external virtual;

    /**
     * @notice Deposit on behalf of another account
     * @dev Must mint receipt tokens to `account`
     * @param account address to receive receipt tokens
     * @param amount deposit tokens
     */
    function depositFor(address account, uint amount) external virtual;

    /**
     * @notice Redeem receipt tokens for deposit tokens
     * @param amount receipt tokens
     */
    function withdraw(uint amount) external virtual;

    /**
     * @notice Reinvest reward tokens into deposit tokens
     */
    function reinvest() external virtual;

    /**
     * @notice Estimate reinvest reward
     * @return reward tokens
     */
    function estimateReinvestReward() external view returns (uint) {
        uint unclaimedRewards = checkReward();
        if (unclaimedRewards >= MIN_TOKENS_TO_REINVEST) {
            return unclaimedRewards.mul(REINVEST_REWARD_BIPS).div(BIPS_DIVISOR);
        }
        return 0;
    }

    /**
     * @notice Reward tokens avialable to strategy, including balance
     * @return reward tokens
     */
    function checkReward() public virtual view returns (uint);

    /**
     * @notice Estimated deposit token balance deployed by strategy, excluding balance
     * @return deposit tokens
     */
    function estimateDeployedBalance() external virtual view returns (uint);

    /**
     * @notice Rescue all available deployed deposit tokens back to Strategy
     * @param minReturnAmountAccepted min deposit tokens to receive
     * @param disableDeposits bool
     */
    function rescueDeployedFunds(uint minReturnAmountAccepted, bool disableDeposits) external virtual;

    /**
     * @notice This function returns a snapshot of last available quotes
     * @return total deposits available on the contract
     */
    function totalDeposits() public virtual view returns (uint);
    /**
     * @notice Calculate receipt tokens for a given amount of deposit tokens
     * @dev If contract is empty, use 1:1 ratio
     * @dev Could return zero shares for very low amounts of deposit tokens
     * @param amount deposit tokens
     * @return receipt tokens
     */
    function getSharesForDepositTokens(uint amount) public view returns (uint) {
        if (totalSupply.mul(totalDeposits()) == 0) {
            return amount;
        }
        return amount.mul(totalSupply).div(totalDeposits());
    }

    /**
     * @notice Calculate deposit tokens for a given amount of receipt tokens
     * @param amount receipt tokens
     * @return deposit tokens
     */
    function getDepositTokensForShares(uint amount) public view returns (uint) {
        if (totalSupply.mul(totalDeposits()) == 0) {
            return 0;
        }
        return amount.mul(totalDeposits()).div(totalSupply);
    }

    /**
     * @notice Update reinvest min threshold
     * @param newValue threshold
     */
    function updateMinTokensToReinvest(uint newValue) public onlyOwner {
        emit UpdateMinTokensToReinvest(MIN_TOKENS_TO_REINVEST, newValue);
        MIN_TOKENS_TO_REINVEST = newValue;
    }

    /**
     * @notice Update reinvest max threshold before a deposit
     * @param newValue threshold
     */
    function updateMaxTokensToDepositWithoutReinvest(uint newValue) public onlyOwner {
        emit UpdateMaxTokensToDepositWithoutReinvest(MAX_TOKENS_TO_DEPOSIT_WITHOUT_REINVEST, newValue);
        MAX_TOKENS_TO_DEPOSIT_WITHOUT_REINVEST = newValue;
    }

    /**
     * @notice Update developer fee
     * @param newValue fee in BIPS
     */
    function updateDevFee(uint newValue) public onlyOwner {
        require(newValue.add(ADMIN_FEE_BIPS).add(REINVEST_REWARD_BIPS) <= BIPS_DIVISOR);
        emit UpdateDevFee(DEV_FEE_BIPS, newValue);
        DEV_FEE_BIPS = newValue;
    }

    /**
     * @notice Update admin fee
     * @param newValue fee in BIPS
     */
    function updateAdminFee(uint newValue) public onlyOwner {
        require(newValue.add(DEV_FEE_BIPS).add(REINVEST_REWARD_BIPS) <= BIPS_DIVISOR);
        emit UpdateAdminFee(ADMIN_FEE_BIPS, newValue);
        ADMIN_FEE_BIPS = newValue;
    }

    /**
     * @notice Update reinvest reward
     * @param newValue fee in BIPS
     */
    function updateReinvestReward(uint newValue) public onlyOwner {
        require(newValue.add(ADMIN_FEE_BIPS).add(DEV_FEE_BIPS) <= BIPS_DIVISOR);
        emit UpdateReinvestReward(REINVEST_REWARD_BIPS, newValue);
        REINVEST_REWARD_BIPS = newValue;
    }

    /**
     * @notice Enable/disable deposits
     * @param newValue bool
     */
    function updateDepositsEnabled(bool newValue) public onlyOwner {
        require(DEPOSITS_ENABLED != newValue);
        DEPOSITS_ENABLED = newValue;
        emit DepositsEnabled(newValue);
    }

    /**
     * @notice Update devAddr
     * @param newValue address
     */
    function updateDevAddr(address newValue) public onlyDev {
        emit UpdateDevAddr(devAddr, newValue);
        devAddr = newValue;
    }

    /**
     * @notice Recover ERC20 from contract
     * @param tokenAddress token address
     * @param tokenAmount amount to recover
     */
    function recoverERC20(address tokenAddress, uint tokenAmount) external onlyOwner {
        require(tokenAmount > 0);
        require(IERC20(tokenAddress).transfer(msg.sender, tokenAmount));
        emit Recovered(tokenAddress, tokenAmount);
    }

    /**
     * @notice Recover AVAX from contract
     * @param amount amount
     */
    function recoverAVAX(uint amount) external onlyOwner {
        require(amount > 0);
        msg.sender.transfer(amount);
        emit Recovered(address(0), amount);
    }
}

File 3 of 15 : IBlizzChef.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;

interface IBlizzChef {
    // Info of each user.
    struct UserInfo {
        uint256 amount;
        uint256 rewardDebt;
    }
    // Info of each pool.
    struct PoolInfo {
        uint256 totalSupply;
        uint256 allocPoint; // How many allocation points assigned to this pool.
        uint256 lastRewardTime; // Last second that reward distribution occurs.
        uint256 accRewardPerShare; // Accumulated rewards per share, times 1e12. See below.
        address onwardIncentives;
    }

    // Info about token emissions for a given time period.
    struct EmissionPoint {
        uint128 startTimeOffset;
        uint128 rewardsPerSecond;
    }

    function claimableReward(address account, address[] memory tokens) external view returns (uint256[] memory);

    function claim(address account, address[] memory tokens) external;

    function userInfo(address token, address user) external view returns (UserInfo memory);

    function poolInfo(address token) external view returns (PoolInfo memory);

    function totalAllocPoint() external view returns (uint256);

    function rewardsPerSecond() external view returns (uint256);

    function startTime() external view returns (uint256);

    function userBaseClaimable(address user) external view returns (uint256);
}

File 4 of 15 : IBlizzMultiFeeDistribution.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

interface IBlizzMultiFeeDistribution {
    function exit(bool claimRewards) external;
}

File 5 of 15 : ILendingPool.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;

library DataTypes {
    // refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties.
    struct ReserveData {
        //stores the reserve configuration
        ReserveConfigurationMap configuration;
        //the liquidity index. Expressed in ray
        uint128 liquidityIndex;
        //variable borrow index. Expressed in ray
        uint128 variableBorrowIndex;
        //the current supply rate. Expressed in ray
        uint128 currentLiquidityRate;
        //the current variable borrow rate. Expressed in ray
        uint128 currentVariableBorrowRate;
        //the current stable borrow rate. Expressed in ray
        uint128 currentStableBorrowRate;
        uint40 lastUpdateTimestamp;
        //tokens addresses
        address aTokenAddress;
        address stableDebtTokenAddress;
        address variableDebtTokenAddress;
        //address of the interest rate strategy
        address interestRateStrategyAddress;
        //the id of the reserve. Represents the position in the list of the active reserves
        uint8 id;
    }

    struct ReserveConfigurationMap {
        //bit 0-15: LTV
        //bit 16-31: Liq. threshold
        //bit 32-47: Liq. bonus
        //bit 48-55: Decimals
        //bit 56: Reserve is active
        //bit 57: reserve is frozen
        //bit 58: borrowing is enabled
        //bit 59: stable rate borrowing enabled
        //bit 60-63: reserved
        //bit 64-79: reserve factor
        uint256 data;
    }

    struct UserConfigurationMap {
        uint256 data;
    }

    enum InterestRateMode {
        NONE,
        STABLE,
        VARIABLE
    }
}

interface ILendingPool {
    /**
     * @dev Emitted on deposit()
     * @param reserve The address of the underlying asset of the reserve
     * @param user The address initiating the deposit
     * @param onBehalfOf The beneficiary of the deposit, receiving the aTokens
     * @param amount The amount deposited
     * @param referral The referral code used
     **/
    event Deposit(
        address indexed reserve,
        address user,
        address indexed onBehalfOf,
        uint256 amount,
        uint16 indexed referral
    );

    /**
     * @dev Emitted on withdraw()
     * @param reserve The address of the underlyng asset being withdrawn
     * @param user The address initiating the withdrawal, owner of aTokens
     * @param to Address that will receive the underlying
     * @param amount The amount to be withdrawn
     **/
    event Withdraw(
        address indexed reserve,
        address indexed user,
        address indexed to,
        uint256 amount
    );

    /**
     * @dev Emitted on borrow() and flashLoan() when debt needs to be opened
     * @param reserve The address of the underlying asset being borrowed
     * @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just
     * initiator of the transaction on flashLoan()
     * @param onBehalfOf The address that will be getting the debt
     * @param amount The amount borrowed out
     * @param borrowRateMode The rate mode: 1 for Stable, 2 for Variable
     * @param borrowRate The numeric rate at which the user has borrowed
     * @param referral The referral code used
     **/
    event Borrow(
        address indexed reserve,
        address user,
        address indexed onBehalfOf,
        uint256 amount,
        uint256 borrowRateMode,
        uint256 borrowRate,
        uint16 indexed referral
    );

    /**
     * @dev Emitted on repay()
     * @param reserve The address of the underlying asset of the reserve
     * @param user The beneficiary of the repayment, getting his debt reduced
     * @param repayer The address of the user initiating the repay(), providing the funds
     * @param amount The amount repaid
     **/
    event Repay(
        address indexed reserve,
        address indexed user,
        address indexed repayer,
        uint256 amount
    );

    /**
     * @dev Emitted on swapBorrowRateMode()
     * @param reserve The address of the underlying asset of the reserve
     * @param user The address of the user swapping his rate mode
     * @param rateMode The rate mode that the user wants to swap to
     **/
    event Swap(address indexed reserve, address indexed user, uint256 rateMode);

    /**
     * @dev Emitted on setUserUseReserveAsCollateral()
     * @param reserve The address of the underlying asset of the reserve
     * @param user The address of the user enabling the usage as collateral
     **/
    event ReserveUsedAsCollateralEnabled(
        address indexed reserve,
        address indexed user
    );

    /**
     * @dev Emitted on setUserUseReserveAsCollateral()
     * @param reserve The address of the underlying asset of the reserve
     * @param user The address of the user enabling the usage as collateral
     **/
    event ReserveUsedAsCollateralDisabled(
        address indexed reserve,
        address indexed user
    );

    /**
     * @dev Emitted on rebalanceStableBorrowRate()
     * @param reserve The address of the underlying asset of the reserve
     * @param user The address of the user for which the rebalance has been executed
     **/
    event RebalanceStableBorrowRate(
        address indexed reserve,
        address indexed user
    );

    /**
     * @dev Emitted on flashLoan()
     * @param target The address of the flash loan receiver contract
     * @param initiator The address initiating the flash loan
     * @param asset The address of the asset being flash borrowed
     * @param amount The amount flash borrowed
     * @param premium The fee flash borrowed
     * @param referralCode The referral code used
     **/
    event FlashLoan(
        address indexed target,
        address indexed initiator,
        address indexed asset,
        uint256 amount,
        uint256 premium,
        uint16 referralCode
    );

    /**
     * @dev Emitted when the pause is triggered.
     */
    event Paused();

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

    /**
     * @dev Emitted when a borrower is liquidated. This event is emitted by the LendingPool via
     * LendingPoolCollateral manager using a DELEGATECALL
     * This allows to have the events in the generated ABI for LendingPool.
     * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
     * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
     * @param user The address of the borrower getting liquidated
     * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
     * @param liquidatedCollateralAmount The amount of collateral received by the liiquidator
     * @param liquidator The address of the liquidator
     * @param receiveAToken `true` if the liquidators wants to receive the collateral aTokens, `false` if he wants
     * to receive the underlying collateral asset directly
     **/
    event LiquidationCall(
        address indexed collateralAsset,
        address indexed debtAsset,
        address indexed user,
        uint256 debtToCover,
        uint256 liquidatedCollateralAmount,
        address liquidator,
        bool receiveAToken
    );

    /**
     * @dev Emitted when the state of a reserve is updated. NOTE: This event is actually declared
     * in the ReserveLogic library and emitted in the updateInterestRates() function. Since the function is internal,
     * the event will actually be fired by the LendingPool contract. The event is therefore replicated here so it
     * gets added to the LendingPool ABI
     * @param reserve The address of the underlying asset of the reserve
     * @param liquidityRate The new liquidity rate
     * @param stableBorrowRate The new stable borrow rate
     * @param variableBorrowRate The new variable borrow rate
     * @param liquidityIndex The new liquidity index
     * @param variableBorrowIndex The new variable borrow index
     **/
    event ReserveDataUpdated(
        address indexed reserve,
        uint256 liquidityRate,
        uint256 stableBorrowRate,
        uint256 variableBorrowRate,
        uint256 liquidityIndex,
        uint256 variableBorrowIndex
    );

    /**
     * @dev Deposits an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.
     * - E.g. User deposits 100 USDC and gets in return 100 aUSDC
     * @param asset The address of the underlying asset to deposit
     * @param amount The amount to be deposited
     * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user
     *   wants to receive them on his own wallet, or a different address if the beneficiary of aTokens
     *   is a different wallet
     * @param referralCode Code used to register the integrator originating the operation, for potential rewards.
     *   0 if the action is executed directly by the user, without any middle-man
     **/
    function deposit(
        address asset,
        uint256 amount,
        address onBehalfOf,
        uint16 referralCode
    ) external;

    /**
     * @dev Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned
     * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC
     * @param asset The address of the underlying asset to withdraw
     * @param amount The underlying amount to be withdrawn
     *   - Send the value type(uint256).max in order to withdraw the whole aToken balance
     * @param to Address that will receive the underlying, same as msg.sender if the user
     *   wants to receive it on his own wallet, or a different address if the beneficiary is a
     *   different wallet
     * @return The final amount withdrawn
     **/
    function withdraw(
        address asset,
        uint256 amount,
        address to
    ) external returns (uint256);

    /**
     * @dev Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower
     * already deposited enough collateral, or he was given enough allowance by a credit delegator on the
     * corresponding debt token (StableDebtToken or VariableDebtToken)
     * - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet
     *   and 100 stable/variable debt tokens, depending on the `interestRateMode`
     * @param asset The address of the underlying asset to borrow
     * @param amount The amount to be borrowed
     * @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable
     * @param referralCode Code used to register the integrator originating the operation, for potential rewards.
     *   0 if the action is executed directly by the user, without any middle-man
     * @param onBehalfOf Address of the user who will receive the debt. Should be the address of the borrower itself
     * calling the function if he wants to borrow against his own collateral, or the address of the credit delegator
     * if he has been given credit delegation allowance
     **/
    function borrow(
        address asset,
        uint256 amount,
        uint256 interestRateMode,
        uint16 referralCode,
        address onBehalfOf
    ) external;

    /**
     * @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned
     * - E.g. User repays 100 USDC, burning 100 variable/stable debt tokens of the `onBehalfOf` address
     * @param asset The address of the borrowed underlying asset previously borrowed
     * @param amount The amount to repay
     * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
     * @param rateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable
     * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the
     * user calling the function if he wants to reduce/remove his own debt, or the address of any other
     * other borrower whose debt should be removed
     * @return The final amount repaid
     **/
    function repay(
        address asset,
        uint256 amount,
        uint256 rateMode,
        address onBehalfOf
    ) external returns (uint256);

    /**
     * @dev Allows a borrower to swap his debt between stable and variable mode, or viceversa
     * @param asset The address of the underlying asset borrowed
     * @param rateMode The rate mode that the user wants to swap to
     **/
    function swapBorrowRateMode(address asset, uint256 rateMode) external;

    /**
     * @dev Rebalances the stable interest rate of a user to the current stable rate defined on the reserve.
     * - Users can be rebalanced if the following conditions are satisfied:
     *     1. Usage ratio is above 95%
     *     2. the current deposit APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too much has been
     *        borrowed at a stable rate and depositors are not earning enough
     * @param asset The address of the underlying asset borrowed
     * @param user The address of the user to be rebalanced
     **/
    function rebalanceStableBorrowRate(address asset, address user) external;

    /**
     * @dev Allows depositors to enable/disable a specific deposited asset as collateral
     * @param asset The address of the underlying asset deposited
     * @param useAsCollateral `true` if the user wants to use the deposit as collateral, `false` otherwise
     **/
    function setUserUseReserveAsCollateral(address asset, bool useAsCollateral)
        external;

    /**
     * @dev Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1
     * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives
     *   a proportionally amount of the `collateralAsset` plus a bonus to cover market risk
     * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
     * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
     * @param user The address of the borrower getting liquidated
     * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
     * @param receiveAToken `true` if the liquidators wants to receive the collateral aTokens, `false` if he wants
     * to receive the underlying collateral asset directly
     **/
    function liquidationCall(
        address collateralAsset,
        address debtAsset,
        address user,
        uint256 debtToCover,
        bool receiveAToken
    ) external;

    /**
     * @dev Allows smartcontracts to access the liquidity of the pool within one transaction,
     * as long as the amount taken plus a fee is returned.
     * IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept into consideration.
     * For further details please visit https://developers.aave.com
     * @param receiverAddress The address of the contract receiving the funds, implementing the IFlashLoanReceiver interface
     * @param assets The addresses of the assets being flash-borrowed
     * @param amounts The amounts amounts being flash-borrowed
     * @param modes Types of the debt to open if the flash loan is not returned:
     *   0 -> Don't open any debt, just revert if funds can't be transferred from the receiver
     *   1 -> Open debt at stable rate for the value of the amount flash-borrowed to the `onBehalfOf` address
     *   2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address
     * @param onBehalfOf The address  that will receive the debt in the case of using on `modes` 1 or 2
     * @param params Variadic packed params to pass to the receiver as extra information
     * @param referralCode Code used to register the integrator originating the operation, for potential rewards.
     *   0 if the action is executed directly by the user, without any middle-man
     **/
    function flashLoan(
        address receiverAddress,
        address[] calldata assets,
        uint256[] calldata amounts,
        uint256[] calldata modes,
        address onBehalfOf,
        bytes calldata params,
        uint16 referralCode
    ) external;

    /**
     * @dev Returns the user account data across all the reserves
     * @param user The address of the user
     * @return totalCollateralETH the total collateral in ETH of the user
     * @return totalDebtETH the total debt in ETH of the user
     * @return availableBorrowsETH the borrowing power left of the user
     * @return currentLiquidationThreshold the liquidation threshold of the user
     * @return ltv the loan to value of the user
     * @return healthFactor the current health factor of the user
     **/
    function getUserAccountData(address user)
        external
        view
        returns (
            uint256 totalCollateralETH,
            uint256 totalDebtETH,
            uint256 availableBorrowsETH,
            uint256 currentLiquidationThreshold,
            uint256 ltv,
            uint256 healthFactor
        );

    function initReserve(
        address reserve,
        address aTokenAddress,
        address stableDebtAddress,
        address variableDebtAddress,
        address interestRateStrategyAddress
    ) external;

    function setReserveInterestRateStrategyAddress(
        address reserve,
        address rateStrategyAddress
    ) external;

    function setConfiguration(address reserve, uint256 configuration) external;

    /**
     * @dev Returns the configuration of the reserve
     * @param asset The address of the underlying asset of the reserve
     * @return The configuration of the reserve
     **/
    function getConfiguration(address asset)
        external
        view
        returns (DataTypes.ReserveConfigurationMap memory);

    /**
     * @dev Returns the configuration of the user across all the reserves
     * @param user The user address
     * @return The configuration of the user
     **/
    function getUserConfiguration(address user)
        external
        view
        returns (DataTypes.UserConfigurationMap memory);

    /**
     * @dev Returns the normalized income normalized income of the reserve
     * @param asset The address of the underlying asset of the reserve
     * @return The reserve's normalized income
     */
    function getReserveNormalizedIncome(address asset)
        external
        view
        returns (uint256);

    /**
     * @dev Returns the normalized variable debt per unit of asset
     * @param asset The address of the underlying asset of the reserve
     * @return The reserve normalized variable debt
     */
    function getReserveNormalizedVariableDebt(address asset)
        external
        view
        returns (uint256);

    /**
     * @dev Returns the state and configuration of the reserve
     * @param asset The address of the underlying asset of the reserve
     * @return The state of the reserve
     **/
    function getReserveData(address asset)
        external
        view
        returns (DataTypes.ReserveData memory);

    function finalizeTransfer(
        address asset,
        address from,
        address to,
        uint256 amount,
        uint256 balanceFromAfter,
        uint256 balanceToBefore
    ) external;

    function getReservesList() external view returns (address[] memory);

    function setPause(bool val) external;

    function paused() external view returns (bool);
}

File 6 of 15 : IWAVAX.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

interface IWAVAX {
    function deposit() external payable;
    function transfer(address to, uint value) external returns (bool);
    function balanceOf(address owner) external view returns (uint); 
    function withdraw(uint) external;
    function approve(address to, uint value) external returns (bool);
}

File 7 of 15 : IERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

interface IERC20 {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view returns (uint8);
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
    function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 8 of 15 : SafeMath.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

// From https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/Math.sol
// Subject to the MIT license.

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting with custom message on overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, errorMessage);

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on underflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot underflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction underflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on underflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot underflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, errorMessage);

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers.
     * Reverts on division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers.
     * Reverts with custom message on division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

File 9 of 15 : DexLibrary.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

import "./SafeMath.sol";
import "../interfaces/IPair.sol";
import "../interfaces/IWAVAX.sol";

library DexLibrary {
    using SafeMath for uint;
    bytes private constant zeroBytes = new bytes(0);
    IWAVAX private constant WAVAX = IWAVAX(0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7);

    /**
     * @notice Swap directly through a Pair
     * @param amountIn input amount
     * @param fromToken address
     * @param toToken address
     * @param pair Pair used for swap
     * @return output amount
     */
    function swap(uint amountIn, address fromToken, address toToken, IPair pair) internal returns (uint) {
        (address token0,) = sortTokens(fromToken, toToken);
        (uint112 reserve0, uint112 reserve1,) = pair.getReserves();
        if (token0 != fromToken) (reserve0, reserve1) = (reserve1, reserve0);
        uint amountOut1 = 0;
        uint amountOut2 = getAmountOut(amountIn, reserve0, reserve1);
        if (token0 != fromToken) (amountOut1, amountOut2) = (amountOut2, amountOut1);
        safeTransfer(fromToken, address(pair), amountIn);
        pair.swap(amountOut1, amountOut2, address(this), zeroBytes);
        return amountOut2 > amountOut1 ? amountOut2 : amountOut1;
    }

    function checkSwapPairCompatibility(IPair pair, address tokenA, address tokenB) internal pure returns (bool) {
        return (tokenA == pair.token0() || tokenA == pair.token1()) && (tokenB == pair.token0() || tokenB == pair.token1()) && tokenA != tokenB;
    }

    function estimateConversionThroughPair(uint amountIn, address fromToken, address toToken, IPair swapPair) internal view returns (uint) {
        (address token0,) = sortTokens(fromToken, toToken);
        (uint112 reserve0, uint112 reserve1,) = swapPair.getReserves();
        if (token0 != fromToken) (reserve0, reserve1) = (reserve1, reserve0);
        return getAmountOut(amountIn, reserve0, reserve1);
    }

    /**
     * @notice Converts reward tokens to deposit tokens
     * @dev No price checks enforced
     * @param amount reward tokens
     * @return deposit tokens
     */
    function convertRewardTokensToDepositTokens(uint amount, address rewardToken, address depositToken, IPair swapPairToken0, IPair swapPairToken1) internal returns (uint) {
        uint amountIn = amount.div(2);
        require(amountIn > 0, "DexLibrary::_convertRewardTokensToDepositTokens");

        address token0 = IPair(depositToken).token0();
        uint amountOutToken0 = amountIn;
        if (rewardToken != token0) {
            amountOutToken0 = DexLibrary.swap(amountIn, rewardToken, token0, swapPairToken0);
        }

        address token1 = IPair(depositToken).token1();
        uint amountOutToken1 = amountIn;
        if (rewardToken != token1) {
            amountOutToken1 = DexLibrary.swap(amountIn, rewardToken, token1, swapPairToken1);
        }

        return DexLibrary.addLiquidity(depositToken, amountOutToken0, amountOutToken1);
    }

    /**
     * @notice Add liquidity directly through a Pair
     * @dev Checks adding the max of each token amount
     * @param depositToken address
     * @param maxAmountIn0 amount token0
     * @param maxAmountIn1 amount token1
     * @return liquidity tokens
     */
    function addLiquidity(address depositToken, uint maxAmountIn0, uint maxAmountIn1) internal returns (uint) {
        (uint112 reserve0, uint112 reserve1,) = IPair(address(depositToken)).getReserves();
        uint amountIn1 = _quoteLiquidityAmountOut(maxAmountIn0, reserve0, reserve1);
        if (amountIn1 > maxAmountIn1) {
            amountIn1 = maxAmountIn1;
            maxAmountIn0 = _quoteLiquidityAmountOut(maxAmountIn1, reserve1, reserve0);
        }

        safeTransfer(IPair(depositToken).token0(), depositToken, maxAmountIn0);
        safeTransfer(IPair(depositToken).token1(), depositToken, amountIn1);
        return IPair(depositToken).mint(address(this));
    }

    /**
     * @notice Quote liquidity amount out
     * @param amountIn input tokens
     * @param reserve0 size of input asset reserve
     * @param reserve1 size of output asset reserve
     * @return liquidity tokens
     */
    function _quoteLiquidityAmountOut(uint amountIn, uint reserve0, uint reserve1) private pure returns (uint) {
        return amountIn.mul(reserve1).div(reserve0);
    }

    /**
     * @notice Given two tokens, it'll return the tokens in the right order for the tokens pair
     * @dev TokenA must be different from TokenB, and both shouldn't be address(0), no validations
     * @param tokenA address
     * @param tokenB address
     * @return sorted tokens
     */
    function sortTokens(address tokenA, address tokenB) internal pure returns (address, address) {
        return tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
    }

    /**
     * @notice Given an input amount of an asset and pair reserves, returns maximum output amount of the other asset
     * @dev Assumes swap fee is 0.30%
     * @param amountIn input asset
     * @param reserveIn size of input asset reserve
     * @param reserveOut size of output asset reserve
     * @return maximum output amount
     */
    function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint) {
        uint amountInWithFee = amountIn.mul(997);
        uint numerator = amountInWithFee.mul(reserveOut);
        uint denominator = reserveIn.mul(1000).add(amountInWithFee);
        return numerator.div(denominator);
    }

    /**
     * @notice Safely transfer using an anonymous ERC20 token
     * @dev Requires token to return true on transfer
     * @param token address
     * @param to recipient address
     * @param value amount
     */
    function safeTransfer(address token, address to, uint256 value) internal {
        require(IERC20(token).transfer(to, value), "DexLibrary::TRANSFER_FROM_FAILED");
    }
}

File 10 of 15 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <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 () internal {
        _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 make 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 15 : Ownable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

import "./Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

File 12 of 15 : Permissioned.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

import "./Ownable.sol";
import "./SafeMath.sol";

abstract contract Permissioned is Ownable {
    using SafeMath for uint;

    uint public numberOfAllowedDepositors;
    mapping(address => bool) public allowedDepositors;

    event AllowDepositor(address indexed account);
    event RemoveDepositor(address indexed account);

    modifier onlyAllowedDeposits() {
        if (numberOfAllowedDepositors > 0) {
            require(allowedDepositors[msg.sender] == true, "Permissioned::onlyAllowedDeposits, not allowed");
        }
        _;
    }

    /**
     * @notice Add an allowed depositor
     * @param depositor address
     */
    function allowDepositor(address depositor) external onlyOwner {
        require(allowedDepositors[depositor] == false, "Permissioned::allowDepositor");
        allowedDepositors[depositor] = true;
        numberOfAllowedDepositors = numberOfAllowedDepositors.add(1);
        emit AllowDepositor(depositor);
    }

    /**
     * @notice Remove an allowed depositor
     * @param depositor address
     */
    function removeDepositor(address depositor) external onlyOwner {
        require(numberOfAllowedDepositors > 0, "Permissioned::removeDepositor, no allowed depositors");
        require(allowedDepositors[depositor] == true, "Permissioned::removeDepositor, not allowed");
        allowedDepositors[depositor] = false;
        numberOfAllowedDepositors = numberOfAllowedDepositors.sub(1);
        emit RemoveDepositor(depositor);
    }
}

File 13 of 15 : YakERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;

import "./lib/SafeMath.sol";
import "./interfaces/IERC20.sol";

abstract contract YakERC20 {
    using SafeMath for uint256;

    string public name = "Yield Yak";
    string public symbol = "YRT";
    uint8 public constant decimals = 18;
    uint256 public totalSupply;
  
    mapping (address => mapping (address => uint256)) internal allowances;
    mapping (address => uint256) internal balances;

    /// @dev keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
    bytes32 public constant DOMAIN_TYPEHASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;

    /// @dev keccak256("1");
    bytes32 public constant VERSION_HASH = 0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6;

    /// @dev keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
    bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;

    mapping(address => uint) public nonces;

    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);

    constructor() {}

    /**
     * @notice Get the number of tokens `spender` is approved to spend on behalf of `account`
     * @param account The address of the account holding the funds
     * @param spender The address of the account spending the funds
     * @return The number of tokens approved
     */
    function allowance(address account, address spender) external view returns (uint) {
        return allowances[account][spender];
    }

    /**
     * @notice Approve `spender` to transfer up to `amount` from `src`
     * @dev This will overwrite the approval amount for `spender`
     * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)
     * It is recommended to use increaseAllowance and decreaseAllowance instead
     * @param spender The address of the account which may transfer tokens
     * @param amount The number of tokens that are approved (2^256-1 means infinite)
     * @return Whether or not the approval succeeded
     */
    function approve(address spender, uint256 amount) external returns (bool) {
        _approve(msg.sender, spender, amount);
        return true;
    }

    /**
     * @notice Get the number of tokens held by the `account`
     * @param account The address of the account to get the balance of
     * @return The number of tokens held
     */
    function balanceOf(address account) external view returns (uint) {
        return balances[account];
    }

    /**
     * @notice Transfer `amount` tokens from `msg.sender` to `dst`
     * @param dst The address of the destination account
     * @param amount The number of tokens to transfer
     * @return Whether or not the transfer succeeded
     */
    function transfer(address dst, uint256 amount) external returns (bool) {
        _transferTokens(msg.sender, dst, amount);
        return true;
    }

    /**
     * @notice Transfer `amount` tokens from `src` to `dst`
     * @param src The address of the source account
     * @param dst The address of the destination account
     * @param amount The number of tokens to transfer
     * @return Whether or not the transfer succeeded
     */
    function transferFrom(address src, address dst, uint256 amount) external returns (bool) {
        address spender = msg.sender;
        uint256 spenderAllowance = allowances[src][spender];

        if (spender != src && spenderAllowance != uint256(-1)) {
            uint256 newAllowance = spenderAllowance.sub(amount, "transferFrom: transfer amount exceeds allowance");
            allowances[src][spender] = newAllowance;

            emit Approval(src, spender, newAllowance);
        }

        _transferTokens(src, dst, amount);
        return true;
    }


    /**
     * @notice Approval implementation
     * @param owner The address of the account which owns tokens
     * @param spender The address of the account which may transfer tokens
     * @param amount The number of tokens that are approved (2^256-1 means infinite)
     */
    function _approve(address owner, address spender, uint256 amount) internal {
        require(owner != address(0), "_approve::owner zero address");
        require(spender != address(0), "_approve::spender zero address");
        allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @notice Transfer implementation
     * @param from The address of the account which owns tokens
     * @param to The address of the account which is receiving tokens
     * @param value The number of tokens that are being transferred
     */
    function _transferTokens(address from, address to, uint256 value) internal {
        require(to != address(0), "_transferTokens: cannot transfer to the zero address");

        balances[from] = balances[from].sub(value, "_transferTokens: transfer exceeds from balance");
        balances[to] = balances[to].add(value);
        emit Transfer(from, to, value);
    }

    function _mint(address to, uint256 value) internal {
        totalSupply = totalSupply.add(value);
        balances[to] = balances[to].add(value);
        emit Transfer(address(0), to, value);
    }

    function _burn(address from, uint256 value) internal {
        balances[from] = balances[from].sub(value, "_burn: burn amount exceeds from balance");
        totalSupply = totalSupply.sub(value, "_burn: burn amount exceeds total supply");
        emit Transfer(from, address(0), value);
    }

    /**
     * @notice Triggers an approval from owner to spender
     * @param owner The address to approve from
     * @param spender The address to be approved
     * @param value The number of tokens that are approved (2^256-1 means infinite)
     * @param deadline The time at which to expire the signature
     * @param v The recovery byte of the signature
     * @param r Half of the ECDSA signature pair
     * @param s Half of the ECDSA signature pair
     */
    function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external {
        require(deadline >= block.timestamp, "permit::expired");

        bytes32 encodeData = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline));
        _validateSignedData(owner, encodeData, v, r, s);

        _approve(owner, spender, value);
    }

    /**
     * @notice Recovers address from signed data and validates the signature
     * @param signer Address that signed the data
     * @param encodeData Data signed by the address
     * @param v The recovery byte of the signature
     * @param r Half of the ECDSA signature pair
     * @param s Half of the ECDSA signature pair
     */
    function _validateSignedData(address signer, bytes32 encodeData, uint8 v, bytes32 r, bytes32 s) internal view {
        bytes32 digest = keccak256(
            abi.encodePacked(
                "\x19\x01",
                getDomainSeparator(),
                encodeData
            )
        );
        address recoveredAddress = ecrecover(digest, v, r, s);
        // Explicitly disallow authorizations for address(0) as ecrecover returns address(0) on malformed messages
        require(recoveredAddress != address(0) && recoveredAddress == signer, "Arch::validateSig: invalid signature");
    }

    /**
     * @notice EIP-712 Domain separator
     * @return Separator
     */
    function getDomainSeparator() public view returns (bytes32) {
        return keccak256(
            abi.encode(
                DOMAIN_TYPEHASH,
                keccak256(bytes(name)),
                VERSION_HASH,
                _getChainId(),
                address(this)
            )
        );
    }

    /**
     * @notice Current id of the chain where this contract is deployed
     * @return Chain id
     */
    function _getChainId() internal pure returns (uint) {
        uint256 chainId;
        assembly { chainId := chainid() }
        return chainId;
    }
}

File 14 of 15 : Context.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.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 GSN 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 payable) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

File 15 of 15 : IPair.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

import "./IERC20.sol";

interface IPair is IERC20 {
    function token0() external pure returns (address);
    function token1() external pure returns (address);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function mint(address to) external returns (uint liquidity);
    function sync() external;
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"address","name":"_rewardDistribution","type":"address"},{"internalType":"address","name":"_blizzChef","type":"address"},{"internalType":"address","name":"_tokenDelegator","type":"address"},{"internalType":"address","name":"_timelock","type":"address"},{"components":[{"internalType":"address","name":"depositToken","type":"address"},{"internalType":"address","name":"poolRewardToken","type":"address"},{"internalType":"address","name":"avToken","type":"address"},{"internalType":"address","name":"avDebtToken","type":"address"}],"internalType":"struct BlizzStrategyV1.Tokens","name":"_tokens","type":"tuple"},{"components":[{"internalType":"address","name":"swapPairRewardDeposit","type":"address"},{"internalType":"address","name":"swapPairPoolReward","type":"address"}],"internalType":"struct BlizzStrategyV1.SwapPairs","name":"_swapPairs","type":"tuple"},{"components":[{"internalType":"uint256","name":"leverageLevel","type":"uint256"},{"internalType":"uint256","name":"safetyFactor","type":"uint256"},{"internalType":"uint256","name":"leverageBips","type":"uint256"},{"internalType":"uint256","name":"minMinting","type":"uint256"}],"internalType":"struct BlizzStrategyV1.LeverageSettings","name":"_leverageSettings","type":"tuple"},{"components":[{"internalType":"uint256","name":"minTokensToReinvest","type":"uint256"},{"internalType":"uint256","name":"adminFeeBips","type":"uint256"},{"internalType":"uint256","name":"devFeeBips","type":"uint256"},{"internalType":"uint256","name":"reinvestRewardBips","type":"uint256"}],"internalType":"struct BlizzStrategyV1.StrategySettings","name":"_strategySettings","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"AllowDepositor","type":"event"},{"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":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"newValue","type":"bool"}],"name":"DepositsEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newTotalDeposits","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newTotalSupply","type":"uint256"}],"name":"Reinvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"RemoveDepositor","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":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"UpdateAdminFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldValue","type":"address"},{"indexed":false,"internalType":"address","name":"newValue","type":"address"}],"name":"UpdateDevAddr","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"UpdateDevFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"UpdateMaxTokensToDepositWithoutReinvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"UpdateMinTokensToReinvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"UpdateReinvestReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"ADMIN_FEE_BIPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPOSITS_ENABLED","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEV_FEE_BIPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOKENS_TO_DEPOSIT_WITHOUT_REINVEST","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_TOKENS_TO_REINVEST","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REINVEST_REWARD_BIPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION_HASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"depositor","type":"address"}],"name":"allowDepositor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowedDepositors","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"checkReward","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":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depositToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"depositWithPermit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"devAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"estimateDeployedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"estimateReinvestReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getActualLeverage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getDepositTokensForShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDomainSeparator","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getSharesForDepositTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numberOfAllowedDepositors","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"recoverAVAX","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reinvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"depositor","type":"address"}],"name":"removeDepositor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minReturnAmountAccepted","type":"uint256"},{"internalType":"bool","name":"disableDeposits","type":"bool"}],"name":"rescueDeployedFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"revokeAllowance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"setAllowances","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDeposits","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":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"updateAdminFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newValue","type":"bool"}],"name":"updateDepositsEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newValue","type":"address"}],"name":"updateDevAddr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"updateDevFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_leverageLevel","type":"uint256"},{"internalType":"uint256","name":"_safetyFactor","type":"uint256"},{"internalType":"uint256","name":"_minMinting","type":"uint256"},{"internalType":"uint256","name":"_leverageBips","type":"uint256"}],"name":"updateLeverage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"updateMaxTokensToDepositWithoutReinvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"updateMinTokensToReinvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"updateReinvestReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60c060405260096080819052685969656c642059616b60b81b60a09081526200002c916000919062000a49565b506040805180820190915260038082526216549560ea1b6020909201918252620000599160019162000a49565b503480156200006757600080fd5b50604051620056bd380380620056bd8339810160408190526200008a9162000c7f565b60006200009662000278565b600680546001600160a01b0319166001600160a01b038316908117909155604051919250906000906000805160206200569d833981519152908290a3508851620000e89060009060208c019062000a49565b50601280546001600160a01b03808b166001600160a01b031992831617909255601380548a841690831617905560148054898416908316179055855160098054918416918316919091179055600a8054821673b31f66aa3c1e785363f0875a1b74e27b85fd66c7179055602080870151601b8054918516918416919091179055850151601c805491909316911617905562000183826200027c565b600b8054336001600160a01b03199182161790915560408501516019805483166001600160a01b039283161790556060860151601a805490931691161790558251620001cf906200029a565b620001d962000353565b8051620001e690620004ba565b6020810151620001f69062000542565b6040810151620002069062000610565b60608101516200021690620006ca565b62000222600162000784565b6200022d856200082c565b7fc7606d21ac05cd309191543e409f0845c016120563783d70e4f41419dc0ef2346000806040516200026192919062000df0565b60405180910390a150505050505050505062000f78565b3390565b80516015556040810151601755602081015160165560600151601855565b6001600160a01b038116620002cc5760405162461bcd60e51b8152600401620002c39062000f0d565b60405180910390fd5b601d80546001600160a01b0319166001600160a01b038381169190911791829055600954600a5462000306938316929182169116620008e6565b80620003315750601d54600a5460095462000331926001600160a01b039081169281169116620008e6565b620003505760405162461bcd60e51b8152600401620002c39062000eb0565b50565b6200035d62000278565b6001600160a01b03166200037062000a0b565b6001600160a01b031614620003995760405162461bcd60e51b8152600401620002c39062000e7b565b60095460145460405163095ea7b360e01b81526001600160a01b039283169263095ea7b392620003d3929116906000199060040162000dcc565b602060405180830381600087803b158015620003ee57600080fd5b505af115801562000403573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000429919062000c5d565b5060195460145460405163095ea7b360e01b81526001600160a01b039283169263095ea7b39262000464929116906000199060040162000dcc565b602060405180830381600087803b1580156200047f57600080fd5b505af115801562000494573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000350919062000c5d565b620004c462000278565b6001600160a01b0316620004d762000a0b565b6001600160a01b031614620005005760405162461bcd60e51b8152600401620002c39062000e7b565b7f481f79ac3a523b6d6db3c5a720e190e986d1cc1b41adcdf50f9caef849901100600c54826040516200053592919062000df0565b60405180910390a1600c55565b6200054c62000278565b6001600160a01b03166200055f62000a0b565b6001600160a01b031614620005885760405162461bcd60e51b8152600401620002c39062000e7b565b612710620005c2600f54620005ae6011548562000a1a60201b62001cb51790919060201c565b62000a1a60201b62001cb51790919060201c565b1115620005ce57600080fd5b7f3cc372f330f95ac9540626dc8a25f5bf21ba607215a5d58304cb804d446f104a601054826040516200060392919062000df0565b60405180910390a1601055565b6200061a62000278565b6001600160a01b03166200062d62000a0b565b6001600160a01b031614620006565760405162461bcd60e51b8152600401620002c39062000e7b565b6127106200067c600f54620005ae6010548562000a1a60201b62001cb51790919060201c565b11156200068857600080fd5b7f2a42303d002f0ba6cfe8259c91d4684443fb0b3de286ba74991175d65172613160115482604051620006bd92919062000df0565b60405180910390a1601155565b620006d462000278565b6001600160a01b0316620006e762000a0b565b6001600160a01b031614620007105760405162461bcd60e51b8152600401620002c39062000e7b565b61271062000736601154620005ae6010548562000a1a60201b62001cb51790919060201c565b11156200074257600080fd5b7fe7f97d51d307dc44045597c9978bec0f842e6bb40d19b9444084cfa30d9ed4f2600f54826040516200077792919062000df0565b60405180910390a1600f55565b6200078e62000278565b6001600160a01b0316620007a162000a0b565b6001600160a01b031614620007ca5760405162461bcd60e51b8152600401620002c39062000e7b565b600e5460ff1615158115151415620007e157600080fd5b600e805460ff19168215151790556040517f7b014ed3854e7f5cb0218d58b3c6ae7d53a68bb0af2f67bfb029ea42c38a7e85906200082190839062000de5565b60405180910390a150565b6200083662000278565b6001600160a01b03166200084962000a0b565b6001600160a01b031614620008725760405162461bcd60e51b8152600401620002c39062000e7b565b6001600160a01b0381166200089b5760405162461bcd60e51b8152600401620002c39062000dfe565b6006546040516001600160a01b038084169216906000805160206200569d83398151915290600090a3600680546001600160a01b0319166001600160a01b0392909216919091179055565b6000826001600160a01b0316846001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b1580156200092c57600080fd5b505afa15801562000941573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000967919062000c40565b6001600160a01b031614801562000a035750816001600160a01b0316846001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015620009bd57600080fd5b505afa158015620009d2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620009f8919062000c40565b6001600160a01b0316145b949350505050565b6006546001600160a01b031690565b60008282018381101562000a425760405162461bcd60e51b8152600401620002c39062000e44565b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1062000a8c57805160ff191683800117855562000abc565b8280016001018555821562000abc579182015b8281111562000abc57825182559160200191906001019062000a9f565b5062000aca92915062000ace565b5090565b5b8082111562000aca576000815560010162000acf565b80516001600160a01b038116811462000afd57600080fd5b919050565b60006080828403121562000b14578081fd5b604051608081016001600160401b038111828210171562000b3157fe5b8060405250809150825181526020830151602082015260408301516040820152606083015160608201525092915050565b60006040828403121562000b74578081fd5b604080519081016001600160401b038111828210171562000b9157fe5b60405290508062000ba28362000ae5565b815262000bb26020840162000ae5565b60208201525092915050565b60006080828403121562000bd0578081fd5b604051608081016001600160401b038111828210171562000bed57fe5b60405290508062000bfe8362000ae5565b815262000c0e6020840162000ae5565b602082015262000c216040840162000ae5565b604082015262000c346060840162000ae5565b60608201525092915050565b60006020828403121562000c52578081fd5b62000a428262000ae5565b60006020828403121562000c6f578081fd5b8151801515811462000a42578182fd5b60008060008060008060008060006102608a8c03121562000c9e578485fd5b89516001600160401b038082111562000cb5578687fd5b818c0191508c601f83011262000cc9578687fd5b81518181111562000cd657fe5b6020915062000cee601f8201601f1916830162000f54565b8181528e8383860101111562000d02578889fd5b885b8281101562000d2157848101840151828201850152830162000d04565b8281111562000d3257898484840101525b509b5062000d4490508c820162000ae5565b9950505062000d5660408b0162000ae5565b965062000d6660608b0162000ae5565b955062000d7660808b0162000ae5565b945062000d878b60a08c0162000bbe565b935062000d998b6101208c0162000b62565b925062000dab8b6101608c0162000b02565b915062000dbd8b6101e08c0162000b02565b90509295985092959850929598565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b918252602082015260400190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526036908201527f53776170207061697220646f6573206e6f74206d61746368206465706f73697460408201527f546f6b656e20616e6420726577617264546f6b656e2e00000000000000000000606082015260800190565b60208082526027908201527f537761702070616972206973206e656365737361727920627574206e6f7420736040820152661d5c1c1b1a595960ca1b606082015260800190565b6040518181016001600160401b038111828210171562000f7057fe5b604052919050565b6147158062000f886000396000f3fe608060405234801561001057600080fd5b50600436106103785760003560e01c80638b73e606116101d3578063c89039c511610104578063dd8ce4d6116100a2578063ed24911d1161007c578063ed24911d1461069d578063f2fde38b146106a5578063f7c618c1146106b8578063fdb5a03e146106c057610378565b8063dd8ce4d614610664578063e21ac82514610677578063eab89a5a1461068a57610378565b8063da09c72c116100de578063da09c72c14610639578063db8dd95c14610641578063dbd9a4d414610649578063dd62ed3e1461065157610378565b8063c89039c51461060b578063cff1b6ef14610613578063d505accf1461062657610378565b8063a9059cbb11610171578063b6b55f251161014b578063b6b55f25146105e0578063b9e57b80146105f3578063bd079f55146105fb578063c4b24a461461060357610378565b8063a9059cbb146105b2578063ac0d31ff146105c5578063b52a321f146105d857610378565b806395d89b41116101ad57806395d89b411461057c57806399729ec1146105845780639e4e731814610597578063a8ae2b7c1461059f57610378565b80638b73e606146105415780638da5cb5b146105545780639291d5631461056957610378565b80634a970be7116102ad578063789139bc1161024b5780637ecebe00116102255780637ecebe001461050057806381837230146105135780638980f11f146105265780638aff733d1461053957610378565b8063789139bc146104dd5780637ae26773146104e55780637d882097146104f857610378565b80634ebb7916116102875780634ebb7916146104a75780635ea682ea146104ba57806370a08231146104c2578063715018a6146104d557610378565b80634a970be71461046e5780634bebd1e7146104815780634e77ace51461049457610378565b806323b872dd1161031a57806330adf81f116102f457806330adf81f14610436578063313ce5671461043e5780633bdc6e7214610453578063483c2ef01461045b57610378565b806323b872dd146103fd5780632e1a7d4d146104105780632f4f21e21461042357610378565b80630f23475d116103565780630f23475d146103d057806318160ddd146103d857806320606b70146103e057806322a05141146103e857610378565b806306fdde031461037d578063076771111461039b578063095ea7b3146103b0575b600080fd5b6103856106c8565b6040516103929190613f1d565b60405180910390f35b6103a3610756565b6040516103929190613e96565b6103c36103be3660046139b2565b61075c565b6040516103929190613e8b565b6103a3610773565b6103a3610783565b6103a3610789565b6103fb6103f6366004613b6e565b6107ad565b005b6103c361040b366004613905565b61083c565b6103fb61041e366004613b1a565b610923565b6103fb6104313660046139b2565b6109cd565b6103a36109d7565b6104466109fb565b6040516103929190614603565b6103a3610a00565b6103c36104693660046138b1565b610a06565b6103fb61047c366004613b9f565b610a1b565b6103fb61048f3660046138b1565b610ab3565b6103fb6104a23660046139dd565b610b97565b6103fb6104b5366004613b1a565b610c35565b6103a3610ce1565b6103a36104d03660046138b1565b610ce7565b6103fb610d06565b6103a3610d9c565b6103fb6104f33660046138cd565b610da2565b6103a3610e6b565b6103a361050e3660046138b1565b610e8f565b6103fb610521366004613b1a565b610ea1565b6103fb6105343660046139b2565b610f20565b6103a3611032565b6103fb61054f3660046138b1565b611038565b61055c61113e565b6040516103929190613cd6565b6103fb6105773660046138b1565b61114d565b6103856111ed565b6103fb610592366004613b1a565b611247565b6103a36112f5565b6103fb6105ad366004613b1a565b611319565b6103c36105c03660046139b2565b6113c1565b6103fb6105d3366004613b4a565b6113ce565b6103c3611651565b6103fb6105ee366004613b1a565b61165a565b6103a3611667565b6103a36116ae565b6103a36116b4565b61055c6116c7565b6103fb610621366004613b1a565b6116d6565b6103fb610634366004613945565b61177e565b61055c611833565b6103a3611842565b6103fb611874565b6103a361065f3660046138cd565b6119c8565b6103a3610672366004613b1a565b6119f3565b6103fb610685366004613b1a565b611a2d565b6103a3610698366004613b1a565b611aac565b6103a3611add565b6103fb6106b33660046138b1565b611b74565b61055c611c42565b6103fb611c51565b6000805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561074e5780601f106107235761010080835404028352916020019161074e565b820191906000526020600020905b81548152906001019060200180831161073157829003601f168201915b505050505081565b60105481565b6000610769338484611ce1565b5060015b92915050565b600061077d610e6b565b90505b90565b60025481565b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b600b546001600160a01b031633146107e05760405162461bcd60e51b81526004016107d790614429565b60405180910390fd5b610809604051806080016040528086815260200185815260200183815260200184815250611d95565b600080610814611db3565b50909250905061082c6108278383611f26565b611f68565b610834612146565b505050505050565b6001600160a01b03831660008181526003602090815260408083203380855292528220549192909190821480159061087657506000198114155b1561090c5760006108a2856040518060600160405280602f815260200161465c602f91398491906122ce565b6001600160a01b03808916600081815260036020908152604080832094891680845294909152908190208490555192935090917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610902908590613e96565b60405180910390a3505b6109178686866122fa565b50600195945050505050565b600061092e82611aac565b905060185481116109515760405162461bcd60e51b81526004016107d790613fc4565b80156109c95761096133836123de565b600061096c826124b8565b600954909150610986906001600160a01b0316338361257c565b336001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364826040516109bf9190613e96565b60405180910390a2505b5050565b6109c98282612618565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b60075481565b60086020526000908152604090205460ff1681565b6009546040517fd505accf0000000000000000000000000000000000000000000000000000000081526001600160a01b039091169063d505accf90610a7090339030908a908a908a908a908a90600401613d0e565b600060405180830381600087803b158015610a8a57600080fd5b505af1158015610a9e573d6000803e3d6000fd5b50505050610aac3386612618565b5050505050565b610abb6127ca565b6001600160a01b0316610acc61113e565b6001600160a01b031614610af25760405162461bcd60e51b81526004016107d790614360565b6001600160a01b03811660009081526008602052604090205460ff1615610b2b5760405162461bcd60e51b81526004016107d790614238565b6001600160a01b0381166000908152600860205260409020805460ff19166001908117909155600754610b5d91611cb5565b6007556040516001600160a01b038216907fc0a1035c16faf8d1304056d92c00edf028f87e62b8235a938f00af9e3c0312c590600090a250565b610b9f6127ca565b6001600160a01b0316610bb061113e565b6001600160a01b031614610bd65760405162461bcd60e51b81526004016107d790614360565b600e5460ff1615158115151415610bec57600080fd5b600e805460ff19168215151790556040517f7b014ed3854e7f5cb0218d58b3c6ae7d53a68bb0af2f67bfb029ea42c38a7e8590610c2a908390613e8b565b60405180910390a150565b610c3d6127ca565b6001600160a01b0316610c4e61113e565b6001600160a01b031614610c745760405162461bcd60e51b81526004016107d790614360565b60008111610c8157600080fd5b604051339082156108fc029083906000818181858888f19350505050158015610cae573d6000803e3d6000fd5b507f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa28600082604051610c2a929190613d4f565b60115481565b6001600160a01b0381166000908152600460205260409020545b919050565b610d0e6127ca565b6001600160a01b0316610d1f61113e565b6001600160a01b031614610d455760405162461bcd60e51b81526004016107d790614360565b6006546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a36006805473ffffffffffffffffffffffffffffffffffffffff19169055565b600d5481565b610daa6127ca565b6001600160a01b0316610dbb61113e565b6001600160a01b031614610de15760405162461bcd60e51b81526004016107d790614360565b60405163095ea7b360e01b81526001600160a01b0383169063095ea7b390610e10908490600090600401613d4f565b602060405180830381600087803b158015610e2a57600080fd5b505af1158015610e3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6291906139f9565b6109c957600080fd5b6000806000610e78611db3565b509092509050610e888282611f26565b9250505090565b60056020526000908152604090205481565b610ea96127ca565b6001600160a01b0316610eba61113e565b6001600160a01b031614610ee05760405162461bcd60e51b81526004016107d790614360565b7f481f79ac3a523b6d6db3c5a720e190e986d1cc1b41adcdf50f9caef849901100600c5482604051610f139291906145bd565b60405180910390a1600c55565b610f286127ca565b6001600160a01b0316610f3961113e565b6001600160a01b031614610f5f5760405162461bcd60e51b81526004016107d790614360565b60008111610f6c57600080fd5b60405163a9059cbb60e01b81526001600160a01b0383169063a9059cbb90610f9a9033908590600401613d4f565b602060405180830381600087803b158015610fb457600080fd5b505af1158015610fc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fec91906139f9565b610ff557600080fd5b7f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa288282604051611026929190613d4f565b60405180910390a15050565b600f5481565b6110406127ca565b6001600160a01b031661105161113e565b6001600160a01b0316146110775760405162461bcd60e51b81526004016107d790614360565b6000600754116110995760405162461bcd60e51b81526004016107d790614149565b6001600160a01b03811660009081526008602052604090205460ff1615156001146110d65760405162461bcd60e51b81526004016107d7906142a6565b6001600160a01b0381166000908152600860205260409020805460ff19169055600754611104906001611f26565b6007556040516001600160a01b038216907f0e86f6608b536e5339a25b65ff531f5ea91e1313d056ecd4752b35cbd16137d490600090a250565b6006546001600160a01b031690565b600b546001600160a01b031633146111775760405162461bcd60e51b81526004016107d790614429565b600b546040517fa8e91499ed37682f43cffb045fcc7d379a91e8c9a14e6321877ee34dee564c00916111b6916001600160a01b03909116908490613d68565b60405180910390a1600b805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b60018054604080516020600284861615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561074e5780601f106107235761010080835404028352916020019161074e565b61124f6127ca565b6001600160a01b031661126061113e565b6001600160a01b0316146112865760405162461bcd60e51b81526004016107d790614360565b6127106112aa600f546112a460105485611cb590919063ffffffff16565b90611cb5565b11156112b557600080fd5b7f2a42303d002f0ba6cfe8259c91d4684443fb0b3de286ba74991175d651726131601154826040516112e89291906145bd565b60405180910390a1601155565b7fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc681565b6113216127ca565b6001600160a01b031661133261113e565b6001600160a01b0316146113585760405162461bcd60e51b81526004016107d790614360565b6127106113766011546112a460105485611cb590919063ffffffff16565b111561138157600080fd5b7fe7f97d51d307dc44045597c9978bec0f842e6bb40d19b9444084cfa30d9ed4f2600f54826040516113b49291906145bd565b60405180910390a1600f55565b60006107693384846122fa565b6113d66127ca565b6001600160a01b03166113e761113e565b6001600160a01b03161461140d5760405162461bcd60e51b81526004016107d790614360565b6009546040516370a0823160e01b81526000916001600160a01b0316906370a082319061143e903090600401613cd6565b60206040518083038186803b15801561145657600080fd5b505afa15801561146a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148e9190613b32565b905060008061149b611db3565b5090925090506114ae6108278383611f26565b601454600954604051631a4ca37b60e21b81526001600160a01b03928316926369328dec926114e892911690600019903090600401613ddc565b602060405180830381600087803b15801561150257600080fd5b505af1158015611516573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061153a9190613b32565b506009546040516370a0823160e01b81526000916001600160a01b0316906370a082319061156c903090600401613cd6565b60206040518083038186803b15801561158457600080fd5b505afa158015611598573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115bc9190613b32565b9050856115c98286611f26565b10156115e75760405162461bcd60e51b81526004016107d790613f30565b7fc7606d21ac05cd309191543e409f0845c016120563783d70e4f41419dc0ef234611610610e6b565b6002546040516116219291906145bd565b60405180910390a1600e5460ff161515600114801561164257506001851515145b15610834576108346000610b97565b600e5460ff1681565b6116643382612618565b50565b6000806116726116b4565b9050600c5481106116a65761169e612710611698600f54846127ce90919063ffffffff16565b90612808565b915050610780565b600091505090565b600c5481565b6000806116bf61284a565b935050505090565b6009546001600160a01b031681565b6116de6127ca565b6001600160a01b03166116ef61113e565b6001600160a01b0316146117155760405162461bcd60e51b81526004016107d790614360565b612710611733600f546112a460115485611cb590919063ffffffff16565b111561173e57600080fd5b7f3cc372f330f95ac9540626dc8a25f5bf21ba607215a5d58304cb804d446f104a601054826040516117719291906145bd565b60405180910390a1601055565b4284101561179e5760405162461bcd60e51b81526004016107d79061426f565b6001600160a01b038716600090815260056020908152604080832080546001810190915590516117f9927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928c928c928c92918c9101613e9f565b60405160208183030381529060405280519060200120905061181e8882868686612def565b611829888888611ce1565b5050505050505050565b600b546001600160a01b031681565b600080600061184f611db3565b509092509050610e886118628383611f26565b61169884670de0b6b3a76400006127ce565b61187c6127ca565b6001600160a01b031661188d61113e565b6001600160a01b0316146118b35760405162461bcd60e51b81526004016107d790614360565b60095460145460405163095ea7b360e01b81526001600160a01b039283169263095ea7b3926118eb9291169060001990600401613d4f565b602060405180830381600087803b15801561190557600080fd5b505af1158015611919573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061193d91906139f9565b5060195460145460405163095ea7b360e01b81526001600160a01b039283169263095ea7b3926119769291169060001990600401613d4f565b602060405180830381600087803b15801561199057600080fd5b505af11580156119a4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061166491906139f9565b6001600160a01b03918216600090815260036020908152604080832093909416825291909152205490565b6000611a09611a00610e6b565b600254906127ce565b611a14575080610d01565b61076d611a1f610e6b565b6002546116989085906127ce565b611a356127ca565b6001600160a01b0316611a4661113e565b6001600160a01b031614611a6c5760405162461bcd60e51b81526004016107d790614360565b7fa5dae50539d56dfe1fb5273d883b0c39bc76750a25d036fc5fbd09ad8fd5f57f600d5482604051611a9f9291906145bd565b60405180910390a1600d55565b6000611ab9611a00610e6b565b611ac557506000610d01565b61076d600254611698611ad6610e6b565b85906127ce565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60001b6000604051611b129190613c30565b6040519081900390207fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6611b44612ec5565b30604051602001611b59959493929190613ed3565b60405160208183030381529060405280519060200120905090565b611b7c6127ca565b6001600160a01b0316611b8d61113e565b6001600160a01b031614611bb35760405162461bcd60e51b81526004016107d790614360565b6001600160a01b038116611bd95760405162461bcd60e51b81526004016107d790614021565b6006546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36006805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b600a546001600160a01b031681565b323314611c705760405162461bcd60e51b81526004016107d79061407e565b6000806000611c7d61284a565b925092509250600c54811015611ca55760405162461bcd60e51b81526004016107d790613f8d565b611cb0838383612ec9565b505050565b600082820183811015611cda5760405162461bcd60e51b81526004016107d7906140b5565b9392505050565b6001600160a01b038316611d075760405162461bcd60e51b81526004016107d790614395565b6001600160a01b038216611d2d5760405162461bcd60e51b81526004016107d790614551565b6001600160a01b0380841660008181526003602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590611d88908590613e96565b60405180910390a3505050565b80516015556040810151601755602081015160165560600151601855565b6019546040516370a0823160e01b8152600091829182916001600160a01b0316906370a0823190611de8903090600401613cd6565b60206040518083038186803b158015611e0057600080fd5b505afa158015611e14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e389190613b32565b601a546040516370a0823160e01b81529194506001600160a01b0316906370a0823190611e69903090600401613cd6565b60206040518083038186803b158015611e8157600080fd5b505afa158015611e95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eb99190613b32565b91506000905081611ee7601554611698611ee0601754601554611f2690919063ffffffff16565b87906127ce565b1115611f2157611f1e82611f18601554611698611f11601754601554611f2690919063ffffffff16565b88906127ce565b90611f26565b90505b909192565b6000611cda83836040518060400160405280601f81526020017f536166654d6174683a207375627472616374696f6e20756e646572666c6f77008152506122ce565b6000806000611f75611db3565b919450925090506000611fc3611f8f86611f188787611f26565b611f18601754611698611faf601654601554611f2690919063ffffffff16565b611fbd8b611f188c8c611f26565b906127ce565b90506000611fd18483611f26565b90505b8015610834578284811115611fe65750835b601454600954604051631a4ca37b60e21b81526001600160a01b03928316926369328dec9261201e9291169085903090600401613ddc565b602060405180830381600087803b15801561203857600080fd5b505af115801561204c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120709190613b32565b506014546009546040517f573ade810000000000000000000000000000000000000000000000000000000081526001600160a01b039283169263573ade81926120c59291169085906002903090600401613e2c565b602060405180830381600087803b1580156120df57600080fd5b505af11580156120f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121179190613b32565b50612120611db3565b919750955093508483106121345750610834565b61213e8584611f26565b915050611fd4565b6000806000612153611db3565b925092509250600061218560175461169861217b601654601554611f2690919063ffffffff16565b611fbd8888611f26565b90505b808410156122c8578061219b8584611cb5565b11156121ae576121ab8185611f26565b91505b6018548210156121bd576122c8565b6014546009546040517fa415bcad0000000000000000000000000000000000000000000000000000000081526001600160a01b039283169263a415bcad926122149291169086906002906000903090600401613e57565b600060405180830381600087803b15801561222e57600080fd5b505af1158015612242573d6000803e3d6000fd5b505060145460095460405163e8eda9df60e01b81526001600160a01b03928316945063e8eda9df9350612282929091169086903090600090600401613dff565b600060405180830381600087803b15801561229c57600080fd5b505af11580156122b0573d6000803e3d6000fd5b505050506122bc611db3565b91955093509150612188565b50505050565b600081848411156122f25760405162461bcd60e51b81526004016107d79190613f1d565b505050900390565b6001600160a01b0382166123205760405162461bcd60e51b81526004016107d7906143cc565b61235d816040518060600160405280602e81526020016146b2602e91396001600160a01b03861660009081526004602052604090205491906122ce565b6001600160a01b03808516600090815260046020526040808220939093559084168152205461238c9082611cb5565b6001600160a01b0380841660008181526004602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611d88908590613e96565b61241b8160405180606001604052806027815260200161468b602791396001600160a01b03851660009081526004602052604090205491906122ce565b60046000846001600160a01b03166001600160a01b031681526020019081526020016000208190555061246b816040518060600160405280602781526020016146356027913960025491906122ce565b6002556040516000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906124ac908590613e96565b60405180910390a35050565b60006124c382611f68565b60006124cd611db3565b505090508083116124de57826124e2565b6000195b601454600954604051631a4ca37b60e21b81529295506000926001600160a01b03928316926369328dec926125209291169088903090600401613ddc565b602060405180830381600087803b15801561253a57600080fd5b505af115801561254e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125729190613b32565b9050611cda612146565b60405163a9059cbb60e01b81526001600160a01b0384169063a9059cbb906125aa9085908590600401613d4f565b602060405180830381600087803b1580156125c457600080fd5b505af11580156125d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125fc91906139f9565b611cb05760405162461bcd60e51b81526004016107d7906144f4565b60075415612654573360009081526008602052604090205460ff1615156001146126545760405162461bcd60e51b81526004016107d7906140ec565b600e5460ff16151560011461267b5760405162461bcd60e51b81526004016107d790614460565b600d54156126af57600080600061269061284a565b925092509250600d548111156126ab576126ab838383612ec9565b5050505b6009546040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b03909116906323b872dd906126fc90339030908690600401613cea565b602060405180830381600087803b15801561271657600080fd5b505af115801561272a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061274e91906139f9565b61276a5760405162461bcd60e51b81526004016107d790614203565b61277c82612777836119f3565b61318a565b6127858161320c565b816001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c826040516127be9190613e96565b60405180910390a25050565b3390565b6000826127dd5750600061076d565b828202828482816127ea57fe5b0414611cda5760405162461bcd60e51b81526004016107d790614303565b6000611cda83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506132a1565b6013546040517fbfccff450000000000000000000000000000000000000000000000000000000081526000918291829182916001600160a01b039091169063bfccff459061289c903090600401613cd6565b60206040518083038186803b1580156128b457600080fd5b505afa1580156128c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128ec9190613b32565b604080516002808252606080830184529394509091602083019080368337505060195482519293506001600160a01b03169183915060009061292a57fe5b6001600160a01b039283166020918202929092010152601a5482519116908290600190811061295557fe5b60200260200101906001600160a01b031690816001600160a01b03168152505061297d613830565b60135482516001600160a01b0390911690639a7b5f1190849060009061299f57fe5b60200260200101516040518263ffffffff1660e01b81526004016129c39190613cd6565b60a06040518083038186803b1580156129db57600080fd5b505afa1580156129ef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a139190613a15565b9050612a1e816132d8565b9050612a28613868565b60135483516001600160a01b0390911690630f208beb908590600090612a4a57fe5b6020026020010151306040518363ffffffff1660e01b8152600401612a70929190613d68565b604080518083038186803b158015612a8757600080fd5b505afa158015612a9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612abf9190613a84565b90506000612ae764e8d4a51000611698856060015185600001516127ce90919063ffffffff16565b9050612b0a612b03836020015183611f2690919063ffffffff16565b8690611cb5565b60135485519196506001600160a01b031690639a7b5f119086906001908110612b2f57fe5b60200260200101516040518263ffffffff1660e01b8152600401612b539190613cd6565b60a06040518083038186803b158015612b6b57600080fd5b505afa158015612b7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ba39190613a15565b9250612bae836132d8565b60135485519194506001600160a01b031690630f208beb9086906001908110612bd357fe5b6020026020010151306040518363ffffffff1660e01b8152600401612bf9929190613d68565b604080518083038186803b158015612c1057600080fd5b505afa158015612c24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c489190613a84565b9150612c6e64e8d4a51000611698856060015185600001516127ce90919063ffffffff16565b9050612c8a612b03836020015183611f2690919063ffffffff16565b9450612c97856002612808565b601b546040516370a0823160e01b8152919650612d1e916001600160a01b03909116906370a0823190612cce903090600401613cd6565b60206040518083038186803b158015612ce657600080fd5b505afa158015612cfa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b039190613b32565b601b54600a54601c54929750600092612d499289926001600160a01b0391821692908216911661347b565b600a546040516370a0823160e01b81529192506000916001600160a01b03909116906370a0823190612d7f903090600401613cd6565b60206040518083038186803b158015612d9757600080fd5b505afa158015612dab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dcf9190613b32565b90506000612ddd8383611cb5565b979b919a509698509650505050505050565b6000612df9611add565b85604051602001612e0b929190613ca0565b604051602081830303815290604052805190602001209050600060018286868660405160008152602001604052604051612e489493929190613eff565b6020604051602081039080840390855afa158015612e6a573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590612ea05750866001600160a01b0316816001600160a01b0316145b612ebc5760405162461bcd60e51b81526004016107d7906141a6565b50505050505050565b4690565b6040805160028082526060808301845292602083019080368337505060195482519293506001600160a01b031691839150600090612f0357fe5b6001600160a01b039283166020918202929092010152601a54825191169082906001908110612f2e57fe5b6001600160a01b0392831660209182029290920101526013546040517f8e2eba09000000000000000000000000000000000000000000000000000000008152911690638e2eba0990612f869030908590600401613d82565b600060405180830381600087803b158015612fa057600080fd5b505af1158015612fb4573d6000803e3d6000fd5b50506012546040517fe6c91a150000000000000000000000000000000000000000000000000000000081526001600160a01b03909116925063e6c91a15915061300290600190600401613e8b565b600060405180830381600087803b15801561301c57600080fd5b505af1158015613030573d6000803e3d6000fd5b5050505061303d84613556565b50600061305b612710611698601154866127ce90919063ffffffff16565b9050801561308057600a54600b54613080916001600160a01b0390811691168361257c565b600061309d612710611698601054876127ce90919063ffffffff16565b905080156130c357600a546130c3906001600160a01b03166130bd61113e565b8361257c565b60006130e0612710611698600f54886127ce90919063ffffffff16565b905080156130ff57600a546130ff906001600160a01b0316338361257c565b600061313361311483611f1886818b8a611f26565b600a54600954601d546001600160a01b0392831692918216911661357a565b905061313e8161320c565b7fc7606d21ac05cd309191543e409f0845c016120563783d70e4f41419dc0ef234613167610e6b565b6002546040516131789291906145bd565b60405180910390a15050505050505050565b6002546131979082611cb5565b6002556001600160a01b0382166000908152600460205260409020546131bd9082611cb5565b6001600160a01b0383166000818152600460205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906124ac908590613e96565b6000811161322c5760405162461bcd60e51b81526004016107d790614497565b60145460095460405163e8eda9df60e01b81526001600160a01b039283169263e8eda9df926132679291169085903090600090600401613dff565b600060405180830381600087803b15801561328157600080fd5b505af1158015613295573d6000803e3d6000fd5b50505050611664612146565b600081836132c25760405162461bcd60e51b81526004016107d79190613f1d565b5060008385816132ce57fe5b0495945050505050565b6132e0613830565b816040015142116132f2575080610d01565b81518061330757505042604082015280610d01565b6000613320846040015142611f2690919063ffffffff16565b9050600061344a601360009054906101000a90046001600160a01b03166001600160a01b03166317caf6f16040518163ffffffff1660e01b815260040160206040518083038186803b15801561337557600080fd5b505afa158015613389573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133ad9190613b32565b602080880151601354604080517feacdaabc000000000000000000000000000000000000000000000000000000008152905161169894611fbd936001600160a01b03169263eacdaabc9260048083019392829003018186803b15801561341257600080fd5b505afa158015613426573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee09190613b32565b905061346d613462846116988464e8d4a510006127ce565b606087015190611cb5565b606086015250929392505050565b600080613488858561371b565b509050600080846001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156134c757600080fd5b505afa1580156134db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134ff9190613acc565b5091509150866001600160a01b0316836001600160a01b03161461351f57905b61354a88836dffffffffffffffffffffffffffff16836dffffffffffffffffffffffffffff1661374c565b98975050505050505050565b601b54600a54601c5460009261076d9285926001600160a01b039283169291821691165b600080613587858561371b565b509050600080846001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156135c657600080fd5b505afa1580156135da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135fe9190613acc565b5091509150866001600160a01b0316836001600160a01b03161461361e57905b60008061364c8a856dffffffffffffffffffffffffffff16856dffffffffffffffffffffffffffff1661374c565b9050886001600160a01b0316856001600160a01b03161461366957905b61367489888c613794565b604080516000815260208101918290527f022c0d9f000000000000000000000000000000000000000000000000000000009091526001600160a01b0388169063022c0d9f906136cc90859085903090602481016145cb565b600060405180830381600087803b1580156136e657600080fd5b505af11580156136fa573d6000803e3d6000fd5b5050505081811161370b578161370d565b805b9a9950505050505050505050565b600080826001600160a01b0316846001600160a01b03161061373e578284613741565b83835b915091509250929050565b60008061375b856103e56127ce565b9050600061376982856127ce565b9050600061377d836112a4886103e86127ce565b90506137898282612808565b979650505050505050565b60405163a9059cbb60e01b81526001600160a01b0384169063a9059cbb906137c29085908590600401613d4f565b602060405180830381600087803b1580156137dc57600080fd5b505af11580156137f0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061381491906139f9565b611cb05760405162461bcd60e51b81526004016107d790614588565b6040518060a001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b031681525090565b604051806040016040528060008152602001600081525090565b80516dffffffffffffffffffffffffffff81168114610d0157600080fd5b803560ff81168114610d0157600080fd5b6000602082840312156138c2578081fd5b8135611cda81614611565b600080604083850312156138df578081fd5b82356138ea81614611565b915060208301356138fa81614611565b809150509250929050565b600080600060608486031215613919578081fd5b833561392481614611565b9250602084013561393481614611565b929592945050506040919091013590565b600080600080600080600060e0888a03121561395f578283fd5b873561396a81614611565b9650602088013561397a81614611565b95506040880135945060608801359350613996608089016138a0565b925060a0880135915060c0880135905092959891949750929550565b600080604083850312156139c4578182fd5b82356139cf81614611565b946020939093013593505050565b6000602082840312156139ee578081fd5b8135611cda81614626565b600060208284031215613a0a578081fd5b8151611cda81614626565b600060a08284031215613a26578081fd5b60405160a0810181811067ffffffffffffffff82111715613a4357fe5b8060405250825181526020830151602082015260408301516040820152606083015160608201526080830151613a7881614611565b60808201529392505050565b600060408284031215613a95578081fd5b6040516040810181811067ffffffffffffffff82111715613ab257fe5b604052825181526020928301519281019290925250919050565b600080600060608486031215613ae0578283fd5b613ae984613882565b9250613af760208501613882565b9150604084015163ffffffff81168114613b0f578182fd5b809150509250925092565b600060208284031215613b2b578081fd5b5035919050565b600060208284031215613b43578081fd5b5051919050565b60008060408385031215613b5c578182fd5b8235915060208301356138fa81614626565b60008060008060808587031215613b83578182fd5b5050823594602084013594506040840135936060013592509050565b600080600080600060a08688031215613bb6578283fd5b8535945060208601359350613bcd604087016138a0565b94979396509394606081013594506080013592915050565b60008151808452815b81811015613c0a57602081850181015186830182015201613bee565b81811115613c1b5782602083870101525b50601f01601f19169290920160200192915050565b6000808354600180821660008114613c4f5760018114613c6657613c95565b60ff198316865260028304607f1686019350613c95565b600283048786526020808720875b83811015613c8d5781548a820152908501908201613c74565b505050860193505b509195945050505050565b7f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0397881681529590961660208601526040850193909352606084019190915260ff16608083015260a082015260c081019190915260e00190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0392831681529116602082015260400190565b6000604082016001600160a01b03808616845260206040818601528286518085526060870191508288019450855b81811015613dce578551851683529483019491830191600101613db0565b509098975050505050505050565b6001600160a01b0393841681526020810192909252909116604082015260600190565b6001600160a01b03948516815260208101939093529216604082015261ffff909116606082015260800190565b6001600160a01b03948516815260208101939093526040830191909152909116606082015260800190565b6001600160a01b0395861681526020810194909452604084019290925261ffff166060830152909116608082015260a00190565b901515815260200190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b9485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b93845260ff9290921660208401526040830152606082015260800190565b600060208252611cda6020830184613be5565b60208082526024908201527f426c697a7a537472617465677956313a3a7265736375654465706c6f7965644660408201527f756e647300000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526019908201527f426c697a7a537472617465677956313a3a7265696e7665737400000000000000604082015260600190565b60208082526027908201527f426c697a7a537472617465677956313a3a62656c6f77206d696e696d756d207760408201527f6974686472617700000000000000000000000000000000000000000000000000606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201527f6464726573730000000000000000000000000000000000000000000000000000606082015260800190565b60208082526014908201527f59616b53747261746567793a3a6f6e6c79454f41000000000000000000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252602e908201527f5065726d697373696f6e65643a3a6f6e6c79416c6c6f7765644465706f73697460408201527f732c206e6f7420616c6c6f776564000000000000000000000000000000000000606082015260800190565b60208082526034908201527f5065726d697373696f6e65643a3a72656d6f76654465706f7369746f722c206e60408201527f6f20616c6c6f776564206465706f7369746f7273000000000000000000000000606082015260800190565b60208082526024908201527f417263683a3a76616c69646174655369673a20696e76616c6964207369676e6160408201527f7475726500000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252818101527f426c697a7a537472617465677956313a3a7472616e73666572206661696c6564604082015260600190565b6020808252601c908201527f5065726d697373696f6e65643a3a616c6c6f774465706f7369746f7200000000604082015260600190565b6020808252600f908201527f7065726d69743a3a657870697265640000000000000000000000000000000000604082015260600190565b6020808252602a908201527f5065726d697373696f6e65643a3a72656d6f76654465706f7369746f722c206e60408201527f6f7420616c6c6f77656400000000000000000000000000000000000000000000606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60408201527f7700000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601c908201527f5f617070726f76653a3a6f776e6572207a65726f206164647265737300000000604082015260600190565b60208082526034908201527f5f7472616e73666572546f6b656e733a2063616e6e6f74207472616e7366657260408201527f20746f20746865207a65726f2061646472657373000000000000000000000000606082015260800190565b60208082526014908201527f59616b53747261746567793a3a6f6e6c79446576000000000000000000000000604082015260600190565b60208082526019908201527f426c697a7a537472617465677956313a3a5f6465706f73697400000000000000604082015260600190565b60208082526024908201527f426c697a7a537472617465677956313a3a5f7374616b654465706f736974546f60408201527f6b656e7300000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526025908201527f426c697a7a537472617465677956313a3a5452414e534645525f46524f4d5f4660408201527f41494c4544000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601e908201527f5f617070726f76653a3a7370656e646572207a65726f20616464726573730000604082015260600190565b6020808252818101527f4465784c6962726172793a3a5452414e534645525f46524f4d5f4641494c4544604082015260600190565b918252602082015260400190565b60008582528460208301526001600160a01b0384166040830152608060608301526145f96080830184613be5565b9695505050505050565b60ff91909116815260200190565b6001600160a01b038116811461166457600080fd5b801515811461166457600080fdfe5f6275726e3a206275726e20616d6f756e74206578636565647320746f74616c20737570706c797472616e7366657246726f6d3a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63655f6275726e3a206275726e20616d6f756e7420657863656564732066726f6d2062616c616e63655f7472616e73666572546f6b656e733a207472616e7366657220657863656564732066726f6d2062616c616e6365a26469706673582212203226d542ba74a299cc3c034bc5624706520b001848f61ab1141b846b914bd2c264736f6c634300070300338be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000a867c1aca4b5f1e0a66cf7b1fe33525d576088540000000000000000000000002d867ae30400fffad9bed8472c514c2d6b827f5f00000000000000000000000070bbe4a294878a14cb3cdd9315f5eb490e3461630000000000000000000000008d36c5c6947adccd25ef49ea1aac2ceacfff0bd700000000000000000000000050b7545627a5162f82a992c33b87adc75187b2180000000000000000000000000f34919404a290e71fc6a510cb4a6acb8d764b2400000000000000000000000081ccdd9e44c518caee2f720c43cd0853032a177900000000000000000000000052b9879984dc9565359bb52117c43665e699397b000000000000000000000000d5a37dc5c9a396a03dd1136fc76a1a02b1c88ffa000000000000000000000000ac3f978714c613e768272c502a8912bc03dcf6240000000000000000000000000000000000000000000000000000000000007cf40000000000000000000000000000000000000000000000000000000000000541000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000005af3107a4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002bc000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000175969656c642059616b3a20426c697a7a20574254432e65000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106103785760003560e01c80638b73e606116101d3578063c89039c511610104578063dd8ce4d6116100a2578063ed24911d1161007c578063ed24911d1461069d578063f2fde38b146106a5578063f7c618c1146106b8578063fdb5a03e146106c057610378565b8063dd8ce4d614610664578063e21ac82514610677578063eab89a5a1461068a57610378565b8063da09c72c116100de578063da09c72c14610639578063db8dd95c14610641578063dbd9a4d414610649578063dd62ed3e1461065157610378565b8063c89039c51461060b578063cff1b6ef14610613578063d505accf1461062657610378565b8063a9059cbb11610171578063b6b55f251161014b578063b6b55f25146105e0578063b9e57b80146105f3578063bd079f55146105fb578063c4b24a461461060357610378565b8063a9059cbb146105b2578063ac0d31ff146105c5578063b52a321f146105d857610378565b806395d89b41116101ad57806395d89b411461057c57806399729ec1146105845780639e4e731814610597578063a8ae2b7c1461059f57610378565b80638b73e606146105415780638da5cb5b146105545780639291d5631461056957610378565b80634a970be7116102ad578063789139bc1161024b5780637ecebe00116102255780637ecebe001461050057806381837230146105135780638980f11f146105265780638aff733d1461053957610378565b8063789139bc146104dd5780637ae26773146104e55780637d882097146104f857610378565b80634ebb7916116102875780634ebb7916146104a75780635ea682ea146104ba57806370a08231146104c2578063715018a6146104d557610378565b80634a970be71461046e5780634bebd1e7146104815780634e77ace51461049457610378565b806323b872dd1161031a57806330adf81f116102f457806330adf81f14610436578063313ce5671461043e5780633bdc6e7214610453578063483c2ef01461045b57610378565b806323b872dd146103fd5780632e1a7d4d146104105780632f4f21e21461042357610378565b80630f23475d116103565780630f23475d146103d057806318160ddd146103d857806320606b70146103e057806322a05141146103e857610378565b806306fdde031461037d578063076771111461039b578063095ea7b3146103b0575b600080fd5b6103856106c8565b6040516103929190613f1d565b60405180910390f35b6103a3610756565b6040516103929190613e96565b6103c36103be3660046139b2565b61075c565b6040516103929190613e8b565b6103a3610773565b6103a3610783565b6103a3610789565b6103fb6103f6366004613b6e565b6107ad565b005b6103c361040b366004613905565b61083c565b6103fb61041e366004613b1a565b610923565b6103fb6104313660046139b2565b6109cd565b6103a36109d7565b6104466109fb565b6040516103929190614603565b6103a3610a00565b6103c36104693660046138b1565b610a06565b6103fb61047c366004613b9f565b610a1b565b6103fb61048f3660046138b1565b610ab3565b6103fb6104a23660046139dd565b610b97565b6103fb6104b5366004613b1a565b610c35565b6103a3610ce1565b6103a36104d03660046138b1565b610ce7565b6103fb610d06565b6103a3610d9c565b6103fb6104f33660046138cd565b610da2565b6103a3610e6b565b6103a361050e3660046138b1565b610e8f565b6103fb610521366004613b1a565b610ea1565b6103fb6105343660046139b2565b610f20565b6103a3611032565b6103fb61054f3660046138b1565b611038565b61055c61113e565b6040516103929190613cd6565b6103fb6105773660046138b1565b61114d565b6103856111ed565b6103fb610592366004613b1a565b611247565b6103a36112f5565b6103fb6105ad366004613b1a565b611319565b6103c36105c03660046139b2565b6113c1565b6103fb6105d3366004613b4a565b6113ce565b6103c3611651565b6103fb6105ee366004613b1a565b61165a565b6103a3611667565b6103a36116ae565b6103a36116b4565b61055c6116c7565b6103fb610621366004613b1a565b6116d6565b6103fb610634366004613945565b61177e565b61055c611833565b6103a3611842565b6103fb611874565b6103a361065f3660046138cd565b6119c8565b6103a3610672366004613b1a565b6119f3565b6103fb610685366004613b1a565b611a2d565b6103a3610698366004613b1a565b611aac565b6103a3611add565b6103fb6106b33660046138b1565b611b74565b61055c611c42565b6103fb611c51565b6000805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561074e5780601f106107235761010080835404028352916020019161074e565b820191906000526020600020905b81548152906001019060200180831161073157829003601f168201915b505050505081565b60105481565b6000610769338484611ce1565b5060015b92915050565b600061077d610e6b565b90505b90565b60025481565b7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b600b546001600160a01b031633146107e05760405162461bcd60e51b81526004016107d790614429565b60405180910390fd5b610809604051806080016040528086815260200185815260200183815260200184815250611d95565b600080610814611db3565b50909250905061082c6108278383611f26565b611f68565b610834612146565b505050505050565b6001600160a01b03831660008181526003602090815260408083203380855292528220549192909190821480159061087657506000198114155b1561090c5760006108a2856040518060600160405280602f815260200161465c602f91398491906122ce565b6001600160a01b03808916600081815260036020908152604080832094891680845294909152908190208490555192935090917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610902908590613e96565b60405180910390a3505b6109178686866122fa565b50600195945050505050565b600061092e82611aac565b905060185481116109515760405162461bcd60e51b81526004016107d790613fc4565b80156109c95761096133836123de565b600061096c826124b8565b600954909150610986906001600160a01b0316338361257c565b336001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364826040516109bf9190613e96565b60405180910390a2505b5050565b6109c98282612618565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b60075481565b60086020526000908152604090205460ff1681565b6009546040517fd505accf0000000000000000000000000000000000000000000000000000000081526001600160a01b039091169063d505accf90610a7090339030908a908a908a908a908a90600401613d0e565b600060405180830381600087803b158015610a8a57600080fd5b505af1158015610a9e573d6000803e3d6000fd5b50505050610aac3386612618565b5050505050565b610abb6127ca565b6001600160a01b0316610acc61113e565b6001600160a01b031614610af25760405162461bcd60e51b81526004016107d790614360565b6001600160a01b03811660009081526008602052604090205460ff1615610b2b5760405162461bcd60e51b81526004016107d790614238565b6001600160a01b0381166000908152600860205260409020805460ff19166001908117909155600754610b5d91611cb5565b6007556040516001600160a01b038216907fc0a1035c16faf8d1304056d92c00edf028f87e62b8235a938f00af9e3c0312c590600090a250565b610b9f6127ca565b6001600160a01b0316610bb061113e565b6001600160a01b031614610bd65760405162461bcd60e51b81526004016107d790614360565b600e5460ff1615158115151415610bec57600080fd5b600e805460ff19168215151790556040517f7b014ed3854e7f5cb0218d58b3c6ae7d53a68bb0af2f67bfb029ea42c38a7e8590610c2a908390613e8b565b60405180910390a150565b610c3d6127ca565b6001600160a01b0316610c4e61113e565b6001600160a01b031614610c745760405162461bcd60e51b81526004016107d790614360565b60008111610c8157600080fd5b604051339082156108fc029083906000818181858888f19350505050158015610cae573d6000803e3d6000fd5b507f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa28600082604051610c2a929190613d4f565b60115481565b6001600160a01b0381166000908152600460205260409020545b919050565b610d0e6127ca565b6001600160a01b0316610d1f61113e565b6001600160a01b031614610d455760405162461bcd60e51b81526004016107d790614360565b6006546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a36006805473ffffffffffffffffffffffffffffffffffffffff19169055565b600d5481565b610daa6127ca565b6001600160a01b0316610dbb61113e565b6001600160a01b031614610de15760405162461bcd60e51b81526004016107d790614360565b60405163095ea7b360e01b81526001600160a01b0383169063095ea7b390610e10908490600090600401613d4f565b602060405180830381600087803b158015610e2a57600080fd5b505af1158015610e3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6291906139f9565b6109c957600080fd5b6000806000610e78611db3565b509092509050610e888282611f26565b9250505090565b60056020526000908152604090205481565b610ea96127ca565b6001600160a01b0316610eba61113e565b6001600160a01b031614610ee05760405162461bcd60e51b81526004016107d790614360565b7f481f79ac3a523b6d6db3c5a720e190e986d1cc1b41adcdf50f9caef849901100600c5482604051610f139291906145bd565b60405180910390a1600c55565b610f286127ca565b6001600160a01b0316610f3961113e565b6001600160a01b031614610f5f5760405162461bcd60e51b81526004016107d790614360565b60008111610f6c57600080fd5b60405163a9059cbb60e01b81526001600160a01b0383169063a9059cbb90610f9a9033908590600401613d4f565b602060405180830381600087803b158015610fb457600080fd5b505af1158015610fc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fec91906139f9565b610ff557600080fd5b7f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa288282604051611026929190613d4f565b60405180910390a15050565b600f5481565b6110406127ca565b6001600160a01b031661105161113e565b6001600160a01b0316146110775760405162461bcd60e51b81526004016107d790614360565b6000600754116110995760405162461bcd60e51b81526004016107d790614149565b6001600160a01b03811660009081526008602052604090205460ff1615156001146110d65760405162461bcd60e51b81526004016107d7906142a6565b6001600160a01b0381166000908152600860205260409020805460ff19169055600754611104906001611f26565b6007556040516001600160a01b038216907f0e86f6608b536e5339a25b65ff531f5ea91e1313d056ecd4752b35cbd16137d490600090a250565b6006546001600160a01b031690565b600b546001600160a01b031633146111775760405162461bcd60e51b81526004016107d790614429565b600b546040517fa8e91499ed37682f43cffb045fcc7d379a91e8c9a14e6321877ee34dee564c00916111b6916001600160a01b03909116908490613d68565b60405180910390a1600b805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b60018054604080516020600284861615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561074e5780601f106107235761010080835404028352916020019161074e565b61124f6127ca565b6001600160a01b031661126061113e565b6001600160a01b0316146112865760405162461bcd60e51b81526004016107d790614360565b6127106112aa600f546112a460105485611cb590919063ffffffff16565b90611cb5565b11156112b557600080fd5b7f2a42303d002f0ba6cfe8259c91d4684443fb0b3de286ba74991175d651726131601154826040516112e89291906145bd565b60405180910390a1601155565b7fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc681565b6113216127ca565b6001600160a01b031661133261113e565b6001600160a01b0316146113585760405162461bcd60e51b81526004016107d790614360565b6127106113766011546112a460105485611cb590919063ffffffff16565b111561138157600080fd5b7fe7f97d51d307dc44045597c9978bec0f842e6bb40d19b9444084cfa30d9ed4f2600f54826040516113b49291906145bd565b60405180910390a1600f55565b60006107693384846122fa565b6113d66127ca565b6001600160a01b03166113e761113e565b6001600160a01b03161461140d5760405162461bcd60e51b81526004016107d790614360565b6009546040516370a0823160e01b81526000916001600160a01b0316906370a082319061143e903090600401613cd6565b60206040518083038186803b15801561145657600080fd5b505afa15801561146a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148e9190613b32565b905060008061149b611db3565b5090925090506114ae6108278383611f26565b601454600954604051631a4ca37b60e21b81526001600160a01b03928316926369328dec926114e892911690600019903090600401613ddc565b602060405180830381600087803b15801561150257600080fd5b505af1158015611516573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061153a9190613b32565b506009546040516370a0823160e01b81526000916001600160a01b0316906370a082319061156c903090600401613cd6565b60206040518083038186803b15801561158457600080fd5b505afa158015611598573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115bc9190613b32565b9050856115c98286611f26565b10156115e75760405162461bcd60e51b81526004016107d790613f30565b7fc7606d21ac05cd309191543e409f0845c016120563783d70e4f41419dc0ef234611610610e6b565b6002546040516116219291906145bd565b60405180910390a1600e5460ff161515600114801561164257506001851515145b15610834576108346000610b97565b600e5460ff1681565b6116643382612618565b50565b6000806116726116b4565b9050600c5481106116a65761169e612710611698600f54846127ce90919063ffffffff16565b90612808565b915050610780565b600091505090565b600c5481565b6000806116bf61284a565b935050505090565b6009546001600160a01b031681565b6116de6127ca565b6001600160a01b03166116ef61113e565b6001600160a01b0316146117155760405162461bcd60e51b81526004016107d790614360565b612710611733600f546112a460115485611cb590919063ffffffff16565b111561173e57600080fd5b7f3cc372f330f95ac9540626dc8a25f5bf21ba607215a5d58304cb804d446f104a601054826040516117719291906145bd565b60405180910390a1601055565b4284101561179e5760405162461bcd60e51b81526004016107d79061426f565b6001600160a01b038716600090815260056020908152604080832080546001810190915590516117f9927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928c928c928c92918c9101613e9f565b60405160208183030381529060405280519060200120905061181e8882868686612def565b611829888888611ce1565b5050505050505050565b600b546001600160a01b031681565b600080600061184f611db3565b509092509050610e886118628383611f26565b61169884670de0b6b3a76400006127ce565b61187c6127ca565b6001600160a01b031661188d61113e565b6001600160a01b0316146118b35760405162461bcd60e51b81526004016107d790614360565b60095460145460405163095ea7b360e01b81526001600160a01b039283169263095ea7b3926118eb9291169060001990600401613d4f565b602060405180830381600087803b15801561190557600080fd5b505af1158015611919573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061193d91906139f9565b5060195460145460405163095ea7b360e01b81526001600160a01b039283169263095ea7b3926119769291169060001990600401613d4f565b602060405180830381600087803b15801561199057600080fd5b505af11580156119a4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061166491906139f9565b6001600160a01b03918216600090815260036020908152604080832093909416825291909152205490565b6000611a09611a00610e6b565b600254906127ce565b611a14575080610d01565b61076d611a1f610e6b565b6002546116989085906127ce565b611a356127ca565b6001600160a01b0316611a4661113e565b6001600160a01b031614611a6c5760405162461bcd60e51b81526004016107d790614360565b7fa5dae50539d56dfe1fb5273d883b0c39bc76750a25d036fc5fbd09ad8fd5f57f600d5482604051611a9f9291906145bd565b60405180910390a1600d55565b6000611ab9611a00610e6b565b611ac557506000610d01565b61076d600254611698611ad6610e6b565b85906127ce565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60001b6000604051611b129190613c30565b6040519081900390207fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6611b44612ec5565b30604051602001611b59959493929190613ed3565b60405160208183030381529060405280519060200120905090565b611b7c6127ca565b6001600160a01b0316611b8d61113e565b6001600160a01b031614611bb35760405162461bcd60e51b81526004016107d790614360565b6001600160a01b038116611bd95760405162461bcd60e51b81526004016107d790614021565b6006546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36006805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b600a546001600160a01b031681565b323314611c705760405162461bcd60e51b81526004016107d79061407e565b6000806000611c7d61284a565b925092509250600c54811015611ca55760405162461bcd60e51b81526004016107d790613f8d565b611cb0838383612ec9565b505050565b600082820183811015611cda5760405162461bcd60e51b81526004016107d7906140b5565b9392505050565b6001600160a01b038316611d075760405162461bcd60e51b81526004016107d790614395565b6001600160a01b038216611d2d5760405162461bcd60e51b81526004016107d790614551565b6001600160a01b0380841660008181526003602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590611d88908590613e96565b60405180910390a3505050565b80516015556040810151601755602081015160165560600151601855565b6019546040516370a0823160e01b8152600091829182916001600160a01b0316906370a0823190611de8903090600401613cd6565b60206040518083038186803b158015611e0057600080fd5b505afa158015611e14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e389190613b32565b601a546040516370a0823160e01b81529194506001600160a01b0316906370a0823190611e69903090600401613cd6565b60206040518083038186803b158015611e8157600080fd5b505afa158015611e95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eb99190613b32565b91506000905081611ee7601554611698611ee0601754601554611f2690919063ffffffff16565b87906127ce565b1115611f2157611f1e82611f18601554611698611f11601754601554611f2690919063ffffffff16565b88906127ce565b90611f26565b90505b909192565b6000611cda83836040518060400160405280601f81526020017f536166654d6174683a207375627472616374696f6e20756e646572666c6f77008152506122ce565b6000806000611f75611db3565b919450925090506000611fc3611f8f86611f188787611f26565b611f18601754611698611faf601654601554611f2690919063ffffffff16565b611fbd8b611f188c8c611f26565b906127ce565b90506000611fd18483611f26565b90505b8015610834578284811115611fe65750835b601454600954604051631a4ca37b60e21b81526001600160a01b03928316926369328dec9261201e9291169085903090600401613ddc565b602060405180830381600087803b15801561203857600080fd5b505af115801561204c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120709190613b32565b506014546009546040517f573ade810000000000000000000000000000000000000000000000000000000081526001600160a01b039283169263573ade81926120c59291169085906002903090600401613e2c565b602060405180830381600087803b1580156120df57600080fd5b505af11580156120f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121179190613b32565b50612120611db3565b919750955093508483106121345750610834565b61213e8584611f26565b915050611fd4565b6000806000612153611db3565b925092509250600061218560175461169861217b601654601554611f2690919063ffffffff16565b611fbd8888611f26565b90505b808410156122c8578061219b8584611cb5565b11156121ae576121ab8185611f26565b91505b6018548210156121bd576122c8565b6014546009546040517fa415bcad0000000000000000000000000000000000000000000000000000000081526001600160a01b039283169263a415bcad926122149291169086906002906000903090600401613e57565b600060405180830381600087803b15801561222e57600080fd5b505af1158015612242573d6000803e3d6000fd5b505060145460095460405163e8eda9df60e01b81526001600160a01b03928316945063e8eda9df9350612282929091169086903090600090600401613dff565b600060405180830381600087803b15801561229c57600080fd5b505af11580156122b0573d6000803e3d6000fd5b505050506122bc611db3565b91955093509150612188565b50505050565b600081848411156122f25760405162461bcd60e51b81526004016107d79190613f1d565b505050900390565b6001600160a01b0382166123205760405162461bcd60e51b81526004016107d7906143cc565b61235d816040518060600160405280602e81526020016146b2602e91396001600160a01b03861660009081526004602052604090205491906122ce565b6001600160a01b03808516600090815260046020526040808220939093559084168152205461238c9082611cb5565b6001600160a01b0380841660008181526004602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611d88908590613e96565b61241b8160405180606001604052806027815260200161468b602791396001600160a01b03851660009081526004602052604090205491906122ce565b60046000846001600160a01b03166001600160a01b031681526020019081526020016000208190555061246b816040518060600160405280602781526020016146356027913960025491906122ce565b6002556040516000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906124ac908590613e96565b60405180910390a35050565b60006124c382611f68565b60006124cd611db3565b505090508083116124de57826124e2565b6000195b601454600954604051631a4ca37b60e21b81529295506000926001600160a01b03928316926369328dec926125209291169088903090600401613ddc565b602060405180830381600087803b15801561253a57600080fd5b505af115801561254e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125729190613b32565b9050611cda612146565b60405163a9059cbb60e01b81526001600160a01b0384169063a9059cbb906125aa9085908590600401613d4f565b602060405180830381600087803b1580156125c457600080fd5b505af11580156125d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125fc91906139f9565b611cb05760405162461bcd60e51b81526004016107d7906144f4565b60075415612654573360009081526008602052604090205460ff1615156001146126545760405162461bcd60e51b81526004016107d7906140ec565b600e5460ff16151560011461267b5760405162461bcd60e51b81526004016107d790614460565b600d54156126af57600080600061269061284a565b925092509250600d548111156126ab576126ab838383612ec9565b5050505b6009546040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b03909116906323b872dd906126fc90339030908690600401613cea565b602060405180830381600087803b15801561271657600080fd5b505af115801561272a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061274e91906139f9565b61276a5760405162461bcd60e51b81526004016107d790614203565b61277c82612777836119f3565b61318a565b6127858161320c565b816001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c826040516127be9190613e96565b60405180910390a25050565b3390565b6000826127dd5750600061076d565b828202828482816127ea57fe5b0414611cda5760405162461bcd60e51b81526004016107d790614303565b6000611cda83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506132a1565b6013546040517fbfccff450000000000000000000000000000000000000000000000000000000081526000918291829182916001600160a01b039091169063bfccff459061289c903090600401613cd6565b60206040518083038186803b1580156128b457600080fd5b505afa1580156128c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128ec9190613b32565b604080516002808252606080830184529394509091602083019080368337505060195482519293506001600160a01b03169183915060009061292a57fe5b6001600160a01b039283166020918202929092010152601a5482519116908290600190811061295557fe5b60200260200101906001600160a01b031690816001600160a01b03168152505061297d613830565b60135482516001600160a01b0390911690639a7b5f1190849060009061299f57fe5b60200260200101516040518263ffffffff1660e01b81526004016129c39190613cd6565b60a06040518083038186803b1580156129db57600080fd5b505afa1580156129ef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a139190613a15565b9050612a1e816132d8565b9050612a28613868565b60135483516001600160a01b0390911690630f208beb908590600090612a4a57fe5b6020026020010151306040518363ffffffff1660e01b8152600401612a70929190613d68565b604080518083038186803b158015612a8757600080fd5b505afa158015612a9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612abf9190613a84565b90506000612ae764e8d4a51000611698856060015185600001516127ce90919063ffffffff16565b9050612b0a612b03836020015183611f2690919063ffffffff16565b8690611cb5565b60135485519196506001600160a01b031690639a7b5f119086906001908110612b2f57fe5b60200260200101516040518263ffffffff1660e01b8152600401612b539190613cd6565b60a06040518083038186803b158015612b6b57600080fd5b505afa158015612b7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ba39190613a15565b9250612bae836132d8565b60135485519194506001600160a01b031690630f208beb9086906001908110612bd357fe5b6020026020010151306040518363ffffffff1660e01b8152600401612bf9929190613d68565b604080518083038186803b158015612c1057600080fd5b505afa158015612c24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c489190613a84565b9150612c6e64e8d4a51000611698856060015185600001516127ce90919063ffffffff16565b9050612c8a612b03836020015183611f2690919063ffffffff16565b9450612c97856002612808565b601b546040516370a0823160e01b8152919650612d1e916001600160a01b03909116906370a0823190612cce903090600401613cd6565b60206040518083038186803b158015612ce657600080fd5b505afa158015612cfa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b039190613b32565b601b54600a54601c54929750600092612d499289926001600160a01b0391821692908216911661347b565b600a546040516370a0823160e01b81529192506000916001600160a01b03909116906370a0823190612d7f903090600401613cd6565b60206040518083038186803b158015612d9757600080fd5b505afa158015612dab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dcf9190613b32565b90506000612ddd8383611cb5565b979b919a509698509650505050505050565b6000612df9611add565b85604051602001612e0b929190613ca0565b604051602081830303815290604052805190602001209050600060018286868660405160008152602001604052604051612e489493929190613eff565b6020604051602081039080840390855afa158015612e6a573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590612ea05750866001600160a01b0316816001600160a01b0316145b612ebc5760405162461bcd60e51b81526004016107d7906141a6565b50505050505050565b4690565b6040805160028082526060808301845292602083019080368337505060195482519293506001600160a01b031691839150600090612f0357fe5b6001600160a01b039283166020918202929092010152601a54825191169082906001908110612f2e57fe5b6001600160a01b0392831660209182029290920101526013546040517f8e2eba09000000000000000000000000000000000000000000000000000000008152911690638e2eba0990612f869030908590600401613d82565b600060405180830381600087803b158015612fa057600080fd5b505af1158015612fb4573d6000803e3d6000fd5b50506012546040517fe6c91a150000000000000000000000000000000000000000000000000000000081526001600160a01b03909116925063e6c91a15915061300290600190600401613e8b565b600060405180830381600087803b15801561301c57600080fd5b505af1158015613030573d6000803e3d6000fd5b5050505061303d84613556565b50600061305b612710611698601154866127ce90919063ffffffff16565b9050801561308057600a54600b54613080916001600160a01b0390811691168361257c565b600061309d612710611698601054876127ce90919063ffffffff16565b905080156130c357600a546130c3906001600160a01b03166130bd61113e565b8361257c565b60006130e0612710611698600f54886127ce90919063ffffffff16565b905080156130ff57600a546130ff906001600160a01b0316338361257c565b600061313361311483611f1886818b8a611f26565b600a54600954601d546001600160a01b0392831692918216911661357a565b905061313e8161320c565b7fc7606d21ac05cd309191543e409f0845c016120563783d70e4f41419dc0ef234613167610e6b565b6002546040516131789291906145bd565b60405180910390a15050505050505050565b6002546131979082611cb5565b6002556001600160a01b0382166000908152600460205260409020546131bd9082611cb5565b6001600160a01b0383166000818152600460205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906124ac908590613e96565b6000811161322c5760405162461bcd60e51b81526004016107d790614497565b60145460095460405163e8eda9df60e01b81526001600160a01b039283169263e8eda9df926132679291169085903090600090600401613dff565b600060405180830381600087803b15801561328157600080fd5b505af1158015613295573d6000803e3d6000fd5b50505050611664612146565b600081836132c25760405162461bcd60e51b81526004016107d79190613f1d565b5060008385816132ce57fe5b0495945050505050565b6132e0613830565b816040015142116132f2575080610d01565b81518061330757505042604082015280610d01565b6000613320846040015142611f2690919063ffffffff16565b9050600061344a601360009054906101000a90046001600160a01b03166001600160a01b03166317caf6f16040518163ffffffff1660e01b815260040160206040518083038186803b15801561337557600080fd5b505afa158015613389573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133ad9190613b32565b602080880151601354604080517feacdaabc000000000000000000000000000000000000000000000000000000008152905161169894611fbd936001600160a01b03169263eacdaabc9260048083019392829003018186803b15801561341257600080fd5b505afa158015613426573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee09190613b32565b905061346d613462846116988464e8d4a510006127ce565b606087015190611cb5565b606086015250929392505050565b600080613488858561371b565b509050600080846001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156134c757600080fd5b505afa1580156134db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134ff9190613acc565b5091509150866001600160a01b0316836001600160a01b03161461351f57905b61354a88836dffffffffffffffffffffffffffff16836dffffffffffffffffffffffffffff1661374c565b98975050505050505050565b601b54600a54601c5460009261076d9285926001600160a01b039283169291821691165b600080613587858561371b565b509050600080846001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156135c657600080fd5b505afa1580156135da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135fe9190613acc565b5091509150866001600160a01b0316836001600160a01b03161461361e57905b60008061364c8a856dffffffffffffffffffffffffffff16856dffffffffffffffffffffffffffff1661374c565b9050886001600160a01b0316856001600160a01b03161461366957905b61367489888c613794565b604080516000815260208101918290527f022c0d9f000000000000000000000000000000000000000000000000000000009091526001600160a01b0388169063022c0d9f906136cc90859085903090602481016145cb565b600060405180830381600087803b1580156136e657600080fd5b505af11580156136fa573d6000803e3d6000fd5b5050505081811161370b578161370d565b805b9a9950505050505050505050565b600080826001600160a01b0316846001600160a01b03161061373e578284613741565b83835b915091509250929050565b60008061375b856103e56127ce565b9050600061376982856127ce565b9050600061377d836112a4886103e86127ce565b90506137898282612808565b979650505050505050565b60405163a9059cbb60e01b81526001600160a01b0384169063a9059cbb906137c29085908590600401613d4f565b602060405180830381600087803b1580156137dc57600080fd5b505af11580156137f0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061381491906139f9565b611cb05760405162461bcd60e51b81526004016107d790614588565b6040518060a001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b031681525090565b604051806040016040528060008152602001600081525090565b80516dffffffffffffffffffffffffffff81168114610d0157600080fd5b803560ff81168114610d0157600080fd5b6000602082840312156138c2578081fd5b8135611cda81614611565b600080604083850312156138df578081fd5b82356138ea81614611565b915060208301356138fa81614611565b809150509250929050565b600080600060608486031215613919578081fd5b833561392481614611565b9250602084013561393481614611565b929592945050506040919091013590565b600080600080600080600060e0888a03121561395f578283fd5b873561396a81614611565b9650602088013561397a81614611565b95506040880135945060608801359350613996608089016138a0565b925060a0880135915060c0880135905092959891949750929550565b600080604083850312156139c4578182fd5b82356139cf81614611565b946020939093013593505050565b6000602082840312156139ee578081fd5b8135611cda81614626565b600060208284031215613a0a578081fd5b8151611cda81614626565b600060a08284031215613a26578081fd5b60405160a0810181811067ffffffffffffffff82111715613a4357fe5b8060405250825181526020830151602082015260408301516040820152606083015160608201526080830151613a7881614611565b60808201529392505050565b600060408284031215613a95578081fd5b6040516040810181811067ffffffffffffffff82111715613ab257fe5b604052825181526020928301519281019290925250919050565b600080600060608486031215613ae0578283fd5b613ae984613882565b9250613af760208501613882565b9150604084015163ffffffff81168114613b0f578182fd5b809150509250925092565b600060208284031215613b2b578081fd5b5035919050565b600060208284031215613b43578081fd5b5051919050565b60008060408385031215613b5c578182fd5b8235915060208301356138fa81614626565b60008060008060808587031215613b83578182fd5b5050823594602084013594506040840135936060013592509050565b600080600080600060a08688031215613bb6578283fd5b8535945060208601359350613bcd604087016138a0565b94979396509394606081013594506080013592915050565b60008151808452815b81811015613c0a57602081850181015186830182015201613bee565b81811115613c1b5782602083870101525b50601f01601f19169290920160200192915050565b6000808354600180821660008114613c4f5760018114613c6657613c95565b60ff198316865260028304607f1686019350613c95565b600283048786526020808720875b83811015613c8d5781548a820152908501908201613c74565b505050860193505b509195945050505050565b7f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0397881681529590961660208601526040850193909352606084019190915260ff16608083015260a082015260c081019190915260e00190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0392831681529116602082015260400190565b6000604082016001600160a01b03808616845260206040818601528286518085526060870191508288019450855b81811015613dce578551851683529483019491830191600101613db0565b509098975050505050505050565b6001600160a01b0393841681526020810192909252909116604082015260600190565b6001600160a01b03948516815260208101939093529216604082015261ffff909116606082015260800190565b6001600160a01b03948516815260208101939093526040830191909152909116606082015260800190565b6001600160a01b0395861681526020810194909452604084019290925261ffff166060830152909116608082015260a00190565b901515815260200190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b9485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b93845260ff9290921660208401526040830152606082015260800190565b600060208252611cda6020830184613be5565b60208082526024908201527f426c697a7a537472617465677956313a3a7265736375654465706c6f7965644660408201527f756e647300000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526019908201527f426c697a7a537472617465677956313a3a7265696e7665737400000000000000604082015260600190565b60208082526027908201527f426c697a7a537472617465677956313a3a62656c6f77206d696e696d756d207760408201527f6974686472617700000000000000000000000000000000000000000000000000606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201527f6464726573730000000000000000000000000000000000000000000000000000606082015260800190565b60208082526014908201527f59616b53747261746567793a3a6f6e6c79454f41000000000000000000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252602e908201527f5065726d697373696f6e65643a3a6f6e6c79416c6c6f7765644465706f73697460408201527f732c206e6f7420616c6c6f776564000000000000000000000000000000000000606082015260800190565b60208082526034908201527f5065726d697373696f6e65643a3a72656d6f76654465706f7369746f722c206e60408201527f6f20616c6c6f776564206465706f7369746f7273000000000000000000000000606082015260800190565b60208082526024908201527f417263683a3a76616c69646174655369673a20696e76616c6964207369676e6160408201527f7475726500000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252818101527f426c697a7a537472617465677956313a3a7472616e73666572206661696c6564604082015260600190565b6020808252601c908201527f5065726d697373696f6e65643a3a616c6c6f774465706f7369746f7200000000604082015260600190565b6020808252600f908201527f7065726d69743a3a657870697265640000000000000000000000000000000000604082015260600190565b6020808252602a908201527f5065726d697373696f6e65643a3a72656d6f76654465706f7369746f722c206e60408201527f6f7420616c6c6f77656400000000000000000000000000000000000000000000606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60408201527f7700000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601c908201527f5f617070726f76653a3a6f776e6572207a65726f206164647265737300000000604082015260600190565b60208082526034908201527f5f7472616e73666572546f6b656e733a2063616e6e6f74207472616e7366657260408201527f20746f20746865207a65726f2061646472657373000000000000000000000000606082015260800190565b60208082526014908201527f59616b53747261746567793a3a6f6e6c79446576000000000000000000000000604082015260600190565b60208082526019908201527f426c697a7a537472617465677956313a3a5f6465706f73697400000000000000604082015260600190565b60208082526024908201527f426c697a7a537472617465677956313a3a5f7374616b654465706f736974546f60408201527f6b656e7300000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526025908201527f426c697a7a537472617465677956313a3a5452414e534645525f46524f4d5f4660408201527f41494c4544000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601e908201527f5f617070726f76653a3a7370656e646572207a65726f20616464726573730000604082015260600190565b6020808252818101527f4465784c6962726172793a3a5452414e534645525f46524f4d5f4641494c4544604082015260600190565b918252602082015260400190565b60008582528460208301526001600160a01b0384166040830152608060608301526145f96080830184613be5565b9695505050505050565b60ff91909116815260200190565b6001600160a01b038116811461166457600080fd5b801515811461166457600080fdfe5f6275726e3a206275726e20616d6f756e74206578636565647320746f74616c20737570706c797472616e7366657246726f6d3a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63655f6275726e3a206275726e20616d6f756e7420657863656564732066726f6d2062616c616e63655f7472616e73666572546f6b656e733a207472616e7366657220657863656564732066726f6d2062616c616e6365a26469706673582212203226d542ba74a299cc3c034bc5624706520b001848f61ab1141b846b914bd2c264736f6c63430007030033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000000000000000000000000000000000000000000260000000000000000000000000a867c1aca4b5f1e0a66cf7b1fe33525d576088540000000000000000000000002d867ae30400fffad9bed8472c514c2d6b827f5f00000000000000000000000070bbe4a294878a14cb3cdd9315f5eb490e3461630000000000000000000000008d36c5c6947adccd25ef49ea1aac2ceacfff0bd700000000000000000000000050b7545627a5162f82a992c33b87adc75187b2180000000000000000000000000f34919404a290e71fc6a510cb4a6acb8d764b2400000000000000000000000081ccdd9e44c518caee2f720c43cd0853032a177900000000000000000000000052b9879984dc9565359bb52117c43665e699397b000000000000000000000000d5a37dc5c9a396a03dd1136fc76a1a02b1c88ffa000000000000000000000000ac3f978714c613e768272c502a8912bc03dcf6240000000000000000000000000000000000000000000000000000000000007cf40000000000000000000000000000000000000000000000000000000000000541000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000005af3107a4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002bc000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000175969656c642059616b3a20426c697a7a20574254432e65000000000000000000

-----Decoded View---------------
Arg [0] : _name (string): Yield Yak: Blizz WBTC.e
Arg [1] : _rewardDistribution (address): 0xA867c1acA4B5F1E0a66cf7b1FE33525D57608854
Arg [2] : _blizzChef (address): 0x2d867AE30400ffFaD9BeD8472c514c2d6b827F5f
Arg [3] : _tokenDelegator (address): 0x70BbE4A294878a14CB3CDD9315f5EB490e346163
Arg [4] : _timelock (address): 0x8d36C5c6947ADCcd25Ef49Ea1aAC2ceACFff0bD7
Arg [5] : _tokens (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
Arg [6] : _swapPairs (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
Arg [7] : _leverageSettings (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
Arg [8] : _strategySettings (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]

-----Encoded View---------------
21 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000260
Arg [1] : 000000000000000000000000a867c1aca4b5f1e0a66cf7b1fe33525d57608854
Arg [2] : 0000000000000000000000002d867ae30400fffad9bed8472c514c2d6b827f5f
Arg [3] : 00000000000000000000000070bbe4a294878a14cb3cdd9315f5eb490e346163
Arg [4] : 0000000000000000000000008d36c5c6947adccd25ef49ea1aac2ceacfff0bd7
Arg [5] : 00000000000000000000000050b7545627a5162f82a992c33b87adc75187b218
Arg [6] : 0000000000000000000000000f34919404a290e71fc6a510cb4a6acb8d764b24
Arg [7] : 00000000000000000000000081ccdd9e44c518caee2f720c43cd0853032a1779
Arg [8] : 00000000000000000000000052b9879984dc9565359bb52117c43665e699397b
Arg [9] : 000000000000000000000000d5a37dc5c9a396a03dd1136fc76a1a02b1c88ffa
Arg [10] : 000000000000000000000000ac3f978714c613e768272c502a8912bc03dcf624
Arg [11] : 0000000000000000000000000000000000000000000000000000000000007cf4
Arg [12] : 0000000000000000000000000000000000000000000000000000000000000541
Arg [13] : 0000000000000000000000000000000000000000000000000000000000002710
Arg [14] : 00000000000000000000000000000000000000000000000000000000000003e8
Arg [15] : 00000000000000000000000000000000000000000000000000005af3107a4000
Arg [16] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [17] : 00000000000000000000000000000000000000000000000000000000000002bc
Arg [18] : 0000000000000000000000000000000000000000000000000000000000000064
Arg [19] : 0000000000000000000000000000000000000000000000000000000000000017
Arg [20] : 5969656c642059616b3a20426c697a7a20574254432e65000000000000000000


Block Transaction Gas Used Reward
view all blocks ##produced##

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.