Feature Tip: Add private address tag to any address under My Name Tag !
ERC-1155
Overview
Max Total Supply
222 sdNFT
Holders
198
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
StakeDaoNFT_V2
Compiler Version
v0.5.17+commit.d19bba13
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: UNLICENSED pragma solidity ^0.5.0; pragma experimental ABIEncoderV2; import "@openzeppelin/contracts/ownership/Ownable.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; import "@openzeppelin/contracts/GSN/Context.sol"; import "./ERC1155Tradable.sol"; /** * @title StrategyRole * @dev Owner is responsible to add/remove strategy */ contract StrategyRole is Context, Ownable { using Roles for Roles.Role; event StrategyAdded(address indexed account); event StrategyRemoved(address indexed account); Roles.Role private _strategies; modifier onlyStrategy() { require( isStrategy(_msgSender()), "StrategyRole: caller does not have the Strategy role" ); _; } function isStrategy(address account) public view returns (bool) { return _strategies.has(account); } function addStrategy(address account) public onlyOwner { _addStrategy(account); } function removeStrategy(address account) public onlyOwner { _removeStrategy(account); } function _addStrategy(address account) internal { _strategies.add(account); emit StrategyAdded(account); } function _removeStrategy(address account) internal { _strategies.remove(account); emit StrategyRemoved(account); } } /** * @title Strategy Access NFT Contract for StakeDAO * @dev The contract keeps a count of NFTs being used in some strategy for * for each user and allows transfers based on that. */ contract StakeDaoNFT_V2 is ERC1155Tradable, StrategyRole { using SafeMath for uint256; event StartedUsingNFT( address indexed account, uint256 indexed id, address indexed strategy ); event EndedUsingNFT( address indexed account, uint256 indexed id, address indexed strategy ); // mapping account => nftId => useCount // this is used to restrict transfers if nft is being used in any strategy mapping(address => mapping(uint256 => uint256)) internal totalUseCount; // mapping account => nftId => strategyAddress => useCount // this is used to make sure a strategy can only end using nft that it started using before mapping(address => mapping(uint256 => mapping(address => uint256))) internal stratUseCount; // TODO: proper name, metadata uri constructor(address _proxyRegistryAddress) public ERC1155Tradable("Stake DAO NFT", "sdNFT", _proxyRegistryAddress) { _setBaseMetadataURI( "https://gateway.pinata.cloud/ipfs/QmS2txkRpQUX3XhMHjYNem8iCoPhPekYcjbwamT2NDCkH1/metadata/" ); // starting ids for these nfts from 223 // since 222 nfts (tempest, pythia) have been minted using old implementation _currentTokenID = 222; } function contractURI() public view returns (string memory) { return "https://gateway.pinata.cloud/ipfs/Qmc1i37KPdg7Cp8rzjgp3QoCECaEbfoSymCpKG8hF85ENv"; } function getTotalUseCount(address _account, uint256 _id) public view returns (uint256) { return totalUseCount[_account][_id]; } function getStratUseCount( address _account, uint256 _id, address _strategy ) public view returns (uint256) { return stratUseCount[_account][_id][_strategy]; } /** * @notice Mark NFT as being used. Only callable by registered strategies * @param _account User account address * @param _id ID of the token type */ function startUsingNFT(address _account, uint256 _id) public onlyStrategy { require( balances[_account][_id] > 0, "StakeDaoNFT_V2: user account doesnt have NFT" ); stratUseCount[_account][_id][msg.sender] = stratUseCount[_account][_id][ msg.sender ].add(1); totalUseCount[_account][_id] = totalUseCount[_account][_id].add(1); emit StartedUsingNFT(_account, _id, msg.sender); } /** * @notice Unmark NFT as being used. Only callable by registered strategies * @param _account User account address * @param _id ID of the token type */ function endUsingNFT(address _account, uint256 _id) public onlyStrategy { // if a strategy tries to call endUsingNFT function for which it did not call // startUsingNFT then subtraction reverts due to safemath. stratUseCount[_account][_id][msg.sender] = stratUseCount[_account][_id][ msg.sender ].sub(1); totalUseCount[_account][_id] = totalUseCount[_account][_id].sub(1); emit EndedUsingNFT(_account, _id, msg.sender); } /** * @dev Overrides safeTransferFrom function of ERC1155 to introduce totalUseCount check */ function safeTransferFrom( address _from, address _to, uint256 _id, uint256 _amount, bytes memory _data ) public { // check if nft is being used require( totalUseCount[_from][_id] == 0, "StakeDaoNFT_V2: NFT being used in strategy" ); super.safeTransferFrom(_from, _to, _id, _amount, _data); } /** * @dev Overrides safeBatchTransferFrom function of ERC1155 to introduce totalUseCount check */ function safeBatchTransferFrom( address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data ) public { // Number of transfer to execute uint256 nTransfer = _ids.length; // check if any nft is being used for (uint256 i = 0; i < nTransfer; i++) { require( totalUseCount[_from][_ids[i]] == 0, "StakeDaoNFT_V2: NFT being used in strategy" ); } super.safeBatchTransferFrom(_from, _to, _ids, _amounts, _data); } function burn( address _from, uint256 _id, uint256 _amount ) public onlyOwner { // check if nft is being used require( totalUseCount[_from][_id] == 0, "StakeDaoNFT_V2: NFT being used in strategy" ); super.burn(_from, _id, _amount); } }
pragma solidity ^0.5.0; import "../GSN/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () internal { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner(), "Ownable: caller is not the owner"); _; } /** * @dev Returns true if the caller is the current owner. */ function isOwner() public view returns (bool) { return _msgSender() == _owner; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public onlyOwner { _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). */ function _transferOwnership(address newOwner) internal { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
pragma solidity ^0.5.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. * * _Available since v2.4.0._ */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. * * _Available since v2.4.0._ */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. * * _Available since v2.4.0._ */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } }
pragma solidity ^0.5.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ contract Context { // Empty internal constructor, to prevent people from mistakenly deploying // an instance of this contract, which should be used via inheritance. constructor () internal { } // solhint-disable-previous-line no-empty-blocks function _msgSender() internal view returns (address payable) { return msg.sender; } function _msgData() internal view returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
//SPDX-License-Identifier: UNLICENSED pragma solidity ^0.5.0; pragma experimental ABIEncoderV2; import "@openzeppelin/contracts/math/Math.sol"; import "@openzeppelin/contracts/GSN/Context.sol"; import "@openzeppelin/contracts/ownership/Ownable.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/utils/Address.sol"; /** * @title Roles * @dev Library for managing addresses assigned to a Role. */ library Roles { struct Role { mapping(address => bool) bearer; } /** * @dev Give an account access to this role. */ function add(Role storage role, address account) internal { require(!has(role, account), "Roles: account already has role"); role.bearer[account] = true; } /** * @dev Remove an account's access to this role. */ function remove(Role storage role, address account) internal { require(has(role, account), "Roles: account does not have role"); role.bearer[account] = false; } /** * @dev Check if an account has this role. * @return bool */ function has(Role storage role, address account) internal view returns (bool) { require(account != address(0), "Roles: account is the zero address"); return role.bearer[account]; } } contract MinterRole is Context { using Roles for Roles.Role; event MinterAdded(address indexed account); event MinterRemoved(address indexed account); Roles.Role private _minters; constructor() internal { _addMinter(_msgSender()); } modifier onlyMinter() { require( isMinter(_msgSender()), "MinterRole: caller does not have the Minter role" ); _; } function isMinter(address account) public view returns (bool) { return _minters.has(account); } function addMinter(address account) public onlyMinter { _addMinter(account); } function renounceMinter() public { _removeMinter(_msgSender()); } function _addMinter(address account) internal { _minters.add(account); emit MinterAdded(account); } function _removeMinter(address account) internal { _minters.remove(account); emit MinterRemoved(account); } } /** * @title WhitelistAdminRole * @dev WhitelistAdmins are responsible for assigning and removing Whitelisted accounts. */ contract WhitelistAdminRole is Context { using Roles for Roles.Role; event WhitelistAdminAdded(address indexed account); event WhitelistAdminRemoved(address indexed account); Roles.Role private _whitelistAdmins; constructor() internal { _addWhitelistAdmin(_msgSender()); } modifier onlyWhitelistAdmin() { require( isWhitelistAdmin(_msgSender()), "WhitelistAdminRole: caller does not have the WhitelistAdmin role" ); _; } function isWhitelistAdmin(address account) public view returns (bool) { return _whitelistAdmins.has(account); } function addWhitelistAdmin(address account) public onlyWhitelistAdmin { _addWhitelistAdmin(account); } function renounceWhitelistAdmin() public { _removeWhitelistAdmin(_msgSender()); } function _addWhitelistAdmin(address account) internal { _whitelistAdmins.add(account); emit WhitelistAdminAdded(account); } function _removeWhitelistAdmin(address account) internal { _whitelistAdmins.remove(account); emit WhitelistAdminRemoved(account); } } /** * @title ERC165 * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md */ interface IERC165 { /** * @notice Query if a contract implements an interface * @dev Interface identification is specified in ERC-165. This function * uses less than 30,000 gas * @param _interfaceId The interface identifier, as specified in ERC-165 */ function supportsInterface(bytes4 _interfaceId) external view returns (bool); } /** * @dev ERC-1155 interface for accepting safe transfers. */ interface IERC1155TokenReceiver { /** * @notice Handle the receipt of a single ERC1155 token type * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated * This function MAY throw to revert and reject the transfer * Return of other amount than the magic value MUST result in the transaction being reverted * Note: The token contract address is always the message sender * @param _operator The address which called the `safeTransferFrom` function * @param _from The address which previously owned the token * @param _id The id of the token being transferred * @param _amount The amount of tokens being transferred * @param _data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` */ function onERC1155Received( address _operator, address _from, uint256 _id, uint256 _amount, bytes calldata _data ) external returns (bytes4); /** * @notice Handle the receipt of multiple ERC1155 token types * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated * This function MAY throw to revert and reject the transfer * Return of other amount than the magic value WILL result in the transaction being reverted * Note: The token contract address is always the message sender * @param _operator The address which called the `safeBatchTransferFrom` function * @param _from The address which previously owned the token * @param _ids An array containing ids of each token being transferred * @param _amounts An array containing amounts of each token being transferred * @param _data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` */ function onERC1155BatchReceived( address _operator, address _from, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data ) external returns (bytes4); /** * @notice Indicates whether a contract implements the `ERC1155TokenReceiver` functions and so can accept ERC1155 token types. * @param interfaceID The ERC-165 interface ID that is queried for support.s * @dev This function MUST return true if it implements the ERC1155TokenReceiver interface and ERC-165 interface. * This function MUST NOT consume more than 5,000 gas. * @return Wheter ERC-165 or ERC1155TokenReceiver interfaces are supported. */ function supportsInterface(bytes4 interfaceID) external view returns (bool); } interface IERC1155 { // Events /** * @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning * Operator MUST be msg.sender * When minting/creating tokens, the `_from` field MUST be set to `0x0` * When burning/destroying tokens, the `_to` field MUST be set to `0x0` * The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID * To broadcast the existence of a token ID with no initial balance, the contract SHOULD emit the TransferSingle event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0 */ event TransferSingle( address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _amount ); /** * @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning * Operator MUST be msg.sender * When minting/creating tokens, the `_from` field MUST be set to `0x0` * When burning/destroying tokens, the `_to` field MUST be set to `0x0` * The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID * To broadcast the existence of multiple token IDs with no initial balance, this SHOULD emit the TransferBatch event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0 */ event TransferBatch( address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _amounts ); /** * @dev MUST emit when an approval is updated */ event ApprovalForAll( address indexed _owner, address indexed _operator, bool _approved ); /** * @dev MUST emit when the URI is updated for a token ID * URIs are defined in RFC 3986 * The URI MUST point a JSON file that conforms to the "ERC-1155 Metadata JSON Schema" */ event URI(string _amount, uint256 indexed _id); /** * @notice Transfers amount of an _id from the _from address to the _to address specified * @dev MUST emit TransferSingle event on success * Caller must be approved to manage the _from account's tokens (see isApprovedForAll) * MUST throw if `_to` is the zero address * MUST throw if balance of sender for token `_id` is lower than the `_amount` sent * MUST throw on any other error * When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). If so, it MUST call `onERC1155Received` on `_to` and revert if the return amount is not `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * @param _from Source address * @param _to Target address * @param _id ID of the token type * @param _amount Transfered amount * @param _data Additional data with no specified format, sent in call to `_to` */ function safeTransferFrom( address _from, address _to, uint256 _id, uint256 _amount, bytes calldata _data ) external; /** * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call) * @dev MUST emit TransferBatch event on success * Caller must be approved to manage the _from account's tokens (see isApprovedForAll) * MUST throw if `_to` is the zero address * MUST throw if length of `_ids` is not the same as length of `_amounts` * MUST throw if any of the balance of sender for token `_ids` is lower than the respective `_amounts` sent * MUST throw on any other error * When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). If so, it MUST call `onERC1155BatchReceived` on `_to` and revert if the return amount is not `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * Transfers and events MUST occur in the array order they were submitted (_ids[0] before _ids[1], etc) * @param _from Source addresses * @param _to Target addresses * @param _ids IDs of each token type * @param _amounts Transfer amounts per token type * @param _data Additional data with no specified format, sent in call to `_to` */ function safeBatchTransferFrom( address _from, address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data ) external; /** * @notice Get the balance of an account's Tokens * @param _owner The address of the token holder * @param _id ID of the Token * @return The _owner's balance of the Token type requested */ function balanceOf(address _owner, uint256 _id) external view returns (uint256); /** * @notice Get the balance of multiple account/token pairs * @param _owners The addresses of the token holders * @param _ids ID of the Tokens * @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair) */ function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external view returns (uint256[] memory); /** * @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens * @dev MUST emit the ApprovalForAll event on success * @param _operator Address to add to the set of authorized operators * @param _approved True if the operator is approved, false to revoke approval */ function setApprovalForAll(address _operator, bool _approved) external; /** * @notice Queries the approval status of an operator for a given owner * @param _owner The owner of the Tokens * @param _operator Address of authorized operator * @return True if the operator is approved, false if not */ function isApprovedForAll(address _owner, address _operator) external view returns (bool isOperator); } /** * @dev Implementation of Multi-Token Standard contract */ contract ERC1155 is IERC165 { using SafeMath for uint256; using Address for address; /***********************************| | Variables and Events | |__________________________________*/ // onReceive function signatures bytes4 internal constant ERC1155_RECEIVED_VALUE = 0xf23a6e61; bytes4 internal constant ERC1155_BATCH_RECEIVED_VALUE = 0xbc197c81; // Objects balances mapping(address => mapping(uint256 => uint256)) internal balances; // Operator Functions mapping(address => mapping(address => bool)) internal operators; // Events event TransferSingle( address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _amount ); event TransferBatch( address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _amounts ); event ApprovalForAll( address indexed _owner, address indexed _operator, bool _approved ); event URI(string _uri, uint256 indexed _id); /***********************************| | Public Transfer Functions | |__________________________________*/ /** * @notice Transfers amount amount of an _id from the _from address to the _to address specified * @param _from Source address * @param _to Target address * @param _id ID of the token type * @param _amount Transfered amount * @param _data Additional data with no specified format, sent in call to `_to` */ function safeTransferFrom( address _from, address _to, uint256 _id, uint256 _amount, bytes memory _data ) public { require( (msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155#safeTransferFrom: INVALID_OPERATOR" ); require( _to != address(0), "ERC1155#safeTransferFrom: INVALID_RECIPIENT" ); // require(_amount >= balances[_from][_id]) is not necessary since checked with safemath operations _safeTransferFrom(_from, _to, _id, _amount); _callonERC1155Received(_from, _to, _id, _amount, _data); } /** * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call) * @param _from Source addresses * @param _to Target addresses * @param _ids IDs of each token type * @param _amounts Transfer amounts per token type * @param _data Additional data with no specified format, sent in call to `_to` */ function safeBatchTransferFrom( address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data ) public { // Requirements require( (msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155#safeBatchTransferFrom: INVALID_OPERATOR" ); require( _to != address(0), "ERC1155#safeBatchTransferFrom: INVALID_RECIPIENT" ); _safeBatchTransferFrom(_from, _to, _ids, _amounts); _callonERC1155BatchReceived(_from, _to, _ids, _amounts, _data); } /***********************************| | Internal Transfer Functions | |__________________________________*/ /** * @notice Transfers amount amount of an _id from the _from address to the _to address specified * @param _from Source address * @param _to Target address * @param _id ID of the token type * @param _amount Transfered amount */ function _safeTransferFrom( address _from, address _to, uint256 _id, uint256 _amount ) internal { // Update balances balances[_from][_id] = balances[_from][_id].sub(_amount); // Subtract amount balances[_to][_id] = balances[_to][_id].add(_amount); // Add amount // Emit event emit TransferSingle(msg.sender, _from, _to, _id, _amount); } /** * @notice Verifies if receiver is contract and if so, calls (_to).onERC1155Received(...) */ function _callonERC1155Received( address _from, address _to, uint256 _id, uint256 _amount, bytes memory _data ) internal { // Check if recipient is contract if (_to.isContract()) { bytes4 retval = IERC1155TokenReceiver(_to).onERC1155Received( msg.sender, _from, _id, _amount, _data ); require( retval == ERC1155_RECEIVED_VALUE, "ERC1155#_callonERC1155Received: INVALID_ON_RECEIVE_MESSAGE" ); } } /** * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call) * @param _from Source addresses * @param _to Target addresses * @param _ids IDs of each token type * @param _amounts Transfer amounts per token type */ function _safeBatchTransferFrom( address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts ) internal { require( _ids.length == _amounts.length, "ERC1155#_safeBatchTransferFrom: INVALID_ARRAYS_LENGTH" ); // Number of transfer to execute uint256 nTransfer = _ids.length; // Executing all transfers for (uint256 i = 0; i < nTransfer; i++) { // Update storage balance of previous bin balances[_from][_ids[i]] = balances[_from][_ids[i]].sub( _amounts[i] ); balances[_to][_ids[i]] = balances[_to][_ids[i]].add(_amounts[i]); } // Emit event emit TransferBatch(msg.sender, _from, _to, _ids, _amounts); } /** * @notice Verifies if receiver is contract and if so, calls (_to).onERC1155BatchReceived(...) */ function _callonERC1155BatchReceived( address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data ) internal { // Pass data if recipient is contract if (_to.isContract()) { bytes4 retval = IERC1155TokenReceiver(_to).onERC1155BatchReceived( msg.sender, _from, _ids, _amounts, _data ); require( retval == ERC1155_BATCH_RECEIVED_VALUE, "ERC1155#_callonERC1155BatchReceived: INVALID_ON_RECEIVE_MESSAGE" ); } } /***********************************| | Operator Functions | |__________________________________*/ /** * @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens * @param _operator Address to add to the set of authorized operators * @param _approved True if the operator is approved, false to revoke approval */ function setApprovalForAll(address _operator, bool _approved) external { // Update operator status operators[msg.sender][_operator] = _approved; emit ApprovalForAll(msg.sender, _operator, _approved); } /** * @notice Queries the approval status of an operator for a given owner * @param _owner The owner of the Tokens * @param _operator Address of authorized operator * @return True if the operator is approved, false if not */ function isApprovedForAll(address _owner, address _operator) public view returns (bool isOperator) { return operators[_owner][_operator]; } /***********************************| | Balance Functions | |__________________________________*/ /** * @notice Get the balance of an account's Tokens * @param _owner The address of the token holder * @param _id ID of the Token * @return The _owner's balance of the Token type requested */ function balanceOf(address _owner, uint256 _id) public view returns (uint256) { return balances[_owner][_id]; } /** * @notice Get the balance of multiple account/token pairs * @param _owners The addresses of the token holders * @param _ids ID of the Tokens * @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair) */ function balanceOfBatch(address[] memory _owners, uint256[] memory _ids) public view returns (uint256[] memory) { require( _owners.length == _ids.length, "ERC1155#balanceOfBatch: INVALID_ARRAY_LENGTH" ); // Variables uint256[] memory batchBalances = new uint256[](_owners.length); // Iterate over each owner and token ID for (uint256 i = 0; i < _owners.length; i++) { batchBalances[i] = balances[_owners[i]][_ids[i]]; } return batchBalances; } /***********************************| | ERC165 Functions | |__________________________________*/ /** * INTERFACE_SIGNATURE_ERC165 = bytes4(keccak256("supportsInterface(bytes4)")); */ bytes4 private constant INTERFACE_SIGNATURE_ERC165 = 0x01ffc9a7; /** * INTERFACE_SIGNATURE_ERC1155 = * bytes4(keccak256("safeTransferFrom(address,address,uint256,uint256,bytes)")) ^ * bytes4(keccak256("safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)")) ^ * bytes4(keccak256("balanceOf(address,uint256)")) ^ * bytes4(keccak256("balanceOfBatch(address[],uint256[])")) ^ * bytes4(keccak256("setApprovalForAll(address,bool)")) ^ * bytes4(keccak256("isApprovedForAll(address,address)")); */ bytes4 private constant INTERFACE_SIGNATURE_ERC1155 = 0xd9b67a26; /** * @notice Query if a contract implements an interface * @param _interfaceID The interface identifier, as specified in ERC-165 * @return `true` if the contract implements `_interfaceID` and */ function supportsInterface(bytes4 _interfaceID) external view returns (bool) { if ( _interfaceID == INTERFACE_SIGNATURE_ERC165 || _interfaceID == INTERFACE_SIGNATURE_ERC1155 ) { return true; } return false; } } /** * @notice Contract that handles metadata related methods. * @dev Methods assume a deterministic generation of URI based on token IDs. * Methods also assume that URI uses hex representation of token IDs. */ contract ERC1155Metadata { // URI's default URI prefix string internal baseMetadataURI; event URI(string _uri, uint256 indexed _id); /***********************************| | Metadata Public Function s | |__________________________________*/ /** * @notice A distinct Uniform Resource Identifier (URI) for a given token. * @dev URIs are defined in RFC 3986. * URIs are assumed to be deterministically generated based on token ID * Token IDs are assumed to be represented in their hex format in URIs * @return URI string */ function uri(uint256 _id) public view returns (string memory) { return string(abi.encodePacked(baseMetadataURI, _uint2str(_id), ".json")); } /***********************************| | Metadata Internal Functions | |__________________________________*/ /** * @notice Will emit default URI log event for corresponding token _id * @param _tokenIDs Array of IDs of tokens to log default URI */ function _logURIs(uint256[] memory _tokenIDs) internal { string memory baseURL = baseMetadataURI; string memory tokenURI; for (uint256 i = 0; i < _tokenIDs.length; i++) { tokenURI = string( abi.encodePacked(baseURL, _uint2str(_tokenIDs[i]), ".json") ); emit URI(tokenURI, _tokenIDs[i]); } } /** * @notice Will emit a specific URI log event for corresponding token * @param _tokenIDs IDs of the token corresponding to the _uris logged * @param _URIs The URIs of the specified _tokenIDs */ function _logURIs(uint256[] memory _tokenIDs, string[] memory _URIs) internal { require( _tokenIDs.length == _URIs.length, "ERC1155Metadata#_logURIs: INVALID_ARRAYS_LENGTH" ); for (uint256 i = 0; i < _tokenIDs.length; i++) { emit URI(_URIs[i], _tokenIDs[i]); } } /** * @notice Will update the base URL of token's URI * @param _newBaseMetadataURI New base URL of token's URI */ function _setBaseMetadataURI(string memory _newBaseMetadataURI) internal { baseMetadataURI = _newBaseMetadataURI; } /***********************************| | Utility Internal Functions | |__________________________________*/ /** * @notice Convert uint256 to string * @param _i Unsigned integer to convert to string */ function _uint2str(uint256 _i) internal pure returns (string memory _uintAsString) { if (_i == 0) { return "0"; } uint256 j = _i; uint256 ii = _i; uint256 len; // Get number of bytes while (j != 0) { len++; j /= 10; } bytes memory bstr = new bytes(len); uint256 k = len - 1; // Get each individual ASCII while (ii != 0) { bstr[k--] = bytes1(uint8(48 + (ii % 10))); ii /= 10; } // Convert to string return string(bstr); } } /** * @dev Multi-Fungible Tokens with minting and burning methods. These methods assume * a parent contract to be executed as they are `internal` functions */ contract ERC1155MintBurn is ERC1155 { /****************************************| | Minting Functions | |_______________________________________*/ /** * @notice Mint _amount of tokens of a given id * @param _to The address to mint tokens to * @param _id Token id to mint * @param _amount The amount to be minted * @param _data Data to pass if receiver is contract */ function _mint( address _to, uint256 _id, uint256 _amount, bytes memory _data ) internal { // Add _amount balances[_to][_id] = balances[_to][_id].add(_amount); // Emit event emit TransferSingle(msg.sender, address(0x0), _to, _id, _amount); // Calling onReceive method if recipient is contract _callonERC1155Received(address(0x0), _to, _id, _amount, _data); } /** * @notice Mint tokens for each ids in _ids * @param _to The address to mint tokens to * @param _ids Array of ids to mint * @param _amounts Array of amount of tokens to mint per id * @param _data Data to pass if receiver is contract */ function _batchMint( address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data ) internal { require( _ids.length == _amounts.length, "ERC1155MintBurn#batchMint: INVALID_ARRAYS_LENGTH" ); // Number of mints to execute uint256 nMint = _ids.length; // Executing all minting for (uint256 i = 0; i < nMint; i++) { // Update storage balance balances[_to][_ids[i]] = balances[_to][_ids[i]].add(_amounts[i]); } // Emit batch mint event emit TransferBatch(msg.sender, address(0x0), _to, _ids, _amounts); // Calling onReceive method if recipient is contract _callonERC1155BatchReceived(address(0x0), _to, _ids, _amounts, _data); } /****************************************| | Burning Functions | |_______________________________________*/ /** * @notice Burn _amount of tokens of a given token id * @param _from The address to burn tokens from * @param _id Token id to burn * @param _amount The amount to be burned */ function _burn( address _from, uint256 _id, uint256 _amount ) internal { //Substract _amount balances[_from][_id] = balances[_from][_id].sub(_amount); // Emit event emit TransferSingle(msg.sender, _from, address(0x0), _id, _amount); } /** * @notice Burn tokens of given token id for each (_ids[i], _amounts[i]) pair * @param _from The address to burn tokens from * @param _ids Array of token ids to burn * @param _amounts Array of the amount to be burned */ function _batchBurn( address _from, uint256[] memory _ids, uint256[] memory _amounts ) internal { require( _ids.length == _amounts.length, "ERC1155MintBurn#batchBurn: INVALID_ARRAYS_LENGTH" ); // Number of mints to execute uint256 nBurn = _ids.length; // Executing all minting for (uint256 i = 0; i < nBurn; i++) { // Update storage balance balances[_from][_ids[i]] = balances[_from][_ids[i]].sub( _amounts[i] ); } // Emit batch mint event emit TransferBatch(msg.sender, _from, address(0x0), _ids, _amounts); } } library Strings { // via https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol function strConcat( string memory _a, string memory _b, string memory _c, string memory _d, string memory _e ) internal pure returns (string memory) { bytes memory _ba = bytes(_a); bytes memory _bb = bytes(_b); bytes memory _bc = bytes(_c); bytes memory _bd = bytes(_d); bytes memory _be = bytes(_e); string memory abcde = new string( _ba.length + _bb.length + _bc.length + _bd.length + _be.length ); bytes memory babcde = bytes(abcde); uint256 k = 0; for (uint256 i = 0; i < _ba.length; i++) babcde[k++] = _ba[i]; for (uint256 i = 0; i < _bb.length; i++) babcde[k++] = _bb[i]; for (uint256 i = 0; i < _bc.length; i++) babcde[k++] = _bc[i]; for (uint256 i = 0; i < _bd.length; i++) babcde[k++] = _bd[i]; for (uint256 i = 0; i < _be.length; i++) babcde[k++] = _be[i]; return string(babcde); } function strConcat( string memory _a, string memory _b, string memory _c, string memory _d ) internal pure returns (string memory) { return strConcat(_a, _b, _c, _d, ""); } function strConcat( string memory _a, string memory _b, string memory _c ) internal pure returns (string memory) { return strConcat(_a, _b, _c, "", ""); } function strConcat(string memory _a, string memory _b) internal pure returns (string memory) { return strConcat(_a, _b, "", "", ""); } function uint2str(uint256 _i) internal pure returns (string memory _uintAsString) { if (_i == 0) { return "0"; } uint256 j = _i; uint256 len; while (j != 0) { len++; j /= 10; } bytes memory bstr = new bytes(len); uint256 k = len - 1; while (_i != 0) { bstr[k--] = bytes1(uint8(48 + (_i % 10))); _i /= 10; } return string(bstr); } } contract OwnableDelegateProxy {} contract ProxyRegistry { mapping(address => OwnableDelegateProxy) public proxies; } /** * @title ERC1155Tradable * ERC1155Tradable - ERC1155 contract that whitelists an operator address, * has create and mint functionality, and supports useful standards from OpenZeppelin, like _exists(), name(), symbol(), and totalSupply() */ contract ERC1155Tradable is ERC1155, ERC1155MintBurn, ERC1155Metadata, Ownable, MinterRole, WhitelistAdminRole { using Strings for string; address proxyRegistryAddress; uint256 internal _currentTokenID = 0; mapping(uint256 => address) public creators; mapping(uint256 => uint256) public tokenSupply; mapping(uint256 => uint256) public tokenMaxSupply; // Contract name string public name; // Contract symbol string public symbol; constructor( string memory _name, string memory _symbol, address _proxyRegistryAddress ) public { name = _name; symbol = _symbol; proxyRegistryAddress = _proxyRegistryAddress; } function removeWhitelistAdmin(address account) public onlyOwner { _removeWhitelistAdmin(account); } function removeMinter(address account) public onlyOwner { _removeMinter(account); } function uri(uint256 _id) public view returns (string memory) { require(_exists(_id), "ERC721Tradable#uri: NONEXISTENT_TOKEN"); return Strings.strConcat(baseMetadataURI, Strings.uint2str(_id)); } /** * @dev Returns the total quantity for a token ID * @param _id uint256 ID of the token to query * @return amount of token in existence */ function totalSupply(uint256 _id) public view returns (uint256) { return tokenSupply[_id]; } /** * @dev Returns the max quantity for a token ID * @param _id uint256 ID of the token to query * @return amount of token in existence */ function maxSupply(uint256 _id) public view returns (uint256) { return tokenMaxSupply[_id]; } /** * @dev Will update the base URL of token's URI * @param _newBaseMetadataURI New base URL of token's URI */ function setBaseMetadataURI(string memory _newBaseMetadataURI) public onlyWhitelistAdmin { _setBaseMetadataURI(_newBaseMetadataURI); } /** * @dev Creates a new token type and assigns _initialSupply to an address * @param _maxSupply max supply allowed * @param _initialSupply Optional amount to supply the first owner * @param _uri Optional URI for this token type * @param _data Optional data to pass if receiver is contract * @return The newly created token ID */ function create( uint256 _maxSupply, uint256 _initialSupply, string memory _uri, bytes memory _data ) public onlyWhitelistAdmin returns (uint256 tokenId) { require(_initialSupply <= _maxSupply, "_initialSupply > _maxSupply"); uint256 _id = _getNextTokenID(); _incrementTokenTypeId(); creators[_id] = msg.sender; if (bytes(_uri).length > 0) { emit URI(_uri, _id); } if (_initialSupply != 0) _mint(msg.sender, _id, _initialSupply, _data); tokenSupply[_id] = _initialSupply; tokenMaxSupply[_id] = _maxSupply; return _id; } /** * @dev Creates multiple new token types and assigns _initialSupply[i] of each token type, to an address * @param _maxSupply Array of max supplies allowed * @param _initialSupply Array of optional amounts to supply the first owner * @param _uri Array of optional URIs for each token type * @param _data Optional data to pass if receiver is contract. Same for each new token type * @return Array of newly created token IDs */ function batchCreate( uint256[] calldata _maxSupply, uint256[] calldata _initialSupply, string[] calldata _uri, bytes calldata _data ) external onlyWhitelistAdmin returns (uint256[] memory) { require( _initialSupply.length == _maxSupply.length && _uri.length == _maxSupply.length, "Array lengths mismatch" ); uint256[] memory _ids = new uint256[](_maxSupply.length); uint256 _id = 0; for (uint256 index = 0; index < _maxSupply.length; index++) { _id = create( _maxSupply[index], _initialSupply[index], _uri[index], _data ); _ids[index] = _id; } return _ids; } /** * @dev Mints some amount of tokens to an address * @param _to Address of the future owner of the token * @param _id Token ID to mint * @param _quantity Amount of tokens to mint * @param _data Data to pass if receiver is contract */ function mint( address _to, uint256 _id, uint256 _quantity, bytes memory _data ) public onlyMinter { uint256 tokenId = _id; require( tokenSupply[tokenId] < tokenMaxSupply[tokenId], "Max supply reached" ); _mint(_to, _id, _quantity, _data); tokenSupply[_id] = tokenSupply[_id].add(_quantity); } /** * @dev Mints some amount of tokens to an address * @param _to The address to mint tokens to * @param _ids Array of ids to mint * @param _amounts Array of amount of tokens to mint per id * @param _data Data to pass if receiver is contract */ function batchMint( address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data ) public onlyMinter { uint256 nMints = _ids.length; for (uint256 i = 0; i < nMints; i++) { uint256 tokenId = _ids[i]; require( tokenSupply[tokenId] < tokenMaxSupply[tokenId], "Max supply reached" ); tokenSupply[tokenId] = tokenSupply[tokenId].add(_amounts[i]); } _batchMint(_to, _ids, _amounts, _data); } /** * @notice Burn _amount of tokens of a given token id * @param _from The address to burn tokens from * @param _id Token id to burn * @param _amount The amount to be burned */ function burn( address _from, uint256 _id, uint256 _amount ) public onlyOwner { tokenSupply[_id] = tokenSupply[_id].sub(_amount); _burn(_from, _id, _amount); } /** * Override isApprovedForAll to whitelist user's OpenSea proxy accounts to enable gas-free listings. */ function isApprovedForAll(address _owner, address _operator) public view returns (bool isOperator) { // Whitelist OpenSea proxy contract for easy trading. ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress); if (address(proxyRegistry.proxies(_owner)) == _operator) { return true; } return ERC1155.isApprovedForAll(_owner, _operator); } /** * @dev Returns whether the specified token exists by checking to see if it has a creator * @param _id uint256 ID of the token to query the existence of * @return bool whether the token exists */ function _exists(uint256 _id) internal view returns (bool) { return creators[_id] != address(0); } /** * @dev calculates the next token ID based on value of _currentTokenID * @return uint256 for the next token ID */ function _getNextTokenID() private view returns (uint256) { return _currentTokenID.add(1); } /** * @dev increments the value of _currentTokenID */ function _incrementTokenTypeId() private { _currentTokenID++; } }
pragma solidity ^0.5.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } }
pragma solidity ^0.5.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. Does not include * the optional functions; to access them see {ERC20Detailed}. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * 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); }
pragma solidity ^0.5.5; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } /** * @dev Converts an `address` into `address payable`. Note that this is * simply a type cast: the actual underlying value is not changed. * * _Available since v2.4.0._ */ function toPayable(address account) internal pure returns (address payable) { return address(uint160(account)); } /** * @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]. * * _Available since v2.4.0._ */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-call-value (bool success, ) = recipient.call.value(amount)(""); require(success, "Address: unable to send value, recipient may have reverted"); } }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_proxyRegistryAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":false,"internalType":"bool","name":"_approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"strategy","type":"address"}],"name":"EndedUsingNFT","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"MinterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"MinterRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"strategy","type":"address"}],"name":"StartedUsingNFT","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"StrategyAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"StrategyRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"_uri","type":"string"},{"indexed":true,"internalType":"uint256","name":"_id","type":"uint256"}],"name":"URI","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"WhitelistAdminAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"WhitelistAdminRemoved","type":"event"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addStrategy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addWhitelistAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address[]","name":"_owners","type":"address[]"},{"internalType":"uint256[]","name":"_ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256[]","name":"_maxSupply","type":"uint256[]"},{"internalType":"uint256[]","name":"_initialSupply","type":"uint256[]"},{"internalType":"string[]","name":"_uri","type":"string[]"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"batchCreate","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"batchMint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_maxSupply","type":"uint256"},{"internalType":"uint256","name":"_initialSupply","type":"uint256"},{"internalType":"string","name":"_uri","type":"string"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"create","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"creators","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"endUsingNFT","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"address","name":"_strategy","type":"address"}],"name":"getStratUseCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getTotalUseCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"isOperator","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isStrategy","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isWhitelistAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_quantity","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeStrategy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeWhitelistAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceWhitelistAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"bool","name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"_newBaseMetadataURI","type":"string"}],"name":"setBaseMetadataURI","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"startUsingNFT","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes4","name":"_interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenMaxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405260006007553480156200001657600080fd5b50604051620061dc380380620061dc83398181016040526200003c919081019062000573565b6040518060400160405280600d81526020017f5374616b652044414f204e4654000000000000000000000000000000000000008152506040518060400160405280600581526020017f73644e4654000000000000000000000000000000000000000000000000000000815250826000620000bb6200024960201b60201c565b905080600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3506200017a6200016e6200024960201b60201c565b6200025160201b60201c565b6200019a6200018e6200024960201b60201c565b620002b260201b60201c565b82600b9080519060200190620001b2929190620004ad565b5081600c9080519060200190620001cb929190620004ad565b5080600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050506200023a6040518060800160405280605a815260200162006182605a91396200031360201b60201c565b60de60078190555050620006ec565b600033905090565b6200026c8160046200032f60201b620034061790919060201c565b8073ffffffffffffffffffffffffffffffffffffffff167f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f660405160405180910390a250565b620002cd8160056200032f60201b620034061790919060201c565b8073ffffffffffffffffffffffffffffffffffffffff167f22380c05984257a1cb900161c713dd71d39e74820f1aea43bd3f1bdd2096129960405160405180910390a250565b80600290805190602001906200032b929190620004ad565b5050565b620003418282620003e260201b60201c565b1562000384576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200037b9062000649565b60405180910390fd5b60018260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141562000456576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200044d906200066b565b60405180910390fd5b8260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620004f057805160ff191683800117855562000521565b8280016001018555821562000521579182015b828111156200052057825182559160200191906001019062000503565b5b50905062000530919062000534565b5090565b6200055991905b80821115620005555760008160009055506001016200053b565b5090565b90565b6000815190506200056d81620006d2565b92915050565b6000602082840312156200058657600080fd5b600062000596848285016200055c565b91505092915050565b6000620005ae601f836200068d565b91507f526f6c65733a206163636f756e7420616c72656164792068617320726f6c65006000830152602082019050919050565b6000620005f06022836200068d565b91507f526f6c65733a206163636f756e7420697320746865207a65726f20616464726560008301527f73730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000602082019050818103600083015262000664816200059f565b9050919050565b600060208201905081810360008301526200068681620005e1565b9050919050565b600082825260208201905092915050565b6000620006ab82620006b2565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b620006dd816200069e565b8114620006e957600080fd5b50565b615a8680620006fc6000396000f3fe608060405234801561001057600080fd5b50600436106102515760003560e01c80637e518ec811610146578063b48ab8b6116100c3578063cd53d08e11610087578063cd53d08e14610728578063e8a3d48514610758578063e985e9c514610776578063f242432a146107a6578063f2fde38b146107c2578063f5298aca146107de57610251565b8063b48ab8b614610660578063bb5f747b1461067c578063bd3b433d146106ac578063bd85b039146106c8578063c47b9bd3146106f857610251565b8063983b2d561161010a578063983b2d56146105be57806398650275146105da578063a22cb465146105e4578063aa271e1a14610600578063b09ddf7b1461063057610251565b80637e518ec814610518578063869f7594146105345780638da5cb5b146105645780638f32d59b1461058257806395d89b41146105a057610251565b80632e8ebaae116101d4578063608cf5f411610198578063608cf5f41461048a5780636897e974146104ba578063715018a6146104d6578063731133e9146104e05780637362d9c8146104fc57610251565b80632e8ebaae146103e85780632eb2c2d6146104185780633092afd5146104345780634c5a628c146104505780634e1273f41461045a57610251565b8063175188e81161021b578063175188e814610334578063223e5479146103505780632693ebf21461036c5780632a634e521461039c5780632e1edf69146103b857610251565b80624221f014610256578062fdd58e1461028657806301ffc9a7146102b657806306fdde03146102e65780630e89341c14610304575b600080fd5b610270600480360361026b9190810190614773565b6107fa565b60405161027d91906156dc565b60405180910390f35b6102a0600480360361029b9190810190614421565b610812565b6040516102ad91906156dc565b60405180910390f35b6102d060048036036102cb91908101906146b7565b61086c565b6040516102dd919061537d565b60405180910390f35b6102ee61091d565b6040516102fb9190615398565b60405180910390f35b61031e60048036036103199190810190614773565b6109bb565b60405161032b91906153ba565b60405180910390f35b61034e60048036036103499190810190614187565b610ab8565b005b61036a60048036036103659190810190614187565b610b0b565b005b61038660048036036103819190810190614773565b610b5e565b60405161039391906156dc565b60405180910390f35b6103b660048036036103b19190810190614421565b610b76565b005b6103d260048036036103cd91908101906145e2565b610e0e565b6040516103df9190615324565b60405180910390f35b61040260048036036103fd9190810190614187565b611055565b60405161040f919061537d565b60405180910390f35b610432600480360361042d91908101906141ec565b611072565b005b61044e60048036036104499190810190614187565b61114f565b005b6104586111a2565b005b610474600480360361046f9190810190614576565b6111b4565b6040516104819190615324565b60405180910390f35b6104a4600480360361049f919081019061445d565b6112e4565b6040516104b191906156dc565b60405180910390f35b6104d460048036036104cf9190810190614187565b61137d565b005b6104de6113d0565b005b6104fa60048036036104f591908101906144fb565b6114d8565b005b61051660048036036105119190810190614187565b6115e4565b005b610532600480360361052d9190810190614732565b61163f565b005b61054e60048036036105499190810190614773565b61169a565b60405161055b91906156dc565b60405180910390f35b61056c6116b7565b6040516105799190615247565b60405180910390f35b61058a6116e1565b604051610597919061537d565b60405180910390f35b6105a8611740565b6040516105b59190615398565b60405180910390f35b6105d860048036036105d39190810190614187565b6117de565b005b6105e2611839565b005b6105fe60048036036105f991908101906143e5565b61184b565b005b61061a60048036036106159190810190614187565b611948565b604051610627919061537d565b60405180910390f35b61064a6004803603610645919081019061479c565b611965565b60405161065791906156dc565b60405180910390f35b61067a6004803603610675919081019061433a565b611af3565b005b61069660048036036106919190810190614187565b611c48565b6040516106a3919061537d565b60405180910390f35b6106c660048036036106c19190810190614421565b611c65565b005b6106e260048036036106dd9190810190614773565b611f8f565b6040516106ef91906156dc565b60405180910390f35b610712600480360361070d9190810190614421565b611fac565b60405161071f91906156dc565b60405180910390f35b610742600480360361073d9190810190614773565b612007565b60405161074f9190615247565b60405180910390f35b61076061203a565b60405161076d91906153ba565b60405180910390f35b610790600480360361078b91908101906141b0565b61205a565b60405161079d919061537d565b60405180910390f35b6107c060048036036107bb91908101906142ab565b61215c565b005b6107dc60048036036107d79190810190614187565b612203565b005b6107f860048036036107f391908101906144ac565b612256565b005b600a6020528060005260406000206000915090505481565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b60006301ffc9a760e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610905575063d9b67a2660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156109135760019050610918565b600090505b919050565b600b8054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156109b35780601f10610988576101008083540402835291602001916109b3565b820191906000526020600020905b81548152906001019060200180831161099657829003601f168201915b505050505081565b60606109c682612340565b610a05576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109fc9061557c565b60405180910390fd5b610ab160028054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a9e5780601f10610a7357610100808354040283529160200191610a9e565b820191906000526020600020905b815481529060010190602001808311610a8157829003601f168201915b5050505050610aac846123ac565b6124d9565b9050919050565b610ac06116e1565b610aff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af69061559c565b60405180910390fd5b610b088161251d565b50565b610b136116e1565b610b52576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b499061559c565b60405180910390fd5b610b5b81612577565b50565b60096020528060005260406000206000915090505481565b610b86610b816125d1565b611055565b610bc5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bbc906154fc565b60405180910390fd5b610c666001600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546125d990919063ffffffff16565b600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610d5b6001600e60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000848152602001908152602001600020546125d990919063ffffffff16565b600e60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16818373ffffffffffffffffffffffffffffffffffffffff167f25db6fd0f22c400fcbc6cd08ce9ee28045ee6ad78ba0cf1cd6409f020d0af71560405160405180910390a45050565b6060610e20610e1b6125d1565b611c48565b610e5f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e56906155dc565b60405180910390fd5b8888905087879050148015610e7957508888905085859050145b610eb8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eaf9061543c565b60405180910390fd5b606089899050604051908082528060200260200182016040528015610eec5781602001602082028038833980820191505090505b509050600080905060008090505b8b8b90508110156110435761101b8c8c83818110610f1457fe5b905060200201358b8b84818110610f2757fe5b905060200201358a8a85818110610f3a57fe5b9050602002810180356001602003833603038112610f5757600080fd5b8083019250508135905060208201915067ffffffffffffffff811115610f7c57600080fd5b600181023603821315610f8e57600080fd5b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505089898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611965565b91508183828151811061102a57fe5b6020026020010181815250508080600101915050610efa565b50819250505098975050505050505050565b600061106b82600d61262390919063ffffffff16565b9050919050565b60008351905060008090505b81811015611139576000600e60008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008784815181106110d557fe5b60200260200101518152602001908152602001600020541461112c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111239061561c565b60405180910390fd5b808060010191505061107e565b5061114786868686866126eb565b505050505050565b6111576116e1565b611196576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118d9061559c565b60405180910390fd5b61119f816127fa565b50565b6111b26111ad6125d1565b612854565b565b606081518351146111fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111f1906155fc565b60405180910390fd5b6060835160405190808252806020026020018201604052801561122c5781602001602082028038833980820191505090505b50905060008090505b84518110156112d95760008086838151811061124d57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600085838151811061129d57fe5b60200260200101518152602001908152602001600020548282815181106112c057fe5b6020026020010181815250508080600101915050611235565b508091505092915050565b6000600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490509392505050565b6113856116e1565b6113c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113bb9061559c565b60405180910390fd5b6113cd81612854565b50565b6113d86116e1565b611417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161140e9061559c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6114e86114e36125d1565b611948565b611527576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151e9061551c565b60405180910390fd5b6000839050600a600082815260200190815260200160002054600960008381526020019081526020016000205410611594576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161158b9061567c565b60405180910390fd5b6115a0858585856128ae565b6115c68360096000878152602001908152602001600020546129f690919063ffffffff16565b60096000868152602001908152602001600020819055505050505050565b6115f46115ef6125d1565b611c48565b611633576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161162a906155dc565b60405180910390fd5b61163c81612a4b565b50565b61164f61164a6125d1565b611c48565b61168e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611685906155dc565b60405180910390fd5b61169781612aa5565b50565b6000600a6000838152602001908152602001600020549050919050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166117246125d1565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600c8054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156117d65780601f106117ab576101008083540402835291602001916117d6565b820191906000526020600020905b8154815290600101906020018083116117b957829003601f168201915b505050505081565b6117ee6117e96125d1565b611948565b61182d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118249061551c565b60405180910390fd5b61183681612abf565b50565b6118496118446125d1565b6127fa565b565b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161193c919061537d565b60405180910390a35050565b600061195e82600461262390919063ffffffff16565b9050919050565b60006119776119726125d1565b611c48565b6119b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119ad906155dc565b60405180910390fd5b848411156119f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f0906154dc565b60405180910390fd5b6000611a03612b19565b9050611a0d612b36565b336008600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600084511115611aa257807f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b85604051611a9991906153ba565b60405180910390a25b60008514611ab757611ab6338287866128ae565b5b84600960008381526020019081526020016000208190555085600a60008381526020019081526020016000208190555080915050949350505050565b611b03611afe6125d1565b611948565b611b42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b399061551c565b60405180910390fd5b60008351905060008090505b81811015611c34576000858281518110611b6457fe5b60200260200101519050600a600082815260200190815260200160002054600960008381526020019081526020016000205410611bd6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bcd9061567c565b60405180910390fd5b611c0f858381518110611be557fe5b602002602001015160096000848152602001908152602001600020546129f690919063ffffffff16565b6009600083815260200190815260200160002081905550508080600101915050611b4e565b50611c4185858585612b4a565b5050505050565b6000611c5e82600561262390919063ffffffff16565b9050919050565b611c75611c706125d1565b611055565b611cb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cab906154fc565b60405180910390fd5b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000205411611d46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3d9061549c565b60405180910390fd5b611de76001600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546129f690919063ffffffff16565b600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611edc6001600e60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000848152602001908152602001600020546129f690919063ffffffff16565b600e60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16818373ffffffffffffffffffffffffffffffffffffffff167f3e77ee48716bf1d18813bff935d16a73c0cf954b49a47b54ca941f0d191aa4ec60405160405180910390a45050565b600060096000838152602001908152602001600020549050919050565b6000600e60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b60086020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60606040518060800160405280605081526020016159f460509139905090565b600080600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1663c4552791866040518263ffffffff1660e01b81526004016120d29190615247565b60206040518083038186803b1580156120ea57600080fd5b505afa1580156120fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506121229190810190614709565b73ffffffffffffffffffffffffffffffffffffffff161415612148576001915050612156565b6121528484612d32565b9150505b92915050565b6000600e60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600085815260200190815260200160002054146121ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121e69061561c565b60405180910390fd5b6121fc8585858585612dc6565b5050505050565b61220b6116e1565b61224a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122419061559c565b60405180910390fd5b61225381612ed5565b50565b61225e6116e1565b61229d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122949061559c565b60405180910390fd5b6000600e60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008481526020019081526020016000205414612330576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123279061561c565b60405180910390fd5b61233b838383613005565b505050565b60008073ffffffffffffffffffffffffffffffffffffffff166008600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b606060008214156123f4576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506124d4565b600082905060005b6000821461241e578080600101915050600a828161241657fe5b0491506123fc565b6060816040519080825280601f01601f1916602001820160405280156124535781602001600182028038833980820191505090505b50905060006001830390505b600086146124cc57600a868161247157fe5b0660300160f81b8282806001900393508151811061248b57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a86816124c457fe5b04955061245f565b819450505050505b919050565b60606125158383604051806020016040528060008152506040518060200160405280600081525060405180602001604052806000815250613099565b905092915050565b61253181600d61335f90919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167f09a1db4b80c32706328728508c941a6b954f31eb5affd32f236c1fd405f8fea460405160405180910390a250565b61258b81600d61340690919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167f3f008fd510eae7a9e7bee13513d7b83bef8003d488b5a3d0b0da4de71d6846f160405160405180910390a250565b600033905090565b600061261b83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506134ae565b905092915050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161268b906155bc565b60405180910390fd5b8260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b8473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061272b575061272a853361205a565b5b61276a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127619061563c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156127da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127d19061555c565b60405180910390fd5b6127e685858585613509565b6127f385858585856137d0565b5050505050565b61280e81600461335f90919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb6669260405160405180910390a250565b61286881600561335f90919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167f0a8eb35e5ca14b3d6f28e4abf2f128dbab231a58b56e89beb5d636115001e16560405160405180910390a250565b612910826000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000868152602001908152602001600020546129f690919063ffffffff16565b6000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6286866040516129da9291906156f7565b60405180910390a46129f060008585858561391b565b50505050565b600080828401905083811015612a41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a389061545c565b60405180910390fd5b8091505092915050565b612a5f81600561340690919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167f22380c05984257a1cb900161c713dd71d39e74820f1aea43bd3f1bdd2096129960405160405180910390a250565b8060029080519060200190612abb929190613dd8565b5050565b612ad381600461340690919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f660405160405180910390a250565b6000612b3160016007546129f690919063ffffffff16565b905090565b600760008154809291906001019190505550565b8151835114612b8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b859061565c565b60405180910390fd5b60008351905060008090505b81811015612c9d57612c2a848281518110612bb157fe5b60200260200101516000808973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000888581518110612c0557fe5b60200260200101518152602001908152602001600020546129f690919063ffffffff16565b6000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000878481518110612c7657fe5b60200260200101518152602001908152602001600020819055508080600101915050612b9a565b508473ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051612d15929190615346565b60405180910390a4612d2b6000868686866137d0565b5050505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b8473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480612e065750612e05853361205a565b5b612e45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e3c9061547c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415612eb5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612eac906153dc565b60405180910390fd5b612ec185858585613a66565b612ece858585858561391b565b5050505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612f45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f3c9061541c565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61300d6116e1565b61304c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130439061559c565b60405180910390fd5b6130728160096000858152602001908152602001600020546125d990919063ffffffff16565b6009600084815260200190815260200160002081905550613094838383613c54565b505050565b6060808690506060869050606086905060608690506060869050606081518351855187518951010101016040519080825280601f01601f1916602001820160405280156130f55781602001600182028038833980820191505090505b5090506060819050600080905060008090505b88518110156131765788818151811061311d57fe5b602001015160f81c60f81b83838060010194508151811061313a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508080600101915050613108565b5060008090505b87518110156131eb5787818151811061319257fe5b602001015160f81c60f81b8383806001019450815181106131af57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350808060010191505061317d565b5060008090505b86518110156132605786818151811061320757fe5b602001015160f81c60f81b83838060010194508151811061322457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080806001019150506131f2565b5060008090505b85518110156132d55785818151811061327c57fe5b602001015160f81c60f81b83838060010194508151811061329957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508080600101915050613267565b5060008090505b845181101561334a578481815181106132f157fe5b602001015160f81c60f81b83838060010194508151811061330e57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080806001019150506132dc565b50819850505050505050505095945050505050565b6133698282612623565b6133a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161339f9061553c565b60405180910390fd5b60008260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6134108282612623565b15613450576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613447906153fc565b60405180910390fd5b60018260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b60008383111582906134f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134ed91906153ba565b60405180910390fd5b5060008385039050809150509392505050565b805182511461354d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613544906154bc565b60405180910390fd5b60008251905060008090505b8181101561374a576135e983828151811061357057fe5b60200260200101516000808973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008785815181106135c457fe5b60200260200101518152602001908152602001600020546125d990919063ffffffff16565b6000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600086848151811061363557fe5b60200260200101518152602001908152602001600020819055506136d783828151811061365e57fe5b60200260200101516000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008785815181106136b257fe5b60200260200101518152602001908152602001600020546129f690919063ffffffff16565b6000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600086848151811061372357fe5b60200260200101518152602001908152602001600020819055508080600101915050613559565b508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb86866040516137c1929190615346565b60405180910390a45050505050565b6137ef8473ffffffffffffffffffffffffffffffffffffffff16613d8d565b156139145760008473ffffffffffffffffffffffffffffffffffffffff1663bc197c8133888787876040518663ffffffff1660e01b8152600401613837959493929190615262565b602060405180830381600087803b15801561385157600080fd5b505af1158015613865573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061388991908101906146e0565b905063bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614613912576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139099061569c565b60405180910390fd5b505b5050505050565b61393a8473ffffffffffffffffffffffffffffffffffffffff16613d8d565b15613a5f5760008473ffffffffffffffffffffffffffffffffffffffff1663f23a6e6133888787876040518663ffffffff1660e01b81526004016139829594939291906152ca565b602060405180830381600087803b15801561399c57600080fd5b505af11580156139b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506139d491908101906146e0565b905063f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614613a5d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a54906156bc565b60405180910390fd5b505b5050505050565b613ac8816000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858152602001908152602001600020546125d990919063ffffffff16565b6000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550613b7d816000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858152602001908152602001600020546129f690919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000848152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051613c469291906156f7565b60405180910390a450505050565b613cb6816000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858152602001908152602001600020546125d990919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051613d809291906156f7565b60405180910390a4505050565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f9150808214158015613dcf57506000801b8214155b92505050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613e1957805160ff1916838001178555613e47565b82800160010185558215613e47579182015b82811115613e46578251825591602001919060010190613e2b565b5b509050613e549190613e58565b5090565b613e7a91905b80821115613e76576000816000905550600101613e5e565b5090565b90565b600081359050613e8c81615980565b92915050565b600082601f830112613ea357600080fd5b8135613eb6613eb18261574d565b615720565b91508181835260208401935060208101905083856020840282011115613edb57600080fd5b60005b83811015613f0b5781613ef18882613e7d565b845260208401935060208301925050600181019050613ede565b5050505092915050565b60008083601f840112613f2757600080fd5b8235905067ffffffffffffffff811115613f4057600080fd5b602083019150836020820283011115613f5857600080fd5b9250929050565b60008083601f840112613f7157600080fd5b8235905067ffffffffffffffff811115613f8a57600080fd5b602083019150836020820283011115613fa257600080fd5b9250929050565b600082601f830112613fba57600080fd5b8135613fcd613fc882615775565b615720565b91508181835260208401935060208101905083856020840282011115613ff257600080fd5b60005b8381101561402257816140088882614172565b845260208401935060208301925050600181019050613ff5565b5050505092915050565b60008135905061403b81615997565b92915050565b600081359050614050816159ae565b92915050565b600081519050614065816159ae565b92915050565b60008083601f84011261407d57600080fd5b8235905067ffffffffffffffff81111561409657600080fd5b6020830191508360018202830111156140ae57600080fd5b9250929050565b600082601f8301126140c657600080fd5b81356140d96140d48261579d565b615720565b915080825260208301602083018583830111156140f557600080fd5b61410083828461592d565b50505092915050565b600081519050614118816159c5565b92915050565b600082601f83011261412f57600080fd5b813561414261413d826157c9565b615720565b9150808252602083016020830185838301111561415e57600080fd5b61416983828461592d565b50505092915050565b600081359050614181816159dc565b92915050565b60006020828403121561419957600080fd5b60006141a784828501613e7d565b91505092915050565b600080604083850312156141c357600080fd5b60006141d185828601613e7d565b92505060206141e285828601613e7d565b9150509250929050565b600080600080600060a0868803121561420457600080fd5b600061421288828901613e7d565b955050602061422388828901613e7d565b945050604086013567ffffffffffffffff81111561424057600080fd5b61424c88828901613fa9565b935050606086013567ffffffffffffffff81111561426957600080fd5b61427588828901613fa9565b925050608086013567ffffffffffffffff81111561429257600080fd5b61429e888289016140b5565b9150509295509295909350565b600080600080600060a086880312156142c357600080fd5b60006142d188828901613e7d565b95505060206142e288828901613e7d565b94505060406142f388828901614172565b935050606061430488828901614172565b925050608086013567ffffffffffffffff81111561432157600080fd5b61432d888289016140b5565b9150509295509295909350565b6000806000806080858703121561435057600080fd5b600061435e87828801613e7d565b945050602085013567ffffffffffffffff81111561437b57600080fd5b61438787828801613fa9565b935050604085013567ffffffffffffffff8111156143a457600080fd5b6143b087828801613fa9565b925050606085013567ffffffffffffffff8111156143cd57600080fd5b6143d9878288016140b5565b91505092959194509250565b600080604083850312156143f857600080fd5b600061440685828601613e7d565b92505060206144178582860161402c565b9150509250929050565b6000806040838503121561443457600080fd5b600061444285828601613e7d565b925050602061445385828601614172565b9150509250929050565b60008060006060848603121561447257600080fd5b600061448086828701613e7d565b935050602061449186828701614172565b92505060406144a286828701613e7d565b9150509250925092565b6000806000606084860312156144c157600080fd5b60006144cf86828701613e7d565b93505060206144e086828701614172565b92505060406144f186828701614172565b9150509250925092565b6000806000806080858703121561451157600080fd5b600061451f87828801613e7d565b945050602061453087828801614172565b935050604061454187828801614172565b925050606085013567ffffffffffffffff81111561455e57600080fd5b61456a878288016140b5565b91505092959194509250565b6000806040838503121561458957600080fd5b600083013567ffffffffffffffff8111156145a357600080fd5b6145af85828601613e92565b925050602083013567ffffffffffffffff8111156145cc57600080fd5b6145d885828601613fa9565b9150509250929050565b6000806000806000806000806080898b0312156145fe57600080fd5b600089013567ffffffffffffffff81111561461857600080fd5b6146248b828c01613f5f565b9850985050602089013567ffffffffffffffff81111561464357600080fd5b61464f8b828c01613f5f565b9650965050604089013567ffffffffffffffff81111561466e57600080fd5b61467a8b828c01613f15565b9450945050606089013567ffffffffffffffff81111561469957600080fd5b6146a58b828c0161406b565b92509250509295985092959890939650565b6000602082840312156146c957600080fd5b60006146d784828501614041565b91505092915050565b6000602082840312156146f257600080fd5b600061470084828501614056565b91505092915050565b60006020828403121561471b57600080fd5b600061472984828501614109565b91505092915050565b60006020828403121561474457600080fd5b600082013567ffffffffffffffff81111561475e57600080fd5b61476a8482850161411e565b91505092915050565b60006020828403121561478557600080fd5b600061479384828501614172565b91505092915050565b600080600080608085870312156147b257600080fd5b60006147c087828801614172565b94505060206147d187828801614172565b935050604085013567ffffffffffffffff8111156147ee57600080fd5b6147fa8782880161411e565b925050606085013567ffffffffffffffff81111561481757600080fd5b614823878288016140b5565b91505092959194509250565b600061483b8383615229565b60208301905092915050565b614850816158f7565b82525050565b61485f81615871565b82525050565b600061487082615805565b61487a818561583e565b9350614885836157f5565b8060005b838110156148b657815161489d888261482f565b97506148a883615831565b925050600181019050614889565b5085935050505092915050565b6148cc81615883565b82525050565b60006148dd82615810565b6148e7818561584f565b93506148f781856020860161593c565b6149008161596f565b840191505092915050565b600061491682615826565b6149208185615860565b935061493081856020860161593c565b6149398161596f565b840191505092915050565b600061494f8261581b565b6149598185615860565b935061496981856020860161593c565b6149728161596f565b840191505092915050565b600061498a602b83615860565b91507f4552433131353523736166655472616e7366657246726f6d3a20494e56414c4960008301527f445f524543495049454e540000000000000000000000000000000000000000006020830152604082019050919050565b60006149f0601f83615860565b91507f526f6c65733a206163636f756e7420616c72656164792068617320726f6c65006000830152602082019050919050565b6000614a30602683615860565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614a96601683615860565b91507f4172726179206c656e67746873206d69736d61746368000000000000000000006000830152602082019050919050565b6000614ad6601b83615860565b91507f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006000830152602082019050919050565b6000614b16602a83615860565b91507f4552433131353523736166655472616e7366657246726f6d3a20494e56414c4960008301527f445f4f50455241544f52000000000000000000000000000000000000000000006020830152604082019050919050565b6000614b7c602c83615860565b91507f5374616b6544616f4e46545f56323a2075736572206163636f756e7420646f6560008301527f736e742068617665204e465400000000000000000000000000000000000000006020830152604082019050919050565b6000614be2603583615860565b91507f45524331313535235f7361666542617463685472616e7366657246726f6d3a2060008301527f494e56414c49445f4152524159535f4c454e47544800000000000000000000006020830152604082019050919050565b6000614c48601b83615860565b91507f5f696e697469616c537570706c79203e205f6d6178537570706c7900000000006000830152602082019050919050565b6000614c88603483615860565b91507f5374726174656779526f6c653a2063616c6c657220646f6573206e6f7420686160008301527f76652074686520537472617465677920726f6c650000000000000000000000006020830152604082019050919050565b6000614cee603083615860565b91507f4d696e746572526f6c653a2063616c6c657220646f6573206e6f74206861766560008301527f20746865204d696e74657220726f6c65000000000000000000000000000000006020830152604082019050919050565b6000614d54602183615860565b91507f526f6c65733a206163636f756e7420646f6573206e6f74206861766520726f6c60008301527f65000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614dba603083615860565b91507f45524331313535237361666542617463685472616e7366657246726f6d3a204960008301527f4e56414c49445f524543495049454e54000000000000000000000000000000006020830152604082019050919050565b6000614e20602583615860565b91507f4552433732315472616461626c65237572693a204e4f4e4558495354454e545f60008301527f544f4b454e0000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614e86602083615860565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000614ec6602283615860565b91507f526f6c65733a206163636f756e7420697320746865207a65726f20616464726560008301527f73730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614f2c604083615860565b91507f57686974656c69737441646d696e526f6c653a2063616c6c657220646f65732060008301527f6e6f742068617665207468652057686974656c69737441646d696e20726f6c656020830152604082019050919050565b6000614f92602c83615860565b91507f455243313135352362616c616e63654f6642617463683a20494e56414c49445f60008301527f41525241595f4c454e47544800000000000000000000000000000000000000006020830152604082019050919050565b6000614ff8602a83615860565b91507f5374616b6544616f4e46545f56323a204e4654206265696e672075736564206960008301527f6e207374726174656779000000000000000000000000000000000000000000006020830152604082019050919050565b600061505e602f83615860565b91507f45524331313535237361666542617463685472616e7366657246726f6d3a204960008301527f4e56414c49445f4f50455241544f5200000000000000000000000000000000006020830152604082019050919050565b60006150c4603083615860565b91507f455243313135354d696e744275726e2362617463684d696e743a20494e56414c60008301527f49445f4152524159535f4c454e475448000000000000000000000000000000006020830152604082019050919050565b600061512a601283615860565b91507f4d617820737570706c79207265616368656400000000000000000000000000006000830152602082019050919050565b600061516a603f83615860565b91507f45524331313535235f63616c6c6f6e455243313135354261746368526563656960008301527f7665643a20494e56414c49445f4f4e5f524543454956455f4d455353414745006020830152604082019050919050565b60006151d0603a83615860565b91507f45524331313535235f63616c6c6f6e4552433131353552656365697665643a2060008301527f494e56414c49445f4f4e5f524543454956455f4d4553534147450000000000006020830152604082019050919050565b615232816158ed565b82525050565b615241816158ed565b82525050565b600060208201905061525c6000830184614856565b92915050565b600060a0820190506152776000830188614847565b6152846020830187614856565b81810360408301526152968186614865565b905081810360608301526152aa8185614865565b905081810360808301526152be81846148d2565b90509695505050505050565b600060a0820190506152df6000830188614847565b6152ec6020830187614856565b6152f96040830186615238565b6153066060830185615238565b818103608083015261531881846148d2565b90509695505050505050565b6000602082019050818103600083015261533e8184614865565b905092915050565b600060408201905081810360008301526153608185614865565b905081810360208301526153748184614865565b90509392505050565b600060208201905061539260008301846148c3565b92915050565b600060208201905081810360008301526153b28184614944565b905092915050565b600060208201905081810360008301526153d4818461490b565b905092915050565b600060208201905081810360008301526153f58161497d565b9050919050565b60006020820190508181036000830152615415816149e3565b9050919050565b6000602082019050818103600083015261543581614a23565b9050919050565b6000602082019050818103600083015261545581614a89565b9050919050565b6000602082019050818103600083015261547581614ac9565b9050919050565b6000602082019050818103600083015261549581614b09565b9050919050565b600060208201905081810360008301526154b581614b6f565b9050919050565b600060208201905081810360008301526154d581614bd5565b9050919050565b600060208201905081810360008301526154f581614c3b565b9050919050565b6000602082019050818103600083015261551581614c7b565b9050919050565b6000602082019050818103600083015261553581614ce1565b9050919050565b6000602082019050818103600083015261555581614d47565b9050919050565b6000602082019050818103600083015261557581614dad565b9050919050565b6000602082019050818103600083015261559581614e13565b9050919050565b600060208201905081810360008301526155b581614e79565b9050919050565b600060208201905081810360008301526155d581614eb9565b9050919050565b600060208201905081810360008301526155f581614f1f565b9050919050565b6000602082019050818103600083015261561581614f85565b9050919050565b6000602082019050818103600083015261563581614feb565b9050919050565b6000602082019050818103600083015261565581615051565b9050919050565b60006020820190508181036000830152615675816150b7565b9050919050565b600060208201905081810360008301526156958161511d565b9050919050565b600060208201905081810360008301526156b58161515d565b9050919050565b600060208201905081810360008301526156d5816151c3565b9050919050565b60006020820190506156f16000830184615238565b92915050565b600060408201905061570c6000830185615238565b6157196020830184615238565b9392505050565b6000604051905081810181811067ffffffffffffffff8211171561574357600080fd5b8060405250919050565b600067ffffffffffffffff82111561576457600080fd5b602082029050602081019050919050565b600067ffffffffffffffff82111561578c57600080fd5b602082029050602081019050919050565b600067ffffffffffffffff8211156157b457600080fd5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff8211156157e057600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600061587c826158cd565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006158c682615871565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600061590282615909565b9050919050565b60006159148261591b565b9050919050565b6000615926826158cd565b9050919050565b82818337600083830152505050565b60005b8381101561595a57808201518184015260208101905061593f565b83811115615969576000848401525b50505050565b6000601f19601f8301169050919050565b61598981615871565b811461599457600080fd5b50565b6159a081615883565b81146159ab57600080fd5b50565b6159b78161588f565b81146159c257600080fd5b50565b6159ce816158bb565b81146159d957600080fd5b50565b6159e5816158ed565b81146159f057600080fd5b5056fe68747470733a2f2f676174657761792e70696e6174612e636c6f75642f697066732f516d63316933374b50646737437038727a6a677033516f434543614562666f53796d43704b473868463835454e76a365627a7a723158203fa247235cf42bfa1a8ca60e59e61d29f6c4de7a91b18c706d5e7ab2e6ef72a36c6578706572696d656e74616cf564736f6c6343000511004068747470733a2f2f676174657761792e70696e6174612e636c6f75642f697066732f516d533274786b52705155583358684d486a594e656d3869436f506850656b59636a6277616d54324e44436b48312f6d657461646174612f000000000000000000000000a5409ec958c83c3f309868babaca7c86dcb077c1
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102515760003560e01c80637e518ec811610146578063b48ab8b6116100c3578063cd53d08e11610087578063cd53d08e14610728578063e8a3d48514610758578063e985e9c514610776578063f242432a146107a6578063f2fde38b146107c2578063f5298aca146107de57610251565b8063b48ab8b614610660578063bb5f747b1461067c578063bd3b433d146106ac578063bd85b039146106c8578063c47b9bd3146106f857610251565b8063983b2d561161010a578063983b2d56146105be57806398650275146105da578063a22cb465146105e4578063aa271e1a14610600578063b09ddf7b1461063057610251565b80637e518ec814610518578063869f7594146105345780638da5cb5b146105645780638f32d59b1461058257806395d89b41146105a057610251565b80632e8ebaae116101d4578063608cf5f411610198578063608cf5f41461048a5780636897e974146104ba578063715018a6146104d6578063731133e9146104e05780637362d9c8146104fc57610251565b80632e8ebaae146103e85780632eb2c2d6146104185780633092afd5146104345780634c5a628c146104505780634e1273f41461045a57610251565b8063175188e81161021b578063175188e814610334578063223e5479146103505780632693ebf21461036c5780632a634e521461039c5780632e1edf69146103b857610251565b80624221f014610256578062fdd58e1461028657806301ffc9a7146102b657806306fdde03146102e65780630e89341c14610304575b600080fd5b610270600480360361026b9190810190614773565b6107fa565b60405161027d91906156dc565b60405180910390f35b6102a0600480360361029b9190810190614421565b610812565b6040516102ad91906156dc565b60405180910390f35b6102d060048036036102cb91908101906146b7565b61086c565b6040516102dd919061537d565b60405180910390f35b6102ee61091d565b6040516102fb9190615398565b60405180910390f35b61031e60048036036103199190810190614773565b6109bb565b60405161032b91906153ba565b60405180910390f35b61034e60048036036103499190810190614187565b610ab8565b005b61036a60048036036103659190810190614187565b610b0b565b005b61038660048036036103819190810190614773565b610b5e565b60405161039391906156dc565b60405180910390f35b6103b660048036036103b19190810190614421565b610b76565b005b6103d260048036036103cd91908101906145e2565b610e0e565b6040516103df9190615324565b60405180910390f35b61040260048036036103fd9190810190614187565b611055565b60405161040f919061537d565b60405180910390f35b610432600480360361042d91908101906141ec565b611072565b005b61044e60048036036104499190810190614187565b61114f565b005b6104586111a2565b005b610474600480360361046f9190810190614576565b6111b4565b6040516104819190615324565b60405180910390f35b6104a4600480360361049f919081019061445d565b6112e4565b6040516104b191906156dc565b60405180910390f35b6104d460048036036104cf9190810190614187565b61137d565b005b6104de6113d0565b005b6104fa60048036036104f591908101906144fb565b6114d8565b005b61051660048036036105119190810190614187565b6115e4565b005b610532600480360361052d9190810190614732565b61163f565b005b61054e60048036036105499190810190614773565b61169a565b60405161055b91906156dc565b60405180910390f35b61056c6116b7565b6040516105799190615247565b60405180910390f35b61058a6116e1565b604051610597919061537d565b60405180910390f35b6105a8611740565b6040516105b59190615398565b60405180910390f35b6105d860048036036105d39190810190614187565b6117de565b005b6105e2611839565b005b6105fe60048036036105f991908101906143e5565b61184b565b005b61061a60048036036106159190810190614187565b611948565b604051610627919061537d565b60405180910390f35b61064a6004803603610645919081019061479c565b611965565b60405161065791906156dc565b60405180910390f35b61067a6004803603610675919081019061433a565b611af3565b005b61069660048036036106919190810190614187565b611c48565b6040516106a3919061537d565b60405180910390f35b6106c660048036036106c19190810190614421565b611c65565b005b6106e260048036036106dd9190810190614773565b611f8f565b6040516106ef91906156dc565b60405180910390f35b610712600480360361070d9190810190614421565b611fac565b60405161071f91906156dc565b60405180910390f35b610742600480360361073d9190810190614773565b612007565b60405161074f9190615247565b60405180910390f35b61076061203a565b60405161076d91906153ba565b60405180910390f35b610790600480360361078b91908101906141b0565b61205a565b60405161079d919061537d565b60405180910390f35b6107c060048036036107bb91908101906142ab565b61215c565b005b6107dc60048036036107d79190810190614187565b612203565b005b6107f860048036036107f391908101906144ac565b612256565b005b600a6020528060005260406000206000915090505481565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b60006301ffc9a760e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610905575063d9b67a2660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156109135760019050610918565b600090505b919050565b600b8054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156109b35780601f10610988576101008083540402835291602001916109b3565b820191906000526020600020905b81548152906001019060200180831161099657829003601f168201915b505050505081565b60606109c682612340565b610a05576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109fc9061557c565b60405180910390fd5b610ab160028054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a9e5780601f10610a7357610100808354040283529160200191610a9e565b820191906000526020600020905b815481529060010190602001808311610a8157829003601f168201915b5050505050610aac846123ac565b6124d9565b9050919050565b610ac06116e1565b610aff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af69061559c565b60405180910390fd5b610b088161251d565b50565b610b136116e1565b610b52576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b499061559c565b60405180910390fd5b610b5b81612577565b50565b60096020528060005260406000206000915090505481565b610b86610b816125d1565b611055565b610bc5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bbc906154fc565b60405180910390fd5b610c666001600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546125d990919063ffffffff16565b600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610d5b6001600e60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000848152602001908152602001600020546125d990919063ffffffff16565b600e60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16818373ffffffffffffffffffffffffffffffffffffffff167f25db6fd0f22c400fcbc6cd08ce9ee28045ee6ad78ba0cf1cd6409f020d0af71560405160405180910390a45050565b6060610e20610e1b6125d1565b611c48565b610e5f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e56906155dc565b60405180910390fd5b8888905087879050148015610e7957508888905085859050145b610eb8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eaf9061543c565b60405180910390fd5b606089899050604051908082528060200260200182016040528015610eec5781602001602082028038833980820191505090505b509050600080905060008090505b8b8b90508110156110435761101b8c8c83818110610f1457fe5b905060200201358b8b84818110610f2757fe5b905060200201358a8a85818110610f3a57fe5b9050602002810180356001602003833603038112610f5757600080fd5b8083019250508135905060208201915067ffffffffffffffff811115610f7c57600080fd5b600181023603821315610f8e57600080fd5b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505089898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611965565b91508183828151811061102a57fe5b6020026020010181815250508080600101915050610efa565b50819250505098975050505050505050565b600061106b82600d61262390919063ffffffff16565b9050919050565b60008351905060008090505b81811015611139576000600e60008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008784815181106110d557fe5b60200260200101518152602001908152602001600020541461112c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111239061561c565b60405180910390fd5b808060010191505061107e565b5061114786868686866126eb565b505050505050565b6111576116e1565b611196576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118d9061559c565b60405180910390fd5b61119f816127fa565b50565b6111b26111ad6125d1565b612854565b565b606081518351146111fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111f1906155fc565b60405180910390fd5b6060835160405190808252806020026020018201604052801561122c5781602001602082028038833980820191505090505b50905060008090505b84518110156112d95760008086838151811061124d57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600085838151811061129d57fe5b60200260200101518152602001908152602001600020548282815181106112c057fe5b6020026020010181815250508080600101915050611235565b508091505092915050565b6000600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490509392505050565b6113856116e1565b6113c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113bb9061559c565b60405180910390fd5b6113cd81612854565b50565b6113d86116e1565b611417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161140e9061559c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6114e86114e36125d1565b611948565b611527576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151e9061551c565b60405180910390fd5b6000839050600a600082815260200190815260200160002054600960008381526020019081526020016000205410611594576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161158b9061567c565b60405180910390fd5b6115a0858585856128ae565b6115c68360096000878152602001908152602001600020546129f690919063ffffffff16565b60096000868152602001908152602001600020819055505050505050565b6115f46115ef6125d1565b611c48565b611633576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161162a906155dc565b60405180910390fd5b61163c81612a4b565b50565b61164f61164a6125d1565b611c48565b61168e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611685906155dc565b60405180910390fd5b61169781612aa5565b50565b6000600a6000838152602001908152602001600020549050919050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166117246125d1565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b600c8054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156117d65780601f106117ab576101008083540402835291602001916117d6565b820191906000526020600020905b8154815290600101906020018083116117b957829003601f168201915b505050505081565b6117ee6117e96125d1565b611948565b61182d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118249061551c565b60405180910390fd5b61183681612abf565b50565b6118496118446125d1565b6127fa565b565b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161193c919061537d565b60405180910390a35050565b600061195e82600461262390919063ffffffff16565b9050919050565b60006119776119726125d1565b611c48565b6119b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119ad906155dc565b60405180910390fd5b848411156119f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f0906154dc565b60405180910390fd5b6000611a03612b19565b9050611a0d612b36565b336008600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600084511115611aa257807f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b85604051611a9991906153ba565b60405180910390a25b60008514611ab757611ab6338287866128ae565b5b84600960008381526020019081526020016000208190555085600a60008381526020019081526020016000208190555080915050949350505050565b611b03611afe6125d1565b611948565b611b42576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b399061551c565b60405180910390fd5b60008351905060008090505b81811015611c34576000858281518110611b6457fe5b60200260200101519050600a600082815260200190815260200160002054600960008381526020019081526020016000205410611bd6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bcd9061567c565b60405180910390fd5b611c0f858381518110611be557fe5b602002602001015160096000848152602001908152602001600020546129f690919063ffffffff16565b6009600083815260200190815260200160002081905550508080600101915050611b4e565b50611c4185858585612b4a565b5050505050565b6000611c5e82600561262390919063ffffffff16565b9050919050565b611c75611c706125d1565b611055565b611cb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cab906154fc565b60405180910390fd5b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000205411611d46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3d9061549c565b60405180910390fd5b611de76001600f60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546129f690919063ffffffff16565b600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611edc6001600e60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000848152602001908152602001600020546129f690919063ffffffff16565b600e60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16818373ffffffffffffffffffffffffffffffffffffffff167f3e77ee48716bf1d18813bff935d16a73c0cf954b49a47b54ca941f0d191aa4ec60405160405180910390a45050565b600060096000838152602001908152602001600020549050919050565b6000600e60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b60086020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60606040518060800160405280605081526020016159f460509139905090565b600080600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1663c4552791866040518263ffffffff1660e01b81526004016120d29190615247565b60206040518083038186803b1580156120ea57600080fd5b505afa1580156120fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506121229190810190614709565b73ffffffffffffffffffffffffffffffffffffffff161415612148576001915050612156565b6121528484612d32565b9150505b92915050565b6000600e60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600085815260200190815260200160002054146121ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121e69061561c565b60405180910390fd5b6121fc8585858585612dc6565b5050505050565b61220b6116e1565b61224a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122419061559c565b60405180910390fd5b61225381612ed5565b50565b61225e6116e1565b61229d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122949061559c565b60405180910390fd5b6000600e60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008481526020019081526020016000205414612330576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123279061561c565b60405180910390fd5b61233b838383613005565b505050565b60008073ffffffffffffffffffffffffffffffffffffffff166008600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b606060008214156123f4576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506124d4565b600082905060005b6000821461241e578080600101915050600a828161241657fe5b0491506123fc565b6060816040519080825280601f01601f1916602001820160405280156124535781602001600182028038833980820191505090505b50905060006001830390505b600086146124cc57600a868161247157fe5b0660300160f81b8282806001900393508151811061248b57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a86816124c457fe5b04955061245f565b819450505050505b919050565b60606125158383604051806020016040528060008152506040518060200160405280600081525060405180602001604052806000815250613099565b905092915050565b61253181600d61335f90919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167f09a1db4b80c32706328728508c941a6b954f31eb5affd32f236c1fd405f8fea460405160405180910390a250565b61258b81600d61340690919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167f3f008fd510eae7a9e7bee13513d7b83bef8003d488b5a3d0b0da4de71d6846f160405160405180910390a250565b600033905090565b600061261b83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506134ae565b905092915050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612694576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161268b906155bc565b60405180910390fd5b8260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b8473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061272b575061272a853361205a565b5b61276a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127619061563c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156127da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127d19061555c565b60405180910390fd5b6127e685858585613509565b6127f385858585856137d0565b5050505050565b61280e81600461335f90919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb6669260405160405180910390a250565b61286881600561335f90919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167f0a8eb35e5ca14b3d6f28e4abf2f128dbab231a58b56e89beb5d636115001e16560405160405180910390a250565b612910826000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000868152602001908152602001600020546129f690919063ffffffff16565b6000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6286866040516129da9291906156f7565b60405180910390a46129f060008585858561391b565b50505050565b600080828401905083811015612a41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a389061545c565b60405180910390fd5b8091505092915050565b612a5f81600561340690919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167f22380c05984257a1cb900161c713dd71d39e74820f1aea43bd3f1bdd2096129960405160405180910390a250565b8060029080519060200190612abb929190613dd8565b5050565b612ad381600461340690919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f660405160405180910390a250565b6000612b3160016007546129f690919063ffffffff16565b905090565b600760008154809291906001019190505550565b8151835114612b8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b859061565c565b60405180910390fd5b60008351905060008090505b81811015612c9d57612c2a848281518110612bb157fe5b60200260200101516000808973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000888581518110612c0557fe5b60200260200101518152602001908152602001600020546129f690919063ffffffff16565b6000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000878481518110612c7657fe5b60200260200101518152602001908152602001600020819055508080600101915050612b9a565b508473ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051612d15929190615346565b60405180910390a4612d2b6000868686866137d0565b5050505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b8473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480612e065750612e05853361205a565b5b612e45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e3c9061547c565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415612eb5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612eac906153dc565b60405180910390fd5b612ec185858585613a66565b612ece858585858561391b565b5050505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612f45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f3c9061541c565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61300d6116e1565b61304c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130439061559c565b60405180910390fd5b6130728160096000858152602001908152602001600020546125d990919063ffffffff16565b6009600084815260200190815260200160002081905550613094838383613c54565b505050565b6060808690506060869050606086905060608690506060869050606081518351855187518951010101016040519080825280601f01601f1916602001820160405280156130f55781602001600182028038833980820191505090505b5090506060819050600080905060008090505b88518110156131765788818151811061311d57fe5b602001015160f81c60f81b83838060010194508151811061313a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508080600101915050613108565b5060008090505b87518110156131eb5787818151811061319257fe5b602001015160f81c60f81b8383806001019450815181106131af57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350808060010191505061317d565b5060008090505b86518110156132605786818151811061320757fe5b602001015160f81c60f81b83838060010194508151811061322457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080806001019150506131f2565b5060008090505b85518110156132d55785818151811061327c57fe5b602001015160f81c60f81b83838060010194508151811061329957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508080600101915050613267565b5060008090505b845181101561334a578481815181106132f157fe5b602001015160f81c60f81b83838060010194508151811061330e57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080806001019150506132dc565b50819850505050505050505095945050505050565b6133698282612623565b6133a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161339f9061553c565b60405180910390fd5b60008260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6134108282612623565b15613450576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613447906153fc565b60405180910390fd5b60018260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b60008383111582906134f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016134ed91906153ba565b60405180910390fd5b5060008385039050809150509392505050565b805182511461354d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613544906154bc565b60405180910390fd5b60008251905060008090505b8181101561374a576135e983828151811061357057fe5b60200260200101516000808973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008785815181106135c457fe5b60200260200101518152602001908152602001600020546125d990919063ffffffff16565b6000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600086848151811061363557fe5b60200260200101518152602001908152602001600020819055506136d783828151811061365e57fe5b60200260200101516000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008785815181106136b257fe5b60200260200101518152602001908152602001600020546129f690919063ffffffff16565b6000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600086848151811061372357fe5b60200260200101518152602001908152602001600020819055508080600101915050613559565b508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb86866040516137c1929190615346565b60405180910390a45050505050565b6137ef8473ffffffffffffffffffffffffffffffffffffffff16613d8d565b156139145760008473ffffffffffffffffffffffffffffffffffffffff1663bc197c8133888787876040518663ffffffff1660e01b8152600401613837959493929190615262565b602060405180830381600087803b15801561385157600080fd5b505af1158015613865573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061388991908101906146e0565b905063bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614613912576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139099061569c565b60405180910390fd5b505b5050505050565b61393a8473ffffffffffffffffffffffffffffffffffffffff16613d8d565b15613a5f5760008473ffffffffffffffffffffffffffffffffffffffff1663f23a6e6133888787876040518663ffffffff1660e01b81526004016139829594939291906152ca565b602060405180830381600087803b15801561399c57600080fd5b505af11580156139b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506139d491908101906146e0565b905063f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614613a5d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a54906156bc565b60405180910390fd5b505b5050505050565b613ac8816000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858152602001908152602001600020546125d990919063ffffffff16565b6000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550613b7d816000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858152602001908152602001600020546129f690919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000848152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051613c469291906156f7565b60405180910390a450505050565b613cb6816000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858152602001908152602001600020546125d990919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051613d809291906156f7565b60405180910390a4505050565b60008060007fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060001b9050833f9150808214158015613dcf57506000801b8214155b92505050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613e1957805160ff1916838001178555613e47565b82800160010185558215613e47579182015b82811115613e46578251825591602001919060010190613e2b565b5b509050613e549190613e58565b5090565b613e7a91905b80821115613e76576000816000905550600101613e5e565b5090565b90565b600081359050613e8c81615980565b92915050565b600082601f830112613ea357600080fd5b8135613eb6613eb18261574d565b615720565b91508181835260208401935060208101905083856020840282011115613edb57600080fd5b60005b83811015613f0b5781613ef18882613e7d565b845260208401935060208301925050600181019050613ede565b5050505092915050565b60008083601f840112613f2757600080fd5b8235905067ffffffffffffffff811115613f4057600080fd5b602083019150836020820283011115613f5857600080fd5b9250929050565b60008083601f840112613f7157600080fd5b8235905067ffffffffffffffff811115613f8a57600080fd5b602083019150836020820283011115613fa257600080fd5b9250929050565b600082601f830112613fba57600080fd5b8135613fcd613fc882615775565b615720565b91508181835260208401935060208101905083856020840282011115613ff257600080fd5b60005b8381101561402257816140088882614172565b845260208401935060208301925050600181019050613ff5565b5050505092915050565b60008135905061403b81615997565b92915050565b600081359050614050816159ae565b92915050565b600081519050614065816159ae565b92915050565b60008083601f84011261407d57600080fd5b8235905067ffffffffffffffff81111561409657600080fd5b6020830191508360018202830111156140ae57600080fd5b9250929050565b600082601f8301126140c657600080fd5b81356140d96140d48261579d565b615720565b915080825260208301602083018583830111156140f557600080fd5b61410083828461592d565b50505092915050565b600081519050614118816159c5565b92915050565b600082601f83011261412f57600080fd5b813561414261413d826157c9565b615720565b9150808252602083016020830185838301111561415e57600080fd5b61416983828461592d565b50505092915050565b600081359050614181816159dc565b92915050565b60006020828403121561419957600080fd5b60006141a784828501613e7d565b91505092915050565b600080604083850312156141c357600080fd5b60006141d185828601613e7d565b92505060206141e285828601613e7d565b9150509250929050565b600080600080600060a0868803121561420457600080fd5b600061421288828901613e7d565b955050602061422388828901613e7d565b945050604086013567ffffffffffffffff81111561424057600080fd5b61424c88828901613fa9565b935050606086013567ffffffffffffffff81111561426957600080fd5b61427588828901613fa9565b925050608086013567ffffffffffffffff81111561429257600080fd5b61429e888289016140b5565b9150509295509295909350565b600080600080600060a086880312156142c357600080fd5b60006142d188828901613e7d565b95505060206142e288828901613e7d565b94505060406142f388828901614172565b935050606061430488828901614172565b925050608086013567ffffffffffffffff81111561432157600080fd5b61432d888289016140b5565b9150509295509295909350565b6000806000806080858703121561435057600080fd5b600061435e87828801613e7d565b945050602085013567ffffffffffffffff81111561437b57600080fd5b61438787828801613fa9565b935050604085013567ffffffffffffffff8111156143a457600080fd5b6143b087828801613fa9565b925050606085013567ffffffffffffffff8111156143cd57600080fd5b6143d9878288016140b5565b91505092959194509250565b600080604083850312156143f857600080fd5b600061440685828601613e7d565b92505060206144178582860161402c565b9150509250929050565b6000806040838503121561443457600080fd5b600061444285828601613e7d565b925050602061445385828601614172565b9150509250929050565b60008060006060848603121561447257600080fd5b600061448086828701613e7d565b935050602061449186828701614172565b92505060406144a286828701613e7d565b9150509250925092565b6000806000606084860312156144c157600080fd5b60006144cf86828701613e7d565b93505060206144e086828701614172565b92505060406144f186828701614172565b9150509250925092565b6000806000806080858703121561451157600080fd5b600061451f87828801613e7d565b945050602061453087828801614172565b935050604061454187828801614172565b925050606085013567ffffffffffffffff81111561455e57600080fd5b61456a878288016140b5565b91505092959194509250565b6000806040838503121561458957600080fd5b600083013567ffffffffffffffff8111156145a357600080fd5b6145af85828601613e92565b925050602083013567ffffffffffffffff8111156145cc57600080fd5b6145d885828601613fa9565b9150509250929050565b6000806000806000806000806080898b0312156145fe57600080fd5b600089013567ffffffffffffffff81111561461857600080fd5b6146248b828c01613f5f565b9850985050602089013567ffffffffffffffff81111561464357600080fd5b61464f8b828c01613f5f565b9650965050604089013567ffffffffffffffff81111561466e57600080fd5b61467a8b828c01613f15565b9450945050606089013567ffffffffffffffff81111561469957600080fd5b6146a58b828c0161406b565b92509250509295985092959890939650565b6000602082840312156146c957600080fd5b60006146d784828501614041565b91505092915050565b6000602082840312156146f257600080fd5b600061470084828501614056565b91505092915050565b60006020828403121561471b57600080fd5b600061472984828501614109565b91505092915050565b60006020828403121561474457600080fd5b600082013567ffffffffffffffff81111561475e57600080fd5b61476a8482850161411e565b91505092915050565b60006020828403121561478557600080fd5b600061479384828501614172565b91505092915050565b600080600080608085870312156147b257600080fd5b60006147c087828801614172565b94505060206147d187828801614172565b935050604085013567ffffffffffffffff8111156147ee57600080fd5b6147fa8782880161411e565b925050606085013567ffffffffffffffff81111561481757600080fd5b614823878288016140b5565b91505092959194509250565b600061483b8383615229565b60208301905092915050565b614850816158f7565b82525050565b61485f81615871565b82525050565b600061487082615805565b61487a818561583e565b9350614885836157f5565b8060005b838110156148b657815161489d888261482f565b97506148a883615831565b925050600181019050614889565b5085935050505092915050565b6148cc81615883565b82525050565b60006148dd82615810565b6148e7818561584f565b93506148f781856020860161593c565b6149008161596f565b840191505092915050565b600061491682615826565b6149208185615860565b935061493081856020860161593c565b6149398161596f565b840191505092915050565b600061494f8261581b565b6149598185615860565b935061496981856020860161593c565b6149728161596f565b840191505092915050565b600061498a602b83615860565b91507f4552433131353523736166655472616e7366657246726f6d3a20494e56414c4960008301527f445f524543495049454e540000000000000000000000000000000000000000006020830152604082019050919050565b60006149f0601f83615860565b91507f526f6c65733a206163636f756e7420616c72656164792068617320726f6c65006000830152602082019050919050565b6000614a30602683615860565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614a96601683615860565b91507f4172726179206c656e67746873206d69736d61746368000000000000000000006000830152602082019050919050565b6000614ad6601b83615860565b91507f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006000830152602082019050919050565b6000614b16602a83615860565b91507f4552433131353523736166655472616e7366657246726f6d3a20494e56414c4960008301527f445f4f50455241544f52000000000000000000000000000000000000000000006020830152604082019050919050565b6000614b7c602c83615860565b91507f5374616b6544616f4e46545f56323a2075736572206163636f756e7420646f6560008301527f736e742068617665204e465400000000000000000000000000000000000000006020830152604082019050919050565b6000614be2603583615860565b91507f45524331313535235f7361666542617463685472616e7366657246726f6d3a2060008301527f494e56414c49445f4152524159535f4c454e47544800000000000000000000006020830152604082019050919050565b6000614c48601b83615860565b91507f5f696e697469616c537570706c79203e205f6d6178537570706c7900000000006000830152602082019050919050565b6000614c88603483615860565b91507f5374726174656779526f6c653a2063616c6c657220646f6573206e6f7420686160008301527f76652074686520537472617465677920726f6c650000000000000000000000006020830152604082019050919050565b6000614cee603083615860565b91507f4d696e746572526f6c653a2063616c6c657220646f6573206e6f74206861766560008301527f20746865204d696e74657220726f6c65000000000000000000000000000000006020830152604082019050919050565b6000614d54602183615860565b91507f526f6c65733a206163636f756e7420646f6573206e6f74206861766520726f6c60008301527f65000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614dba603083615860565b91507f45524331313535237361666542617463685472616e7366657246726f6d3a204960008301527f4e56414c49445f524543495049454e54000000000000000000000000000000006020830152604082019050919050565b6000614e20602583615860565b91507f4552433732315472616461626c65237572693a204e4f4e4558495354454e545f60008301527f544f4b454e0000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614e86602083615860565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000614ec6602283615860565b91507f526f6c65733a206163636f756e7420697320746865207a65726f20616464726560008301527f73730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000614f2c604083615860565b91507f57686974656c69737441646d696e526f6c653a2063616c6c657220646f65732060008301527f6e6f742068617665207468652057686974656c69737441646d696e20726f6c656020830152604082019050919050565b6000614f92602c83615860565b91507f455243313135352362616c616e63654f6642617463683a20494e56414c49445f60008301527f41525241595f4c454e47544800000000000000000000000000000000000000006020830152604082019050919050565b6000614ff8602a83615860565b91507f5374616b6544616f4e46545f56323a204e4654206265696e672075736564206960008301527f6e207374726174656779000000000000000000000000000000000000000000006020830152604082019050919050565b600061505e602f83615860565b91507f45524331313535237361666542617463685472616e7366657246726f6d3a204960008301527f4e56414c49445f4f50455241544f5200000000000000000000000000000000006020830152604082019050919050565b60006150c4603083615860565b91507f455243313135354d696e744275726e2362617463684d696e743a20494e56414c60008301527f49445f4152524159535f4c454e475448000000000000000000000000000000006020830152604082019050919050565b600061512a601283615860565b91507f4d617820737570706c79207265616368656400000000000000000000000000006000830152602082019050919050565b600061516a603f83615860565b91507f45524331313535235f63616c6c6f6e455243313135354261746368526563656960008301527f7665643a20494e56414c49445f4f4e5f524543454956455f4d455353414745006020830152604082019050919050565b60006151d0603a83615860565b91507f45524331313535235f63616c6c6f6e4552433131353552656365697665643a2060008301527f494e56414c49445f4f4e5f524543454956455f4d4553534147450000000000006020830152604082019050919050565b615232816158ed565b82525050565b615241816158ed565b82525050565b600060208201905061525c6000830184614856565b92915050565b600060a0820190506152776000830188614847565b6152846020830187614856565b81810360408301526152968186614865565b905081810360608301526152aa8185614865565b905081810360808301526152be81846148d2565b90509695505050505050565b600060a0820190506152df6000830188614847565b6152ec6020830187614856565b6152f96040830186615238565b6153066060830185615238565b818103608083015261531881846148d2565b90509695505050505050565b6000602082019050818103600083015261533e8184614865565b905092915050565b600060408201905081810360008301526153608185614865565b905081810360208301526153748184614865565b90509392505050565b600060208201905061539260008301846148c3565b92915050565b600060208201905081810360008301526153b28184614944565b905092915050565b600060208201905081810360008301526153d4818461490b565b905092915050565b600060208201905081810360008301526153f58161497d565b9050919050565b60006020820190508181036000830152615415816149e3565b9050919050565b6000602082019050818103600083015261543581614a23565b9050919050565b6000602082019050818103600083015261545581614a89565b9050919050565b6000602082019050818103600083015261547581614ac9565b9050919050565b6000602082019050818103600083015261549581614b09565b9050919050565b600060208201905081810360008301526154b581614b6f565b9050919050565b600060208201905081810360008301526154d581614bd5565b9050919050565b600060208201905081810360008301526154f581614c3b565b9050919050565b6000602082019050818103600083015261551581614c7b565b9050919050565b6000602082019050818103600083015261553581614ce1565b9050919050565b6000602082019050818103600083015261555581614d47565b9050919050565b6000602082019050818103600083015261557581614dad565b9050919050565b6000602082019050818103600083015261559581614e13565b9050919050565b600060208201905081810360008301526155b581614e79565b9050919050565b600060208201905081810360008301526155d581614eb9565b9050919050565b600060208201905081810360008301526155f581614f1f565b9050919050565b6000602082019050818103600083015261561581614f85565b9050919050565b6000602082019050818103600083015261563581614feb565b9050919050565b6000602082019050818103600083015261565581615051565b9050919050565b60006020820190508181036000830152615675816150b7565b9050919050565b600060208201905081810360008301526156958161511d565b9050919050565b600060208201905081810360008301526156b58161515d565b9050919050565b600060208201905081810360008301526156d5816151c3565b9050919050565b60006020820190506156f16000830184615238565b92915050565b600060408201905061570c6000830185615238565b6157196020830184615238565b9392505050565b6000604051905081810181811067ffffffffffffffff8211171561574357600080fd5b8060405250919050565b600067ffffffffffffffff82111561576457600080fd5b602082029050602081019050919050565b600067ffffffffffffffff82111561578c57600080fd5b602082029050602081019050919050565b600067ffffffffffffffff8211156157b457600080fd5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff8211156157e057600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600061587c826158cd565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006158c682615871565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600061590282615909565b9050919050565b60006159148261591b565b9050919050565b6000615926826158cd565b9050919050565b82818337600083830152505050565b60005b8381101561595a57808201518184015260208101905061593f565b83811115615969576000848401525b50505050565b6000601f19601f8301169050919050565b61598981615871565b811461599457600080fd5b50565b6159a081615883565b81146159ab57600080fd5b50565b6159b78161588f565b81146159c257600080fd5b50565b6159ce816158bb565b81146159d957600080fd5b50565b6159e5816158ed565b81146159f057600080fd5b5056fe68747470733a2f2f676174657761792e70696e6174612e636c6f75642f697066732f516d63316933374b50646737437038727a6a677033516f434543614562666f53796d43704b473868463835454e76a365627a7a723158203fa247235cf42bfa1a8ca60e59e61d29f6c4de7a91b18c706d5e7ab2e6ef72a36c6578706572696d656e74616cf564736f6c63430005110040
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000a5409ec958c83c3f309868babaca7c86dcb077c1
-----Decoded View---------------
Arg [0] : _proxyRegistryAddress (address): 0xa5409ec958C83C3f309868babACA7c86DCB077c1
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000a5409ec958c83c3f309868babaca7c86dcb077c1
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.