false
true
0

Contract Address Details

0x10E2fa0A0C699c84Fc15ec7d4F6543c4fdF97fA0

Contract Name
PulseXStableSwapFactory
Creator
0x30e22a–c72539 at 0xd8fc51–a0a2e7
Balance
0 PLS ( )
Tokens
Fetching tokens...
Transactions
2 Transactions
Transfers
0 Transfers
Gas Used
0
Last Balance Update
25874411
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
PulseXStableSwapFactory




Optimization enabled
true
Compiler version
v0.8.10+commit.fc410830




Optimization runs
100
EVM Version
default




Verified at
2024-09-04T14:04:08.404444Z

Constructor Arguments

0x000000000000000000000000178b64ccb44f2507996f7f8c2c5e9b74e532171f0000000000000000000000006e3deb239c899295f096827ebf2cae724323734d000000000000000000000000fec0d60b442e5585fd4f17e6480a39565309a812000000000000000000000000d6ca7ee047a6f45d20d2962e4394e070cf27724f

Arg [0] (address) : 0x178b64ccb44f2507996f7f8c2c5e9b74e532171f
Arg [1] (address) : 0x6e3deb239c899295f096827ebf2cae724323734d
Arg [2] (address) : 0xfec0d60b442e5585fd4f17e6480a39565309a812
Arg [3] (address) : 0xd6ca7ee047a6f45d20d2962e4394e070cf27724f

              

contracts/PulseXStableSwapFactory.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

import "@openzeppelin-4.5.0/contracts/access/Ownable.sol";
import "./interfaces/IPulseXStableSwap.sol";
import "./interfaces/IPulseXStableSwapLP.sol";
import "./interfaces/IPulseXStableSwapDeployer.sol";
import "./interfaces/IPulseXStableSwapLPFactory.sol";
import { CreateTwoPoolArgs, CreateThreePoolArgs } from "./interfaces/IPulseXStableSwapDeployer.sol";

