- Contract name:
- IHubLauncher
- Optimization enabled
- true
- Compiler version
- v0.6.12+commit.27d51765
- Optimization runs
- 200
- Verified at
- 2023-12-13T12:38:06.473486Z
contracts/IHubLauncher.sol
pragma solidity 0.6.12;// IHub Launcher//// A factory to conveniently deploy your own liquidity contracts//// Inspired by Bokky's EtherVendingMachince.io// https://github.com/bokkypoobah/FixedSupplyTokenFactory//// This program is free software: you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation, either version 3 of the License//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// The above copyright notice and this permission notice shall be included// in all copies or substantial portions of the Software.//// ---------------------------------------------------------------------// SPDX-License-Identifier: GPL-3.0// ---------------------------------------------------------------------import "./Utils/SafeTransfer.sol";import "./Utils/BoringMath.sol";import "./Access/IHubAccessControls.sol";import "./interfaces/IERC20.sol";import "./interfaces/IIHubLiquidity.sol";import "./interfaces/INeutronStarFactory.sol";import "./OpenZeppelin/token/ERC20/SafeERC20.sol";contract IHubLauncher is SafeTransfer {using BoringMath for uint256;using BoringMath128 for uint128;using BoringMath64 for uint64;using SafeERC20 for IERC20;/// @notice Responsible for access rights to the contract.IHubAccessControls public accessControls;
contracts/Access/IHubAccessControls.sol
// SPDX-License-Identifier: GPL-3.0-onlypragma solidity 0.6.12;import "./IHubAdminAccess.sol";/*** @notice Access Controls* @author Attr: BlockRocket.tech*/contract IHubAccessControls is IHubAdminAccess {/// @notice Role definitionsbytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");bytes32 public constant SMART_CONTRACT_ROLE = keccak256("SMART_CONTRACT_ROLE");bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");/*** @notice The deployer is automatically given the admin role which will allow them to then grant roles to other addresses*/// solhint-disable-next-line no-empty-blocksconstructor() public {}/////////////// Lookups ////////////////*** @notice Used to check whether an address has the minter role* @param _address EOA or contract being checked* @return bool True if the account has the role or false if it does not*/function hasMinterRole(address _address) public view returns (bool) {return hasRole(MINTER_ROLE, _address);}/*** @notice Used to check whether an address has the smart contract role* @param _address EOA or contract being checked* @return bool True if the account has the role or false if it does not*/function hasSmartContractRole(address _address) public view returns (bool) {return hasRole(SMART_CONTRACT_ROLE, _address);
contracts/Access/IHubAdminAccess.sol
// SPDX-License-Identifier: GPL-3.0-onlypragma solidity 0.6.12;import "../OpenZeppelin/access/AccessControl.sol";contract IHubAdminAccess is AccessControl {/// @dev Whether access is initialised.bool private initAccess;/// @notice The deployer is automatically given the admin role which will allow them to then grant roles to other addresses.// solhint-disable-next-line no-empty-blocksconstructor() public {}/*** @notice Initializes access controls.* @param _admin Admins address.*/function initAccessControls(address _admin) public {require(!initAccess, "Already initialised");require(_admin != address(0), "Incorrect input");_setupRole(DEFAULT_ADMIN_ROLE, _admin);initAccess = true;}/////////////// Lookups ////////////////*** @notice Used to check whether an address has the admin role.* @param _address EOA or contract being checked.* @return bool True if the account has the role or false if it does not.*/function hasAdminRole(address _address) public view returns (bool) {return hasRole(DEFAULT_ADMIN_ROLE, _address);}///////////////// Modifiers /////////////////
contracts/OpenZeppelin/access/AccessControl.sol
pragma solidity 0.6.12;import "../utils/EnumerableSet.sol";import "../utils/Context.sol";/*** @dev Contract module that allows children to implement role-based access* control mechanisms.** Roles are referred to by their `bytes32` identifier. These should be exposed* in the external API and be unique. The best way to achieve this is by* using `public constant` hash digests:** ```* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");* ```** Roles can be used to represent a set of permissions. To restrict access to a* function call, use {hasRole}:** ```* function foo() public {* require(hasRole(MY_ROLE, msg.sender));* ...* }* ```** Roles can be granted and revoked dynamically via the {grantRole} and* {revokeRole} functions. Each role has an associated admin role, and only* accounts that have a role's admin role can call {grantRole} and {revokeRole}.** By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means* that only accounts with this role will be able to grant or revoke other* roles. More complex role relationships can be created by using* {_setRoleAdmin}.** WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to* grant and revoke this role. Extra precautions should be taken to secure* accounts that have been granted it.*/abstract contract AccessControl is Context {
contracts/OpenZeppelin/math/SafeMath.sol
pragma solidity 0.6.12;/*** @dev Wrappers over Solidity's arithmetic operations with added overflow* checks.** Arithmetic operations in Solidity wrap on overflow. This can easily result* in bugs, because programmers usually assume that an overflow raises an* error, which is the standard behavior in high level programming languages.* `SafeMath` restores this intuition by reverting the transaction when an* operation overflows.** Using this library instead of the unchecked operations eliminates an entire* class of bugs, so it's recommended to use it always.*/library SafeMath {/*** @dev Returns the addition of two unsigned integers, with an overflow flag.** _Available since v3.4._*/function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {uint256 c = a + b;if (c < a) return (false, 0);return (true, c);}/*** @dev Returns the substraction of two unsigned integers, with an overflow flag.** _Available since v3.4._*/function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {if (b > a) return (false, 0);return (true, a - b);}/*** @dev Returns the multiplication of two unsigned integers, with an overflow flag.*
contracts/OpenZeppelin/token/ERC20/SafeERC20.sol
pragma solidity 0.6.12;import "../../../interfaces/IERC20.sol";import "../../math/SafeMath.sol";import "../../utils/Address.sol";/*** @title SafeERC20* @dev Wrappers around ERC20 operations that throw on failure (when the token* contract returns false). Tokens that return no value (and instead revert or* throw on failure) are also supported, non-reverting calls are assumed to be* successful.* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.*/library SafeERC20 {using SafeMath for uint256;using Address for address;function safeTransfer(IERC20 token, address to, uint256 value) internal {// 0xa9059cbb = bytes4(keccak256("transfer(address,uint256)"))_callOptionalReturn(token, abi.encodeWithSelector(0xa9059cbb, to, value));}function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {// 0x23b872dd = bytes4(keccak256("transferFrom(address,address,uint256)"))_callOptionalReturn(token, abi.encodeWithSelector(0x23b872dd, from, to, value));}/*** @dev Deprecated. This function has issues similar to the ones found in* {IERC20-approve}, and its usage is discouraged.** Whenever possible, use {safeIncreaseAllowance} and* {safeDecreaseAllowance} instead.*/function safeApprove(IERC20 token, address spender, uint256 value) internal {// safeApprove should only be called when setting an initial allowance,// or when resetting it to zero. To increase and decrease it, use// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
contracts/OpenZeppelin/utils/Address.sol
pragma solidity 0.6.12;/*** @dev Collection of functions related to the address type*/library Address {/*** @dev Returns true if `account` is a contract.** [IMPORTANT]* ====* It is unsafe to assume that an address for which this function returns* false is an externally-owned account (EOA) and not a contract.** Among others, `isContract` will return false for the following* types of addresses:** - an externally-owned account* - a contract in construction* - an address where a contract will be created* - an address where a contract lived, but was destroyed* ====*/function isContract(address account) internal view returns (bool) {// This method relies on extcodesize, which returns 0 for contracts in// construction, since the code is only stored at the end of the// constructor execution.uint256 size;// solhint-disable-next-line no-inline-assemblyassembly { size := extcodesize(account) }return size > 0;}/*** @dev Replacement for Solidity's `transfer`: sends `amount` wei to* `recipient`, forwarding all available gas and reverting on errors.** https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost* of certain opcodes, possibly making contracts go over the 2300 gas limit* imposed by `transfer`, making them unable to receive funds via
contracts/OpenZeppelin/utils/Context.sol
pragma solidity 0.6.12;/** @dev Provides information about the current execution context, including the* sender of the transaction and its data. While these are generally available* via msg.sender and msg.data, they should not be accessed in such a direct* manner, since when dealing with GSN meta-transactions the account sending and* paying for execution may not be the actual sender (as far as an application* is concerned).** This contract is only required for intermediate, library-like contracts.*/abstract contract Context {function _msgSender() internal view virtual returns (address payable) {return msg.sender;}function _msgData() internal view virtual returns (bytes memory) {this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691return msg.data;}}
contracts/OpenZeppelin/utils/EnumerableSet.sol
pragma solidity 0.6.12;/*** @dev Library for managing* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive* types.** Sets have the following properties:** - Elements are added, removed, and checked for existence in constant time* (O(1)).* - Elements are enumerated in O(n). No guarantees are made on the ordering.** ```* contract Example {* // Add the library methods* using EnumerableSet for EnumerableSet.AddressSet;** // Declare a set state variable* EnumerableSet.AddressSet private mySet;* }* ```** As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)* and `uint256` (`UintSet`) are supported.*/library EnumerableSet {// To implement this library for multiple types with as little code// repetition as possible, we write it in terms of a generic Set type with// bytes32 values.// The Set implementation uses private functions, and user-facing// implementations (such as AddressSet) are just wrappers around the// underlying Set.// This means that we can only create new EnumerableSets for types that fit// in bytes32.struct Set {// Storage of set valuesbytes32[] _values;// Position of the value in the `values` array, plus 1 because index 0
contracts/Utils/BoringMath.sol
pragma solidity 0.6.12;/// @notice A library for performing overflow-/underflow-safe math,/// updated with awesomeness from of DappHub (https://github.com/dapphub/ds-math).library BoringMath {function add(uint256 a, uint256 b) internal pure returns (uint256 c) {require((c = a + b) >= b, "BoringMath: Add Overflow");}function sub(uint256 a, uint256 b) internal pure returns (uint256 c) {require((c = a - b) <= a, "BoringMath: Underflow");}function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {require(b == 0 || (c = a * b) / b == a, "BoringMath: Mul Overflow");}function div(uint256 a, uint256 b) internal pure returns (uint256 c) {require(b > 0, "BoringMath: Div zero");c = a / b;}function to128(uint256 a) internal pure returns (uint128 c) {require(a <= uint128(-1), "BoringMath: uint128 Overflow");c = uint128(a);}function to64(uint256 a) internal pure returns (uint64 c) {require(a <= uint64(-1), "BoringMath: uint64 Overflow");c = uint64(a);}function to32(uint256 a) internal pure returns (uint32 c) {require(a <= uint32(-1), "BoringMath: uint32 Overflow");c = uint32(a);}function to16(uint256 a) internal pure returns (uint16 c) {require(a <= uint16(-1), "BoringMath: uint16 Overflow");c = uint16(a);}
contracts/Utils/SafeTransfer.sol
pragma solidity 0.6.12;contract SafeTransfer {address private constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;/// @notice Event for token withdrawals.event TokensWithdrawn(address token, address to, uint256 amount);/// @dev Helper function to handle both ETH and ERC20 paymentsfunction _safeTokenPayment(address _token, address payable _to, uint256 _amount) internal {if (address(_token) == ETH_ADDRESS) {_safeTransferETH(_to, _amount);} else {_safeTransfer(_token, _to, _amount);}emit TokensWithdrawn(_token, _to, _amount);}/// @dev Helper function to handle both ETH and ERC20 paymentsfunction _tokenPayment(address _token, address payable _to, uint256 _amount) internal {if (address(_token) == ETH_ADDRESS) {_to.transfer(_amount);} else {_safeTransfer(_token, _to, _amount);}emit TokensWithdrawn(_token, _to, _amount);}/// @dev Transfer helper from UniswapV2 Routerfunction _safeApprove(address token, address to, uint value) internal {// bytes4(keccak256(bytes('approve(address,uint256)')));// solhint-disable-next-line avoid-low-level-calls(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));require(success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper: APPROVE_FAILED");}/*** There are many non-compliant ERC20 tokens... this can handle most, adapted from UniSwap V2* Im trying to make it a habit to put external calls last (reentrancy)
contracts/interfaces/IERC20.sol
pragma solidity 0.6.12;interface IERC20 {function totalSupply() external view returns (uint256);function balanceOf(address account) external view returns (uint256);function allowance(address owner, address spender) external view returns (uint256);function approve(address spender, uint256 amount) external returns (bool);function name() external view returns (string memory);function symbol() external view returns (string memory);function decimals() external view returns (uint8);event Transfer(address indexed from, address indexed to, uint256 value);event Approval(address indexed owner, address indexed spender, uint256 value);function transferFrom(address from, address to, uint256 amount) external returns (bool);function permit(address owner,address spender,uint256 value,uint256 deadline,uint8 v,bytes32 r,bytes32 s) external;}
contracts/interfaces/IIHubLiquidity.sol
pragma solidity 0.6.12;interface IIHubLiquidity {function initLauncher(bytes calldata data) external;function getMarkets() external view returns (address[] memory);function liquidityTemplate() external view returns (uint256);}
contracts/interfaces/INeutronStarFactory.sol
pragma solidity 0.6.12;interface INeutronStarFactory {function deploy(address masterContract,bytes calldata data,bool useCreate2) external payable returns (address cloneAddress);function masterContractApproved(address, address) external view returns (bool);function masterContractOf(address) external view returns (address);function setMasterContractApproval(address user,address masterContract,bool approved,uint8 v,bytes32 r,bytes32 s) external;}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"event","name":"IHubInitLauncher","inputs":[{"type":"address","name":"sender","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"LauncherCreated","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"addr","internalType":"address","indexed":true},{"type":"address","name":"launcherTemplate","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"LauncherTemplateAdded","inputs":[{"type":"address","name":"newLauncher","internalType":"address","indexed":false},{"type":"uint256","name":"templateId","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"LauncherTemplateRemoved","inputs":[{"type":"address","name":"launcher","internalType":"address","indexed":false},{"type":"uint256","name":"templateId","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TokensWithdrawn","inputs":[{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"address","name":"to","internalType":"address","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"LAUNCHER_MINTER_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IHubAccessControls"}],"name":"accessControls","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addLiquidityLauncherTemplate","inputs":[{"type":"address","name":"_template","internalType":"address"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"address","name":"newLauncher","internalType":"address"}],"name":"createLauncher","inputs":[{"type":"uint256","name":"_templateId","internalType":"uint256"},{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_tokenSupply","internalType":"uint256"},{"type":"address","name":"_integratorFeeAccount","internalType":"address payable"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"currentTemplateId","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"address","name":"launcher","internalType":"address"}],"name":"deployLauncher","inputs":[{"type":"uint256","name":"_templateId","internalType":"uint256"},{"type":"address","name":"_integratorFeeAccount","internalType":"address payable"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint64","name":"","internalType":"uint64"}],"name":"getLauncherTemplateId","inputs":[{"type":"address","name":"_launcher","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"","internalType":"address[]"}],"name":"getLaunchers","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getLiquidityLauncherTemplate","inputs":[{"type":"uint256","name":"_templateId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getTemplateId","inputs":[{"type":"address","name":"_launcherTemplate","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"hasLauncherMinterRole","inputs":[{"type":"address","name":"_address","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address payable"}],"name":"iHubDiv","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initIHubLauncher","inputs":[{"type":"address","name":"_accessControls","internalType":"address"},{"type":"address","name":"_neutronStar","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint128","name":"minimumFee","internalType":"uint128"},{"type":"uint32","name":"integratorFeePct","internalType":"uint32"}],"name":"launcherFees","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"exists","internalType":"bool"},{"type":"uint64","name":"templateId","internalType":"uint64"},{"type":"uint128","name":"index","internalType":"uint128"}],"name":"launcherInfo","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"launcherTemplateId","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"launchers","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"locked","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint128","name":"","internalType":"uint128"}],"name":"minimumFee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract INeutronStarFactory"}],"name":"neutronStar","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"numberOfLiquidityLauncherContracts","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeLiquidityLauncherTemplate","inputs":[{"type":"uint256","name":"_templateId","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setCurrentTemplateId","inputs":[{"type":"uint256","name":"_templateType","internalType":"uint256"},{"type":"uint256","name":"_templateId","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setDividends","inputs":[{"type":"address","name":"_divaddr","internalType":"address payable"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setIntegratorFeePct","inputs":[{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setLocked","inputs":[{"type":"bool","name":"_locked","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMinimumFee","inputs":[{"type":"uint256","name":"_amount","internalType":"uint256"}]}]
Deployed ByteCode
0x60806040526004361061019c5760003560e01c80638637e041116100ec578063b1495b011161008a578063cd70f73411610064578063cd70f73414610670578063cf3090121461069c578063d335ebda146106b1578063fcb62f90146106e45761019c565b8063b1495b01146105d0578063bc79913b146105e5578063c890ee2d146106355761019c565b806392787b48116100c657806392787b481461052e57806396f1266e146105585780639e5940cc1461056d5780639e9188ea1461059d5761019c565b80638637e041146104bd57806386adc322146104d25780638c363a0b146104e75761019c565b80633f1f44b0116101595780636de88d97116101335780636de88d97146103e657806370433d0314610410578063748365ef146104755780637b7fb1531461048a5761019c565b80633f1f44b0146102c1578063632cef90146102eb5780636c4ceb36146103815761019c565b8063182a7506146101a15780631a7626e7146101cd578063211e28b6146101fe578063289591541461022a5780632ed4f5781461025b5780633eb63aa014610297575b600080fd5b3480156101ad57600080fd5b506101cb600480360360208110156101c457600080fd5b5035610721565b005b3480156101d957600080fd5b506101e2610808565b604080516001600160801b039092168252519081900360200190f35b34801561020a57600080fd5b506101cb6004803603602081101561022157600080fd5b50351515610817565b34801561023657600080fd5b5061023f6108dc565b604080516001600160a01b039092168252519081900360200190f35b34801561026757600080fd5b506102856004803603602081101561027e57600080fd5b50356108eb565b60408051918252519081900360200190f35b3480156102a357600080fd5b5061023f600480360360208110156102ba57600080fd5b50356108fd565b3480156102cd57600080fd5b506101cb600480360360208110156102e457600080fd5b5035610924565b61023f600480360360a081101561030157600080fd5b8135916001600160a01b0360208201358116926040830135926060810135909216919081019060a08101608082013564010000000081111561034257600080fd5b82018360208201111561035457600080fd5b8035906020019184600183028401116401000000008311171561037657600080fd5b509092509050610a48565b34801561038d57600080fd5b506103b4600480360360208110156103a457600080fd5b50356001600160a01b0316610baa565b60408051931515845267ffffffffffffffff90921660208401526001600160801b031682820152519081900360600190f35b3480156103f257600080fd5b5061023f6004803603602081101561040957600080fd5b5035610be1565b34801561041c57600080fd5b50610425610bfc565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610461578181015183820152602001610449565b505050509050019250505060405180910390f35b34801561048157600080fd5b5061023f610c5e565b34801561049657600080fd5b506101cb600480360360208110156104ad57600080fd5b50356001600160a01b0316610c6d565b3480156104c957600080fd5b50610285610ed2565b3480156104de57600080fd5b50610285610ef6565b3480156104f357600080fd5b5061051a6004803603602081101561050a57600080fd5b50356001600160a01b0316610efc565b604080519115158252519081900360200190f35b34801561053a57600080fd5b506101cb6004803603602081101561055157600080fd5b5035610fa2565b34801561056457600080fd5b506102856111fc565b34801561057957600080fd5b506101cb6004803603604081101561059057600080fd5b5080359060200135611202565b3480156105a957600080fd5b506101cb600480360360208110156105c057600080fd5b50356001600160a01b0316611344565b3480156105dc57600080fd5b5061023f611431565b3480156105f157600080fd5b506106186004803603602081101561060857600080fd5b50356001600160a01b0316611445565b6040805167ffffffffffffffff9092168252519081900360200190f35b34801561064157600080fd5b506101cb6004803603604081101561065857600080fd5b506001600160a01b038135811691602001351661146f565b61023f6004803603604081101561068657600080fd5b50803590602001356001600160a01b03166115cd565b3480156106a857600080fd5b5061051a611ab5565b3480156106bd57600080fd5b50610285600480360360208110156106d457600080fd5b50356001600160a01b0316611abe565b3480156106f057600080fd5b506106f9611ad9565b604080516001600160801b03909316835263ffffffff90911660208301528051918290030190f35b6000546040805163c395fcb360e01b815233600482015290516001600160a01b039092169163c395fcb391602480820192602092909190829003018186803b15801561076c57600080fd5b505afa158015610780573d6000803e3d6000fd5b505050506040513d602081101561079657600080fd5b50516107d35760405162461bcd60e51b815260040180806020018281038252602581526020018061241f6025913960400191505060405180910390fd5b6107dc81611af7565b600880546fffffffffffffffffffffffffffffffff19166001600160801b039290921691909117905550565b6008546001600160801b031690565b6000546040805163c395fcb360e01b815233600482015290516001600160a01b039092169163c395fcb391602480820192602092909190829003018186803b15801561086257600080fd5b505afa158015610876573d6000803e3d6000fd5b505050506040513d602081101561088c57600080fd5b50516108c95760405162461bcd60e51b81526004018080602001828103825260228152602001806123736022913960400191505060405180910390fd5b6009805460ff1916911515919091179055565b6003546001600160a01b031681565b60066020526000908152604090205481565b6001818154811061090a57fe5b6000918252602090912001546001600160a01b0316905081565b6000546040805163c395fcb360e01b815233600482015290516001600160a01b039092169163c395fcb391602480820192602092909190829003018186803b15801561096f57600080fd5b505afa158015610983573d6000803e3d6000fd5b505050506040513d602081101561099957600080fd5b50516109d65760405162461bcd60e51b815260040180806020018281038252602581526020018061241f6025913960400191505060405180910390fd5b6103e8811115610a175760405162461bcd60e51b81526004018080602001828103825260278152602001806123cb6027913960400191505060405180910390fd5b610a2081611b59565b6008805463ffffffff92909216600160801b0263ffffffff60801b1990921691909117905550565b6000610a5487856115cd565b90508415610a7b57610a67863387611bb4565b610a7b6001600160a01b0387168287611d0e565b604051637c17e46760e11b8152602060048201908152602482018490526001600160a01b0383169163f82fc8ce9186918691908190604401848480828437600081840152601f19601f8201169050808301925050509350505050600060405180830381600087803b158015610aef57600080fd5b505af1158015610b03573d6000803e3d6000fd5b505050506000851115610ba0576000866001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610b5f57600080fd5b505afa158015610b73573d6000803e3d6000fd5b505050506040513d6020811015610b8957600080fd5b505190508015610b9e57610b9e873383611e26565b505b9695505050505050565b60076020526000908152604090205460ff811690610100810467ffffffffffffffff1690600160481b90046001600160801b031683565b6000908152600460205260409020546001600160a01b031690565b60606001805480602002602001604051908101604052809291908181526020018280548015610c5457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610c36575b5050505050905090565b6000546001600160a01b031681565b6000546040805163c395fcb360e01b815233600482015290516001600160a01b039092169163c395fcb391602480820192602092909190829003018186803b158015610cb857600080fd5b505afa158015610ccc573d6000803e3d6000fd5b505050506040513d6020811015610ce257600080fd5b505180610d62575060005460408051637e271f0560e11b815233600482015290516001600160a01b039092169163fc4e3e0a91602480820192602092909190829003018186803b158015610d3557600080fd5b505afa158015610d49573d6000803e3d6000fd5b505050506040513d6020811015610d5f57600080fd5b50515b610d9d5760405162461bcd60e51b815260040180806020018281038252602581526020018061241f6025913960400191505060405180910390fd5b6000816001600160a01b0316638566de4b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610dd857600080fd5b505afa158015610dec573d6000803e3d6000fd5b505050506040513d6020811015610e0257600080fd5b5051905080610e425760405162461bcd60e51b81526004018080602001828103825260258152602001806124446025913960400191505060405180910390fd5b60028054600101808255600090815260046020908152604080832080546001600160a01b0319166001600160a01b038816908117909155935484845260058352818420819055858452600683529281902083905580519384529083019190915280517f6c52e34db307a16709b387d61b2de0b4dd4a2ef6fd68b04b5515ef00a533b18f9281900390910190a15050565b7fceb69df9dd42f6c115645ad1e6ac8c9f124a39546dd50de2e04024128b14698081565b60015490565b6000805460408051632474521560e21b81527fceb69df9dd42f6c115645ad1e6ac8c9f124a39546dd50de2e04024128b14698060048201526001600160a01b038581166024830152915191909216916391d14854916044808301926020929190829003018186803b158015610f7057600080fd5b505afa158015610f84573d6000803e3d6000fd5b505050506040513d6020811015610f9a57600080fd5b505192915050565b6000546040805163c395fcb360e01b815233600482015290516001600160a01b039092169163c395fcb391602480820192602092909190829003018186803b158015610fed57600080fd5b505afa158015611001573d6000803e3d6000fd5b505050506040513d602081101561101757600080fd5b505180611097575060005460408051637e271f0560e11b815233600482015290516001600160a01b039092169163fc4e3e0a91602480820192602092909190829003018186803b15801561106a57600080fd5b505afa15801561107e573d6000803e3d6000fd5b505050506040513d602081101561109457600080fd5b50515b6110d25760405162461bcd60e51b815260040180806020018281038252602581526020018061241f6025913960400191505060405180910390fd5b6000818152600460205260409020546001600160a01b03166110f357600080fd5b600081815260046020818152604080842080546001600160a01b031981169091556001600160a01b0316808552600583528185208590558151638566de4b60e01b815291519094938593638566de4b9380830193919290829003018186803b15801561115e57600080fd5b505afa158015611172573d6000803e3d6000fd5b505050506040513d602081101561118857600080fd5b50516000818152600660205260409020549091508314156111b3576000818152600660205260408120555b604080516001600160a01b03841681526020810185905281517f9c4b27a4ee95cde6444d871111211ff603accbdff0b4e96e07af9f4eba52be57929181900390910190a1505050565b60025481565b6000546040805163c395fcb360e01b815233600482015290516001600160a01b039092169163c395fcb391602480820192602092909190829003018186803b15801561124d57600080fd5b505afa158015611261573d6000803e3d6000fd5b505050506040513d602081101561127757600080fd5b5051806112f7575060005460408051637e271f0560e11b815233600482015290516001600160a01b039092169163fc4e3e0a91602480820192602092909190829003018186803b1580156112ca57600080fd5b505afa1580156112de573d6000803e3d6000fd5b505050506040513d60208110156112f457600080fd5b50515b6113325760405162461bcd60e51b81526004018080602001828103825260258152602001806123216025913960400191505060405180910390fd5b60009182526006602052604090912055565b6000546040805163c395fcb360e01b815233600482015290516001600160a01b039092169163c395fcb391602480820192602092909190829003018186803b15801561138f57600080fd5b505afa1580156113a3573d6000803e3d6000fd5b505050506040513d60208110156113b957600080fd5b50516113f65760405162461bcd60e51b815260040180806020018281038252602581526020018061241f6025913960400191505060405180910390fd5b6001600160a01b03811661140957600080fd5b600980546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b60095461010090046001600160a01b031681565b6001600160a01b0316600090815260076020526040902054610100900467ffffffffffffffff1690565b600054600160a01b900460ff16156114c4576040805162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5cd959606a1b604482015290519081900360640190fd5b6001600160a01b0382166115095760405162461bcd60e51b81526004018080602001828103825260368152602001806123956036913960400191505060405180910390fd5b6001600160a01b03811661154e5760405162461bcd60e51b81526004018080602001828103825260338152602001806124b76033913960400191505060405180910390fd5b60008054600380546001600160a01b038581166001600160a01b0319928316179092556009805460ff1916600117905560ff60a01b1991861692169190911716600160a01b1790556040805133815290517fa7318042eedf5a2fc814f6236a395324443d5885e7a5417a7dc684580eb290679181900360200190a15050565b60095460009060ff161561171a576000546040805163c395fcb360e01b815233600482015290516001600160a01b039092169163c395fcb391602480820192602092909190829003018186803b15801561162657600080fd5b505afa15801561163a573d6000803e3d6000fd5b505050506040513d602081101561165057600080fd5b5051806116d057506000546040805163099db01760e01b815233600482015290516001600160a01b039092169163099db01791602480820192602092909190829003018186803b1580156116a357600080fd5b505afa1580156116b7573d6000803e3d6000fd5b505050506040513d60208110156116cd57600080fd5b50515b806116df57506116df33610efc565b61171a5760405162461bcd60e51b815260040180806020018281038252602d8152602001806123f2602d913960400191505060405180910390fd5b6117226122b8565b506040805180820182526008546001600160801b038082168352600160801b90910463ffffffff16602080840191909152600087815260049091529290922054815191926001600160a01b0390911691163410156117b15760405162461bcd60e51b815260040180806020018281038252602b8152602001806122d0602b913960400191505060405180910390fd5b6001600160a01b0381166117f65760405162461bcd60e51b815260040180806020018281038252602d815260200180612346602d913960400191505060405180910390fd5b6000346001600160a01b0386161580159061182457506009546001600160a01b038781166101009092041614155b15611847576103e8846020015163ffffffff1682028161184057fe5b0491508190035b60035460408051631f54245b60e01b81526001600160a01b03868116600483015260006044830181905260606024840152606483018190529251931692631f54245b9260a480840193602093929083900390910190829087803b1580156118ad57600080fd5b505af11580156118c1573d6000803e3d6000fd5b505050506040513d60208110156118d757600080fd5b5051604080516060810190915260018152909550602081016118f889611f89565b67ffffffffffffffff168152602001611915600180549050611af7565b6001600160801b039081169091526001600160a01b038088166000818152600760209081526040808320875181548985015199840151909816600160481b0278ffffffffffffffffffffffffffffffff0000000000000000001967ffffffffffffffff909a166101000268ffffffffffffffff001992151560ff19909a169990991791909116979097179790971695909517909555600180548082019091557fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b031916831790558b815260048552839020548351921682529151919233927f3ba8b254094e662ed7500a3ad77fd9f4f041f221a7b9f0714e3fdbf324c5d8639281900390910190a38015611a6d576009546040516101009091046001600160a01b0316906108fc8315029083906000818181858888f19350505050158015611a6b573d6000803e3d6000fd5b505b8115611aab576040516001600160a01b0387169083156108fc029084906000818181858888f19350505050158015611aa9573d6000803e3d6000fd5b505b5050505092915050565b60095460ff1681565b6001600160a01b031660009081526005602052604090205490565b6008546001600160801b03811690600160801b900463ffffffff1682565b60006001600160801b03821115611b55576040805162461bcd60e51b815260206004820152601c60248201527f426f72696e674d6174683a2075696e74313238204f766572666c6f7700000000604482015290519081900360640190fd5b5090565b600063ffffffff821115611b55576040805162461bcd60e51b815260206004820152601b60248201527f426f72696e674d6174683a2075696e743332204f766572666c6f770000000000604482015290519081900360640190fd5b604080516001600160a01b038481166024830152306044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b178152925182516000946060949389169392918291908083835b60208310611c375780518252601f199092019160209182019101611c18565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611c99576040519150601f19603f3d011682016040523d82523d6000602084013e611c9e565b606091505b5091509150818015611ccc575080511580611ccc5750808060200190516020811015611cc957600080fd5b50515b611d075760405162461bcd60e51b81526004018080602001828103825260248152602001806124936024913960400191505060405180910390fd5b5050505050565b801580611d94575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b158015611d6657600080fd5b505afa158015611d7a573d6000803e3d6000fd5b505050506040513d6020811015611d9057600080fd5b5051155b611dcf5760405162461bcd60e51b81526004018080602001828103825260368152602001806124ea6036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052611e21908490611fe8565b505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b178152925182516000946060949389169392918291908083835b60208310611ea35780518252601f199092019160209182019101611e84565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611f05576040519150601f19603f3d011682016040523d82523d6000602084013e611f0a565b606091505b5091509150818015611f38575080511580611f385750808060200190516020811015611f3557600080fd5b50515b611d07576040805162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c454400604482015290519081900360640190fd5b600067ffffffffffffffff821115611b55576040805162461bcd60e51b815260206004820152601b60248201527f426f72696e674d6174683a2075696e743634204f766572666c6f770000000000604482015290519081900360640190fd5b606061203d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166120999092919063ffffffff16565b805190915015611e215780806020019051602081101561205c57600080fd5b5051611e215760405162461bcd60e51b815260040180806020018281038252602a815260200180612469602a913960400191505060405180910390fd5b60606120a884846000856120b2565b90505b9392505050565b6060824710156120f35760405162461bcd60e51b81526004018080602001828103825260268152602001806122fb6026913960400191505060405180910390fd5b6120fc8561220e565b61214d576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b6020831061218c5780518252601f19909201916020918201910161216d565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146121ee576040519150601f19603f3d011682016040523d82523d6000602084013e6121f3565b606091505b5091509150612203828286612214565b979650505050505050565b3b151590565b606083156122235750816120ab565b8251156122335782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561227d578181015183820152602001612265565b50505050905090810190601f1680156122aa5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b60408051808201909152600080825260208201529056fe494875624c61756e636865723a204661696c656420746f207472616e73666572206d696e696d756d466565416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c494875624c61756e636865723a2053656e646572206d757374206265204f70657261746f72494875624c61756e636865723a204c61756e636865722074656d706c61746520646f65736e2774206578697374494875624c61756e636865723a2053656e646572206d7573742062652061646d696e696e6974494875624c61756e636865723a20616363657373436f6e74726f6c732063616e6e6f742062652073657420746f207a65726f494875624c61756e636865723a2050657263656e74616765206973206f7574206f662031303030494875624c61756e636865723a2053656e646572206d757374206265206d696e746572206966206c6f636b6564494875624c61756e636865723a2053656e646572206d757374206265206f70657261746f72494875624c61756e636865723a20496e636f72726563742074656d706c61746520636f64655361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645472616e7366657248656c7065723a205452414e534645525f46524f4d5f4641494c4544696e6974494875624c61756e636865723a206e657574726f6e537461722063616e6e6f742062652073657420746f207a65726f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a26469706673582212209aab19dc173b6365828537b8b076907937ff496923735a21b21af15030155dad64736f6c634300060c0033