Polygon Sponsored slots available. Book your slot here!
Overview
MATIC Balance
0 MATIC
MATIC Value
$0.00More Info
Private Name Tags
ContractCreator:
Sponsored
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 30360979 | 632 days ago | IN | Create: HandlerReserveUpgradeable | 0 MATIC | 0.23812084 |
Loading...
Loading
Contract Name:
HandlerReserveUpgradeable
Compiler Version
v0.8.2+commit.661d1103
Optimization Enabled:
Yes with 50 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity >=0.8.2; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; import "../interfaces/IWETH.sol"; import "../interfaces/IOneSplitWrap.sol"; import "../ERC20SafeUpgradeable.sol"; import "../interfaces/IEthHandler.sol"; contract HandlerReserveUpgradeable is Initializable, ContextUpgradeable, AccessControlUpgradeable, ERC20SafeUpgradeable { // token lp address => contract address mapping(address => address) public _lpToContract; // token contract address => lp address mapping(address => address) public _contractToLP; //Middleman for handling eth (Istanbul fix) IEthHandler private _ethHandler; function __HandlerReserveUpgradeable_init(address handler) internal initializer { __Context_init_unchained(); __AccessControl_init(); __ERC20SafeUpgradeable_init(); _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); _setupRole(ERC20HANDLER_ROLE, handler); } function __HandlerReserveUpgradeable_init_unchained() internal initializer {} function initialize(address handler) external initializer { __HandlerReserveUpgradeable_init(handler); } receive() external payable {} /// @dev Set the address of the ethHandler contract. function setEthHandler(IEthHandler ethHandler) external onlyRole(DEFAULT_ADMIN_ROLE) { _ethHandler = ethHandler; } function deductFee( address feeTokenAddress, address depositor, uint256 requiredFee, bool _isFeeEnabled, address _feeManager ) external onlyRole(ERC20HANDLER_ROLE) { if (requiredFee > 0 && _isFeeEnabled) { lockERC20(feeTokenAddress, depositor, _feeManager, requiredFee); } } function mintWrappedERC20( address tokenAddress, address recipient, uint256 amount ) public onlyRole(ERC20HANDLER_ROLE) { require(_contractToLP[tokenAddress] != address(0), "ERC20Handler: Liquidity pool not found"); mintERC20(_contractToLP[tokenAddress], recipient, amount); } function stake( address depositor, address tokenAddress, uint256 amount ) external virtual onlyRole(ERC20HANDLER_ROLE) { require(_contractToLP[tokenAddress] != address(0), "ERC20Handler: Liquidity pool not created"); lockERC20(tokenAddress, depositor, address(this), amount); mintERC20(_contractToLP[tokenAddress], depositor, amount); } function stakeETH( address depositor, address tokenAddress, uint256 amount ) external virtual onlyRole(ERC20HANDLER_ROLE) { require(_contractToLP[tokenAddress] != address(0), "ERC20Handler: Liquidity pool not created"); mintERC20(_contractToLP[tokenAddress], depositor, amount); } /** @notice Staking should be done by using bridge contract. @param unstaker removes liquidity from the pool. @param tokenAddress staking token of which liquidity needs to be removed. @param amount Amount that needs to be unstaked. */ function unstake( address unstaker, address tokenAddress, uint256 amount ) external virtual onlyRole(ERC20HANDLER_ROLE) { require(_contractToLP[tokenAddress] != address(0), "ERC20Handler: Liquidity pool not created"); burnERC20(_contractToLP[tokenAddress], unstaker, amount); releaseERC20(tokenAddress, unstaker, amount); } function unstakeETH( address unstaker, address tokenAddress, uint256 amount, address WETH ) external virtual onlyRole(ERC20HANDLER_ROLE) { require(_contractToLP[tokenAddress] != address(0), "ERC20Handler: Liquidity pool not created"); burnERC20(_contractToLP[tokenAddress], unstaker, amount); IWETH(WETH).transfer(address(_ethHandler), amount); _ethHandler.withdraw(WETH, amount); safeTransferETH(unstaker, amount); } function getStakedRecord(address account, address tokenAddress) external view virtual returns (uint256) { if(_contractToLP[tokenAddress] != address(0)){ return RouterERC20Upgradable(_contractToLP[tokenAddress]).balanceOf(account); } return 0; } function withdrawWETH(address WETH, uint256 amount) external onlyRole(ERC20HANDLER_ROLE) { IWETH(WETH).transfer(address(_ethHandler), amount); _ethHandler.withdraw(WETH, amount); } function _setLiquidityPoolOwner( address newOwner, address tokenAddress, address lpAddress ) external virtual onlyRole(ERC20HANDLER_ROLE) { require(newOwner != address(0), "ERC20Handler: new owner cannot be null"); require(tokenAddress != address(0), "ERC20Handler: tokenAddress cannot be null"); require(lpAddress != address(0), "ERC20Handler: lpAddress cannot be null"); RouterERC20Upgradable token = RouterERC20Upgradable(lpAddress); _lpToContract[lpAddress] = tokenAddress; _contractToLP[tokenAddress] = lpAddress; token.grantRole(DEFAULT_ADMIN_ROLE, newOwner); } function _setLiquidityPool( string memory name, string memory symbol, uint8 decimals, address contractAddress, address lpAddress ) external virtual onlyRole(ERC20HANDLER_ROLE) returns (address) { require(_contractToLP[contractAddress] == address(0), "ERC20Handler: pool already deployed"); address newLPAddress; if (lpAddress == address(0)) { //TODO Why we need upgradeable here ? RouterERC20Upgradable newLPAddr = new RouterERC20Upgradable(name, symbol, decimals); // newLPAddr.initialize(name, symbol, decimals); newLPAddress = address(newLPAddr); } else { newLPAddress = lpAddress; } _lpToContract[newLPAddress] = contractAddress; _contractToLP[contractAddress] = newLPAddress; return newLPAddress; } function resetLP( address contractAddress, address lpAddress ) external virtual onlyRole(DEFAULT_ADMIN_ROLE) { _lpToContract[lpAddress] = address(0); _contractToLP[contractAddress] = address(0); } function swap( address oneSplitAddress, address fromToken, address destToken, uint256 amount, uint256 minReturn, uint256 flags, bytes memory dataTx ) external onlyRole(ERC20HANDLER_ROLE) returns (uint256 returnAmount) { IOneSplitWrap oneSplitWrap = IOneSplitWrap(oneSplitAddress); returnAmount = oneSplitWrap.swap(fromToken, destToken, amount, minReturn, flags, dataTx, true); return returnAmount; } function swapMulti( address oneSplitAddress, address[] memory tokens, uint256 amount, uint256 minReturn, uint256[] memory flags, bytes[] memory dataTx ) external onlyRole(ERC20HANDLER_ROLE) returns (uint256 returnAmount) { IOneSplitWrap oneSplitWrap = IOneSplitWrap(oneSplitAddress); returnAmount = oneSplitWrap.swapMulti(tokens, amount, minReturn, flags, dataTx, true); return returnAmount; } function getExpectedReturn( address oneSplitAddress, address fromToken, address toToken, uint256 amount, uint256 parts, uint256 flags ) public view virtual returns (uint256 returnAmount, uint256[] memory distribution) { IOneSplitWrap oneSplitWrap = IOneSplitWrap(oneSplitAddress); return oneSplitWrap.getExpectedReturn(fromToken, toToken, amount, parts, flags); } function getExpectedReturnWithGas( address oneSplitAddress, address fromToken, address toToken, uint256 amount, uint256 parts, uint256 flags, uint256 toTokenEthPriceTimesGasPrice ) public view virtual returns ( uint256 returnAmount, uint256 estimateGasAmount, uint256[] memory distribution ) { IOneSplitWrap oneSplitWrap = IOneSplitWrap(oneSplitAddress); return oneSplitWrap.getExpectedReturnWithGas( fromToken, toToken, amount, parts, flags, toTokenEthPriceTimesGasPrice ); } function getExpectedReturnWithGasMulti( address oneSplitAddress, address[] memory tokens, uint256 amount, uint256[] memory parts, uint256[] memory flags, uint256[] memory destTokenEthPriceTimesGasPrices ) public view virtual returns ( uint256[] memory returnAmounts, uint256 estimateGasAmount, uint256[] memory distribution ) { IOneSplitWrap oneSplitWrap = IOneSplitWrap(oneSplitAddress); return oneSplitWrap.getExpectedReturnWithGasMulti(tokens, amount, parts, flags, destTokenEthPriceTimesGasPrices); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol) pragma solidity ^0.8.0; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() initializer {} * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { // If the contract is initializing we ignore whether _initialized is set in order to support multiple // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the // contract may have been reentered. require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} modifier, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @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 ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { __Context_init_unchained(); } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControlUpgradeable.sol"; import "../utils/ContextUpgradeable.sol"; import "../utils/StringsUpgradeable.sol"; import "../utils/introspection/ERC165Upgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * 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 AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable { function __AccessControl_init() internal onlyInitializing { __Context_init_unchained(); __ERC165_init_unchained(); __AccessControl_init_unchained(); } function __AccessControl_init_unchained() internal onlyInitializing { } struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role, _msgSender()); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", StringsUpgradeable.toHexString(uint160(account), 20), " is missing role ", StringsUpgradeable.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.2; interface IWETH { function deposit() external payable; function transfer(address to, uint256 value) external returns (bool); function withdraw(uint256) external; function transferFrom( address src, address dst, uint256 wad ) external returns (bool); function approve(address guy, uint256 wad) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.2; interface IOneSplitWrap { function withdraw( address tokenAddress, address recipient, uint256 amount ) external returns (bool); function getExpectedReturn( address fromToken, address destToken, uint256 amount, uint256 parts, uint256 flags ) external view returns (uint256 returnAmount, uint256[] memory distribution); function getExpectedReturnWithGas( address fromToken, address destToken, uint256 amount, uint256 parts, uint256 flags, uint256 destTokenEthPriceTimesGasPrice ) external view returns ( uint256 returnAmount, uint256 estimateGasAmount, uint256[] memory distribution ); function getExpectedReturnWithGasMulti( address[] memory tokens, uint256 amount, uint256[] memory parts, uint256[] memory flags, uint256[] memory destTokenEthPriceTimesGasPrices ) external view returns ( uint256[] memory returnAmounts, uint256 estimateGasAmount, uint256[] memory distribution ); function swap( address fromToken, address destToken, uint256 amount, uint256 minReturn, uint256 flags, bytes memory dataTx, bool isWrapper ) external payable returns (uint256 returnAmount); function swapMulti( address[] memory tokens, uint256 amount, uint256 minReturn, uint256[] memory flags, bytes[] memory dataTx, bool isWrapper ) external payable returns (uint256 returnAmount); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.2; // import "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import "./RouterERC20Upgradable.sol"; /** @title Manages deposited ERC20s. @author Router Protocol. @notice This contract is intended to be used with ERC20Handler contract. */ contract ERC20SafeUpgradeable is Initializable, ContextUpgradeable, AccessControlUpgradeable { // using SafeCastUpgradeable for *; using AddressUpgradeable for address; bytes32 public constant ERC20HANDLER_ROLE = keccak256("ERC20HANDLER_ROLE"); function __ERC20SafeUpgradeable_init() internal initializer { __Context_init_unchained(); __AccessControl_init_unchained(); } function __ERC20SafeUpgradeable_init_unchained() internal initializer {} /** @notice Used to transfer tokens into the safe to fund proposals. @param tokenAddress Address of ERC20 to transfer. @param owner Address of current token owner. @param amount Amount of tokens to transfer. */ function fundERC20( address tokenAddress, address owner, uint256 amount ) public onlyRole(ERC20HANDLER_ROLE) { IERC20Upgradeable erc20 = IERC20Upgradeable(tokenAddress); _safeTransferFrom(erc20, owner, address(this), amount); } /** @notice Used to gain custody of deposited token. @param tokenAddress Address of ERC20 to transfer. @param owner Address of current token owner. @param recipient Address to transfer tokens to. @param amount Amount of tokens to transfer. */ function lockERC20( address tokenAddress, address owner, address recipient, uint256 amount ) public onlyRole(ERC20HANDLER_ROLE) { IERC20Upgradeable erc20 = IERC20Upgradeable(tokenAddress); _safeTransferFrom(erc20, owner, recipient, amount); } /** @notice Transfers custody of token to recipient. @param tokenAddress Address of ERC20 to transfer. @param recipient Address to transfer tokens to. @param amount Amount of tokens to transfer. */ function releaseERC20( address tokenAddress, address recipient, uint256 amount ) public onlyRole(ERC20HANDLER_ROLE) { IERC20Upgradeable erc20 = IERC20Upgradeable(tokenAddress); _safeTransfer(erc20, recipient, amount); } /** @notice Used to create new ERC20s. @param tokenAddress Address of ERC20 to transfer. @param recipient Address to mint token to. @param amount Amount of token to mint. */ function mintERC20( address tokenAddress, address recipient, uint256 amount ) public onlyRole(ERC20HANDLER_ROLE) { bytes memory data = abi.encodeWithSelector(0x40c10f19, recipient, amount); //mint(address,uint256) bytes memory returndata = tokenAddress.functionCall(data, "SafeERC20: low-level mint call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } /** @notice Used to burn ERC20s. @param tokenAddress Address of ERC20 to burn. @param owner Current owner of tokens. @param amount Amount of tokens to burn. */ function burnERC20( address tokenAddress, address owner, uint256 amount ) public onlyRole(ERC20HANDLER_ROLE) { bytes memory data = abi.encodeWithSelector(0x9dc29fac, owner, amount); //burn(address,uint256) bytes memory returndata = tokenAddress.functionCall(data, "SafeERC20: low-level burn call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } /** @notice used to transfer ERC20s safely @param token Token instance to transfer @param to Address to transfer token to @param value Amount of token to transfer */ function _safeTransfer( IERC20Upgradeable token, address to, uint256 value ) internal { _safeCall(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** @notice used to transfer ERC20s safely @param token Token instance to transfer @param from Address to transfer token from @param to Address to transfer token to @param value Amount of token to transfer */ function _safeTransferFrom( IERC20Upgradeable token, address from, address to, uint256 value ) internal { _safeCall(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** @notice used to make calls to ERC20s safely @param token Token instance call targets @param data encoded call data */ function _safeCall(IERC20Upgradeable token, bytes memory data) internal { bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } function safeTransferETH(address to, uint256 value) public onlyRole(ERC20HANDLER_ROLE) { require(to != address(0), "safeTransferETH: transfer to address 0"); (bool success, ) = to.call{ value: value }(new bytes(0)); require(success, "safeTransferETH: ETH transfer failed"); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.2; interface IEthHandler { function withdraw(address WETH, uint256) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Address.sol) pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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; assembly { 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 * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControlUpgradeable { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library StringsUpgradeable { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165Upgradeable.sol"; import "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal onlyInitializing { __ERC165_init_unchained(); } function __ERC165_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.2; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; contract RouterERC20Upgradable is Initializable, ContextUpgradeable, AccessControlUpgradeable, PausableUpgradeable, ERC20Upgradeable { using AddressUpgradeable for address; bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE"); bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); uint8 private _decimals; // Upgradable Functions // function initialize( // string memory name_, // string memory symbol_, // uint8 decimals_ // ) external initializer { // __RouterERC20Upgradable_init(name_, symbol_, decimals_); // } constructor( string memory name_, string memory symbol_, uint8 decimals_ ) { __RouterERC20Upgradable_init(name_, symbol_, decimals_); } /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ function __RouterERC20Upgradable_init( string memory name_, string memory symbol_, uint8 decimals_ ) internal initializer { __Context_init_unchained(); __AccessControl_init(); __Pausable_init(); __ERC20_init_unchained(name_, symbol_); __RouterERC20Upgradable_init_unchained(); _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); _setDecimals(decimals_); _setupRole(MINTER_ROLE, _msgSender()); _setupRole(BURNER_ROLE, _msgSender()); _setupRole(PAUSER_ROLE, _msgSender()); } function __RouterERC20Upgradable_init_unchained() internal initializer {} // Upgradable Functions //Core Contract Functions function _setDecimals(uint8 decimal) internal virtual { _decimals = decimal; } function decimals() public view virtual override returns (uint8) { return _decimals; } function pauseToken() public virtual onlyRole(PAUSER_ROLE) returns (bool) { _pause(); return true; } function unpauseToken() public virtual onlyRole(PAUSER_ROLE) returns (bool) { _unpause(); return true; } function mint(address _to, uint256 _value) public virtual onlyRole(MINTER_ROLE) returns (bool) { _mint(_to, _value); return true; } function burn(address _from, uint256 _value) public virtual onlyRole(BURNER_ROLE) returns (bool) { _burn(_from, _value); return true; } /** * @dev See {ERC20-_beforeTokenTransfer}. * * Requirements: * * - the contract must not be paused. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual override { super._beforeTokenTransfer(from, to, amount); require(!paused(), "ERC20Pausable: token transfer while paused"); } //Core Contract Functions }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "./IERC20Upgradeable.sol"; import "./extensions/IERC20MetadataUpgradeable.sol"; import "../../utils/ContextUpgradeable.sol"; import "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing { __Context_init_unchained(); __ERC20_init_unchained(name_, symbol_); } function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, _msgSender(), currentAllowance - amount); } return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(_msgSender(), spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[sender] = senderBalance - amount; } _balances[recipient] += amount; emit Transfer(sender, recipient, amount); _afterTokenTransfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} uint256[45] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __Context_init_unchained(); __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20Upgradeable.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20MetadataUpgradeable is IERC20Upgradeable { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
{ "evmVersion": "berlin", "metadata": { "bytecodeHash": "none", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 50 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERC20HANDLER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_contractToLP","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_lpToContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"address","name":"lpAddress","type":"address"}],"name":"_setLiquidityPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"lpAddress","type":"address"}],"name":"_setLiquidityPoolOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"feeTokenAddress","type":"address"},{"internalType":"address","name":"depositor","type":"address"},{"internalType":"uint256","name":"requiredFee","type":"uint256"},{"internalType":"bool","name":"_isFeeEnabled","type":"bool"},{"internalType":"address","name":"_feeManager","type":"address"}],"name":"deductFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"fundERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"oneSplitAddress","type":"address"},{"internalType":"address","name":"fromToken","type":"address"},{"internalType":"address","name":"toToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"parts","type":"uint256"},{"internalType":"uint256","name":"flags","type":"uint256"}],"name":"getExpectedReturn","outputs":[{"internalType":"uint256","name":"returnAmount","type":"uint256"},{"internalType":"uint256[]","name":"distribution","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"oneSplitAddress","type":"address"},{"internalType":"address","name":"fromToken","type":"address"},{"internalType":"address","name":"toToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"parts","type":"uint256"},{"internalType":"uint256","name":"flags","type":"uint256"},{"internalType":"uint256","name":"toTokenEthPriceTimesGasPrice","type":"uint256"}],"name":"getExpectedReturnWithGas","outputs":[{"internalType":"uint256","name":"returnAmount","type":"uint256"},{"internalType":"uint256","name":"estimateGasAmount","type":"uint256"},{"internalType":"uint256[]","name":"distribution","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"oneSplitAddress","type":"address"},{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256[]","name":"parts","type":"uint256[]"},{"internalType":"uint256[]","name":"flags","type":"uint256[]"},{"internalType":"uint256[]","name":"destTokenEthPriceTimesGasPrices","type":"uint256[]"}],"name":"getExpectedReturnWithGasMulti","outputs":[{"internalType":"uint256[]","name":"returnAmounts","type":"uint256[]"},{"internalType":"uint256","name":"estimateGasAmount","type":"uint256"},{"internalType":"uint256[]","name":"distribution","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"getStakedRecord","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"handler","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"lockERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mintERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mintWrappedERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"releaseERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"address","name":"lpAddress","type":"address"}],"name":"resetLP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"safeTransferETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IEthHandler","name":"ethHandler","type":"address"}],"name":"setEthHandler","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"depositor","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"depositor","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stakeETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"oneSplitAddress","type":"address"},{"internalType":"address","name":"fromToken","type":"address"},{"internalType":"address","name":"destToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minReturn","type":"uint256"},{"internalType":"uint256","name":"flags","type":"uint256"},{"internalType":"bytes","name":"dataTx","type":"bytes"}],"name":"swap","outputs":[{"internalType":"uint256","name":"returnAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"oneSplitAddress","type":"address"},{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minReturn","type":"uint256"},{"internalType":"uint256[]","name":"flags","type":"uint256[]"},{"internalType":"bytes[]","name":"dataTx","type":"bytes[]"}],"name":"swapMulti","outputs":[{"internalType":"uint256","name":"returnAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"unstaker","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"unstaker","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"WETH","type":"address"}],"name":"unstakeETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"WETH","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawWETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405234801561001057600080fd5b50614e3f806100206000396000f3fe608060405260043610620001e75760003560e01c806360829f8a1162000103578063aa50ec12116200009d578063aa50ec12146200060e578063ad527b211462000648578063bf6eac2f146200066d578063c4d66de81462000692578063d547741f14620006b7578063da041a8514620006dc578063dc9655821462000701578063f19457251462000726578063f4e480e1146200074b57620001ef565b806360829f8a14620004f45780636cd533d814620005195780636f8d52d3146200053e5780637c4368c1146200056357806391d14854146200058857806393113b5c14620005ad57806395601f0914620005d2578063a217fddf14620005f757620001ef565b806336568abe116200018157806336568abe14620003515780633826c40214620003765780633c94d19e14620003ac57806347c07e8814620003e0578063494082ff14620004055780634ab81254146200043a5780634c62b25714620004705780635739ac7a14620004955780635fae924514620004ba57620001ef565b806301ffc9a714620001f457806304a1d7f9146200022e5780631d27af6814620002555780632214e13b146200027a578063248a9ca314620002ae5780632dd35dae14620002e25780632f2ff15d146200030757806334de0af4146200032c57620001ef565b36620001ef57005b600080fd5b3480156200020157600080fd5b506200021962000213366004620029bc565b62000770565b60405190151581526020015b60405180910390f35b3480156200023b57600080fd5b50620002536200024d36600462002677565b620007aa565b005b3480156200026257600080fd5b506200025362000274366004620025d9565b620007f1565b3480156200028757600080fd5b506200029f62000299366004620027b6565b620008d3565b60405190815260200162000225565b348015620002bb57600080fd5b506200029f620002cd3660046200297c565b60009081526065602052604090206001015490565b348015620002ef57600080fd5b506200025362000301366004620023b9565b6200098f565b3480156200031457600080fd5b50620002536200032636600462002995565b62000b8b565b3480156200033957600080fd5b506200029f60008051602062004dee83398151915281565b3480156200035e57600080fd5b50620002536200037036600462002995565b62000bba565b3480156200038357600080fd5b506200039b62000395366004620026e7565b62000c3c565b604051620002259392919062002dd6565b348015620003b957600080fd5b50620003d1620003cb366004620029e6565b62000ce7565b60405162000225919062002c4e565b348015620003ed57600080fd5b5062000253620003ff366004620025d9565b62000e27565b3480156200041257600080fd5b506200042a6200042436600462002461565b62000ec0565b6040516200022592919062002f8c565b3480156200044757600080fd5b506200045f6200045936600462002565565b62000f77565b604051620002259392919062002fa7565b3480156200047d57600080fd5b50620002536200048f3660046200240a565b6200103a565b348015620004a257600080fd5b5062000253620004b4366004620025d9565b62001065565b348015620004c757600080fd5b50620003d1620004d93660046200235d565b6098602052600090815260409020546001600160a01b031681565b3480156200050157600080fd5b506200025362000513366004620025d9565b62001127565b3480156200052657600080fd5b506200025362000538366004620025d9565b620011ad565b3480156200054b57600080fd5b50620002536200055d3660046200235d565b620011de565b3480156200057057600080fd5b506200025362000582366004620028bf565b6200120f565b3480156200059557600080fd5b5062000219620005a736600462002995565b62001361565b348015620005ba57600080fd5b5062000253620005cc366004620028bf565b6200138e565b348015620005df57600080fd5b5062000253620005f1366004620025d9565b620014a4565b3480156200060457600080fd5b506200029f600081565b3480156200061b57600080fd5b50620003d16200062d3660046200235d565b6097602052600090815260409020546001600160a01b031681565b3480156200065557600080fd5b506200029f620006673660046200237c565b620014cf565b3480156200067a57600080fd5b50620002536200068c366004620025d9565b62001598565b3480156200069f57600080fd5b5062000253620006b13660046200235d565b62001624565b348015620006c457600080fd5b5062000253620006d636600462002995565b620016b1565b348015620006e957600080fd5b506200029f620006fb366004620024cc565b620016db565b3480156200070e57600080fd5b5062000253620007203660046200261e565b6200179a565b3480156200073357600080fd5b5062000253620007453660046200237c565b62001919565b3480156200075857600080fd5b50620002536200076a366004620025d9565b62001969565b60006001600160e01b03198216637965db0b60e01b1480620007a257506301ffc9a760e01b6001600160e01b03198316145b90505b919050565b60008051602062004dee833981519152620007c781335b620019bf565b600084118015620007d55750825b15620007e957620007e9868684876200103a565b505050505050565b60008051602062004dee8339815191526200080d8133620007c1565b6000639dc29fac84846040516024016200082992919062002cb7565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050905060006200088a8260405180606001604052806025815260200162004e0e602591396001600160a01b038916919062001a2e565b805190915015620007e95780806020019051810190620008ab91906200295d565b620007e95760405162461bcd60e51b8152600401620008ca9062002f42565b60405180910390fd5b600060008051602062004dee833981519152620008f18133620007c1565b60405163d835b06960e01b815288906001600160a01b0382169063d835b069906200092c908b908b908b908b908b9060019060040162002d37565b602060405180830381600087803b1580156200094757600080fd5b505af11580156200095c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000982919062002a71565b9998505050505050505050565b60008051602062004dee833981519152620009ab8133620007c1565b6001600160a01b03841662000a125760405162461bcd60e51b815260206004820152602660248201527f455243323048616e646c65723a206e6577206f776e65722063616e6e6f74206260448201526519481b9d5b1b60d21b6064820152608401620008ca565b6001600160a01b03831662000a7c5760405162461bcd60e51b815260206004820152602960248201527f455243323048616e646c65723a20746f6b656e416464726573732063616e6e6f6044820152681d081899481b9d5b1b60ba1b6064820152608401620008ca565b6001600160a01b03821662000ae35760405162461bcd60e51b815260206004820152602660248201527f455243323048616e646c65723a206c70416464726573732063616e6e6f74206260448201526519481b9d5b1b60d21b6064820152608401620008ca565b6001600160a01b03828116600081815260976020908152604080832080548987166001600160a01b0319918216811790925590845260989092528083208054909216841790915551632f2ff15d60e01b8152600481019190915291861660248301528391632f2ff15d90604401600060405180830381600087803b15801562000b6b57600080fd5b505af115801562000b80573d6000803e3d6000fd5b505050505050505050565b60008281526065602052604090206001015462000ba98133620007c1565b62000bb5838362001a49565b505050565b6001600160a01b038116331462000c2c5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401620008ca565b62000c38828262001ad3565b5050565b604051633d99b80d60e11b8152606090600090829089906001600160a01b03821690637b33701a9062000c7c908c908c908c908c908c9060040162002cd0565b60006040518083038186803b15801562000c9557600080fd5b505afa15801562000caa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000cd49190810190620028ed565b9350935093505096509650969350505050565b600060008051602062004dee83398151915262000d058133620007c1565b6001600160a01b03848116600090815260986020526040902054161562000d7b5760405162461bcd60e51b815260206004820152602360248201527f455243323048616e646c65723a20706f6f6c20616c7265616479206465706c6f6044820152621e595960ea1b6064820152608401620008ca565b60006001600160a01b03841662000dd557600088888860405162000d9f9062002190565b62000dad9392919062002e24565b604051809103906000f08015801562000dca573d6000803e3d6000fd5b50915062000dd89050565b50825b6001600160a01b0380821660008181526097602090815260408083208054958b166001600160a01b03199687168117909155835260989091529020805490921617905591505095945050505050565b60008051602062004dee83398151915262000e438133620007c1565b60006340c10f19848460405160240162000e5f92919062002cb7565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050905060006200088a8260405180606001604052806025815260200162004dc9602591396001600160a01b038916919062001a2e565b60405163085e2c5b60e01b81526001600160a01b038681166004830152858116602483015260448201859052606482018490526084820183905260009160609189919082169063085e2c5b9060a40160006040518083038186803b15801562000f2857600080fd5b505afa15801562000f3d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000f67919081019062002a8a565b9250925050965096945050505050565b604051638373f26560e01b81526001600160a01b038781166004830152868116602483015260448201869052606482018590526084820184905260a4820183905260009182916060918b91821690638373f2659060c40160006040518083038186803b15801562000fe757600080fd5b505afa15801562000ffc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262001026919081019062002ad2565b935093509350509750975097945050505050565b60008051602062004dee833981519152620010568133620007c1565b84620007e98186868662001b3d565b60008051602062004dee833981519152620010818133620007c1565b6001600160a01b0384811660009081526098602052604090205416620010f95760405162461bcd60e51b815260206004820152602660248201527f455243323048616e646c65723a204c697175696469747920706f6f6c206e6f7460448201526508199bdd5b9960d21b6064820152608401620008ca565b6001600160a01b03808516600090815260986020526040902054620011219116848462000e27565b50505050565b60008051602062004dee833981519152620011438133620007c1565b6001600160a01b03838116600090815260986020526040902054166200117d5760405162461bcd60e51b8152600401620008ca9062002e61565b6001600160a01b03808416600090815260986020526040902054620011a591168584620007f1565b620011218385845b60008051602062004dee833981519152620011c98133620007c1565b83620011d781858562001baa565b5050505050565b6000620011ec8133620007c1565b50609980546001600160a01b0319166001600160a01b0392909216919091179055565b60008051602062004dee8339815191526200122b8133620007c1565b6001600160a01b038316620012925760405162461bcd60e51b815260206004820152602660248201527f736166655472616e736665724554483a207472616e7366657220746f2061646460448201526507265737320360d41b6064820152608401620008ca565b604080516000808252602082019092526001600160a01b038516908490604051620012be919062002bbd565b60006040518083038185875af1925050503d8060008114620012fd576040519150601f19603f3d011682016040523d82523d6000602084013e62001302565b606091505b5050905080620011215760405162461bcd60e51b8152602060048201526024808201527f736166655472616e736665724554483a20455448207472616e736665722066616044820152631a5b195960e21b6064820152608401620008ca565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff165b92915050565b60008051602062004dee833981519152620013aa8133620007c1565b60995460405163a9059cbb60e01b81526001600160a01b038581169263a9059cbb92620013e09290911690869060040162002cb7565b602060405180830381600087803b158015620013fb57600080fd5b505af115801562001410573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200143691906200295d565b5060995460405163f3fef3a360e01b81526001600160a01b039091169063f3fef3a3906200146b908690869060040162002cb7565b600060405180830381600087803b1580156200148657600080fd5b505af11580156200149b573d6000803e3d6000fd5b50505050505050565b60008051602062004dee833981519152620014c08133620007c1565b83620011d78185308662001b3d565b6001600160a01b03818116600090815260986020526040812054909116156200158f576001600160a01b03808316600090815260986020526040908190205490516370a0823160e01b81529116906370a08231906200153390869060040162002c4e565b60206040518083038186803b1580156200154c57600080fd5b505afa15801562001561573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001587919062002a71565b905062001388565b50600092915050565b60008051602062004dee833981519152620015b48133620007c1565b6001600160a01b0383811660009081526098602052604090205416620015ee5760405162461bcd60e51b8152600401620008ca9062002e61565b620015fc838530856200103a565b6001600160a01b03808416600090815260986020526040902054620011219116858462000e27565b600054610100900460ff16620016415760005460ff161562001645565b303b155b620016645760405162461bcd60e51b8152600401620008ca9062002ea9565b600054610100900460ff1615801562001690576000805460ff1961ff0019909116610100171660011790555b6200169b8262001bcc565b801562000c38576000805461ff00191690555050565b600082815260656020526040902060010154620016cf8133620007c1565b62000bb5838362001ad3565b600060008051602062004dee833981519152620016f98133620007c1565b6040516333e2977f60e11b815289906001600160a01b038216906367c52efe9062001736908c908c908c908c908c908c9060019060040162002c62565b602060405180830381600087803b1580156200175157600080fd5b505af115801562001766573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200178c919062002a71565b9a9950505050505050505050565b60008051602062004dee833981519152620017b68133620007c1565b6001600160a01b0384811660009081526098602052604090205416620017f05760405162461bcd60e51b8152600401620008ca9062002e61565b6001600160a01b038085166000908152609860205260409020546200181891168685620007f1565b60995460405163a9059cbb60e01b81526001600160a01b038481169263a9059cbb926200184e9290911690879060040162002cb7565b602060405180830381600087803b1580156200186957600080fd5b505af11580156200187e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018a491906200295d565b5060995460405163f3fef3a360e01b81526001600160a01b039091169063f3fef3a390620018d9908590879060040162002cb7565b600060405180830381600087803b158015620018f457600080fd5b505af115801562001909573d6000803e3d6000fd5b50505050620011d785846200120f565b6000620019278133620007c1565b506001600160a01b03908116600090815260976020908152604080832080546001600160a01b0319908116909155949093168252609890522080549091169055565b60008051602062004dee833981519152620019858133620007c1565b6001600160a01b0383811660009081526098602052604090205416620015fc5760405162461bcd60e51b8152600401620008ca9062002e61565b620019cb828262001361565b62000c3857620019e6816001600160a01b0316601462001c7e565b620019f383602062001c7e565b60405160200162001a0692919062002bdb565b60408051601f198184030181529082905262461bcd60e51b8252620008ca9160040162002e0f565b606062001a3f848460008562001e73565b90505b9392505050565b62001a55828262001361565b62000c385760008281526065602090815260408083206001600160a01b03851684529091529020805460ff1916600117905562001a8f3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b62001adf828262001361565b1562000c385760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6040516001600160a01b0380851660248301528316604482015260648101829052620011219085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915262001fa5565b62000bb58363a9059cbb60e01b848460405160240162001b7292919062002cb7565b600054610100900460ff1662001be95760005460ff161562001bed565b303b155b62001c0c5760405162461bcd60e51b8152600401620008ca9062002ea9565b600054610100900460ff1615801562001c38576000805460ff1961ff0019909116610100171660011790555b62001c426200203c565b62001c4c62002068565b62001c56620020b0565b62001c6360003362002146565b6200169b60008051602062004dee8339815191528362002146565b6060600062001c8f83600262003045565b62001c9c9060026200302a565b6001600160401b0381111562001cc257634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801562001ced576020820181803683370190505b509050600360fc1b8160008151811062001d1757634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811062001d5557634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600062001d7b84600262003045565b62001d889060016200302a565b90505b600181111562001e22576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811062001dcc57634e487b7160e01b600052603260045260246000fd5b1a60f81b82828151811062001df157634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c9362001e1a8162003096565b905062001d8b565b50831562001a425760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401620008ca565b60608247101562001ed65760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401620008ca565b843b62001f265760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401620008ca565b600080866001600160a01b0316858760405162001f44919062002bbd565b60006040518083038185875af1925050503d806000811462001f83576040519150601f19603f3d011682016040523d82523d6000602084013e62001f88565b606091505b509150915062001f9a82828662002152565b979650505050505050565b600062001ffc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031662001a2e9092919063ffffffff16565b80519091501562000bb557808060200190518101906200201d91906200295d565b62000bb55760405162461bcd60e51b8152600401620008ca9062002f42565b600054610100900460ff16620020665760405162461bcd60e51b8152600401620008ca9062002ef7565b565b600054610100900460ff16620020925760405162461bcd60e51b8152600401620008ca9062002ef7565b6200209c6200203c565b620020a66200203c565b620020666200203c565b600054610100900460ff16620020cd5760005460ff1615620020d1565b303b155b620020f05760405162461bcd60e51b8152600401620008ca9062002ea9565b600054610100900460ff161580156200211c576000805460ff1961ff0019909116610100171660011790555b620021266200203c565b620021306200203c565b801562002143576000805461ff00191690555b50565b62000c38828262001a49565b606083156200216357508162001a42565b825115620021745782518084602001fd5b8160405162461bcd60e51b8152600401620008ca919062002e0f565b611cc7806200310283390190565b8035620007a581620030dc565b600082601f830112620021bc578081fd5b81356020620021d5620021cf8362003004565b62002fd1565b8281528181019085830183850287018401881015620021f2578586fd5b855b858110156200221d5781356200220a81620030dc565b84529284019290840190600101620021f4565b5090979650505050505050565b600082601f8301126200223b578081fd5b813560206200224e620021cf8362003004565b82815281810190858301838502870184018810156200226b578586fd5b855b858110156200221d578135845292840192908401906001016200226d565b600082601f8301126200229c578081fd5b81516020620022af620021cf8362003004565b8281528181019085830183850287018401881015620022cc578586fd5b855b858110156200221d57815184529284019290840190600101620022ce565b600082601f830112620022fd578081fd5b81356001600160401b03811115620023195762002319620030c6565b6200232e601f8201601f191660200162002fd1565b81815284602083860101111562002343578283fd5b816020850160208301379081016020019190915292915050565b6000602082840312156200236f578081fd5b813562001a4281620030dc565b600080604083850312156200238f578081fd5b82356200239c81620030dc565b91506020830135620023ae81620030dc565b809150509250929050565b600080600060608486031215620023ce578081fd5b8335620023db81620030dc565b92506020840135620023ed81620030dc565b91506040840135620023ff81620030dc565b809150509250925092565b6000806000806080858703121562002420578182fd5b84356200242d81620030dc565b935060208501356200243f81620030dc565b925060408501356200245181620030dc565b9396929550929360600135925050565b60008060008060008060c087890312156200247a578384fd5b86356200248781620030dc565b955060208701356200249981620030dc565b94506040870135620024ab81620030dc565b959894975094956060810135955060808101359460a0909101359350915050565b600080600080600080600060e0888a031215620024e7578485fd5b8735620024f481620030dc565b965060208801356200250681620030dc565b955060408801356200251881620030dc565b9450606088013593506080880135925060a0880135915060c08801356001600160401b0381111562002548578182fd5b620025568a828b01620022ec565b91505092959891949750929550565b600080600080600080600060e0888a03121562002580578081fd5b87356200258d81620030dc565b965060208801356200259f81620030dc565b95506040880135620025b181620030dc565b969995985095966060810135965060808101359560a0820135955060c0909101359350915050565b600080600060608486031215620025ee578081fd5b8335620025fb81620030dc565b925060208401356200260d81620030dc565b929592945050506040919091013590565b6000806000806080858703121562002634578182fd5b84356200264181620030dc565b935060208501356200265381620030dc565b92506040850135915060608501356200266c81620030dc565b939692955090935050565b600080600080600060a086880312156200268f578283fd5b85356200269c81620030dc565b94506020860135620026ae81620030dc565b9350604086013592506060860135620026c781620030f2565b91506080860135620026d981620030dc565b809150509295509295909350565b60008060008060008060c0878903121562002700578384fd5b6200270b876200219e565b955060208701356001600160401b038082111562002727578586fd5b620027358a838b01620021ab565b965060408901359550606089013591508082111562002752578384fd5b620027608a838b016200222a565b9450608089013591508082111562002776578384fd5b620027848a838b016200222a565b935060a08901359150808211156200279a578283fd5b50620027a989828a016200222a565b9150509295509295509295565b60008060008060008060c08789031215620027cf578384fd5b8635620027dc81620030dc565b95506020878101356001600160401b0380821115620027f9578687fd5b620028078b838c01620021ab565b975060408a0135965060608a0135955060808a01359150808211156200282b578485fd5b620028398b838c016200222a565b945060a08a01359150808211156200284f578384fd5b508801601f81018a1362002861578283fd5b803562002872620021cf8262003004565b81815283810190838501865b84811015620028ab57620028988f888435890101620022ec565b845292860192908601906001016200287e565b505080955050505050509295509295509295565b60008060408385031215620028d2578182fd5b8235620028df81620030dc565b946020939093013593505050565b60008060006060848603121562002902578081fd5b83516001600160401b038082111562002919578283fd5b62002927878388016200228b565b945060208601519350604086015191508082111562002944578283fd5b5062002953868287016200228b565b9150509250925092565b6000602082840312156200296f578081fd5b815162001a4281620030f2565b6000602082840312156200298e578081fd5b5035919050565b60008060408385031215620029a8578182fd5b823591506020830135620023ae81620030dc565b600060208284031215620029ce578081fd5b81356001600160e01b03198116811462001a42578182fd5b600080600080600060a08688031215620029fe578283fd5b85356001600160401b038082111562002a15578485fd5b62002a2389838a01620022ec565b9650602088013591508082111562002a39578485fd5b5062002a4888828901620022ec565b945050604086013560ff8116811462002a5f578384fd5b92506060860135620026c781620030dc565b60006020828403121562002a83578081fd5b5051919050565b6000806040838503121562002a9d578182fd5b8251915060208301516001600160401b0381111562002aba578182fd5b62002ac8858286016200228b565b9150509250929050565b60008060006060848603121562002ae7578081fd5b835192506020840151915060408401516001600160401b0381111562002b0b578182fd5b62002953868287016200228b565b6000815180845260208085019450808401835b8381101562002b535781516001600160a01b03168752958201959082019060010162002b2c565b509495945050505050565b6000815180845260208085019450808401835b8381101562002b535781518752958201959082019060010162002b71565b6000815180845262002ba981602086016020860162003067565b601f01601f19169290920160200192915050565b6000825162002bd181846020870162003067565b9190910192915050565b600076020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8252835162002c0f81601785016020880162003067565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835162002c4281602884016020880162003067565b01602801949350505050565b6001600160a01b0391909116815260200190565b600060018060a01b03808a16835280891660208401525086604083015285606083015284608083015260e060a083015262002ca160e083018562002b8f565b905082151560c083015298975050505050505050565b6001600160a01b03929092168252602082015260400190565b600060a0825262002ce560a083018862002b19565b866020840152828103604084015262002cff818762002b5e565b9050828103606084015262002d15818662002b5e565b9050828103608084015262002d2b818562002b5e565b98975050505050505050565b600060c0825262002d4c60c083018962002b19565b60208881850152876040850152838203606085015262002d6d828862002b5e565b848103608086015286518082529092508183019082810284018301838901865b8381101562002dbf57601f1987840301855262002dac83835162002b8f565b9486019492509085019060010162002d8d565b505087151560a0880152945062001f9a9350505050565b60006060825262002deb606083018662002b5e565b846020840152828103604084015262002e05818562002b5e565b9695505050505050565b60006020825262001a42602083018462002b8f565b60006060825262002e39606083018662002b8f565b828103602084015262002e4d818662002b8f565b91505060ff83166040830152949350505050565b60208082526028908201527f455243323048616e646c65723a204c697175696469747920706f6f6c206e6f746040820152670818dc99585d195960c21b606082015260800190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b60008382526040602083015262001a3f604083018462002b5e565b60008482528360208301526060604083015262002fc8606083018462002b5e565b95945050505050565b604051601f8201601f191681016001600160401b038111828210171562002ffc5762002ffc620030c6565b604052919050565b60006001600160401b03821115620030205762003020620030c6565b5060209081020190565b60008219821115620030405762003040620030b0565b500190565b6000816000190483118215151615620030625762003062620030b0565b500290565b60005b83811015620030845781810151838201526020016200306a565b83811115620011215750506000910152565b600081620030a857620030a8620030b0565b506000190190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146200214357600080fd5b80151581146200214357600080fdfe60806040523480156200001157600080fd5b5060405162001cc738038062001cc783398101604081905262000034916200070d565b620000418383836200004a565b505050620007e1565b600054610100900460ff16620000675760005460ff161562000071565b62000071620001e3565b620000c95760405162461bcd60e51b815260206004820152602e602482015260008051602062001c8783398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b600054610100900460ff16158015620000f5576000805460ff1961ff0019909116610100171660011790555b620000ff62000201565b620001096200025f565b62000113620002d9565b6200011f848462000349565b62000129620003d5565b620001376000335b62000492565b60fb805460ff191660ff8416179055620001727f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a63362000131565b6200019e7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8483362000131565b620001ca7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a3362000131565b8015620001dd576000805461ff00191690555b50505050565b6000620001fb30620004a260201b620007d51760201c565b15905090565b600054610100900460ff166200025d5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ca783398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000c0565b565b600054610100900460ff16620002bb5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ca783398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000c0565b620002c562000201565b620002cf62000201565b6200025d62000201565b600054610100900460ff16620003355760405162461bcd60e51b815260206004820152602b602482015260008051602062001ca783398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000c0565b6200033f62000201565b6200025d620004a8565b600054610100900460ff16620003a55760405162461bcd60e51b815260206004820152602b602482015260008051602062001ca783398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000c0565b8151620003ba9060cc906020850190620005b4565b508051620003d09060cd906020840190620005b4565b505050565b600054610100900460ff16620003f25760005460ff1615620003fc565b620003fc620001e3565b620004505760405162461bcd60e51b815260206004820152602e602482015260008051602062001c8783398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620000c0565b600054610100900460ff161580156200047c576000805460ff1961ff0019909116610100171660011790555b80156200048f576000805461ff00191690555b50565b6200049e828262000510565b5050565b3b151590565b600054610100900460ff16620005045760405162461bcd60e51b815260206004820152602b602482015260008051602062001ca783398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000c0565b6097805460ff19169055565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff166200049e5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620005703390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b828054620005c2906200078e565b90600052602060002090601f016020900481019282620005e6576000855562000631565b82601f106200060157805160ff191683800117855562000631565b8280016001018555821562000631579182015b828111156200063157825182559160200191906001019062000614565b506200063f92915062000643565b5090565b5b808211156200063f576000815560010162000644565b600082601f8301126200066b578081fd5b81516001600160401b0380821115620006885762000688620007cb565b604051601f8301601f19908116603f01168101908282118183101715620006b357620006b3620007cb565b81604052838152602092508683858801011115620006cf578485fd5b8491505b83821015620006f25785820183015181830184015290820190620006d3565b838211156200070357848385830101525b9695505050505050565b60008060006060848603121562000722578283fd5b83516001600160401b038082111562000739578485fd5b62000747878388016200065a565b945060208601519150808211156200075d578384fd5b506200076c868287016200065a565b925050604084015160ff8116811462000783578182fd5b809150509250925092565b600281046001821680620007a357607f821691505b60208210811415620007c557634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b61149680620007f16000396000f3fe608060405234801561001057600080fd5b506004361061014e5760003560e01c806350669a03116100be57806350669a031461027d5780635c975abb1461028557806370a082311461029057806391d14854146102b957806395d89b41146102cc5780639dc29fac146102d4578063a217fddf146102e7578063a457c2d7146102ef578063a9059cbb14610302578063d539139314610315578063d547741f1461033c578063dd62ed3e1461034f578063e63ab1e9146103885761014e565b806301ffc9a71461015357806306fdde031461017b578063095ea7b31461019057806318160ddd146101a357806323b872dd146101b5578063248a9ca3146101c8578063282c51f3146101eb5780632c349627146102125780632f2ff15d1461021a578063313ce5671461022f57806336568abe14610244578063395093511461025757806340c10f191461026a575b600080fd5b61016661016136600461129d565b61039d565b60405190151581526020015b60405180910390f35b6101836103d6565b6040516101729190611334565b61016661019e36600461123a565b610468565b60cb545b604051908152602001610172565b6101666101c33660046111ff565b61047e565b6101a76101d6366004611263565b60009081526065602052604090206001015490565b6101a77f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b61016661052d565b61022d61022836600461127b565b610559565b005b60fb5460405160ff9091168152602001610172565b61022d61025236600461127b565b610584565b61016661026536600461123a565b610602565b61016661027836600461123a565b61063e565b61016661067f565b60975460ff16610166565b6101a761029e3660046111b3565b6001600160a01b0316600090815260c9602052604090205490565b6101666102c736600461127b565b6106a2565b6101836106cd565b6101666102e236600461123a565b6106dc565b6101a7600081565b6101666102fd36600461123a565b610713565b61016661031036600461123a565b6107a2565b6101a77f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b61022d61034a36600461127b565b6107af565b6101a761035d3660046111cd565b6001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205490565b6101a760008051602061144a83398151915281565b60006001600160e01b03198216637965db0b60e01b14806103ce57506301ffc9a760e01b6001600160e01b03198316145b90505b919050565b606060cc80546103e5906113f8565b80601f0160208091040260200160405190810160405280929190818152602001828054610411906113f8565b801561045e5780601f106104335761010080835404028352916020019161045e565b820191906000526020600020905b81548152906001019060200180831161044157829003601f168201915b5050505050905090565b60006104753384846107db565b50600192915050565b600061048b8484846108ff565b6001600160a01b038416600090815260ca60209081526040808320338452909152902054828110156105155760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b60648201526084015b60405180910390fd5b61052285338584036107db565b506001949350505050565b600060008051602061144a83398151915261054981335b610ac8565b610551610b2c565b600191505090565b6000828152606560205260409020600101546105758133610544565b61057f8383610bc4565b505050565b6001600160a01b03811633146105f45760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b606482015260840161050c565b6105fe8282610c4a565b5050565b33600081815260ca602090815260408083206001600160a01b03871684529091528120549091610475918590610639908690611367565b6107db565b60007f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a661066b8133610544565b6106758484610cb1565b5060019392505050565b600060008051602061144a83398151915261069a8133610544565b610551610d8b565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060cd80546103e5906113f8565b60007f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8486107098133610544565b6106758484610e05565b33600090815260ca602090815260408083206001600160a01b0386168452909152812054828110156107955760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161050c565b61067533858584036107db565b60006104753384846108ff565b6000828152606560205260409020600101546107cb8133610544565b61057f8383610c4a565b3b151590565b6001600160a01b03831661083d5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161050c565b6001600160a01b03821661089e5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161050c565b6001600160a01b03838116600081815260ca602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166109635760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161050c565b6001600160a01b0382166109c55760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161050c565b6109d0838383610f4d565b6001600160a01b038316600090815260c9602052604090205481811015610a485760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161050c565b6001600160a01b03808516600090815260c96020526040808220858503905591851681529081208054849290610a7f908490611367565b92505081905550826001600160a01b0316846001600160a01b031660008051602061146a83398151915284604051610ab991815260200190565b60405180910390a35b50505050565b610ad282826106a2565b6105fe57610aea816001600160a01b03166014610fb3565b610af5836020610fb3565b604051602001610b069291906112c5565b60408051601f198184030181529082905262461bcd60e51b825261050c91600401611334565b60975460ff1615610b725760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161050c565b6097805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610ba73390565b6040516001600160a01b03909116815260200160405180910390a1565b610bce82826106a2565b6105fe5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055610c063390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b610c5482826106a2565b156105fe5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6001600160a01b038216610d075760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161050c565b610d1360008383610f4d565b8060cb6000828254610d259190611367565b90915550506001600160a01b038216600090815260c9602052604081208054839290610d52908490611367565b90915550506040518181526001600160a01b0383169060009060008051602061146a8339815191529060200160405180910390a36105fe565b60975460ff16610dd45760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161050c565b6097805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33610ba7565b6001600160a01b038216610e655760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161050c565b610e7182600083610f4d565b6001600160a01b038216600090815260c9602052604090205481811015610ee55760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161050c565b6001600160a01b038316600090815260c960205260408120838303905560cb8054849290610f1490849061139e565b90915550506040518281526000906001600160a01b0385169060008051602061146a8339815191529060200160405180910390a361057f565b60975460ff161561057f5760405162461bcd60e51b815260206004820152602a60248201527f45524332305061757361626c653a20746f6b656e207472616e736665722077686044820152691a5b19481c185d5cd95960b21b606482015260840161050c565b60606000610fc283600261137f565b610fcd906002611367565b67ffffffffffffffff811115610ff357634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561101d576020820181803683370190505b509050600360fc1b8160008151811061104657634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061108357634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060006110a784600261137f565b6110b2906001611367565b90505b6001811115611146576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106110f457634e487b7160e01b600052603260045260246000fd5b1a60f81b82828151811061111857634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c9361113f816113e1565b90506110b5565b5083156111955760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161050c565b9392505050565b80356001600160a01b03811681146103d157600080fd5b6000602082840312156111c4578081fd5b6111958261119c565b600080604083850312156111df578081fd5b6111e88361119c565b91506111f66020840161119c565b90509250929050565b600080600060608486031215611213578081fd5b61121c8461119c565b925061122a6020850161119c565b9150604084013590509250925092565b6000806040838503121561124c578182fd5b6112558361119c565b946020939093013593505050565b600060208284031215611274578081fd5b5035919050565b6000806040838503121561128d578182fd5b823591506111f66020840161119c565b6000602082840312156112ae578081fd5b81356001600160e01b031981168114611195578182fd5b600076020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b825283516112f78160178501602088016113b5565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516113288160288401602088016113b5565b01602801949350505050565b60006020825282518060208401526113538160408501602087016113b5565b601f01601f19169190910160400192915050565b6000821982111561137a5761137a611433565b500190565b600081600019048311821515161561139957611399611433565b500290565b6000828210156113b0576113b0611433565b500390565b60005b838110156113d05781810151838201526020016113b8565b83811115610ac25750506000910152565b6000816113f0576113f0611433565b506000190190565b60028104600182168061140c57607f821691505b6020821081141561142d57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fdfe65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862addf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa164736f6c6343000802000a496e697469616c697a61626c653a20636f6e747261637420697320616c726561496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420695361666545524332303a206c6f772d6c6576656c206d696e742063616c6c206661696c656410d92ebf33ed5dfcdea18b9de7842a212ff94c76d989a24bcfaeaaa3f8d1b1985361666545524332303a206c6f772d6c6576656c206275726e2063616c6c206661696c6564a164736f6c6343000802000a
Deployed Bytecode
0x608060405260043610620001e75760003560e01c806360829f8a1162000103578063aa50ec12116200009d578063aa50ec12146200060e578063ad527b211462000648578063bf6eac2f146200066d578063c4d66de81462000692578063d547741f14620006b7578063da041a8514620006dc578063dc9655821462000701578063f19457251462000726578063f4e480e1146200074b57620001ef565b806360829f8a14620004f45780636cd533d814620005195780636f8d52d3146200053e5780637c4368c1146200056357806391d14854146200058857806393113b5c14620005ad57806395601f0914620005d2578063a217fddf14620005f757620001ef565b806336568abe116200018157806336568abe14620003515780633826c40214620003765780633c94d19e14620003ac57806347c07e8814620003e0578063494082ff14620004055780634ab81254146200043a5780634c62b25714620004705780635739ac7a14620004955780635fae924514620004ba57620001ef565b806301ffc9a714620001f457806304a1d7f9146200022e5780631d27af6814620002555780632214e13b146200027a578063248a9ca314620002ae5780632dd35dae14620002e25780632f2ff15d146200030757806334de0af4146200032c57620001ef565b36620001ef57005b600080fd5b3480156200020157600080fd5b506200021962000213366004620029bc565b62000770565b60405190151581526020015b60405180910390f35b3480156200023b57600080fd5b50620002536200024d36600462002677565b620007aa565b005b3480156200026257600080fd5b506200025362000274366004620025d9565b620007f1565b3480156200028757600080fd5b506200029f62000299366004620027b6565b620008d3565b60405190815260200162000225565b348015620002bb57600080fd5b506200029f620002cd3660046200297c565b60009081526065602052604090206001015490565b348015620002ef57600080fd5b506200025362000301366004620023b9565b6200098f565b3480156200031457600080fd5b50620002536200032636600462002995565b62000b8b565b3480156200033957600080fd5b506200029f60008051602062004dee83398151915281565b3480156200035e57600080fd5b50620002536200037036600462002995565b62000bba565b3480156200038357600080fd5b506200039b62000395366004620026e7565b62000c3c565b604051620002259392919062002dd6565b348015620003b957600080fd5b50620003d1620003cb366004620029e6565b62000ce7565b60405162000225919062002c4e565b348015620003ed57600080fd5b5062000253620003ff366004620025d9565b62000e27565b3480156200041257600080fd5b506200042a6200042436600462002461565b62000ec0565b6040516200022592919062002f8c565b3480156200044757600080fd5b506200045f6200045936600462002565565b62000f77565b604051620002259392919062002fa7565b3480156200047d57600080fd5b50620002536200048f3660046200240a565b6200103a565b348015620004a257600080fd5b5062000253620004b4366004620025d9565b62001065565b348015620004c757600080fd5b50620003d1620004d93660046200235d565b6098602052600090815260409020546001600160a01b031681565b3480156200050157600080fd5b506200025362000513366004620025d9565b62001127565b3480156200052657600080fd5b506200025362000538366004620025d9565b620011ad565b3480156200054b57600080fd5b50620002536200055d3660046200235d565b620011de565b3480156200057057600080fd5b506200025362000582366004620028bf565b6200120f565b3480156200059557600080fd5b5062000219620005a736600462002995565b62001361565b348015620005ba57600080fd5b5062000253620005cc366004620028bf565b6200138e565b348015620005df57600080fd5b5062000253620005f1366004620025d9565b620014a4565b3480156200060457600080fd5b506200029f600081565b3480156200061b57600080fd5b50620003d16200062d3660046200235d565b6097602052600090815260409020546001600160a01b031681565b3480156200065557600080fd5b506200029f620006673660046200237c565b620014cf565b3480156200067a57600080fd5b50620002536200068c366004620025d9565b62001598565b3480156200069f57600080fd5b5062000253620006b13660046200235d565b62001624565b348015620006c457600080fd5b5062000253620006d636600462002995565b620016b1565b348015620006e957600080fd5b506200029f620006fb366004620024cc565b620016db565b3480156200070e57600080fd5b5062000253620007203660046200261e565b6200179a565b3480156200073357600080fd5b5062000253620007453660046200237c565b62001919565b3480156200075857600080fd5b50620002536200076a366004620025d9565b62001969565b60006001600160e01b03198216637965db0b60e01b1480620007a257506301ffc9a760e01b6001600160e01b03198316145b90505b919050565b60008051602062004dee833981519152620007c781335b620019bf565b600084118015620007d55750825b15620007e957620007e9868684876200103a565b505050505050565b60008051602062004dee8339815191526200080d8133620007c1565b6000639dc29fac84846040516024016200082992919062002cb7565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050905060006200088a8260405180606001604052806025815260200162004e0e602591396001600160a01b038916919062001a2e565b805190915015620007e95780806020019051810190620008ab91906200295d565b620007e95760405162461bcd60e51b8152600401620008ca9062002f42565b60405180910390fd5b600060008051602062004dee833981519152620008f18133620007c1565b60405163d835b06960e01b815288906001600160a01b0382169063d835b069906200092c908b908b908b908b908b9060019060040162002d37565b602060405180830381600087803b1580156200094757600080fd5b505af11580156200095c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000982919062002a71565b9998505050505050505050565b60008051602062004dee833981519152620009ab8133620007c1565b6001600160a01b03841662000a125760405162461bcd60e51b815260206004820152602660248201527f455243323048616e646c65723a206e6577206f776e65722063616e6e6f74206260448201526519481b9d5b1b60d21b6064820152608401620008ca565b6001600160a01b03831662000a7c5760405162461bcd60e51b815260206004820152602960248201527f455243323048616e646c65723a20746f6b656e416464726573732063616e6e6f6044820152681d081899481b9d5b1b60ba1b6064820152608401620008ca565b6001600160a01b03821662000ae35760405162461bcd60e51b815260206004820152602660248201527f455243323048616e646c65723a206c70416464726573732063616e6e6f74206260448201526519481b9d5b1b60d21b6064820152608401620008ca565b6001600160a01b03828116600081815260976020908152604080832080548987166001600160a01b0319918216811790925590845260989092528083208054909216841790915551632f2ff15d60e01b8152600481019190915291861660248301528391632f2ff15d90604401600060405180830381600087803b15801562000b6b57600080fd5b505af115801562000b80573d6000803e3d6000fd5b505050505050505050565b60008281526065602052604090206001015462000ba98133620007c1565b62000bb5838362001a49565b505050565b6001600160a01b038116331462000c2c5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401620008ca565b62000c38828262001ad3565b5050565b604051633d99b80d60e11b8152606090600090829089906001600160a01b03821690637b33701a9062000c7c908c908c908c908c908c9060040162002cd0565b60006040518083038186803b15801562000c9557600080fd5b505afa15801562000caa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000cd49190810190620028ed565b9350935093505096509650969350505050565b600060008051602062004dee83398151915262000d058133620007c1565b6001600160a01b03848116600090815260986020526040902054161562000d7b5760405162461bcd60e51b815260206004820152602360248201527f455243323048616e646c65723a20706f6f6c20616c7265616479206465706c6f6044820152621e595960ea1b6064820152608401620008ca565b60006001600160a01b03841662000dd557600088888860405162000d9f9062002190565b62000dad9392919062002e24565b604051809103906000f08015801562000dca573d6000803e3d6000fd5b50915062000dd89050565b50825b6001600160a01b0380821660008181526097602090815260408083208054958b166001600160a01b03199687168117909155835260989091529020805490921617905591505095945050505050565b60008051602062004dee83398151915262000e438133620007c1565b60006340c10f19848460405160240162000e5f92919062002cb7565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050905060006200088a8260405180606001604052806025815260200162004dc9602591396001600160a01b038916919062001a2e565b60405163085e2c5b60e01b81526001600160a01b038681166004830152858116602483015260448201859052606482018490526084820183905260009160609189919082169063085e2c5b9060a40160006040518083038186803b15801562000f2857600080fd5b505afa15801562000f3d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000f67919081019062002a8a565b9250925050965096945050505050565b604051638373f26560e01b81526001600160a01b038781166004830152868116602483015260448201869052606482018590526084820184905260a4820183905260009182916060918b91821690638373f2659060c40160006040518083038186803b15801562000fe757600080fd5b505afa15801562000ffc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262001026919081019062002ad2565b935093509350509750975097945050505050565b60008051602062004dee833981519152620010568133620007c1565b84620007e98186868662001b3d565b60008051602062004dee833981519152620010818133620007c1565b6001600160a01b0384811660009081526098602052604090205416620010f95760405162461bcd60e51b815260206004820152602660248201527f455243323048616e646c65723a204c697175696469747920706f6f6c206e6f7460448201526508199bdd5b9960d21b6064820152608401620008ca565b6001600160a01b03808516600090815260986020526040902054620011219116848462000e27565b50505050565b60008051602062004dee833981519152620011438133620007c1565b6001600160a01b03838116600090815260986020526040902054166200117d5760405162461bcd60e51b8152600401620008ca9062002e61565b6001600160a01b03808416600090815260986020526040902054620011a591168584620007f1565b620011218385845b60008051602062004dee833981519152620011c98133620007c1565b83620011d781858562001baa565b5050505050565b6000620011ec8133620007c1565b50609980546001600160a01b0319166001600160a01b0392909216919091179055565b60008051602062004dee8339815191526200122b8133620007c1565b6001600160a01b038316620012925760405162461bcd60e51b815260206004820152602660248201527f736166655472616e736665724554483a207472616e7366657220746f2061646460448201526507265737320360d41b6064820152608401620008ca565b604080516000808252602082019092526001600160a01b038516908490604051620012be919062002bbd565b60006040518083038185875af1925050503d8060008114620012fd576040519150601f19603f3d011682016040523d82523d6000602084013e62001302565b606091505b5050905080620011215760405162461bcd60e51b8152602060048201526024808201527f736166655472616e736665724554483a20455448207472616e736665722066616044820152631a5b195960e21b6064820152608401620008ca565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff165b92915050565b60008051602062004dee833981519152620013aa8133620007c1565b60995460405163a9059cbb60e01b81526001600160a01b038581169263a9059cbb92620013e09290911690869060040162002cb7565b602060405180830381600087803b158015620013fb57600080fd5b505af115801562001410573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200143691906200295d565b5060995460405163f3fef3a360e01b81526001600160a01b039091169063f3fef3a3906200146b908690869060040162002cb7565b600060405180830381600087803b1580156200148657600080fd5b505af11580156200149b573d6000803e3d6000fd5b50505050505050565b60008051602062004dee833981519152620014c08133620007c1565b83620011d78185308662001b3d565b6001600160a01b03818116600090815260986020526040812054909116156200158f576001600160a01b03808316600090815260986020526040908190205490516370a0823160e01b81529116906370a08231906200153390869060040162002c4e565b60206040518083038186803b1580156200154c57600080fd5b505afa15801562001561573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001587919062002a71565b905062001388565b50600092915050565b60008051602062004dee833981519152620015b48133620007c1565b6001600160a01b0383811660009081526098602052604090205416620015ee5760405162461bcd60e51b8152600401620008ca9062002e61565b620015fc838530856200103a565b6001600160a01b03808416600090815260986020526040902054620011219116858462000e27565b600054610100900460ff16620016415760005460ff161562001645565b303b155b620016645760405162461bcd60e51b8152600401620008ca9062002ea9565b600054610100900460ff1615801562001690576000805460ff1961ff0019909116610100171660011790555b6200169b8262001bcc565b801562000c38576000805461ff00191690555050565b600082815260656020526040902060010154620016cf8133620007c1565b62000bb5838362001ad3565b600060008051602062004dee833981519152620016f98133620007c1565b6040516333e2977f60e11b815289906001600160a01b038216906367c52efe9062001736908c908c908c908c908c908c9060019060040162002c62565b602060405180830381600087803b1580156200175157600080fd5b505af115801562001766573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200178c919062002a71565b9a9950505050505050505050565b60008051602062004dee833981519152620017b68133620007c1565b6001600160a01b0384811660009081526098602052604090205416620017f05760405162461bcd60e51b8152600401620008ca9062002e61565b6001600160a01b038085166000908152609860205260409020546200181891168685620007f1565b60995460405163a9059cbb60e01b81526001600160a01b038481169263a9059cbb926200184e9290911690879060040162002cb7565b602060405180830381600087803b1580156200186957600080fd5b505af11580156200187e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018a491906200295d565b5060995460405163f3fef3a360e01b81526001600160a01b039091169063f3fef3a390620018d9908590879060040162002cb7565b600060405180830381600087803b158015620018f457600080fd5b505af115801562001909573d6000803e3d6000fd5b50505050620011d785846200120f565b6000620019278133620007c1565b506001600160a01b03908116600090815260976020908152604080832080546001600160a01b0319908116909155949093168252609890522080549091169055565b60008051602062004dee833981519152620019858133620007c1565b6001600160a01b0383811660009081526098602052604090205416620015fc5760405162461bcd60e51b8152600401620008ca9062002e61565b620019cb828262001361565b62000c3857620019e6816001600160a01b0316601462001c7e565b620019f383602062001c7e565b60405160200162001a0692919062002bdb565b60408051601f198184030181529082905262461bcd60e51b8252620008ca9160040162002e0f565b606062001a3f848460008562001e73565b90505b9392505050565b62001a55828262001361565b62000c385760008281526065602090815260408083206001600160a01b03851684529091529020805460ff1916600117905562001a8f3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b62001adf828262001361565b1562000c385760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6040516001600160a01b0380851660248301528316604482015260648101829052620011219085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915262001fa5565b62000bb58363a9059cbb60e01b848460405160240162001b7292919062002cb7565b600054610100900460ff1662001be95760005460ff161562001bed565b303b155b62001c0c5760405162461bcd60e51b8152600401620008ca9062002ea9565b600054610100900460ff1615801562001c38576000805460ff1961ff0019909116610100171660011790555b62001c426200203c565b62001c4c62002068565b62001c56620020b0565b62001c6360003362002146565b6200169b60008051602062004dee8339815191528362002146565b6060600062001c8f83600262003045565b62001c9c9060026200302a565b6001600160401b0381111562001cc257634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801562001ced576020820181803683370190505b509050600360fc1b8160008151811062001d1757634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811062001d5557634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600062001d7b84600262003045565b62001d889060016200302a565b90505b600181111562001e22576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811062001dcc57634e487b7160e01b600052603260045260246000fd5b1a60f81b82828151811062001df157634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c9362001e1a8162003096565b905062001d8b565b50831562001a425760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401620008ca565b60608247101562001ed65760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401620008ca565b843b62001f265760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401620008ca565b600080866001600160a01b0316858760405162001f44919062002bbd565b60006040518083038185875af1925050503d806000811462001f83576040519150601f19603f3d011682016040523d82523d6000602084013e62001f88565b606091505b509150915062001f9a82828662002152565b979650505050505050565b600062001ffc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031662001a2e9092919063ffffffff16565b80519091501562000bb557808060200190518101906200201d91906200295d565b62000bb55760405162461bcd60e51b8152600401620008ca9062002f42565b600054610100900460ff16620020665760405162461bcd60e51b8152600401620008ca9062002ef7565b565b600054610100900460ff16620020925760405162461bcd60e51b8152600401620008ca9062002ef7565b6200209c6200203c565b620020a66200203c565b620020666200203c565b600054610100900460ff16620020cd5760005460ff1615620020d1565b303b155b620020f05760405162461bcd60e51b8152600401620008ca9062002ea9565b600054610100900460ff161580156200211c576000805460ff1961ff0019909116610100171660011790555b620021266200203c565b620021306200203c565b801562002143576000805461ff00191690555b50565b62000c38828262001a49565b606083156200216357508162001a42565b825115620021745782518084602001fd5b8160405162461bcd60e51b8152600401620008ca919062002e0f565b611cc7806200310283390190565b8035620007a581620030dc565b600082601f830112620021bc578081fd5b81356020620021d5620021cf8362003004565b62002fd1565b8281528181019085830183850287018401881015620021f2578586fd5b855b858110156200221d5781356200220a81620030dc565b84529284019290840190600101620021f4565b5090979650505050505050565b600082601f8301126200223b578081fd5b813560206200224e620021cf8362003004565b82815281810190858301838502870184018810156200226b578586fd5b855b858110156200221d578135845292840192908401906001016200226d565b600082601f8301126200229c578081fd5b81516020620022af620021cf8362003004565b8281528181019085830183850287018401881015620022cc578586fd5b855b858110156200221d57815184529284019290840190600101620022ce565b600082601f830112620022fd578081fd5b81356001600160401b03811115620023195762002319620030c6565b6200232e601f8201601f191660200162002fd1565b81815284602083860101111562002343578283fd5b816020850160208301379081016020019190915292915050565b6000602082840312156200236f578081fd5b813562001a4281620030dc565b600080604083850312156200238f578081fd5b82356200239c81620030dc565b91506020830135620023ae81620030dc565b809150509250929050565b600080600060608486031215620023ce578081fd5b8335620023db81620030dc565b92506020840135620023ed81620030dc565b91506040840135620023ff81620030dc565b809150509250925092565b6000806000806080858703121562002420578182fd5b84356200242d81620030dc565b935060208501356200243f81620030dc565b925060408501356200245181620030dc565b9396929550929360600135925050565b60008060008060008060c087890312156200247a578384fd5b86356200248781620030dc565b955060208701356200249981620030dc565b94506040870135620024ab81620030dc565b959894975094956060810135955060808101359460a0909101359350915050565b600080600080600080600060e0888a031215620024e7578485fd5b8735620024f481620030dc565b965060208801356200250681620030dc565b955060408801356200251881620030dc565b9450606088013593506080880135925060a0880135915060c08801356001600160401b0381111562002548578182fd5b620025568a828b01620022ec565b91505092959891949750929550565b600080600080600080600060e0888a03121562002580578081fd5b87356200258d81620030dc565b965060208801356200259f81620030dc565b95506040880135620025b181620030dc565b969995985095966060810135965060808101359560a0820135955060c0909101359350915050565b600080600060608486031215620025ee578081fd5b8335620025fb81620030dc565b925060208401356200260d81620030dc565b929592945050506040919091013590565b6000806000806080858703121562002634578182fd5b84356200264181620030dc565b935060208501356200265381620030dc565b92506040850135915060608501356200266c81620030dc565b939692955090935050565b600080600080600060a086880312156200268f578283fd5b85356200269c81620030dc565b94506020860135620026ae81620030dc565b9350604086013592506060860135620026c781620030f2565b91506080860135620026d981620030dc565b809150509295509295909350565b60008060008060008060c0878903121562002700578384fd5b6200270b876200219e565b955060208701356001600160401b038082111562002727578586fd5b620027358a838b01620021ab565b965060408901359550606089013591508082111562002752578384fd5b620027608a838b016200222a565b9450608089013591508082111562002776578384fd5b620027848a838b016200222a565b935060a08901359150808211156200279a578283fd5b50620027a989828a016200222a565b9150509295509295509295565b60008060008060008060c08789031215620027cf578384fd5b8635620027dc81620030dc565b95506020878101356001600160401b0380821115620027f9578687fd5b620028078b838c01620021ab565b975060408a0135965060608a0135955060808a01359150808211156200282b578485fd5b620028398b838c016200222a565b945060a08a01359150808211156200284f578384fd5b508801601f81018a1362002861578283fd5b803562002872620021cf8262003004565b81815283810190838501865b84811015620028ab57620028988f888435890101620022ec565b845292860192908601906001016200287e565b505080955050505050509295509295509295565b60008060408385031215620028d2578182fd5b8235620028df81620030dc565b946020939093013593505050565b60008060006060848603121562002902578081fd5b83516001600160401b038082111562002919578283fd5b62002927878388016200228b565b945060208601519350604086015191508082111562002944578283fd5b5062002953868287016200228b565b9150509250925092565b6000602082840312156200296f578081fd5b815162001a4281620030f2565b6000602082840312156200298e578081fd5b5035919050565b60008060408385031215620029a8578182fd5b823591506020830135620023ae81620030dc565b600060208284031215620029ce578081fd5b81356001600160e01b03198116811462001a42578182fd5b600080600080600060a08688031215620029fe578283fd5b85356001600160401b038082111562002a15578485fd5b62002a2389838a01620022ec565b9650602088013591508082111562002a39578485fd5b5062002a4888828901620022ec565b945050604086013560ff8116811462002a5f578384fd5b92506060860135620026c781620030dc565b60006020828403121562002a83578081fd5b5051919050565b6000806040838503121562002a9d578182fd5b8251915060208301516001600160401b0381111562002aba578182fd5b62002ac8858286016200228b565b9150509250929050565b60008060006060848603121562002ae7578081fd5b835192506020840151915060408401516001600160401b0381111562002b0b578182fd5b62002953868287016200228b565b6000815180845260208085019450808401835b8381101562002b535781516001600160a01b03168752958201959082019060010162002b2c565b509495945050505050565b6000815180845260208085019450808401835b8381101562002b535781518752958201959082019060010162002b71565b6000815180845262002ba981602086016020860162003067565b601f01601f19169290920160200192915050565b6000825162002bd181846020870162003067565b9190910192915050565b600076020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8252835162002c0f81601785016020880162003067565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835162002c4281602884016020880162003067565b01602801949350505050565b6001600160a01b0391909116815260200190565b600060018060a01b03808a16835280891660208401525086604083015285606083015284608083015260e060a083015262002ca160e083018562002b8f565b905082151560c083015298975050505050505050565b6001600160a01b03929092168252602082015260400190565b600060a0825262002ce560a083018862002b19565b866020840152828103604084015262002cff818762002b5e565b9050828103606084015262002d15818662002b5e565b9050828103608084015262002d2b818562002b5e565b98975050505050505050565b600060c0825262002d4c60c083018962002b19565b60208881850152876040850152838203606085015262002d6d828862002b5e565b848103608086015286518082529092508183019082810284018301838901865b8381101562002dbf57601f1987840301855262002dac83835162002b8f565b9486019492509085019060010162002d8d565b505087151560a0880152945062001f9a9350505050565b60006060825262002deb606083018662002b5e565b846020840152828103604084015262002e05818562002b5e565b9695505050505050565b60006020825262001a42602083018462002b8f565b60006060825262002e39606083018662002b8f565b828103602084015262002e4d818662002b8f565b91505060ff83166040830152949350505050565b60208082526028908201527f455243323048616e646c65723a204c697175696469747920706f6f6c206e6f746040820152670818dc99585d195960c21b606082015260800190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b60008382526040602083015262001a3f604083018462002b5e565b60008482528360208301526060604083015262002fc8606083018462002b5e565b95945050505050565b604051601f8201601f191681016001600160401b038111828210171562002ffc5762002ffc620030c6565b604052919050565b60006001600160401b03821115620030205762003020620030c6565b5060209081020190565b60008219821115620030405762003040620030b0565b500190565b6000816000190483118215151615620030625762003062620030b0565b500290565b60005b83811015620030845781810151838201526020016200306a565b83811115620011215750506000910152565b600081620030a857620030a8620030b0565b506000190190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146200214357600080fd5b80151581146200214357600080fdfe60806040523480156200001157600080fd5b5060405162001cc738038062001cc783398101604081905262000034916200070d565b620000418383836200004a565b505050620007e1565b600054610100900460ff16620000675760005460ff161562000071565b62000071620001e3565b620000c95760405162461bcd60e51b815260206004820152602e602482015260008051602062001c8783398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b600054610100900460ff16158015620000f5576000805460ff1961ff0019909116610100171660011790555b620000ff62000201565b620001096200025f565b62000113620002d9565b6200011f848462000349565b62000129620003d5565b620001376000335b62000492565b60fb805460ff191660ff8416179055620001727f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a63362000131565b6200019e7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8483362000131565b620001ca7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a3362000131565b8015620001dd576000805461ff00191690555b50505050565b6000620001fb30620004a260201b620007d51760201c565b15905090565b600054610100900460ff166200025d5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ca783398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000c0565b565b600054610100900460ff16620002bb5760405162461bcd60e51b815260206004820152602b602482015260008051602062001ca783398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000c0565b620002c562000201565b620002cf62000201565b6200025d62000201565b600054610100900460ff16620003355760405162461bcd60e51b815260206004820152602b602482015260008051602062001ca783398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000c0565b6200033f62000201565b6200025d620004a8565b600054610100900460ff16620003a55760405162461bcd60e51b815260206004820152602b602482015260008051602062001ca783398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000c0565b8151620003ba9060cc906020850190620005b4565b508051620003d09060cd906020840190620005b4565b505050565b600054610100900460ff16620003f25760005460ff1615620003fc565b620003fc620001e3565b620004505760405162461bcd60e51b815260206004820152602e602482015260008051602062001c8783398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620000c0565b600054610100900460ff161580156200047c576000805460ff1961ff0019909116610100171660011790555b80156200048f576000805461ff00191690555b50565b6200049e828262000510565b5050565b3b151590565b600054610100900460ff16620005045760405162461bcd60e51b815260206004820152602b602482015260008051602062001ca783398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000c0565b6097805460ff19169055565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff166200049e5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620005703390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b828054620005c2906200078e565b90600052602060002090601f016020900481019282620005e6576000855562000631565b82601f106200060157805160ff191683800117855562000631565b8280016001018555821562000631579182015b828111156200063157825182559160200191906001019062000614565b506200063f92915062000643565b5090565b5b808211156200063f576000815560010162000644565b600082601f8301126200066b578081fd5b81516001600160401b0380821115620006885762000688620007cb565b604051601f8301601f19908116603f01168101908282118183101715620006b357620006b3620007cb565b81604052838152602092508683858801011115620006cf578485fd5b8491505b83821015620006f25785820183015181830184015290820190620006d3565b838211156200070357848385830101525b9695505050505050565b60008060006060848603121562000722578283fd5b83516001600160401b038082111562000739578485fd5b62000747878388016200065a565b945060208601519150808211156200075d578384fd5b506200076c868287016200065a565b925050604084015160ff8116811462000783578182fd5b809150509250925092565b600281046001821680620007a357607f821691505b60208210811415620007c557634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b61149680620007f16000396000f3fe608060405234801561001057600080fd5b506004361061014e5760003560e01c806350669a03116100be57806350669a031461027d5780635c975abb1461028557806370a082311461029057806391d14854146102b957806395d89b41146102cc5780639dc29fac146102d4578063a217fddf146102e7578063a457c2d7146102ef578063a9059cbb14610302578063d539139314610315578063d547741f1461033c578063dd62ed3e1461034f578063e63ab1e9146103885761014e565b806301ffc9a71461015357806306fdde031461017b578063095ea7b31461019057806318160ddd146101a357806323b872dd146101b5578063248a9ca3146101c8578063282c51f3146101eb5780632c349627146102125780632f2ff15d1461021a578063313ce5671461022f57806336568abe14610244578063395093511461025757806340c10f191461026a575b600080fd5b61016661016136600461129d565b61039d565b60405190151581526020015b60405180910390f35b6101836103d6565b6040516101729190611334565b61016661019e36600461123a565b610468565b60cb545b604051908152602001610172565b6101666101c33660046111ff565b61047e565b6101a76101d6366004611263565b60009081526065602052604090206001015490565b6101a77f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b61016661052d565b61022d61022836600461127b565b610559565b005b60fb5460405160ff9091168152602001610172565b61022d61025236600461127b565b610584565b61016661026536600461123a565b610602565b61016661027836600461123a565b61063e565b61016661067f565b60975460ff16610166565b6101a761029e3660046111b3565b6001600160a01b0316600090815260c9602052604090205490565b6101666102c736600461127b565b6106a2565b6101836106cd565b6101666102e236600461123a565b6106dc565b6101a7600081565b6101666102fd36600461123a565b610713565b61016661031036600461123a565b6107a2565b6101a77f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b61022d61034a36600461127b565b6107af565b6101a761035d3660046111cd565b6001600160a01b03918216600090815260ca6020908152604080832093909416825291909152205490565b6101a760008051602061144a83398151915281565b60006001600160e01b03198216637965db0b60e01b14806103ce57506301ffc9a760e01b6001600160e01b03198316145b90505b919050565b606060cc80546103e5906113f8565b80601f0160208091040260200160405190810160405280929190818152602001828054610411906113f8565b801561045e5780601f106104335761010080835404028352916020019161045e565b820191906000526020600020905b81548152906001019060200180831161044157829003601f168201915b5050505050905090565b60006104753384846107db565b50600192915050565b600061048b8484846108ff565b6001600160a01b038416600090815260ca60209081526040808320338452909152902054828110156105155760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b60648201526084015b60405180910390fd5b61052285338584036107db565b506001949350505050565b600060008051602061144a83398151915261054981335b610ac8565b610551610b2c565b600191505090565b6000828152606560205260409020600101546105758133610544565b61057f8383610bc4565b505050565b6001600160a01b03811633146105f45760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b606482015260840161050c565b6105fe8282610c4a565b5050565b33600081815260ca602090815260408083206001600160a01b03871684529091528120549091610475918590610639908690611367565b6107db565b60007f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a661066b8133610544565b6106758484610cb1565b5060019392505050565b600060008051602061144a83398151915261069a8133610544565b610551610d8b565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b606060cd80546103e5906113f8565b60007f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8486107098133610544565b6106758484610e05565b33600090815260ca602090815260408083206001600160a01b0386168452909152812054828110156107955760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161050c565b61067533858584036107db565b60006104753384846108ff565b6000828152606560205260409020600101546107cb8133610544565b61057f8383610c4a565b3b151590565b6001600160a01b03831661083d5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161050c565b6001600160a01b03821661089e5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161050c565b6001600160a01b03838116600081815260ca602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166109635760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161050c565b6001600160a01b0382166109c55760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161050c565b6109d0838383610f4d565b6001600160a01b038316600090815260c9602052604090205481811015610a485760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161050c565b6001600160a01b03808516600090815260c96020526040808220858503905591851681529081208054849290610a7f908490611367565b92505081905550826001600160a01b0316846001600160a01b031660008051602061146a83398151915284604051610ab991815260200190565b60405180910390a35b50505050565b610ad282826106a2565b6105fe57610aea816001600160a01b03166014610fb3565b610af5836020610fb3565b604051602001610b069291906112c5565b60408051601f198184030181529082905262461bcd60e51b825261050c91600401611334565b60975460ff1615610b725760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161050c565b6097805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610ba73390565b6040516001600160a01b03909116815260200160405180910390a1565b610bce82826106a2565b6105fe5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055610c063390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b610c5482826106a2565b156105fe5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6001600160a01b038216610d075760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161050c565b610d1360008383610f4d565b8060cb6000828254610d259190611367565b90915550506001600160a01b038216600090815260c9602052604081208054839290610d52908490611367565b90915550506040518181526001600160a01b0383169060009060008051602061146a8339815191529060200160405180910390a36105fe565b60975460ff16610dd45760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161050c565b6097805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33610ba7565b6001600160a01b038216610e655760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161050c565b610e7182600083610f4d565b6001600160a01b038216600090815260c9602052604090205481811015610ee55760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161050c565b6001600160a01b038316600090815260c960205260408120838303905560cb8054849290610f1490849061139e565b90915550506040518281526000906001600160a01b0385169060008051602061146a8339815191529060200160405180910390a361057f565b60975460ff161561057f5760405162461bcd60e51b815260206004820152602a60248201527f45524332305061757361626c653a20746f6b656e207472616e736665722077686044820152691a5b19481c185d5cd95960b21b606482015260840161050c565b60606000610fc283600261137f565b610fcd906002611367565b67ffffffffffffffff811115610ff357634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561101d576020820181803683370190505b509050600360fc1b8160008151811061104657634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061108357634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060006110a784600261137f565b6110b2906001611367565b90505b6001811115611146576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106110f457634e487b7160e01b600052603260045260246000fd5b1a60f81b82828151811061111857634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c9361113f816113e1565b90506110b5565b5083156111955760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161050c565b9392505050565b80356001600160a01b03811681146103d157600080fd5b6000602082840312156111c4578081fd5b6111958261119c565b600080604083850312156111df578081fd5b6111e88361119c565b91506111f66020840161119c565b90509250929050565b600080600060608486031215611213578081fd5b61121c8461119c565b925061122a6020850161119c565b9150604084013590509250925092565b6000806040838503121561124c578182fd5b6112558361119c565b946020939093013593505050565b600060208284031215611274578081fd5b5035919050565b6000806040838503121561128d578182fd5b823591506111f66020840161119c565b6000602082840312156112ae578081fd5b81356001600160e01b031981168114611195578182fd5b600076020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b825283516112f78160178501602088016113b5565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516113288160288401602088016113b5565b01602801949350505050565b60006020825282518060208401526113538160408501602087016113b5565b601f01601f19169190910160400192915050565b6000821982111561137a5761137a611433565b500190565b600081600019048311821515161561139957611399611433565b500290565b6000828210156113b0576113b0611433565b500390565b60005b838110156113d05781810151838201526020016113b8565b83811115610ac25750506000910152565b6000816113f0576113f0611433565b506000190190565b60028104600182168061140c57607f821691505b6020821081141561142d57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fdfe65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862addf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa164736f6c6343000802000a496e697469616c697a61626c653a20636f6e747261637420697320616c726561496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420695361666545524332303a206c6f772d6c6576656c206d696e742063616c6c206661696c656410d92ebf33ed5dfcdea18b9de7842a212ff94c76d989a24bcfaeaaa3f8d1b1985361666545524332303a206c6f772d6c6576656c206275726e2063616c6c206661696c6564a164736f6c6343000802000a
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.