contract PulseXStableSwapFactory is Ownable {
    struct StableSwapTwoPoolInfo {
        address swapContract;
        address token0;
        address token1;
        address LPContract;
    }
    struct StableSwapThreePoolInfo {
        address swapContract;
        address token0;
        address token1;
        address token2;
        address LPContract;
    }

    mapping(address => mapping(address => StableSwapTwoPoolInfo)) twoPoolInfo;
    mapping(address => mapping(address => mapping(address => StableSwapThreePoolInfo))) public threePoolInfo;
    mapping(uint256 => address) public swapPoolContract;

    IPulseXStableSwapLPFactory public immutable LPFactory;
    IPulseXStableSwapDeployer public immutable SwapTwoPoolDeployer;
    IPulseXStableSwapDeployer public immutable SwapThreePoolDeployer;

    address constant ZEROADDRESS = address(0);

    uint256 public pairLength;
    address public fee_to;

    event NewStableSwapPool(address indexed swapContract, address tokenA, address tokenB, address tokenC, address LP);

    /**
     * @notice constructor
     * _LPFactory: LP factory
     * _SwapTwoPoolDeployer: Swap two pool deployer
     * _SwapThreePoolDeployer: Swap three pool deployer
     * _fee_to: fee_to
     */
    constructor(
        IPulseXStableSwapLPFactory _LPFactory,
        IPulseXStableSwapDeployer _SwapTwoPoolDeployer,
        IPulseXStableSwapDeployer _SwapThreePoolDeployer,
        address _fee_to
    ) {
        LPFactory = _LPFactory;
        SwapTwoPoolDeployer = _SwapTwoPoolDeployer;
        SwapThreePoolDeployer = _SwapThreePoolDeployer;
        fee_to = _fee_to;
    }

    // returns sorted token addresses, used to handle return values from pairs sorted in this order
    function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) {
        require(tokenA != tokenB, "IDENTICAL_ADDRESSES");
        (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
    }

    function sortTokens(
        address tokenA,
        address tokenB,
        address tokenC
    )
        internal
        pure
        returns (
            address,
            address,
            address
        )
    {
        require(tokenA != tokenB && tokenA != tokenC && tokenB != tokenC, "IDENTICAL_ADDRESSES");
        address tmp;
        if (tokenA > tokenB) {
            tmp = tokenA;
            tokenA = tokenB;
            tokenB = tmp;
        }
        if (tokenB > tokenC) {
            tmp = tokenB;
            tokenB = tokenC;
            tokenC = tmp;
            if (tokenA > tokenB) {
                tmp = tokenA;
                tokenA = tokenB;
                tokenB = tmp;
            }
        }
        return (tokenA, tokenB, tokenC);
    }

    /**
     * @notice createTwoPool
     * @param _tokenA: Addresses of ERC20 conracts .
     * @param _tokenB: Addresses of ERC20 conracts .
     * @param _A: Amplification coefficient multiplied by n * (n - 1)
     * @param _fee: Fee to charge for exchanges
     * @param _admin_fee: Admin fee
     * @param _WPLS: WPLS
     */
    function createTwoPool(
        address _tokenA,
        address _tokenB,
        uint256 _A,
        uint256 _fee,
        uint256 _admin_fee,
        address _WPLS
    ) external onlyOwner {
        require(_tokenA != ZEROADDRESS && _tokenB != ZEROADDRESS && _WPLS != ZEROADDRESS, "Illegal token");
        (address t0, address t1) = sortTokens(_tokenA, _tokenB);
        address LP = LPFactory.createSwapLP(t0, t1, ZEROADDRESS, address(this));
        CreateTwoPoolArgs memory args = CreateTwoPoolArgs({
            tokenA: t0,
            tokenB: t1,
            A: _A,
            fee: _fee,
            admin_fee: _admin_fee,
            admin: msg.sender,
            LP: LP,
            STABLESWAP_FACTORY: address(this),
            WPLS: _WPLS
        });
        address swapContract = SwapTwoPoolDeployer.createPool(args);
        IPulseXStableSwapLP(LP).setMinter(swapContract);
        addTwoPoolInfoInternal(swapContract, t0, t1, LP);
    }

    /**
     * @notice createThreePool
     * @param _tokenA: Addresses of ERC20 conracts .
     * @param _tokenB: Addresses of ERC20 conracts .
     * @param _tokenC: Addresses of ERC20 conracts .
     * @param _A: Amplification coefficient multiplied by n * (n - 1)
     * @param _fee: Fee to charge for exchanges
     * @param _admin_fee: Admin fee
     * @param _WPLS: WPLS
     */
    function createThreePool(
        address _tokenA,
        address _tokenB,
        address _tokenC,
        uint256 _A,
        uint256 _fee,
        uint256 _admin_fee,
        address _WPLS
    ) external onlyOwner {
        require(_tokenA != ZEROADDRESS && _tokenB != ZEROADDRESS && _tokenC != ZEROADDRESS && _WPLS != ZEROADDRESS, "Illegal token");
        (address t0, address t1, address t2) = sortTokens(_tokenA, _tokenB, _tokenC);
        address LP = LPFactory.createSwapLP(t0, t1, t2, address(this));
        CreateThreePoolArgs memory args = CreateThreePoolArgs({
            tokenA: t0,
            tokenB: t1,
            tokenC: t2,
            A: _A,
            fee: _fee,
            admin_fee: _admin_fee,
            admin: msg.sender,
            LP: LP,
            STABLESWAP_FACTORY: address(this),
            WPLS: _WPLS
        });
        address swapContract = SwapThreePoolDeployer.createPool(args);
        IPulseXStableSwapLP(LP).setMinter(swapContract);
        addThreePoolInfoInternal(swapContract, t0, t1, t2, LP);
    }

    function addTwoPoolInfoInternal(
        address _swapContract,
        address _t0,
        address _t1,
        address _LP
    ) internal {
        StableSwapTwoPoolInfo storage info = twoPoolInfo[_t0][_t1];
        info.swapContract = _swapContract;
        info.token0 = _t0;
        info.token1 = _t1;
        info.LPContract = _LP;
        swapPoolContract[pairLength] = _swapContract;
        pairLength += 1;
        emit NewStableSwapPool(_swapContract, _t0, _t1, ZEROADDRESS, _LP);
    }

    function addThreePoolInfoInternal(
        address _swapContract,
        address _t0,
        address _t1,
        address _t2,
        address _LP
    ) internal {
        StableSwapThreePoolInfo storage info = threePoolInfo[_t0][_t1][_t2];
        info.swapContract = _swapContract;
        info.token0 = _t0;
        info.token1 = _t1;
        info.token2 = _t2;
        info.LPContract = _LP;
        swapPoolContract[pairLength] = _swapContract;
        pairLength += 1;
        emit NewStableSwapPool(_swapContract, _t0, _t1, _t2, _LP);
    }

    function addPoolInfo(address _swapContract) external onlyOwner {
        IPulseXStableSwap swap = IPulseXStableSwap(_swapContract);
        uint256 N_COINS = swap.N_COINS();
        if (N_COINS == 2) {
            addTwoPoolInfoInternal(_swapContract, swap.coins(0), swap.coins(1), swap.token());
        } else {
            addThreePoolInfoInternal(_swapContract, swap.coins(0), swap.coins(1), swap.coins(2), swap.token());
        }
    }

    function set_fee_to(address _fee_to) external onlyOwner {
        fee_to = _fee_to;
    }

    function getTwoPoolInfo(address _tokenA, address _tokenB) external view returns (StableSwapTwoPoolInfo memory info) {
        (address t0, address t1) = sortTokens(_tokenA, _tokenB);
        info = twoPoolInfo[t0][t1];
    }

    function getThreePoolInfo(address _tokenA, address _tokenB, address _tokenC)
        external
        view
        returns (StableSwapThreePoolInfo memory info)
    {
        (address t0, address t1, address t2) = sortTokens(_tokenA, _tokenB, _tokenC);
        info = threePoolInfo[t0][t1][t2];
    }

    function renounceOwnership() public view override onlyOwner {
        revert("Not allowed");
    }

    function getMatchingThreePools(address _tokenA, address _tokenB) external view returns (StableSwapThreePoolInfo[] memory) {
        StableSwapThreePoolInfo[] memory matchingPools = new StableSwapThreePoolInfo[](pairLength);
        uint256 count = 0;

        for (uint256 i = 0; i < pairLength; i++) {
            address swapContract = swapPoolContract[i];
            IPulseXStableSwap swap = IPulseXStableSwap(swapContract);
        
            // Check if it's a three-pool
            if (swap.N_COINS() == 3) {
                address t0 = swap.coins(0);
                address t1 = swap.coins(1);
                address t2 = swap.coins(2);
            
                if (
                    (t0 == _tokenA && (t1 == _tokenB || t2 == _tokenB)) ||
                    (t1 == _tokenA && (t0 == _tokenB || t2 == _tokenB)) ||
                    (t2 == _tokenA && (t0 == _tokenB || t1 == _tokenB))
                ) {
                    matchingPools[count] = threePoolInfo[t0][t1][t2];
                    count++;
                }
            }
        }

        // Resize the array to remove unused slots
        bytes memory encodedPools = abi.encode(matchingPools);
        assembly { mstore(add(encodedPools, 0x40), count) }
        return abi.decode(encodedPools, (StableSwapThreePoolInfo[]));
    }
}
        

@openzeppelin-4.5.0/contracts/access/Ownable.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;

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

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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

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

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

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

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}
          

@openzeppelin-4.5.0/contracts/utils/Context.sol

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

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}
          

contracts/interfaces/IPulseXStableSwap.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

interface IPulseXStableSwap {
    function token() external view returns (address);

