MATIC Price: $1.03 (-3.13%)
Gas: 83 GWei
 

Overview

MATIC Balance

Polygon PoS Chain LogoPolygon PoS Chain LogoPolygon PoS Chain Logo0 MATIC

MATIC Value

$0.00

Sponsored

Transaction Hash
Method
Block
From
To
Value
0x60806040259577332022-03-15 5:02:03714 days 17 hrs ago1647320523IN
 Create: LendingDataV2
0 MATIC0.1840994534.3

Parent Txn Hash Block From To Value
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
LendingDataV2

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 2 : LendingDataV2.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;

import "../library/Ownable.sol";

library SafeMath {
    function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x + y) >= x, "ds-math-add-overflow");
    }

    function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x - y) <= x, "ds-math-sub-underflow");
    }

    function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require(y == 0 || (z = x * y) / y == x, "ds-math-mul-overflow");
    }

    function div(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require(y > 0, "ds-math-div-overflow");
        z = x / y;
    }
}

library SafeRatioMath {
    using SafeMath for uint256;

    uint256 private constant BASE = 10**18;

    function rmul(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = x.mul(y).div(BASE);
    }

    function rdiv(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = x.mul(BASE).div(y);
    }

    function rpow(
        uint256 x,
        uint256 n,
        uint256 base
    ) internal pure returns (uint256 z) {
        assembly {
            switch x
                case 0 {
                    switch n
                        case 0 {
                            z := base
                        }
                        default {
                            z := 0
                        }
                }
                default {
                    switch mod(n, 2)
                        case 0 {
                            z := base
                        }
                        default {
                            z := x
                        }
                    let half := div(base, 2) // for rounding.

                    for {
                        n := div(n, 2)
                    } n {
                        n := div(n, 2)
                    } {
                        let xx := mul(x, x)
                        if iszero(eq(div(xx, x), x)) {
                            revert(0, 0)
                        }
                        let xxRound := add(xx, half)
                        if lt(xxRound, xx) {
                            revert(0, 0)
                        }
                        x := div(xxRound, base)
                        if mod(n, 2) {
                            let zx := mul(z, x)
                            if and(
                                iszero(iszero(x)),
                                iszero(eq(div(zx, x), z))
                            ) {
                                revert(0, 0)
                            }
                            let zxRound := add(zx, half)
                            if lt(zxRound, zx) {
                                revert(0, 0)
                            }
                            z := div(zxRound, base)
                        }
                    }
                }
        }
    }
}

/**
 * @dev Interface of the ERC20 standard as defined in the EIP. Does not include
 * the optional functions; to access them see {ERC20Detailed}.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external;

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external;

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external;

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );

    // This function is not a standard ERC20 interface, just for compitable with market.
    function decimals() external view returns (uint8);
}

interface IInterestRateModel {
    function blocksPerYear() external view returns (uint256);
}

interface IPriceOracle {
    /**
     * @notice Get the underlying price of a iToken asset
     * @param _iToken The iToken to get the underlying price of
     * @return The underlying asset price mantissa (scaled by 1e18).
     *  Zero means the price is unavailable.
     */
    function getUnderlyingPrice(IiToken _iToken)
        external
        view
        returns (uint256);

    /**
     * @notice Get the price of a underlying asset
     * @param _iToken The iToken to get the underlying price of
     * @return The underlying asset price mantissa (scaled by 1e18).
     *  Zero means the price is unavailable and whether the price is valid.
     */
    function getUnderlyingPriceAndStatus(IiToken _iToken)
        external
        view
        returns (uint256, bool);
    function getAssetPriceStatus(IiToken _iToken) external view returns (bool);
}

interface IRewardDistributor {
    function updateDistributionState(IiToken _iToken, bool _isBorrow) external;

    function updateReward(
        IiToken _iToken,
        address _account,
        bool _isBorrow
    ) external;

    function updateRewardBatch(
        address[] memory _holders,
        IiToken[] memory _iTokens
    ) external;

    function reward(address _account) external view returns (uint256);
}

interface IController {
    function getAlliTokens() external view returns (IiToken[] memory);

    function getEnteredMarkets(address _account)
        external
        view
        returns (IiToken[] memory);
    
    function getBorrowedAssets(address _account) external view returns (IiToken[] memory);

    function hasEnteredMarket(address _account, IiToken _iToken)
        external
        view
        returns (bool);

    function hasBorrowed(address _account, IiToken _iToken)
        external
        view
        returns (bool);

    function priceOracle() external view returns (IPriceOracle);

    function markets(IiToken _asset)
        external
        view
        returns (
            uint256,
            uint256,
            uint256,
            uint256,
            bool,
            bool,
            bool
        );

    function calcAccountEquity(address _account)
        external
        view
        returns (
            uint256,
            uint256,
            uint256,
            uint256
        );

    function beforeRedeem(
        address iToken,
        address redeemer,
        uint256 redeemAmount
    ) external returns (bool);

    function closeFactorMantissa() external view returns (uint256);

    function liquidationIncentiveMantissa() external view returns (uint256);

    function rewardDistributor() external view returns (address);
}

interface IiToken {
    function decimals() external view returns (uint8);

    function balanceOf(address _account) external view returns (uint256);

    function totalSupply() external view returns (uint256);

    function isSupported() external view returns (bool);
    
    function isiToken() external view returns (bool);

    function underlying() external view returns (IERC20);

    function getCash() external view returns (uint256);

    function supplyRatePerBlock() external view returns (uint256);

    function borrowRatePerBlock() external view returns (uint256);

    function balanceOfUnderlying(address _account) external returns (uint256);

    function borrowBalanceStored(address _account)
        external
        view
        returns (uint256);

    function borrowBalanceCurrent(address _account) external returns (uint256);

    function totalBorrowsCurrent() external returns (uint256);

    function totalBorrows() external view returns (uint256);

    function exchangeRateStored() external view returns (uint256);

    function exchangeRateCurrent() external returns (uint256);

    function updateInterest() external returns (bool);

    function interestRateModel() external view returns (IInterestRateModel);
}