    function balances(uint256 i) external view returns (uint256);

    function support_PLS() external view returns (bool);

    function N_COINS() external view returns (uint256);

    function RATES(uint256 i) external view returns (uint256);

    function coins(uint256 i) external view returns (address);

    function PRECISION_MUL(uint256 i) external view returns (uint256);

    function fee() external view returns (uint256);

    function admin_fee() external view returns (uint256);

    function A() external view returns (uint256);

    function get_virtual_price() external view returns (uint256);

    function get_D_mem(uint256[2] memory _balances, uint256 amp) external view returns (uint256);

    function get_dy(
        uint256 i,
        uint256 j,
        uint256 dx
    ) external view returns (uint256);

    function calc_withdraw_one_coin(uint256 _token_amount, uint256 i) external view returns (uint256);

    // two pool
    function add_liquidity(uint256[2] memory amounts, uint256 min_mint_amount) external payable;

    function remove_liquidity(uint256 _amount, uint256[2] memory min_amounts) external;

    function remove_liquidity_imbalance(uint256[2] memory amounts, uint256 max_burn_amount) external;

    function get_y(
        uint256 i,
        uint256 j,
        uint256 x,
        uint256[2] memory xp_
    ) external view returns (uint256);

    // three pool
    function add_liquidity(uint256[3] memory amounts, uint256 min_mint_amount) external payable;

    function remove_liquidity(uint256 _amount, uint256[3] memory min_amounts) external;

    function remove_liquidity_imbalance(uint256[3] memory amounts, uint256 max_burn_amount) external;

    function get_y(
        uint256 i,
        uint256 j,
        uint256 x,
        uint256[3] memory xp_
    ) external view returns (uint256);
}
          

contracts/interfaces/IPulseXStableSwapDeployer.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

struct CreateTwoPoolArgs {
    address tokenA;
    address tokenB;
    uint256 A;
    uint256 fee;
    uint256 admin_fee;
    address admin;
    address LP;
    address STABLESWAP_FACTORY;
    address WPLS;
}

struct CreateThreePoolArgs {
    address tokenA;
    address tokenB;
    address tokenC;
    uint256 A;
    uint256 fee;
    uint256 admin_fee;
    address admin;
    address LP;
    address STABLESWAP_FACTORY;
    address WPLS;
}

interface IPulseXStableSwapDeployer {
    function createPool(CreateTwoPoolArgs calldata) external returns (address);

    function createPool(CreateThreePoolArgs calldata) external returns (address);
}
          

contracts/interfaces/IPulseXStableSwapLP.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

interface IPulseXStableSwapLP {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    function mint(address _to, uint256 _amount) external;

    function burnFrom(address _to, uint256 _amount) external;

    function setMinter(address _newMinter) external;
}
          

contracts/interfaces/IPulseXStableSwapLPFactory.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

interface IPulseXStableSwapLPFactory {
    function createSwapLP(
        address _tokenA,
        address _tokenB,
        address _tokenC,
        address _minter
    ) external returns (address);
}
          

Compiler Settings