contract LendingDataV2 is Ownable {
    using SafeMath for uint256;
    using SafeRatioMath for uint256;
    bool private initialized;

    uint256 constant BASE = 1e18;

    uint256 public blocksPerYear;
    uint256 constant daysPerYear = 365;

    IController public controller;
    IiToken public priceToken;

    IiToken[] public tokens;
    uint256[] public amounts;
    uint8[] public decimals;

    constructor(
        address _controller,
        IiToken _priceToken
    ) public {
        initialize(_controller, _priceToken);
    }

    function initialize(
        address _controller,
        IiToken _priceToken
    ) public {
        require(!initialized, "initialize: Already initialized!");
        __Ownable_init();
        controller = IController(_controller);
        priceToken = _priceToken;
        initialized = true;
    }

    function setController(IController _newController) external onlyOwner {
        // Sets to new controller.
        controller = _newController;
    }

    function setPriceToken(IiToken _newAsset) external onlyOwner {
        priceToken = _newAsset;
    }

    struct totalValueLocalVars {
        IiToken[] iTokens;
        IController controller;
        IPriceOracle priceOracle;
        uint256 assetPrice;
        uint256 collateralFactor;
        uint256 sumCollateral;
        uint256 sumBorrowed;
        uint256 supplyValue;
        uint256 collateralVaule;
        uint256 borrowValue;
    }

    function getAccountTotalValue(address _account)
        external
        returns (
            uint256,
            uint256,
            uint256,
            uint256
        )
    {
        totalValueLocalVars memory _var;
        _var.controller = controller;
        _var.iTokens = _var.controller.getAlliTokens();
        _var.priceOracle = _var.controller.priceOracle();
        for (uint256 i = 0; i < _var.iTokens.length; i++) {
            _var.assetPrice = _var.priceOracle.getUnderlyingPrice(
                _var.iTokens[i]
            );
            _var.supplyValue = _var.supplyValue.add(
                _var.iTokens[i].balanceOfUnderlying(_account).mul(
                    _var.assetPrice
                )
            );
            (_var.collateralFactor, , , , , , ) = controller.markets(_var.iTokens[i]);
            if (
                _var.controller.hasEnteredMarket(_account, _var.iTokens[i]) &&
                _var.collateralFactor > 0
            )
                _var.collateralVaule = _var.collateralVaule.add(
                    _var.iTokens[i].balanceOfUnderlying(_account).mul(
                        _var.assetPrice
                    )
                );

            if (_var.controller.hasBorrowed(_account, _var.iTokens[i]))
                _var.borrowValue = _var.borrowValue.add(
                    _var.iTokens[i].borrowBalanceCurrent(_account).mul(
                        _var.assetPrice
                    )
                );
        }
        _var.assetPrice = getAssetUSDPrice(priceToken);
        if (_var.assetPrice == 0) return (0, 0, 0, 0);

        _var.supplyValue = _var.supplyValue.div(_var.assetPrice);
        _var.collateralVaule = _var.collateralVaule.div(_var.assetPrice);
        _var.borrowValue = _var.borrowValue.div(_var.assetPrice);
        (, , _var.sumCollateral, _var.sumBorrowed) = calcAccountEquity(_account);
        return (
            _var.supplyValue,
            _var.collateralVaule,
            _var.borrowValue,
            _var.sumBorrowed == 0 ? 0 : _var.sumCollateral.rdiv(_var.sumBorrowed)
        );
    }

    function getAccountAssetStatus(IiToken _asset, address _account, uint256 _type) internal returns (bool, uint256) {
        uint256 _balance;
        if (_type == 0) {
            _balance = _asset.balanceOfUnderlying(_account);
            return ( _balance == 0 ? false : true, _balance);
        }

        bool _isiToken = _asset.isiToken();
        if ((_type & 1 > 0 && _isiToken) || (_type & 2 > 0 && !_isiToken))
            _balance = _asset.borrowBalanceCurrent(_account);

        return ( _balance == 0 ? false : true, _balance);
    }

    function getAccountAssets(address _account, uint256 _type)
        internal
        returns (
            IiToken[] memory,
            uint256[] memory,
            uint8[] memory
        )
    {
        delete tokens;
        delete amounts;
        delete decimals;
        uint256 _balance;
        bool _status;
        IiToken[] memory _iTokens = controller.getAlliTokens();
        for (uint256 i = 0; i < _iTokens.length; i++) {
            (_status, _balance) = getAccountAssetStatus(_iTokens[i], _account, _type);
            if (_status) {
                tokens.push(_iTokens[i]);
                amounts.push(_balance);
                decimals.push(_iTokens[i].decimals());
            }
        }

        return (tokens, amounts, decimals);
    }

    
    function getAccountSupplyTokens(address _account)
        public
        returns (
            IiToken[] memory,
            uint256[] memory,
            uint8[] memory
        )
    {
        return getAccountAssets(_account, 0);
    }

    function getAccountBorrowTokens(address _account)
        public
        returns (
            IiToken[] memory,
            uint256[] memory,
            uint8[] memory
        )
    {
        return getAccountAssets(_account, 1);
    }

    function getAccountMSDTokens(address _account)
        public
        returns (
            IiToken[] memory,
            uint256[] memory,
            uint8[] memory
        )
    {
        return getAccountAssets(_account, 2);
    }

    function getAccountTokens(address _account)
        external
        returns (
            IiToken[] memory _supplyTokens,
            uint256[] memory _supplyAmounts,
            uint8[] memory _supplyDecimals,
            IiToken[] memory _borrowTokens,
            uint256[] memory _borrowAmounts,
            uint8[] memory _borrowDecimals
        )
    {
        (
            _supplyTokens,
            _supplyAmounts,
            _supplyDecimals
        ) = getAccountAssets(_account, 0);
        (
            _borrowTokens,
            _borrowAmounts,
            _borrowDecimals
        ) = getAccountAssets(_account, 3);
    }

    function getAssetUSDPrice(IiToken _asset) public view returns (uint256) {
        uint256 _USDPrice = controller.priceOracle().getUnderlyingPrice(
                priceToken
            );
        if (_USDPrice == 0) return 0;

        uint256 _assetUSDPrice = controller.priceOracle()
                .getUnderlyingPrice(_asset)
                .rdiv(_USDPrice);
        uint8 _assetDecimals = _asset.decimals();
        uint8 _priceTokenDecimals = priceToken.decimals();

        return
            _assetDecimals > _priceTokenDecimals
                ? _assetUSDPrice.mul(
                    10**(uint256(_assetDecimals - _priceTokenDecimals))
                )
                : _assetUSDPrice.div(
                    10**(uint256(_priceTokenDecimals - _assetDecimals))
                );
    }

    function getSupplyTokenData(IiToken _asset)
        public
        view
        returns (
            uint256,
            uint256,
            uint256
        )
    {
        (uint256 _collateralFactor, , , , , , ) = controller.markets(_asset);
        if (_asset.isiToken()) {
            uint256 _blocksPerDay = _asset.supplyRatePerBlock() * _asset.interestRateModel().blocksPerYear() / daysPerYear;
            return (
                (_blocksPerDay + BASE).rpow(
                    daysPerYear,
                    BASE
                ) - BASE,
                _collateralFactor,
                getAssetUSDPrice(_asset)
            );
        }
        return (0, _collateralFactor, getAssetUSDPrice(_asset));
    }

    function getAccountSupplyInfo(
        IiToken _asset,
        address _account,
        uint256 _safeMaxFactor
    )
        public
        returns (
            uint256 _assetPrice,
            bool _asCollateral,
            bool _executed,
            bool _accountAvailable
        )
    {
        _asCollateral = controller.hasEnteredMarket(_account, _asset);
        if (!_asCollateral) {
            (uint256 _collateralFactor, , , , , , ) = controller.markets(_asset);
            _executed = _collateralFactor > 0 ? true : false;
            _accountAvailable = true;
        } else {
            _executed = canAccountRemoveFromCollateral(
                _asset,
                _account,
                _safeMaxFactor
            );
            _accountAvailable = getAccountAvailable(_account);
        }
        
        uint256 _USDPrice = controller.priceOracle().getUnderlyingPrice(priceToken);
        _assetPrice = _USDPrice == 0 ? 0 : getBalance(_asset, _account).mul(controller.priceOracle().getUnderlyingPrice(_asset)).div(_USDPrice);
    }

    struct removeFromCollateralLocalVars {
        uint256 assetPrice;
        uint256 collateralFactor;
        uint256 accountEquity;
        uint256 sumCollateral;
        uint256 sumBorrowed;
        uint256 safeAvailableToken;
    }

    function canAccountRemoveFromCollateral(
        IiToken _asset,
        address _account,
        uint256 _safeMaxFactor
    ) public returns (bool) {
        if (getAccountBorrowStatus(_account)) {
            removeFromCollateralLocalVars memory _var;

            (_var.collateralFactor, , , , , , ) = controller.markets(_asset);
            (
                _var.accountEquity,
                ,
                _var.sumCollateral,
                _var.sumBorrowed
            ) = calcAccountEquity(_account);
            if (_var.collateralFactor == 0 && _var.accountEquity > 0)
                return true;

            _var.assetPrice = controller.priceOracle()
                .getUnderlyingPrice(_asset);
            if (
                _var.assetPrice == 0 ||
                _var.collateralFactor == 0 ||
                _var.accountEquity == 0
            ) return false;

            _var.safeAvailableToken = _var.sumCollateral >
                _var.sumBorrowed.rdiv(_safeMaxFactor)
                ? _var.sumCollateral.sub(_var.sumBorrowed.rdiv(_safeMaxFactor))
                : 0;
            _var.safeAvailableToken = _var
                .safeAvailableToken
                .div(_var.assetPrice)
                .rdiv(_var.collateralFactor);

            return
                _var.safeAvailableToken >=
                IiToken(_asset).balanceOfUnderlying(_account);
        }

        return true;
    }

    struct supplyLocalVars {
        uint256 cash;
        uint256 assetPrice;
        uint256 collateralFactor;
        uint256 supplyCapacity;
        uint256 totalUnderlying;
        uint256 accountEquity;
        uint256 sumCollateral;
        uint256 sumBorrowed;
        uint256 availableToken;
        uint256 safeAvailableToken;
        uint256 suppliedBalance;
        uint256 accountBalance;
        uint256 maxMintAmount;
        uint256 availableToWithdraw;
        uint256 safeAvailableToWithdraw;
        uint256 iTokenBalance;
        uint8 decimals;
    }

    function getAccountSupplyData(
        IiToken _asset,
        address _account,
        uint256 _safeMaxFactor
    )
        public
        returns (
            uint256,
            uint256,
            uint256,
            uint256,
            uint256,
            uint256,
            uint8
        )
    {
        supplyLocalVars memory _var;
        _var.suppliedBalance = _asset.balanceOfUnderlying(_account);
        _var.accountBalance = getBalance(_asset, _account);
        _var.iTokenBalance = _asset.balanceOf(_account);
        _var.decimals = _asset.decimals();

        _var.maxMintAmount = 0;
        (_var.collateralFactor, , , _var.supplyCapacity, , ,) = controller.markets(
            _asset
        );
        _var.totalUnderlying = _asset.totalSupply().rmul(
            _asset.exchangeRateStored()
        );
        if (_var.supplyCapacity > _var.totalUnderlying) {
            _var.maxMintAmount = _var.supplyCapacity.sub(_var.totalUnderlying);
            _var.maxMintAmount = _var.maxMintAmount > _var.accountBalance
                ? _var.accountBalance
                : _var.maxMintAmount;
        }

        if (_asset.isiToken()) {
            _var.cash = _asset.getCash();
            _var.availableToWithdraw = _var.cash > _var.suppliedBalance
                ? _var.suppliedBalance
                : _var.cash;
        }
        _var.safeAvailableToWithdraw = _var.availableToWithdraw;

        if (
            controller.hasEnteredMarket(_account, _asset) &&
            getAccountBorrowStatus(_account)
        ) {
            (
                _var.accountEquity,
                ,
                _var.sumCollateral,
                _var.sumBorrowed
            ) = calcAccountEquity(_account);
            if (_var.collateralFactor == 0 && _var.accountEquity > 0)
                return (
                    _var.suppliedBalance,
                    _var.accountBalance,
                    _var.maxMintAmount,
                    _var.availableToWithdraw,
                    _var.safeAvailableToWithdraw,
                    _var.iTokenBalance,
                    _var.decimals
                );

            _var.assetPrice = controller.priceOracle()
                .getUnderlyingPrice(_asset);
            if (
                _var.assetPrice == 0 ||
                _var.collateralFactor == 0 ||
                _var.accountEquity == 0
            )
                return (
                    _var.suppliedBalance,
                    _var.accountBalance,
                    _var.maxMintAmount,
                    0,
                    0,
                    0,
                    _var.decimals
                );

            _var.availableToken = _var.accountEquity.div(_var.assetPrice).rdiv(
                _var.collateralFactor
            );
            _var.availableToWithdraw = _var.availableToWithdraw >
                _var.availableToken
                ? _var.availableToken
                : _var.availableToWithdraw;

            _var.safeAvailableToken = _var.sumCollateral >
                _var.sumBorrowed.rdiv(_safeMaxFactor)
                ? _var.sumCollateral.sub(_var.sumBorrowed.rdiv(_safeMaxFactor))
                : 0;
            _var.safeAvailableToken = _var
                .safeAvailableToken
                .div(_var.assetPrice)
                .rdiv(_var.collateralFactor);
            _var.safeAvailableToWithdraw = _var.safeAvailableToWithdraw >
                _var.safeAvailableToken
                ? _var.safeAvailableToken
                : _var.safeAvailableToWithdraw;

            _var.safeAvailableToWithdraw = _var.safeAvailableToWithdraw >
                _var.availableToWithdraw
                ? _var.availableToWithdraw
                : _var.safeAvailableToWithdraw;
        }

        return (
            _var.suppliedBalance,
            _var.accountBalance,
            _var.maxMintAmount,
            _var.availableToWithdraw,
            _var.safeAvailableToWithdraw,
            _var.iTokenBalance,
            _var.decimals
        );
    }

    function getAccountBorrowValue(address _account) public returns (uint256 _borrowValue) {
        IiToken[] memory _iTokens = controller.getAlliTokens();
        IPriceOracle _priceOracle = controller.priceOracle();
        for (uint256 i = 0; i < _iTokens.length; i++) {
            if (controller.hasBorrowed(_account, _iTokens[i]))
                _borrowValue = _borrowValue.add(
                    _iTokens[i].borrowBalanceCurrent(_account).mul(_priceOracle.getUnderlyingPrice(_iTokens[i]))
                );
        }
        return _borrowValue;
    }

    function getAccountBorrowStatus(address _account)
        public
        view
        returns (bool)
    {
        IiToken[] memory _iTokens = controller.getAlliTokens();
        for (uint256 i = 0; i < _iTokens.length; i++)
            if (_iTokens[i].borrowBalanceStored(_account) > 0)
                return true;

        return false;
    }

    function getBorrowTokenData(IiToken _asset)
        public
        view
        returns (
            uint256,
            uint256,
            uint256,
            uint256
        )
    {
        if (_asset.isSupported()) {
            (, uint256 _borrowFactor, , , , , ) = controller.markets(_asset);
            return (
                _asset.getCash(),
                _borrowFactor,
                (_asset.borrowRatePerBlock() * _asset.interestRateModel().blocksPerYear() / daysPerYear + BASE).rpow(
                    daysPerYear,
                    BASE
                ) - BASE,
                getAssetUSDPrice(_asset)
            );
        }
        return (0, 0, 0, 0);
    }

    struct borrowInfoLocalVars {
        IPriceOracle oracle;
        uint256 assetPrice;
        uint256 USDPrice;
        uint256 accountEquity;
        uint256 sumCollateral;
        uint256 sumBorrowed;
        uint256 borrowFactor;
        uint256 maxBorrowValue;
        uint256 safeBorrowValue;
        bool accountAvailable;
    }

    function getAccountBorrowInfo(
        IiToken _asset,
        address _account,
        uint256 _safeMaxFactor
    )
        public
        returns (
            uint256,
            uint256,
            uint256,
            bool
        )
    {
        borrowInfoLocalVars memory _var;
        _var.oracle = controller.priceOracle();
        _var.USDPrice = _var.oracle.getUnderlyingPrice(priceToken);
        if (_var.oracle.getAssetPriceStatus(_asset))
            _var.accountAvailable = getAccountAvailable(_account);

        if (_var.USDPrice == 0) return (0, 0, 0, _var.accountAvailable);

        IiToken(_asset).updateInterest();
        (
            _var.accountEquity,
            ,
            _var.sumCollateral,
            _var.sumBorrowed
        ) = calcAccountEquity(_account);
        (, _var.borrowFactor, , , , , ) = controller.markets(_asset);

        _var.maxBorrowValue = _var.accountEquity.rmul(_var.borrowFactor).div(
            _var.USDPrice
        );
        _var.safeBorrowValue = _var.sumCollateral.rmul(_safeMaxFactor) >
            _var.sumBorrowed
            ? _var.sumCollateral.rmul(_safeMaxFactor).sub(_var.sumBorrowed)
            : 0;
        _var.safeBorrowValue = _var.safeBorrowValue.rmul(_var.borrowFactor).div(
            _var.USDPrice
        );

        _var.assetPrice = _var.oracle.getUnderlyingPrice(_asset);
        return (
            _var.maxBorrowValue,
            _var.safeBorrowValue,
            getBalance(_asset, _account).mul(_var.assetPrice).div(_var.USDPrice),
            _var.accountAvailable
        );
    }

    struct borrowLocalVars {
        uint256 cash;
        uint256 assetPrice;
        uint256 borrowCapacity;
        uint256 accountEquity;
        uint256 sumCollateral;
        uint256 sumBorrowed;
        uint256 borrowFactor;
        uint256 totalBorrows;
        uint256 canBorrows;
        uint256 borrowedBalance;
        uint256 availableToBorrow;
        uint256 safeAvailableToBorrow;
        uint256 accountBalance;
        uint256 maxRepay;
    }

    function getAccountBorrowData(
        IiToken _asset,
        address _account,
        uint256 _safeMaxFactor
    )
        public
        returns (
            uint256,
            uint256,
            uint256,
            uint256,
            uint256,
            uint8
        )
    {
        borrowLocalVars memory _var;
        _var.borrowedBalance = _asset.borrowBalanceCurrent(_account);
        _var.accountBalance = getBalance(_asset, _account);
        _var.maxRepay = _var.borrowedBalance > _var.accountBalance
            ? _var.accountBalance
            : _var.borrowedBalance;

        _var.assetPrice = controller.priceOracle()
            .getUnderlyingPrice(_asset);
        (, _var.borrowFactor, _var.borrowCapacity, , , , ) = controller.markets(
            _asset
        );
        if (
            _var.assetPrice == 0 ||
            _var.borrowCapacity == 0 ||
            _var.borrowFactor == 0
        )
            return (
                _var.borrowedBalance,
                0,
                0,
                _var.accountBalance,
                _var.maxRepay,
                _asset.decimals()
            );

        (
            _var.accountEquity,
            ,
            _var.sumCollateral,
            _var.sumBorrowed
        ) = calcAccountEquity(_account);
        _var.availableToBorrow = _var.accountEquity.rmul(_var.borrowFactor).div(
            _var.assetPrice
        );

        _var.safeAvailableToBorrow = _var.sumCollateral.rmul(_safeMaxFactor) >
            _var.sumBorrowed
            ? _var.sumCollateral.rmul(_safeMaxFactor).sub(_var.sumBorrowed)
            : 0;
        _var.safeAvailableToBorrow = _var
            .safeAvailableToBorrow
            .rmul(_var.borrowFactor)
            .div(_var.assetPrice);

        if (_asset.isiToken()) {
            _var.cash = _asset.getCash();
            _var.availableToBorrow = _var.availableToBorrow > _var.cash
                ? _var.cash
                : _var.availableToBorrow;

            _var.safeAvailableToBorrow = _var.safeAvailableToBorrow > _var.cash
                ? _var.cash
                : _var.safeAvailableToBorrow;
        }

        _var.totalBorrows = _asset.totalBorrowsCurrent();
        _var.canBorrows = _var.totalBorrows >= _var.borrowCapacity
            ? 0
            : _var.borrowCapacity.sub(_var.totalBorrows);

        _var.availableToBorrow = _var.availableToBorrow > _var.canBorrows
            ? _var.canBorrows
            : _var.availableToBorrow;

        _var.safeAvailableToBorrow = _var.safeAvailableToBorrow >
            _var.canBorrows
            ? _var.canBorrows
            : _var.safeAvailableToBorrow;

        return (
            _var.borrowedBalance,
            _var.canBorrows,
            _var.safeAvailableToBorrow,
            _var.accountBalance,
            _var.maxRepay,
            _asset.decimals()
        );
    }

    struct availableToBorrowLocalVars {
        uint256 borrowFactor;
        uint256 accountEquity;
        uint256 sumCollateral;
        uint256 sumBorrowed;
        uint256 availableToBorrow;
        uint256 safeAvailableToBorrow;
    }

    function getBalance(IiToken _asset, address _account)
        public
        view
        returns (uint256)
    {
        return
            _asset.underlying() == IERC20(0)
                ? _account.balance
                : _asset.underlying().balanceOf(_account);
    }

    struct liquidateLocalVars {
        IPriceOracle oracle;
        uint256 priceBorrowed;
        uint256 priceCollateral;
        uint256 liquidatorBalance;
        uint256 borrowerCollateralBalance;
        uint256 shortfall;
        uint256 exchangeRateCollateral;
        uint256 maxRepay;
        uint256 maxSeizediToken;
        uint256 maxRepayByCollateral;
        bool available;
    }

    function getLiquidationInfo(
        address _borrower,
        address _liquidator,
        IiToken _assetBorrowed,
        IiToken _assetCollateral
    )
        public
        returns (
            uint256,
            uint256,
            uint256,
            bool
        )
    {
        liquidateLocalVars memory _var;

        _var.oracle = controller.priceOracle();
        if (_var.oracle.getAssetPriceStatus(_assetCollateral))
            _var.available = getAccountAvailable(_borrower);

        _var.maxRepay = _assetBorrowed.borrowBalanceCurrent(_borrower)
            .rmul(controller.closeFactorMantissa());
        _var.exchangeRateCollateral = _assetCollateral.exchangeRateCurrent();

        _var.liquidatorBalance = getBalance(_assetBorrowed, _liquidator);
        (, _var.shortfall, , ) = calcAccountEquity(_borrower);
        if (_var.shortfall == 0 || _borrower == _liquidator)
            return (0, 0, _var.liquidatorBalance, _var.available);

        _var.priceBorrowed = _var.oracle.getUnderlyingPrice(_assetBorrowed);
        _var.priceCollateral = _var.oracle.getUnderlyingPrice(_assetCollateral);

        _var.maxSeizediToken = _var
            .maxRepay
            .mul(_var.priceBorrowed)
            .rmul(controller.liquidationIncentiveMantissa())
            .rdiv(_var.exchangeRateCollateral)
            .div(_var.priceCollateral);
        _var.borrowerCollateralBalance = _assetCollateral.balanceOf(
            _borrower
        );
        if (_var.maxSeizediToken < _var.borrowerCollateralBalance)
            return (
                _var.maxRepay,
                _var.maxRepay,
                _var.liquidatorBalance,
                _var.available
            );

        _var.maxRepayByCollateral = _var
            .borrowerCollateralBalance
            .rmul(_var.exchangeRateCollateral)
            .mul(_var.priceCollateral)
            .div(_var.priceBorrowed)
            .rdiv(controller.liquidationIncentiveMantissa());
        return (
            _var.maxRepay,
            _var.maxRepayByCollateral,
            _var.liquidatorBalance,
            _var.available
        );
    }

    function getAccountRewardAmount(address _account) external returns (uint256) {

        IRewardDistributor _rewardDistributor = IRewardDistributor(controller.rewardDistributor());
        address[] memory _accounts = new address[](1);
        _accounts[0] = _account;
        _rewardDistributor.updateRewardBatch(_accounts ,controller.getAlliTokens());
        return _rewardDistributor.reward(_account);
    }

    struct AccountEquityLocalVars {
        IiToken[] collateralITokens;
        IiToken[] borrowedITokens;
        uint256 collateralFactor;
        uint256 borrowFactor;
        uint256 sumCollateral;
        uint256 sumBorrowed;
    }

    function calcAccountEquity(address _account) public view returns (uint256, uint256, uint256, uint256) {
        AccountEquityLocalVars memory _var;
        _var.collateralITokens = controller.getEnteredMarkets(_account);
        for (uint256 i = 0; i < _var.collateralITokens.length; i++) {
            (_var.collateralFactor, , , , , , ) = controller.markets(_var.collateralITokens[i]);
            _var.sumCollateral = _var.sumCollateral.add(
                _var.collateralITokens[i].balanceOf(_account)
                .mul(controller.priceOracle().getUnderlyingPrice(_var.collateralITokens[i]))
                .rmul(_var.collateralITokens[i].exchangeRateStored())
                .rmul(_var.collateralFactor)
            );
        }
        _var.borrowedITokens = controller.getBorrowedAssets(_account);
        for (uint256 i = 0; i < _var.borrowedITokens.length; i++) {
            (, _var.borrowFactor, , , , , ) = controller.markets(_var.borrowedITokens[i]);
            _var.sumBorrowed = _var.sumBorrowed.add(
                _var.borrowedITokens[i].borrowBalanceStored(_account)
                .mul(controller.priceOracle().getUnderlyingPrice(_var.borrowedITokens[i]))
                .rdiv(_var.borrowFactor)
            );
        }
        return
            _var.sumCollateral > _var.sumBorrowed
                ? (
                    _var.sumCollateral - _var.sumBorrowed,
                    uint256(0),
                    _var.sumCollateral,
                    _var.sumBorrowed
                )
                : (
                    uint256(0),
                    _var.sumBorrowed - _var.sumCollateral,
                    _var.sumCollateral,
                    _var.sumBorrowed
                );
    }

    function getAccountAvailable(address _account) public view returns (bool) {
        
        IiToken[] memory _collateralITokens = controller.getEnteredMarkets(_account);
        for (uint256 i = 0; i < _collateralITokens.length; i++) {
            if (!controller.priceOracle().getAssetPriceStatus(_collateralITokens[i]))
                return false;
        }
        IiToken[] memory _borrowedITokens = controller.getBorrowedAssets(_account);
        for (uint256 i = 0; i < _borrowedITokens.length; i++) {
            if (!controller.priceOracle().getAssetPriceStatus(_borrowedITokens[i]))
                return false;
        }
        return true;
    }
}

File 2 of 2 : Ownable.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.6.12;

/**
 * @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 {_setPendingOwner} and {_acceptOwner}.
 */
contract Ownable {
    /**
     * @dev Returns the address of the current owner.
     */
    address payable public owner;

    /**
     * @dev Returns the address of the current pending owner.
     */
    address payable public pendingOwner;

    event NewOwner(address indexed previousOwner, address indexed newOwner);
    event NewPendingOwner(
        address indexed oldPendingOwner,
        address indexed newPendingOwner
    );

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    function __Ownable_init() internal {
        owner = msg.sender;
        emit NewOwner(address(0), msg.sender);
    }

    /**
     * @notice Base on the inputing parameter `newPendingOwner` to check the exact error reason.
     * @dev Transfer contract control to a new owner. The newPendingOwner must call `_acceptOwner` to finish the transfer.
     * @param newPendingOwner New pending owner.
     */
    function _setPendingOwner(address payable newPendingOwner)
        external
        onlyOwner
    {
        require(
            newPendingOwner != address(0) && newPendingOwner != pendingOwner,
            "_setPendingOwner: New owenr can not be zero address and owner has been set!"
        );

        // Gets current owner.
        address oldPendingOwner = pendingOwner;

        // Sets new pending owner.
        pendingOwner = newPendingOwner;

        emit NewPendingOwner(oldPendingOwner, newPendingOwner);
    }

    /**
     * @dev Accepts the admin rights, but only for pendingOwenr.
     */
    function _acceptOwner() external {
        require(
            msg.sender == pendingOwner,
            "_acceptOwner: Only for pending owner!"
        );

        // Gets current values for events.
        address oldOwner = owner;
        address oldPendingOwner = pendingOwner;

        // Set the new contract owner.
        owner = pendingOwner;

        // Clear the pendingOwner.
        pendingOwner = address(0);

        emit NewOwner(oldOwner, owner);
        emit NewPendingOwner(oldPendingOwner, pendingOwner);
    }

    uint256[50] private __gap;
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_controller","type":"address"},{"internalType":"contract IiToken","name":"_priceToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"NewOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldPendingOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newPendingOwner","type":"address"}],"name":"NewPendingOwner","type":"event"},{"inputs":[],"name":"_acceptOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"newPendingOwner","type":"address"}],"name":"_setPendingOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"amounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blocksPerYear","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"calcAccountEquity","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IiToken","name":"_asset","type":"address"},{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_safeMaxFactor","type":"uint256"}],"name":"canAccountRemoveFromCollateral","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"contract IController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getAccountAvailable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IiToken","name":"_asset","type":"address"},{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_safeMaxFactor","type":"uint256"}],"name":"getAccountBorrowData","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IiToken","name":"_asset","type":"address"},{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_safeMaxFactor","type":"uint256"}],"name":"getAccountBorrowInfo","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getAccountBorrowStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getAccountBorrowTokens","outputs":[{"internalType":"contract IiToken[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint8[]","name":"","type":"uint8[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getAccountBorrowValue","outputs":[{"internalType":"uint256","name":"_borrowValue","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getAccountMSDTokens","outputs":[{"internalType":"contract IiToken[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint8[]","name":"","type":"uint8[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getAccountRewardAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IiToken","name":"_asset","type":"address"},{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_safeMaxFactor","type":"uint256"}],"name":"getAccountSupplyData","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IiToken","name":"_asset","type":"address"},{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_safeMaxFactor","type":"uint256"}],"name":"getAccountSupplyInfo","outputs":[{"internalType":"uint256","name":"_assetPrice","type":"uint256"},{"internalType":"bool","name":"_asCollateral","type":"bool"},{"internalType":"bool","name":"_executed","type":"bool"},{"internalType":"bool","name":"_accountAvailable","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getAccountSupplyTokens","outputs":[{"internalType":"contract IiToken[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint8[]","name":"","type":"uint8[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getAccountTokens","outputs":[{"internalType":"contract IiToken[]","name":"_supplyTokens","type":"address[]"},{"internalType":"uint256[]","name":"_supplyAmounts","type":"uint256[]"},{"internalType":"uint8[]","name":"_supplyDecimals","type":"uint8[]"},{"internalType":"contract IiToken[]","name":"_borrowTokens","type":"address[]"},{"internalType":"uint256[]","name":"_borrowAmounts","type":"uint256[]"},{"internalType":"uint8[]","name":"_borrowDecimals","type":"uint8[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getAccountTotalValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IiToken","name":"_asset","type":"address"}],"name":"getAssetUSDPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IiToken","name":"_asset","type":"address"},{"internalType":"address","name":"_account","type":"address"}],"name":"getBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IiToken","name":"_asset","type":"address"}],"name":"getBorrowTokenData","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"address","name":"_liquidator","type":"address"},{"internalType":"contract IiToken","name":"_assetBorrowed","type":"address"},{"internalType":"contract IiToken","name":"_assetCollateral","type":"address"}],"name":"getLiquidationInfo","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IiToken","name":"_asset","type":"address"}],"name":"getSupplyTokenData","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_controller","type":"address"},{"internalType":"contract IiToken","name":"_priceToken","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceToken","outputs":[{"internalType":"contract IiToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IController","name":"_newController","type":"address"}],"name":"setController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IiToken","name":"_newAsset","type":"address"}],"name":"setPriceToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokens","outputs":[{"internalType":"contract IiToken","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b5060405162005fb438038062005fb4833981810160405260408110156200003757600080fd5b5080516020909101516200004c828262000054565b505062000133565b60345460ff1615620000ad576040805162461bcd60e51b815260206004820181905260248201527f696e697469616c697a653a20416c726561647920696e697469616c697a656421604482015290519081900360640190fd5b620000b7620000f2565b603680546001600160a01b039384166001600160a01b031991821617909155603780549290931691161790556034805460ff19166001179055565b600080546001600160a01b0319163390811782556040519091907f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b2364908290a3565b615e7180620001436000396000f3fe608060405234801561001057600080fd5b50600436106101fb5760003560e01c8063779a45021161011a578063a385fb96116100ad578063e00ea6f01161007c578063e00ea6f0146109ba578063e30c3978146109f0578063f565fd7b146109f8578063f77c479114610a69578063fc4d33f914610a71576101fb565b8063a385fb9614610928578063a799599a14610930578063d4fac45d14610956578063debbf76a14610984576101fb565b8063918eadd3116100e9578063918eadd31461089057806392eefe9b146108b65780639fbcc4b8146108dc578063a09cf78b14610902576101fb565b8063779a45021461079e5780637aa5e5d4146107c45780638da5cb5b1461082a5780638eeaaf0014610832576101fb565b80633f47e662116101925780634f64b2be116101615780634f64b2be1461070f578063547792f11461072c5780636e96dfd7146107525780637594795f14610778576101fb565b80633f47e66214610657578063411092e31461068a57806345f0a44f146106b2578063485cc955146106e1576101fb565b80632c9e0a82116101ce5780632c9e0a82146103a85780632ff6fe761461041457806330f487e2146104385780633edb65b61461060b576101fb565b80630a9eeb2a1461020057806317563cc314610304578063243dfec61461033e5780632669264e14610364575b600080fd5b6102266004803603602081101561021657600080fd5b50356001600160a01b0316610a79565b60405180806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b8381101561026e578181015183820152602001610256565b50505050905001848103835286818151815260200191508051906020019060200280838360005b838110156102ad578181015183820152602001610295565b50505050905001848103825285818151815260200191508051906020019060200280838360005b838110156102ec5781810151838201526020016102d4565b50505050905001965050505050505060405180910390f35b61032a6004803603602081101561031a57600080fd5b50356001600160a01b0316610a97565b604080519115158252519081900360200190f35b6102266004803603602081101561035457600080fd5b50356001600160a01b0316610c71565b61038a6004803603602081101561037a57600080fd5b50356001600160a01b0316610c81565b60408051938452602084019290925282820152519081900360600190f35b6103de600480360360608110156103be57600080fd5b506001600160a01b03813581169160208101359091169060400135610f11565b604080519687526020870195909552858501939093526060850191909152608084015260ff1660a0830152519081900360c00190f35b61041c611555565b604080516001600160a01b039092168252519081900360200190f35b61045e6004803603602081101561044e57600080fd5b50356001600160a01b0316611564565b6040518080602001806020018060200180602001806020018060200187810387528d818151815260200191508051906020019060200280838360005b838110156104b257818101518382015260200161049a565b5050505090500187810386528c818151815260200191508051906020019060200280838360005b838110156104f15781810151838201526020016104d9565b5050505090500187810385528b818151815260200191508051906020019060200280838360005b83811015610530578181015183820152602001610518565b5050505090500187810384528a818151815260200191508051906020019060200280838360005b8381101561056f578181015183820152602001610557565b50505050905001878103835289818151815260200191508051906020019060200280838360005b838110156105ae578181015183820152602001610596565b50505050905001878103825288818151815260200191508051906020019060200280838360005b838110156105ed5781810151838201526020016105d5565b505050509050019c5050505050505050505050505060405180910390f35b6106316004803603602081101561062157600080fd5b50356001600160a01b031661159b565b604080519485526020850193909352838301919091526060830152519081900360800190f35b6106746004803603602081101561066d57600080fd5b5035611c2c565b6040805160ff9092168252519081900360200190f35b6106b0600480360360208110156106a057600080fd5b50356001600160a01b0316611c5d565b005b6106cf600480360360208110156106c857600080fd5b5035611cc8565b60408051918252519081900360200190f35b6106b0600480360360408110156106f757600080fd5b506001600160a01b0381358116916020013516611ce6565b61041c6004803603602081101561072557600080fd5b5035611d81565b61032a6004803603602081101561074257600080fd5b50356001600160a01b0316611da8565b6106b06004803603602081101561076857600080fd5b50356001600160a01b0316612243565b6106cf6004803603602081101561078e57600080fd5b50356001600160a01b031661233f565b610226600480360360208110156107b457600080fd5b50356001600160a01b0316612667565b610802600480360360808110156107da57600080fd5b506001600160a01b038135811691602081013582169160408201358116916060013516612677565b6040805194855260208501939093528383019190915215156060830152519081900360800190f35b61041c612c76565b6108686004803603606081101561084857600080fd5b506001600160a01b03813581169160208101359091169060400135612c85565b6040805194855292151560208501529015158383015215156060830152519081900360800190f35b610631600480360360208110156108a657600080fd5b50356001600160a01b0316612fd0565b6106b0600480360360208110156108cc57600080fd5b50356001600160a01b03166132d9565b6106cf600480360360208110156108f257600080fd5b50356001600160a01b0316613344565b6106316004803603602081101561091857600080fd5b50356001600160a01b03166136a4565b6106cf613e30565b6106cf6004803603602081101561094657600080fd5b50356001600160a01b0316613e36565b6106cf6004803603604081101561096c57600080fd5b506001600160a01b038135811691602001351661415b565b61032a6004803603606081101561099a57600080fd5b506001600160a01b038135811691602081013590911690604001356142cf565b610802600480360360608110156109d057600080fd5b506001600160a01b038135811691602081013590911690604001356145b0565b61041c6149ae565b610a2e60048036036060811015610a0e57600080fd5b506001600160a01b038135811691602081013590911690604001356149bd565b604080519788526020880196909652868601949094526060860192909252608085015260a084015260ff1660c0830152519081900360e00190f35b61041c61518f565b6106b061519e565b6060806060610a89846002615281565b9250925092505b9193909250565b60006060603660009054906101000a90046001600160a01b03166001600160a01b03166360a8a9316040518163ffffffff1660e01b815260040160006040518083038186803b158015610ae957600080fd5b505afa158015610afd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015610b2657600080fd5b8101908080516040519392919084600160201b821115610b4557600080fd5b908301906020820185811115610b5a57600080fd5b82518660208202830111600160201b82111715610b7657600080fd5b82525081516020918201928201910280838360005b83811015610ba3578181015183820152602001610b8b565b50505050905001604052505050905060005b8151811015610c65576000828281518110610bcc57fe5b60200260200101516001600160a01b03166395dd9193866040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610c2057600080fd5b505afa158015610c34573d6000803e3d6000fd5b505050506040513d6020811015610c4a57600080fd5b50511115610c5d57600192505050610c6c565b600101610bb5565b5060009150505b919050565b6060806060610a89846000615281565b60365460408051638e8f294b60e01b81526001600160a01b03848116600483015291516000938493849384939190921691638e8f294b9160248083019260e0929190829003018186803b158015610cd757600080fd5b505afa158015610ceb573d6000803e3d6000fd5b505050506040513d60e0811015610d0157600080fd5b50516040805163621fd50760e01b815290519192506001600160a01b0387169163621fd50791600480820192602092909190829003018186803b158015610d4757600080fd5b505afa158015610d5b573d6000803e3d6000fd5b505050506040513d6020811015610d7157600080fd5b505115610ef757600061016d866001600160a01b031663f3fdb15a6040518163ffffffff1660e01b815260040160206040518083038186803b158015610db657600080fd5b505afa158015610dca573d6000803e3d6000fd5b505050506040513d6020811015610de057600080fd5b5051604080516351c2fdcb60e11b815290516001600160a01b039092169163a385fb9691600480820192602092909190829003018186803b158015610e2457600080fd5b505afa158015610e38573d6000803e3d6000fd5b505050506040513d6020811015610e4e57600080fd5b505160408051630ae9d70b60e41b815290516001600160a01b038a169163ae9d70b0916004808301926020929190829003018186803b158015610e9057600080fd5b505afa158015610ea4573d6000803e3d6000fd5b505050506040513d6020811015610eba57600080fd5b50510281610ec457fe5b049050670de0b6b3a7640000610edf81830161016d83615665565b0382610eea88613e36565b9450945094505050610a90565b600081610f0387613e36565b935093509350509193909250565b600080600080600080610f22615ac4565b896001600160a01b03166317bfdfbc8a6040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381600087803b158015610f7157600080fd5b505af1158015610f85573d6000803e3d6000fd5b505050506040513d6020811015610f9b57600080fd5b5051610120820152610fad8a8a61415b565b610180820181905261012082015111610fcb57806101200151610fd2565b8061018001515b6101a082015260365460408051632630c12f60e01b815290516001600160a01b0390921691632630c12f91600480820192602092909190829003018186803b15801561101d57600080fd5b505afa158015611031573d6000803e3d6000fd5b505050506040513d602081101561104757600080fd5b50516040805163fc57d4df60e01b81526001600160a01b038d811660048301529151919092169163fc57d4df916024808301926020929190829003018186803b15801561109357600080fd5b505afa1580156110a7573d6000803e3d6000fd5b505050506040513d60208110156110bd57600080fd5b5051602082015260365460408051638e8f294b60e01b81526001600160a01b038d8116600483015291519190921691638e8f294b9160248083019260e0929190829003018186803b15801561111157600080fd5b505afa158015611125573d6000803e3d6000fd5b505050506040513d60e081101561113b57600080fd5b506020808201516040928301519284019290925260c0830191909152810151158061116857506040810151155b80611175575060c0810151155b1561120a57806101200151600080836101800151846101a001518e6001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156111c857600080fd5b505afa1580156111dc573d6000803e3d6000fd5b505050506040513d60208110156111f257600080fd5b5051949b509299509097509550935091506115499050565b611213896136a4565b60a085015260808401525060608201819052602082015160c08301516112429261123c91615723565b9061573b565b61014082015260a0810151608082015161125c908a615723565b1161126857600061128d565b61128d8160a001516112878a846080015161572390919063ffffffff16565b90615799565b6101608201819052602082015160c08301516112ac9261123c91615723565b81610160018181525050896001600160a01b031663621fd5076040518163ffffffff1660e01b815260040160206040518083038186803b1580156112ef57600080fd5b505afa158015611303573d6000803e3d6000fd5b505050506040513d602081101561131957600080fd5b5051156113c957896001600160a01b0316633b1d21a26040518163ffffffff1660e01b815260040160206040518083038186803b15801561135957600080fd5b505afa15801561136d573d6000803e3d6000fd5b505050506040513d602081101561138357600080fd5b50518082526101408201511161139e578061014001516113a1565b80515b6101408201528051610160820151116113bf578061016001516113c2565b80515b6101608201525b896001600160a01b03166373acee986040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561140457600080fd5b505af1158015611418573d6000803e3d6000fd5b505050506040513d602081101561142e57600080fd5b505160e082018190526040820151111561145a5760e0810151604082015161145591615799565b61145d565b60005b61010082018190526101408201511161147b57806101400151611482565b8061010001515b610140820152610100810151610160820151116114a4578061016001516114ab565b8061010001515b81610160018181525050806101200151816101000151826101600151836101800151846101a001518e6001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561150c57600080fd5b505afa158015611520573d6000803e3d6000fd5b505050506040513d602081101561153657600080fd5b5051949b50929950909750955093509150505b93975093979195509350565b6037546001600160a01b031681565b606080606080606080611578876000615281565b9197509550935061158a876003615281565b979996985094969095909350915050565b6000806000806115a9615b33565b6036546001600160a01b031660208201819052604080516360a8a93160e01b815290516360a8a93191600480820192600092909190829003018186803b1580156115f257600080fd5b505afa158015611606573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561162f57600080fd5b8101908080516040519392919084600160201b82111561164e57600080fd5b90830190602082018581111561166357600080fd5b82518660208202830111600160201b8211171561167f57600080fd5b82525081516020918201928201910280838360005b838110156116ac578181015183820152602001611694565b50505050905001604052505050816000018190525080602001516001600160a01b0316632630c12f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156116fe57600080fd5b505afa158015611712573d6000803e3d6000fd5b505050506040513d602081101561172857600080fd5b50516001600160a01b0316604082015260005b815151811015611b4b5781604001516001600160a01b031663fc57d4df8360000151838151811061176857fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156117ad57600080fd5b505afa1580156117c1573d6000803e3d6000fd5b505050506040513d60208110156117d757600080fd5b5051606083018190528251805161188b92611880929091859081106117f857fe5b60200260200101516001600160a01b0316633af9e6698b6040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381600087803b15801561184e57600080fd5b505af1158015611862573d6000803e3d6000fd5b505050506040513d602081101561187857600080fd5b5051906157e9565b60e08401519061584c565b60e0830152603654825180516001600160a01b0390921691638e8f294b9190849081106118b457fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060e06040518083038186803b1580156118f957600080fd5b505afa15801561190d573d6000803e3d6000fd5b505050506040513d60e081101561192357600080fd5b505160808301526020820151825180516001600160a01b039092169163d4d48473918a918590811061195157fe5b60200260200101516040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b1580156119a657600080fd5b505afa1580156119ba573d6000803e3d6000fd5b505050506040513d60208110156119d057600080fd5b505180156119e2575060008260800151115b15611a1557611a0e611a028360600151846000015184815181106117f857fe5b6101008401519061584c565b6101008301525b81602001516001600160a01b0316638283e3e28884600001518481518110611a3957fe5b60200260200101516040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b158015611a8e57600080fd5b505afa158015611aa2573d6000803e3d6000fd5b505050506040513d6020811015611ab857600080fd5b505115611b4357611b3c611b30836060015184600001518481518110611ada57fe5b60200260200101516001600160a01b03166317bfdfbc8b6040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381600087803b15801561184e57600080fd5b6101208401519061584c565b6101208301525b60010161173b565b50603754611b61906001600160a01b0316613e36565b60608201819052611b8057600080600080945094509450945050611c25565b606081015160e0820151611b939161573b565b60e08201526060810151610100820151611bac9161573b565b6101008201526060810151610120820151611bc69161573b565b610120820152611bd5866136a4565b60c0850181905260a085019190915260e084015161010085015161012086015191945092509015611c185760c084015160a0850151611c139161589b565b611c1b565b60005b9450945094509450505b9193509193565b603a8181548110611c3957fe5b9060005260206000209060209182820401919006915054906101000a900460ff1681565b6000546001600160a01b03163314611ca65760405162461bcd60e51b8152600401808060200182810382526022815260200180615df56022913960400191505060405180910390fd5b603780546001600160a01b0319166001600160a01b0392909216919091179055565b60398181548110611cd557fe5b600091825260209091200154905081565b60345460ff1615611d3e576040805162461bcd60e51b815260206004820181905260248201527f696e697469616c697a653a20416c726561647920696e697469616c697a656421604482015290519081900360640190fd5b611d466158b3565b603680546001600160a01b039384166001600160a01b031991821617909155603780549290931691161790556034805460ff19166001179055565b60388181548110611d8e57fe5b6000918252602090912001546001600160a01b0316905081565b60365460408051638ccb720b60e01b81526001600160a01b03848116600483015291516000936060931691638ccb720b9160248083019287929190829003018186803b158015611df757600080fd5b505afa158015611e0b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611e3457600080fd5b8101908080516040519392919084600160201b821115611e5357600080fd5b908301906020820185811115611e6857600080fd5b82518660208202830111600160201b82111715611e8457600080fd5b82525081516020918201928201910280838360005b83811015611eb1578181015183820152602001611e99565b50505050905001604052505050905060005b8151811015611fee57603660009054906101000a90046001600160a01b03166001600160a01b0316632630c12f6040518163ffffffff1660e01b815260040160206040518083038186803b158015611f1a57600080fd5b505afa158015611f2e573d6000803e3d6000fd5b505050506040513d6020811015611f4457600080fd5b505182516001600160a01b0390911690630a2b53bf90849084908110611f6657fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611fab57600080fd5b505afa158015611fbf573d6000803e3d6000fd5b505050506040513d6020811015611fd557600080fd5b5051611fe657600092505050610c6c565b600101611ec3565b50603654604080516303ad7f9b60e11b81526001600160a01b0386811660048301529151606093929092169163075aff3691602480820192600092909190829003018186803b15801561204057600080fd5b505afa158015612054573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561207d57600080fd5b8101908080516040519392919084600160201b82111561209c57600080fd5b9083019060208201858111156120b157600080fd5b82518660208202830111600160201b821117156120cd57600080fd5b82525081516020918201928201910280838360005b838110156120fa5781810151838201526020016120e2565b50505050905001604052505050905060005b815181101561223857603660009054906101000a90046001600160a01b03166001600160a01b0316632630c12f6040518163ffffffff1660e01b815260040160206040518083038186803b15801561216357600080fd5b505afa158015612177573d6000803e3d6000fd5b505050506040513d602081101561218d57600080fd5b505182516001600160a01b0390911690630a2b53bf908490849081106121af57fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156121f457600080fd5b505afa158015612208573d6000803e3d6000fd5b505050506040513d602081101561221e57600080fd5b50516122305760009350505050610c6c565b60010161210c565b506001949350505050565b6000546001600160a01b0316331461228c5760405162461bcd60e51b8152600401808060200182810382526022815260200180615df56022913960400191505060405180910390fd5b6001600160a01b038116158015906122b257506001546001600160a01b03828116911614155b6122ed5760405162461bcd60e51b815260040180806020018281038252604b815260200180615daa604b913960600191505060405180910390fd5b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fb3d55174552271a4f1aaf36b72f50381e892171636b3fb5447fe00e995e7a37b90600090a35050565b600080603660009054906101000a90046001600160a01b03166001600160a01b031663acc2166a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561239057600080fd5b505afa1580156123a4573d6000803e3d6000fd5b505050506040513d60208110156123ba57600080fd5b5051604080516001808252818301909252919250606091906020808301908036833701905050905083816000815181106123f057fe5b6001600160a01b039283166020918202929092010152603654604080516360a8a93160e01b8152905185841693635f1c86659386939116916360a8a93191600480820192600092909190829003018186803b15801561244e57600080fd5b505afa158015612462573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561248b57600080fd5b8101908080516040519392919084600160201b8211156124aa57600080fd5b9083019060208201858111156124bf57600080fd5b82518660208202830111600160201b821117156124db57600080fd5b82525081516020918201928201910280838360005b838110156125085781810151838201526020016124f0565b505050509050016040525050506040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015612568578181015183820152602001612550565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156125a757818101518382015260200161258f565b50505050905001945050505050600060405180830381600087803b1580156125ce57600080fd5b505af11580156125e2573d6000803e3d6000fd5b50505050816001600160a01b0316636353586b856040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561263357600080fd5b505afa158015612647573d6000803e3d6000fd5b505050506040513d602081101561265d57600080fd5b5051949350505050565b6060806060610a89846001615281565b600080600080612685615b98565b603660009054906101000a90046001600160a01b03166001600160a01b0316632630c12f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156126d357600080fd5b505afa1580156126e7573d6000803e3d6000fd5b505050506040513d60208110156126fd57600080fd5b50516001600160a01b0390811680835260408051630a2b53bf60e01b81529289166004840152519091630a2b53bf916024808301926020929190829003018186803b15801561274b57600080fd5b505afa15801561275f573d6000803e3d6000fd5b505050506040513d602081101561277557600080fd5b50511561278e5761278589611da8565b15156101408201525b6036546040805163743aaa2360e11b8152905161287e926001600160a01b03169163e8755446916004808301926020929190829003018186803b1580156127d457600080fd5b505afa1580156127e8573d6000803e3d6000fd5b505050506040513d60208110156127fe57600080fd5b5051604080516305eff7ef60e21b81526001600160a01b038d811660048301529151918b16916317bfdfbc916024808201926020929091908290030181600087803b15801561284c57600080fd5b505af1158015612860573d6000803e3d6000fd5b505050506040513d602081101561287657600080fd5b505190615723565b8160e0018181525050856001600160a01b031663bd6d894d6040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156128c257600080fd5b505af11580156128d6573d6000803e3d6000fd5b505050506040513d60208110156128ec57600080fd5b505160c08201526128fd878961415b565b606082015261290b896136a4565b505060a08301819052159050806129335750876001600160a01b0316896001600160a01b0316145b15612954576000808260600151836101400151945094509450945050612c6b565b80600001516001600160a01b031663fc57d4df886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156129a557600080fd5b505afa1580156129b9573d6000803e3d6000fd5b505050506040513d60208110156129cf57600080fd5b505160208281019190915281516040805163fc57d4df60e01b81526001600160a01b038a811660048301529151919092169263fc57d4df9260248082019391829003018186803b158015612a2257600080fd5b505afa158015612a36573d6000803e3d6000fd5b505050506040513d6020811015612a4c57600080fd5b5051604080830182905260c08301516036548251634ada90af60e01b81529251612af6949361123c9392612af0926001600160a01b0390911691634ada90af916004808301926020929190829003018186803b158015612aab57600080fd5b505afa158015612abf573d6000803e3d6000fd5b505050506040513d6020811015612ad557600080fd5b5051602087015160e0880151612aea916157e9565b90615723565b9061589b565b610100820152604080516370a0823160e01b81526001600160a01b038b811660048301529151918816916370a0823191602480820192602092909190829003018186803b158015612b4657600080fd5b505afa158015612b5a573d6000803e3d6000fd5b505050506040513d6020811015612b7057600080fd5b5051608082018190526101008201511015612ba65760e08101516060820151610140909201519095508594509092509050612c6b565b60365460408051634ada90af60e01b81529051612c46926001600160a01b031691634ada90af916004808301926020929190829003018186803b158015612bec57600080fd5b505afa158015612c00573d6000803e3d6000fd5b505050506040513d6020811015612c1657600080fd5b50516020830151604084015160c08501516080860151612af0939261123c929091612c4091615723565b906157e9565b610120820181905260e082015160608301516101409093015190965090945090925090505b945094509450949050565b6000546001600160a01b031681565b6036546040805163d4d4847360e01b81526001600160a01b03858116600483015286811660248301529151600093849384938493919092169163d4d48473916044808301926020929190829003018186803b158015612ce357600080fd5b505afa158015612cf7573d6000803e3d6000fd5b505050506040513d6020811015612d0d57600080fd5b5051925082612db05760365460408051638e8f294b60e01b81526001600160a01b038a8116600483015291516000939290921691638e8f294b9160248082019260e092909190829003018186803b158015612d6757600080fd5b505afa158015612d7b573d6000803e3d6000fd5b505050506040513d60e0811015612d9157600080fd5b5051905080612da1576000612da4565b60015b92506001915050612dc9565b612dbb8787876142cf565b9150612dc686611da8565b90505b60365460408051632630c12f60e01b815290516000926001600160a01b031691632630c12f916004808301926020929190829003018186803b158015612e0e57600080fd5b505afa158015612e22573d6000803e3d6000fd5b505050506040513d6020811015612e3857600080fd5b50516037546040805163fc57d4df60e01b81526001600160a01b0392831660048201529051919092169163fc57d4df916024808301926020929190829003018186803b158015612e8757600080fd5b505afa158015612e9b573d6000803e3d6000fd5b505050506040513d6020811015612eb157600080fd5b505190508015612fc157612fbc8161123c603660009054906101000a90046001600160a01b03166001600160a01b0316632630c12f6040518163ffffffff1660e01b815260040160206040518083038186803b158015612f1057600080fd5b505afa158015612f24573d6000803e3d6000fd5b505050506040513d6020811015612f3a57600080fd5b50516040805163fc57d4df60e01b81526001600160a01b038e811660048301529151919092169163fc57d4df916024808301926020929190829003018186803b158015612f8657600080fd5b505afa158015612f9a573d6000803e3d6000fd5b505050506040513d6020811015612fb057600080fd5b5051612c408c8c61415b565b612fc4565b60005b94505093509350935093565b600080600080846001600160a01b031663744279376040518163ffffffff1660e01b815260040160206040518083038186803b15801561300f57600080fd5b505afa158015613023573d6000803e3d6000fd5b505050506040513d602081101561303957600080fd5b5051156132c85760365460408051638e8f294b60e01b81526001600160a01b03888116600483015291516000939290921691638e8f294b9160248082019260e092909190829003018186803b15801561309157600080fd5b505afa1580156130a5573d6000803e3d6000fd5b505050506040513d60e08110156130bb57600080fd5b5060209081015160408051631d8e90d160e11b815290519193506001600160a01b03891692633b1d21a292600480840193829003018186803b15801561310057600080fd5b505afa158015613114573d6000803e3d6000fd5b505050506040513d602081101561312a57600080fd5b810190808051906020019092919050505081670de0b6b3a76400006132b061016d670de0b6b3a76400008061016d8d6001600160a01b031663f3fdb15a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561319157600080fd5b505afa1580156131a5573d6000803e3d6000fd5b505050506040513d60208110156131bb57600080fd5b5051604080516351c2fdcb60e11b815290516001600160a01b039092169163a385fb9691600480820192602092909190829003018186803b1580156131ff57600080fd5b505afa158015613213573d6000803e3d6000fd5b505050506040513d602081101561322957600080fd5b81019080805190602001909291905050508e6001600160a01b031663f8f9da286040518163ffffffff1660e01b815260040160206040518083038186803b15801561327357600080fd5b505afa158015613287573d6000803e3d6000fd5b505050506040513d602081101561329d57600080fd5b505102816132a757fe5b04019190615665565b036132ba89613e36565b945094509450945050611c25565b506000948594508493508392509050565b6000546001600160a01b031633146133225760405162461bcd60e51b8152600401808060200182810382526022815260200180615df56022913960400191505060405180910390fd5b603680546001600160a01b0319166001600160a01b0392909216919091179055565b60006060603660009054906101000a90046001600160a01b03166001600160a01b03166360a8a9316040518163ffffffff1660e01b815260040160006040518083038186803b15801561339657600080fd5b505afa1580156133aa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156133d357600080fd5b8101908080516040519392919084600160201b8211156133f257600080fd5b90830190602082018581111561340757600080fd5b82518660208202830111600160201b8211171561342357600080fd5b82525081516020918201928201910280838360005b83811015613450578181015183820152602001613438565b5050505090500160405250505090506000603660009054906101000a90046001600160a01b03166001600160a01b0316632630c12f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156134af57600080fd5b505afa1580156134c3573d6000803e3d6000fd5b505050506040513d60208110156134d957600080fd5b5051905060005b825181101561369c5760365483516001600160a01b0390911690638283e3e290879086908590811061350e57fe5b60200260200101516040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561356357600080fd5b505afa158015613577573d6000803e3d6000fd5b505050506040513d602081101561358d57600080fd5b5051156136945761369161368a836001600160a01b031663fc57d4df8685815181106135b557fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156135fa57600080fd5b505afa15801561360e573d6000803e3d6000fd5b505050506040513d602081101561362457600080fd5b5051855186908590811061363457fe5b60200260200101516001600160a01b03166317bfdfbc896040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381600087803b15801561184e57600080fd5b859061584c565b93505b6001016134e0565b505050919050565b6000806000806136b2615bfd565b60365460408051638ccb720b60e01b81526001600160a01b03898116600483015291519190921691638ccb720b916024808301926000929190829003018186803b1580156136ff57600080fd5b505afa158015613713573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561373c57600080fd5b8101908080516040519392919084600160201b82111561375b57600080fd5b90830190602082018581111561377057600080fd5b82518660208202830111600160201b8211171561378c57600080fd5b82525081516020918201928201910280838360005b838110156137b95781810151838201526020016137a1565b50505050919091016040525050509082525060005b815151811015613a8f57603654825180516001600160a01b0390921691638e8f294b9190849081106137fc57fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060e06040518083038186803b15801561384157600080fd5b505afa158015613855573d6000803e3d6000fd5b505050506040513d60e081101561386b57600080fd5b50516040830181905282518051613a8292613a77929091612aea91908690811061389157fe5b60200260200101516001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b1580156138d157600080fd5b505afa1580156138e5573d6000803e3d6000fd5b505050506040513d60208110156138fb57600080fd5b505160365460408051632630c12f60e01b81529051612aea926001600160a01b031691632630c12f916004808301926020929190829003018186803b15801561394357600080fd5b505afa158015613957573d6000803e3d6000fd5b505050506040513d602081101561396d57600080fd5b5051885180516001600160a01b039092169163fc57d4df91908a90811061399057fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156139d557600080fd5b505afa1580156139e9573d6000803e3d6000fd5b505050506040513d60208110156139ff57600080fd5b50518851805189908110613a0f57fe5b60200260200101516001600160a01b03166370a082318f6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613a6357600080fd5b505afa158015611862573d6000803e3d6000fd5b60808401519061584c565b60808301526001016137ce565b50603654604080516303ad7f9b60e11b81526001600160a01b0389811660048301529151919092169163075aff36916024808301926000929190829003018186803b158015613add57600080fd5b505afa158015613af1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015613b1a57600080fd5b8101908080516040519392919084600160201b821115613b3957600080fd5b908301906020820185811115613b4e57600080fd5b82518660208202830111600160201b82111715613b6a57600080fd5b82525081516020918201928201910280838360005b83811015613b97578181015183820152602001613b7f565b505050509190910160405250505050602082015260005b816020015151811015613dec57603654602083015180516001600160a01b0390921691638e8f294b919084908110613be257fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060e06040518083038186803b158015613c2757600080fd5b505afa158015613c3b573d6000803e3d6000fd5b505050506040513d60e0811015613c5157600080fd5b506020908101516060840181905260365460408051632630c12f60e01b81529051613ddf94613dd49493612af0936001600160a01b0390911692632630c12f92600480840193919291829003018186803b158015613cae57600080fd5b505afa158015613cc2573d6000803e3d6000fd5b505050506040513d6020811015613cd857600080fd5b5051602087015180516001600160a01b039092169163fc57d4df919088908110613cfe57fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613d4357600080fd5b505afa158015613d57573d6000803e3d6000fd5b505050506040513d6020811015613d6d57600080fd5b50516020870151805187908110613d8057fe5b60200260200101516001600160a01b03166395dd91938d6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613a6357600080fd5b60a08401519061584c565b60a0830152600101613bae565b508060a00151816080015111613e1257608081015160a082015160009180820391611c1b565b60a08101516080909101518181039760009750909550909350915050565b60355481565b600080603660009054906101000a90046001600160a01b03166001600160a01b0316632630c12f6040518163ffffffff1660e01b815260040160206040518083038186803b158015613e8757600080fd5b505afa158015613e9b573d6000803e3d6000fd5b505050506040513d6020811015613eb157600080fd5b50516037546040805163fc57d4df60e01b81526001600160a01b0392831660048201529051919092169163fc57d4df916024808301926020929190829003018186803b158015613f0057600080fd5b505afa158015613f14573d6000803e3d6000fd5b505050506040513d6020811015613f2a57600080fd5b5051905080613f3d576000915050610c6c565b600061403982603660009054906101000a90046001600160a01b03166001600160a01b0316632630c12f6040518163ffffffff1660e01b815260040160206040518083038186803b158015613f9157600080fd5b505afa158015613fa5573d6000803e3d6000fd5b505050506040513d6020811015613fbb57600080fd5b50516040805163fc57d4df60e01b81526001600160a01b0389811660048301529151919092169163fc57d4df916024808301926020929190829003018186803b15801561400757600080fd5b505afa15801561401b573d6000803e3d6000fd5b505050506040513d602081101561403157600080fd5b50519061589b565b90506000846001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561407657600080fd5b505afa15801561408a573d6000803e3d6000fd5b505050506040513d60208110156140a057600080fd5b50516037546040805163313ce56760e01b815290519293506000926001600160a01b039092169163313ce56791600480820192602092909190829003018186803b1580156140ed57600080fd5b505afa158015614101573d6000803e3d6000fd5b505050506040513d602081101561411757600080fd5b5051905060ff8082169083161161413f5761413a8360ff84840316600a0a61573b565b614151565b6141518360ff83850316600a0a6157e9565b9695505050505050565b6000806001600160a01b0316836001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b1580156141a057600080fd5b505afa1580156141b4573d6000803e3d6000fd5b505050506040513d60208110156141ca57600080fd5b50516001600160a01b0316146142ba57826001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561421357600080fd5b505afa158015614227573d6000803e3d6000fd5b505050506040513d602081101561423d57600080fd5b5051604080516370a0823160e01b81526001600160a01b038581166004830152915191909216916370a08231916024808301926020929190829003018186803b15801561428957600080fd5b505afa15801561429d573d6000803e3d6000fd5b505050506040513d60208110156142b357600080fd5b50516142c6565b816001600160a01b0316315b90505b92915050565b60006142da83610a97565b156145a5576142e7615c33565b60365460408051638e8f294b60e01b81526001600160a01b03888116600483015291519190921691638e8f294b9160248083019260e0929190829003018186803b15801561433457600080fd5b505afa158015614348573d6000803e3d6000fd5b505050506040513d60e081101561435e57600080fd5b5051602082015261436e846136a4565b608085015260608401525060408201526020810151158015614394575060008160400151115b156143a35760019150506145a9565b603660009054906101000a90046001600160a01b03166001600160a01b0316632630c12f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156143f157600080fd5b505afa158015614405573d6000803e3d6000fd5b505050506040513d602081101561441b57600080fd5b50516040805163fc57d4df60e01b81526001600160a01b0388811660048301529151919092169163fc57d4df916024808301926020929190829003018186803b15801561446757600080fd5b505afa15801561447b573d6000803e3d6000fd5b505050506040513d602081101561449157600080fd5b505180825215806144a457506020810151155b806144b157506040810151155b156144c05760009150506145a9565b60808101516144cf908461589b565b8160600151116144e05760006144fe565b60808101516144fe906144f3908561589b565b606083015190615799565b60a082018190526020820151825161451992612af09161573b565b60a082015260408051633af9e66960e01b81526001600160a01b038681166004830152915191871691633af9e669916024808201926020929091908290030181600087803b15801561456a57600080fd5b505af115801561457e573d6000803e3d6000fd5b505050506040513d602081101561459457600080fd5b505160a090910151101590506145a9565b5060015b9392505050565b6000806000806145be615c69565b603660009054906101000a90046001600160a01b03166001600160a01b0316632630c12f6040518163ffffffff1660e01b815260040160206040518083038186803b15801561460c57600080fd5b505afa158015614620573d6000803e3d6000fd5b505050506040513d602081101561463657600080fd5b50516001600160a01b039081168083526037546040805163fc57d4df60e01b81529190931660048201529151909163fc57d4df916024808301926020929190829003018186803b15801561468957600080fd5b505afa15801561469d573d6000803e3d6000fd5b505050506040513d60208110156146b357600080fd5b505160408083019190915281518151630a2b53bf60e01b81526001600160a01b038b8116600483015292519290911691630a2b53bf91602480820192602092909190829003018186803b15801561470957600080fd5b505afa15801561471d573d6000803e3d6000fd5b505050506040513d602081101561473357600080fd5b50511561474c5761474387611da8565b15156101208201525b604081015161476b5761012001516000945084935083925090506149a5565b876001600160a01b031663d14827916040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156147a657600080fd5b505af11580156147ba573d6000803e3d6000fd5b505050506040513d60208110156147d057600080fd5b506147dc9050876136a4565b60a0850152608084015250606082015260365460408051638e8f294b60e01b81526001600160a01b038b8116600483015291519190921691638e8f294b9160248083019260e0929190829003018186803b15801561483957600080fd5b505afa15801561484d573d6000803e3d6000fd5b505050506040513d60e081101561486357600080fd5b506020015160c08201819052604082015160608301516148879261123c9190615723565b60e082015260a081015160808201516148a09088615723565b116148ac5760006148cb565b6148cb8160a0015161128788846080015161572390919063ffffffff16565b6101008201819052604082015160c08301516148ea9261123c91615723565b61010082015280516040805163fc57d4df60e01b81526001600160a01b038b811660048301529151919092169163fc57d4df916024808301926020929190829003018186803b15801561493c57600080fd5b505afa158015614950573d6000803e3d6000fd5b505050506040513d602081101561496657600080fd5b50516020820181905260e08201516101008301516040840151919290916149959161123c90612c408e8e61415b565b8361012001519450945094509450505b93509350935093565b6001546001600160a01b031681565b60008060008060008060006149d0615cc7565b8a6001600160a01b0316633af9e6698b6040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381600087803b158015614a1f57600080fd5b505af1158015614a33573d6000803e3d6000fd5b505050506040513d6020811015614a4957600080fd5b5051610140820152614a5b8b8b61415b565b610160820152604080516370a0823160e01b81526001600160a01b038c811660048301529151918d16916370a0823191602480820192602092909190829003018186803b158015614aab57600080fd5b505afa158015614abf573d6000803e3d6000fd5b505050506040513d6020811015614ad557600080fd5b50516101e08201526040805163313ce56760e01b815290516001600160a01b038d169163313ce567916004808301926020929190829003018186803b158015614b1d57600080fd5b505afa158015614b31573d6000803e3d6000fd5b505050506040513d6020811015614b4757600080fd5b505160ff16610200820152600061018082015260365460408051638e8f294b60e01b81526001600160a01b038e8116600483015291519190921691638e8f294b9160248083019260e0929190829003018186803b158015614ba757600080fd5b505afa158015614bbb573d6000803e3d6000fd5b505050506040513d60e0811015614bd157600080fd5b50805160609182015191830191909152604082810191909152805163182df0f560e01b81529051614cad916001600160a01b038e169163182df0f591600480820192602092909190829003018186803b158015614c2d57600080fd5b505afa158015614c41573d6000803e3d6000fd5b505050506040513d6020811015614c5757600080fd5b5051604080516318160ddd60e01b815290516001600160a01b038f16916318160ddd916004808301926020929190829003018186803b158015614c9957600080fd5b505afa158015612860573d6000803e3d6000fd5b6080820181905260608201511115614cfe5760808101516060820151614cd291615799565b610180820181905261016082015110614cf057806101800151614cf7565b8061016001515b6101808201525b8a6001600160a01b031663621fd5076040518163ffffffff1660e01b815260040160206040518083038186803b158015614d3757600080fd5b505afa158015614d4b573d6000803e3d6000fd5b505050506040513d6020811015614d6157600080fd5b505115614df0578a6001600160a01b0316633b1d21a26040518163ffffffff1660e01b815260040160206040518083038186803b158015614da157600080fd5b505afa158015614db5573d6000803e3d6000fd5b505050506040513d6020811015614dcb57600080fd5b505180825261014082015110614de2578051614de9565b8061014001515b6101a08201525b6101a08101516101c08201526036546040805163d4d4847360e01b81526001600160a01b038d811660048301528e811660248301529151919092169163d4d48473916044808301926020929190829003018186803b158015614e5157600080fd5b505afa158015614e65573d6000803e3d6000fd5b505050506040513d6020811015614e7b57600080fd5b50518015614e8d5750614e8d8a610a97565b1561514857614e9b8a6136a4565b60e085015260c08401525060a08201526040810151158015614ec1575060008160a00151115b15614f0457806101400151816101600151826101800151836101a00151846101c00151856101e00151866102000151975097509750975097509750975050615182565b603660009054906101000a90046001600160a01b03166001600160a01b0316632630c12f6040518163ffffffff1660e01b815260040160206040518083038186803b158015614f5257600080fd5b505afa158015614f66573d6000803e3d6000fd5b505050506040513d6020811015614f7c57600080fd5b50516040805163fc57d4df60e01b81526001600160a01b038e811660048301529151919092169163fc57d4df916024808301926020929190829003018186803b158015614fc857600080fd5b505afa158015614fdc573d6000803e3d6000fd5b505050506040513d6020811015614ff257600080fd5b505160208201819052158061500957506040810151155b80615016575060a0810151155b1561504c578061014001518161016001518261018001516000806000866102000151975097509750975097509750975050615182565b61506f8160400151612af083602001518460a0015161573b90919063ffffffff16565b61010082018190526101a08201511161508d57806101a00151615094565b8061010001515b6101a082015260e08101516150a9908a61589b565b8160c00151116150ba5760006150d8565b60e08101516150d8906150cd908b61589b565b60c083015190615799565b6101208201819052604082015160208301516150f792612af09161573b565b61012082018190526101c08201511161511557806101c0015161511c565b8061012001515b6101c082018190526101a08201511061513a57806101c00151615141565b806101a001515b6101c08201525b806101400151816101600151826101800151836101a00151846101c00151856101e001518661020001519750975097509750975097509750505b9397509397509397909450565b6036546001600160a01b031681565b6001546001600160a01b031633146151e75760405162461bcd60e51b8152600401808060200182810382526025815260200180615e176025913960400191505060405180910390fd5b60008054600180546001600160a01b038082166001600160a01b03198086168217808855931690935560405193811694929391169184917f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b23649190a36001546040516001600160a01b03918216918316907fb3d55174552271a4f1aaf36b72f50381e892171636b3fb5447fe00e995e7a37b90600090a35050565b6060808061529160386000615d4e565b61529d60396000615d4e565b6152a9603a6000615d6f565b6000806060603660009054906101000a90046001600160a01b03166001600160a01b03166360a8a9316040518163ffffffff1660e01b815260040160006040518083038186803b1580156152fc57600080fd5b505afa158015615310573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561533957600080fd5b8101908080516040519392919084600160201b82111561535857600080fd5b90830190602082018581111561536d57600080fd5b82518660208202830111600160201b8211171561538957600080fd5b82525081516020918201928201910280838360005b838110156153b657818101518382015260200161539e565b50505050905001604052505050905060005b8151811015615530576153ef8282815181106153e057fe5b60200260200101518a8a6158f4565b94509250821561552857603882828151811061540757fe5b60209081029190910181015182546001808201855560009485529284200180546001600160a01b0319166001600160a01b039092169190911790556039805491820181559091527fdc16fef70f8d5ddbc01ee3d903d1e69c18a3c7be080eb86a81e0578814ee58d3018490558151603a9083908390811061548457fe5b60200260200101516001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156154c457600080fd5b505afa1580156154d8573d6000803e3d6000fd5b505050506040513d60208110156154ee57600080fd5b505181546001810183556000928352602092839020928104909201805460ff928316601f9094166101000a93840292909302199092161790555b6001016153c8565b5060386039603a8280548060200260200160405190810160405280929190818152602001828054801561558c57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161556e575b50505050509250818054806020026020016040519081016040528092919081815260200182805480156155de57602002820191906000526020600020905b8154815260200190600101908083116155ca575b505050505091508080548060200260200160405190810160405280929190818152602001828054801561564e57602002820191906000526020600020906000905b825461010083900a900460ff1681526020600192830181810494850194909303909202910180841161561f5790505b505050505090509550955095505050509250925092565b60008380156157055760018416801561568057859250615684565b8392505b50600283046002850494505b84156156ff5785860286878204146156a757600080fd5b818101818110156156b757600080fd5b85900496505060018516156156f45785830283878204141587151516156156dd57600080fd5b818101818110156156ed57600080fd5b8590049350505b600285049450615690565b5061571b565b8380156157155760009250615719565b8392505b505b509392505050565b60006142c6670de0b6b3a764000061123c85856157e9565b6000808211615788576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6469762d6f766572666c6f7760601b604482015290519081900360640190fd5b81838161579157fe5b049392505050565b808203828111156142c9576040805162461bcd60e51b815260206004820152601560248201527464732d6d6174682d7375622d756e646572666c6f7760581b604482015290519081900360640190fd5b60008115806158045750508082028282828161580157fe5b04145b6142c9576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6d756c2d6f766572666c6f7760601b604482015290519081900360640190fd5b808201828110156142c9576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6164642d6f766572666c6f7760601b604482015290519081900360640190fd5b60006142c68261123c85670de0b6b3a76400006157e9565b600080546001600160a01b0319163390811782556040519091907f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b2364908290a3565b600080808361599357856001600160a01b0316633af9e669866040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381600087803b15801561594c57600080fd5b505af1158015615960573d6000803e3d6000fd5b505050506040513d602081101561597657600080fd5b50519050801561598757600161598a565b60005b92509050615abc565b6000866001600160a01b031663621fd5076040518163ffffffff1660e01b815260040160206040518083038186803b1580156159ce57600080fd5b505afa1580156159e2573d6000803e3d6000fd5b505050506040513d60208110156159f857600080fd5b505190506001851615801590615a0b5750805b80615a225750600085600216118015615a22575080155b15615aa557866001600160a01b03166317bfdfbc876040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381600087803b158015615a7657600080fd5b505af1158015615a8a573d6000803e3d6000fd5b505050506040513d6020811015615aa057600080fd5b505191505b8115615ab2576001615ab5565b60005b9350909150505b935093915050565b604051806101c0016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518061014001604052806060815260200160006001600160a01b0316815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60405180610160016040528060006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000151581525090565b6040518060c001604052806060815260200160608152602001600081526020016000815260200160008152602001600081525090565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60405180610140016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000151581525090565b60405180610220016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600060ff1681525090565b5080546000825590600052602060002090810190615d6c9190615d90565b50565b50805460008255601f016020900490600052602060002090810190615d6c91905b5b80821115615da55760008155600101615d91565b509056fe5f73657450656e64696e674f776e65723a204e6577206f77656e722063616e206e6f74206265207a65726f206164647265737320616e64206f776e657220686173206265656e20736574216f6e6c794f776e65723a2063616c6c6572206973206e6f7420746865206f776e65725f6163636570744f776e65723a204f6e6c7920666f722070656e64696e67206f776e657221a26469706673582212206443d0f764fd76f62b4f8fb809ebad7828d7610b36d953a46cbd22f700b1df8164736f6c634300060c003300000000000000000000000052eacd19e38d501d006d2023c813d7e37f025f37000000000000000000000000c171ebe1a2873f042f1dddd9327d00527ca29882

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101fb5760003560e01c8063779a45021161011a578063a385fb96116100ad578063e00ea6f01161007c578063e00ea6f0146109ba578063e30c3978146109f0578063f565fd7b146109f8578063f77c479114610a69578063fc4d33f914610a71576101fb565b8063a385fb9614610928578063a799599a14610930578063d4fac45d14610956578063debbf76a14610984576101fb565b8063918eadd3116100e9578063918eadd31461089057806392eefe9b146108b65780639fbcc4b8146108dc578063a09cf78b14610902576101fb565b8063779a45021461079e5780637aa5e5d4146107c45780638da5cb5b1461082a5780638eeaaf0014610832576101fb565b80633f47e662116101925780634f64b2be116101615780634f64b2be1461070f578063547792f11461072c5780636e96dfd7146107525780637594795f14610778576101fb565b80633f47e66214610657578063411092e31461068a57806345f0a44f146106b2578063485cc955146106e1576101fb565b80632c9e0a82116101ce5780632c9e0a82146103a85780632ff6fe761461041457806330f487e2146104385780633edb65b61461060b576101fb565b80630a9eeb2a1461020057806317563cc314610304578063243dfec61461033e5780632669264e14610364575b600080fd5b6102266004803603602081101561021657600080fd5b50356001600160a01b0316610a79565b60405180806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b8381101561026e578181015183820152602001610256565b50505050905001848103835286818151815260200191508051906020019060200280838360005b838110156102ad578181015183820152602001610295565b50505050905001848103825285818151815260200191508051906020019060200280838360005b838110156102ec5781810151838201526020016102d4565b50505050905001965050505050505060405180910390f35b61032a6004803603602081101561031a57600080fd5b50356001600160a01b0316610a97565b604080519115158252519081900360200190f35b6102266004803603602081101561035457600080fd5b50356001600160a01b0316610c71565b61038a6004803603602081101561037a57600080fd5b50356001600160a01b0316610c81565b60408051938452602084019290925282820152519081900360600190f35b6103de600480360360608110156103be57600080fd5b506001600160a01b03813581169160208101359091169060400135610f11565b604080519687526020870195909552858501939093526060850191909152608084015260ff1660a0830152519081900360c00190f35b61041c611555565b604080516001600160a01b039092168252519081900360200190f35b61045e6004803603602081101561044e57600080fd5b50356001600160a01b0316611564565b6040518080602001806020018060200180602001806020018060200187810387528d818151815260200191508051906020019060200280838360005b838110156104b257818101518382015260200161049a565b5050505090500187810386528c818151815260200191508051906020019060200280838360005b838110156104f15781810151838201526020016104d9565b5050505090500187810385528b818151815260200191508051906020019060200280838360005b83811015610530578181015183820152602001610518565b5050505090500187810384528a818151815260200191508051906020019060200280838360005b8381101561056f578181015183820152602001610557565b50505050905001878103835289818151815260200191508051906020019060200280838360005b838110156105ae578181015183820152602001610596565b50505050905001878103825288818151815260200191508051906020019060200280838360005b838110156105ed5781810151838201526020016105d5565b505050509050019c5050505050505050505050505060405180910390f35b6106316004803603602081101561062157600080fd5b50356001600160a01b031661159b565b604080519485526020850193909352838301919091526060830152519081900360800190f35b6106746004803603602081101561066d57600080fd5b5035611c2c565b6040805160ff9092168252519081900360200190f35b6106b0600480360360208110156106a057600080fd5b50356001600160a01b0316611c5d565b005b6106cf600480360360208110156106c857600080fd5b5035611cc8565b60408051918252519081900360200190f35b6106b0600480360360408110156106f757600080fd5b506001600160a01b0381358116916020013516611ce6565b61041c6004803603602081101561072557600080fd5b5035611d81565b61032a6004803603602081101561074257600080fd5b50356001600160a01b0316611da8565b6106b06004803603602081101561076857600080fd5b50356001600160a01b0316612243565b6106cf6004803603602081101561078e57600080fd5b50356001600160a01b031661233f565b610226600480360360208110156107b457600080fd5b50356001600160a01b0316612667565b610802600480360360808110156107da57600080fd5b506001600160a01b038135811691602081013582169160408201358116916060013516612677565b6040805194855260208501939093528383019190915215156060830152519081900360800190f35b61041c612c76565b6108686004803603606081101561084857600080fd5b506001600160a01b03813581169160208101359091169060400135612c85565b6040805194855292151560208501529015158383015215156060830152519081900360800190f35b610631600480360360208110156108a657600080fd5b50356001600160a01b0316612fd0565b6106b0600480360360208110156108cc57600080fd5b50356001600160a01b03166132d9565b6106cf600480360360208110156108f257600080fd5b50356001600160a01b0316613344565b6106316004803603602081101561091857600080fd5b50356001600160a01b03166136a4565b6106cf613e30565b6106cf6004803603602081101561094657600080fd5b50356001600160a01b0316613e36565b6106cf6004803603604081101561096c57600080fd5b506001600160a01b038135811691602001351661415b565b61032a6004803603606081101561099a57600080fd5b506001600160a01b038135811691602081013590911690604001356142cf565b610802600480360360608110156109d057600080fd5b506001600160a01b038135811691602081013590911690604001356145b0565b61041c6149ae565b610a2e60048036036060811015610a0e57600080fd5b506001600160a01b038135811691602081013590911690604001356149bd565b604080519788526020880196909652868601949094526060860192909252608085015260a084015260ff1660c0830152519081900360e00190f35b61041c61518f565b6106b061519e565b6060806060610a89846002615281565b9250925092505b9193909250565b60006060603660009054906101000a90046001600160a01b03166001600160a01b03166360a8a9316040518163ffffffff1660e01b815260040160006040518083038186803b158015610ae957600080fd5b505afa158015610afd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015610b2657600080fd5b8101908080516040519392919084600160201b821115610b4557600080fd5b908301906020820185811115610b5a57600080fd5b82518660208202830111600160201b82111715610b7657600080fd5b82525081516020918201928201910280838360005b83811015610ba3578181015183820152602001610b8b565b50505050905001604052505050905060005b8151811015610c65576000828281518110610bcc57fe5b60200260200101516001600160a01b03166395dd9193866040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610c2057600080fd5b505afa158015610c34573d6000803e3d6000fd5b505050506040513d6020811015610c4a57600080fd5b50511115610c5d57600192505050610c6c565b600101610bb5565b5060009150505b919050565b6060806060610a89846000615281565b60365460408051638e8f294b60e01b81526001600160a01b03848116600483015291516000938493849384939190921691638e8f294b9160248083019260e0929190829003018186803b158015610cd757600080fd5b505afa158015610ceb573d6000803e3d6000fd5b505050506040513d60e0811015610d0157600080fd5b50516040805163621fd50760e01b815290519192506001600160a01b0387169163621fd50791600480820192602092909190829003018186803b158015610d4757600080fd5b505afa158015610d5b573d6000803e3d6000fd5b505050506040513d6020811015610d7157600080fd5b505115610ef757600061016d866001600160a01b031663f3fdb15a6040518163ffffffff1660e01b815260040160206040518083038186803b158015610db657600080fd5b505afa158015610dca573d6000803e3d6000fd5b505050506040513d6020811015610de057600080fd5b5051604080516351c2fdcb60e11b815290516001600160a01b039092169163a385fb9691600480820192602092909190829003018186803b158015610e2457600080fd5b505afa158015610e38573d6000803e3d6000fd5b505050506040513d6020811015610e4e57600080fd5b505160408051630ae9d70b60e41b815290516001600160a01b038a169163ae9d70b0916004808301926020929190829003018186803b158015610e9057600080fd5b505afa158015610ea4573d6000803e3d6000fd5b505050506040513d6020811015610eba57600080fd5b50510281610ec457fe5b049050670de0b6b3a7640000610edf81830161016d83615665565b0382610eea88613e36565b9450945094505050610a90565b600081610f0387613e36565b935093509350509193909250565b600080600080600080610f22615ac4565b896001600160a01b03166317bfdfbc8a6040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381600087803b158015610f7157600080fd5b505af1158015610f85573d6000803e3d6000fd5b505050506040513d6020811015610f9b57600080fd5b5051610120820152610fad8a8a61415b565b610180820181905261012082015111610fcb57806101200151610fd2565b8061018001515b6101a082015260365460408051632630c12f60e01b815290516001600160a01b0390921691632630c12f91600480820192602092909190829003018186803b15801561101d57600080fd5b505afa158015611031573d6000803e3d6000fd5b505050506040513d602081101561104757600080fd5b50516040805163fc57d4df60e01b81526001600160a01b038d811660048301529151919092169163fc57d4df916024808301926020929190829003018186803b15801561109357600080fd5b505afa1580156110a7573d6000803e3d6000fd5b505050506040513d60208110156110bd57600080fd5b5051602082015260365460408051638e8f294b60e01b81526001600160a01b038d8116600483015291519190921691638e8f294b9160248083019260e0929190829003018186803b15801561111157600080fd5b505afa158015611125573d6000803e3d6000fd5b505050506040513d60e081101561113b57600080fd5b506020808201516040928301519284019290925260c0830191909152810151158061116857506040810151155b80611175575060c0810151155b1561120a57806101200151600080836101800151846101a001518e6001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156111c857600080fd5b505afa1580156111dc573d6000803e3d6000fd5b505050506040513d60208110156111f257600080fd5b5051949b509299509097509550935091506115499050565b611213896136a4565b60a085015260808401525060608201819052602082015160c08301516112429261123c91615723565b9061573b565b61014082015260a0810151608082015161125c908a615723565b1161126857600061128d565b61128d8160a001516112878a846080015161572390919063ffffffff16565b90615799565b6101608201819052602082015160c08301516112ac9261123c91615723565b81610160018181525050896001600160a01b031663621fd5076040518163ffffffff1660e01b815260040160206040518083038186803b1580156112ef57600080fd5b505afa158015611303573d6000803e3d6000fd5b505050506040513d602081101561131957600080fd5b5051156113c957896001600160a01b0316633b1d21a26040518163ffffffff1660e01b815260040160206040518083038186803b15801561135957600080fd5b505afa15801561136d573d6000803e3d6000fd5b505050506040513d602081101561138357600080fd5b50518082526101408201511161139e578061014001516113a1565b80515b6101408201528051610160820151116113bf578061016001516113c2565b80515b6101608201525b896001600160a01b03166373acee986040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561140457600080fd5b505af1158015611418573d6000803e3d6000fd5b505050506040513d602081101561142e57600080fd5b505160e082018190526040820151111561145a5760e0810151604082015161145591615799565b61145d565b60005b61010082018190526101408201511161147b57806101400151611482565b8061010001515b610140820152610100810151610160820151116114a4578061016001516114ab565b8061010001515b81610160018181525050806101200151816101000151826101600151836101800151846101a001518e6001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561150c57600080fd5b505afa158015611520573d6000803e3d6000fd5b505050506040513d602081101561153657600080fd5b5051949b50929950909750955093509150505b93975093979195509350565b6037546001600160a01b031681565b606080606080606080611578876000615281565b9197509550935061158a876003615281565b979996985094969095909350915050565b6000806000806115a9615b33565b6036546001600160a01b031660208201819052604080516360a8a93160e01b815290516360a8a93191600480820192600092909190829003018186803b1580156115f257600080fd5b505afa158015611606573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561162f57600080fd5b8101908080516040519392919084600160201b82111561164e57600080fd5b90830190602082018581111561166357600080fd5b82518660208202830111600160201b8211171561167f57600080fd5b82525081516020918201928201910280838360005b838110156116ac578181015183820152602001611694565b50505050905001604052505050816000018190525080602001516001600160a01b0316632630c12f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156116fe57600080fd5b505afa158015611712573d6000803e3d6000fd5b505050506040513d602081101561172857600080fd5b50516001600160a01b0316604082015260005b815151811015611b4b5781604001516001600160a01b031663fc57d4df8360000151838151811061176857fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156117ad57600080fd5b505afa1580156117c1573d6000803e3d6000fd5b505050506040513d60208110156117d757600080fd5b5051606083018190528251805161188b92611880929091859081106117f857fe5b60200260200101516001600160a01b0316633af9e6698b6040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381600087803b15801561184e57600080fd5b505af1158015611862573d6000803e3d6000fd5b505050506040513d602081101561187857600080fd5b5051906157e9565b60e08401519061584c565b60e0830152603654825180516001600160a01b0390921691638e8f294b9190849081106118b457fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060e06040518083038186803b1580156118f957600080fd5b505afa15801561190d573d6000803e3d6000fd5b505050506040513d60e081101561192357600080fd5b505160808301526020820151825180516001600160a01b039092169163d4d48473918a918590811061195157fe5b60200260200101516040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b1580156119a657600080fd5b505afa1580156119ba573d6000803e3d6000fd5b505050506040513d60208110156119d057600080fd5b505180156119e2575060008260800151115b15611a1557611a0e611a028360600151846000015184815181106117f857fe5b6101008401519061584c565b6101008301525b81602001516001600160a01b0316638283e3e28884600001518481518110611a3957fe5b60200260200101516040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b158015611a8e57600080fd5b505afa158015611aa2573d6000803e3d6000fd5b505050506040513d6020811015611ab857600080fd5b505115611b4357611b3c611b30836060015184600001518481518110611ada57fe5b60200260200101516001600160a01b03166317bfdfbc8b6040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381600087803b15801561184e57600080fd5b6101208401519061584c565b6101208301525b60010161173b565b50603754611b61906001600160a01b0316613e36565b60608201819052611b8057600080600080945094509450945050611c25565b606081015160e0820151611b939161573b565b60e08201526060810151610100820151611bac9161573b565b6101008201526060810151610120820151611bc69161573b565b610120820152611bd5866136a4565b60c0850181905260a085019190915260e084015161010085015161012086015191945092509015611c185760c084015160a0850151611c139161589b565b611c1b565b60005b9450945094509450505b9193509193565b603a8181548110611c3957fe5b9060005260206000209060209182820401919006915054906101000a900460ff1681565b6000546001600160a01b03163314611ca65760405162461bcd60e51b8152600401808060200182810382526022815260200180615df56022913960400191505060405180910390fd5b603780546001600160a01b0319166001600160a01b0392909216919091179055565b60398181548110611cd557fe5b600091825260209091200154905081565b60345460ff1615611d3e576040805162461bcd60e51b815260206004820181905260248201527f696e697469616c697a653a20416c726561647920696e697469616c697a656421604482015290519081900360640190fd5b611d466158b3565b603680546001600160a01b039384166001600160a01b031991821617909155603780549290931691161790556034805460ff19166001179055565b60388181548110611d8e57fe5b6000918252602090912001546001600160a01b0316905081565b60365460408051638ccb720b60e01b81526001600160a01b03848116600483015291516000936060931691638ccb720b9160248083019287929190829003018186803b158015611df757600080fd5b505afa158015611e0b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611e3457600080fd5b8101908080516040519392919084600160201b821115611e5357600080fd5b908301906020820185811115611e6857600080fd5b82518660208202830111600160201b82111715611e8457600080fd5b82525081516020918201928201910280838360005b83811015611eb1578181015183820152602001611e99565b50505050905001604052505050905060005b8151811015611fee57603660009054906101000a90046001600160a01b03166001600160a01b0316632630c12f6040518163ffffffff1660e01b815260040160206040518083038186803b158015611f1a57600080fd5b505afa158015611f2e573d6000803e3d6000fd5b505050506040513d6020811015611f4457600080fd5b505182516001600160a01b0390911690630a2b53bf90849084908110611f6657fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611fab57600080fd5b505afa158015611fbf573d6000803e3d6000fd5b505050506040513d6020811015611fd557600080fd5b5051611fe657600092505050610c6c565b600101611ec3565b50603654604080516303ad7f9b60e11b81526001600160a01b0386811660048301529151606093929092169163075aff3691602480820192600092909190829003018186803b15801561204057600080fd5b505afa158015612054573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561207d57600080fd5b8101908080516040519392919084600160201b82111561209c57600080fd5b9083019060208201858111156120b157600080fd5b82518660208202830111600160201b821117156120cd57600080fd5b82525081516020918201928201910280838360005b838110156120fa5781810151838201526020016120e2565b50505050905001604052505050905060005b815181101561223857603660009054906101000a90046001600160a01b03166001600160a01b0316632630c12f6040518163ffffffff1660e01b815260040160206040518083038186803b15801561216357600080fd5b505afa158015612177573d6000803e3d6000fd5b505050506040513d602081101561218d57600080fd5b505182516001600160a01b0390911690630a2b53bf908490849081106121af57fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156121f457600080fd5b505afa158015612208573d6000803e3d6000fd5b505050506040513d602081101561221e57600080fd5b50516122305760009350505050610c6c565b60010161210c565b506001949350505050565b6000546001600160a01b0316331461228c5760405162461bcd60e51b8152600401808060200182810382526022815260200180615df56022913960400191505060405180910390fd5b6001600160a01b038116158015906122b257506001546001600160a01b03828116911614155b6122ed5760405162461bcd60e51b815260040180806020018281038252604b815260200180615daa604b913960600191505060405180910390fd5b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fb3d55174552271a4f1aaf36b72f50381e892171636b3fb5447fe00e995e7a37b90600090a35050565b600080603660009054906101000a90046001600160a01b03166001600160a01b031663acc2166a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561239057600080fd5b505afa1580156123a4573d6000803e3d6000fd5b505050506040513d60208110156123ba57600080fd5b5051604080516001808252818301909252919250606091906020808301908036833701905050905083816000815181106123f057fe5b6001600160a01b039283166020918202929092010152603654604080516360a8a93160e01b8152905185841693635f1c86659386939116916360a8a93191600480820192600092909190829003018186803b15801561244e57600080fd5b505afa158015612462573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561248b57600080fd5b8101908080516040519392919084600160201b8211156124aa57600080fd5b9083019060208201858111156124bf57600080fd5b82518660208202830111600160201b821117156124db57600080fd5b82525081516020918201928201910280838360005b838110156125085781810151838201526020016124f0565b505050509050016040525050506040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015612568578181015183820152602001612550565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156125a757818101518382015260200161258f565b50505050905001945050505050600060405180830381600087803b1580156125ce57600080fd5b505af11580156125e2573d6000803e3d6000fd5b50505050816001600160a01b0316636353586b856040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561263357600080fd5b505afa158015612647573d6000803e3d6000fd5b505050506040513d602081101561265d57600080fd5b5051949350505050565b6060806060610a89846001615281565b600080600080612685615b98565b603660009054906101000a90046001600160a01b03166001600160a01b0316632630c12f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156126d357600080fd5b505afa1580156126e7573d6000803e3d6000fd5b505050506040513d60208110156126fd57600080fd5b50516001600160a01b0390811680835260408051630a2b53bf60e01b81529289166004840152519091630a2b53bf916024808301926020929190829003018186803b15801561274b57600080fd5b505afa15801561275f573d6000803e3d6000fd5b505050506040513d602081101561277557600080fd5b50511561278e5761278589611da8565b15156101408201525b6036546040805163743aaa2360e11b8152905161287e926001600160a01b03169163e8755446916004808301926020929190829003018186803b1580156127d457600080fd5b505afa1580156127e8573d6000803e3d6000fd5b505050506040513d60208110156127fe57600080fd5b5051604080516305eff7ef60e21b81526001600160a01b038d811660048301529151918b16916317bfdfbc916024808201926020929091908290030181600087803b15801561284c57600080fd5b505af1158015612860573d6000803e3d6000fd5b505050506040513d602081101561287657600080fd5b505190615723565b8160e0018181525050856001600160a01b031663bd6d894d6040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156128c257600080fd5b505af11580156128d6573d6000803e3d6000fd5b505050506040513d60208110156128ec57600080fd5b505160c08201526128fd878961415b565b606082015261290b896136a4565b505060a08301819052159050806129335750876001600160a01b0316896001600160a01b0316145b15612954576000808260600151836101400151945094509450945050612c6b565b80600001516001600160a01b031663fc57d4df886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156129a557600080fd5b505afa1580156129b9573d6000803e3d6000fd5b505050506040513d60208110156129cf57600080fd5b505160208281019190915281516040805163fc57d4df60e01b81526001600160a01b038a811660048301529151919092169263fc57d4df9260248082019391829003018186803b158015612a2257600080fd5b505afa158015612a36573d6000803e3d6000fd5b505050506040513d6020811015612a4c57600080fd5b5051604080830182905260c08301516036548251634ada90af60e01b81529251612af6949361123c9392612af0926001600160a01b0390911691634ada90af916004808301926020929190829003018186803b158015612aab57600080fd5b505afa158015612abf573d6000803e3d6000fd5b505050506040513d6020811015612ad557600080fd5b5051602087015160e0880151612aea916157e9565b90615723565b9061589b565b610100820152604080516370a0823160e01b81526001600160a01b038b811660048301529151918816916370a0823191602480820192602092909190829003018186803b158015612b4657600080fd5b505afa158015612b5a573d6000803e3d6000fd5b505050506040513d6020811015612b7057600080fd5b5051608082018190526101008201511015612ba65760e08101516060820151610140909201519095508594509092509050612c6b565b60365460408051634ada90af60e01b81529051612c46926001600160a01b031691634ada90af916004808301926020929190829003018186803b158015612bec57600080fd5b505afa158015612c00573d6000803e3d6000fd5b505050506040513d6020811015612c1657600080fd5b50516020830151604084015160c08501516080860151612af0939261123c929091612c4091615723565b906157e9565b610120820181905260e082015160608301516101409093015190965090945090925090505b945094509450949050565b6000546001600160a01b031681565b6036546040805163d4d4847360e01b81526001600160a01b03858116600483015286811660248301529151600093849384938493919092169163d4d48473916044808301926020929190829003018186803b158015612ce357600080fd5b505afa158015612cf7573d6000803e3d6000fd5b505050506040513d6020811015612d0d57600080fd5b5051925082612db05760365460408051638e8f294b60e01b81526001600160a01b038a8116600483015291516000939290921691638e8f294b9160248082019260e092909190829003018186803b158015612d6757600080fd5b505afa158015612d7b573d6000803e3d6000fd5b505050506040513d60e0811015612d9157600080fd5b5051905080612da1576000612da4565b60015b92506001915050612dc9565b612dbb8787876142cf565b9150612dc686611da8565b90505b60365460408051632630c12f60e01b815290516000926001600160a01b031691632630c12f916004808301926020929190829003018186803b158015612e0e57600080fd5b505afa158015612e22573d6000803e3d6000fd5b505050506040513d6020811015612e3857600080fd5b50516037546040805163fc57d4df60e01b81526001600160a01b0392831660048201529051919092169163fc57d4df916024808301926020929190829003018186803b158015612e8757600080fd5b505afa158015612e9b573d6000803e3d6000fd5b505050506040513d6020811015612eb157600080fd5b505190508015612fc157612fbc8161123c603660009054906101000a90046001600160a01b03166001600160a01b0316632630c12f6040518163ffffffff1660e01b815260040160206040518083038186803b158015612f1057600080fd5b505afa158015612f24573d6000803e3d6000fd5b505050506040513d6020811015612f3a57600080fd5b50516040805163fc57d4df60e01b81526001600160a01b038e811660048301529151919092169163fc57d4df916024808301926020929190829003018186803b158015612f8657600080fd5b505afa158015612f9a573d6000803e3d6000fd5b505050506040513d6020811015612fb057600080fd5b5051612c408c8c61415b565b612fc4565b60005b94505093509350935093565b600080600080846001600160a01b031663744279376040518163ffffffff1660e01b815260040160206040518083038186803b15801561300f57600080fd5b505afa158015613023573d6000803e3d6000fd5b505050506040513d602081101561303957600080fd5b5051156132c85760365460408051638e8f294b60e01b81526001600160a01b03888116600483015291516000939290921691638e8f294b9160248082019260e092909190829003018186803b15801561309157600080fd5b505afa1580156130a5573d6000803e3d6000fd5b505050506040513d60e08110156130bb57600080fd5b5060209081015160408051631d8e90d160e11b815290519193506001600160a01b03891692633b1d21a292600480840193829003018186803b15801561310057600080fd5b505afa158015613114573d6000803e3d6000fd5b505050506040513d602081101561312a57600080fd5b810190808051906020019092919050505081670de0b6b3a76400006132b061016d670de0b6b3a76400008061016d8d6001600160a01b031663f3fdb15a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561319157600080fd5b505afa1580156131a5573d6000803e3d6000fd5b505050506040513d60208110156131bb57600080fd5b5051604080516351c2fdcb60e11b815290516001600160a01b039092169163a385fb9691600480820192602092909190829003018186803b1580156131ff57600080fd5b505afa158015613213573d6000803e3d6000fd5b505050506040513d602081101561322957600080fd5b81019080805190602001909291905050508e6001600160a01b031663f8f9da286040518163ffffffff1660e01b815260040160206040518083038186803b15801561327357600080fd5b505afa158015613287573d6000803e3d6000fd5b505050506040513d602081101561329d57600080fd5b505102816132a757fe5b04019190615665565b036132ba89613e36565b945094509450945050611c25565b506000948594508493508392509050565b6000546001600160a01b031633146133225760405162461bcd60e51b8152600401808060200182810382526022815260200180615df56022913960400191505060405180910390fd5b603680546001600160a01b0319166001600160a01b0392909216919091179055565b60006060603660009054906101000a90046001600160a01b03166001600160a01b03166360a8a9316040518163ffffffff1660e01b815260040160006040518083038186803b15801561339657600080fd5b505afa1580156133aa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156133d357600080fd5b8101908080516040519392919084600160201b8211156133f257600080fd5b90830190602082018581111561340757600080fd5b82518660208202830111600160201b8211171561342357600080fd5b82525081516020918201928201910280838360005b83811015613450578181015183820152602001613438565b5050505090500160405250505090506000603660009054906101000a90046001600160a01b03166001600160a01b0316632630c12f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156134af57600080fd5b505afa1580156134c3573d6000803e3d6000fd5b505050506040513d60208110156134d957600080fd5b5051905060005b825181101561369c5760365483516001600160a01b0390911690638283e3e290879086908590811061350e57fe5b60200260200101516040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561356357600080fd5b505afa158015613577573d6000803e3d6000fd5b505050506040513d602081101561358d57600080fd5b5051156136945761369161368a836001600160a01b031663fc57d4df8685815181106135b557fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156135fa57600080fd5b505afa15801561360e573d6000803e3d6000fd5b505050506040513d602081101561362457600080fd5b5051855186908590811061363457fe5b60200260200101516001600160a01b03166317bfdfbc896040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381600087803b15801561184e57600080fd5b859061584c565b93505b6001016134e0565b505050919050565b6000806000806136b2615bfd565b60365460408051638ccb720b60e01b81526001600160a01b03898116600483015291519190921691638ccb720b916024808301926000929190829003018186803b1580156136ff57600080fd5b505afa158015613713573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561373c57600080fd5b8101908080516040519392919084600160201b82111561375b57600080fd5b90830190602082018581111561377057600080fd5b82518660208202830111600160201b8211171561378c57600080fd5b82525081516020918201928201910280838360005b838110156137b95781810151838201526020016137a1565b50505050919091016040525050509082525060005b815151811015613a8f57603654825180516001600160a01b0390921691638e8f294b9190849081106137fc57fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060e06040518083038186803b15801561384157600080fd5b505afa158015613855573d6000803e3d6000fd5b505050506040513d60e081101561386b57600080fd5b50516040830181905282518051613a8292613a77929091612aea91908690811061389157fe5b60200260200101516001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b1580156138d157600080fd5b505afa1580156138e5573d6000803e3d6000fd5b505050506040513d60208110156138fb57600080fd5b505160365460408051632630c12f60e01b81529051612aea926001600160a01b031691632630c12f916004808301926020929190829003018186803b15801561394357600080fd5b505afa158015613957573d6000803e3d6000fd5b505050506040513d602081101561396d57600080fd5b5051885180516001600160a01b039092169163fc57d4df91908a90811061399057fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156139d557600080fd5b505afa1580156139e9573d6000803e3d6000fd5b505050506040513d60208110156139ff57600080fd5b50518851805189908110613a0f57fe5b60200260200101516001600160a01b03166370a082318f6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613a6357600080fd5b505afa158015611862573d6000803e3d6000fd5b60808401519061584c565b60808301526001016137ce565b50603654604080516303ad7f9b60e11b81526001600160a01b0389811660048301529151919092169163075aff36916024808301926000929190829003018186803b158015613add57600080fd5b505afa158015613af1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015613b1a57600080fd5b8101908080516040519392919084600160201b821115613b3957600080fd5b908301906020820185811115613b4e57600080fd5b82518660208202830111600160201b82111715613b6a57600080fd5b82525081516020918201928201910280838360005b83811015613b97578181015183820152602001613b7f565b505050509190910160405250505050602082015260005b816020015151811015613dec57603654602083015180516001600160a01b0390921691638e8f294b919084908110613be257fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060e06040518083038186803b158015613c2757600080fd5b505afa158015613c3b573d6000803e3d6000fd5b505050506040513d60e0811015613c5157600080fd5b506020908101516060840181905260365460408051632630c12f60e01b81529051613ddf94613dd49493612af0936001600160a01b0390911692632630c12f92600480840193919291829003018186803b158015613cae57600080fd5b505afa158015613cc2573d6000803e3d6000fd5b505050506040513d6020811015613cd857600080fd5b5051602087015180516001600160a01b039092169163fc57d4df919088908110613cfe57fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613d4357600080fd5b505afa158015613d57573d6000803e3d6000fd5b505050506040513d6020811015613d6d57600080fd5b50516020870151805187908110613d8057fe5b60200260200101516001600160a01b03166395dd91938d6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613a6357600080fd5b60a08401519061584c565b60a0830152600101613bae565b508060a00151816080015111613e1257608081015160a082015160009180820391611c1b565b60a08101516080909101518181039760009750909550909350915050565b60355481565b600080603660009054906101000a90046001600160a01b03166001600160a01b0316632630c12f6040518163ffffffff1660e01b815260040160206040518083038186803b158015613e8757600080fd5b505afa158015613e9b573d6000803e3d6000fd5b505050506040513d6020811015613eb157600080fd5b50516037546040805163fc57d4df60e01b81526001600160a01b0392831660048201529051919092169163fc57d4df916024808301926020929190829003018186803b158015613f0057600080fd5b505afa158015613f14573d6000803e3d6000fd5b505050506040513d6020811015613f2a57600080fd5b5051905080613f3d576000915050610c6c565b600061403982603660009054906101000a90046001600160a01b03166001600160a01b0316632630c12f6040518163ffffffff1660e01b815260040160206040518083038186803b158015613f9157600080fd5b505afa158015613fa5573d6000803e3d6000fd5b505050506040513d6020811015613fbb57600080fd5b50516040805163fc57d4df60e01b81526001600160a01b0389811660048301529151919092169163fc57d4df916024808301926020929190829003018186803b15801561400757600080fd5b505afa15801561401b573d6000803e3d6000fd5b505050506040513d602081101561403157600080fd5b50519061589b565b90506000846001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561407657600080fd5b505afa15801561408a573d6000803e3d6000fd5b505050506040513d60208110156140a057600080fd5b50516037546040805163313ce56760e01b815290519293506000926001600160a01b039092169163313ce56791600480820192602092909190829003018186803b1580156140ed57600080fd5b505afa158015614101573d6000803e3d6000fd5b505050506040513d602081101561411757600080fd5b5051905060ff8082169083161161413f5761413a8360ff84840316600a0a61573b565b614151565b6141518360ff83850316600a0a6157e9565b9695505050505050565b6000806001600160a01b0316836001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b1580156141a057600080fd5b505afa1580156141b4573d6000803e3d6000fd5b505050506040513d60208110156141ca57600080fd5b50516001600160a01b0316146142ba57826001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b15801561421357600080fd5b505afa158015614227573d6000803e3d6000fd5b505050506040513d602081101561423d57600080fd5b5051604080516370a0823160e01b81526001600160a01b038581166004830152915191909216916370a08231916024808301926020929190829003018186803b15801561428957600080fd5b505afa15801561429d573d6000803e3d6000fd5b505050506040513d60208110156142b357600080fd5b50516142c6565b816001600160a01b0316315b90505b92915050565b60006142da83610a97565b156145a5576142e7615c33565b60365460408051638e8f294b60e01b81526001600160a01b03888116600483015291519190921691638e8f294b9160248083019260e0929190829003018186803b15801561433457600080fd5b505afa158015614348573d6000803e3d6000fd5b505050506040513d60e081101561435e57600080fd5b5051602082015261436e846136a4565b608085015260608401525060408201526020810151158015614394575060008160400151115b156143a35760019150506145a9565b603660009054906101000a90046001600160a01b03166001600160a01b0316632630c12f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156143f157600080fd5b505afa158015614405573d6000803e3d6000fd5b505050506040513d602081101561441b57600080fd5b50516040805163fc57d4df60e01b81526001600160a01b0388811660048301529151919092169163fc57d4df916024808301926020929190829003018186803b15801561446757600080fd5b505afa15801561447b573d6000803e3d6000fd5b505050506040513d602081101561449157600080fd5b505180825215806144a457506020810151155b806144b157506040810151155b156144c05760009150506145a9565b60808101516144cf908461589b565b8160600151116144e05760006144fe565b60808101516144fe906144f3908561589b565b606083015190615799565b60a082018190526020820151825161451992612af09161573b565b60a082015260408051633af9e66960e01b81526001600160a01b038681166004830152915191871691633af9e669916024808201926020929091908290030181600087803b15801561456a57600080fd5b505af115801561457e573d6000803e3d6000fd5b505050506040513d602081101561459457600080fd5b505160a090910151101590506145a9565b5060015b9392505050565b6000806000806145be615c69565b603660009054906101000a90046001600160a01b03166001600160a01b0316632630c12f6040518163ffffffff1660e01b815260040160206040518083038186803b15801561460c57600080fd5b505afa158015614620573d6000803e3d6000fd5b505050506040513d602081101561463657600080fd5b50516001600160a01b039081168083526037546040805163fc57d4df60e01b81529190931660048201529151909163fc57d4df916024808301926020929190829003018186803b15801561468957600080fd5b505afa15801561469d573d6000803e3d6000fd5b505050506040513d60208110156146b357600080fd5b505160408083019190915281518151630a2b53bf60e01b81526001600160a01b038b8116600483015292519290911691630a2b53bf91602480820192602092909190829003018186803b15801561470957600080fd5b505afa15801561471d573d6000803e3d6000fd5b505050506040513d602081101561473357600080fd5b50511561474c5761474387611da8565b15156101208201525b604081015161476b5761012001516000945084935083925090506149a5565b876001600160a01b031663d14827916040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156147a657600080fd5b505af11580156147ba573d6000803e3d6000fd5b505050506040513d60208110156147d057600080fd5b506147dc9050876136a4565b60a0850152608084015250606082015260365460408051638e8f294b60e01b81526001600160a01b038b8116600483015291519190921691638e8f294b9160248083019260e0929190829003018186803b15801561483957600080fd5b505afa15801561484d573d6000803e3d6000fd5b505050506040513d60e081101561486357600080fd5b506020015160c08201819052604082015160608301516148879261123c9190615723565b60e082015260a081015160808201516148a09088615723565b116148ac5760006148cb565b6148cb8160a0015161128788846080015161572390919063ffffffff16565b6101008201819052604082015160c08301516148ea9261123c91615723565b61010082015280516040805163fc57d4df60e01b81526001600160a01b038b811660048301529151919092169163fc57d4df916024808301926020929190829003018186803b15801561493c57600080fd5b505afa158015614950573d6000803e3d6000fd5b505050506040513d602081101561496657600080fd5b50516020820181905260e08201516101008301516040840151919290916149959161123c90612c408e8e61415b565b8361012001519450945094509450505b93509350935093565b6001546001600160a01b031681565b60008060008060008060006149d0615cc7565b8a6001600160a01b0316633af9e6698b6040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381600087803b158015614a1f57600080fd5b505af1158015614a33573d6000803e3d6000fd5b505050506040513d6020811015614a4957600080fd5b5051610140820152614a5b8b8b61415b565b610160820152604080516370a0823160e01b81526001600160a01b038c811660048301529151918d16916370a0823191602480820192602092909190829003018186803b158015614aab57600080fd5b505afa158015614abf573d6000803e3d6000fd5b505050506040513d6020811015614ad557600080fd5b50516101e08201526040805163313ce56760e01b815290516001600160a01b038d169163313ce567916004808301926020929190829003018186803b158015614b1d57600080fd5b505afa158015614b31573d6000803e3d6000fd5b505050506040513d6020811015614b4757600080fd5b505160ff16610200820152600061018082015260365460408051638e8f294b60e01b81526001600160a01b038e8116600483015291519190921691638e8f294b9160248083019260e0929190829003018186803b158015614ba757600080fd5b505afa158015614bbb573d6000803e3d6000fd5b505050506040513d60e0811015614bd157600080fd5b50805160609182015191830191909152604082810191909152805163182df0f560e01b81529051614cad916001600160a01b038e169163182df0f591600480820192602092909190829003018186803b158015614c2d57600080fd5b505afa158015614c41573d6000803e3d6000fd5b505050506040513d6020811015614c5757600080fd5b5051604080516318160ddd60e01b815290516001600160a01b038f16916318160ddd916004808301926020929190829003018186803b158015614c9957600080fd5b505afa158015612860573d6000803e3d6000fd5b6080820181905260608201511115614cfe5760808101516060820151614cd291615799565b610180820181905261016082015110614cf057806101800151614cf7565b8061016001515b6101808201525b8a6001600160a01b031663621fd5076040518163ffffffff1660e01b815260040160206040518083038186803b158015614d3757600080fd5b505afa158015614d4b573d6000803e3d6000fd5b505050506040513d6020811015614d6157600080fd5b505115614df0578a6001600160a01b0316633b1d21a26040518163ffffffff1660e01b815260040160206040518083038186803b158015614da157600080fd5b505afa158015614db5573d6000803e3d6000fd5b505050506040513d6020811015614dcb57600080fd5b505180825261014082015110614de2578051614de9565b8061014001515b6101a08201525b6101a08101516101c08201526036546040805163d4d4847360e01b81526001600160a01b038d811660048301528e811660248301529151919092169163d4d48473916044808301926020929190829003018186803b158015614e5157600080fd5b505afa158015614e65573d6000803e3d6000fd5b505050506040513d6020811015614e7b57600080fd5b50518015614e8d5750614e8d8a610a97565b1561514857614e9b8a6136a4565b60e085015260c08401525060a08201526040810151158015614ec1575060008160a00151115b15614f0457806101400151816101600151826101800151836101a00151846101c00151856101e00151866102000151975097509750975097509750975050615182565b603660009054906101000a90046001600160a01b03166001600160a01b0316632630c12f6040518163ffffffff1660e01b815260040160206040518083038186803b158015614f5257600080fd5b505afa158015614f66573d6000803e3d6000fd5b505050506040513d6020811015614f7c57600080fd5b50516040805163fc57d4df60e01b81526001600160a01b038e811660048301529151919092169163fc57d4df916024808301926020929190829003018186803b158015614fc857600080fd5b505afa158015614fdc573d6000803e3d6000fd5b505050506040513d6020811015614ff257600080fd5b505160208201819052158061500957506040810151155b80615016575060a0810151155b1561504c578061014001518161016001518261018001516000806000866102000151975097509750975097509750975050615182565b61506f8160400151612af083602001518460a0015161573b90919063ffffffff16565b61010082018190526101a08201511161508d57806101a00151615094565b8061010001515b6101a082015260e08101516150a9908a61589b565b8160c00151116150ba5760006150d8565b60e08101516150d8906150cd908b61589b565b60c083015190615799565b6101208201819052604082015160208301516150f792612af09161573b565b61012082018190526101c08201511161511557806101c0015161511c565b8061012001515b6101c082018190526101a08201511061513a57806101c00151615141565b806101a001515b6101c08201525b806101400151816101600151826101800151836101a00151846101c00151856101e001518661020001519750975097509750975097509750505b9397509397509397909450565b6036546001600160a01b031681565b6001546001600160a01b031633146151e75760405162461bcd60e51b8152600401808060200182810382526025815260200180615e176025913960400191505060405180910390fd5b60008054600180546001600160a01b038082166001600160a01b03198086168217808855931690935560405193811694929391169184917f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b23649190a36001546040516001600160a01b03918216918316907fb3d55174552271a4f1aaf36b72f50381e892171636b3fb5447fe00e995e7a37b90600090a35050565b6060808061529160386000615d4e565b61529d60396000615d4e565b6152a9603a6000615d6f565b6000806060603660009054906101000a90046001600160a01b03166001600160a01b03166360a8a9316040518163ffffffff1660e01b815260040160006040518083038186803b1580156152fc57600080fd5b505afa158015615310573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561533957600080fd5b8101908080516040519392919084600160201b82111561535857600080fd5b90830190602082018581111561536d57600080fd5b82518660208202830111600160201b8211171561538957600080fd5b82525081516020918201928201910280838360005b838110156153b657818101518382015260200161539e565b50505050905001604052505050905060005b8151811015615530576153ef8282815181106153e057fe5b60200260200101518a8a6158f4565b94509250821561552857603882828151811061540757fe5b60209081029190910181015182546001808201855560009485529284200180546001600160a01b0319166001600160a01b039092169190911790556039805491820181559091527fdc16fef70f8d5ddbc01ee3d903d1e69c18a3c7be080eb86a81e0578814ee58d3018490558151603a9083908390811061548457fe5b60200260200101516001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156154c457600080fd5b505afa1580156154d8573d6000803e3d6000fd5b505050506040513d60208110156154ee57600080fd5b505181546001810183556000928352602092839020928104909201805460ff928316601f9094166101000a93840292909302199092161790555b6001016153c8565b5060386039603a8280548060200260200160405190810160405280929190818152602001828054801561558c57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161556e575b50505050509250818054806020026020016040519081016040528092919081815260200182805480156155de57602002820191906000526020600020905b8154815260200190600101908083116155ca575b505050505091508080548060200260200160405190810160405280929190818152602001828054801561564e57602002820191906000526020600020906000905b825461010083900a900460ff1681526020600192830181810494850194909303909202910180841161561f5790505b505050505090509550955095505050509250925092565b60008380156157055760018416801561568057859250615684565b8392505b50600283046002850494505b84156156ff5785860286878204146156a757600080fd5b818101818110156156b757600080fd5b85900496505060018516156156f45785830283878204141587151516156156dd57600080fd5b818101818110156156ed57600080fd5b8590049350505b600285049450615690565b5061571b565b8380156157155760009250615719565b8392505b505b509392505050565b60006142c6670de0b6b3a764000061123c85856157e9565b6000808211615788576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6469762d6f766572666c6f7760601b604482015290519081900360640190fd5b81838161579157fe5b049392505050565b808203828111156142c9576040805162461bcd60e51b815260206004820152601560248201527464732d6d6174682d7375622d756e646572666c6f7760581b604482015290519081900360640190fd5b60008115806158045750508082028282828161580157fe5b04145b6142c9576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6d756c2d6f766572666c6f7760601b604482015290519081900360640190fd5b808201828110156142c9576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6164642d6f766572666c6f7760601b604482015290519081900360640190fd5b60006142c68261123c85670de0b6b3a76400006157e9565b600080546001600160a01b0319163390811782556040519091907f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b2364908290a3565b600080808361599357856001600160a01b0316633af9e669866040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381600087803b15801561594c57600080fd5b505af1158015615960573d6000803e3d6000fd5b505050506040513d602081101561597657600080fd5b50519050801561598757600161598a565b60005b92509050615abc565b6000866001600160a01b031663621fd5076040518163ffffffff1660e01b815260040160206040518083038186803b1580156159ce57600080fd5b505afa1580156159e2573d6000803e3d6000fd5b505050506040513d60208110156159f857600080fd5b505190506001851615801590615a0b5750805b80615a225750600085600216118015615a22575080155b15615aa557866001600160a01b03166317bfdfbc876040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381600087803b158015615a7657600080fd5b505af1158015615a8a573d6000803e3d6000fd5b505050506040513d6020811015615aa057600080fd5b505191505b8115615ab2576001615ab5565b60005b9350909150505b935093915050565b604051806101c0016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518061014001604052806060815260200160006001600160a01b0316815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60405180610160016040528060006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000151581525090565b6040518060c001604052806060815260200160608152602001600081526020016000815260200160008152602001600081525090565b6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60405180610140016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000151581525090565b60405180610220016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600060ff1681525090565b5080546000825590600052602060002090810190615d6c9190615d90565b50565b50805460008255601f016020900490600052602060002090810190615d6c91905b5b80821115615da55760008155600101615d91565b509056fe5f73657450656e64696e674f776e65723a204e6577206f77656e722063616e206e6f74206265207a65726f206164647265737320616e64206f776e657220686173206265656e20736574216f6e6c794f776e65723a2063616c6c6572206973206e6f7420746865206f776e65725f6163636570744f776e65723a204f6e6c7920666f722070656e64696e67206f776e657221a26469706673582212206443d0f764fd76f62b4f8fb809ebad7828d7610b36d953a46cbd22f700b1df8164736f6c634300060c0033

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

00000000000000000000000052eacd19e38d501d006d2023c813d7e37f025f37000000000000000000000000c171ebe1a2873f042f1dddd9327d00527ca29882

-----Decoded View---------------
Arg [0] : _controller (address): 0x52eaCd19E38D501D006D2023C813d7E37F025f37
Arg [1] : _priceToken (address): 0xc171EBE1A2873F042F1dDdd9327D00527CA29882

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000052eacd19e38d501d006d2023c813d7e37f025f37
Arg [1] : 000000000000000000000000c171ebe1a2873f042f1dddd9327d00527ca29882


Block Transaction Difficulty 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

Txn 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.