{"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata"],"":["ast"]}},"optimizer":{"runs":100,"enabled":true},"libraries":{}}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_LPFactory","internalType":"contract IPulseXStableSwapLPFactory"},{"type":"address","name":"_SwapTwoPoolDeployer","internalType":"contract IPulseXStableSwapDeployer"},{"type":"address","name":"_SwapThreePoolDeployer","internalType":"contract IPulseXStableSwapDeployer"},{"type":"address","name":"_fee_to","internalType":"address"}]},{"type":"event","name":"NewStableSwapPool","inputs":[{"type":"address","name":"swapContract","internalType":"address","indexed":true},{"type":"address","name":"tokenA","internalType":"address","indexed":false},{"type":"address","name":"tokenB","internalType":"address","indexed":false},{"type":"address","name":"tokenC","internalType":"address","indexed":false},{"type":"address","name":"LP","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IPulseXStableSwapLPFactory"}],"name":"LPFactory","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IPulseXStableSwapDeployer"}],"name":"SwapThreePoolDeployer","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IPulseXStableSwapDeployer"}],"name":"SwapTwoPoolDeployer","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addPoolInfo","inputs":[{"type":"address","name":"_swapContract","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"createThreePool","inputs":[{"type":"address","name":"_tokenA","internalType":"address"},{"type":"address","name":"_tokenB","internalType":"address"},{"type":"address","name":"_tokenC","internalType":"address"},{"type":"uint256","name":"_A","internalType":"uint256"},{"type":"uint256","name":"_fee","internalType":"uint256"},{"type":"uint256","name":"_admin_fee","internalType":"uint256"},{"type":"address","name":"_WPLS","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"createTwoPool","inputs":[{"type":"address","name":"_tokenA","internalType":"address"},{"type":"address","name":"_tokenB","internalType":"address"},{"type":"uint256","name":"_A","internalType":"uint256"},{"type":"uint256","name":"_fee","internalType":"uint256"},{"type":"uint256","name":"_admin_fee","internalType":"uint256"},{"type":"address","name":"_WPLS","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"fee_to","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct PulseXStableSwapFactory.StableSwapThreePoolInfo[]","components":[{"type":"address","name":"swapContract","internalType":"address"},{"type":"address","name":"token0","internalType":"address"},{"type":"address","name":"token1","internalType":"address"},{"type":"address","name":"token2","internalType":"address"},{"type":"address","name":"LPContract","internalType":"address"}]}],"name":"getMatchingThreePools","inputs":[{"type":"address","name":"_tokenA","internalType":"address"},{"type":"address","name":"_tokenB","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"info","internalType":"struct PulseXStableSwapFactory.StableSwapThreePoolInfo","components":[{"type":"address","name":"swapContract","internalType":"address"},{"type":"address","name":"token0","internalType":"address"},{"type":"address","name":"token1","internalType":"address"},{"type":"address","name":"token2","internalType":"address"},{"type":"address","name":"LPContract","internalType":"address"}]}],"name":"getThreePoolInfo","inputs":[{"type":"address","name":"_tokenA","internalType":"address"},{"type":"address","name":"_tokenB","internalType":"address"},{"type":"address","name":"_tokenC","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"info","internalType":"struct PulseXStableSwapFactory.StableSwapTwoPoolInfo","components":[{"type":"address","name":"swapContract","internalType":"address"},{"type":"address","name":"token0","internalType":"address"},{"type":"address","name":"token1","internalType":"address"},{"type":"address","name":"LPContract","internalType":"address"}]}],"name":"getTwoPoolInfo","inputs":[{"type":"address","name":"_tokenA","internalType":"address"},{"type":"address","name":"_tokenB","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"pairLength","inputs":[]},{"type":"function","stateMutability":"view","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"set_fee_to","inputs":[{"type":"address","name":"_fee_to","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"swapPoolContract","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"swapContract","internalType":"address"},{"type":"address","name":"token0","internalType":"address"},{"type":"address","name":"token1","internalType":"address"},{"type":"address","name":"token2","internalType":"address"},{"type":"address","name":"LPContract","internalType":"address"}],"name":"threePoolInfo","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]}]
              

Contract Creation Code

0x60e06040523480156200001157600080fd5b5060405162001ee138038062001ee18339810160408190526200003491620000dc565b6200003f3362000073565b6001600160a01b0393841660805291831660a052821660c052600580546001600160a01b0319169190921617905562000144565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0381168114620000d957600080fd5b50565b60008060008060808587031215620000f357600080fd5b84516200010081620000c3565b60208601519094506200011381620000c3565b60408601519093506200012681620000c3565b60608601519092506200013981620000c3565b939692955090935050565b60805160a05160c051611d526200018f600039600081816101320152610cd701526000818161021a015261050501526000818160f50152818161040b0152610bd50152611d526000f3fe608060405234801561001057600080fd5b50600436106100eb5760003560e01c80638da5cb5b116100925780638da5cb5b14610257578063a0a384341461025f578063a90cf38e14610288578063b053c886146102de578063c6f39910146102fe578063f2fde38b14610311578063fc8820dc14610324578063fcc9136c14610337578063fd36aec71461034e57600080fd5b806314c77a6d146100f057806321420c4b1461012d57806326cfa27c1461015457806334b3230b146101675780635a0525ea1461017c57806368fae3f314610215578063715018a61461023c578063719f0bd914610244575b600080fd5b6101177f000000000000000000000000000000000000000000000000000000000000000081565b604051610124919061169f565b60405180910390f35b6101177f000000000000000000000000000000000000000000000000000000000000000081565b600554610117906001600160a01b031681565b61017a6101753660046116d5565b61036e565b005b6101db61018a36600461173c565b6002602081815260009485526040808620825293855283852090529083529120805460018201549282015460038301546004909301546001600160a01b039283169483169391831692918216911685565b604080516001600160a01b03968716815294861660208601529285169284019290925283166060830152909116608082015260a001610124565b6101177f000000000000000000000000000000000000000000000000000000000000000081565b61017a6105f7565b61017a610252366004611787565b61065c565b6101176109eb565b61011761026d3660046117ab565b6003602052600090815260409020546001600160a01b031681565b61029b6102963660046117c4565b6109fa565b604051610124919081516001600160a01b039081168252602080840151821690830152604080840151821690830152606092830151169181019190915260800190565b6102f16102ec36600461173c565b610a8f565b604051610124919061183c565b61017a61030c36600461184a565b610b28565b61017a61031f366004611787565b610dcc565b61017a610332366004611787565b610e6c565b61034060045481565b604051908152602001610124565b61036161035c3660046117c4565b610ebd565b60405161012491906118c5565b336103776109eb565b6001600160a01b0316146103a65760405162461bcd60e51b815260040161039d90611913565b60405180910390fd5b6001600160a01b038616158015906103c657506001600160a01b03851615155b80156103da57506001600160a01b03811615155b6103f65760405162461bcd60e51b815260040161039d90611948565b60008061040388886112f2565b9150915060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b240221a84846000306040518563ffffffff1660e01b815260040161045c949392919061196f565b6020604051808303816000875af115801561047b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061049f919061199a565b60408051610120810182526001600160a01b03808716825285811660208301528183018b9052606082018a9052608082018990523360a083015280841660c08301523060e0830152878116610100830152915163850787a160e01b8152929350916000917f0000000000000000000000000000000000000000000000000000000000000000169063850787a19061053a9085906004016119b7565b6020604051808303816000875af1158015610559573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057d919061199a565b604051637e51dad560e11b81529091506001600160a01b0384169063fca3b5aa906105ac90849060040161169f565b600060405180830381600087803b1580156105c657600080fd5b505af11580156105da573d6000803e3d6000fd5b505050506105ea81868686611355565b5050505050505050505050565b336106006109eb565b6001600160a01b0316146106265760405162461bcd60e51b815260040161039d90611913565b60405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b604482015260640161039d565b336106656109eb565b6001600160a01b03161461068b5760405162461bcd60e51b815260040161039d90611913565b60008190506000816001600160a01b031663293577506040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f49190611a4c565b905080600214156108435760405163c661065760e01b81526000600482015261083e9084906001600160a01b0385169063c661065790602401602060405180830381865afa15801561074a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076e919061199a565b60405163c661065760e01b8152600160048201526001600160a01b0386169063c661065790602401602060405180830381865afa1580156107b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d7919061199a565b856001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610815573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610839919061199a565b611355565b505050565b60405163c661065760e01b81526000600482015261083e9084906001600160a01b0385169063c661065790602401602060405180830381865afa15801561088e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b2919061199a565b60405163c661065760e01b8152600160048201526001600160a01b0386169063c661065790602401602060405180830381865afa1580156108f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091b919061199a565b60405163c661065760e01b8152600260048201526001600160a01b0387169063c661065790602401602060405180830381865afa158015610960573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610984919061199a565b866001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e6919061199a565b611443565b6000546001600160a01b031690565b60408051608081018252600080825260208201819052918101829052606081018290529080610a2985856112f2565b6001600160a01b039182166000908152600160208181526040808420948616845293815291839020835160808101855281548616815291810154851692820192909252600282015484169281019290925260030154909116606082015295945050505050565b610a97611671565b6000806000610aa7878787611546565b6001600160a01b0392831660009081526002602081815260408084209587168452948152848320938616835292835290839020835160a0810185528154861681526001820154861693810193909352908101548416928201929092526003820154831660608201526004909101549091166080820152979650505050505050565b33610b316109eb565b6001600160a01b031614610b575760405162461bcd60e51b815260040161039d90611913565b6001600160a01b03871615801590610b7757506001600160a01b03861615155b8015610b8b57506001600160a01b03851615155b8015610b9f57506001600160a01b03811615155b610bbb5760405162461bcd60e51b815260040161039d90611948565b6000806000610bcb8a8a8a611546565b92509250925060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b240221a858585306040518563ffffffff1660e01b8152600401610c25949392919061196f565b6020604051808303816000875af1158015610c44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c68919061199a565b60408051610140810182526001600160a01b038088168252868116602083015285811682840152606082018c9052608082018b905260a082018a90523360c083015280841660e083015230610100830152888116610120830152915163b4f0b00f60e01b8152929350916000917f0000000000000000000000000000000000000000000000000000000000000000169063b4f0b00f90610d0c908590600401611a65565b6020604051808303816000875af1158015610d2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4f919061199a565b604051637e51dad560e11b81529091506001600160a01b0384169063fca3b5aa90610d7e90849060040161169f565b600060405180830381600087803b158015610d9857600080fd5b505af1158015610dac573d6000803e3d6000fd5b50505050610dbd8187878787611443565b50505050505050505050505050565b33610dd56109eb565b6001600160a01b031614610dfb5760405162461bcd60e51b815260040161039d90611913565b6001600160a01b038116610e605760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161039d565b610e6981611621565b50565b33610e756109eb565b6001600160a01b031614610e9b5760405162461bcd60e51b815260040161039d90611913565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6060600060045467ffffffffffffffff811115610edc57610edc611b0b565b604051908082528060200260200182016040528015610f1557816020015b610f02611671565b815260200190600190039081610efa5790505b5090506000805b6004548110156112a757600081815260036020908152604091829020548251630293577560e41b815292516001600160a01b03909116928392839263293577509260048082019392918290030181865afa158015610f7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa29190611a4c565b600314156112925760405163c661065760e01b8152600060048201819052906001600160a01b0383169063c661065790602401602060405180830381865afa158015610ff2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611016919061199a565b60405163c661065760e01b8152600160048201529091506000906001600160a01b0384169063c661065790602401602060405180830381865afa158015611061573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611085919061199a565b60405163c661065760e01b8152600260048201529091506000906001600160a01b0385169063c661065790602401602060405180830381865afa1580156110d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f4919061199a565b90508a6001600160a01b0316836001600160a01b03161480156111435750896001600160a01b0316826001600160a01b031614806111435750896001600160a01b0316816001600160a01b0316145b8061119657508a6001600160a01b0316826001600160a01b03161480156111965750896001600160a01b0316836001600160a01b031614806111965750896001600160a01b0316816001600160a01b0316145b806111e957508a6001600160a01b0316816001600160a01b03161480156111e95750896001600160a01b0316836001600160a01b031614806111e95750896001600160a01b0316826001600160a01b0316145b1561128e576001600160a01b038084166000908152600260208181526040808420878616855282528084208686168552825292839020835160a081018552815486168152600182015486169281019290925291820154841692810192909252600381015483166060830152600401549091166080820152885189908990811061127457611274611b21565b6020026020010181905250868061128a90611b4d565b9750505b5050505b5050808061129f90611b4d565b915050610f1c565b506000826040516020016112bb91906118c5565b6040516020818303038152906040529050816040820152808060200190518101906112e69190611bc2565b93505050505b92915050565b600080826001600160a01b0316846001600160a01b031614156113275760405162461bcd60e51b815260040161039d90611cd7565b826001600160a01b0316846001600160a01b03161061134757828461134a565b83835b909590945092505050565b6001600160a01b03808416600081815260016020818152604080842088871680865290835281852080548c89166001600160a01b03199182168117835582870180548316909917909855600282018054821690931790925560038082018054998b16998416999099179098556004805487529790935290842080549091169094179093558354929390929091906113ed908490611d04565b92505081905550846001600160a01b03167f6b3057ede23dda3e6342e9131c7d0b4a0be94b52bcbcf29b527074e2c2a5a8838585600086604051611434949392919061196f565b60405180910390a25050505050565b6001600160a01b03808516600081815260026020818152604080842089871680865290835281852089881680875290845282862080548e8a166001600160a01b031991821681178355600180840180548416909b17909a5596820180548216909417909355600380820180548516909317909255600480820180549a8c169a85169a909a1790995588548752935290842080549091169092179091558354909391906114f0908490611d04565b92505081905550856001600160a01b03167f6b3057ede23dda3e6342e9131c7d0b4a0be94b52bcbcf29b527074e2c2a5a88386868686604051611536949392919061196f565b60405180910390a2505050505050565b6000806000846001600160a01b0316866001600160a01b03161415801561157f5750836001600160a01b0316866001600160a01b031614155b801561159d5750836001600160a01b0316856001600160a01b031614155b6115b95760405162461bcd60e51b815260040161039d90611cd7565b6000856001600160a01b0316876001600160a01b031611156115db5750939493845b846001600160a01b0316866001600160a01b031611156116145750929392836001600160a01b0380871690881611156116145750939493845b5094959394509192915050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b6001600160a01b0391909116815260200190565b6001600160a01b03169052565b6001600160a01b0381168114610e6957600080fd5b60008060008060008060c087890312156116ee57600080fd5b86356116f9816116c0565b95506020870135611709816116c0565b945060408701359350606087013592506080870135915060a087013561172e816116c0565b809150509295509295509295565b60008060006060848603121561175157600080fd5b833561175c816116c0565b9250602084013561176c816116c0565b9150604084013561177c816116c0565b809150509250925092565b60006020828403121561179957600080fd5b81356117a4816116c0565b9392505050565b6000602082840312156117bd57600080fd5b5035919050565b600080604083850312156117d757600080fd5b82356117e2816116c0565b915060208301356117f2816116c0565b809150509250929050565b80516001600160a01b03908116835260208083015182169084015260408083015182169084015260608083015182169084015260809182015116910152565b60a081016112ec82846117fd565b600080600080600080600060e0888a03121561186557600080fd5b8735611870816116c0565b96506020880135611880816116c0565b95506040880135611890816116c0565b9450606088013593506080880135925060a0880135915060c08801356118b5816116c0565b8091505092959891949750929550565b6020808252825182820181905260009190848201906040850190845b81811015611907576118f48385516117fd565b9284019260a092909201916001016118e1565b50909695505050505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252600d908201526c24b63632b3b0b6103a37b5b2b760991b604082015260600190565b6001600160a01b03948516815292841660208401529083166040830152909116606082015260800190565b6000602082840312156119ac57600080fd5b81516117a4816116c0565b60006101208201905060018060a01b038084511683528060208501511660208401525060408301516040830152606083015160608301526080830151608083015260a0830151611a0a60a08401826116b3565b5060c0830151611a1d60c08401826116b3565b5060e0830151611a3060e08401826116b3565b5061010080840151611a44828501826116b3565b505092915050565b600060208284031215611a5e57600080fd5b5051919050565b600061014082019050611a798284516116b3565b6020830151611a8b60208401826116b3565b506040830151611a9e60408401826116b3565b50606083015160608301526080830151608083015260a083015160a083015260c0830151611acf60c08401826116b3565b5060e0830151611ae260e08401826116b3565b5061010080840151611af6828501826116b3565b505061012080840151611a44828501826116b3565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600019821415611b6157611b61611b37565b5060010190565b60405160a0810167ffffffffffffffff81118282101715611b8b57611b8b611b0b565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611bba57611bba611b0b565b604052919050565b60006020808385031215611bd557600080fd5b825167ffffffffffffffff80821115611bed57600080fd5b818501915085601f830112611c0157600080fd5b815181811115611c1357611c13611b0b565b611c21848260051b01611b91565b818152848101925060a0918202840185019188831115611c4057600080fd5b938501935b82851015611ccb5780858a031215611c5d5760008081fd5b611c65611b68565b8551611c70816116c0565b815285870151611c7f816116c0565b81880152604086810151611c92816116c0565b90820152606086810151611ca5816116c0565b90820152608086810151611cb8816116c0565b9082015284529384019392850192611c45565b50979650505050505050565b6020808252601390820152724944454e544943414c5f41444452455353455360681b604082015260600190565b60008219821115611d1757611d17611b37565b50019056fea2646970667358221220f4be4aa1bd608d1b8360ef619b17a3c1da2c9ccc3938156fbcdfe2f3caea363764736f6c634300080a0033000000000000000000000000178b64ccb44f2507996f7f8c2c5e9b74e532171f0000000000000000000000006e3deb239c899295f096827ebf2cae724323734d000000000000000000000000fec0d60b442e5585fd4f17e6480a39565309a812000000000000000000000000d6ca7ee047a6f45d20d2962e4394e070cf27724f

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106100eb5760003560e01c80638da5cb5b116100925780638da5cb5b14610257578063a0a384341461025f578063a90cf38e14610288578063b053c886146102de578063c6f39910146102fe578063f2fde38b14610311578063fc8820dc14610324578063fcc9136c14610337578063fd36aec71461034e57600080fd5b806314c77a6d146100f057806321420c4b1461012d57806326cfa27c1461015457806334b3230b146101675780635a0525ea1461017c57806368fae3f314610215578063715018a61461023c578063719f0bd914610244575b600080fd5b6101177f000000000000000000000000178b64ccb44f2507996f7f8c2c5e9b74e532171f81565b604051610124919061169f565b60405180910390f35b6101177f000000000000000000000000fec0d60b442e5585fd4f17e6480a39565309a81281565b600554610117906001600160a01b031681565b61017a6101753660046116d5565b61036e565b005b6101db61018a36600461173c565b6002602081815260009485526040808620825293855283852090529083529120805460018201549282015460038301546004909301546001600160a01b039283169483169391831692918216911685565b604080516001600160a01b03968716815294861660208601529285169284019290925283166060830152909116608082015260a001610124565b6101177f0000000000000000000000006e3deb239c899295f096827ebf2cae724323734d81565b61017a6105f7565b61017a610252366004611787565b61065c565b6101176109eb565b61011761026d3660046117ab565b6003602052600090815260409020546001600160a01b031681565b61029b6102963660046117c4565b6109fa565b604051610124919081516001600160a01b039081168252602080840151821690830152604080840151821690830152606092830151169181019190915260800190565b6102f16102ec36600461173c565b610a8f565b604051610124919061183c565b61017a61030c36600461184a565b610b28565b61017a61031f366004611787565b610dcc565b61017a610332366004611787565b610e6c565b61034060045481565b604051908152602001610124565b61036161035c3660046117c4565b610ebd565b60405161012491906118c5565b336103776109eb565b6001600160a01b0316146103a65760405162461bcd60e51b815260040161039d90611913565b60405180910390fd5b6001600160a01b038616158015906103c657506001600160a01b03851615155b80156103da57506001600160a01b03811615155b6103f65760405162461bcd60e51b815260040161039d90611948565b60008061040388886112f2565b9150915060007f000000000000000000000000178b64ccb44f2507996f7f8c2c5e9b74e532171f6001600160a01b031663b240221a84846000306040518563ffffffff1660e01b815260040161045c949392919061196f565b6020604051808303816000875af115801561047b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061049f919061199a565b60408051610120810182526001600160a01b03808716825285811660208301528183018b9052606082018a9052608082018990523360a083015280841660c08301523060e0830152878116610100830152915163850787a160e01b8152929350916000917f0000000000000000000000006e3deb239c899295f096827ebf2cae724323734d169063850787a19061053a9085906004016119b7565b6020604051808303816000875af1158015610559573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057d919061199a565b604051637e51dad560e11b81529091506001600160a01b0384169063fca3b5aa906105ac90849060040161169f565b600060405180830381600087803b1580156105c657600080fd5b505af11580156105da573d6000803e3d6000fd5b505050506105ea81868686611355565b5050505050505050505050565b336106006109eb565b6001600160a01b0316146106265760405162461bcd60e51b815260040161039d90611913565b60405162461bcd60e51b815260206004820152600b60248201526a139bdd08185b1b1bddd95960aa1b604482015260640161039d565b336106656109eb565b6001600160a01b03161461068b5760405162461bcd60e51b815260040161039d90611913565b60008190506000816001600160a01b031663293577506040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f49190611a4c565b905080600214156108435760405163c661065760e01b81526000600482015261083e9084906001600160a01b0385169063c661065790602401602060405180830381865afa15801561074a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076e919061199a565b60405163c661065760e01b8152600160048201526001600160a01b0386169063c661065790602401602060405180830381865afa1580156107b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d7919061199a565b856001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610815573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610839919061199a565b611355565b505050565b60405163c661065760e01b81526000600482015261083e9084906001600160a01b0385169063c661065790602401602060405180830381865afa15801561088e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b2919061199a565b60405163c661065760e01b8152600160048201526001600160a01b0386169063c661065790602401602060405180830381865afa1580156108f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091b919061199a565b60405163c661065760e01b8152600260048201526001600160a01b0387169063c661065790602401602060405180830381865afa158015610960573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610984919061199a565b866001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e6919061199a565b611443565b6000546001600160a01b031690565b60408051608081018252600080825260208201819052918101829052606081018290529080610a2985856112f2565b6001600160a01b039182166000908152600160208181526040808420948616845293815291839020835160808101855281548616815291810154851692820192909252600282015484169281019290925260030154909116606082015295945050505050565b610a97611671565b6000806000610aa7878787611546565b6001600160a01b0392831660009081526002602081815260408084209587168452948152848320938616835292835290839020835160a0810185528154861681526001820154861693810193909352908101548416928201929092526003820154831660608201526004909101549091166080820152979650505050505050565b33610b316109eb565b6001600160a01b031614610b575760405162461bcd60e51b815260040161039d90611913565b6001600160a01b03871615801590610b7757506001600160a01b03861615155b8015610b8b57506001600160a01b03851615155b8015610b9f57506001600160a01b03811615155b610bbb5760405162461bcd60e51b815260040161039d90611948565b6000806000610bcb8a8a8a611546565b92509250925060007f000000000000000000000000178b64ccb44f2507996f7f8c2c5e9b74e532171f6001600160a01b031663b240221a858585306040518563ffffffff1660e01b8152600401610c25949392919061196f565b6020604051808303816000875af1158015610c44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c68919061199a565b60408051610140810182526001600160a01b038088168252868116602083015285811682840152606082018c9052608082018b905260a082018a90523360c083015280841660e083015230610100830152888116610120830152915163b4f0b00f60e01b8152929350916000917f000000000000000000000000fec0d60b442e5585fd4f17e6480a39565309a812169063b4f0b00f90610d0c908590600401611a65565b6020604051808303816000875af1158015610d2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4f919061199a565b604051637e51dad560e11b81529091506001600160a01b0384169063fca3b5aa90610d7e90849060040161169f565b600060405180830381600087803b158015610d9857600080fd5b505af1158015610dac573d6000803e3d6000fd5b50505050610dbd8187878787611443565b50505050505050505050505050565b33610dd56109eb565b6001600160a01b031614610dfb5760405162461bcd60e51b815260040161039d90611913565b6001600160a01b038116610e605760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161039d565b610e6981611621565b50565b33610e756109eb565b6001600160a01b031614610e9b5760405162461bcd60e51b815260040161039d90611913565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6060600060045467ffffffffffffffff811115610edc57610edc611b0b565b604051908082528060200260200182016040528015610f1557816020015b610f02611671565b815260200190600190039081610efa5790505b5090506000805b6004548110156112a757600081815260036020908152604091829020548251630293577560e41b815292516001600160a01b03909116928392839263293577509260048082019392918290030181865afa158015610f7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa29190611a4c565b600314156112925760405163c661065760e01b8152600060048201819052906001600160a01b0383169063c661065790602401602060405180830381865afa158015610ff2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611016919061199a565b60405163c661065760e01b8152600160048201529091506000906001600160a01b0384169063c661065790602401602060405180830381865afa158015611061573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611085919061199a565b60405163c661065760e01b8152600260048201529091506000906001600160a01b0385169063c661065790602401602060405180830381865afa1580156110d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f4919061199a565b90508a6001600160a01b0316836001600160a01b03161480156111435750896001600160a01b0316826001600160a01b031614806111435750896001600160a01b0316816001600160a01b0316145b8061119657508a6001600160a01b0316826001600160a01b03161480156111965750896001600160a01b0316836001600160a01b031614806111965750896001600160a01b0316816001600160a01b0316145b806111e957508a6001600160a01b0316816001600160a01b03161480156111e95750896001600160a01b0316836001600160a01b031614806111e95750896001600160a01b0316826001600160a01b0316145b1561128e576001600160a01b038084166000908152600260208181526040808420878616855282528084208686168552825292839020835160a081018552815486168152600182015486169281019290925291820154841692810192909252600381015483166060830152600401549091166080820152885189908990811061127457611274611b21565b6020026020010181905250868061128a90611b4d565b9750505b5050505b5050808061129f90611b4d565b915050610f1c565b506000826040516020016112bb91906118c5565b6040516020818303038152906040529050816040820152808060200190518101906112e69190611bc2565b93505050505b92915050565b600080826001600160a01b0316846001600160a01b031614156113275760405162461bcd60e51b815260040161039d90611cd7565b826001600160a01b0316846001600160a01b03161061134757828461134a565b83835b909590945092505050565b6001600160a01b03808416600081815260016020818152604080842088871680865290835281852080548c89166001600160a01b03199182168117835582870180548316909917909855600282018054821690931790925560038082018054998b16998416999099179098556004805487529790935290842080549091169094179093558354929390929091906113ed908490611d04565b92505081905550846001600160a01b03167f6b3057ede23dda3e6342e9131c7d0b4a0be94b52bcbcf29b527074e2c2a5a8838585600086604051611434949392919061196f565b60405180910390a25050505050565b6001600160a01b03808516600081815260026020818152604080842089871680865290835281852089881680875290845282862080548e8a166001600160a01b031991821681178355600180840180548416909b17909a5596820180548216909417909355600380820180548516909317909255600480820180549a8c169a85169a909a1790995588548752935290842080549091169092179091558354909391906114f0908490611d04565b92505081905550856001600160a01b03167f6b3057ede23dda3e6342e9131c7d0b4a0be94b52bcbcf29b527074e2c2a5a88386868686604051611536949392919061196f565b60405180910390a2505050505050565b6000806000846001600160a01b0316866001600160a01b03161415801561157f5750836001600160a01b0316866001600160a01b031614155b801561159d5750836001600160a01b0316856001600160a01b031614155b6115b95760405162461bcd60e51b815260040161039d90611cd7565b6000856001600160a01b0316876001600160a01b031611156115db5750939493845b846001600160a01b0316866001600160a01b031611156116145750929392836001600160a01b0380871690881611156116145750939493845b5094959394509192915050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b6001600160a01b0391909116815260200190565b6001600160a01b03169052565b6001600160a01b0381168114610e6957600080fd5b60008060008060008060c087890312156116ee57600080fd5b86356116f9816116c0565b95506020870135611709816116c0565b945060408701359350606087013592506080870135915060a087013561172e816116c0565b809150509295509295509295565b60008060006060848603121561175157600080fd5b833561175c816116c0565b9250602084013561176c816116c0565b9150604084013561177c816116c0565b809150509250925092565b60006020828403121561179957600080fd5b81356117a4816116c0565b9392505050565b6000602082840312156117bd57600080fd5b5035919050565b600080604083850312156117d757600080fd5b82356117e2816116c0565b915060208301356117f2816116c0565b809150509250929050565b80516001600160a01b03908116835260208083015182169084015260408083015182169084015260608083015182169084015260809182015116910152565b60a081016112ec82846117fd565b600080600080600080600060e0888a03121561186557600080fd5b8735611870816116c0565b96506020880135611880816116c0565b95506040880135611890816116c0565b9450606088013593506080880135925060a0880135915060c08801356118b5816116c0565b8091505092959891949750929550565b6020808252825182820181905260009190848201906040850190845b81811015611907576118f48385516117fd565b9284019260a092909201916001016118e1565b50909695505050505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252600d908201526c24b63632b3b0b6103a37b5b2b760991b604082015260600190565b6001600160a01b03948516815292841660208401529083166040830152909116606082015260800190565b6000602082840312156119ac57600080fd5b81516117a4816116c0565b60006101208201905060018060a01b038084511683528060208501511660208401525060408301516040830152606083015160608301526080830151608083015260a0830151611a0a60a08401826116b3565b5060c0830151611a1d60c08401826116b3565b5060e0830151611a3060e08401826116b3565b5061010080840151611a44828501826116b3565b505092915050565b600060208284031215611a5e57600080fd5b5051919050565b600061014082019050611a798284516116b3565b6020830151611a8b60208401826116b3565b506040830151611a9e60408401826116b3565b50606083015160608301526080830151608083015260a083015160a083015260c0830151611acf60c08401826116b3565b5060e0830151611ae260e08401826116b3565b5061010080840151611af6828501826116b3565b505061012080840151611a44828501826116b3565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600019821415611b6157611b61611b37565b5060010190565b60405160a0810167ffffffffffffffff81118282101715611b8b57611b8b611b0b565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611bba57611bba611b0b565b604052919050565b60006020808385031215611bd557600080fd5b825167ffffffffffffffff80821115611bed57600080fd5b818501915085601f830112611c0157600080fd5b815181811115611c1357611c13611b0b565b611c21848260051b01611b91565b818152848101925060a0918202840185019188831115611c4057600080fd5b938501935b82851015611ccb5780858a031215611c5d5760008081fd5b611c65611b68565b8551611c70816116c0565b815285870151611c7f816116c0565b81880152604086810151611c92816116c0565b90820152606086810151611ca5816116c0565b90820152608086810151611cb8816116c0565b9082015284529384019392850192611c45565b50979650505050505050565b6020808252601390820152724944454e544943414c5f41444452455353455360681b604082015260600190565b60008219821115611d1757611d17611b37565b50019056fea2646970667358221220f4be4aa1bd608d1b8360ef619b17a3c1da2c9ccc3938156fbcdfe2f3caea363764736f6c634300080a0033